diff options
author | Andy Lutomirski <luto@mit.edu> | 2011-07-21 15:47:10 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2011-07-21 16:41:53 -0400 |
commit | aafade242ff24fac3aabf61c7861dfa44a3c2445 (patch) | |
tree | e28352a5883b5684466ea44f3caebe99c088eaf7 /arch | |
parent | ae7bd11b471931752e5609094ca0a49386590524 (diff) |
x86-64, vdso: Do not allocate memory for the vDSO
We can map the vDSO straight from kernel data, saving a few page
allocations. As an added bonus, the deleted code contained a memory
leak.
Signed-off-by: Andy Lutomirski <luto@mit.edu>
Link: http://lkml.kernel.org/r/2c4ed5c2c2e93603790229e0c3403ae506ccc0cb.1311277573.git.luto@mit.edu
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/vdso/vdso.S | 15 | ||||
-rw-r--r-- | arch/x86/vdso/vma.c | 25 |
2 files changed, 19 insertions, 21 deletions
diff --git a/arch/x86/vdso/vdso.S b/arch/x86/vdso/vdso.S index 1d3aa6b87181..1b979c12ba85 100644 --- a/arch/x86/vdso/vdso.S +++ b/arch/x86/vdso/vdso.S | |||
@@ -1,10 +1,21 @@ | |||
1 | #include <asm/page_types.h> | ||
2 | #include <linux/linkage.h> | ||
1 | #include <linux/init.h> | 3 | #include <linux/init.h> |
2 | 4 | ||
3 | __INITDATA | 5 | __PAGE_ALIGNED_DATA |
4 | 6 | ||
5 | .globl vdso_start, vdso_end | 7 | .globl vdso_start, vdso_end |
8 | .align PAGE_SIZE | ||
6 | vdso_start: | 9 | vdso_start: |
7 | .incbin "arch/x86/vdso/vdso.so" | 10 | .incbin "arch/x86/vdso/vdso.so" |
8 | vdso_end: | 11 | vdso_end: |
9 | 12 | ||
10 | __FINIT | 13 | .previous |
14 | |||
15 | .globl vdso_pages | ||
16 | .bss | ||
17 | .align 8 | ||
18 | .type vdso_pages, @object | ||
19 | vdso_pages: | ||
20 | .zero (vdso_end - vdso_start + PAGE_SIZE - 1) / PAGE_SIZE * 8 | ||
21 | .size vdso_pages, .-vdso_pages | ||
diff --git a/arch/x86/vdso/vma.c b/arch/x86/vdso/vma.c index c39938d1332f..316fbca3490e 100644 --- a/arch/x86/vdso/vma.c +++ b/arch/x86/vdso/vma.c | |||
@@ -14,13 +14,14 @@ | |||
14 | #include <asm/vgtod.h> | 14 | #include <asm/vgtod.h> |
15 | #include <asm/proto.h> | 15 | #include <asm/proto.h> |
16 | #include <asm/vdso.h> | 16 | #include <asm/vdso.h> |
17 | #include <asm/page.h> | ||
17 | 18 | ||
18 | unsigned int __read_mostly vdso_enabled = 1; | 19 | unsigned int __read_mostly vdso_enabled = 1; |
19 | 20 | ||
20 | extern char vdso_start[], vdso_end[]; | 21 | extern char vdso_start[], vdso_end[]; |
21 | extern unsigned short vdso_sync_cpuid; | 22 | extern unsigned short vdso_sync_cpuid; |
22 | 23 | ||
23 | static struct page **vdso_pages; | 24 | extern struct page *vdso_pages[]; |
24 | static unsigned vdso_size; | 25 | static unsigned vdso_size; |
25 | 26 | ||
26 | static void __init patch_vdso(void *vdso, size_t len) | 27 | static void __init patch_vdso(void *vdso, size_t len) |
@@ -54,7 +55,7 @@ found: | |||
54 | apply_alternatives(alt_data, alt_data + alt_sec->sh_size); | 55 | apply_alternatives(alt_data, alt_data + alt_sec->sh_size); |
55 | } | 56 | } |
56 | 57 | ||
57 | static int __init init_vdso_vars(void) | 58 | static int __init init_vdso(void) |
58 | { | 59 | { |
59 | int npages = (vdso_end - vdso_start + PAGE_SIZE - 1) / PAGE_SIZE; | 60 | int npages = (vdso_end - vdso_start + PAGE_SIZE - 1) / PAGE_SIZE; |
60 | int i; | 61 | int i; |
@@ -62,26 +63,12 @@ static int __init init_vdso_vars(void) | |||
62 | patch_vdso(vdso_start, vdso_end - vdso_start); | 63 | patch_vdso(vdso_start, vdso_end - vdso_start); |
63 | 64 | ||
64 | vdso_size = npages << PAGE_SHIFT; | 65 | vdso_size = npages << PAGE_SHIFT; |
65 | vdso_pages = kmalloc(sizeof(struct page *) * npages, GFP_KERNEL); | 66 | for (i = 0; i < npages; i++) |
66 | if (!vdso_pages) | 67 | vdso_pages[i] = virt_to_page(vdso_start + i*PAGE_SIZE); |
67 | goto oom; | ||
68 | for (i = 0; i < npages; i++) { | ||
69 | struct page *p; | ||
70 | p = alloc_page(GFP_KERNEL); | ||
71 | if (!p) | ||
72 | goto oom; | ||
73 | vdso_pages[i] = p; | ||
74 | copy_page(page_address(p), vdso_start + i*PAGE_SIZE); | ||
75 | } | ||
76 | 68 | ||
77 | return 0; | 69 | return 0; |
78 | |||
79 | oom: | ||
80 | printk("Cannot allocate vdso\n"); | ||
81 | vdso_enabled = 0; | ||
82 | return -ENOMEM; | ||
83 | } | 70 | } |
84 | subsys_initcall(init_vdso_vars); | 71 | subsys_initcall(init_vdso); |
85 | 72 | ||
86 | struct linux_binprm; | 73 | struct linux_binprm; |
87 | 74 | ||