1 // SPDX-License-Identifier: GPL-2.0-only
3 * VDSO implementations.
5 * Copyright (C) 2012 ARM Limited
7 * Author: Will Deacon <will.deacon@arm.com>
10 #include <linux/cache.h>
11 #include <linux/clocksource.h>
12 #include <linux/elf.h>
13 #include <linux/err.h>
14 #include <linux/errno.h>
15 #include <linux/gfp.h>
16 #include <linux/kernel.h>
18 #include <linux/sched.h>
19 #include <linux/signal.h>
20 #include <linux/slab.h>
21 #include <linux/time_namespace.h>
22 #include <linux/vmalloc.h>
23 #include <vdso/datapage.h>
24 #include <vdso/helpers.h>
25 #include <vdso/vsyscall.h>
27 #include <asm/cacheflush.h>
28 #include <asm/signal32.h>
36 struct vdso_abi_info
{
38 const char *vdso_code_start
;
39 const char *vdso_code_end
;
40 unsigned long vdso_pages
;
42 struct vm_special_mapping
*cm
;
45 static struct vdso_abi_info vdso_info
[] __ro_after_init
= {
48 .vdso_code_start
= vdso_start
,
49 .vdso_code_end
= vdso_end
,
51 #ifdef CONFIG_COMPAT_VDSO
54 .vdso_code_start
= vdso32_start
,
55 .vdso_code_end
= vdso32_end
,
57 #endif /* CONFIG_COMPAT_VDSO */
63 static union vdso_data_store vdso_data_store __page_aligned_data
;
64 struct vdso_data
*vdso_data
= vdso_data_store
.data
;
66 static int vdso_mremap(const struct vm_special_mapping
*sm
,
67 struct vm_area_struct
*new_vma
)
69 current
->mm
->context
.vdso
= (void *)new_vma
->vm_start
;
74 static int __init
__vdso_init(enum vdso_abi abi
)
77 struct page
**vdso_pagelist
;
80 if (memcmp(vdso_info
[abi
].vdso_code_start
, "\177ELF", 4)) {
81 pr_err("vDSO is not a valid ELF object!\n");
85 vdso_info
[abi
].vdso_pages
= (
86 vdso_info
[abi
].vdso_code_end
-
87 vdso_info
[abi
].vdso_code_start
) >>
90 vdso_pagelist
= kcalloc(vdso_info
[abi
].vdso_pages
,
91 sizeof(struct page
*),
93 if (vdso_pagelist
== NULL
)
96 /* Grab the vDSO code pages. */
97 pfn
= sym_to_pfn(vdso_info
[abi
].vdso_code_start
);
99 for (i
= 0; i
< vdso_info
[abi
].vdso_pages
; i
++)
100 vdso_pagelist
[i
] = pfn_to_page(pfn
+ i
);
102 vdso_info
[abi
].cm
->pages
= vdso_pagelist
;
107 #ifdef CONFIG_TIME_NS
108 struct vdso_data
*arch_get_vdso_data(void *vvar_page
)
110 return (struct vdso_data
*)(vvar_page
);
113 static const struct vm_special_mapping vvar_map
;
116 * The vvar mapping contains data for a specific time namespace, so when a task
117 * changes namespace we must unmap its vvar data for the old namespace.
118 * Subsequent faults will map in data for the new namespace.
120 * For more details see timens_setup_vdso_data().
122 int vdso_join_timens(struct task_struct
*task
, struct time_namespace
*ns
)
124 struct mm_struct
*mm
= task
->mm
;
125 struct vm_area_struct
*vma
;
126 VMA_ITERATOR(vmi
, mm
, 0);
130 for_each_vma(vmi
, vma
) {
131 if (vma_is_special_mapping(vma
, &vvar_map
))
135 mmap_read_unlock(mm
);
140 static vm_fault_t
vvar_fault(const struct vm_special_mapping
*sm
,
141 struct vm_area_struct
*vma
, struct vm_fault
*vmf
)
143 struct page
*timens_page
= find_timens_vvar_page(vma
);
146 switch (vmf
->pgoff
) {
147 case VVAR_DATA_PAGE_OFFSET
:
149 pfn
= page_to_pfn(timens_page
);
151 pfn
= sym_to_pfn(vdso_data
);
153 #ifdef CONFIG_TIME_NS
154 case VVAR_TIMENS_PAGE_OFFSET
:
156 * If a task belongs to a time namespace then a namespace
157 * specific VVAR is mapped with the VVAR_DATA_PAGE_OFFSET and
158 * the real VVAR page is mapped with the VVAR_TIMENS_PAGE_OFFSET
160 * See also the comment near timens_setup_vdso_data().
163 return VM_FAULT_SIGBUS
;
164 pfn
= sym_to_pfn(vdso_data
);
166 #endif /* CONFIG_TIME_NS */
168 return VM_FAULT_SIGBUS
;
171 return vmf_insert_pfn(vma
, vmf
->address
, pfn
);
174 static const struct vm_special_mapping vvar_map
= {
179 static int __setup_additional_pages(enum vdso_abi abi
,
180 struct mm_struct
*mm
,
181 struct linux_binprm
*bprm
,
184 unsigned long vdso_base
, vdso_text_len
, vdso_mapping_len
;
185 unsigned long gp_flags
= 0;
188 BUILD_BUG_ON(VVAR_NR_PAGES
!= __VVAR_PAGES
);
190 vdso_text_len
= vdso_info
[abi
].vdso_pages
<< PAGE_SHIFT
;
191 /* Be sure to map the data page */
192 vdso_mapping_len
= vdso_text_len
+ VVAR_NR_PAGES
* PAGE_SIZE
;
194 vdso_base
= get_unmapped_area(NULL
, 0, vdso_mapping_len
, 0, 0);
195 if (IS_ERR_VALUE(vdso_base
)) {
196 ret
= ERR_PTR(vdso_base
);
200 ret
= _install_special_mapping(mm
, vdso_base
, VVAR_NR_PAGES
* PAGE_SIZE
,
201 VM_READ
|VM_MAYREAD
|VM_PFNMAP
,
206 if (system_supports_bti_kernel())
207 gp_flags
= VM_ARM64_BTI
;
209 vdso_base
+= VVAR_NR_PAGES
* PAGE_SIZE
;
210 mm
->context
.vdso
= (void *)vdso_base
;
211 ret
= _install_special_mapping(mm
, vdso_base
, vdso_text_len
,
212 VM_READ
|VM_EXEC
|gp_flags
|
213 VM_MAYREAD
|VM_MAYWRITE
|VM_MAYEXEC
,
221 mm
->context
.vdso
= NULL
;
227 * Create and map the vectors page for AArch32 tasks.
230 AA32_MAP_VECTORS
, /* kuser helpers */
235 static struct page
*aarch32_vectors_page __ro_after_init
;
236 static struct page
*aarch32_sig_page __ro_after_init
;
238 static int aarch32_sigpage_mremap(const struct vm_special_mapping
*sm
,
239 struct vm_area_struct
*new_vma
)
241 current
->mm
->context
.sigpage
= (void *)new_vma
->vm_start
;
246 static struct vm_special_mapping aarch32_vdso_maps
[] = {
247 [AA32_MAP_VECTORS
] = {
248 .name
= "[vectors]", /* ABI */
249 .pages
= &aarch32_vectors_page
,
251 [AA32_MAP_SIGPAGE
] = {
252 .name
= "[sigpage]", /* ABI */
253 .pages
= &aarch32_sig_page
,
254 .mremap
= aarch32_sigpage_mremap
,
258 .mremap
= vdso_mremap
,
262 static int aarch32_alloc_kuser_vdso_page(void)
264 extern char __kuser_helper_start
[], __kuser_helper_end
[];
265 int kuser_sz
= __kuser_helper_end
- __kuser_helper_start
;
266 unsigned long vdso_page
;
268 if (!IS_ENABLED(CONFIG_KUSER_HELPERS
))
271 vdso_page
= get_zeroed_page(GFP_KERNEL
);
275 memcpy((void *)(vdso_page
+ 0x1000 - kuser_sz
), __kuser_helper_start
,
277 aarch32_vectors_page
= virt_to_page((void *)vdso_page
);
281 #define COMPAT_SIGPAGE_POISON_WORD 0xe7fddef1
282 static int aarch32_alloc_sigpage(void)
284 extern char __aarch32_sigret_code_start
[], __aarch32_sigret_code_end
[];
285 int sigret_sz
= __aarch32_sigret_code_end
- __aarch32_sigret_code_start
;
286 __le32 poison
= cpu_to_le32(COMPAT_SIGPAGE_POISON_WORD
);
289 sigpage
= (void *)__get_free_page(GFP_KERNEL
);
293 memset32(sigpage
, (__force u32
)poison
, PAGE_SIZE
/ sizeof(poison
));
294 memcpy(sigpage
, __aarch32_sigret_code_start
, sigret_sz
);
295 aarch32_sig_page
= virt_to_page(sigpage
);
299 static int __init
__aarch32_alloc_vdso_pages(void)
302 if (!IS_ENABLED(CONFIG_COMPAT_VDSO
))
305 vdso_info
[VDSO_ABI_AA32
].cm
= &aarch32_vdso_maps
[AA32_MAP_VDSO
];
307 return __vdso_init(VDSO_ABI_AA32
);
310 static int __init
aarch32_alloc_vdso_pages(void)
314 ret
= __aarch32_alloc_vdso_pages();
318 ret
= aarch32_alloc_sigpage();
322 return aarch32_alloc_kuser_vdso_page();
324 arch_initcall(aarch32_alloc_vdso_pages
);
326 static int aarch32_kuser_helpers_setup(struct mm_struct
*mm
)
330 if (!IS_ENABLED(CONFIG_KUSER_HELPERS
))
334 * Avoid VM_MAYWRITE for compatibility with arch/arm/, where it's
335 * not safe to CoW the page containing the CPU exception vectors.
337 ret
= _install_special_mapping(mm
, AARCH32_VECTORS_BASE
, PAGE_SIZE
,
339 VM_MAYREAD
| VM_MAYEXEC
,
340 &aarch32_vdso_maps
[AA32_MAP_VECTORS
]);
342 return PTR_ERR_OR_ZERO(ret
);
345 static int aarch32_sigreturn_setup(struct mm_struct
*mm
)
350 addr
= get_unmapped_area(NULL
, 0, PAGE_SIZE
, 0, 0);
351 if (IS_ERR_VALUE(addr
)) {
357 * VM_MAYWRITE is required to allow gdb to Copy-on-Write and
360 ret
= _install_special_mapping(mm
, addr
, PAGE_SIZE
,
361 VM_READ
| VM_EXEC
| VM_MAYREAD
|
362 VM_MAYWRITE
| VM_MAYEXEC
,
363 &aarch32_vdso_maps
[AA32_MAP_SIGPAGE
]);
367 mm
->context
.sigpage
= (void *)addr
;
370 return PTR_ERR_OR_ZERO(ret
);
373 int aarch32_setup_additional_pages(struct linux_binprm
*bprm
, int uses_interp
)
375 struct mm_struct
*mm
= current
->mm
;
378 if (mmap_write_lock_killable(mm
))
381 ret
= aarch32_kuser_helpers_setup(mm
);
385 if (IS_ENABLED(CONFIG_COMPAT_VDSO
)) {
386 ret
= __setup_additional_pages(VDSO_ABI_AA32
, mm
, bprm
,
392 ret
= aarch32_sigreturn_setup(mm
);
394 mmap_write_unlock(mm
);
397 #endif /* CONFIG_COMPAT */
399 static struct vm_special_mapping aarch64_vdso_map __ro_after_init
= {
401 .mremap
= vdso_mremap
,
404 static int __init
vdso_init(void)
406 vdso_info
[VDSO_ABI_AA64
].cm
= &aarch64_vdso_map
;
408 return __vdso_init(VDSO_ABI_AA64
);
410 arch_initcall(vdso_init
);
412 int arch_setup_additional_pages(struct linux_binprm
*bprm
, int uses_interp
)
414 struct mm_struct
*mm
= current
->mm
;
417 if (mmap_write_lock_killable(mm
))
420 ret
= __setup_additional_pages(VDSO_ABI_AA64
, mm
, bprm
, uses_interp
);
421 mmap_write_unlock(mm
);