2007-11-19 21:59:59

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 00/18] x86 vDSO revamp

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


2007-11-19 22:01:32

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 01/18] x86 vDSO: generate vdso-syms.lds


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 <[email protected]>
---
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)/[email protected] $(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;

2007-11-19 22:02:21

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 02/18] x86 vDSO: use vdso-syms.lds


This patch changes the kernel's references to addresses in the vDSO image
to be based on the symbols defined by vdso-syms.lds instead of the old
vdso-syms.o symbols. This is all wrapped up in a macro defined by the new
asm-x86/vdso.h header; that's the only place in the kernel source that has
to know the details of the scheme for getting vDSO symbol values.

Signed-off-by: Roland McGrath <[email protected]>
---
arch/x86/vdso/Makefile | 3 +--
arch/x86/vdso/vdso-start.S | 2 --
arch/x86/vdso/vma.c | 18 +++++++-----------
include/asm-x86/vdso.h | 14 ++++++++++++++
4 files changed, 22 insertions(+), 15 deletions(-)
delete mode 100644 arch/x86/vdso/vdso-start.S
create mode 100644 include/asm-x86/vdso.h

diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile
index d8200ad..d2ec170 100644
--- a/arch/x86/vdso/Makefile
+++ b/arch/x86/vdso/Makefile
@@ -3,8 +3,7 @@
#

# files to link into the vdso
-# vdso-start.o has to be first
-vobjs-y := vdso-start.o vdso-note.o vclock_gettime.o vgetcpu.o vvar.o
+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
diff --git a/arch/x86/vdso/vdso-start.S b/arch/x86/vdso/vdso-start.S
deleted file mode 100644
index 2dc2cdb..0000000
--- a/arch/x86/vdso/vdso-start.S
+++ /dev/null
@@ -1,2 +0,0 @@
- .globl vdso_kernel_start
-vdso_kernel_start:
diff --git a/arch/x86/vdso/vma.c b/arch/x86/vdso/vma.c
index ff9333e..3fdd514 100644
--- a/arch/x86/vdso/vma.c
+++ b/arch/x86/vdso/vma.c
@@ -11,23 +11,20 @@
#include <asm/vsyscall.h>
#include <asm/vgtod.h>
#include <asm/proto.h>
-#include "voffset.h"
+#include <asm/vdso.h>

-int vdso_enabled = 1;
-
-#define VEXTERN(x) extern typeof(__ ## x) *vdso_ ## x;
-#include "vextern.h"
+#include "vextern.h" /* Just for VMAGIC. */
#undef VEXTERN

-extern char vdso_kernel_start[], vdso_start[], vdso_end[];
+int vdso_enabled = 1;
+
+extern char vdso_start[], vdso_end[];
extern unsigned short vdso_sync_cpuid;

struct page **vdso_pages;

-static inline void *var_ref(void *vbase, char *var, char *name)
+static inline void *var_ref(void *p, char *name)
{
- unsigned offset = var - &vdso_kernel_start[0] + VDSO_TEXT_OFFSET;
- void *p = vbase + offset;
if (*(void **)p != (void *)VMAGIC) {
printk("VDSO: variable %s broken\n", name);
vdso_enabled = 0;
@@ -62,9 +59,8 @@ static int __init init_vdso_vars(void)
vdso_enabled = 0;
}

-#define V(x) *(typeof(x) *) var_ref(vbase, (char *)RELOC_HIDE(&x, 0), #x)
#define VEXTERN(x) \
- V(vdso_ ## x) = &__ ## x;
+ *(typeof(__ ## x) **) var_ref(VDSO64_SYMBOL(vbase, x), #x) = &__ ## x;
#include "vextern.h"
#undef VEXTERN
return 0;
diff --git a/include/asm-x86/vdso.h b/include/asm-x86/vdso.h
new file mode 100644
index 0000000..9379ec0
--- /dev/null
+++ b/include/asm-x86/vdso.h
@@ -0,0 +1,14 @@
+#ifndef _ASM_X86_VDSO_H
+#define _ASM_X86_VDSO_H 1
+
+extern const char VDSO64_PRELINK[];
+
+/*
+ * Given a pointer to the vDSO image, find the pointer to VDSO64_name
+ * as that symbol is defined in the vDSO sources or linker script.
+ */
+#define VDSO64_SYMBOL(base, name) ({ \
+ extern const char VDSO64_##name[]; \
+ (void *) (VDSO64_##name - VDSO64_PRELINK + (unsigned long) (base)); })
+
+#endif /* asm-x86/vdso.h */

2007-11-19 22:03:13

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 03/18] x86 vDSO: remove vdso-syms.o


Get rid of vdso-syms.o from the kernel link. We don't need it any more.

Signed-off-by: Roland McGrath <[email protected]>
---
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

2007-11-19 22:04:29

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 04/18] x86 vDSO: new layout


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 <[email protected]>
---
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 away from the non-instruction data.
+ * This is the best thing for the I-cache.
+ */
+ . = ALIGN(0x100);
+
+ .text : { *(.text*) } :text =0x90909090
+}
+
+/*
+ * Very old versions of ld do not recognize this name token; use the constant.
+ */
+#define PT_GNU_EH_FRAME 0x6474e550
+
+/*
+ * We must supply the ELF program headers explicitly to get just one
+ * PT_LOAD segment, and set the flags explicitly to make segments read-only.
+ */
+PHDRS
+{
+ text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
+ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
+ note PT_NOTE FLAGS(4); /* PF_R */
+ eh_frame_hdr PT_GNU_EH_FRAME;
+}
diff --git a/arch/x86/vdso/vdso.lds.S b/arch/x86/vdso/vdso.lds.S
index d40d0e9..4e5dd3b 100644
--- a/arch/x86/vdso/vdso.lds.S
+++ b/arch/x86/vdso/vdso.lds.S
@@ -1,89 +1,37 @@
/*
- * Linker script for vsyscall DSO. The vsyscall page is an ELF shared
- * object prelinked to its virtual address, and with only one read-only
- * segment (that fits in one page). This script controls its layout.
+ * Linker script for 64-bit vDSO.
+ * We #include the file to define the layout details.
+ * Here we only choose the prelinked virtual address.
+ *
+ * This file defines the version script giving the user-exported symbols in
+ * the DSO. We can define local symbols here called VDSO* to make their
+ * values visible using the asm-x86/vdso.h macros from the kernel proper.
*/
-#include <asm/asm-offsets.h>
-#include "voffset.h"

#define VDSO_PRELINK 0xffffffffff700000
+#include "vdso-layout.lds.S"

/*
- * Symbols we define here called VDSO* get their values into vdso-syms.lds
- * and become visible to the kernel itself.
+ * This controls what userland symbols we export from the vDSO.
*/
-VDSO64_PRELINK = VDSO_PRELINK;
-
-#define VEXTERN(x) VDSO64_ ## x = vdso_ ## x;
-#include "vextern.h"
-#undef VEXTERN
-
-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) }
-
- /* This linker script is used both with -r and with -shared.
- For the layouts to match, we need to skip more than enough
- space for the dynamic symbol table et al. If this amount
- is insufficient, ld -shared will barf. Just increase it here. */
- . = VDSO_PRELINK + VDSO_TEXT_OFFSET;
-
- .text : { *(.text*) } :text
- .rodata : { *(.rodata*) } :text
- .data : {
- *(.data*)
- *(.sdata*)
- *(.bss*)
- *(.dynbss*)
- } :text
-
- .altinstructions : { *(.altinstructions) } :text
- .altinstr_replacement : { *(.altinstr_replacement) } :text
-
- .note : { *(.note.*) } :text :note
- .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
- .eh_frame : { KEEP (*(.eh_frame)) } :text
- .dynamic : { *(.dynamic) } :text :dynamic
- .useless : {
- *(.got.plt) *(.got)
- *(.gnu.linkonce.d.*)
- *(.gnu.linkonce.b.*)
- } :text
+VERSION {
+ LINUX_2.6 {
+ global:
+ clock_gettime;
+ __vdso_clock_gettime;
+ gettimeofday;
+ __vdso_gettimeofday;
+ getcpu;
+ __vdso_getcpu;
+ local: *;
+ };
}

-/*
- * We must supply the ELF program headers explicitly to get just one
- * PT_LOAD segment, and set the flags explicitly to make segments read-only.
- */
-PHDRS
-{
- text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
- dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
- note PT_NOTE FLAGS(4); /* PF_R */
- eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */
-}
+VDSO64_PRELINK = VDSO_PRELINK;

/*
- * This controls what symbols we export from the DSO.
+ * Define VDSO64_x for each VEXTERN(x), for use via VDSO64_SYMBOL.
*/
-VERSION
-{
- LINUX_2.6 {
- global:
- clock_gettime;
- __vdso_clock_gettime;
- gettimeofday;
- __vdso_gettimeofday;
- getcpu;
- __vdso_getcpu;
- local: *;
- };
-}
+#define VEXTERN(x) VDSO64_ ## x = vdso_ ## x;
+#include "vextern.h"
+#undef VEXTERN
diff --git a/arch/x86/vdso/voffset.h b/arch/x86/vdso/voffset.h
deleted file mode 100644
index 4af67c7..0000000
--- a/arch/x86/vdso/voffset.h
+++ /dev/null
@@ -1 +0,0 @@
-#define VDSO_TEXT_OFFSET 0x600

2007-11-19 22:04:48

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 05/18] x86 vDSO: harmonize asm-offsets


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 <[email protected]>
---
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
--- a/arch/x86/kernel/vsyscall-sigreturn_32.S
+++ b/arch/x86/kernel/vsyscall-sigreturn_32.S
@@ -91,27 +91,27 @@ __kernel_rt_sigreturn:
.sleb128 offset; /* offset */ \
1:

- do_cfa_expr(SIGCONTEXT_esp+4)
- do_expr(0, SIGCONTEXT_eax+4)
- do_expr(1, SIGCONTEXT_ecx+4)
- do_expr(2, SIGCONTEXT_edx+4)
- do_expr(3, SIGCONTEXT_ebx+4)
- do_expr(5, SIGCONTEXT_ebp+4)
- do_expr(6, SIGCONTEXT_esi+4)
- do_expr(7, SIGCONTEXT_edi+4)
- do_expr(8, SIGCONTEXT_eip+4)
+ do_cfa_expr(IA32_SIGCONTEXT_esp+4)
+ do_expr(0, IA32_SIGCONTEXT_eax+4)
+ do_expr(1, IA32_SIGCONTEXT_ecx+4)
+ do_expr(2, IA32_SIGCONTEXT_edx+4)
+ do_expr(3, IA32_SIGCONTEXT_ebx+4)
+ do_expr(5, IA32_SIGCONTEXT_ebp+4)
+ do_expr(6, IA32_SIGCONTEXT_esi+4)
+ do_expr(7, IA32_SIGCONTEXT_edi+4)
+ do_expr(8, IA32_SIGCONTEXT_eip+4)

.byte 0x42 /* DW_CFA_advance_loc 2 -- nop; popl eax. */

- do_cfa_expr(SIGCONTEXT_esp)
- do_expr(0, SIGCONTEXT_eax)
- do_expr(1, SIGCONTEXT_ecx)
- do_expr(2, SIGCONTEXT_edx)
- do_expr(3, SIGCONTEXT_ebx)
- do_expr(5, SIGCONTEXT_ebp)
- do_expr(6, SIGCONTEXT_esi)
- do_expr(7, SIGCONTEXT_edi)
- do_expr(8, SIGCONTEXT_eip)
+ do_cfa_expr(IA32_SIGCONTEXT_esp)
+ do_expr(0, IA32_SIGCONTEXT_eax)
+ do_expr(1, IA32_SIGCONTEXT_ecx)
+ do_expr(2, IA32_SIGCONTEXT_edx)
+ do_expr(3, IA32_SIGCONTEXT_ebx)
+ do_expr(5, IA32_SIGCONTEXT_ebp)
+ do_expr(6, IA32_SIGCONTEXT_esi)
+ do_expr(7, IA32_SIGCONTEXT_edi)
+ do_expr(8, IA32_SIGCONTEXT_eip)

