Skip to content

Commit

Permalink
x86/vdso: Remove runtime 32-bit vDSO selection
Browse files Browse the repository at this point in the history
32-bit userspace will now always see the same vDSO, which is
exactly what used to be the int80 vDSO.  Subsequent patches will
clean it up and make it support SYSENTER and SYSCALL using
alternatives.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Link: http://lkml.kernel.org/r/e7e6b3526fa442502e6125fe69486aab50813c32.1444091584.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Andy Lutomirski authored and Ingo Molnar committed Oct 7, 2015
1 parent b611acf commit 0a6d1fa
Show file tree
Hide file tree
Showing 12 changed files with 21 additions and 279 deletions.
35 changes: 11 additions & 24 deletions arch/x86/entry/vdso/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ obj-y += vma.o
# vDSO images to build
vdso_img-$(VDSO64-y) += 64
vdso_img-$(VDSOX32-y) += x32
vdso_img-$(VDSO32-y) += 32-int80
vdso_img-$(CONFIG_IA32_EMULATION) += 32-syscall
vdso_img-$(VDSO32-y) += 32-sysenter
vdso_img-$(VDSO32-y) += 32

obj-$(VDSO32-y) += vdso32-setup.o

Expand Down Expand Up @@ -122,15 +120,6 @@ $(obj)/%.so: $(obj)/%.so.dbg
$(obj)/vdsox32.so.dbg: $(src)/vdsox32.lds $(vobjx32s) FORCE
$(call if_changed,vdso)

#
# Build multiple 32-bit vDSO images to choose from at boot time.
#
vdso32.so-$(VDSO32-y) += int80
vdso32.so-$(CONFIG_IA32_EMULATION) += syscall
vdso32.so-$(VDSO32-y) += sysenter

vdso32-images = $(vdso32.so-y:%=vdso32-%.so)

CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds)
VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-m,elf_i386 -Wl,-soname=linux-gate.so.1

Expand All @@ -139,14 +128,12 @@ VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-m,elf_i386 -Wl,-soname=linux-gate.so.1
override obj-dirs = $(dir $(obj)) $(obj)/vdso32/

targets += vdso32/vdso32.lds
targets += vdso32/note.o vdso32/vclock_gettime.o $(vdso32.so-y:%=vdso32/%.o)
targets += vdso32/note.o vdso32/vclock_gettime.o vdso32/system_call.o
targets += vdso32/vclock_gettime.o

$(obj)/vdso32.o: $(vdso32-images:%=$(obj)/%)

KBUILD_AFLAGS_32 := $(filter-out -m64,$(KBUILD_AFLAGS))
$(vdso32-images:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_32)
$(vdso32-images:%=$(obj)/%.dbg): asflags-$(CONFIG_X86_64) += -m32
$(obj)/vdso32.so.dbg: KBUILD_AFLAGS = $(KBUILD_AFLAGS_32)
$(obj)/vdso32.so.dbg: asflags-$(CONFIG_X86_64) += -m32

KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS))
KBUILD_CFLAGS_32 := $(filter-out -mcmodel=kernel,$(KBUILD_CFLAGS_32))
Expand All @@ -157,13 +144,13 @@ KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector)
KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls)
KBUILD_CFLAGS_32 += -fno-omit-frame-pointer
KBUILD_CFLAGS_32 += -DDISABLE_BRANCH_PROFILING
$(vdso32-images:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_32)
$(obj)/vdso32.so.dbg: KBUILD_CFLAGS = $(KBUILD_CFLAGS_32)

$(vdso32-images:%=$(obj)/%.dbg): $(obj)/vdso32-%.so.dbg: FORCE \
$(obj)/vdso32/vdso32.lds \
$(obj)/vdso32/vclock_gettime.o \
$(obj)/vdso32/note.o \
$(obj)/vdso32/%.o
$(obj)/vdso32.so.dbg: FORCE \
$(obj)/vdso32/vdso32.lds \
$(obj)/vdso32/vclock_gettime.o \
$(obj)/vdso32/note.o \
$(obj)/vdso32/system_call.o
$(call if_changed,vdso)

#
Expand Down Expand Up @@ -206,4 +193,4 @@ $(vdso_img_insttargets): install_%: $(obj)/%.dbg $(MODLIB)/vdso FORCE
PHONY += vdso_install $(vdso_img_insttargets)
vdso_install: $(vdso_img_insttargets) FORCE

clean-files := vdso32-syscall* vdso32-sysenter* vdso32-int80* vdso64* vdso-image-*.c vdsox32.so*
clean-files := vdso32.so vdso32.so.dbg vdso64* vdso-image-*.c vdsox32.so*
1 change: 0 additions & 1 deletion arch/x86/entry/vdso/vdso2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ struct vdso_sym required_syms[] = {
"VDSO_FAKE_SECTION_TABLE_END", false
},
{"VDSO32_NOTE_MASK", true},
{"VDSO32_SYSENTER_RETURN", true},
{"__kernel_vsyscall", true},
{"__kernel_sigreturn", true},
{"__kernel_rt_sigreturn", true},
Expand Down
28 changes: 1 addition & 27 deletions arch/x86/entry/vdso/vdso32-setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,35 +48,9 @@ __setup("vdso32=", vdso32_setup);
__setup_param("vdso=", vdso_setup, vdso32_setup, 0);
#endif

