aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/boot/compressed/relocs.c1
-rw-r--r--arch/i386/kernel/vsyscall-note.S15
-rw-r--r--arch/i386/xen/setup.c15
-rw-r--r--arch/i386/xen/vdso.h4
4 files changed, 29 insertions, 6 deletions
diff --git a/arch/i386/boot/compressed/relocs.c b/arch/i386/boot/compressed/relocs.c
index b0e21c3cee5c..2d77ee728f92 100644
--- a/arch/i386/boot/compressed/relocs.c
+++ b/arch/i386/boot/compressed/relocs.c
@@ -31,6 +31,7 @@ static const char* safe_abs_relocs[] = {
31 "__kernel_rt_sigreturn", 31 "__kernel_rt_sigreturn",
32 "__kernel_sigreturn", 32 "__kernel_sigreturn",
33 "SYSENTER_RETURN", 33 "SYSENTER_RETURN",
34 "VDSO_NOTE_MASK",
34 "xen_irq_disable_direct_reloc", 35 "xen_irq_disable_direct_reloc",
35 "xen_save_fl_direct_reloc", 36 "xen_save_fl_direct_reloc",
36}; 37};
diff --git a/arch/i386/kernel/vsyscall-note.S b/arch/i386/kernel/vsyscall-note.S
index 271f16a8ca01..07c0daf78237 100644
--- a/arch/i386/kernel/vsyscall-note.S
+++ b/arch/i386/kernel/vsyscall-note.S
@@ -14,7 +14,6 @@ ELFNOTE_START(Linux, 0, "a")
14ELFNOTE_END 14ELFNOTE_END
15 15
16#ifdef CONFIG_XEN 16#ifdef CONFIG_XEN
17
18/* 17/*
19 * Add a special note telling glibc's dynamic linker a fake hardware 18 * Add a special note telling glibc's dynamic linker a fake hardware
20 * flavor that it will use to choose the search path for libraries in the 19 * flavor that it will use to choose the search path for libraries in the
@@ -28,15 +27,19 @@ ELFNOTE_END
28 * It should contain: 27 * It should contain:
29 * hwcap 1 nosegneg 28 * hwcap 1 nosegneg
30 * to match the mapping of bit to name that we give here. 29 * to match the mapping of bit to name that we give here.
30 *
31 * At runtime, the fake hardware feature will be considered to be present
32 * if its bit is set in the mask word. So, we start with the mask 0, and
33 * at boot time we set VDSO_NOTE_NONEGSEG_BIT if running under Xen.
31 */ 34 */
32 35
33/* Bit used for the pseudo-hwcap for non-negative segments. We use 36#include "../xen/vdso.h" /* Defines VDSO_NOTE_NONEGSEG_BIT. */
34 bit 1 to avoid bugs in some versions of glibc when bit 0 is
35 used; the choice is otherwise arbitrary. */
36#define VDSO_NOTE_NONEGSEG_BIT 1
37 37
38 .globl VDSO_NOTE_MASK
38ELFNOTE_START(GNU, 2, "a") 39ELFNOTE_START(GNU, 2, "a")
39 .long 1, 1<<VDSO_NOTE_NONEGSEG_BIT /* ncaps, mask */ 40 .long 1 /* ncaps */
41VDSO_NOTE_MASK:
42 .long 0 /* mask */
40 .byte VDSO_NOTE_NONEGSEG_BIT; .asciz "nosegneg" /* bit, name */ 43 .byte VDSO_NOTE_NONEGSEG_BIT; .asciz "nosegneg" /* bit, name */
41ELFNOTE_END 44ELFNOTE_END
42#endif 45#endif
diff --git a/arch/i386/xen/setup.c b/arch/i386/xen/setup.c
index 2fe6eac510f0..f84e77226646 100644
--- a/arch/i386/xen/setup.c
+++ b/arch/i386/xen/setup.c
@@ -19,6 +19,7 @@
19#include <xen/features.h> 19#include <xen/features.h>
20 20
21#include "xen-ops.h" 21#include "xen-ops.h"
22#include "vdso.h"
22 23
23/* These are code, but not functions. Defined in entry.S */ 24/* These are code, but not functions. Defined in entry.S */
24extern const char xen_hypervisor_callback[]; 25extern const char xen_hypervisor_callback[];
@@ -55,6 +56,18 @@ static void xen_idle(void)
55 } 56 }
56} 57}
57 58
59/*
60 * Set the bit indicating "nosegneg" library variants should be used.
61 */
62static void fiddle_vdso(void)
63{
64 extern u32 VDSO_NOTE_MASK; /* See ../kernel/vsyscall-note.S. */
65 extern char vsyscall_int80_start;
66 u32 *mask = (u32 *) ((unsigned long) &VDSO_NOTE_MASK - VDSO_PRELINK +
67 &vsyscall_int80_start);
68 *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT;
69}
70
58void __init xen_arch_setup(void) 71void __init xen_arch_setup(void)
59{ 72{
60 struct physdev_set_iopl set_iopl; 73 struct physdev_set_iopl set_iopl;
@@ -93,4 +106,6 @@ void __init xen_arch_setup(void)
93#endif 106#endif
94 107
95 paravirt_disable_iospace(); 108 paravirt_disable_iospace();
109
110 fiddle_vdso();
96} 111}
diff --git a/arch/i386/xen/vdso.h b/arch/i386/xen/vdso.h
new file mode 100644
index 000000000000..861fedfe5230
--- /dev/null
+++ b/arch/i386/xen/vdso.h
@@ -0,0 +1,4 @@
1/* Bit used for the pseudo-hwcap for non-negative segments. We use
2 bit 1 to avoid bugs in some versions of glibc when bit 0 is
3 used; the choice is otherwise arbitrary. */
4#define VDSO_NOTE_NONEGSEG_BIT 1