.align 4
.LENDFDEDLSI1:
@@ -128,15 +128,15 @@ __kernel_rt_sigreturn:
slightly less complicated than the above, since we don't
modify the stack pointer in the process. */

- do_cfa_expr(RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_esp)
- do_expr(0, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_eax)
- do_expr(1, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_ecx)
- do_expr(2, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_edx)
- do_expr(3, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_ebx)
- do_expr(5, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_ebp)
- do_expr(6, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_esi)
- do_expr(7, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_edi)
- do_expr(8, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_eip)
+ do_cfa_expr(IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esp)
+ do_expr(0, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eax)
+ do_expr(1, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ecx)
+ do_expr(2, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edx)
+ do_expr(3, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebx)
+ do_expr(5, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebp)
+ do_expr(6, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esi)
+ do_expr(7, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edi)
+ do_expr(8, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eip)

.align 4
.LENDFDEDLSI2:

2007-11-19 22:06:14

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 06/18] x86 vDSO: arch/x86/vdso/vdso32


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 <[email protected]>
---
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 b/arch/x86/vdso/vdso32/int80.S
similarity index 97%
rename from arch/x86/kernel/vsyscall-int80_32.S
rename to arch/x86/vdso/vdso32/int80.S
index 103cab6..3c8e4c6 100644
--- a/arch/x86/kernel/vsyscall-int80_32.S
+++ b/arch/x86/vdso/vdso32/int80.S
@@ -50,4 +50,4 @@ __kernel_vsyscall:
/*
* Get the common code for the sigreturn entry points.
*/
-#include "vsyscall-sigreturn_32.S"
+#include "sigreturn.S"
diff --git a/arch/x86/kernel/vsyscall-note_32.S b/arch/x86/vdso/vdso32/note.S
similarity index 95%
rename from arch/x86/kernel/vsyscall-note_32.S
rename to arch/x86/vdso/vdso32/note.S
index fcf376a..0cf934f 100644
--- a/arch/x86/kernel/vsyscall-note_32.S
+++ b/arch/x86/vdso/vdso32/note.S
@@ -33,7 +33,7 @@ ELFNOTE_END
* at boot time we set VDSO_NOTE_NONEGSEG_BIT if running under Xen.
*/

-#include "../../x86/xen/vdso.h" /* Defines VDSO_NOTE_NONEGSEG_BIT. */
+#include "../../xen/vdso.h" /* Defines VDSO_NOTE_NONEGSEG_BIT. */

.globl VDSO_NOTE_MASK
ELFNOTE_START(GNU, 2, "a")
diff --git a/arch/x86/kernel/vsyscall-sigreturn_32.S b/arch/x86/vdso/vdso32/sigreturn.S
similarity index 100%
rename from arch/x86/kernel/vsyscall-sigreturn_32.S
rename to arch/x86/vdso/vdso32/sigreturn.S
diff --git a/arch/x86/kernel/vsyscall-sysenter_32.S b/arch/x86/vdso/vdso32/sysenter.S
similarity index 99%
rename from arch/x86/kernel/vsyscall-sysenter_32.S
rename to arch/x86/vdso/vdso32/sysenter.S
index ed879bf..4b98fc4 100644
--- a/arch/x86/kernel/vsyscall-sysenter_32.S
+++ b/arch/x86/vdso/vdso32/sysenter.S
@@ -119,4 +119,4 @@ SYSENTER_RETURN:
/*
* Get the common code for the sigreturn entry points.
*/
-#include "vsyscall-sigreturn_32.S"
+#include "sigreturn.S"

2007-11-19 22:06:32

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 07/18] x86 vDSO: vdso32 build


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 <[email protected]>
---
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) += -m32
+
+$(vdso32.so-y:%=$(obj)/vdso32-%.so.dbg): $(obj)/vdso32-%.so.dbg: FORCE \
+ $(obj)/vdso32/vdso32.lds \
+ $(obj)/vdso32/note.o \
+ $(obj)/vdso32/%.o
+ $(call if_changed,vdso)
+
+# Make vdso32-*-syms.lds from each image, and then make sure they match.
+# The only difference should be that some do not define VDSO32_SYSENTER_RETURN.
+
+targets += vdso32-syms.lds $(vdso32.so-y:%=vdso32-%-syms.lds)
+
+quiet_cmd_vdso32sym = VDSOSYM $@
+define cmd_vdso32sym
+ if LC_ALL=C sort -u $(filter-out FORCE,$^) > $(@D)/.tmp_$(@F) && \
+ $(foreach H,$(filter-out FORCE,$^),\
+ if grep -q VDSO32_SYSENTER_RETURN $H; \
+ then diff -u $(@D)/.tmp_$(@F) $H; \
+ else sed /VDSO32_SYSENTER_RETURN/d $(@D)/.tmp_$(@F) | \
+ diff -u - $H; fi &&) : ;\
+ then mv -f $(@D)/.tmp_$(@F) $@; \
+ else rm -f $(@D)/.tmp_$(@F); exit 1; \
+ fi
+endef
+
+$(obj)/vdso32-syms.lds: $(vdso32.so-y:%=$(obj)/vdso32-%-syms.lds) FORCE
+ $(call if_changed,vdso32sym)
+
+#
+# The DSO images are built using a special linker script.
+#
+quiet_cmd_vdso = VDSO $@
+ cmd_vdso = $(CC) -nostdlib -o $@ \
+ $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
+ -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^)
+
+VDSO_LDFLAGS = -fPIC -shared $(call ld-option, -Wl$(comma)--hash-style=sysv)
+
+#
+# Install the unstripped copy of vdso*.so listed in $(vdso-install-y).
+#
quiet_cmd_vdso_install = INSTALL $@
cmd_vdso_install = cp $(obj)/[email protected] $(MODLIB)/vdso/$@
-vdso.so:
+$(vdso-install-y): %.so: $(obj)/%.so.dbg FORCE
@mkdir -p $(MODLIB)/vdso
$(call cmd,vdso_install)

-vdso_install: vdso.so
+PHONY += vdso_install $(vdso-install-y)
+vdso_install: $(vdso-install-y)
diff --git a/arch/x86/vdso/vdso32/vdso32.lds.S b/arch/x86/vdso/vdso32/vdso32.lds.S
new file mode 100644
index 0000000..976124b
--- /dev/null
+++ b/arch/x86/vdso/vdso32/vdso32.lds.S
@@ -0,0 +1,37 @@
+/*
+ * Linker script for 32-bit vDSO.
+ * We #include the file to define the layout details.
+ * Here we only choose the prelinked virtual address.
+ *
+ * This file defines the version script giving the user-exported symbols in
+ * the DSO. We can define local symbols here called VDSO* to make their
+ * values visible using the asm-x86/vdso.h macros from the kernel proper.
+ */
+
+#define VDSO_PRELINK 0
+#include "../vdso-layout.lds.S"
+
+/* The ELF entry point can be used to set the AT_SYSINFO value. */
+ENTRY(__kernel_vsyscall);
+
+/*
+ * This controls what userland symbols we export from the vDSO.
+ */
+VERSION
+{
+ LINUX_2.5 {
+ global:
+ __kernel_vsyscall;
+ __kernel_sigreturn;
+ __kernel_rt_sigreturn;
+ local: *;
+ };
+}
+
+/*
+ * Symbols we define here called VDSO* get their values into vdso32-syms.h.
+ */
+VDSO32_PRELINK = VDSO_PRELINK;
+VDSO32_vsyscall = __kernel_vsyscall;
+VDSO32_sigreturn = __kernel_sigreturn;
+VDSO32_rt_sigreturn = __kernel_rt_sigreturn;

2007-11-19 22:07:08

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 08/18] x86 vDSO: i386 vdso32


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 <[email protected]>
---
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) += module_32.o
-obj-y += sysenter_32.o vsyscall_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
@@ -48,44 +48,3 @@ obj-$(CONFIG_PARAVIRT) += paravirt_32.o
obj-y += pcspeaker.o

obj-$(CONFIG_SCx200) += scx200_32.o
-
-# vsyscall_32.o contains the vsyscall DSO images as __initdata.
-# We must build both images before we can assemble it.
-# Note: kbuild does not track this dependency due to usage of .incbin
-$(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)) \
- -Wl,-T,$(filter-out FORCE,$^) -o $@
-
-export CPPFLAGS_vsyscall_32.lds += -P -C -Ui386
-
-vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 \
- $(call ld-option, -Wl$(comma)--hash-style=sysv)
-SYSCFLAGS_vsyscall-sysenter_32.so = $(vsyscall-flags)
-SYSCFLAGS_vsyscall-int80_32.so = $(vsyscall-flags)
-
-$(obj)/vsyscall-int80_32.so $(obj)/vsyscall-sysenter_32.so: \
-$(obj)/vsyscall-%.so: $(src)/vsyscall_32.lds \
- $(obj)/vsyscall-%.o $(obj)/vsyscall-note_32.o FORCE
- $(call if_changed,syscall)
-
-# 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 += vsyscall-syms.o
-$(obj)/built-in.o: $(obj)/vsyscall-syms.o
-$(obj)/built-in.o: ld_flags += -R $(obj)/vsyscall-syms.o
-
-SYSCFLAGS_vsyscall-syms.o = -r
-$(obj)/vsyscall-syms.o: $(src)/vsyscall_32.lds \
- $(obj)/vsyscall-sysenter_32.o $(obj)/vsyscall-note_32.o FORCE
- $(call if_changed,syscall)
-
-
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
index c578a2b..2784f2c 100644
--- a/arch/x86/kernel/asm-offsets_32.c
+++ b/arch/x86/kernel/asm-offsets_32.c
@@ -111,8 +111,6 @@ void foo(void)
DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);

- DEFINE(VDSO_PRELINK_asm, VDSO_PRELINK);
-
OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);

#ifdef CONFIG_PARAVIRT
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
index 9bdd830..696cb89 100644
--- a/arch/x86/kernel/signal_32.c
+++ b/arch/x86/kernel/signal_32.c
@@ -23,6 +23,7 @@
#include <asm/ucontext.h>
#include <asm/uaccess.h>
#include <asm/i387.h>
+#include <asm/vdso.h>
#include "sigframe_32.h"

#define DEBUG_SIG 0
@@ -355,7 +356,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
}

if (current->binfmt->hasvdso)
- restorer = (void *)VDSO_SYM(&__kernel_sigreturn);
+ restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
else
restorer = (void *)&frame->retcode;
if (ka->sa.sa_flags & SA_RESTORER)
@@ -452,7 +453,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
goto give_sigsegv;

/* Set up to return from userspace. */
- restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn);
+ restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
if (ka->sa.sa_flags & SA_RESTORER)
restorer = ka->sa.sa_restorer;
err |= __put_user(restorer, &frame->pretcode);
diff --git a/arch/x86/kernel/sysenter_32.c b/arch/x86/kernel/sysenter_32.c
index 5a2d951..85c52d2 100644
--- a/arch/x86/kernel/sysenter_32.c
+++ b/arch/x86/kernel/sysenter_32.c
@@ -23,6 +23,7 @@
#include <asm/unistd.h>
#include <asm/elf.h>
#include <asm/tlbflush.h>
+#include <asm/vdso.h>

enum {
VDSO_DISABLED = 0,
@@ -259,9 +260,6 @@ int __init sysenter_setup(void)
return 0;
}

-/* Defined in vsyscall-sysenter.S */
-extern void SYSENTER_RETURN;
-
/* Setup a VMA at program startup for the vsyscall page */
int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)
{
@@ -308,7 +306,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)

