1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
5 * <benh@kernel.crashing.org>
8 #include <linux/errno.h>
9 #include <linux/sched.h>
10 #include <linux/kernel.h>
12 #include <linux/smp.h>
13 #include <linux/stddef.h>
14 #include <linux/unistd.h>
15 #include <linux/slab.h>
16 #include <linux/user.h>
17 #include <linux/elf.h>
18 #include <linux/security.h>
19 #include <linux/memblock.h>
20 #include <linux/syscalls.h>
21 #include <vdso/datapage.h>
23 #include <asm/syscall.h>
24 #include <asm/processor.h>
26 #include <asm/mmu_context.h>
28 #include <asm/machdep.h>
29 #include <asm/cputable.h>
30 #include <asm/sections.h>
31 #include <asm/firmware.h>
33 #include <asm/vdso_datapage.h>
34 #include <asm/setup.h>
36 /* The alignment of the vDSO */
37 #define VDSO_ALIGNMENT (1 << 16)
39 extern char vdso32_start
, vdso32_end
;
40 extern char vdso64_start
, vdso64_end
;
43 * The vdso data page (aka. systemcfg for old ppc64 fans) is here.
44 * Once the early boot kernel code no longer needs to muck around
45 * with it, it will become dynamically allocated
48 struct vdso_arch_data data
;
50 } vdso_data_store __page_aligned_data
;
51 struct vdso_arch_data
*vdso_data
= &vdso_data_store
.data
;
53 static int vdso_mremap(const struct vm_special_mapping
*sm
, struct vm_area_struct
*new_vma
,
54 unsigned long text_size
)
56 unsigned long new_size
= new_vma
->vm_end
- new_vma
->vm_start
;
58 if (new_size
!= text_size
+ PAGE_SIZE
)
61 current
->mm
->context
.vdso
= (void __user
*)new_vma
->vm_start
+ PAGE_SIZE
;
66 static int vdso32_mremap(const struct vm_special_mapping
*sm
, struct vm_area_struct
*new_vma
)
68 return vdso_mremap(sm
, new_vma
, &vdso32_end
- &vdso32_start
);
71 static int vdso64_mremap(const struct vm_special_mapping
*sm
, struct vm_area_struct
*new_vma
)
73 return vdso_mremap(sm
, new_vma
, &vdso64_end
- &vdso64_start
);
76 static struct vm_special_mapping vdso32_spec __ro_after_init
= {
78 .mremap
= vdso32_mremap
,
81 static struct vm_special_mapping vdso64_spec __ro_after_init
= {
83 .mremap
= vdso64_mremap
,
87 * This is called from binfmt_elf, we create the special vma for the
88 * vDSO and insert it into the mm struct tree
90 static int __arch_setup_additional_pages(struct linux_binprm
*bprm
, int uses_interp
)
92 struct mm_struct
*mm
= current
->mm
;
93 struct vm_special_mapping
*vdso_spec
;
94 struct vm_area_struct
*vma
;
95 unsigned long vdso_size
;
96 unsigned long vdso_base
;
98 if (is_32bit_task()) {
99 vdso_spec
= &vdso32_spec
;
100 vdso_size
= &vdso32_end
- &vdso32_start
;
101 vdso_base
= VDSO32_MBASE
;
103 vdso_spec
= &vdso64_spec
;
104 vdso_size
= &vdso64_end
- &vdso64_start
;
106 * On 64bit we don't have a preferred map address. This
107 * allows get_unmapped_area to find an area near other mmaps
108 * and most likely share a SLB entry.
113 /* Add a page to the vdso size for the data page */
114 vdso_size
+= PAGE_SIZE
;
117 * pick a base address for the vDSO in process space. We try to put it
118 * at vdso_base which is the "natural" base for it, but we might fail
119 * and end up putting it elsewhere.
120 * Add enough to the size so that the result can be aligned.
122 vdso_base
= get_unmapped_area(NULL
, vdso_base
,
123 vdso_size
+ ((VDSO_ALIGNMENT
- 1) & PAGE_MASK
),
125 if (IS_ERR_VALUE(vdso_base
))
128 /* Add required alignment. */
129 vdso_base
= ALIGN(vdso_base
, VDSO_ALIGNMENT
);
132 * Put vDSO base into mm struct. We need to do this before calling
133 * install_special_mapping or the perf counter mmap tracking code
134 * will fail to recognise it as a vDSO.
136 mm
->context
.vdso
= (void __user
*)vdso_base
+ PAGE_SIZE
;
139 * our vma flags don't have VM_WRITE so by default, the process isn't
140 * allowed to write those pages.
141 * gdb can break that with ptrace interface, and thus trigger COW on
142 * those pages but it's then your responsibility to never do that on
143 * the "data" page of the vDSO or you'll stop getting kernel updates
144 * and your nice userland gettimeofday will be totally dead.
145 * It's fine to use that for setting breakpoints in the vDSO code
148 vma
= _install_special_mapping(mm
, vdso_base
, vdso_size
,
149 VM_READ
| VM_EXEC
| VM_MAYREAD
|
150 VM_MAYWRITE
| VM_MAYEXEC
, vdso_spec
);
151 return PTR_ERR_OR_ZERO(vma
);
154 int arch_setup_additional_pages(struct linux_binprm
*bprm
, int uses_interp
)
156 struct mm_struct
*mm
= current
->mm
;
159 mm
->context
.vdso
= NULL
;
161 if (mmap_write_lock_killable(mm
))
164 rc
= __arch_setup_additional_pages(bprm
, uses_interp
);
166 mm
->context
.vdso
= NULL
;
168 mmap_write_unlock(mm
);
172 #define VDSO_DO_FIXUPS(type, value, bits, sec) do { \
173 void *__start = (void *)VDSO##bits##_SYMBOL(&vdso##bits##_start, sec##_start); \
174 void *__end = (void *)VDSO##bits##_SYMBOL(&vdso##bits##_start, sec##_end); \
176 do_##type##_fixups((value), __start, __end); \
179 static void __init
vdso_fixup_features(void)
182 VDSO_DO_FIXUPS(feature
, cur_cpu_spec
->cpu_features
, 64, ftr_fixup
);
183 VDSO_DO_FIXUPS(feature
, cur_cpu_spec
->mmu_features
, 64, mmu_ftr_fixup
);
184 VDSO_DO_FIXUPS(feature
, powerpc_firmware_features
, 64, fw_ftr_fixup
);
185 VDSO_DO_FIXUPS(lwsync
, cur_cpu_spec
->cpu_features
, 64, lwsync_fixup
);
186 #endif /* CONFIG_PPC64 */
189 VDSO_DO_FIXUPS(feature
, cur_cpu_spec
->cpu_features
, 32, ftr_fixup
);
190 VDSO_DO_FIXUPS(feature
, cur_cpu_spec
->mmu_features
, 32, mmu_ftr_fixup
);
192 VDSO_DO_FIXUPS(feature
, powerpc_firmware_features
, 32, fw_ftr_fixup
);
193 #endif /* CONFIG_PPC64 */
194 VDSO_DO_FIXUPS(lwsync
, cur_cpu_spec
->cpu_features
, 32, lwsync_fixup
);
199 * Called from setup_arch to initialize the bitmap of available
200 * syscalls in the systemcfg page
202 static void __init
vdso_setup_syscall_map(void)
206 for (i
= 0; i
< NR_syscalls
; i
++) {
207 if (sys_call_table
[i
] != (unsigned long)&sys_ni_syscall
)
208 vdso_data
->syscall_map
[i
>> 5] |= 0x80000000UL
>> (i
& 0x1f);
209 if (IS_ENABLED(CONFIG_COMPAT
) &&
210 compat_sys_call_table
[i
] != (unsigned long)&sys_ni_syscall
)
211 vdso_data
->compat_syscall_map
[i
>> 5] |= 0x80000000UL
>> (i
& 0x1f);
216 int vdso_getcpu_init(void)
218 unsigned long cpu
, node
, val
;
221 * SPRG_VDSO contains the CPU in the bottom 16 bits and the NUMA node
222 * in the next 16 bits. The VDSO uses this to implement getcpu().
225 WARN_ON_ONCE(cpu
> 0xffff);
227 node
= cpu_to_node(cpu
);
228 WARN_ON_ONCE(node
> 0xffff);
230 val
= (cpu
& 0xffff) | ((node
& 0xffff) << 16);
231 mtspr(SPRN_SPRG_VDSO_WRITE
, val
);
232 get_paca()->sprg_vdso
= val
;
238 /* We need to call this before SMP init */
239 early_initcall(vdso_getcpu_init
);
242 static struct page
** __init
vdso_setup_pages(void *start
, void *end
)
245 struct page
**pagelist
;
246 int pages
= (end
- start
) >> PAGE_SHIFT
;
248 pagelist
= kcalloc(pages
+ 1, sizeof(struct page
*), GFP_KERNEL
);
250 panic("%s: Cannot allocate page list for VDSO", __func__
);
252 pagelist
[0] = virt_to_page(vdso_data
);
254 for (i
= 0; i
< pages
; i
++)
255 pagelist
[i
+ 1] = virt_to_page(start
+ i
* PAGE_SIZE
);
260 static int __init
vdso_init(void)
264 * Fill up the "systemcfg" stuff for backward compatibility
266 strcpy((char *)vdso_data
->eye_catcher
, "SYSTEMCFG:PPC64");
267 vdso_data
->version
.major
= SYSTEMCFG_MAJOR
;
268 vdso_data
->version
.minor
= SYSTEMCFG_MINOR
;
269 vdso_data
->processor
= mfspr(SPRN_PVR
);
271 * Fake the old platform number for pSeries and add
272 * in LPAR bit if necessary
274 vdso_data
->platform
= 0x100;
275 if (firmware_has_feature(FW_FEATURE_LPAR
))
276 vdso_data
->platform
|= 1;
277 vdso_data
->physicalMemorySize
= memblock_phys_mem_size();
278 vdso_data
->dcache_size
= ppc64_caches
.l1d
.size
;
279 vdso_data
->dcache_line_size
= ppc64_caches
.l1d
.line_size
;
280 vdso_data
->icache_size
= ppc64_caches
.l1i
.size
;
281 vdso_data
->icache_line_size
= ppc64_caches
.l1i
.line_size
;
282 vdso_data
->dcache_block_size
= ppc64_caches
.l1d
.block_size
;
283 vdso_data
->icache_block_size
= ppc64_caches
.l1i
.block_size
;
284 vdso_data
->dcache_log_block_size
= ppc64_caches
.l1d
.log_block_size
;
285 vdso_data
->icache_log_block_size
= ppc64_caches
.l1i
.log_block_size
;
286 #endif /* CONFIG_PPC64 */
288 vdso_setup_syscall_map();
290 vdso_fixup_features();
292 if (IS_ENABLED(CONFIG_VDSO32
))
293 vdso32_spec
.pages
= vdso_setup_pages(&vdso32_start
, &vdso32_end
);
295 if (IS_ENABLED(CONFIG_PPC64
))
296 vdso64_spec
.pages
= vdso_setup_pages(&vdso64_start
, &vdso64_end
);
302 arch_initcall(vdso_init
);