From nobody Tue Apr 7 23:43:43 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AC11A3D9DA1; Wed, 11 Mar 2026 09:31:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773221511; cv=none; b=g3Zb0G5+19vsdt5XlxZR9BS3VyiiN6j0sSAEkgJnrr/emgGBHXkKQ1HVWf5gilzmi/TIyM1SY3ssYBOoRu/b7uFujwMmJrez/c1tHkxTlzhlXP9qK8ogJdGHaGMhI1FMDZS0yj0Zu5aYIzRgjwCXoVbsNrbhgstw/9+7tGL23JE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773221511; c=relaxed/simple; bh=Ywy5FEoE2F1bDoaymGzCdzc3jNZ0OaHv2NnLf4Xbcgc=; h=Date:From:To:Subject:Cc:In-Reply-To:References:MIME-Version: Message-ID:Content-Type; b=faWNxbc87fY60tjoTIlVDuoGCs5e7vSbm7BIZD2OgoIruSbkkmD228W3gavb35NZnJ0FGiy1OHc1bm18h9CCly6zbUQzJ7AR8BdBeRifa1pq0iOfRVC6ASuCM1PYCxHWdMd1eN9dBoOeLedLOWs8CwQfX2l8Qjrh5KbxRSlyTAo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=bIuKGw9/; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=ofS4wNfA; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="bIuKGw9/"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="ofS4wNfA" Date: Wed, 11 Mar 2026 09:31:47 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1773221508; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=JkaUF/sfpmCXShTyV7EcjC0qo8jCDXPaGQUN8d1hayE=; b=bIuKGw9/m/C61nse+vWTsPzonTf4aS+mVnhi/WWtw3Qrq2bNIUREPuxHP8tr5euPIB4m2x G1gQqAzPGV6LUdh96O4xNnPlZp4uyFb+fuXnP4AAvlYm5gshuIF2PURhqiTvHLzBynRgGm 5RmovQRsnK92nSXpGu9alWUXjMWVgndS71ANYnO6AXtnDQCfx0zWAE5Fy27ufHv0tNy4my 8CJnRrAQCr8AGSfdwv0MGp5f7HN+kncNw7u/TOc1r4lJXyI6GAlyWvnkaku4y4Orcu7hBi OHGHClWx53lMtIBegMk2ZEh6rK/MPm+MSWgEmhYXGaQ1T+UvV9CvKREOpkhPBQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1773221508; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=JkaUF/sfpmCXShTyV7EcjC0qo8jCDXPaGQUN8d1hayE=; b=ofS4wNfAmXJ2U+Bz5rBSqqETCnXG2Sc/IAPVMgFEJb+s04a2Z5QSh0tveHkpCWD9BkWo/X NQtIaxCHRo0RDICQ== From: tip-bot2 for Thomas =?utf-8?q?Wei=C3=9Fschuh?= Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: timers/vdso] vdso/datastore: Allocate data pages dynamically Cc: thomas.weissschuh@linutronix.de, Thomas Gleixner , "Christophe Leroy (CS GROUP)" , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20260304-vdso-sparc64-generic-2-v6-3-d8eb3b0e1410@linutronix.de> References: <20260304-vdso-sparc64-generic-2-v6-3-d8eb3b0e1410@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <177322150700.1647592.16665966234389586049.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The following commit has been merged into the timers/vdso branch of tip: Commit-ID: 05988dba11791ccbb458254484826b32f17f4ad2 Gitweb: https://git.kernel.org/tip/05988dba11791ccbb458254484826b32f= 17f4ad2 Author: Thomas Wei=C3=9Fschuh AuthorDate: Wed, 04 Mar 2026 08:49:00 +01:00 Committer: Thomas Gleixner CommitterDate: Wed, 11 Mar 2026 10:18:30 +01:00 vdso/datastore: Allocate data pages dynamically Allocating the data pages as part of the kernel image does not work on SPARC. The MMU will raise a fault when userspace tries to access them. Allocate the data pages through the page allocator instead. Unused pages in the vDSO VMA are still allocated to keep the virtual addresses aligned. Switch the mapping from PFNs to 'struct page' as that is required for dynamically allocated pages. This also aligns the allocation of the datapages with the code pages and is a prerequisite for mlockall() support. VM_MIXEDMAP is necessary for the call to vmf_insert_page() in the timens prefault path to work. The data pages need to be order-0, non-compound pages so that the mapping to userspace and the different orderings work. These pages are also used by the timekeeping, random pool and architecture initialization code. Some of these are running before the page allocator is available. To keep these subsytems working without changes, introduce early, statically data storage which will then replaced by the real one as soon as that is available. Signed-off-by: Thomas Wei=C3=9Fschuh Signed-off-by: Thomas Gleixner Reviewed-by: Christophe Leroy (CS GROUP) Link: https://patch.msgid.link/20260304-vdso-sparc64-generic-2-v6-3-d8eb3b0= e1410@linutronix.de --- include/linux/vdso_datastore.h | 6 ++- init/main.c | 2 +- lib/vdso/datastore.c | 92 +++++++++++++++++++++------------ 3 files changed, 68 insertions(+), 32 deletions(-) diff --git a/include/linux/vdso_datastore.h b/include/linux/vdso_datastore.h index a91fa24..0b53042 100644 --- a/include/linux/vdso_datastore.h +++ b/include/linux/vdso_datastore.h @@ -2,9 +2,15 @@ #ifndef _LINUX_VDSO_DATASTORE_H #define _LINUX_VDSO_DATASTORE_H =20 +#ifdef CONFIG_HAVE_GENERIC_VDSO #include =20 extern const struct vm_special_mapping vdso_vvar_mapping; struct vm_area_struct *vdso_install_vvar_mapping(struct mm_struct *mm, uns= igned long addr); =20 +void __init vdso_setup_data_pages(void); +#else /* !CONFIG_HAVE_GENERIC_VDSO */ +static inline void vdso_setup_data_pages(void) { } +#endif /* CONFIG_HAVE_GENERIC_VDSO */ + #endif /* _LINUX_VDSO_DATASTORE_H */ diff --git a/init/main.c b/init/main.c index 1cb395d..de867b2 100644 --- a/init/main.c +++ b/init/main.c @@ -105,6 +105,7 @@ #include #include #include +#include #include =20 #include @@ -1119,6 +1120,7 @@ void start_kernel(void) srcu_init(); hrtimers_init(); softirq_init(); + vdso_setup_data_pages(); timekeeping_init(); time_init(); =20 diff --git a/lib/vdso/datastore.c b/lib/vdso/datastore.c index 7377fcb..faebf5b 100644 --- a/lib/vdso/datastore.c +++ b/lib/vdso/datastore.c @@ -1,52 +1,79 @@ // SPDX-License-Identifier: GPL-2.0-only =20 -#include +#include +#include #include #include #include #include #include =20 -/* - * The vDSO data page. - */ +static u8 vdso_initdata[VDSO_NR_PAGES * PAGE_SIZE] __aligned(PAGE_SIZE) __= initdata =3D {}; + #ifdef CONFIG_GENERIC_GETTIMEOFDAY -static union { - struct vdso_time_data data; - u8 page[PAGE_SIZE]; -} vdso_time_data_store __page_aligned_data; -struct vdso_time_data *vdso_k_time_data =3D &vdso_time_data_store.data; -static_assert(sizeof(vdso_time_data_store) =3D=3D PAGE_SIZE); +struct vdso_time_data *vdso_k_time_data __refdata =3D + (void *)&vdso_initdata[VDSO_TIME_PAGE_OFFSET * PAGE_SIZE]; + +static_assert(sizeof(struct vdso_time_data) <=3D PAGE_SIZE); #endif /* CONFIG_GENERIC_GETTIMEOFDAY */ =20 #ifdef CONFIG_VDSO_GETRANDOM -static union { - struct vdso_rng_data data; - u8 page[PAGE_SIZE]; -} vdso_rng_data_store __page_aligned_data; -struct vdso_rng_data *vdso_k_rng_data =3D &vdso_rng_data_store.data; -static_assert(sizeof(vdso_rng_data_store) =3D=3D PAGE_SIZE); +struct vdso_rng_data *vdso_k_rng_data __refdata =3D + (void *)&vdso_initdata[VDSO_RNG_PAGE_OFFSET * PAGE_SIZE]; + +static_assert(sizeof(struct vdso_rng_data) <=3D PAGE_SIZE); #endif /* CONFIG_VDSO_GETRANDOM */ =20 #ifdef CONFIG_ARCH_HAS_VDSO_ARCH_DATA -static union { - struct vdso_arch_data data; - u8 page[VDSO_ARCH_DATA_SIZE]; -} vdso_arch_data_store __page_aligned_data; -struct vdso_arch_data *vdso_k_arch_data =3D &vdso_arch_data_store.data; +struct vdso_arch_data *vdso_k_arch_data __refdata =3D + (void *)&vdso_initdata[VDSO_ARCH_PAGES_START * PAGE_SIZE]; #endif /* CONFIG_ARCH_HAS_VDSO_ARCH_DATA */ =20 +void __init vdso_setup_data_pages(void) +{ + unsigned int order =3D get_order(VDSO_NR_PAGES * PAGE_SIZE); + struct page *pages; + + /* + * Allocate the data pages dynamically. SPARC does not support mapping + * static pages to be mapped into userspace. + * It is also a requirement for mlockall() support. + * + * Do not use folios. In time namespaces the pages are mapped in a differ= ent order + * to userspace, which is not handled by the folio optimizations in finis= h_fault(). + */ + pages =3D alloc_pages(GFP_KERNEL, order); + if (!pages) + panic("Unable to allocate VDSO storage pages"); + + /* The pages are mapped one-by-one into userspace and each one needs to b= e refcounted. */ + split_page(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); + + if (IS_ENABLED(CONFIG_GENERIC_GETTIMEOFDAY)) + vdso_k_time_data =3D page_address(pages + VDSO_TIME_PAGE_OFFSET); + + if (IS_ENABLED(CONFIG_VDSO_GETRANDOM)) + vdso_k_rng_data =3D page_address(pages + VDSO_RNG_PAGE_OFFSET); + + if (IS_ENABLED(CONFIG_ARCH_HAS_VDSO_ARCH_DATA)) + vdso_k_arch_data =3D page_address(pages + VDSO_ARCH_PAGES_START); +} + static vm_fault_t vvar_fault(const struct vm_special_mapping *sm, struct vm_area_struct *vma, struct vm_fault *vmf) { - struct page *timens_page =3D find_timens_vvar_page(vma); - unsigned long pfn; + struct page *page, *timens_page; + + timens_page =3D find_timens_vvar_page(vma); =20 switch (vmf->pgoff) { case VDSO_TIME_PAGE_OFFSET: if (!IS_ENABLED(CONFIG_GENERIC_GETTIMEOFDAY)) return VM_FAULT_SIGBUS; - pfn =3D __phys_to_pfn(__pa_symbol(vdso_k_time_data)); + page =3D virt_to_page(vdso_k_time_data); if (timens_page) { /* * Fault in VVAR page too, since it will be accessed @@ -56,10 +83,10 @@ static vm_fault_t vvar_fault(const struct vm_special_ma= pping *sm, vm_fault_t err; =20 addr =3D vmf->address + VDSO_TIMENS_PAGE_OFFSET * PAGE_SIZE; - err =3D vmf_insert_pfn(vma, addr, pfn); + err =3D vmf_insert_page(vma, addr, page); if (unlikely(err & VM_FAULT_ERROR)) return err; - pfn =3D page_to_pfn(timens_page); + page =3D timens_page; } break; case VDSO_TIMENS_PAGE_OFFSET: @@ -72,24 +99,25 @@ static vm_fault_t vvar_fault(const struct vm_special_ma= pping *sm, */ if (!IS_ENABLED(CONFIG_TIME_NS) || !timens_page) return VM_FAULT_SIGBUS; - pfn =3D __phys_to_pfn(__pa_symbol(vdso_k_time_data)); + page =3D virt_to_page(vdso_k_time_data); break; case VDSO_RNG_PAGE_OFFSET: if (!IS_ENABLED(CONFIG_VDSO_GETRANDOM)) return VM_FAULT_SIGBUS; - pfn =3D __phys_to_pfn(__pa_symbol(vdso_k_rng_data)); + page =3D 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; - pfn =3D __phys_to_pfn(__pa_symbol(vdso_k_arch_data)) + - vmf->pgoff - VDSO_ARCH_PAGES_START; + page =3D virt_to_page(vdso_k_arch_data) + vmf->pgoff - VDSO_ARCH_PAGES_S= TART; break; default: return VM_FAULT_SIGBUS; } =20 - return vmf_insert_pfn(vma, vmf->address, pfn); + get_page(page); + vmf->page =3D page; + return 0; } =20 const struct vm_special_mapping vdso_vvar_mapping =3D { @@ -101,7 +129,7 @@ struct vm_area_struct *vdso_install_vvar_mapping(struct= mm_struct *mm, unsigned=20 { return _install_special_mapping(mm, addr, VDSO_NR_PAGES * PAGE_SIZE, VM_READ | VM_MAYREAD | VM_IO | VM_DONTDUMP | - VM_PFNMAP | VM_SEALED_SYSMAP, + VM_MIXEDMAP | VM_SEALED_SYSMAP, &vdso_vvar_mapping); } =20