current->mm->context.vdso = (void *)addr;
current_thread_info()->sysenter_return =
- (void *)VDSO_SYM(&SYSENTER_RETURN);
+ VDSO32_SYMBOL(addr, SYSENTER_RETURN);

up_fail:
up_write(&mm->mmap_sem);
diff --git a/arch/x86/kernel/vsyscall_32.lds.S b/arch/x86/kernel/vsyscall_32.lds.S
deleted file mode 100644
index 4a8b0ed..0000000
--- a/arch/x86/kernel/vsyscall_32.lds.S
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Linker script for vsyscall DSO. The vsyscall page is an ELF shared
- * object prelinked to its virtual address, and with only one read-only
- * segment (that fits in one page). This script controls its layout.
- */
-#include <asm/asm-offsets.h>
-
-SECTIONS
-{
- . = VDSO_PRELINK_asm + 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) }
-
- /* This linker script is used both with -r and with -shared.
- For the layouts to match, we need to skip more than enough
- space for the dynamic symbol table et al. If this amount
- is insufficient, ld -shared will barf. Just increase it here. */
- . = VDSO_PRELINK_asm + 0x400;
-
- .text : { *(.text) } :text =0x90909090
- .note : { *(.note.*) } :text :note
- .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
- .eh_frame : { KEEP (*(.eh_frame)) } :text
- .dynamic : { *(.dynamic) } :text :dynamic
- .useless : {
- *(.got.plt) *(.got)
- *(.data .data.* .gnu.linkonce.d.*)
- *(.dynbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- } :text
-}
-
-/*
- * We must supply the ELF program headers explicitly to get just one
- * PT_LOAD segment, and set the flags explicitly to make segments read-only.
- */
-PHDRS
-{
- text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
- dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
- note PT_NOTE FLAGS(4); /* PF_R */
- eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */
-}
-
-/*
- * This controls what symbols we export from the DSO.
- */
-VERSION
-{
- LINUX_2.5 {
- global:
- __kernel_vsyscall;
- __kernel_sigreturn;
- __kernel_rt_sigreturn;
-
- local: *;
- };
-}
-
-/* The ELF entry point can be used to set the AT_SYSINFO value. */
-ENTRY(__kernel_vsyscall);
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile
index a1e0418..cabb0c2 100644
--- a/arch/x86/vdso/Makefile
+++ b/arch/x86/vdso/Makefile
@@ -14,7 +14,8 @@ vdso-install-$(VDSO32-y) += $(vdso32-y:=.so)
vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o vvar.o

# files to link into kernel
-obj-y := vma.o vdso.o
+obj-$(VDSO64-y) += vma.o vdso.o
+obj-$(CONFIG_X86_32) += vdso32.o

vobjs := $(foreach F,$(vobjs-y),$(obj)/$F)

@@ -52,7 +53,7 @@ $(obj)/vclock_gettime.o: KBUILD_CFLAGS = $(CFL)
$(obj)/vgetcpu.o: KBUILD_CFLAGS = $(CFL)

targets += vdso-syms.lds
-obj-y += vdso-syms.lds
+obj-$(VDSO64-y) += vdso-syms.lds

#
# Match symbols in the DSO that look like VDSO*; produce a file of constants.
@@ -68,6 +69,7 @@ $(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE
#
# Build multiple 32-bit vDSO images to choose from at boot time.
#
+obj-$(VDSO32-y) += vdso32-syms.lds
vdso32.so-$(CONFIG_X86_32) += int80
vdso32.so-$(VDSO32-y) += sysenter

@@ -84,6 +86,8 @@ targets += vdso32/note.o $(vdso32.so-y:%=vdso32/%.o)

extra-y += $(vdso32.so-y:%=vdso32-%.so)

+$(obj)/vdso32.o: $(vdso32.so-y:%=$(obj)/vdso32-%.so)
+
$(vdso32.so-y:%=$(obj)/vdso32-%.so.dbg): asflags-$(CONFIG_X86_64) += -m32

$(vdso32.so-y:%=$(obj)/vdso32-%.so.dbg): $(obj)/vdso32-%.so.dbg: FORCE \
diff --git a/arch/x86/kernel/vsyscall_32.S b/arch/x86/vdso/vdso32.S
similarity index 70%
rename from arch/x86/kernel/vsyscall_32.S
rename to arch/x86/vdso/vdso32.S
index a5ab3dc..cab020c 100644
--- a/arch/x86/kernel/vsyscall_32.S
+++ b/arch/x86/vdso/vdso32.S
@@ -4,12 +4,12 @@ __INITDATA

.globl vsyscall_int80_start, vsyscall_int80_end
vsyscall_int80_start:
- .incbin "arch/x86/kernel/vsyscall-int80_32.so"
+ .incbin "arch/x86/vdso/vdso32-int80.so"
vsyscall_int80_end:

.globl vsyscall_sysenter_start, vsyscall_sysenter_end
vsyscall_sysenter_start:
- .incbin "arch/x86/kernel/vsyscall-sysenter_32.so"
+ .incbin "arch/x86/vdso/vdso32-sysenter.so"
vsyscall_sysenter_end:

__FINIT
diff --git a/arch/x86/vdso/vdso32/note.S b/arch/x86/vdso/vdso32/note.S
index 0cf934f..c83f257 100644
--- a/arch/x86/vdso/vdso32/note.S
+++ b/arch/x86/vdso/vdso32/note.S
@@ -35,10 +35,9 @@ ELFNOTE_END

#include "../../xen/vdso.h" /* Defines VDSO_NOTE_NONEGSEG_BIT. */

- .globl VDSO_NOTE_MASK
ELFNOTE_START(GNU, 2, "a")
.long 1 /* ncaps */
-VDSO_NOTE_MASK:
+VDSO32_NOTE_MASK: /* Symbol used by arch/x86/xen/setup.c */
.long 0 /* mask */
.byte VDSO_NOTE_NONEGSEG_BIT; .asciz "nosegneg" /* bit, name */
ELFNOTE_END
diff --git a/arch/x86/vdso/vdso32/sysenter.S b/arch/x86/vdso/vdso32/sysenter.S
index 4b98fc4..109bfa3 100644
--- a/arch/x86/vdso/vdso32/sysenter.S
+++ b/arch/x86/vdso/vdso32/sysenter.S
@@ -45,8 +45,7 @@ __kernel_vsyscall:
/* 14: System call restart point is here! (SYSENTER_RETURN-2) */
jmp .Lenter_kernel
/* 16: System call normal return point is here! */
- .globl SYSENTER_RETURN /* Symbol used by sysenter.c */
-SYSENTER_RETURN:
+VDSO32_SYSENTER_RETURN: /* Symbol used by sysenter.c via vdso32-syms.h */
pop %ebp
.Lpop_ebp:
pop %edx
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index f84e772..fd91568 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -10,6 +10,7 @@
#include <linux/pm.h>

#include <asm/elf.h>
+#include <asm/vdso.h>
#include <asm/e820.h>
#include <asm/setup.h>
#include <asm/xen/hypervisor.h>
@@ -61,10 +62,8 @@ static void xen_idle(void)
*/
static void fiddle_vdso(void)
{
- extern u32 VDSO_NOTE_MASK; /* See ../kernel/vsyscall-note.S. */
extern char vsyscall_int80_start;
- u32 *mask = (u32 *) ((unsigned long) &VDSO_NOTE_MASK - VDSO_PRELINK +
- &vsyscall_int80_start);
+ u32 *mask = VDSO32_SYMBOL(&vsyscall_int80_start, NOTE_MASK);
*mask |= 1 << VDSO_NOTE_NONEGSEG_BIT;
}

diff --git a/include/asm-x86/elf.h b/include/asm-x86/elf.h
index ec42a4d..0dd21ee 100644
--- a/include/asm-x86/elf.h
+++ b/include/asm-x86/elf.h
@@ -78,6 +78,7 @@ typedef struct user_fxsr_struct elf_fpxregset_t;
#include <asm/processor.h>
#include <asm/system.h> /* for savesegment */
#include <asm/desc.h>
+#include <asm/vdso.h>

/*
* This is used to ensure we don't load something for the wrong architecture.
@@ -247,17 +248,9 @@ extern int dump_task_extended_fpu (struct task_struct *,

#define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO))
#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
-#define VDSO_PRELINK 0

-#define VDSO_SYM(x) \
- (VDSO_CURRENT_BASE + (unsigned long)(x) - VDSO_PRELINK)
-
-#define VDSO_HIGH_EHDR ((const struct elfhdr *) VDSO_HIGH_BASE)
-#define VDSO_EHDR ((const struct elfhdr *) VDSO_CURRENT_BASE)
-
-extern void __kernel_vsyscall;
-
-#define VDSO_ENTRY VDSO_SYM(&__kernel_vsyscall)
+#define VDSO_ENTRY \
+ ((unsigned long) VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))

/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */

diff --git a/include/asm-x86/vdso.h b/include/asm-x86/vdso.h
index 9379ec0..629bcb6 100644
--- a/include/asm-x86/vdso.h
+++ b/include/asm-x86/vdso.h
@@ -1,6 +1,7 @@
#ifndef _ASM_X86_VDSO_H
#define _ASM_X86_VDSO_H 1

+#ifdef CONFIG_X86_64
extern const char VDSO64_PRELINK[];

/*
@@ -10,5 +11,18 @@ extern const char VDSO64_PRELINK[];
#define VDSO64_SYMBOL(base, name) ({ \
extern const char VDSO64_##name[]; \
(void *) (VDSO64_##name - VDSO64_PRELINK + (unsigned long) (base)); })
+#endif
+
+#if defined CONFIG_X86_32 || defined CONFIG_COMPAT
+extern const char VDSO32_PRELINK[];
+
+/*
+ * Given a pointer to the vDSO image, find the pointer to VDSO32_name
+ * as that symbol is defined in the vDSO sources or linker script.
+ */
+#define VDSO32_SYMBOL(base, name) ({ \
+ extern const char VDSO32_##name[]; \
+ (void *) (VDSO32_##name - VDSO32_PRELINK + (unsigned long) (base)); })
+#endif

#endif /* asm-x86/vdso.h */

2007-11-19 22:07:36

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 09/18] x86 vDSO: absolute relocs


This updates the exceptions for absolute relocs for the new symbol name
convention used for symbols extracted from the vDSO images.

Signed-off-by: Roland McGrath <[email protected]>
---
arch/x86/boot/compressed/relocs.c | 7 ++-----
1 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/arch/x86/boot/compressed/relocs.c b/arch/x86/boot/compressed/relocs.c
index 7a0d00b..d01ea42 100644
--- a/arch/x86/boot/compressed/relocs.c
+++ b/arch/x86/boot/compressed/relocs.c
@@ -27,11 +27,6 @@ static unsigned long *relocs;
* absolute relocations present w.r.t these symbols.
*/
static const char* safe_abs_relocs[] = {
- "__kernel_vsyscall",
- "__kernel_rt_sigreturn",
- "__kernel_sigreturn",
- "SYSENTER_RETURN",
- "VDSO_NOTE_MASK",
"xen_irq_disable_direct_reloc",
"xen_save_fl_direct_reloc",
};
@@ -45,6 +40,8 @@ static int is_safe_abs_reloc(const char* sym_name)
/* Match found */
return 1;
}
+ if (strncmp(sym_name, "VDSO", 4) == 0)
+ return 1;
if (strncmp(sym_name, "__crc_", 6) == 0)
return 1;
return 0;

2007-11-19 22:07:52

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 10/18] x86 vDSO: i386 vdso32 install


This enables 'make vdso_install' for i386 as on x86_64 and powerpc.

Signed-off-by: Roland McGrath <[email protected]>
---
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

2007-11-19 22:08:19

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 11/18] x86 vDSO: vdso32 setup


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 <[email protected]>
---
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