#ifdef CONFIG_X86_64

#define vdso32_sysenter() (boot_cpu_has(X86_FEATURE_SYSENTER32))
#define vdso32_syscall() (boot_cpu_has(X86_FEATURE_SYSCALL32))

#else /* CONFIG_X86_32 */

#define vdso32_sysenter() (boot_cpu_has(X86_FEATURE_SEP))
#define vdso32_syscall() (0)

#endif /* CONFIG_X86_64 */

#if defined(CONFIG_X86_32) || defined(CONFIG_COMPAT)
const struct vdso_image *selected_vdso32;
#endif

int __init sysenter_setup(void)
{
#ifdef CONFIG_COMPAT
if (vdso32_syscall())
selected_vdso32 = &vdso_image_32_syscall;
else
#endif
if (vdso32_sysenter())
selected_vdso32 = &vdso_image_32_sysenter;
else
selected_vdso32 = &vdso_image_32_int80;

init_vdso_image(selected_vdso32);
init_vdso_image(&vdso_image_32);

return 0;
}
Expand Down
75 changes: 0 additions & 75 deletions arch/x86/entry/vdso/vdso32/syscall.S

This file was deleted.

116 changes: 0 additions & 116 deletions arch/x86/entry/vdso/vdso32/sysenter.S

This file was deleted.

File renamed without changes.
13 changes: 1 addition & 12 deletions arch/x86/entry/vdso/vma.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,21 +180,10 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
static int load_vdso32(void)
{
int ret;

if (vdso32_enabled != 1) /* Other values all mean "disabled" */
return 0;

ret = map_vdso(selected_vdso32, false);
if (ret)
return ret;

if (selected_vdso32->sym_VDSO32_SYSENTER_RETURN)
current_thread_info()->sysenter_return =
current->mm->context.vdso +
selected_vdso32->sym_VDSO32_SYSENTER_RETURN;

return 0;
return map_vdso(&vdso_image_32, false);
}
#endif

Expand Down
4 changes: 2 additions & 2 deletions arch/x86/ia32/ia32_signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ int ia32_setup_frame(int sig, struct ksignal *ksig,
/* Return stub is in 32bit vsyscall page */
if (current->mm->context.vdso)
restorer = current->mm->context.vdso +
selected_vdso32->sym___kernel_sigreturn;
vdso_image_32.sym___kernel_sigreturn;
else
restorer = &frame->retcode;
}
Expand Down Expand Up @@ -368,7 +368,7 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
restorer = ksig->ka.sa.sa_restorer;
else
restorer = current->mm->context.vdso +
selected_vdso32->sym___kernel_rt_sigreturn;
vdso_image_32.sym___kernel_rt_sigreturn;
put_user_ex(ptr_to_compat(restorer), &frame->pretcode);

/*
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/include/asm/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ else \

#define VDSO_ENTRY \
((unsigned long)current->mm->context.vdso + \
selected_vdso32->sym___kernel_vsyscall)
vdso_image_32.sym___kernel_vsyscall)

struct linux_binprm;

Expand Down
9 changes: 1 addition & 8 deletions arch/x86/include/asm/vdso.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ struct vdso_image {
long sym___kernel_sigreturn;
long sym___kernel_rt_sigreturn;
long sym___kernel_vsyscall;
long sym_VDSO32_SYSENTER_RETURN;
};

#ifdef CONFIG_X86_64
Expand All @@ -38,13 +37,7 @@ extern const struct vdso_image vdso_image_x32;
#endif

#if defined CONFIG_X86_32 || defined CONFIG_COMPAT
extern const struct vdso_image vdso_image_32_int80;
#ifdef CONFIG_COMPAT
extern const struct vdso_image vdso_image_32_syscall;
#endif
extern const struct vdso_image vdso_image_32_sysenter;

extern const struct vdso_image *selected_vdso32;
extern const struct vdso_image vdso_image_32;
#endif

extern void __init init_vdso_image(const struct vdso_image *image);
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ __setup_frame(int sig, struct ksignal *ksig, sigset_t *set,

if (current->mm->context.vdso)
restorer = current->mm->context.vdso +
selected_vdso32->sym___kernel_sigreturn;
vdso_image_32.sym___kernel_sigreturn;
else
restorer = &frame->retcode;
if (ksig->ka.sa.sa_flags & SA_RESTORER)
Expand Down Expand Up @@ -363,7 +363,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,

/* Set up to return from userspace. */
restorer = current->mm->context.vdso +
selected_vdso32->sym___kernel_rt_sigreturn;
vdso_image_32.sym___kernel_rt_sigreturn;
if (ksig->ka.sa.sa_flags & SA_RESTORER)
restorer = ksig->ka.sa.sa_restorer;
put_user_ex(restorer, &frame->pretcode);
Expand Down
Loading

0 comments on commit 0a6d1fa

Please sign in to comment.