summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2026-07-23 12:39:42 +0200
committerIngo Molnar <mingo@kernel.org>2026-07-23 12:39:43 +0200
commit4d181e45d622ef4230e9b7888ed4261e2e660e37 (patch)
tree46d1d2218b2ed6fc7498de243b607297e5854885 /lib
parentcee1cdc3c0fbe93c17498c75ec6c17d049ee27ec (diff)
parentecacc9c8d3ed0f63065f4a1e94bfd8bf65a3ffaf (diff)
downloadlinux-next-4d181e45d622ef4230e9b7888ed4261e2e660e37.tar.gz
linux-next-4d181e45d622ef4230e9b7888ed4261e2e660e37.zip
Merge branch into tip/master: 'timers/vdso'
# New commits in timers/vdso: ecacc9c8d3ed ("vdso: Rename HAVE_GENERIC_VDSO to VDSO_DATASTORE") 52447180f4fb ("vdso: Drop HAVE_GENERIC_VDSO from architecture kconfig files") faeff8d416c4 ("vdso: Automatically select HAVE_GENERIC_VDSO if necessary") 8c0015572c61 ("MIPS: vdso: Stop using CONFIG_HAVE_GENERIC_VDSO") a92426375870 ("vdso: Remove the dependency on HAVE_GENERIC_VDSO from ARCH_HAS_VDSO_ARCH_DATA") 2558084d2b03 ("futex: Remove dependency on HAVE_GENERIC_VDSO from FUTEX_ROBUST_UNLOCK") 369cecd238ac ("vdso/gettimeofday: Verify COMPAT_32BIT_TIME interactions") 2700297b69fe ("sparc: vdso: Respect COMPAT_32BIT_TIME") 377e3f2d4130 ("MIPS: VDSO: Respect COMPAT_32BIT_TIME") e01abc70af38 ("powerpc/vdso: Respect COMPAT_32BIT_TIME") 95216f4647e7 ("ARM: VDSO: Respect COMPAT_32BIT_TIME") abb1537388ba ("arm64: vdso32: Respect COMPAT_32BIT_TIME") 1a4660da3130 ("x86/vdso: Respect COMPAT_32BIT_TIME") f8b946772554 ("vdso/gettimeofday: Validate system call existence for time() and gettimeofday()") dce21fb3d570 ("time: Respect COMPAT_32BIT_TIME for old time type functions") 0b50763e8439 ("vdso/datastore: Simplify the mapping logic for VDSO_TIME_PAGE_OFFSET") c27e727c9a60 ("vdso/datastore: Allow prefaulting by mlockall()") 9ab500d47f5f ("vdso/datastore: Explicitly prevent remote access to timens vvar page") 43648f9f3a67 ("vdso/datastore: Map zeroed pages for unavailable data") 7557273419dd ("vdso/datastore: Map pages in terms of the faults pgoff") ff868f43eb8f ("vdso/datastore: Rename data pages variable") 02475538bec2 ("vdso: Replace __ASSEMBLY__ with __ASSEMBLER__ in header files") Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/vdso/Kconfig8
-rw-r--r--lib/vdso/Makefile2
-rw-r--r--lib/vdso/datastore.c65
-rw-r--r--lib/vdso/gettimeofday.c20
4 files changed, 54 insertions, 41 deletions
diff --git a/lib/vdso/Kconfig b/lib/vdso/Kconfig
index db87ba34ef19..597f5f0f9681 100644
--- a/lib/vdso/Kconfig
+++ b/lib/vdso/Kconfig
@@ -1,12 +1,11 @@
# SPDX-License-Identifier: GPL-2.0
-config HAVE_GENERIC_VDSO
+config VDSO_DATASTORE
bool
-if HAVE_GENERIC_VDSO
-
config GENERIC_GETTIMEOFDAY
bool
+ select VDSO_DATASTORE
help
This is a generic implementation of gettimeofday vdso.
Each architecture that enables this feature has to
@@ -21,7 +20,6 @@ config GENERIC_VDSO_OVERFLOW_PROTECT
config VDSO_GETRANDOM
bool
+ select VDSO_DATASTORE
help
Selected by architectures that support vDSO getrandom().
-
-endif
diff --git a/lib/vdso/Makefile b/lib/vdso/Makefile
index 405f743253d7..ac304def42d6 100644
--- a/lib/vdso/Makefile
+++ b/lib/vdso/Makefile
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_HAVE_GENERIC_VDSO) += datastore.o
+obj-$(CONFIG_VDSO_DATASTORE) += datastore.o
diff --git a/lib/vdso/datastore.c b/lib/vdso/datastore.c
index 17d37b82ebc6..1426bf4e0c12 100644
--- a/lib/vdso/datastore.c
+++ b/lib/vdso/datastore.c
@@ -29,10 +29,11 @@ struct vdso_arch_data *vdso_k_arch_data __ro_after_init =
(void *)&vdso_initdata[VDSO_ARCH_PAGES_START * PAGE_SIZE];
#endif /* CONFIG_ARCH_HAS_VDSO_ARCH_DATA */
+static struct page *vdso_data_pages __ro_after_init;
+
void __init vdso_setup_data_pages(void)
{
unsigned int order = get_order(VDSO_NR_PAGES * PAGE_SIZE);
- struct page *pages;
/*
* Allocate the data pages dynamically. SPARC does not support mapping
@@ -42,24 +43,24 @@ void __init vdso_setup_data_pages(void)
* Do not use folios. In time namespaces the pages are mapped in a different order
* to userspace, which is not handled by the folio optimizations in finish_fault().
*/
- pages = alloc_pages(GFP_KERNEL, order);
- if (!pages)
+ vdso_data_pages = alloc_pages(GFP_KERNEL, order);
+ if (!vdso_data_pages)
panic("Unable to allocate VDSO storage pages");
/* The pages are mapped one-by-one into userspace and each one needs to be refcounted. */
- split_page(pages, order);
+ split_page(vdso_data_pages, order);
/* Move the data already written by other subsystems to the new pages */
- memcpy(page_address(pages), vdso_initdata, VDSO_NR_PAGES * PAGE_SIZE);
+ memcpy(page_address(vdso_data_pages), vdso_initdata, VDSO_NR_PAGES * PAGE_SIZE);
if (IS_ENABLED(CONFIG_GENERIC_GETTIMEOFDAY))
- vdso_k_time_data = page_address(pages + VDSO_TIME_PAGE_OFFSET);
+ vdso_k_time_data = page_address(vdso_data_pages + VDSO_TIME_PAGE_OFFSET);
if (IS_ENABLED(CONFIG_VDSO_GETRANDOM))
- vdso_k_rng_data = page_address(pages + VDSO_RNG_PAGE_OFFSET);
+ vdso_k_rng_data = page_address(vdso_data_pages + VDSO_RNG_PAGE_OFFSET);
if (IS_ENABLED(CONFIG_ARCH_HAS_VDSO_ARCH_DATA))
- vdso_k_arch_data = page_address(pages + VDSO_ARCH_PAGES_START);
+ vdso_k_arch_data = page_address(vdso_data_pages + VDSO_ARCH_PAGES_START);
}
static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
@@ -67,27 +68,28 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
{
struct page *page, *timens_page;
+ if (unlikely(vmf->flags & FAULT_FLAG_REMOTE))
+ return VM_FAULT_SIGBUS;
+
+ page = vdso_data_pages + vmf->pgoff;
timens_page = find_timens_vvar_page(vma);
switch (vmf->pgoff) {
case VDSO_TIME_PAGE_OFFSET:
- if (!IS_ENABLED(CONFIG_GENERIC_GETTIMEOFDAY))
- return VM_FAULT_SIGBUS;
- page = virt_to_page(vdso_k_time_data);
- if (timens_page) {
- /*
- * Fault in VVAR page too, since it will be accessed
- * to get clock data anyway.
- */
- unsigned long addr;
- vm_fault_t err;
-
- addr = vmf->address + VDSO_TIMENS_PAGE_OFFSET * PAGE_SIZE;
- err = vmf_insert_page(vma, addr, page);
- if (unlikely(err & VM_FAULT_ERROR))
- return err;
- page = timens_page;
- }
+ if (!IS_ENABLED(CONFIG_GENERIC_GETTIMEOFDAY) || !timens_page)
+ break;
+ /*
+ * Fault in VVAR page too, since it will be accessed
+ * to get clock data anyway.
+ */
+ unsigned long addr;
+ vm_fault_t err;
+
+ addr = vmf->address + VDSO_TIMENS_PAGE_OFFSET * PAGE_SIZE;
+ err = vmf_insert_page(vma, addr, page);
+ if (unlikely(err & VM_FAULT_ERROR))
+ return err;
+ page = timens_page;
break;
case VDSO_TIMENS_PAGE_OFFSET:
/*
@@ -98,18 +100,11 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
* See also the comment near timens_setup_vdso_data().
*/
if (!IS_ENABLED(CONFIG_TIME_NS) || !timens_page)
- return VM_FAULT_SIGBUS;
- page = virt_to_page(vdso_k_time_data);
+ break;
+ page = vdso_data_pages + VDSO_TIME_PAGE_OFFSET;
break;
case VDSO_RNG_PAGE_OFFSET:
- if (!IS_ENABLED(CONFIG_VDSO_GETRANDOM))
- return VM_FAULT_SIGBUS;
- page = virt_to_page(vdso_k_rng_data);
- break;
case VDSO_ARCH_PAGES_START ... VDSO_ARCH_PAGES_END:
- if (!IS_ENABLED(CONFIG_ARCH_HAS_VDSO_ARCH_DATA))
- return VM_FAULT_SIGBUS;
- page = virt_to_page(vdso_k_arch_data) + vmf->pgoff - VDSO_ARCH_PAGES_START;
break;
default:
return VM_FAULT_SIGBUS;
@@ -128,7 +123,7 @@ const struct vm_special_mapping vdso_vvar_mapping = {
struct vm_area_struct *vdso_install_vvar_mapping(struct mm_struct *mm, unsigned long addr)
{
return _install_special_mapping(mm, addr, VDSO_NR_PAGES * PAGE_SIZE,
- VM_READ | VM_MAYREAD | VM_IO | VM_DONTDUMP |
+ VM_READ | VM_MAYREAD | VM_DONTDUMP |
VM_MIXEDMAP | VM_SEALED_SYSMAP,
&vdso_vvar_mapping);
}
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index e0f289d3d110..f7a591aba59f 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -12,6 +12,8 @@
#include <vdso/time32.h>
#include <vdso/time64.h>
+#include <uapi/linux/unistd.h>
+
/*
* The generic vDSO implementation requires that gettimeofday.h
* provides:
@@ -23,6 +25,8 @@
*/
#include <asm/vdso/gettimeofday.h>
+#include <linux/build_bug.h>
+
/* Bring in default accessors */
#include <vdso/vsyscall.h>
@@ -323,6 +327,8 @@ __cvdso_clock_gettime32_data(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec ts;
bool ok;
+ BUILD_BUG_ON(!IS_ENABLED(CONFIG_COMPAT_32BIT_TIME));
+
ok = __cvdso_clock_gettime_common(vd, clock, &ts);
if (unlikely(!ok))
@@ -348,6 +354,12 @@ __cvdso_gettimeofday_data(const struct vdso_time_data *vd,
{
const struct vdso_clock *vc = vd->clock_data;
+#ifndef __NR_gettimeofday
+ BUILD_BUG();
+#endif
+
+ BUILD_BUG_ON(sizeof(tv->tv_sec) != 8 && !IS_ENABLED(CONFIG_COMPAT_32BIT_TIME));
+
if (likely(tv != NULL)) {
struct __kernel_timespec ts;
@@ -382,6 +394,12 @@ __cvdso_time_data(const struct vdso_time_data *vd, __kernel_old_time_t *time)
const struct vdso_clock *vc = vd->clock_data;
__kernel_old_time_t t;
+#ifndef __NR_time
+ BUILD_BUG();
+#endif
+
+ BUILD_BUG_ON(sizeof(*time) != 8 && !IS_ENABLED(CONFIG_COMPAT_32BIT_TIME));
+
if (vdso_is_timens_clock(vc)) {
vd = vdso_timens_data(vd);
vc = vd->clock_data;
@@ -471,6 +489,8 @@ __cvdso_clock_getres_time32_data(const struct vdso_time_data *vd, clockid_t cloc
struct __kernel_timespec ts;
bool ok;
+ BUILD_BUG_ON(!IS_ENABLED(CONFIG_COMPAT_32BIT_TIME));
+
ok = __cvdso_clock_getres_common(vd, clock, &ts);
if (unlikely(!ok))