2007-11-19 22:08:56

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 12/18] x86 vDSO: ia32_sysenter_target


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 <[email protected]>
---
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 asmlinkage void ia32_sysenter_target(void);

static __init void reloc_symtab(Elf32_Ehdr *ehdr,
unsigned offset, unsigned size)
@@ -187,7 +187,7 @@ void enable_sep_cpu(void)
tss->x86_tss.esp1 = sizeof(struct tss_struct) + (unsigned long) tss;
wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
wrmsr(MSR_IA32_SYSENTER_ESP, tss->x86_tss.esp1, 0);
- wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0);
+ wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) ia32_sysenter_target, 0);
put_cpu();
}

2007-11-19 22:09:20

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 13/18] x86 vDSO: ia32 sysenter_return


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 <[email protected]>
---
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 a/arch/x86/ia32/syscall32.c b/arch/x86/ia32/syscall32.c
index 15013ba..2c9c145 100644
--- a/arch/x86/ia32/syscall32.c
+++ b/arch/x86/ia32/syscall32.c
@@ -45,6 +45,10 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack)
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
VM_ALWAYSDUMP,
syscall32_pages);
+ if (ret == 0) {
+ current->mm->context.vdso = (void __user *)VSYSCALL32_BASE;
+ current_thread_info()->sysenter_return = VSYSCALL32_SYSEXIT;
+ }
up_write(&mm->mmap_sem);
return ret;
}
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c
index d1b6ed9..1f9b0b5 100644
--- a/arch/x86/kernel/asm-offsets_64.c
+++ b/arch/x86/kernel/asm-offsets_64.c
@@ -47,6 +47,7 @@ int main(void)
ENTRY(addr_limit);
ENTRY(preempt_count);
ENTRY(status);
+ ENTRY(sysenter_return);
BLANK();
#undef ENTRY
#define ENTRY(entry) DEFINE(pda_ ## entry, offsetof(struct x8664_pda, entry))
diff --git a/include/asm-x86/thread_info_64.h b/include/asm-x86/thread_info_64.h
index beae2bf..f81638e 100644
--- a/include/asm-x86/thread_info_64.h
+++ b/include/asm-x86/thread_info_64.h
@@ -33,6 +33,9 @@ struct thread_info {

mm_segment_t addr_limit;
struct restart_block restart_block;
+#ifdef CONFIG_IA32_EMULATION
+ void __user *sysenter_return;
+#endif
};
#endif

2007-11-19 22:09:57

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 14/18] x86 vDSO: ia32 vdso32-syscall build


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 <[email protected]>
---
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 b/arch/x86/vdso/vdso32/syscall.S
new file mode 100644
index 0000000..333bfb5
--- /dev/null
+++ b/arch/x86/vdso/vdso32/syscall.S
@@ -0,0 +1,69 @@
+/*
+ * Code for the vsyscall page. This version uses the syscall instruction.
+ */
+
+#include <asm/asm-offsets.h>
+#include <asm/segment.h>
+
+ .text
+ .globl __kernel_vsyscall
+ .type __kernel_vsyscall,@function
+__kernel_vsyscall:
+.LSTART_vsyscall:
+ push %ebp
+.Lpush_ebp:
+ movl %ecx, %ebp
+ syscall
+ movl $__USER32_DS, %ecx
+ movl %ecx, %ss
+ movl %ebp, %ecx
+ popl %ebp
+.Lpop_ebp:
+ ret
+.LEND_vsyscall:
+ .size __kernel_vsyscall,.-.LSTART_vsyscall
+
+ .section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+ .long .LENDCIE-.LSTARTCIE
+.LSTARTCIE:
+ .long 0 /* CIE ID */
+ .byte 1 /* Version number */
+ .string "zR" /* NUL-terminated augmentation string */
+ .uleb128 1 /* Code alignment factor */
+ .sleb128 -4 /* Data alignment factor */
+ .byte 8 /* Return address register column */
+ .uleb128 1 /* Augmentation value length */
+ .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
+ .byte 0x0c /* DW_CFA_def_cfa */
+ .uleb128 4
+ .uleb128 4
+ .byte 0x88 /* DW_CFA_offset, column 0x8 */
+ .uleb128 1
+ .align 4
+.LENDCIE:
+
+ .long .LENDFDE1-.LSTARTFDE1 /* Length FDE */
+.LSTARTFDE1:
+ .long .LSTARTFDE1-.LSTARTFRAME /* CIE pointer */
+ .long .LSTART_vsyscall-. /* PC-relative start address */
+ .long .LEND_vsyscall-.LSTART_vsyscall
+ .uleb128 0 /* Augmentation length */
+ /* What follows are the instructions for the table generation.
+ We have to record all changes of the stack pointer. */
+ .byte 0x40 + .Lpush_ebp-.LSTART_vsyscall /* DW_CFA_advance_loc */
+ .byte 0x0e /* DW_CFA_def_cfa_offset */
+ .uleb128 8
+ .byte 0x85, 0x02 /* DW_CFA_offset %ebp -8 */
+ .byte 0x40 + .Lpop_ebp-.Lpush_ebp /* DW_CFA_advance_loc */
+ .byte 0xc5 /* DW_CFA_restore %ebp */
+ .byte 0x0e /* DW_CFA_def_cfa_offset */
+ .uleb128 4
+ .align 4
+.LENDFDE1:
+
+/*
+ * Get the common code for the sigreturn entry points.
+ */
+#define SYSCALL_ENTER_KERNEL syscall
+#include "sigreturn.S"

2007-11-19 22:10:30

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 18/18] x86 vDSO: makefile cleanup


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 <[email protected]>
---
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

2007-11-19 22:11:20

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 15/18] x86 vDSO: consolidate vdso32


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 <[email protected]>
---
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 a/arch/x86/Kconfig b/arch/x86/Kconfig
index 368864d..52280e3 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1189,9 +1189,9 @@ config HOTPLUG_CPU
config COMPAT_VDSO
bool "Compat VDSO support"
default y
- depends on X86_32
+ depends on X86_32 || IA32_EMULATION
help
- Map the VDSO to the predictable old-style address too.
+ Map the 32-bit VDSO to the predictable old-style address too.
---help---
Say N here if you are running a sufficiently recent glibc
version (2.3.3 or later), to remove the high-mapped
diff --git a/arch/x86/ia32/Makefile b/arch/x86/ia32/Makefile
index e2edda2..9abb0db 100644
--- a/arch/x86/ia32/Makefile
+++ b/arch/x86/ia32/Makefile
@@ -3,7 +3,7 @@
#

obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o tls32.o \
- ia32_binfmt.o fpu32.o ptrace32.o syscall32.o syscall32_syscall.o \
+ ia32_binfmt.o fpu32.o ptrace32.o \
mmap32.o

sysv-$(CONFIG_SYSVIPC) := ipc32.o
diff --git a/arch/x86/ia32/ia32_binfmt.c b/arch/x86/ia32/ia32_binfmt.c
index 55822d2..e32974c 100644
--- a/arch/x86/ia32/ia32_binfmt.c
+++ b/arch/x86/ia32/ia32_binfmt.c
@@ -26,7 +26,7 @@
#include <asm/i387.h>
#include <asm/uaccess.h>
#include <asm/ia32.h>
-#include <asm/vsyscall32.h>
+#include <asm/vdso.h>

#undef ELF_ARCH
#undef ELF_CLASS
@@ -47,14 +47,13 @@
#define AT_SYSINFO 32
#define AT_SYSINFO_EHDR 33

-int sysctl_vsyscall32 = 1;
+extern int sysctl_vsyscall32;

#undef ARCH_DLINFO
#define ARCH_DLINFO do { \
if (sysctl_vsyscall32) { \
- current->mm->context.vdso = (void *)VSYSCALL32_BASE; \
- NEW_AUX_ENT(AT_SYSINFO, (u32)(u64)VSYSCALL32_VSYSCALL); \
- NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL32_BASE); \
+ NEW_AUX_ENT(AT_SYSINFO, (u32)VDSO_ENTRY); \
+ NEW_AUX_ENT(AT_SYSINFO_EHDR, (u32)VDSO_CURRENT_BASE); \
} \
} while(0)

diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index 6ea19c2..120b607 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -31,7 +31,7 @@
#include <asm/sigcontext32.h>
#include <asm/fpu32.h>
#include <asm/proto.h>
-#include <asm/vsyscall32.h>
+#include <asm/vdso.h>

#define DEBUG_SIG 0

