hc
2024-11-01 2f529f9b558ca1c1bd74be7437a84e4711743404
kernel/arch/arm/kernel/vdso.c
....@@ -32,7 +32,10 @@
3232
3333 extern char vdso_start[], vdso_end[];
3434
35
-/* Total number of pages needed for the data and text portions of the VDSO. */
35
+/*
36
+ * Total number of pages needed for the data, private and text
37
+ * portions of the VDSO.
38
+ */
3639 unsigned int vdso_total_pages __ro_after_init;
3740
3841 /*
....@@ -53,8 +56,8 @@
5356 unsigned long new_size = new_vma->vm_end - new_vma->vm_start;
5457 unsigned long vdso_size;
5558
56
- /* without VVAR page */
57
- vdso_size = (vdso_total_pages - 1) << PAGE_SHIFT;
59
+ /* without VVAR and VPRIV pages */
60
+ vdso_size = (vdso_total_pages - 2) << PAGE_SHIFT;
5861
5962 if (vdso_size != new_size)
6063 return -EINVAL;
....@@ -180,8 +183,10 @@
180183 /* If the virtual counter is absent or non-functional we don't
181184 * want programs to incur the slight additional overhead of
182185 * dispatching through the VDSO only to fall back to syscalls.
186
+ * However, if clocksources supporting generic MMIO access can
187
+ * be reached via the vDSO, keep this fast path enabled.
183188 */
184
- if (!cntvct_ok) {
189
+ if (!cntvct_ok && !IS_ENABLED(CONFIG_GENERIC_CLOCKSOURCE_VDSO)) {
185190 vdso_nullpatch_one(&einfo, "__vdso_gettimeofday");
186191 vdso_nullpatch_one(&einfo, "__vdso_clock_gettime");
187192 vdso_nullpatch_one(&einfo, "__vdso_clock_gettime64");
....@@ -219,16 +224,26 @@
219224
220225 vdso_text_mapping.pages = vdso_text_pagelist;
221226
222
- vdso_total_pages = 1; /* for the data/vvar page */
227
+ vdso_total_pages = 2; /* for the data/vvar and vpriv pages */
223228 vdso_total_pages += text_pages;
224229
225230 cntvct_ok = cntvct_functional();
226231
227232 patch_vdso(vdso_start);
233
+#ifdef CONFIG_GENERIC_CLOCKSOURCE_VDSO
234
+ vdso_data->cs_type_seq = CLOCKSOURCE_VDSO_NONE << 16 | 1;
235
+#endif
228236
229237 return 0;
230238 }
231239 arch_initcall(vdso_init);
240
+
241
+static int install_vpriv(struct mm_struct *mm, unsigned long addr)
242
+{
243
+ return mmap_region(NULL, addr, PAGE_SIZE,
244
+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE,
245
+ 0, NULL) != addr ? -EINVAL : 0;
246
+}
232247
233248 static int install_vvar(struct mm_struct *mm, unsigned long addr)
234249 {
....@@ -237,8 +252,13 @@
237252 vma = _install_special_mapping(mm, addr, PAGE_SIZE,
238253 VM_READ | VM_MAYREAD,
239254 &vdso_data_mapping);
255
+ if (IS_ERR(vma))
256
+ return PTR_ERR(vma);
240257
241
- return PTR_ERR_OR_ZERO(vma);
258
+ if (cache_is_vivt())
259
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
260
+
261
+ return vma->vm_start != addr ? -EINVAL : 0;
242262 }
243263
244264 /* assumes mmap_lock is write-locked */
....@@ -252,18 +272,29 @@
252272 if (vdso_text_pagelist == NULL)
253273 return;
254274
255
- if (install_vvar(mm, addr))
275
+ if (install_vpriv(mm, addr)) {
276
+ pr_err("cannot map VPRIV at expected address!\n");
256277 return;
278
+ }
257279
258
- /* Account for vvar page. */
280
+ /* Account for the private storage. */
259281 addr += PAGE_SIZE;
260
- len = (vdso_total_pages - 1) << PAGE_SHIFT;
282
+ if (install_vvar(mm, addr)) {
283
+ WARN(1, "cannot map VVAR at expected address!\n");
284
+ return;
285
+ }
286
+
287
+ /* Account for vvar and vpriv pages. */
288
+ addr += PAGE_SIZE;
289
+ len = (vdso_total_pages - 2) << PAGE_SHIFT;
261290
262291 vma = _install_special_mapping(mm, addr, len,
263292 VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
264293 &vdso_text_mapping);
265294
266
- if (!IS_ERR(vma))
295
+ if (IS_ERR(vma) || vma->vm_start != addr)
296
+ WARN(1, "cannot map VDSO at expected address!\n");
297
+ else
267298 mm->context.vdso = addr;
268299 }
269300