aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/vdso
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@amacapital.net>2014-03-17 18:22:08 -0400
committerH. Peter Anvin <hpa@linux.intel.com>2014-03-18 15:52:33 -0400
commitb4b541a610c4db8643b36030ee5012203ca65778 (patch)
tree80019c3a48ec605144b5c88f147a46ff7869eb1a /arch/x86/vdso
parentef721987aef0cc0abba08c88810f2155f76b0b1f (diff)
x86, vdso: Patch alternatives in the 32-bit VDSO
We need the alternatives mechanism for rdtsc_barrier() to work. Signed-off-by: Stefani Seibold <stefani@seibold.net> Link: http://lkml.kernel.org/r/1395094933-14252-9-git-send-email-stefani@seibold.net Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/vdso')
-rw-r--r--arch/x86/vdso/Makefile3
-rw-r--r--arch/x86/vdso/vdso32-setup.c23
-rw-r--r--arch/x86/vdso/vma.c13
3 files changed, 24 insertions, 15 deletions
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile
index fd14be1d1472..7a3d13e23f25 100644
--- a/arch/x86/vdso/Makefile
+++ b/arch/x86/vdso/Makefile
@@ -21,7 +21,8 @@ vobjs-$(VDSOX32-y) += $(vobjx32s-compat)
21vobj64s := $(filter-out $(vobjx32s-compat),$(vobjs-y)) 21vobj64s := $(filter-out $(vobjx32s-compat),$(vobjs-y))
22 22
23# files to link into kernel 23# files to link into kernel
24obj-$(VDSO64-y) += vma.o vdso.o 24obj-y += vma.o
25obj-$(VDSO64-y) += vdso.o
25obj-$(VDSOX32-y) += vdsox32.o 26obj-$(VDSOX32-y) += vdsox32.o
26obj-$(VDSO32-y) += vdso32.o vdso32-setup.o 27obj-$(VDSO32-y) += vdso32.o vdso32-setup.o
27 28
diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c
index ab20c04b688a..e0fc767bcad3 100644
--- a/arch/x86/vdso/vdso32-setup.c
+++ b/arch/x86/vdso/vdso32-setup.c
@@ -112,24 +112,25 @@ void enable_sep_cpu(void)
112 112
113int __init sysenter_setup(void) 113int __init sysenter_setup(void)
114{ 114{
115 void *syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); 115 void *vdso_page = (void *)get_zeroed_page(GFP_ATOMIC);
116 const void *vsyscall; 116 const void *vdso;
117 size_t vsyscall_len; 117 size_t vdso_len;
118 118
119 vdso32_pages[0] = virt_to_page(syscall_page); 119 vdso32_pages[0] = virt_to_page(vdso_page);
120 120
121 if (vdso32_syscall()) { 121 if (vdso32_syscall()) {
122 vsyscall = &vdso32_syscall_start; 122 vdso = &vdso32_syscall_start;
123 vsyscall_len = &vdso32_syscall_end - &vdso32_syscall_start; 123 vdso_len = &vdso32_syscall_end - &vdso32_syscall_start;
124 } else if (vdso32_sysenter()){ 124 } else if (vdso32_sysenter()){
125 vsyscall = &vdso32_sysenter_start; 125 vdso = &vdso32_sysenter_start;
126 vsyscall_len = &vdso32_sysenter_end - &vdso32_sysenter_start; 126 vdso_len = &vdso32_sysenter_end - &vdso32_sysenter_start;
127 } else { 127 } else {
128 vsyscall = &vdso32_int80_start; 128 vdso = &vdso32_int80_start;
129 vsyscall_len = &vdso32_int80_end - &vdso32_int80_start; 129 vdso_len = &vdso32_int80_end - &vdso32_int80_start;
130 } 130 }
131 131
132 memcpy(syscall_page, vsyscall, vsyscall_len); 132 memcpy(vdso_page, vdso, vdso_len);
133 patch_vdso32(vdso_page, vdso_len);
133 134
134 return 0; 135 return 0;
135} 136}
diff --git a/arch/x86/vdso/vma.c b/arch/x86/vdso/vma.c
index 431e87544411..7345bc9a1af6 100644
--- a/arch/x86/vdso/vma.c
+++ b/arch/x86/vdso/vma.c
@@ -16,6 +16,7 @@
16#include <asm/vdso.h> 16#include <asm/vdso.h>
17#include <asm/page.h> 17#include <asm/page.h>
18 18
19#if defined(CONFIG_X86_64)
19unsigned int __read_mostly vdso_enabled = 1; 20unsigned int __read_mostly vdso_enabled = 1;
20 21
21extern char vdso_start[], vdso_end[]; 22extern char vdso_start[], vdso_end[];
@@ -28,8 +29,12 @@ static unsigned vdso_size;
28extern char vdsox32_start[], vdsox32_end[]; 29extern char vdsox32_start[], vdsox32_end[];
29extern struct page *vdsox32_pages[]; 30extern struct page *vdsox32_pages[];
30static unsigned vdsox32_size; 31static unsigned vdsox32_size;
32#endif
33#endif
31 34
32static void __init patch_vdsox32(void *vdso, size_t len) 35#if defined(CONFIG_X86_32) || defined(CONFIG_X86_X32_ABI) || \
36 defined(CONFIG_COMPAT)
37void __init patch_vdso32(void *vdso, size_t len)
33{ 38{
34 Elf32_Ehdr *hdr = vdso; 39 Elf32_Ehdr *hdr = vdso;
35 Elf32_Shdr *sechdrs, *alt_sec = 0; 40 Elf32_Shdr *sechdrs, *alt_sec = 0;
@@ -52,7 +57,7 @@ static void __init patch_vdsox32(void *vdso, size_t len)
52 } 57 }
53 58
54 /* If we get here, it's probably a bug. */ 59 /* If we get here, it's probably a bug. */
55 pr_warning("patch_vdsox32: .altinstructions not found\n"); 60 pr_warning("patch_vdso32: .altinstructions not found\n");
56 return; /* nothing to patch */ 61 return; /* nothing to patch */
57 62
58found: 63found:
@@ -61,6 +66,7 @@ found:
61} 66}
62#endif 67#endif
63 68
69#if defined(CONFIG_X86_64)
64static void __init patch_vdso64(void *vdso, size_t len) 70static void __init patch_vdso64(void *vdso, size_t len)
65{ 71{
66 Elf64_Ehdr *hdr = vdso; 72 Elf64_Ehdr *hdr = vdso;
@@ -104,7 +110,7 @@ static int __init init_vdso(void)
104 vdso_pages[i] = virt_to_page(vdso_start + i*PAGE_SIZE); 110 vdso_pages[i] = virt_to_page(vdso_start + i*PAGE_SIZE);
105 111
106#ifdef CONFIG_X86_X32_ABI 112#ifdef CONFIG_X86_X32_ABI
107 patch_vdsox32(vdsox32_start, vdsox32_end - vdsox32_start); 113 patch_vdso32(vdsox32_start, vdsox32_end - vdsox32_start);
108 npages = (vdsox32_end - vdsox32_start + PAGE_SIZE - 1) / PAGE_SIZE; 114 npages = (vdsox32_end - vdsox32_start + PAGE_SIZE - 1) / PAGE_SIZE;
109 vdsox32_size = npages << PAGE_SHIFT; 115 vdsox32_size = npages << PAGE_SHIFT;
110 for (i = 0; i < npages; i++) 116 for (i = 0; i < npages; i++)
@@ -204,3 +210,4 @@ static __init int vdso_setup(char *s)
204 return 0; 210 return 0;
205} 211}
206__setup("vdso=", vdso_setup); 212__setup("vdso=", vdso_setup);
213#endif