@@ -451,7 +451,8 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
{
void __user *restorer;
if (current->binfmt->hasvdso)
- restorer = VSYSCALL32_SIGRETURN;
+ restorer = VDSO32_SYMBOL(current->mm->context.vdso,
+ sigreturn);
else
restorer = (void *)&frame->retcode;
if (ka->sa.sa_flags & SA_RESTORER)
@@ -551,7 +552,8 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,


{
- void __user *restorer = VSYSCALL32_RTSIGRETURN;
+ void __user *restorer = VDSO32_SYMBOL(current->mm->context.vdso,
+ rt_sigreturn);
if (ka->sa.sa_flags & SA_RESTORER)
restorer = ka->sa.sa_restorer;
err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile
index 64e4f47..53f36bc 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 vdso32-setup.o
+obj-$(VDSO32-y) += vdso32.o vdso32-setup.o

vobjs := $(foreach F,$(vobjs-y),$(obj)/$F)

diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c
index fb71a93..d97a6d7 100644
--- a/arch/x86/vdso/vdso32-setup.c
+++ b/arch/x86/vdso/vdso32-setup.c
@@ -24,6 +24,7 @@
#include <asm/elf.h>
#include <asm/tlbflush.h>
#include <asm/vdso.h>
+#include <asm/proto.h>

enum {
VDSO_DISABLED = 0,
@@ -37,14 +38,24 @@ enum {
#define VDSO_DEFAULT VDSO_ENABLED
#endif

+#ifdef CONFIG_X86_64
+#define vdso_enabled sysctl_vsyscall32
+#define arch_setup_additional_pages syscall32_setup_pages
+#endif
+
+/*
+ * This is the difference between the prelinked addresses in the vDSO images
+ * and the VDSO_HIGH_BASE address where CONFIG_COMPAT_VDSO places the vDSO
+ * in the user address space.
+ */
+#define VDSO_ADDR_ADJUST (VDSO_HIGH_BASE - (unsigned long)VDSO32_PRELINK)
+
/*
* Should the kernel map a VDSO page into processes and pass its
* address down to glibc upon exec()?
*/
unsigned int __read_mostly vdso_enabled = VDSO_DEFAULT;

-EXPORT_SYMBOL_GPL(vdso_enabled);
-
static int __init vdso_setup(char *s)
{
vdso_enabled = simple_strtoul(s, NULL, 0);
@@ -52,9 +63,18 @@ static int __init vdso_setup(char *s)
return 1;
}

-__setup("vdso=", vdso_setup);
+/*
+ * For consistency, the argument vdso32=[012] affects the 32-bit vDSO
+ * behavior on both 64-bit and 32-bit kernels.
+ * On 32-bit kernels, vdso=[012] means the same thing.
+ */
+__setup("vdso32=", vdso_setup);

-extern asmlinkage void ia32_sysenter_target(void);
+#ifdef CONFIG_X86_32
+__setup_param("vdso=", vdso32_setup, vdso_setup, 0);
+
+EXPORT_SYMBOL_GPL(vdso_enabled);
+#endif

static __init void reloc_symtab(Elf32_Ehdr *ehdr,
unsigned offset, unsigned size)
@@ -79,7 +99,7 @@ static __init void reloc_symtab(Elf32_Ehdr *ehdr,
case STT_FUNC:
case STT_SECTION:
case STT_FILE:
- sym->st_value += VDSO_HIGH_BASE;
+ sym->st_value += VDSO_ADDR_ADJUST;
}
}
}
@@ -105,7 +125,7 @@ static __init void reloc_dyn(Elf32_Ehdr *ehdr, unsigned offset)
case DT_VERNEED:
case DT_ADDRRNGLO ... DT_ADDRRNGHI:
/* definitely pointers needing relocation */
- dyn->d_un.d_ptr += VDSO_HIGH_BASE;
+ dyn->d_un.d_ptr += VDSO_ADDR_ADJUST;
break;

case DT_ENCODING ... OLD_DT_LOOS-1:
@@ -114,7 +134,7 @@ static __init void reloc_dyn(Elf32_Ehdr *ehdr, unsigned offset)
they're even */
if (dyn->d_tag >= DT_ENCODING &&
(dyn->d_tag & 1) == 0)
- dyn->d_un.d_ptr += VDSO_HIGH_BASE;
+ dyn->d_un.d_ptr += VDSO_ADDR_ADJUST;
break;

case DT_VERDEFNUM:
@@ -143,15 +163,15 @@ static __init void relocate_vdso(Elf32_Ehdr *ehdr)
int i;

BUG_ON(memcmp(ehdr->e_ident, ELFMAG, 4) != 0 ||
- !elf_check_arch(ehdr) ||
+ !elf_check_arch_ia32(ehdr) ||
ehdr->e_type != ET_DYN);

- ehdr->e_entry += VDSO_HIGH_BASE;
+ ehdr->e_entry += VDSO_ADDR_ADJUST;

/* rebase phdrs */
phdr = (void *)ehdr + ehdr->e_phoff;
for (i = 0; i < ehdr->e_phnum; i++) {
- phdr[i].p_vaddr += VDSO_HIGH_BASE;
+ phdr[i].p_vaddr += VDSO_ADDR_ADJUST;

/* relocate dynamic stuff */
if (phdr[i].p_type == PT_DYNAMIC)
@@ -164,7 +184,7 @@ static __init void relocate_vdso(Elf32_Ehdr *ehdr)
if (!(shdr[i].sh_flags & SHF_ALLOC))
continue;

- shdr[i].sh_addr += VDSO_HIGH_BASE;
+ shdr[i].sh_addr += VDSO_ADDR_ADJUST;

if (shdr[i].sh_type == SHT_SYMTAB ||
shdr[i].sh_type == SHT_DYNSYM)
@@ -173,6 +193,45 @@ static __init void relocate_vdso(Elf32_Ehdr *ehdr)
}
}

+/*
+ * These symbols are defined by vdso32.S to mark the bounds
+ * of the ELF DSO images included therein.
+ */
+extern const char vdso32_default_start, vdso32_default_end;
+extern const char vdso32_sysenter_start, vdso32_sysenter_end;
+static struct page *vdso32_pages[1];
+
+#ifdef CONFIG_X86_64
+
+static int use_sysenter __read_mostly = -1;
+
+#define vdso32_sysenter() (use_sysenter > 0)
+
+/* May not be __init: called during resume */
+void syscall32_cpu_init(void)
+{
+ if (use_sysenter < 0)
+ use_sysenter = (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL);
+
+ /* Load these always in case some future AMD CPU supports
+ SYSENTER from compat mode too. */
+ checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS);
+ checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL);
+ checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target);
+
+ wrmsrl(MSR_CSTAR, ia32_cstar_target);
+}
+
+#define compat_uses_vma 1
+
+static inline void map_compat_vdso(int map)
+{
+}
+
+#else /* CONFIG_X86_32 */
+
+#define vdso32_sysenter() (boot_cpu_has(X86_FEATURE_SEP))
+
void enable_sep_cpu(void)
{
int cpu = get_cpu();
@@ -210,13 +269,7 @@ static int __init gate_vma_init(void)
return 0;
}

-/*
- * These symbols are defined by vsyscall.o to mark the bounds
- * of the ELF DSO images included therein.
- */
-extern const char vsyscall_int80_start, vsyscall_int80_end;
-extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
-static struct page *syscall_pages[1];
+#define compat_uses_vma 0

static void map_compat_vdso(int map)
{
@@ -227,31 +280,35 @@ static void map_compat_vdso(int map)

vdso_mapped = map;

- __set_fixmap(FIX_VDSO, page_to_pfn(syscall_pages[0]) << PAGE_SHIFT,
+ __set_fixmap(FIX_VDSO, page_to_pfn(vdso32_pages[0]) << PAGE_SHIFT,
map ? PAGE_READONLY_EXEC : PAGE_NONE);

/* flush stray tlbs */
flush_tlb_all();
}

+#endif /* CONFIG_X86_64 */
+
int __init sysenter_setup(void)
{
void *syscall_page = (void *)get_zeroed_page(GFP_ATOMIC);
const void *vsyscall;
size_t vsyscall_len;

- syscall_pages[0] = virt_to_page(syscall_page);
+ vdso32_pages[0] = virt_to_page(syscall_page);

+#ifdef CONFIG_X86_32
gate_vma_init();

printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO));
+#endif

- if (!boot_cpu_has(X86_FEATURE_SEP)) {
- vsyscall = &vsyscall_int80_start;
- vsyscall_len = &vsyscall_int80_end - &vsyscall_int80_start;
+ if (!vdso32_sysenter()) {
+ vsyscall = &vdso32_default_start;
+ vsyscall_len = &vdso32_default_end - &vdso32_default_start;
} else {
- vsyscall = &vsyscall_sysenter_start;
- vsyscall_len = &vsyscall_sysenter_end - &vsyscall_sysenter_start;
+ vsyscall = &vdso32_sysenter_start;
+ vsyscall_len = &vdso32_sysenter_end - &vdso32_sysenter_start;
}

memcpy(syscall_page, vsyscall, vsyscall_len);
@@ -284,7 +341,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)
ret = addr;
goto up_fail;
}
+ }

+ if (compat_uses_vma || !compat) {
/*
* MAYWRITE to allow gdb to COW and set breakpoints
*
@@ -298,7 +357,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)
VM_READ|VM_EXEC|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
VM_ALWAYSDUMP,
- syscall_pages);
+ vdso32_pages);

if (ret)
goto up_fail;
@@ -314,6 +373,12 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)
return ret;
}

+#ifdef CONFIG_X86_64
+
+__initcall(sysenter_setup);
+
+#else /* CONFIG_X86_32 */
+
const char *arch_vma_name(struct vm_area_struct *vma)
{
if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
@@ -342,3 +407,5 @@ int in_gate_area_no_task(unsigned long addr)
{
return 0;
}
+
+#endif /* CONFIG_X86_64 */
diff --git a/arch/x86/vdso/vdso32.S b/arch/x86/vdso/vdso32.S
index cab020c..1e36f72 100644
--- a/arch/x86/vdso/vdso32.S
+++ b/arch/x86/vdso/vdso32.S
@@ -2,14 +2,18 @@

__INITDATA

- .globl vsyscall_int80_start, vsyscall_int80_end
-vsyscall_int80_start:
+ .globl vdso32_default_start, vdso32_default_end
+vdso32_default_start:
+#ifdef CONFIG_X86_32
.incbin "arch/x86/vdso/vdso32-int80.so"
-vsyscall_int80_end:
+#else
+ .incbin "arch/x86/vdso/vdso32-syscall.so"
+#endif
+vdso32_default_end:

- .globl vsyscall_sysenter_start, vsyscall_sysenter_end
-vsyscall_sysenter_start:
+ .globl vdso32_sysenter_start, vdso32_sysenter_end
+vdso32_sysenter_start:
.incbin "arch/x86/vdso/vdso32-sysenter.so"
-vsyscall_sysenter_end:
+vdso32_sysenter_end:

__FINIT
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index fd91568..7d6d0ef 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -62,8 +62,8 @@ static void xen_idle(void)
*/
static void fiddle_vdso(void)
{
- extern char vsyscall_int80_start;
- u32 *mask = VDSO32_SYMBOL(&vsyscall_int80_start, NOTE_MASK);
+ extern const char vdso32_default_start;
+ u32 *mask = VDSO32_SYMBOL(&vdso32_default_start, NOTE_MASK);
*mask |= 1 << VDSO_NOTE_NONEGSEG_BIT;
}

diff --git a/include/asm-x86/elf.h b/include/asm-x86/elf.h
index 0dd21ee..0ff9c2f 100644
--- a/include/asm-x86/elf.h
+++ b/include/asm-x86/elf.h
@@ -74,17 +74,19 @@ typedef struct user_fxsr_struct elf_fpxregset_t;

#ifdef __KERNEL__

+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch_ia32(x) \
+ (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486))
+
#ifdef CONFIG_X86_32
#include <asm/processor.h>
#include <asm/system.h> /* for savesegment */
#include <asm/desc.h>
#include <asm/vdso.h>

-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) \
- (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486))
+#define elf_check_arch(x) elf_check_arch_ia32(x)

/* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program starts %edx
contains a pointer to a function which might be registered using `atexit'.
@@ -247,10 +249,6 @@ extern int dump_task_extended_fpu (struct task_struct *,
#define ELF_CORE_XFPREG_TYPE NT_PRXFPREG

#define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO))
-#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
-
-#define VDSO_ENTRY \
- ((unsigned long) VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))

/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */

