vdso/datastore: Map zeroed pages for unavailable data

mlockall() stops if a page in a VMA is unmappable. As the datastore VMA
can contain holes, mlockall() would not process all data pages.

Replace the mapping error VM_FAULT_SIGBUS by just mapping the underlying
unused and zeroed-out data page. The vDSO will not access these pages in
any case and for other userspace these pages have undefined contents.

This will allow mlockall() to process all pages within the VMA as soon
as VM_IO is removed from the VMA.

Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Tested-by: Nam Cao <namcao@linutronix.de>
Link: https://patch.msgid.link/20260630-vdso-mlockall-v4-3-6c93708ce723@linutronix.de
This commit is contained in:
Thomas Weißschuh
2026-07-07 23:52:52 +02:00
committed by Thomas Gleixner
parent 7557273419
commit 43648f9f3a
+2 -7
View File
@@ -74,7 +74,7 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
switch (vmf->pgoff) { switch (vmf->pgoff) {
case VDSO_TIME_PAGE_OFFSET: case VDSO_TIME_PAGE_OFFSET:
if (!IS_ENABLED(CONFIG_GENERIC_GETTIMEOFDAY)) if (!IS_ENABLED(CONFIG_GENERIC_GETTIMEOFDAY))
return VM_FAULT_SIGBUS; break;
if (timens_page) { if (timens_page) {
/* /*
* Fault in VVAR page too, since it will be accessed * Fault in VVAR page too, since it will be accessed
@@ -99,16 +99,11 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
* See also the comment near timens_setup_vdso_data(). * See also the comment near timens_setup_vdso_data().
*/ */
if (!IS_ENABLED(CONFIG_TIME_NS) || !timens_page) if (!IS_ENABLED(CONFIG_TIME_NS) || !timens_page)
return VM_FAULT_SIGBUS; break;
page = vdso_data_pages + VDSO_TIME_PAGE_OFFSET; page = vdso_data_pages + VDSO_TIME_PAGE_OFFSET;
break; break;
case VDSO_RNG_PAGE_OFFSET: case VDSO_RNG_PAGE_OFFSET:
if (!IS_ENABLED(CONFIG_VDSO_GETRANDOM))
return VM_FAULT_SIGBUS;
break;
case VDSO_ARCH_PAGES_START ... VDSO_ARCH_PAGES_END: case VDSO_ARCH_PAGES_START ... VDSO_ARCH_PAGES_END:
if (!IS_ENABLED(CONFIG_ARCH_HAS_VDSO_ARCH_DATA))
return VM_FAULT_SIGBUS;
break; break;
default: default:
return VM_FAULT_SIGBUS; return VM_FAULT_SIGBUS;