]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/s390/kernel/vdso.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[linux-2.6-omap-h63xx.git] / arch / s390 / kernel / vdso.c
1 /*
2  * vdso setup for s390
3  *
4  *  Copyright IBM Corp. 2008
5  *  Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License (version 2 only)
9  * as published by the Free Software Foundation.
10  */
11
12 #include <linux/module.h>
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/kernel.h>
16 #include <linux/mm.h>
17 #include <linux/smp.h>
18 #include <linux/stddef.h>
19 #include <linux/unistd.h>
20 #include <linux/slab.h>
21 #include <linux/user.h>
22 #include <linux/elf.h>
23 #include <linux/security.h>
24 #include <linux/bootmem.h>
25
26 #include <asm/pgtable.h>
27 #include <asm/system.h>
28 #include <asm/processor.h>
29 #include <asm/mmu.h>
30 #include <asm/mmu_context.h>
31 #include <asm/sections.h>
32 #include <asm/vdso.h>
33
34 /* Max supported size for symbol names */
35 #define MAX_SYMNAME     64
36
37 #if defined(CONFIG_32BIT) || defined(CONFIG_COMPAT)
38 extern char vdso32_start, vdso32_end;
39 static void *vdso32_kbase = &vdso32_start;
40 static unsigned int vdso32_pages;
41 static struct page **vdso32_pagelist;
42 #endif
43
44 #ifdef CONFIG_64BIT
45 extern char vdso64_start, vdso64_end;
46 static void *vdso64_kbase = &vdso64_start;
47 static unsigned int vdso64_pages;
48 static struct page **vdso64_pagelist;
49 #endif /* CONFIG_64BIT */
50
51 /*
52  * Should the kernel map a VDSO page into processes and pass its
53  * address down to glibc upon exec()?
54  */
55 unsigned int __read_mostly vdso_enabled = 1;
56
57 static int __init vdso_setup(char *s)
58 {
59         vdso_enabled = simple_strtoul(s, NULL, 0);
60         return 1;
61 }
62 __setup("vdso=", vdso_setup);
63
64 /*
65  * The vdso data page
66  */
67 static union {
68         struct vdso_data        data;
69         u8                      page[PAGE_SIZE];
70 } vdso_data_store __attribute__((__section__(".data.page_aligned")));
71 struct vdso_data *vdso_data = &vdso_data_store.data;
72
73 /*
74  * This is called from binfmt_elf, we create the special vma for the
75  * vDSO and insert it into the mm struct tree
76  */
77 int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
78 {
79         struct mm_struct *mm = current->mm;
80         struct page **vdso_pagelist;
81         unsigned long vdso_pages;
82         unsigned long vdso_base;
83         int rc;
84
85         if (!vdso_enabled)
86                 return 0;
87         /*
88          * Only map the vdso for dynamically linked elf binaries.
89          */
90         if (!uses_interp)
91                 return 0;
92
93         vdso_base = mm->mmap_base;
94 #ifdef CONFIG_64BIT
95         vdso_pagelist = vdso64_pagelist;
96         vdso_pages = vdso64_pages;
97 #ifdef CONFIG_COMPAT
98         if (test_thread_flag(TIF_31BIT)) {
99                 vdso_pagelist = vdso32_pagelist;
100                 vdso_pages = vdso32_pages;
101         }
102 #endif
103 #else
104         vdso_pagelist = vdso32_pagelist;
105         vdso_pages = vdso32_pages;
106 #endif
107
108         /*
109          * vDSO has a problem and was disabled, just don't "enable" it for
110          * the process
111          */
112         if (vdso_pages == 0)
113                 return 0;
114
115         current->mm->context.vdso_base = 0;
116
117         /*
118          * pick a base address for the vDSO in process space. We try to put
119          * it at vdso_base which is the "natural" base for it, but we might
120          * fail and end up putting it elsewhere.
121          */
122         down_write(&mm->mmap_sem);
123         vdso_base = get_unmapped_area(NULL, vdso_base,
124                                       vdso_pages << PAGE_SHIFT, 0, 0);
125         if (IS_ERR_VALUE(vdso_base)) {
126                 rc = vdso_base;
127                 goto out_up;
128         }
129
130         /*
131          * our vma flags don't have VM_WRITE so by default, the process
132          * isn't allowed to write those pages.
133          * gdb can break that with ptrace interface, and thus trigger COW
134          * on those pages but it's then your responsibility to never do that
135          * on the "data" page of the vDSO or you'll stop getting kernel
136          * updates and your nice userland gettimeofday will be totally dead.
137          * It's fine to use that for setting breakpoints in the vDSO code
138          * pages though
139          *
140          * Make sure the vDSO gets into every core dump.
141          * Dumping its contents makes post-mortem fully interpretable later
142          * without matching up the same kernel and hardware config to see
143          * what PC values meant.
144          */
145         rc = install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT,
146                                      VM_READ|VM_EXEC|
147                                      VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
148                                      VM_ALWAYSDUMP,
149                                      vdso_pagelist);
150         if (rc)
151                 goto out_up;
152
153         /* Put vDSO base into mm struct */
154         current->mm->context.vdso_base = vdso_base;
155
156         up_write(&mm->mmap_sem);
157         return 0;
158
159 out_up:
160         up_write(&mm->mmap_sem);
161         return rc;
162 }
163
164 const char *arch_vma_name(struct vm_area_struct *vma)
165 {
166         if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso_base)
167                 return "[vdso]";
168         return NULL;
169 }
170
171 static int __init vdso_init(void)
172 {
173         int i;
174
175 #if defined(CONFIG_32BIT) || defined(CONFIG_COMPAT)
176         /* Calculate the size of the 32 bit vDSO */
177         vdso32_pages = ((&vdso32_end - &vdso32_start
178                          + PAGE_SIZE - 1) >> PAGE_SHIFT) + 1;
179
180         /* Make sure pages are in the correct state */
181         vdso32_pagelist = kzalloc(sizeof(struct page *) * (vdso32_pages + 1),
182                                   GFP_KERNEL);
183         BUG_ON(vdso32_pagelist == NULL);
184         for (i = 0; i < vdso32_pages - 1; i++) {
185                 struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE);
186                 ClearPageReserved(pg);
187                 get_page(pg);
188                 vdso32_pagelist[i] = pg;
189         }
190         vdso32_pagelist[vdso32_pages - 1] = virt_to_page(vdso_data);
191         vdso32_pagelist[vdso32_pages] = NULL;
192 #endif
193
194 #ifdef CONFIG_64BIT
195         /* Calculate the size of the 64 bit vDSO */
196         vdso64_pages = ((&vdso64_end - &vdso64_start
197                          + PAGE_SIZE - 1) >> PAGE_SHIFT) + 1;
198
199         /* Make sure pages are in the correct state */
200         vdso64_pagelist = kzalloc(sizeof(struct page *) * (vdso64_pages + 1),
201                                   GFP_KERNEL);
202         BUG_ON(vdso64_pagelist == NULL);
203         for (i = 0; i < vdso64_pages - 1; i++) {
204                 struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE);
205                 ClearPageReserved(pg);
206                 get_page(pg);
207                 vdso64_pagelist[i] = pg;
208         }
209         vdso64_pagelist[vdso64_pages - 1] = virt_to_page(vdso_data);
210         vdso64_pagelist[vdso64_pages] = NULL;
211 #endif /* CONFIG_64BIT */
212
213         get_page(virt_to_page(vdso_data));
214
215         smp_wmb();
216
217         return 0;
218 }
219 arch_initcall(vdso_init);
220
221 int in_gate_area_no_task(unsigned long addr)
222 {
223         return 0;
224 }
225
226 int in_gate_area(struct task_struct *task, unsigned long addr)
227 {
228         return 0;
229 }
230
231 struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
232 {
233         return NULL;
234 }