@@ -262,6 +260,8 @@ do if (vdso_enabled) { \

#else /* CONFIG_X86_32 */

+#define VDSO_HIGH_BASE 0xffffe000U /* CONFIG_COMPAT_VDSO address */
+
/* 1GB for 64bit, 8MB for 32bit */
#define STACK_RND_MASK (test_thread_flag(TIF_IA32) ? 0x7ff : 0x3fffff)

@@ -272,6 +272,11 @@ do if (vdso_enabled) { \

#endif /* !CONFIG_X86_32 */

+#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
+
+#define VDSO_ENTRY \
+ ((unsigned long) VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
+
struct linux_binprm;

#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1

2007-11-19 22:11:40

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 17/18] x86 vDSO: reorder vdso32 code


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 <[email protected]>
---
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 the sigreturn entry points in vDSO images.
* So far this code is the same for both int80 and sysenter versions.
- * This file is #include'd by vsyscall-*.S to define them after the
- * vsyscall entry point. The kernel assumes that the addresses of these
- * routines are constant for all vsyscall implementations.
+ * This file is #include'd by int80.S et al to define them first thing.
+ * The kernel assumes that the addresses of these routines are constant
+ * for all vDSO implementations.
*/

+#include <linux/linkage.h>
#include <asm/unistd_32.h>
#include <asm/asm-offsets.h>

@@ -13,32 +14,29 @@
#define SYSCALL_ENTER_KERNEL int $0x80
#endif

-/* XXX
- Should these be named "_sigtramp" or something?
-*/
-
.text
- .org __kernel_vsyscall+32,0x90
.globl __kernel_sigreturn
.type __kernel_sigreturn,@function
+ ALIGN
__kernel_sigreturn:
.LSTART_sigreturn:
popl %eax /* XXX does this mean it needs unwind info? */
movl $__NR_sigreturn, %eax
SYSCALL_ENTER_KERNEL
.LEND_sigreturn:
+ nop
.size __kernel_sigreturn,.-.LSTART_sigreturn

- .balign 32
.globl __kernel_rt_sigreturn
.type __kernel_rt_sigreturn,@function
+ ALIGN
__kernel_rt_sigreturn:
.LSTART_rt_sigreturn:
movl $__NR_rt_sigreturn, %eax
SYSCALL_ENTER_KERNEL
.LEND_rt_sigreturn:
+ nop
.size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn
- .balign 32
.previous

.section .eh_frame,"a",@progbits
diff --git a/arch/x86/vdso/vdso32/syscall.S b/arch/x86/vdso/vdso32/syscall.S
index 333bfb5..c5ccc98 100644
--- a/arch/x86/vdso/vdso32/syscall.S
+++ b/arch/x86/vdso/vdso32/syscall.S
@@ -1,13 +1,18 @@
/*
- * Code for the vsyscall page. This version uses the syscall instruction.
+ * Code for the vDSO. This version uses the syscall instruction.
+ *
+ * First get the common code for the sigreturn entry points.
+ * This must come first.
*/
+#define SYSCALL_ENTER_KERNEL syscall
+#include "sigreturn.S"

-#include <asm/asm-offsets.h>
#include <asm/segment.h>

.text
.globl __kernel_vsyscall
.type __kernel_vsyscall,@function
+ ALIGN
__kernel_vsyscall:
.LSTART_vsyscall:
push %ebp
@@ -61,9 +66,3 @@ __kernel_vsyscall:
.uleb128 4
.align 4
.LENDFDE1:
-
-/*
- * Get the common code for the sigreturn entry points.
- */
-#define SYSCALL_ENTER_KERNEL syscall
-#include "sigreturn.S"
diff --git a/arch/x86/vdso/vdso32/sysenter.S b/arch/x86/vdso/vdso32/sysenter.S
index 109bfa3..a9bb825 100644
--- a/arch/x86/vdso/vdso32/sysenter.S
+++ b/arch/x86/vdso/vdso32/sysenter.S
@@ -1,11 +1,10 @@
/*
- * Code for the vsyscall page. This version uses the sysenter instruction.
+ * Code for the vDSO. This version uses the sysenter instruction.
*
- * 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"

/*
* The caller puts arg2 in %ecx, which gets pushed. The kernel will use
@@ -23,11 +22,12 @@
* arg6 from the stack.
*
* You can not use this vsyscall for the clone() syscall because the
- * three dwords on the parent stack do not get copied to the child.
+ * three words on the parent stack do not get copied to the child.
*/
.text
.globl __kernel_vsyscall
.type __kernel_vsyscall,@function
+ ALIGN
__kernel_vsyscall:
.LSTART_vsyscall:
push %ecx
@@ -114,8 +114,3 @@ VDSO32_SYSENTER_RETURN: /* Symbol used by sysenter.c via vdso32-syms.h */
.align 4
.LENDFDEDLSI:
.previous
-
-/*
- * Get the common code for the sigreturn entry points.
- */
-#include "sigreturn.S"

2007-11-19 22:11:55

by Roland McGrath

[permalink] [raw]
Subject: [PATCH 16/18] x86 vDSO: ia32 vsyscall removal


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 <[email protected]>
---
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 targets
-targets := $(foreach F,$(addprefix vsyscall-,sysenter syscall),\
- $F.o $F.so $F.so.dbg)
-
-# The DSO images are built using a special linker script
-quiet_cmd_syscall = SYSCALL $@
- cmd_syscall = $(CC) -m32 -nostdlib -shared \
- $(call ld-option, -Wl$(comma)--hash-style=sysv) \
- -Wl,-soname=linux-gate.so.1 -o $@ \
- -Wl,-T,$(filter-out FORCE,$^)
-
-$(obj)/%.so: OBJCOPYFLAGS := -S
-$(obj)/%.so: $(obj)/%.so.dbg FORCE
- $(call if_changed,objcopy)
-
-$(obj)/vsyscall-sysenter.so.dbg $(obj)/vsyscall-syscall.so.dbg: \
-$(obj)/vsyscall-%.so.dbg: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
- $(call if_changed,syscall)
-
-AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32
-AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32
-
-vdsos := vdso32-sysenter.so vdso32-syscall.so
-
-quiet_cmd_vdso_install = INSTALL $@
- cmd_vdso_install = cp $(@:vdso32-%.so=$(obj)/vsyscall-%.so.dbg) \
- $(MODLIB)/vdso/$@
-
-$(vdsos):
- @mkdir -p $(MODLIB)/vdso
- $(call cmd,vdso_install)
-
-vdso_install: $(vdsos)
diff --git a/arch/x86/ia32/syscall32.c b/arch/x86/ia32/syscall32.c
deleted file mode 100644
index 2c9c145..0000000
--- a/arch/x86/ia32/syscall32.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Copyright 2002,2003 Andi Kleen, SuSE Labs */
-
-/* vsyscall handling for 32bit processes. Map a stub page into it
- on demand because 32bit cannot reach the kernel's fixmaps */
-
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/gfp.h>
-#include <linux/init.h>
-#include <linux/stringify.h>
-#include <linux/security.h>
-#include <asm/proto.h>
-#include <asm/tlbflush.h>
-#include <asm/ia32_unistd.h>
-#include <asm/vsyscall32.h>
-
-extern unsigned char syscall32_syscall[], syscall32_syscall_end[];
-extern unsigned char syscall32_sysenter[], syscall32_sysenter_end[];
-extern int sysctl_vsyscall32;
-
-static struct page *syscall32_pages[1];
-static int use_sysenter = -1;
-
-struct linux_binprm;
-
-/* Setup a VMA at program startup for the vsyscall page */
-int syscall32_setup_pages(struct linux_binprm *bprm, int exstack)
-{
- struct mm_struct *mm = current->mm;
- int ret;
-
- down_write(&mm->mmap_sem);
- /*
- * MAYWRITE to allow gdb to COW and set breakpoints
- *
- * Make sure the vDSO gets into every core dump.
- * Dumping its contents makes post-mortem fully interpretable later
- * without matching up the same kernel and hardware config to see
- * what PC values meant.
- */
- /* Could randomize here */
- ret = install_special_mapping(mm, VSYSCALL32_BASE, PAGE_SIZE,
- VM_READ|VM_EXEC|
- VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
- VM_ALWAYSDUMP,
- syscall32_pages);
- if (ret == 0) {
- current->mm->context.vdso = (void __user *)VSYSCALL32_BASE;
- current_thread_info()->sysenter_return = VSYSCALL32_SYSEXIT;
- }
- up_write(&mm->mmap_sem);
- return ret;
-}
-
-static int __init init_syscall32(void)
-{
- char *syscall32_page = (void *)get_zeroed_page(GFP_KERNEL);
- if (!syscall32_page)
- panic("Cannot allocate syscall32 page");
- syscall32_pages[0] = virt_to_page(syscall32_page);
- if (use_sysenter > 0) {
- memcpy(syscall32_page, syscall32_sysenter,
- syscall32_sysenter_end - syscall32_sysenter);
- } else {
- memcpy(syscall32_page, syscall32_syscall,
- syscall32_syscall_end - syscall32_syscall);
- }
- return 0;
-}
-
-__initcall(init_syscall32);
-
-/* May not be __init: called during resume */
-void syscall32_cpu_init(void)
-{
- if (use_sysenter < 0)
- use_sysenter = (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL);
-
- /* Load these always in case some future AMD CPU supports
- SYSENTER from compat mode too. */
- checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS);
- checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL);
- checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target);
-
- wrmsrl(MSR_CSTAR, ia32_cstar_target);
-}
diff --git a/arch/x86/ia32/syscall32_syscall.S b/arch/x86/ia32/syscall32_syscall.S
deleted file mode 100644
index 933f0f0..0000000
--- a/arch/x86/ia32/syscall32_syscall.S
+++ /dev/null
@@ -1,17 +0,0 @@
-/* 32bit VDSOs mapped into user space. */
-
- .section ".init.data","aw"
-
- .globl syscall32_syscall
- .globl syscall32_syscall_end
-
-syscall32_syscall:
- .incbin "arch/x86/ia32/vsyscall-syscall.so"
-syscall32_syscall_end:
-
- .globl syscall32_sysenter
- .globl syscall32_sysenter_end
-
-syscall32_sysenter:
- .incbin "arch/x86/ia32/vsyscall-sysenter.so"
-syscall32_sysenter_end:
diff --git a/arch/x86/ia32/vsyscall-sigreturn.S b/arch/x86/ia32/vsyscall-sigreturn.S
deleted file mode 100644
index 295eecf..0000000
--- a/arch/x86/ia32/vsyscall-sigreturn.S
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Common code for the sigreturn entry points on the vsyscall page.
- * This code uses SYSCALL_ENTER_KERNEL (either syscall or int $0x80)
- * to enter the kernel.
- * This file is #include'd by vsyscall-*.S to define them after the
- * vsyscall entry point. The addresses we get for these entry points
- * by doing ".balign 32" must match in both versions of the page.
- */
-
- .code32
- .section .text.sigreturn,"ax"
- .balign 32
- .globl __kernel_sigreturn
- .type __kernel_sigreturn,@function
-__kernel_sigreturn:
-.LSTART_sigreturn:
- popl %eax
- movl $__NR_ia32_sigreturn, %eax
- SYSCALL_ENTER_KERNEL
-.LEND_sigreturn:
- .size __kernel_sigreturn,.-.LSTART_sigreturn
-
- .section .text.rtsigreturn,"ax"
- .balign 32
- .globl __kernel_rt_sigreturn
- .type __kernel_rt_sigreturn,@function
-__kernel_rt_sigreturn:
-.LSTART_rt_sigreturn:
- movl $__NR_ia32_rt_sigreturn, %eax
- SYSCALL_ENTER_KERNEL
-.LEND_rt_sigreturn:
- .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn
-
- .section .eh_frame,"a",@progbits
-.LSTARTFRAMES:
- .long .LENDCIES-.LSTARTCIES
-.LSTARTCIES:
- .long 0 /* CIE ID */
- .byte 1 /* Version number */
- .string "zRS" /* NUL-terminated augmentation string */
- .uleb128 1 /* Code alignment factor */
- .sleb128 -4 /* Data alignment factor */
- .byte 8 /* Return address register column */
- .uleb128 1 /* Augmentation value length */
- .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
- .byte 0x0c /* DW_CFA_def_cfa */
- .uleb128 4
- .uleb128 4
- .byte 0x88 /* DW_CFA_offset, column 0x8 */
- .uleb128 1
- .align 4
-.LENDCIES:
-
- .long .LENDFDE2-.LSTARTFDE2 /* Length FDE */
-.LSTARTFDE2:
- .long .LSTARTFDE2-.LSTARTFRAMES /* CIE pointer */
- /* HACK: The dwarf2 unwind routines will subtract 1 from the
- return address to get an address in the middle of the
- presumed call instruction. Since we didn't get here via
- a call, we need to include the nop before the real start
- to make up for it. */
- .long .LSTART_sigreturn-1-. /* PC-relative start address */
- .long .LEND_sigreturn-.LSTART_sigreturn+1
- .uleb128 0 /* Augmentation length */
- /* What follows are the instructions for the table generation.
- We record the locations of each register saved. This is
- complicated by the fact that the "CFA" is always assumed to
- be the value of the stack pointer in the caller. This means
- that we must define the CFA of this body of code to be the
- saved value of the stack pointer in the sigcontext. Which
- also means that there is no fixed relation to the other
- saved registers, which means that we must use DW_CFA_expression
- to compute their addresses. It also means that when we
- adjust the stack with the popl, we have to do it all over again. */
-
-#define do_cfa_expr(offset) \
- .byte 0x0f; /* DW_CFA_def_cfa_expression */ \
- .uleb128 1f-0f; /* length */ \
-0: .byte 0x74; /* DW_OP_breg4 */ \
- .sleb128 offset; /* offset */ \
- .byte 0x06; /* DW_OP_deref */ \
-1:
-
-#define do_expr(regno, offset) \
- .byte 0x10; /* DW_CFA_expression */ \
- .uleb128 regno; /* regno */ \
- .uleb128 1f-0f; /* length */ \
-0: .byte 0x74; /* DW_OP_breg4 */ \
- .sleb128 offset; /* offset */ \
-1:
-
- do_cfa_expr(IA32_SIGCONTEXT_esp+4)
- do_expr(0, IA32_SIGCONTEXT_eax+4)
- do_expr(1, IA32_SIGCONTEXT_ecx+4)
- do_expr(2, IA32_SIGCONTEXT_edx+4)
- do_expr(3, IA32_SIGCONTEXT_ebx+4)
- do_expr(5, IA32_SIGCONTEXT_ebp+4)
- do_expr(6, IA32_SIGCONTEXT_esi+4)
- do_expr(7, IA32_SIGCONTEXT_edi+4)
- do_expr(8, IA32_SIGCONTEXT_eip+4)
-
- .byte 0x42 /* DW_CFA_advance_loc 2 -- nop; popl eax. */
-
- do_cfa_expr(IA32_SIGCONTEXT_esp)
- do_expr(0, IA32_SIGCONTEXT_eax)
- do_expr(1, IA32_SIGCONTEXT_ecx)
- do_expr(2, IA32_SIGCONTEXT_edx)
- do_expr(3, IA32_SIGCONTEXT_ebx)
- do_expr(5, IA32_SIGCONTEXT_ebp)
- do_expr(6, IA32_SIGCONTEXT_esi)
- do_expr(7, IA32_SIGCONTEXT_edi)
- do_expr(8, IA32_SIGCONTEXT_eip)
-
- .align 4
-.LENDFDE2:
-
- .long .LENDFDE3-.LSTARTFDE3 /* Length FDE */
-.LSTARTFDE3:
- .long .LSTARTFDE3-.LSTARTFRAMES /* CIE pointer */
- /* HACK: See above wrt unwind library assumptions. */
- .long .LSTART_rt_sigreturn-1-. /* PC-relative start address */
- .long .LEND_rt_sigreturn-.LSTART_rt_sigreturn+1
- .uleb128 0 /* Augmentation */
- /* What follows are the instructions for the table generation.
- We record the locations of each register saved. This is
- slightly less complicated than the above, since we don't
- modify the stack pointer in the process. */
-
- do_cfa_expr(IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esp)
- do_expr(0, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eax)
- do_expr(1, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ecx)
- do_expr(2, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edx)
- do_expr(3, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebx)
- do_expr(5, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebp)
- do_expr(6, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esi)
- do_expr(7, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edi)
- do_expr(8, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eip)
-
- .align 4
-.LENDFDE3:
-
-#include "../vdso/vdso32/note.S"
diff --git a/arch/x86/ia32/vsyscall-syscall.S b/arch/x86/ia32/vsyscall-syscall.S
deleted file mode 100644
index cf9ef67..0000000
--- a/arch/x86/ia32/vsyscall-syscall.S
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Code for the vsyscall page. This version uses the syscall instruction.
- */
-
-#include <asm/ia32_unistd.h>
-#include <asm/asm-offsets.h>
-#include <asm/segment.h>
-
- .code32
- .text
- .section .text.vsyscall,"ax"
- .globl __kernel_vsyscall
- .type __kernel_vsyscall,@function
-__kernel_vsyscall:
-.LSTART_vsyscall:
- push %ebp
-.Lpush_ebp:
- movl %ecx, %ebp
- syscall
- movl $__USER32_DS, %ecx
- movl %ecx, %ss
- movl %ebp, %ecx
- popl %ebp
-.Lpop_ebp:
- ret
-.LEND_vsyscall:
- .size __kernel_vsyscall,.-.LSTART_vsyscall
-
- .section .eh_frame,"a",@progbits
-.LSTARTFRAME:
- .long .LENDCIE-.LSTARTCIE
-.LSTARTCIE:
- .long 0 /* CIE ID */
- .byte 1 /* Version number */
- .string "zR" /* NUL-terminated augmentation string */
- .uleb128 1 /* Code alignment factor */
- .sleb128 -4 /* Data alignment factor */
- .byte 8 /* Return address register column */
- .uleb128 1 /* Augmentation value length */
- .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
- .byte 0x0c /* DW_CFA_def_cfa */
- .uleb128 4
- .uleb128 4
- .byte 0x88 /* DW_CFA_offset, column 0x8 */
- .uleb128 1
- .align 4
-.LENDCIE:
-
- .long .LENDFDE1-.LSTARTFDE1 /* Length FDE */
-.LSTARTFDE1:
- .long .LSTARTFDE1-.LSTARTFRAME /* CIE pointer */
- .long .LSTART_vsyscall-. /* PC-relative start address */
- .long .LEND_vsyscall-.LSTART_vsyscall
- .uleb128 0 /* Augmentation length */
- /* What follows are the instructions for the table generation.
- We have to record all changes of the stack pointer. */
- .byte 0x40 + .Lpush_ebp-.LSTART_vsyscall /* DW_CFA_advance_loc */
- .byte 0x0e /* DW_CFA_def_cfa_offset */
- .uleb128 8
- .byte 0x85, 0x02 /* DW_CFA_offset %ebp -8 */
- .byte 0x40 + .Lpop_ebp-.Lpush_ebp /* DW_CFA_advance_loc */
- .byte 0xc5 /* DW_CFA_restore %ebp */
- .byte 0x0e /* DW_CFA_def_cfa_offset */
- .uleb128 4
- .align 4
-.LENDFDE1:
-
-#define SYSCALL_ENTER_KERNEL syscall
-#include "vsyscall-sigreturn.S"
diff --git a/arch/x86/ia32/vsyscall-sysenter.S b/arch/x86/ia32/vsyscall-sysenter.S
deleted file mode 100644
index ae056e5..0000000
--- a/arch/x86/ia32/vsyscall-sysenter.S
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Code for the vsyscall page. This version uses the sysenter instruction.
- */
-
-#include <asm/ia32_unistd.h>
-#include <asm/asm-offsets.h>
-
- .code32
- .text
- .section .text.vsyscall,"ax"
- .globl __kernel_vsyscall
- .type __kernel_vsyscall,@function
-__kernel_vsyscall:
-.LSTART_vsyscall:
- push %ecx
-.Lpush_ecx:
- push %edx
-.Lpush_edx:
- push %ebp
-.Lenter_kernel:
- movl %esp,%ebp
- sysenter
- .space 7,0x90
- jmp .Lenter_kernel
- /* 16: System call normal return point is here! */
- pop %ebp
-.Lpop_ebp:
- pop %edx
-.Lpop_edx:
- pop %ecx
-.Lpop_ecx:
- ret
-.LEND_vsyscall:
- .size __kernel_vsyscall,.-.LSTART_vsyscall
-
- .section .eh_frame,"a",@progbits
-.LSTARTFRAME:
- .long .LENDCIE-.LSTARTCIE
-.LSTARTCIE:
- .long 0 /* CIE ID */
- .byte 1 /* Version number */
- .string "zR" /* NUL-terminated augmentation string */
- .uleb128 1 /* Code alignment factor */
- .sleb128 -4 /* Data alignment factor */
- .byte 8 /* Return address register column */
- .uleb128 1 /* Augmentation value length */
- .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
- .byte 0x0c /* DW_CFA_def_cfa */
- .uleb128 4
- .uleb128 4
- .byte 0x88 /* DW_CFA_offset, column 0x8 */
- .uleb128 1
- .align 4
-.LENDCIE:
-
- .long .LENDFDE1-.LSTARTFDE1 /* Length FDE */
-.LSTARTFDE1:
- .long .LSTARTFDE1-.LSTARTFRAME /* CIE pointer */
- .long .LSTART_vsyscall-. /* PC-relative start address */
- .long .LEND_vsyscall-.LSTART_vsyscall
- .uleb128 0 /* Augmentation length */
- /* What follows are the instructions for the table generation.
- We have to record all changes of the stack pointer. */
- .byte 0x04 /* DW_CFA_advance_loc4 */
- .long .Lpush_ecx-.LSTART_vsyscall
- .byte 0x0e /* DW_CFA_def_cfa_offset */
- .byte 0x08 /* RA at offset 8 now */
- .byte 0x04 /* DW_CFA_advance_loc4 */
- .long .Lpush_edx-.Lpush_ecx
- .byte 0x0e /* DW_CFA_def_cfa_offset */
- .byte 0x0c /* RA at offset 12 now */
- .byte 0x04 /* DW_CFA_advance_loc4 */
- .long .Lenter_kernel-.Lpush_edx
- .byte 0x0e /* DW_CFA_def_cfa_offset */
- .byte 0x10 /* RA at offset 16 now */
- .byte 0x85, 0x04 /* DW_CFA_offset %ebp -16 */
- /* Finally the epilogue. */
- .byte 0x04 /* DW_CFA_advance_loc4 */
- .long .Lpop_ebp-.Lenter_kernel
- .byte 0x0e /* DW_CFA_def_cfa_offset */
- .byte 0x12 /* RA at offset 12 now */
- .byte 0xc5 /* DW_CFA_restore %ebp */
- .byte 0x04 /* DW_CFA_advance_loc4 */
- .long .Lpop_edx-.Lpop_ebp
- .byte 0x0e /* DW_CFA_def_cfa_offset */
- .byte 0x08 /* RA at offset 8 now */
- .byte 0x04 /* DW_CFA_advance_loc4 */
- .long .Lpop_ecx-.Lpop_edx
- .byte 0x0e /* DW_CFA_def_cfa_offset */
- .byte 0x04 /* RA at offset 4 now */
- .align 4
-.LENDFDE1:
-
-#define SYSCALL_ENTER_KERNEL int $0x80
-#include "vsyscall-sigreturn.S"
diff --git a/arch/x86/ia32/vsyscall.lds b/arch/x86/ia32/vsyscall.lds
deleted file mode 100644
index 1dc86ff..0000000
--- a/arch/x86/ia32/vsyscall.lds
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Linker script for vsyscall DSO. The vsyscall page is an ELF shared
- * object prelinked to its virtual address. This script controls its layout.
- */
-
-/* This must match <asm/fixmap.h>. */
-VSYSCALL_BASE = 0xffffe000;
-
-SECTIONS
-{
- . = VSYSCALL_BASE + 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) }
-
- /* This linker script is used both with -r and with -shared.
- For the layouts to match, we need to skip more than enough
- space for the dynamic symbol table et al. If this amount
- is insufficient, ld -shared will barf. Just increase it here. */
- . = VSYSCALL_BASE + 0x400;
-
- .text.vsyscall : { *(.text.vsyscall) } :text =0x90909090
-
- /* This is an 32bit object and we cannot easily get the offsets
- into the 64bit kernel. Just hardcode them here. This assumes
- that all the stubs don't need more than 0x100 bytes. */
- . = VSYSCALL_BASE + 0x500;
-
- .text.sigreturn : { *(.text.sigreturn) } :text =0x90909090
-
- . = VSYSCALL_BASE + 0x600;
-
- .text.rtsigreturn : { *(.text.rtsigreturn) } :text =0x90909090
-
- .note : { *(.note.*) } :text :note
- .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
- .eh_frame : { KEEP (*(.eh_frame)) } :text
- .dynamic : { *(.dynamic) } :text :dynamic
- .useless : {
- *(.got.plt) *(.got)
- *(.data .data.* .gnu.linkonce.d.*)
- *(.dynbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- } :text
-}
-
-/*
- * We must supply the ELF program headers explicitly to get just one
- * PT_LOAD segment, and set the flags explicitly to make segments read-only.
- */
-PHDRS
-{
- text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
- dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
- note PT_NOTE FLAGS(4); /* PF_R */
- eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */
-}
-
-/*
- * This controls what symbols we export from the DSO.
- */
-VERSION
-{
- LINUX_2.5 {
- global:
- __kernel_vsyscall;
- __kernel_sigreturn;
- __kernel_rt_sigreturn;
-
- local: *;
- };
-}
-
-/* The ELF entry point can be used to set the AT_SYSINFO value. */
-ENTRY(__kernel_vsyscall);
diff --git a/include/asm-x86/Kbuild b/include/asm-x86/Kbuild
index 12db5a1..22e3a28 100644
--- a/include/asm-x86/Kbuild
+++ b/include/asm-x86/Kbuild
@@ -9,7 +9,6 @@ header-y += prctl.h
header-y += ptrace-abi.h
header-y += sigcontext32.h
header-y += ucontext.h
-header-y += vsyscall32.h

