The following patches do a bunch of cleanup and rejiggering to the x86 vDSO implementation, but don't change any actual code in the routines in the vDSO. They consolidate the 32-bit vDSO code and support for it between i386 and x86_64/ia32. This makes them behave the same where they didn't before (placement), and reduces a lot of duplication. They simplify the magic for tracking addresses inside the vDSO, which makes it possible to remove the fragile kludges in the layout of the vDSO images. They consolidate the layout details and build logic for 64-bit and 32-bit vDSOs. Most of these patches require the earlier ones in the series, and mostly in this order. Patch 17 is optional without upsetting the others, and is the only one that changes anything users might see in 32-bit processes (aside from x86_64 behaving more like real i386). It changes the code addresses inside the vDSO, commonly seen in backtraces. Nothing should care, but anything that had previously hard-coded the expected low 0xfff bits of those addresses could be wrong now (e.g. tests that check for verbatim backtrace output including __kernel_* addresses). There are several renames in here, so GIT can apply them but maybe patch can't. (If there is a switch to git-format-patch to produce something more universally applicable, I haven't found it.) Thanks, Roland -
This patch adds a new way of extracting symbols from the built vDSO image.
This is much simpler and less fragile than using ld -R; it removes the
need to control the DSO layout quite so exactly. I was clearly unduly
distracted by clever ld uses when I did the original vDSO implementation.
Signed-off-by: Roland McGrath <roland@redhat.com>
---
arch/x86/vdso/Makefile | 14 ++++++++++++++
arch/x86/vdso/vdso.lds.S | 10 ++++++++++
2 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile
index e7bff0f..d8200ad 100644
--- a/arch/x86/vdso/Makefile
+++ b/arch/x86/vdso/Makefile
@@ -55,6 +55,20 @@ SYSCFLAGS_vdso-syms.o = -r -d
$(obj)/vdso-syms.o: $(src)/vdso.lds $(vobjs) FORCE
$(call if_changed,syscall)
+targets += vdso-syms.lds
+obj-y += vdso-syms.lds
+
+#
+# Match symbols in the DSO that look like VDSO*; produce a file of constants.
+#
+sed-vdsosym := -e 's/^00*/0/' \
+ -e 's/^\([0-9a-fA-F]*\) . \(VDSO[a-zA-Z0-9_]*\)$$/\2 = 0x\1;/p'
+quiet_cmd_vdsosym = VDSOSYM $@
+ cmd_vdsosym = $(NM) $< | sed -n $(sed-vdsosym) | LC_ALL=C sort > $@
+
+$(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE
+ $(call if_changed,vdsosym)
+
quiet_cmd_vdso_install = INSTALL $@
cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
vdso.so:
diff --git a/arch/x86/vdso/vdso.lds.S b/arch/x86/vdso/vdso.lds.S
index 667d324..d40d0e9 100644
--- a/arch/x86/vdso/vdso.lds.S
+++ b/arch/x86/vdso/vdso.lds.S
@@ -8,6 +8,16 @@
#define VDSO_PRELINK 0xffffffffff700000
+/*
+ * Symbols we define here called VDSO* get their values into vdso-syms.lds
+ * and become visible to the kernel itself.
+ */
+VDSO64_PRELINK = VDSO_PRELINK;
+
+#define VEXTERN(x) VDSO64_ ## x = vdso_ ## x;
+#include "vextern.h"
+#undef VEXTERN
+
SECTIONS
{
. = VDSO_PRELINK + SIZEOF_HEADERS;
-
Get rid of vdso-syms.o from the kernel link. We don't need it any more. Signed-off-by: Roland McGrath <roland@redhat.com> --- arch/x86/vdso/Makefile | 15 ++------------- 1 files changed, 2 insertions(+), 13 deletions(-) diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile index d2ec170..6a665dd 100644 --- a/arch/x86/vdso/Makefile +++ b/arch/x86/vdso/Makefile @@ -6,13 +6,13 @@ vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o vvar.o # files to link into kernel -obj-y := vma.o vdso.o vdso-syms.o +obj-y := vma.o vdso.o vobjs := $(foreach F,$(vobjs-y),$(obj)/$F) $(obj)/vdso.o: $(obj)/vdso.so -targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y) vdso-syms.o +targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y) # The DSO images are built using a special linker script. quiet_cmd_syscall = SYSCALL $@ @@ -43,17 +43,6 @@ CFL := $(PROFILING) -mcmodel=small -fPIC -g0 -O2 -fasynchronous-unwind-tables -m $(obj)/vclock_gettime.o: KBUILD_CFLAGS = $(CFL) $(obj)/vgetcpu.o: KBUILD_CFLAGS = $(CFL) -# We also create a special relocatable object that should mirror the symbol -# table and layout of the linked DSO. With ld -R we can then refer to -# these symbols in the kernel code rather than hand-coded addresses. -extra-y += vdso-syms.o -$(obj)/built-in.o: $(obj)/vdso-syms.o -$(obj)/built-in.o: ld_flags += -R $(obj)/vdso-syms.o - -SYSCFLAGS_vdso-syms.o = -r -d -$(obj)/vdso-syms.o: $(src)/vdso.lds $(vobjs) FORCE - $(call if_changed,syscall) - targets += vdso-syms.lds obj-y += vdso-syms.lds -
This change harmonizes the asm-offsets macros used in the 32-bit vDSO
across 32-bit and 64-bit builds. It's a purely cosmetic change for now,
but it paves the way for consolidating the 32-bit vDSO builds.
Signed-off-by: Roland McGrath <roland@redhat.com>
---
arch/x86/kernel/asm-offsets_32.c | 20 ++++++------
arch/x86/kernel/vsyscall-sigreturn_32.S | 54 +++++++++++++++---------------
2 files changed, 37 insertions(+), 37 deletions(-)
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
index 0e45981..c578a2b 100644
--- a/arch/x86/kernel/asm-offsets_32.c
+++ b/arch/x86/kernel/asm-offsets_32.c
@@ -38,15 +38,15 @@ void foo(void);
void foo(void)
{
- OFFSET(SIGCONTEXT_eax, sigcontext, eax);
- OFFSET(SIGCONTEXT_ebx, sigcontext, ebx);
- OFFSET(SIGCONTEXT_ecx, sigcontext, ecx);
- OFFSET(SIGCONTEXT_edx, sigcontext, edx);
- OFFSET(SIGCONTEXT_esi, sigcontext, esi);
- OFFSET(SIGCONTEXT_edi, sigcontext, edi);
- OFFSET(SIGCONTEXT_ebp, sigcontext, ebp);
- OFFSET(SIGCONTEXT_esp, sigcontext, esp);
- OFFSET(SIGCONTEXT_eip, sigcontext, eip);
+ OFFSET(IA32_SIGCONTEXT_eax, sigcontext, eax);
+ OFFSET(IA32_SIGCONTEXT_ebx, sigcontext, ebx);
+ OFFSET(IA32_SIGCONTEXT_ecx, sigcontext, ecx);
+ OFFSET(IA32_SIGCONTEXT_edx, sigcontext, edx);
+ OFFSET(IA32_SIGCONTEXT_esi, sigcontext, esi);
+ OFFSET(IA32_SIGCONTEXT_edi, sigcontext, edi);
+ OFFSET(IA32_SIGCONTEXT_ebp, sigcontext, ebp);
+ OFFSET(IA32_SIGCONTEXT_esp, sigcontext, esp);
+ OFFSET(IA32_SIGCONTEXT_eip, sigcontext, eip);
BLANK();
OFFSET(CPUINFO_x86, cpuinfo_x86, x86);
@@ -94,7 +94,7 @@ void foo(void)
BLANK();
OFFSET(EXEC_DOMAIN_handler, exec_domain, handler);
- OFFSET(RT_SIGFRAME_sigcontext, rt_sigframe, uc.uc_mcontext);
+ OFFSET(IA32_RT_SIGFRAME_sigcontext, rt_sigframe, uc.uc_mcontext);
BLANK();
OFFSET(pbe_address, pbe, address);
diff --git a/arch/x86/kernel/vsyscall-sigreturn_32.S b/arch/x86/kernel/vsyscall-sigreturn_32.S
index a92262f..e939253 100644
--- ...This revamps the vDSO linker script to lay things out with the best
packing of the data and good, separate alignment of the code. The
rigid layout using VDSO_TEXT_OFFSET no longer matters to the kernel.
I've moved the layout parts of the linker script into a new include
file, vdso-layout.lds.S; this is in preparation for sharing the script
for the 32-bit vDSO builds too.
Signed-off-by: Roland McGrath <roland@redhat.com>
---
arch/x86/vdso/vdso-layout.lds.S | 64 ++++++++++++++++++++++++
arch/x86/vdso/vdso.lds.S | 102 ++++++++++-----------------------------
arch/x86/vdso/voffset.h | 1 -
3 files changed, 89 insertions(+), 78 deletions(-)
create mode 100644 arch/x86/vdso/vdso-layout.lds.S
delete mode 100644 arch/x86/vdso/voffset.h
diff --git a/arch/x86/vdso/vdso-layout.lds.S b/arch/x86/vdso/vdso-layout.lds.S
new file mode 100644
index 0000000..634a2cf
--- /dev/null
+++ b/arch/x86/vdso/vdso-layout.lds.S
@@ -0,0 +1,64 @@
+/*
+ * Linker script for vDSO. This is an ELF shared object prelinked to
+ * its virtual address, and with only one read-only segment.
+ * This script controls its layout.
+ */
+
+SECTIONS
+{
+ . = VDSO_PRELINK + SIZEOF_HEADERS;
+
+ .hash : { *(.hash) } :text
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+
+ .note : { *(.note.*) } :text :note
+
+ .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
+ .eh_frame : { KEEP (*(.eh_frame)) } :text
+
+ .dynamic : { *(.dynamic) } :text :dynamic
+
+ .rodata : { *(.rodata*) } :text
+ .data : {
+ *(.data*)
+ *(.sdata*)
+ *(.got.plt) *(.got)
+ *(.gnu.linkonce.d.*)
+ *(.bss*)
+ *(.dynbss*)
+ *(.gnu.linkonce.b.*)
+ }
+
+ .altinstructions : { *(.altinstructions) }
+ .altinstr_replacement : { *(.altinstr_replacement) }
+
+ /*
+ * Align the actual code well ...This moves the i386 vDSO sources into arch/x86/vdso/vdso32/, a
new directory. This patch is a pure renaming, but paves the way
for consolidating the vDSO build logic.
Signed-off-by: Roland McGrath <roland@redhat.com>
---
arch/x86/ia32/vsyscall-sigreturn.S | 3 +--
arch/x86/kernel/Makefile_32 | 3 +++
.../vsyscall-int80_32.S => vdso/vdso32/int80.S} | 2 +-
.../vsyscall-note_32.S => vdso/vdso32/note.S} | 2 +-
.../vdso32/sigreturn.S} | 0
.../vdso32/sysenter.S} | 2 +-
6 files changed, 7 insertions(+), 5 deletions(-)
rename arch/x86/{kernel/vsyscall-int80_32.S => vdso/vdso32/int80.S} (97%)
rename arch/x86/{kernel/vsyscall-note_32.S => vdso/vdso32/note.S} (95%)
rename arch/x86/{kernel/vsyscall-sigreturn_32.S => vdso/vdso32/sigreturn.S} (100%)
rename arch/x86/{kernel/vsyscall-sysenter_32.S => vdso/vdso32/sysenter.S} (99%)
diff --git a/arch/x86/ia32/vsyscall-sigreturn.S b/arch/x86/ia32/vsyscall-sigreturn.S
index b383be0..295eecf 100644
--- a/arch/x86/ia32/vsyscall-sigreturn.S
+++ b/arch/x86/ia32/vsyscall-sigreturn.S
@@ -139,5 +139,4 @@ __kernel_rt_sigreturn:
.align 4
.LENDFDE3:
-#include "../../x86/kernel/vsyscall-note_32.S"
-
+#include "../vdso/vdso32/note.S"
diff --git a/arch/x86/kernel/Makefile_32 b/arch/x86/kernel/Makefile_32
index a7bc93c..7791895 100644
--- a/arch/x86/kernel/Makefile_32
+++ b/arch/x86/kernel/Makefile_32
@@ -56,6 +56,9 @@ $(obj)/vsyscall_32.o: $(obj)/vsyscall-int80_32.so $(obj)/vsyscall-sysenter_32.so
targets += $(foreach F,int80 sysenter,vsyscall-$F_32.o vsyscall-$F_32.so)
targets += vsyscall-note_32.o vsyscall_32.lds
+$(obj)/vsyscall-%_32.o: $(src)/../vdso/vdso32/%.S
+ $(call if_changed_dep,as_o_S)
+
# The DSO images are built using a special linker script.
quiet_cmd_syscall = SYSCALL $@
cmd_syscall = $(CC) -m elf_i386 -nostdlib $(SYSCFLAGS_$(@F)) \
diff --git a/arch/x86/kernel/vsyscall-int80_32.S ...You don't have to do anything manual. git-apply handles these fine. From my introduction post (00/18): There are several renames in here, so GIT can apply them but maybe patch can't. (If there is a switch to git-format-patch to produce something more universally applicable, I haven't found it.) Thanks, Roland -
Sorry my bad. I skipped that while reading through the series. git
rants are in my builtin "skip this section" regex patterns :)
I do not use git-apply of course.
git format-patch -p
does the trick at least here :)
tglx
-
Ok, I can use that in future. I hope it still means that in the eventual merged state, GIT will be aware of all the renames. Thanks, Roland -
git does not store the "renamed/copied" info at all. That's just an optimization. It does not matter if you use git-mv or just apply a patch which does the same. git figures that out by looking at the changes AFAICT, but not by storing metadata which keeps track of this. Thanks, tglx -
Git doesn't care. You can do renames by hand, or with "git mv", you can do them as a delete/create pair, you can use "git-apply" with a rename patch, and you can do them by re-typing in all of the file contents from scratch. Regardless of how the rename is done, git will represent the data the exact same way: the state of the tree before and after. The rename-patches are a lot denser and a lot more readable for humans (ie you can actually see what *happens*, unlike a traditional stupid unified diff), and I was hoping that eventually somebody in the GNU patch community would see how wonderful the extended patch information is, but when I tried to write a patch to "patch" to do it, I almost dug out my eyes with spoons from looking at the source code, so I haven't actually helped it happen. So you can ask for patches in traditional format (*most* git command lines will default to that anyway, and only give a copy-patch with -C or -M on the command line), or people could realize that "git-apply" actually works even on non-git source code, and just stop using that abomination that is "patch" with all of it's totally wrong and unsafe defaults (*). But whatever works. I'm currently skipping the patches since they didn't seem like 2.6.24 fodder anyway. Linus (*) Let me count the ways: applying patches partially when it fails half-way through a series. Defaulting to totally randomly guessing the path-name skip depth when not explicitly given a -pX option. Defaulting to "--fuzz=2" which is almost guaranteed to apply a patch even when it makes no sense what-so-ever. Yes, git-apply has stricter rules, but they are stricter for damn good reasons. For people who want the insane unsafe GNU patch defaults, they just have to specifically ask for unsafe modes.. -
The vdso cleanups are pure cleanup, not fixing anything that's actively broken. Thanks, Roland -
This builds the 32-bit vDSO images in the arch/x86/vdso subdirectory. Nothing uses the images yet, but this paves the way for consolidating the vDSO build logic all in one place. The new images use a linker script sharing the layout parts from vdso-layout.lds.S with the 64-bit vDSO. A new vdso32-syms.lds is generated in the style of vdso-syms.lds. Signed-off-by: Roland McGrath <roland@redhat.com> --- arch/x86/vdso/Makefile | 76 +++++++++++++++++++++++++++++++++++- arch/x86/vdso/vdso32/vdso32.lds.S | 37 ++++++++++++++++++ 2 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 arch/x86/vdso/vdso32/vdso32.lds.S diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile index 6a665dd..a1e0418 100644 --- a/arch/x86/vdso/Makefile +++ b/arch/x86/vdso/Makefile @@ -1,7 +1,15 @@ # -# x86-64 vDSO. +# Building vDSO images for x86. # +VDSO64-$(CONFIG_X86_64) := y +VDSO32-$(CONFIG_X86_32) := y +VDSO32-$(CONFIG_COMPAT) := y + +vdso-install-$(VDSO64-y) += vdso.so +vdso-install-$(VDSO32-y) += $(vdso32-y:=.so) + + # files to link into the vdso vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o vvar.o @@ -57,10 +65,72 @@ quiet_cmd_vdsosym = VDSOSYM $@ $(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE $(call if_changed,vdsosym) +# +# Build multiple 32-bit vDSO images to choose from at boot time. +# +vdso32.so-$(CONFIG_X86_32) += int80 +vdso32.so-$(VDSO32-y) += sysenter + +CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds) +VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -Wl,-soname=linux-gate.so.1 + +# This makes sure the $(obj) subdirectory exists even though vdso32/ +# is not a kbuild sub-make subdirectory. +override obj-dirs = $(dir $(obj)) $(obj)/vdso32/ + +targets += vdso32/vdso32.lds +targets += $(vdso32.so-y:%=vdso32-%.so.dbg) $(vdso32.so-y:%=vdso32-%.so) +targets += vdso32/note.o $(vdso32.so-y:%=vdso32/%.o) + +extra-y += $(vdso32.so-y:%=vdso32-%.so) + +$(vdso32.so-y:%=$(obj)/vdso32-%.so.dbg): asflags-$(CONFIG_X86_64) += ...
Hi Roland. Some minor things below. In general I like the simplification of this area and having it moved out of kernel/Makefile is the-right-thing. Sam Should we teach kbuild to create dirs specified in targets? use "set -e; in front of this shell script to bail out early Please use $(Q) in preference for @ -
Back when I knew something about make, all commands ran with sh -ec. Ah, progress. Anyway, the one you cited does not have any commands that Using this rule for the 64-bit vDSO is not in this patch. This line is not being changed in this patch, so that is really a separate question. Other places in other Makefiles use @mkdir too, so if you are concerned you could do a patch covering all of those. Thanks, Roland -
I assume that if an error happened in a pipe set -e; would catch it. But I did not check that - I normally just adds set -e; without much thought. Sam -
No, you need set -o pipefail for that (which is a bashism). Thanks, Roland -
This enables 'make vdso_install' for i386 as on x86_64 and powerpc. Signed-off-by: Roland McGrath <roland@redhat.com> --- arch/x86/Makefile_32 | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/arch/x86/Makefile_32 b/arch/x86/Makefile_32 index 99dc511..4c869ef 100644 --- a/arch/x86/Makefile_32 +++ b/arch/x86/Makefile_32 @@ -153,9 +153,13 @@ zdisk bzdisk: vmlinux fdimage fdimage144 fdimage288 isoimage: vmlinux $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@ -install: +install: vdso_install $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install +PHONY += vdso_install +vdso_install: + $(Q)$(MAKE) $(build)=arch/x86/vdso $@ + archclean: $(Q)rm -rf $(objtree)/arch/i386/boot $(Q)$(MAKE) $(clean)=arch/x86/boot -
This moves arch/x86/kernel/sysenter_32.c to arch/x86/vdso/vdso32-setup.c,
keeping all the code relating only to vDSO magic in the vdso/ subdirectory.
This is a pure renaming, but it paves the way to consolidating the code for
dealing with 32-bit vDSOs across CONFIG_X86_32 and CONFIG_IA32_EMULATION.
Signed-off-by: Roland McGrath <roland@redhat.com>
---
arch/x86/kernel/Makefile_32 | 1 -
arch/x86/vdso/Makefile | 2 +-
.../{kernel/sysenter_32.c => vdso/vdso32-setup.c} | 0
3 files changed, 1 insertions(+), 2 deletions(-)
rename arch/x86/{kernel/sysenter_32.c => vdso/vdso32-setup.c} (100%)
diff --git a/arch/x86/kernel/Makefile_32 b/arch/x86/kernel/Makefile_32
index 1ece642..882f164 100644
--- a/arch/x86/kernel/Makefile_32
+++ b/arch/x86/kernel/Makefile_32
@@ -33,7 +33,6 @@ obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
obj-$(CONFIG_X86_SUMMIT_NUMA) += summit_32.o
obj-$(CONFIG_KPROBES) += kprobes_32.o
obj-$(CONFIG_MODULES) += module_32.o
-obj-y += sysenter_32.o
obj-$(CONFIG_ACPI_SRAT) += srat_32.o
obj-$(CONFIG_EFI) += efi_32.o efi_stub_32.o
obj-$(CONFIG_DOUBLEFAULT) += doublefault_32.o
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile
index cabb0c2..9ffd03f 100644
--- a/arch/x86/vdso/Makefile
+++ b/arch/x86/vdso/Makefile
@@ -15,7 +15,7 @@ vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o vvar.o
# files to link into kernel
obj-$(VDSO64-y) += vma.o vdso.o
-obj-$(CONFIG_X86_32) += vdso32.o
+obj-$(CONFIG_X86_32) += vdso32.o vdso32-setup.o
vobjs := $(foreach F,$(vobjs-y),$(obj)/$F)
diff --git a/arch/x86/kernel/sysenter_32.c b/arch/x86/vdso/vdso32-setup.c
similarity index 100%
rename from arch/x86/kernel/sysenter_32.c
rename to arch/x86/vdso/vdso32-setup.c
-
This makes the i386 kernel use the new vDSO build in arch/x86/vdso/vdso32/
to replace the old one from arch/x86/kernel/.
Signed-off-by: Roland McGrath <roland@redhat.com>
---
arch/x86/Makefile_32 | 3 +-
arch/x86/kernel/Makefile_32 | 43 +--------------
arch/x86/kernel/asm-offsets_32.c | 2 -
arch/x86/kernel/signal_32.c | 5 +-
arch/x86/kernel/sysenter_32.c | 6 +-
arch/x86/kernel/vsyscall_32.lds.S | 67 ----------------------
arch/x86/vdso/Makefile | 8 ++-
arch/x86/{kernel/vsyscall_32.S => vdso/vdso32.S} | 4 +-
arch/x86/vdso/vdso32/note.S | 3 +-
arch/x86/vdso/vdso32/sysenter.S | 3 +-
arch/x86/xen/setup.c | 5 +-
include/asm-x86/elf.h | 13 +---
include/asm-x86/vdso.h | 14 +++++
13 files changed, 37 insertions(+), 139 deletions(-)
delete mode 100644 arch/x86/kernel/vsyscall_32.lds.S
rename arch/x86/{kernel/vsyscall_32.S => vdso/vdso32.S} (70%)
diff --git a/arch/x86/Makefile_32 b/arch/x86/Makefile_32
index 50394da..99dc511 100644
--- a/arch/x86/Makefile_32
+++ b/arch/x86/Makefile_32
@@ -114,7 +114,8 @@ libs-y += arch/x86/lib/
core-y += arch/x86/kernel/ \
arch/x86/mm/ \
$(mcore-y)/ \
- arch/x86/crypto/
+ arch/x86/crypto/ \
+ arch/x86/vdso/
drivers-$(CONFIG_MATH_EMULATION) += arch/x86/math-emu/
drivers-$(CONFIG_PCI) += arch/x86/pci/
# must be linked after kernel/
diff --git a/arch/x86/kernel/Makefile_32 b/arch/x86/kernel/Makefile_32
index 7791895..1ece642 100644
--- a/arch/x86/kernel/Makefile_32
+++ b/arch/x86/kernel/Makefile_32
@@ -33,7 +33,7 @@ obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
obj-$(CONFIG_X86_SUMMIT_NUMA) += summit_32.o
obj-$(CONFIG_KPROBES) += kprobes_32.o
obj-$(CONFIG_MODULES) += ...This harmonizes the name for the entry point from the 32-bit sysenter
instruction across 32-bit and 64-bit kernels.
Signed-off-by: Roland McGrath <roland@redhat.com>
---
arch/x86/kernel/entry_32.S | 10 +++++-----
arch/x86/vdso/vdso32-setup.c | 4 ++--
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index dc7f938..388786c 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -283,7 +283,7 @@ END(resume_kernel)
the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */
# sysenter call handler stub
-ENTRY(sysenter_entry)
+ENTRY(ia32_sysenter_target)
CFI_STARTPROC simple
CFI_SIGNAL_FRAME
CFI_DEF_CFA esp, 0
@@ -360,7 +360,7 @@ sysenter_past_esp:
.align 4
.long 1b,2b
.popsection
-ENDPROC(sysenter_entry)
+ENDPROC(ia32_sysenter_target)
# system call handler stub
ENTRY(system_call)
@@ -768,7 +768,7 @@ label: \
KPROBE_ENTRY(debug)
RING0_INT_FRAME
- cmpl $sysenter_entry,(%esp)
+ cmpl $ia32_sysenter_target,(%esp)
jne debug_stack_correct
FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
debug_stack_correct:
@@ -799,7 +799,7 @@ KPROBE_ENTRY(nmi)
popl %eax
CFI_ADJUST_CFA_OFFSET -4
je nmi_espfix_stack
- cmpl $sysenter_entry,(%esp)
+ cmpl $ia32_sysenter_target,(%esp)
je nmi_stack_fixup
pushl %eax
CFI_ADJUST_CFA_OFFSET 4
@@ -812,7 +812,7 @@ KPROBE_ENTRY(nmi)
popl %eax
CFI_ADJUST_CFA_OFFSET -4
jae nmi_stack_correct
- cmpl $sysenter_entry,12(%esp)
+ cmpl $ia32_sysenter_target,12(%esp)
je nmi_debug_stack_check
nmi_stack_correct:
/* We have a RING0_INT_FRAME here */
diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c
index 85c52d2..fb71a93 100644
--- a/arch/x86/vdso/vdso32-setup.c
+++ b/arch/x86/vdso/vdso32-setup.c
@@ -54,7 +54,7 @@ static int __init vdso_setup(char *s)
__setup("vdso=", vdso_setup);
-extern asmlinkage void sysenter_entry(void);
+extern ...This changes the 64-bit kernel's support for the 32-bit sysenter instruction to use stored fields rather than constants for the user-mode return address, as the 32-bit kernel does. This adds a sysenter_return field to struct thread_info, as 32-bit has. There is no observable effect from this yet. It makes the assembly code independent of the 32-bit vDSO mapping address, paving the way for making the vDSO address vary as it does on the 32-bit kernel. Signed-off-by: Roland McGrath <roland@redhat.com> --- arch/x86/ia32/ia32entry.S | 7 +++---- arch/x86/ia32/syscall32.c | 4 ++++ arch/x86/kernel/asm-offsets_64.c | 1 + include/asm-x86/thread_info_64.h | 3 +++ 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index df588f0..2499a32 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -12,7 +12,6 @@ #include <asm/ia32_unistd.h> #include <asm/thread_info.h> #include <asm/segment.h> -#include <asm/vsyscall32.h> #include <asm/irqflags.h> #include <linux/linkage.h> @@ -104,7 +103,7 @@ ENTRY(ia32_sysenter_target) pushfq CFI_ADJUST_CFA_OFFSET 8 /*CFI_REL_OFFSET rflags,0*/ - movl $VSYSCALL32_SYSEXIT, %r10d + movl 8*3-THREAD_SIZE+threadinfo_sysenter_return(%rsp), %r10d CFI_REGISTER rip,r10 pushq $__USER32_CS CFI_ADJUST_CFA_OFFSET 8 @@ -142,6 +141,8 @@ sysenter_do_call: andl $~TS_COMPAT,threadinfo_status(%r10) /* clear IF, that popfq doesn't enable interrupts early */ andl $~0x200,EFLAGS-R11(%rsp) + movl RIP-R11(%rsp),%edx /* User %eip */ + CFI_REGISTER rip,rdx RESTORE_ARGS 1,24,1,1,1,1 popfq CFI_ADJUST_CFA_OFFSET -8 @@ -149,8 +150,6 @@ sysenter_do_call: popq %rcx /* User %esp */ CFI_ADJUST_CFA_OFFSET -8 CFI_REGISTER rsp,rcx - movl $VSYSCALL32_SYSEXIT,%edx /* User %eip */ - CFI_REGISTER rip,rdx TRACE_IRQS_ON swapgs sti /* sti only takes effect after the next instruction */ diff --git ...
I hope you won't carry the dependency of COMPAT_VDSO over to 64-bit when 8*3-THREAD_SIZE is not very intuitive. Can you add a comment on the math? Zach -
When you are reading the whole stretch of code right there, and not just the patch, it's fairly obvious that it matches the three pushes right there. Thanks, Roland -
This cleans up the arch/x86/vdso/Makefile rules for vdso.so to share more code with the vdso32-*.so rules and remove old cruft. Signed-off-by: Roland McGrath <roland@redhat.com> --- arch/x86/vdso/Makefile | 19 ++++--------------- 1 files changed, 4 insertions(+), 15 deletions(-) diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile index 53f36bc..2d5bbbe 100644 --- a/arch/x86/vdso/Makefile +++ b/arch/x86/vdso/Makefile @@ -23,25 +23,15 @@ $(obj)/vdso.o: $(obj)/vdso.so targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y) -# The DSO images are built using a special linker script. -quiet_cmd_syscall = SYSCALL $@ - cmd_syscall = $(CC) -m elf_x86_64 -nostdlib $(SYSCFLAGS_$(@F)) \ - -Wl,-T,$(filter-out FORCE,$^) -o $@ - export CPPFLAGS_vdso.lds += -P -C -vdso-flags = -fPIC -shared -Wl,-soname=linux-vdso.so.1 \ - $(call ld-option, -Wl$(comma)--hash-style=sysv) \ - -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 -SYSCFLAGS_vdso.so = $(vdso-flags) -SYSCFLAGS_vdso.so.dbg = $(vdso-flags) +VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -Wl,-soname=linux-vdso.so.1 \ + -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 $(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so -$(obj)/vdso.so: $(src)/vdso.lds $(vobjs) FORCE - $(obj)/vdso.so.dbg: $(src)/vdso.lds $(vobjs) FORCE - $(call if_changed,syscall) + $(call if_changed,vdso) $(obj)/%.so: OBJCOPYFLAGS := -S $(obj)/%.so: $(obj)/%.so.dbg FORCE @@ -49,8 +39,7 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE CFL := $(PROFILING) -mcmodel=small -fPIC -g0 -O2 -fasynchronous-unwind-tables -m64 -$(obj)/vclock_gettime.o: KBUILD_CFLAGS = $(CFL) -$(obj)/vgetcpu.o: KBUILD_CFLAGS = $(CFL) +$(vobjs): KBUILD_CFLAGS = $(CFL) targets += vdso-syms.lds obj-$(VDSO64-y) += vdso-syms.lds -
This puts the syscall version of the 32-bit vDSO in arch/x86/vdso/vdso32/
for 64-bit IA32 support. This is not used yet, but it paves the way for
consolidating the 32-bit vDSO source and build logic all in one place.
Signed-off-by: Roland McGrath <roland@redhat.com>
---
arch/x86/vdso/Makefile | 1 +
arch/x86/vdso/vdso32/sigreturn.S | 9 +++--
arch/x86/vdso/vdso32/syscall.S | 69 ++++++++++++++++++++++++++++++++++++++
3 files changed, 76 insertions(+), 3 deletions(-)
create mode 100644 arch/x86/vdso/vdso32/syscall.S
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile
index 9ffd03f..64e4f47 100644
--- a/arch/x86/vdso/Makefile
+++ b/arch/x86/vdso/Makefile
@@ -71,6 +71,7 @@ $(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE
#
obj-$(VDSO32-y) += vdso32-syms.lds
vdso32.so-$(CONFIG_X86_32) += int80
+vdso32.so-$(CONFIG_COMPAT) += syscall
vdso32.so-$(VDSO32-y) += sysenter
CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds)
diff --git a/arch/x86/vdso/vdso32/sigreturn.S b/arch/x86/vdso/vdso32/sigreturn.S
index e939253..f222889 100644
--- a/arch/x86/vdso/vdso32/sigreturn.S
+++ b/arch/x86/vdso/vdso32/sigreturn.S
@@ -6,9 +6,12 @@
* routines are constant for all vsyscall implementations.
*/
-#include <asm/unistd.h>
+#include <asm/unistd_32.h>
#include <asm/asm-offsets.h>
+#ifndef SYSCALL_ENTER_KERNEL
+#define SYSCALL_ENTER_KERNEL int $0x80
+#endif
/* XXX
Should these be named "_sigtramp" or something?
@@ -22,7 +25,7 @@ __kernel_sigreturn:
.LSTART_sigreturn:
popl %eax /* XXX does this mean it needs unwind info? */
movl $__NR_sigreturn, %eax
- int $0x80
+ SYSCALL_ENTER_KERNEL
.LEND_sigreturn:
.size __kernel_sigreturn,.-.LSTART_sigreturn
@@ -32,7 +35,7 @@ __kernel_sigreturn:
__kernel_rt_sigreturn:
.LSTART_rt_sigreturn:
movl $__NR_rt_sigreturn, %eax
- int $0x80
+ SYSCALL_ENTER_KERNEL
.LEND_rt_sigreturn:
.size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn
.balign 32
diff --git a/arch/x86/vdso/vdso32/syscall.S ...This makes x86_64's ia32 emulation support share the sources used in the 32-bit kernel for the 32-bit vDSO and much of its setup code. The 32-bit vDSO mapping now behaves the same on x86_64 as on native 32-bit. The abi.syscall32 sysctl on x86_64 now takes the same values that vm.vdso_enabled takes on the 32-bit kernel. That is, 1 means a randomized vDSO location, 2 means the fixed old address. The CONFIG_COMPAT_VDSO option is now available to make this the default setting, the same meaning it has for the 32-bit kernel. (This does not affect the 64-bit vDSO.) The argument vdso32=[012] can be used on both 32-bit and 64-bit kernels to set this paramter at boot time. The vdso=[012] argument still does this same thing on the 32-bit kernel. Signed-off-by: Roland McGrath <roland@redhat.com> --- Documentation/kernel-parameters.txt | 5 ++ arch/x86/Kconfig | 4 +- arch/x86/ia32/Makefile | 2 +- arch/x86/ia32/ia32_binfmt.c | 9 +-- arch/x86/ia32/ia32_signal.c | 8 ++- arch/x86/vdso/Makefile | 2 +- arch/x86/vdso/vdso32-setup.c | 119 +++++++++++++++++++++++++++-------- arch/x86/vdso/vdso32.S | 16 +++-- arch/x86/xen/setup.c | 4 +- include/asm-x86/elf.h | 23 ++++--- 10 files changed, 137 insertions(+), 55 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 33121d6..2374e37 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1951,6 +1951,11 @@ and is between 256 and 4096 characters. It is defined in the file vdso=1: enable VDSO (default) vdso=0: disable VDSO mapping + vdso32= [X86-32,X86-64] + vdso32=2: enable compat VDSO (default with COMPAT_VDSO) + vdso32=1: enable 32-bit VDSO (default) + vdso32=0: disable 32-bit VDSO mapping + vector= [IA-64,SMP] vector=percpu: enable percpu vector domain diff --git ...
I think you should drop CONFIG_COMPAT_VDSO support for 32-bit VDSO on 64-bit kernel. This was only to hack around a broken version of glibc that shipped with SUSE PRO 9.0, which had broken assertions based on misinterpretation of ELF fields. 64-bit machines will never see this glibc and the hack can die. Perhaps it is finally time to remove the hack from 32-bit as well, and eliminate COMPAT_VDSO entirely? Or does it really have to live forever. Zach -
we can phase it out, via the Documentation/feature-removal-schedule.txt mechanism. Ingo -
This reorders the code in the 32-bit vDSO images to put the signal trampolines first and __kernel_vsyscall after them. The order does not matter to userland, it just uses what AT_SYSINFO or e_entry says. Since the signal trampolines are the same size in both versions of the vDSO, putting them first is the simplest way to get the addresses to line up. This makes it work to use a more compact layout for the vDSO. Signed-off-by: Roland McGrath <roland@redhat.com> --- arch/x86/vdso/vdso32/int80.S | 15 +++++---------- arch/x86/vdso/vdso32/sigreturn.S | 20 +++++++++----------- arch/x86/vdso/vdso32/syscall.S | 15 +++++++-------- arch/x86/vdso/vdso32/sysenter.S | 17 ++++++----------- 4 files changed, 27 insertions(+), 40 deletions(-) diff --git a/arch/x86/vdso/vdso32/int80.S b/arch/x86/vdso/vdso32/int80.S index 3c8e4c6..9d382c9 100644 --- a/arch/x86/vdso/vdso32/int80.S +++ b/arch/x86/vdso/vdso32/int80.S @@ -1,15 +1,15 @@ /* - * Code for the vsyscall page. This version uses the old int $0x80 method. + * Code for the vDSO. This version uses the old int $0x80 method. * - * NOTE: - * 1) __kernel_vsyscall _must_ be first in this page. - * 2) there are alignment constraints on this stub, see vsyscall-sigreturn.S - * for details. + * First get the common code for the sigreturn entry points. + * This must come first. */ +#include "sigreturn.S" .text .globl __kernel_vsyscall .type __kernel_vsyscall,@function + ALIGN __kernel_vsyscall: .LSTART_vsyscall: int $0x80 @@ -46,8 +46,3 @@ __kernel_vsyscall: .align 4 .LENDFDEDLSI: .previous - -/* - * Get the common code for the sigreturn entry points. - */ -#include "sigreturn.S" diff --git a/arch/x86/vdso/vdso32/sigreturn.S b/arch/x86/vdso/vdso32/sigreturn.S index f222889..0c1a606 100644 --- a/arch/x86/vdso/vdso32/sigreturn.S +++ b/arch/x86/vdso/vdso32/sigreturn.S @@ -1,11 +1,12 @@ /* - * Common code for the sigreturn entry points on the vsyscall page. + * Common code for ...
This removes all the old vsyscall code from arch/x86/ia32/ that is no longer used because arch/x86/vdso/ code has replaced it. Signed-off-by: Roland McGrath <roland@redhat.com> --- arch/x86/Makefile_64 | 3 - arch/x86/ia32/Makefile | 37 --------- arch/x86/ia32/syscall32.c | 87 ---------------------- arch/x86/ia32/syscall32_syscall.S | 17 ---- arch/x86/ia32/vsyscall-sigreturn.S | 142 ------------------------------------ arch/x86/ia32/vsyscall-syscall.S | 69 ----------------- arch/x86/ia32/vsyscall-sysenter.S | 95 ------------------------ arch/x86/ia32/vsyscall.lds | 80 -------------------- include/asm-x86/Kbuild | 1 - include/asm-x86/vsyscall32.h | 20 ----- 10 files changed, 0 insertions(+), 551 deletions(-) delete mode 100644 arch/x86/ia32/syscall32.c delete mode 100644 arch/x86/ia32/syscall32_syscall.S delete mode 100644 arch/x86/ia32/vsyscall-sigreturn.S delete mode 100644 arch/x86/ia32/vsyscall-syscall.S delete mode 100644 arch/x86/ia32/vsyscall-sysenter.S delete mode 100644 arch/x86/ia32/vsyscall.lds delete mode 100644 include/asm-x86/vsyscall32.h diff --git a/arch/x86/Makefile_64 b/arch/x86/Makefile_64 index a804860..d12bb14 100644 --- a/arch/x86/Makefile_64 +++ b/arch/x86/Makefile_64 @@ -117,9 +117,6 @@ install: vdso_install $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@ vdso_install: -ifeq ($(CONFIG_IA32_EMULATION),y) - $(Q)$(MAKE) $(build)=arch/x86/ia32 $@ -endif $(Q)$(MAKE) $(build)=arch/x86/vdso $@ archclean: diff --git a/arch/x86/ia32/Makefile b/arch/x86/ia32/Makefile index 9abb0db..bf91690 100644 --- a/arch/x86/ia32/Makefile +++ b/arch/x86/ia32/Makefile @@ -13,40 +13,3 @@ obj-$(CONFIG_IA32_AOUT) += ia32_aout.o audit-class-$(CONFIG_AUDIT) := audit.o obj-$(CONFIG_IA32_EMULATION) += $(audit-class-y) - -$(obj)/syscall32_syscall.o: \ - $(foreach F,sysenter syscall,$(obj)/vsyscall-$F.so) - -# Teach kbuild about ...
