Skip to content

Commit

Permalink
powerpc/vdso: Disable building the 32-bit VDSO on little endian
Browse files Browse the repository at this point in the history
The only little endian configuration we support is ppc64le. As such if
we're building little endian we don't need a 32-bit VDSO, because there
is no 32-bit userspace.

This patch is a fairly ugly mess of #ifdefs, but is the minimal logic
required to disable the 32-bit VDSO. We can hopefully clean up the
result in future with some further refactoring.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
  • Loading branch information
Michael Ellerman committed May 11, 2015
1 parent 6e5c077 commit e0d0059
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 3 deletions.
3 changes: 2 additions & 1 deletion arch/powerpc/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ obj-y := cputable.o ptrace.o syscalls.o \
signal.o sysfs.o cacheinfo.o time.o \
prom.o traps.o setup-common.o \
udbg.o misc.o io.o dma.o \
misc_$(CONFIG_WORD_SIZE).o vdso32/ \
misc_$(CONFIG_WORD_SIZE).o \
of_platform.o prom_parse.o
obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \
signal_64.o ptrace32.o \
paca.o nvram_64.o firmware.o
obj-$(CONFIG_VDSO32) += vdso32/
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o
obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power.o
Expand Down
36 changes: 34 additions & 2 deletions arch/powerpc/kernel/vdso.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,16 @@
/* The alignment of the vDSO */
#define VDSO_ALIGNMENT (1 << 16)

extern char vdso32_start, vdso32_end;
static void *vdso32_kbase = &vdso32_start;
static unsigned int vdso32_pages;
static void *vdso32_kbase;
static struct page **vdso32_pagelist;
unsigned long vdso32_sigtramp;
unsigned long vdso32_rt_sigtramp;

#ifdef CONFIG_VDSO32
extern char vdso32_start, vdso32_end;
#endif

#ifdef CONFIG_PPC64
extern char vdso64_start, vdso64_end;
static void *vdso64_kbase = &vdso64_start;
Expand Down Expand Up @@ -248,6 +251,7 @@ const char *arch_vma_name(struct vm_area_struct *vma)



#ifdef CONFIG_VDSO32
static void * __init find_section32(Elf32_Ehdr *ehdr, const char *secname,
unsigned long *size)
{
Expand Down Expand Up @@ -335,6 +339,20 @@ static int __init vdso_do_func_patch32(struct lib32_elfinfo *v32,

return 0;
}
#else /* !CONFIG_VDSO32 */
static unsigned long __init find_function32(struct lib32_elfinfo *lib,
const char *symname)
{
return 0;
}

static int __init vdso_do_func_patch32(struct lib32_elfinfo *v32,
struct lib64_elfinfo *v64,
const char *orig, const char *fix)
{
return 0;
}
#endif /* CONFIG_VDSO32 */


#ifdef CONFIG_PPC64
Expand Down Expand Up @@ -445,6 +463,7 @@ static __init int vdso_do_find_sections(struct lib32_elfinfo *v32,
* Locate symbol tables & text section
*/

#ifdef CONFIG_VDSO32
v32->dynsym = find_section32(v32->hdr, ".dynsym", &v32->dynsymsize);
v32->dynstr = find_section32(v32->hdr, ".dynstr", NULL);
if (v32->dynsym == NULL || v32->dynstr == NULL) {
Expand All @@ -457,6 +476,7 @@ static __init int vdso_do_find_sections(struct lib32_elfinfo *v32,
return -1;
}
v32->text = sect - vdso32_kbase;
#endif

#ifdef CONFIG_PPC64
v64->dynsym = find_section64(v64->hdr, ".dynsym", &v64->dynsymsize);
Expand Down Expand Up @@ -493,7 +513,9 @@ static __init void vdso_setup_trampolines(struct lib32_elfinfo *v32,
static __init int vdso_fixup_datapage(struct lib32_elfinfo *v32,
struct lib64_elfinfo *v64)
{
#ifdef CONFIG_VDSO32
Elf32_Sym *sym32;
#endif
#ifdef CONFIG_PPC64
Elf64_Sym *sym64;

Expand All @@ -508,6 +530,7 @@ static __init int vdso_fixup_datapage(struct lib32_elfinfo *v32,
(sym64->st_value - VDSO64_LBASE);
#endif /* CONFIG_PPC64 */

#ifdef CONFIG_VDSO32
sym32 = find_symbol32(v32, "__kernel_datapage_offset");
if (sym32 == NULL) {
printk(KERN_ERR "vDSO32: Can't find symbol "
Expand All @@ -517,6 +540,7 @@ static __init int vdso_fixup_datapage(struct lib32_elfinfo *v32,
*((int *)(vdso32_kbase + (sym32->st_value - VDSO32_LBASE))) =
(vdso32_pages << PAGE_SHIFT) -
(sym32->st_value - VDSO32_LBASE);
#endif

return 0;
}
Expand Down Expand Up @@ -550,6 +574,7 @@ static __init int vdso_fixup_features(struct lib32_elfinfo *v32,
start, start + size);
#endif /* CONFIG_PPC64 */

#ifdef CONFIG_VDSO32
start = find_section32(v32->hdr, "__ftr_fixup", &size);
if (start)
do_feature_fixups(cur_cpu_spec->cpu_features,
Expand All @@ -571,6 +596,7 @@ static __init int vdso_fixup_features(struct lib32_elfinfo *v32,
if (start)
do_lwsync_fixups(cur_cpu_spec->cpu_features,
start, start + size);
#endif

return 0;
}
Expand Down Expand Up @@ -732,11 +758,15 @@ static int __init vdso_init(void)
#endif /* CONFIG_PPC64 */


#ifdef CONFIG_VDSO32
vdso32_kbase = &vdso32_start;

/*
* Calculate the size of the 32 bits vDSO
*/
vdso32_pages = (&vdso32_end - &vdso32_start) >> PAGE_SHIFT;
DBG("vdso32_kbase: %p, 0x%x pages\n", vdso32_kbase, vdso32_pages);
#endif


/*
Expand All @@ -757,6 +787,7 @@ static int __init vdso_init(void)
return 0;
}

#ifdef CONFIG_VDSO32
/* Make sure pages are in the correct state */
vdso32_pagelist = kzalloc(sizeof(struct page *) * (vdso32_pages + 2),
GFP_KERNEL);
Expand All @@ -769,6 +800,7 @@ static int __init vdso_init(void)
}
vdso32_pagelist[i++] = virt_to_page(vdso_data);
vdso32_pagelist[i] = NULL;
#endif

#ifdef CONFIG_PPC64
vdso64_pagelist = kzalloc(sizeof(struct page *) * (vdso64_pages + 2),
Expand Down
10 changes: 10 additions & 0 deletions arch/powerpc/platforms/Kconfig.cputype
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,16 @@ config PPC_DOORBELL

endmenu

config VDSO32
def_bool y
depends on PPC32 || CPU_BIG_ENDIAN
help
This symbol controls whether we build the 32-bit VDSO. We obviously
want to do that if we're building a 32-bit kernel. If we're building
a 64-bit kernel then we only want a 32-bit VDSO if we're building for
big endian. That is because the only little endian configuration we
support is ppc64le which is 64-bit only.

choice
prompt "Endianness selection"
default CPU_BIG_ENDIAN
Expand Down

0 comments on commit e0d0059

Please sign in to comment.