unifdef-y += e820.h
unifdef-y += ist.h
diff --git a/include/asm-x86/vsyscall32.h b/include/asm-x86/vsyscall32.h
deleted file mode 100644
index c631c08..0000000
--- a/include/asm-x86/vsyscall32.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef _ASM_VSYSCALL32_H
-#define _ASM_VSYSCALL32_H 1
-
-/* Values need to match arch/x86_64/ia32/vsyscall.lds */
-
-#ifdef __ASSEMBLY__
-#define VSYSCALL32_BASE 0xffffe000
-#define VSYSCALL32_SYSEXIT (VSYSCALL32_BASE + 0x410)
-#else
-#define VSYSCALL32_BASE 0xffffe000UL
-#define VSYSCALL32_END (VSYSCALL32_BASE + PAGE_SIZE)
-#define VSYSCALL32_EHDR ((const struct elf32_hdr *) VSYSCALL32_BASE)
-
-#define VSYSCALL32_VSYSCALL ((void *)VSYSCALL32_BASE + 0x400)
-#define VSYSCALL32_SYSEXIT ((void *)VSYSCALL32_BASE + 0x410)
-#define VSYSCALL32_SIGRETURN ((void __user *)VSYSCALL32_BASE + 0x500)
-#define VSYSCALL32_RTSIGRETURN ((void __user *)VSYSCALL32_BASE + 0x600)
-#endif
-
-#endif

