diff options
| author | Ingo Molnar <mingo@kernel.org> | 2026-07-23 12:39:42 +0200 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2026-07-23 12:39:43 +0200 |
| commit | 4d181e45d622ef4230e9b7888ed4261e2e660e37 (patch) | |
| tree | 46d1d2218b2ed6fc7498de243b607297e5854885 /lib | |
| parent | cee1cdc3c0fbe93c17498c75ec6c17d049ee27ec (diff) | |
| parent | ecacc9c8d3ed0f63065f4a1e94bfd8bf65a3ffaf (diff) | |
| download | linux-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/Kconfig | 8 | ||||
| -rw-r--r-- | lib/vdso/Makefile | 2 | ||||
| -rw-r--r-- | lib/vdso/datastore.c | 65 | ||||
| -rw-r--r-- | lib/vdso/gettimeofday.c | 20 |
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)) |