2007-11-20 13:06:10

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [PATCH 06/18] x86 vDSO: arch/x86/vdso/vdso32

Roland,

On Mon, 19 Nov 2007, Roland McGrath wrote:

>
> 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 <[email protected]>
> ---
> 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%)

I just stumbled accross those renames, when I tried to apply your
series from the mailbox. I guess there is some option to git which
creates a real patch. I fixed it up manually for now.

Thanks,

tglx

2007-11-20 20:58:44

by Roland McGrath

[permalink] [raw]
Subject: Re: [PATCH 06/18] x86 vDSO: arch/x86/vdso/vdso32

> > 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%)
>
> I just stumbled accross those renames, when I tried to apply your
> series from the mailbox. I guess there is some option to git which
> creates a real patch. I fixed it up manually for now.

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

2007-11-20 23:08:20

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [PATCH 06/18] x86 vDSO: arch/x86/vdso/vdso32

On Tue, 20 Nov 2007, Roland McGrath wrote:

> > > 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%)
> >
> > I just stumbled accross those renames, when I tried to apply your
> > series from the mailbox. I guess there is some option to git which
> > creates a real patch. I fixed it up manually for now.
>
> 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.)

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



2007-11-20 23:27:48

by Roland McGrath

[permalink] [raw]
Subject: Re: [PATCH 06/18] x86 vDSO: arch/x86/vdso/vdso32

> git format-patch -p
>
> does the trick at least here :)

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

2007-11-20 23:52:22

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [PATCH 06/18] x86 vDSO: arch/x86/vdso/vdso32

On Tue, 20 Nov 2007, Roland McGrath wrote:

> > git format-patch -p
> >
> > does the trick at least here :)
>
> 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.

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

2007-11-21 00:02:22

by Zachary Amsden

[permalink] [raw]
Subject: Re: [PATCH 13/18] x86 vDSO: ia32 sysenter_return

On Mon, 2007-11-19 at 14:06 -0800, Roland McGrath wrote:
> 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.

I hope you won't carry the dependency of COMPAT_VDSO over to 64-bit when
that happens.

> @@ -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

8*3-THREAD_SIZE is not very intuitive. Can you add a comment on the
math?

Zach

2007-11-21 00:10:22

by Zachary Amsden

[permalink] [raw]
Subject: Re: [PATCH 15/18] x86 vDSO: consolidate vdso32

On Mon, 2007-11-19 at 14:06 -0800, Roland McGrath wrote:
> 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.)

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

2007-11-21 00:13:53

by Ingo Molnar

[permalink] [raw]
Subject: Re: [PATCH 15/18] x86 vDSO: consolidate vdso32


* Zachary Amsden <[email protected]> wrote:

> > 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.)
>
> 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.

we can phase it out, via the Documentation/feature-removal-schedule.txt
mechanism.

Ingo

2007-11-21 00:16:42

by Andi Kleen

[permalink] [raw]
Subject: Re: [PATCH 15/18] x86 vDSO: consolidate vdso32


> 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,

I would be severly opposed to that. You cannot break compatibility to a large
chunk of userland. You would also break some of my test setups.

> 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.

Yes it has.

-Andi

2007-11-21 00:32:54

by Roland McGrath

[permalink] [raw]
Subject: Re: [PATCH 15/18] x86 vDSO: consolidate vdso32

For 64-bit, the hack consists of a switch that chooses whether to use a
fixed address or a generically-assigned one, that's all there is to it.
So it costs about nothing.

Even for 32-bit, CONFIG_COMPAT_VDSO for a while now is doing nothing but
changing the default of the sysctl variable. There the fixmap part is some
extra stuff that could go away in the ideal in the fullness of time. But
it doesn't hurt to keep it, especially when never turned on.

The upshot of my changes is that whatever the choices available for the
layout of 32-bit address spaces, they should match on 32-bit and 64-bit kernels.
If you want to reduce that set of choices in both, that is a separate issue.


Thanks,
Roland

2007-11-21 00:34:26

by Roland McGrath

[permalink] [raw]
Subject: Re: [PATCH 13/18] x86 vDSO: ia32 sysenter_return

> > @@ -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
>
> 8*3-THREAD_SIZE is not very intuitive. Can you add a comment on the
> math?

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

2007-11-21 06:00:29

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH 07/18] x86 vDSO: vdso32 build

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

On Mon, Nov 19, 2007 at 02:05:32PM -0800, Roland McGrath wrote:
>
> 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 <[email protected]>
> ---
> 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/

Should we teach kbuild to create dirs specified in targets?
Or we could 'fix' it so you do not need the override.

> +
> +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) += -m32
> +
> +$(vdso32.so-y:%=$(obj)/vdso32-%.so.dbg): $(obj)/vdso32-%.so.dbg: FORCE \
> + $(obj)/vdso32/vdso32.lds \
> + $(obj)/vdso32/note.o \
> + $(obj)/vdso32/%.o
> + $(call if_changed,vdso)
> +
> +# Make vdso32-*-syms.lds from each image, and then make sure they match.
> +# The only difference should be that some do not define VDSO32_SYSENTER_RETURN.
> +
> +targets += vdso32-syms.lds $(vdso32.so-y:%=vdso32-%-syms.lds)
> +
> +quiet_cmd_vdso32sym = VDSOSYM $@
> +define cmd_vdso32sym
> + if LC_ALL=C sort -u $(filter-out FORCE,$^) > $(@D)/.tmp_$(@F) && \
> + $(foreach H,$(filter-out FORCE,$^),\
> + if grep -q VDSO32_SYSENTER_RETURN $H; \
> + then diff -u $(@D)/.tmp_$(@F) $H; \
> + else sed /VDSO32_SYSENTER_RETURN/d $(@D)/.tmp_$(@F) | \
> + diff -u - $H; fi &&) : ;\
> + then mv -f $(@D)/.tmp_$(@F) $@; \
> + else rm -f $(@D)/.tmp_$(@F); exit 1; \
> + fi
> +endef

use "set -e; in front of this shell script to bail out early
in case of errors.


> +
> +$(obj)/vdso32-syms.lds: $(vdso32.so-y:%=$(obj)/vdso32-%-syms.lds) FORCE
> + $(call if_changed,vdso32sym)
> +
> +#
> +# The DSO images are built using a special linker script.
> +#
> +quiet_cmd_vdso = VDSO $@
> + cmd_vdso = $(CC) -nostdlib -o $@ \
> + $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
> + -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^)
> +
> +VDSO_LDFLAGS = -fPIC -shared $(call ld-option, -Wl$(comma)--hash-style=sysv)

Do you need to specify soname for 64-bit - seems missing?

> +
> +#
> +# Install the unstripped copy of vdso*.so listed in $(vdso-install-y).
> +#
> quiet_cmd_vdso_install = INSTALL $@
> cmd_vdso_install = cp $(obj)/[email protected] $(MODLIB)/vdso/$@
> -vdso.so:
> +$(vdso-install-y): %.so: $(obj)/%.so.dbg FORCE
> @mkdir -p $(MODLIB)/vdso
> $(call cmd,vdso_install)
Please use $(Q) in preference for @
Then it is easier to debug using make V=1

> -vdso_install: vdso.so
> +PHONY += vdso_install $(vdso-install-y)
> +vdso_install: $(vdso-install-y)

2007-11-21 07:10:32

by Roland McGrath

[permalink] [raw]
Subject: Re: [PATCH 07/18] x86 vDSO: vdso32 build

> > +# This makes sure the $(obj) subdirectory exists even though vdso32/
> > +# is not a kbuild sub-make subdirectory.
> > +override obj-dirs = $(dir $(obj)) $(obj)/vdso32/
>
> Should we teach kbuild to create dirs specified in targets?
> Or we could 'fix' it so you do not need the override.

Something cleaner would be nice, yes. I'll leave it to you to decide.

> use "set -e; in front of this shell script to bail out early
> in case of errors.

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
aren't tested with && or if already. set -e would have no effect.

> > +VDSO_LDFLAGS = -fPIC -shared $(call ld-option, -Wl$(comma)--hash-style=sysv)
>
> Do you need to specify soname for 64-bit - seems missing?

Using this rule for the 64-bit vDSO is not in this patch.
Patch 18/18 defines VDSO_LDFLAGS_vdso.lds for this.

> > +$(vdso-install-y): %.so: $(obj)/%.so.dbg FORCE
> > @mkdir -p $(MODLIB)/vdso
> > $(call cmd,vdso_install)
> Please use $(Q) in preference for @
> Then it is easier to debug using make V=1

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

2007-11-21 07:31:25

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH 07/18] x86 vDSO: vdso32 build

On Tue, Nov 20, 2007 at 11:10:15PM -0800, Roland McGrath wrote:
> > > +# This makes sure the $(obj) subdirectory exists even though vdso32/
> > > +# is not a kbuild sub-make subdirectory.
> > > +override obj-dirs = $(dir $(obj)) $(obj)/vdso32/
> >
> > Should we teach kbuild to create dirs specified in targets?
> > Or we could 'fix' it so you do not need the override.
>
> Something cleaner would be nice, yes. I'll leave it to you to decide.

OK - if I come up with something smart I will convert the vdso stuff.

>
> > use "set -e; in front of this shell script to bail out early
> > in case of errors.
>
> 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
> aren't tested with && or if already. set -e would have no effect.
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

2007-11-21 07:56:27

by Roland McGrath

[permalink] [raw]
Subject: Re: [PATCH 07/18] x86 vDSO: vdso32 build

> 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.

No, you need set -o pipefail for that (which is a bashism).


Thanks,
Roland

2007-11-27 01:54:43

by Linus Torvalds

[permalink] [raw]
Subject: Re: [PATCH 06/18] x86 vDSO: arch/x86/vdso/vdso32



On Tue, 20 Nov 2007, Roland McGrath wrote:
>
> > git format-patch -p
> >
> > does the trick at least here :)
>
> 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.

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..

2007-11-27 02:02:13

by Roland McGrath

[permalink] [raw]
Subject: Re: [PATCH 06/18] x86 vDSO: arch/x86/vdso/vdso32

> But whatever works. I'm currently skipping the patches since they didn't
> seem like 2.6.24 fodder anyway.

The vdso cleanups are pure cleanup, not fixing anything that's actively broken.


Thanks,
Roland