From 39c089a01a7e431383710a566864644cbbc0f8fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 17:44:44 +0200 Subject: [PATCH 01/42] vdso: Remove timekeeper argument of __arch_update_vsyscall() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No implementation of this hook uses the passed in timekeeper anymore. This avoids including a non-VDSO header while building the VDSO, which can lead to compilation errors. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Acked-by: Will Deacon Link: https://lore.kernel.org/all/20241010-vdso-generic-arch_update_vsyscall-v1-1-7fe5a3ea4382@linutronix.de --- arch/arm64/include/asm/vdso/vsyscall.h | 3 +-- include/asm-generic/vdso/vsyscall.h | 3 +-- kernel/time/vsyscall.c | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/vdso/vsyscall.h b/arch/arm64/include/asm/vdso/vsyscall.h index 5b6d0dd3cef54..eea51946d45a2 100644 --- a/arch/arm64/include/asm/vdso/vsyscall.h +++ b/arch/arm64/include/asm/vdso/vsyscall.h @@ -6,7 +6,6 @@ #ifndef __ASSEMBLY__ -#include #include enum vvar_pages { @@ -37,7 +36,7 @@ struct vdso_rng_data *__arm64_get_k_vdso_rnd_data(void) #define __arch_get_k_vdso_rng_data __arm64_get_k_vdso_rnd_data static __always_inline -void __arm64_update_vsyscall(struct vdso_data *vdata, struct timekeeper *tk) +void __arm64_update_vsyscall(struct vdso_data *vdata) { vdata[CS_HRES_COARSE].mask = VDSO_PRECISION_MASK; vdata[CS_RAW].mask = VDSO_PRECISION_MASK; diff --git a/include/asm-generic/vdso/vsyscall.h b/include/asm-generic/vdso/vsyscall.h index c835607f78ae9..01dafd604188f 100644 --- a/include/asm-generic/vdso/vsyscall.h +++ b/include/asm-generic/vdso/vsyscall.h @@ -12,8 +12,7 @@ static __always_inline struct vdso_data *__arch_get_k_vdso_data(void) #endif /* __arch_get_k_vdso_data */ #ifndef __arch_update_vsyscall -static __always_inline void __arch_update_vsyscall(struct vdso_data *vdata, - struct timekeeper *tk) +static __always_inline void __arch_update_vsyscall(struct vdso_data *vdata) { } #endif /* __arch_update_vsyscall */ diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c index 9193d6133e5d6..28706a13c222d 100644 --- a/kernel/time/vsyscall.c +++ b/kernel/time/vsyscall.c @@ -119,7 +119,7 @@ void update_vsyscall(struct timekeeper *tk) if (clock_mode != VDSO_CLOCKMODE_NONE) update_vdso_data(vdata, tk); - __arch_update_vsyscall(vdata, tk); + __arch_update_vsyscall(vdata); vdso_write_end(vdata); From d2caf94c0a94e32a0beb56beacaf380ad33124fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 17:44:45 +0200 Subject: [PATCH 02/42] arm: vdso: Remove timekeeper includes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the generic VDSO clock mode storage is used, this header file is unused and can be removed. This avoids including a non-VDSO header while building the VDSO, which can lead to compilation errors. Also drop the comment which is out of date and in the wrong place. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-arch_update_vsyscall-v1-2-7fe5a3ea4382@linutronix.de --- arch/arm/include/asm/vdso/vsyscall.h | 4 ---- arch/arm/kernel/vdso.c | 1 - 2 files changed, 5 deletions(-) diff --git a/arch/arm/include/asm/vdso/vsyscall.h b/arch/arm/include/asm/vdso/vsyscall.h index 47e41ae8ccd0b..705414710dcdb 100644 --- a/arch/arm/include/asm/vdso/vsyscall.h +++ b/arch/arm/include/asm/vdso/vsyscall.h @@ -4,16 +4,12 @@ #ifndef __ASSEMBLY__ -#include #include #include extern struct vdso_data *vdso_data; extern bool cntvct_ok; -/* - * Update the vDSO data page to keep in sync with kernel timekeeping. - */ static __always_inline struct vdso_data *__arm_get_k_vdso_data(void) { diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c index d499ad461b004..29dd2f3c62fec 100644 --- a/arch/arm/kernel/vdso.c +++ b/arch/arm/kernel/vdso.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include From 8603652569f9c10744f204466dcf527653591d1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 17:44:46 +0200 Subject: [PATCH 03/42] arm64: vdso: Remove timekeeper include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the generic VDSO clock mode storage is used, this header file is unused and can be removed. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Acked-by: Will Deacon Link: https://lore.kernel.org/all/20241010-vdso-generic-arch_update_vsyscall-v1-3-7fe5a3ea4382@linutronix.de --- arch/arm64/kernel/vdso.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 706c9c3a7a50a..8ef20c16bc482 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include From d93948d3ce591b90a43f922b73876e3511eec796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 17:44:47 +0200 Subject: [PATCH 04/42] powerpc/vdso: Remove timekeeper includes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the generic VDSO clock mode storage is used, this header file is unused and can be removed. This avoids including a non-VDSO header while building the VDSO, which can lead to compilation errors. Also drop the comment which is out of date and in the wrong place. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-arch_update_vsyscall-v1-4-7fe5a3ea4382@linutronix.de --- arch/powerpc/include/asm/vdso/vsyscall.h | 4 ---- arch/powerpc/kernel/time.c | 1 - 2 files changed, 5 deletions(-) diff --git a/arch/powerpc/include/asm/vdso/vsyscall.h b/arch/powerpc/include/asm/vdso/vsyscall.h index 92f480d8cc6dc..48560a1195595 100644 --- a/arch/powerpc/include/asm/vdso/vsyscall.h +++ b/arch/powerpc/include/asm/vdso/vsyscall.h @@ -4,12 +4,8 @@ #ifndef __ASSEMBLY__ -#include #include -/* - * Update the vDSO data page to keep in sync with kernel timekeeping. - */ static __always_inline struct vdso_data *__arch_get_k_vdso_data(void) { diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 0ff9f038e800d..4a95654c1d36f 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -75,7 +75,6 @@ /* powerpc clocksource/clockevent code */ #include -#include static u64 timebase_read(struct clocksource *); static struct clocksource clocksource_timebase = { From 930916d85a0958827d5150bb506044424adadf21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 17:44:48 +0200 Subject: [PATCH 05/42] riscv: vdso: Remove timekeeper include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the generic VDSO clock mode storage is used, this header file is unused and can be removed. This avoids including a non-VDSO header while building the VDSO, which can lead to compilation errors. Also drop the comment which is out of date and in the wrong place. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-arch_update_vsyscall-v1-5-7fe5a3ea4382@linutronix.de --- arch/riscv/include/asm/vdso/vsyscall.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/riscv/include/asm/vdso/vsyscall.h b/arch/riscv/include/asm/vdso/vsyscall.h index 82fd5d83bd602..e8a9c4b53c0c9 100644 --- a/arch/riscv/include/asm/vdso/vsyscall.h +++ b/arch/riscv/include/asm/vdso/vsyscall.h @@ -4,14 +4,10 @@ #ifndef __ASSEMBLY__ -#include #include extern struct vdso_data *vdso_data; -/* - * Update the vDSO data page to keep in sync with kernel timekeeping. - */ static __always_inline struct vdso_data *__riscv_get_k_vdso_data(void) { return vdso_data; From 3aa8881ebd1e673fd21785352bf5e78c2597b18f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 17:44:49 +0200 Subject: [PATCH 06/42] s390/vdso: Remove timekeeper includes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the generic VDSO clock mode storage is used, this header file is unused and can be removed. This avoids including a non-VDSO header while building the VDSO, which can lead to compilation errors. Also drop the comment which is out of date and in the wrong place. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Acked-by: Heiko Carstens Link: https://lore.kernel.org/all/20241010-vdso-generic-arch_update_vsyscall-v1-6-7fe5a3ea4382@linutronix.de --- arch/s390/include/asm/vdso/vsyscall.h | 5 ----- arch/s390/kernel/time.c | 1 - 2 files changed, 6 deletions(-) diff --git a/arch/s390/include/asm/vdso/vsyscall.h b/arch/s390/include/asm/vdso/vsyscall.h index 3c5d5e47814e1..3eb576ecd3bd9 100644 --- a/arch/s390/include/asm/vdso/vsyscall.h +++ b/arch/s390/include/asm/vdso/vsyscall.h @@ -7,7 +7,6 @@ #ifndef __ASSEMBLY__ #include -#include #include #include @@ -17,10 +16,6 @@ enum vvar_pages { VVAR_NR_PAGES }; -/* - * Update the vDSO data page to keep in sync with kernel timekeeping. - */ - static __always_inline struct vdso_data *__s390_get_k_vdso_data(void) { return vdso_data; diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index b713effe05796..4fae6c7017847 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include From 9025e3a6ecfcd9c9036778aa833211026c5ccf8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 17:44:50 +0200 Subject: [PATCH 07/42] x86/vdso: Remove timekeeper include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the generic VDSO clock mode storage is used, this header file is unused and can be removed. This avoids including a non-VDSO header while building the VDSO, which can lead to compilation errors. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-arch_update_vsyscall-v1-7-7fe5a3ea4382@linutronix.de --- arch/x86/include/asm/vdso/vsyscall.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/include/asm/vdso/vsyscall.h b/arch/x86/include/asm/vdso/vsyscall.h index 67fedf1698b5e..a1f916b18400f 100644 --- a/arch/x86/include/asm/vdso/vsyscall.h +++ b/arch/x86/include/asm/vdso/vsyscall.h @@ -4,7 +4,6 @@ #ifndef __ASSEMBLY__ -#include #include #include #include From fc06b914c1ce8009d6f469c512aa993b1c601da8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 17:44:51 +0200 Subject: [PATCH 08/42] LoongArch: vdso: Remove timekeeper includes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the generic VDSO clock mode storage is used, this header file is unused and can be removed. This avoids including a non-VDSO header while building the VDSO, which can lead to compilation errors. Also drop the comment which is out of date and in the wrong place. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-arch_update_vsyscall-v1-8-7fe5a3ea4382@linutronix.de --- arch/loongarch/include/asm/vdso/vsyscall.h | 4 ---- arch/loongarch/kernel/vdso.c | 1 - 2 files changed, 5 deletions(-) diff --git a/arch/loongarch/include/asm/vdso/vsyscall.h b/arch/loongarch/include/asm/vdso/vsyscall.h index b1273ce6f1406..8987e951d0a93 100644 --- a/arch/loongarch/include/asm/vdso/vsyscall.h +++ b/arch/loongarch/include/asm/vdso/vsyscall.h @@ -4,15 +4,11 @@ #ifndef __ASSEMBLY__ -#include #include extern struct vdso_data *vdso_data; extern struct vdso_rng_data *vdso_rng_data; -/* - * Update the vDSO data page to keep in sync with kernel timekeeping. - */ static __always_inline struct vdso_data *__loongarch_get_k_vdso_data(void) { diff --git a/arch/loongarch/kernel/vdso.c b/arch/loongarch/kernel/vdso.c index f6fcc52aefae0..4d7cb9425dc34 100644 --- a/arch/loongarch/kernel/vdso.c +++ b/arch/loongarch/kernel/vdso.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include From c0fba50a1e672629588c28ed70f01d516c1e1b27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 17:44:52 +0200 Subject: [PATCH 09/42] MIPS: vdso: Remove timekeeper includes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the generic VDSO clock mode storage is used, this header file is unused and can be removed. This avoids including a non-VDSO header while building the VDSO, which can lead to compilation errors. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-arch_update_vsyscall-v1-9-7fe5a3ea4382@linutronix.de --- arch/mips/include/asm/vdso/vsyscall.h | 1 - arch/mips/kernel/vdso.c | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/mips/include/asm/vdso/vsyscall.h b/arch/mips/include/asm/vdso/vsyscall.h index 47168aaf1eff0..a4582870aaea4 100644 --- a/arch/mips/include/asm/vdso/vsyscall.h +++ b/arch/mips/include/asm/vdso/vsyscall.h @@ -4,7 +4,6 @@ #ifndef __ASSEMBLY__ -#include #include extern struct vdso_data *vdso_data; diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c index dda36fa26307e..4c8e3c0aa2104 100644 --- a/arch/mips/kernel/vdso.c +++ b/arch/mips/kernel/vdso.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include From 8fd236b00fc1bc40e2f9205d0121a2de5ea506d0 Mon Sep 17 00:00:00 2001 From: Vincenzo Frascino Date: Mon, 14 Oct 2024 16:13:38 +0100 Subject: [PATCH 10/42] drm: i915: Change fault type to unsigned long MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fault is currently of type u32 and with the introduction of the generalized vdso/page.h we trigger the error below: drivers/gpu/drm/i915/gt/intel_gt_print.h:29:36: error: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 6 has type ‘u32’ {aka ‘unsigned int’} [-Werror=format=] 29 | drm_dbg(&(_gt)->i915->drm, "GT%u: " _fmt, (_gt)->info.id, | ^~~~~~~~ include/drm/drm_print.h:424:39: note: in definition of macro ‘drm_dev_dbg’ 424 | __drm_dev_dbg(NULL, dev, cat, fmt, ##__VA_ARGS__) | ^~~ include/drm/drm_print.h:524:33: note: in expansion of macro ‘drm_dbg_driver’ 524 | #define drm_dbg(drm, fmt, ...) drm_dbg_driver(drm, fmt, ##__VA_ARGS__) | ^~~~~~~~~~~~~~ linux/drivers/gpu/drm/i915/gt/intel_gt_print.h:29:9: note: in expansion of macro ‘drm_dbg’ 29 | drm_dbg(&(_gt)->i915->drm, "GT%u: " _fmt, (_gt)->info.id, | ^~~~~~~ drivers/gpu/drm/i915/gt/intel_gt.c:310:25: note: in expansion of macro ‘gt_dbg’ 310 | gt_dbg(gt, "Unexpected fault\n" | ^~~~~~ This happens because the type of PAGE_MASK depends on the architecture. Prevent the compilation error changing the 'fault' type to unsigned long. Signed-off-by: Vincenzo Frascino Signed-off-by: Thomas Gleixner Reviewed-by: Arnd Bergmann Link: https://lore.kernel.org/all/20241014151340.1639555-2-vincenzo.frascino@arm.com --- drivers/gpu/drm/i915/gt/intel_gt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c index a6c69a706fd76..bb29f361110e8 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.c +++ b/drivers/gpu/drm/i915/gt/intel_gt.c @@ -302,7 +302,7 @@ static void gen6_check_faults(struct intel_gt *gt) { struct intel_engine_cs *engine; enum intel_engine_id id; - u32 fault; + unsigned long fault; for_each_engine(engine, gt, id) { fault = GEN6_RING_FAULT_REG_READ(engine); @@ -310,8 +310,8 @@ static void gen6_check_faults(struct intel_gt *gt) gt_dbg(gt, "Unexpected fault\n" "\tAddr: 0x%08lx\n" "\tAddress space: %s\n" - "\tSource ID: %d\n" - "\tType: %d\n", + "\tSource ID: %ld\n" + "\tType: %ld\n", fault & PAGE_MASK, fault & RING_FAULT_GTTSEL_MASK ? "GGTT" : "PPGTT", From efe8419ae78d65e83edc31aad74b605c12e7d60c Mon Sep 17 00:00:00 2001 From: Vincenzo Frascino Date: Mon, 14 Oct 2024 16:13:39 +0100 Subject: [PATCH 11/42] vdso: Introduce vdso/page.h The VDSO implementation includes headers from outside of the vdso/ namespace. Introduce vdso/page.h to make sure that the generic library uses only the allowed namespace. Signed-off-by: Vincenzo Frascino Signed-off-by: Thomas Gleixner Reviewed-by: Arnd Bergmann Acked-by: Geert Uytterhoeven # m68k Link: https://lore.kernel.org/all/20241014151340.1639555-3-vincenzo.frascino@arm.com --- arch/alpha/include/asm/page.h | 6 +----- arch/arc/include/uapi/asm/page.h | 7 +++---- arch/arm/include/asm/page.h | 5 +---- arch/arm64/include/asm/page-def.h | 5 +---- arch/csky/include/asm/page.h | 8 ++------ arch/hexagon/include/asm/page.h | 4 +--- arch/loongarch/include/asm/page.h | 7 +------ arch/m68k/include/asm/page.h | 6 ++---- arch/microblaze/include/asm/page.h | 5 +---- arch/mips/include/asm/page.h | 7 +------ arch/nios2/include/asm/page.h | 7 +------ arch/openrisc/include/asm/page.h | 11 +---------- arch/parisc/include/asm/page.h | 4 +--- arch/powerpc/include/asm/page.h | 10 +--------- arch/riscv/include/asm/page.h | 4 +--- arch/s390/include/asm/page.h | 13 +++++-------- arch/sh/include/asm/page.h | 6 ++---- arch/sparc/include/asm/page_32.h | 4 +--- arch/sparc/include/asm/page_64.h | 4 +--- arch/um/include/asm/page.h | 5 +---- arch/x86/include/asm/page_types.h | 5 +---- arch/xtensa/include/asm/page.h | 8 +------- include/vdso/page.h | 30 ++++++++++++++++++++++++++++++ 23 files changed, 61 insertions(+), 110 deletions(-) create mode 100644 include/vdso/page.h diff --git a/arch/alpha/include/asm/page.h b/arch/alpha/include/asm/page.h index 70419e6be1a35..261af54fd601d 100644 --- a/arch/alpha/include/asm/page.h +++ b/arch/alpha/include/asm/page.h @@ -4,11 +4,7 @@ #include #include - -/* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) +#include #ifndef __ASSEMBLY__ diff --git a/arch/arc/include/uapi/asm/page.h b/arch/arc/include/uapi/asm/page.h index 7fd9e741b5274..4606a326af5c4 100644 --- a/arch/arc/include/uapi/asm/page.h +++ b/arch/arc/include/uapi/asm/page.h @@ -14,7 +14,7 @@ /* PAGE_SHIFT determines the page size */ #ifdef __KERNEL__ -#define PAGE_SHIFT CONFIG_PAGE_SHIFT +#include #else /* * Default 8k @@ -24,11 +24,10 @@ * not available */ #define PAGE_SHIFT 13 +#define PAGE_SIZE _BITUL(PAGE_SHIFT) /* Default 8K */ +#define PAGE_MASK (~(PAGE_SIZE-1)) #endif -#define PAGE_SIZE _BITUL(PAGE_SHIFT) /* Default 8K */ #define PAGE_OFFSET _AC(0x80000000, UL) /* Kernel starts at 2G onwrds */ -#define PAGE_MASK (~(PAGE_SIZE-1)) - #endif /* _UAPI__ASM_ARC_PAGE_H */ diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h index 62af9f7f9e963..ef11b721230e2 100644 --- a/arch/arm/include/asm/page.h +++ b/arch/arm/include/asm/page.h @@ -7,10 +7,7 @@ #ifndef _ASMARM_PAGE_H #define _ASMARM_PAGE_H -/* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) -#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) +#include #ifndef __ASSEMBLY__ diff --git a/arch/arm64/include/asm/page-def.h b/arch/arm64/include/asm/page-def.h index 792e9fe881dcf..d402e08442ee2 100644 --- a/arch/arm64/include/asm/page-def.h +++ b/arch/arm64/include/asm/page-def.h @@ -10,9 +10,6 @@ #include -/* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) +#include #endif /* __ASM_PAGE_DEF_H */ diff --git a/arch/csky/include/asm/page.h b/arch/csky/include/asm/page.h index 0ca6c408c07f2..f8beae295afb0 100644 --- a/arch/csky/include/asm/page.h +++ b/arch/csky/include/asm/page.h @@ -7,12 +7,8 @@ #include #include -/* - * PAGE_SHIFT determines the page size: 4KB - */ -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE - 1)) +#include + #define THREAD_SIZE (PAGE_SIZE * 2) #define THREAD_MASK (~(THREAD_SIZE - 1)) #define THREAD_SHIFT (PAGE_SHIFT + 1) diff --git a/arch/hexagon/include/asm/page.h b/arch/hexagon/include/asm/page.h index 8a6af57274c2d..b01f8df69dd40 100644 --- a/arch/hexagon/include/asm/page.h +++ b/arch/hexagon/include/asm/page.h @@ -45,9 +45,7 @@ #define HVM_HUGEPAGE_SIZE 0x5 #endif -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (1UL << PAGE_SHIFT) -#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) +#include #ifdef __KERNEL__ #ifndef __ASSEMBLY__ diff --git a/arch/loongarch/include/asm/page.h b/arch/loongarch/include/asm/page.h index e85df33f11c77..83f3533e31a47 100644 --- a/arch/loongarch/include/asm/page.h +++ b/arch/loongarch/include/asm/page.h @@ -8,12 +8,7 @@ #include #include -/* - * PAGE_SHIFT determines the page size - */ -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE - 1)) +#include #define HPAGE_SHIFT (PAGE_SHIFT + PAGE_SHIFT - 3) #define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT) diff --git a/arch/m68k/include/asm/page.h b/arch/m68k/include/asm/page.h index 8cfb84b499751..b173ba27d36f1 100644 --- a/arch/m68k/include/asm/page.h +++ b/arch/m68k/include/asm/page.h @@ -6,10 +6,8 @@ #include #include -/* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) +#include + #define PAGE_OFFSET (PAGE_OFFSET_RAW) #ifndef __ASSEMBLY__ diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h index 8810f4f1c3b02..d1ec3806edab9 100644 --- a/arch/microblaze/include/asm/page.h +++ b/arch/microblaze/include/asm/page.h @@ -19,10 +19,7 @@ #ifdef __KERNEL__ -/* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) +#include #define LOAD_OFFSET ASM_CONST((CONFIG_KERNEL_START-CONFIG_KERNEL_BASE_ADDR)) diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index 4609cb0326cf3..bc3e3484c1bfa 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h @@ -14,12 +14,7 @@ #include #include -/* - * PAGE_SHIFT determines the page size - */ -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) -#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) +#include /* * This is used for calculating the real page sizes diff --git a/arch/nios2/include/asm/page.h b/arch/nios2/include/asm/page.h index 0722f88e63cc7..2897ec1b74f61 100644 --- a/arch/nios2/include/asm/page.h +++ b/arch/nios2/include/asm/page.h @@ -18,12 +18,7 @@ #include #include -/* - * PAGE_SHIFT determines the page size - */ -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE - 1)) +#include /* * PAGE_OFFSET -- the first address of the first page of memory. diff --git a/arch/openrisc/include/asm/page.h b/arch/openrisc/include/asm/page.h index 1d5913f67c312..124a2db4b1603 100644 --- a/arch/openrisc/include/asm/page.h +++ b/arch/openrisc/include/asm/page.h @@ -15,16 +15,7 @@ #ifndef __ASM_OPENRISC_PAGE_H #define __ASM_OPENRISC_PAGE_H - -/* PAGE_SHIFT determines the page size */ - -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#ifdef __ASSEMBLY__ -#define PAGE_SIZE (1 << PAGE_SHIFT) -#else -#define PAGE_SIZE (1UL << PAGE_SHIFT) -#endif -#define PAGE_MASK (~(PAGE_SIZE-1)) +#include #define PAGE_OFFSET 0xc0000000 #define KERNELBASE PAGE_OFFSET diff --git a/arch/parisc/include/asm/page.h b/arch/parisc/include/asm/page.h index 4bea2e95798f0..6c4836fb54070 100644 --- a/arch/parisc/include/asm/page.h +++ b/arch/parisc/include/asm/page.h @@ -4,9 +4,7 @@ #include -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) +#include #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index 83d0a4fc5f755..af9a2628d1df0 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h @@ -21,8 +21,7 @@ * page size. When using 64K pages however, whether we are really supporting * 64K pages in HW or not is irrelevant to those definitions. */ -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT) +#include #ifndef __ASSEMBLY__ #ifndef CONFIG_HUGETLB_PAGE @@ -41,13 +40,6 @@ extern unsigned int hpage_shift; #define HUGE_MAX_HSTATE (MMU_PAGE_COUNT-1) #endif -/* - * Subtle: (1 << PAGE_SHIFT) is an int, not an unsigned long. So if we - * assign PAGE_MASK to a larger type it gets extended the way we want - * (i.e. with 1s in the high bits) - */ -#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) - /* * KERNELBASE is the virtual address of the start of the kernel, it's often * the same as PAGE_OFFSET, but _might not be_. diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h index 32d308a3355fd..9875399827c78 100644 --- a/arch/riscv/include/asm/page.h +++ b/arch/riscv/include/asm/page.h @@ -12,9 +12,7 @@ #include #include -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE - 1)) +#include #define HPAGE_SHIFT PMD_SHIFT #define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT) diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h index 73e1e03317b43..dbc25dc5fa0a3 100644 --- a/arch/s390/include/asm/page.h +++ b/arch/s390/include/asm/page.h @@ -11,14 +11,11 @@ #include #include -#define _PAGE_SHIFT CONFIG_PAGE_SHIFT -#define _PAGE_SIZE (_AC(1, UL) << _PAGE_SHIFT) -#define _PAGE_MASK (~(_PAGE_SIZE - 1)) - -/* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT _PAGE_SHIFT -#define PAGE_SIZE _PAGE_SIZE -#define PAGE_MASK _PAGE_MASK +#include + +#define _PAGE_SHIFT PAGE_SHIFT +#define _PAGE_SIZE PAGE_SIZE +#define _PAGE_MASK PAGE_MASK #define PAGE_DEFAULT_ACC _AC(0, UL) /* storage-protection override */ #define PAGE_SPO_ACC 9 diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index f780b467e75d7..fc39b8171bfb4 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -8,10 +8,8 @@ #include -/* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) +#include + #define PTE_MASK PAGE_MASK #if defined(CONFIG_HUGETLB_PAGE_SIZE_64K) diff --git a/arch/sparc/include/asm/page_32.h b/arch/sparc/include/asm/page_32.h index 9977c77374cd4..9954254ea5698 100644 --- a/arch/sparc/include/asm/page_32.h +++ b/arch/sparc/include/asm/page_32.h @@ -11,9 +11,7 @@ #include -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) +#include #ifndef __ASSEMBLY__ diff --git a/arch/sparc/include/asm/page_64.h b/arch/sparc/include/asm/page_64.h index e9bd24821c93d..2a68ff5b6eabd 100644 --- a/arch/sparc/include/asm/page_64.h +++ b/arch/sparc/include/asm/page_64.h @@ -4,9 +4,7 @@ #include -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) +#include /* Flushing for D-cache alias handling is only needed if * the page size is smaller than 16K. diff --git a/arch/um/include/asm/page.h b/arch/um/include/asm/page.h index 9ef9a8aedfa66..834313ecd3d65 100644 --- a/arch/um/include/asm/page.h +++ b/arch/um/include/asm/page.h @@ -9,10 +9,7 @@ #include -/* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) +#include #ifndef __ASSEMBLY__ diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h index 52f1b4ff0cc16..974688973cf6e 100644 --- a/arch/x86/include/asm/page_types.h +++ b/arch/x86/include/asm/page_types.h @@ -6,10 +6,7 @@ #include #include -/* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) +#include #define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1) diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h index 4db56ef052d22..595c1037b7388 100644 --- a/arch/xtensa/include/asm/page.h +++ b/arch/xtensa/include/asm/page.h @@ -18,13 +18,7 @@ #include #include -/* - * PAGE_SHIFT determines the page size - */ - -#define PAGE_SHIFT CONFIG_PAGE_SHIFT -#define PAGE_SIZE (__XTENSA_UL_CONST(1) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) +#include #ifdef CONFIG_MMU #define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR diff --git a/include/vdso/page.h b/include/vdso/page.h new file mode 100644 index 0000000000000..4ada1ba6bd1f8 --- /dev/null +++ b/include/vdso/page.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __VDSO_PAGE_H +#define __VDSO_PAGE_H + +#include + +/* + * PAGE_SHIFT determines the page size. + * + * Note: This definition is required because PAGE_SHIFT is used + * in several places throuout the codebase. + */ +#define PAGE_SHIFT CONFIG_PAGE_SHIFT + +#define PAGE_SIZE (_AC(1,UL) << CONFIG_PAGE_SHIFT) + +#if defined(CONFIG_PHYS_ADDR_T_64BIT) && !defined(CONFIG_64BIT) +/* + * Applies only to 32-bit architectures with a 64-bit phys_addr_t. + * + * Subtle: (1 << CONFIG_PAGE_SHIFT) is an int, not an unsigned long. + * So if we assign PAGE_MASK to a larger type it gets extended the + * way we want (i.e. with 1s in the high bits) + */ +#define PAGE_MASK (~((1 << CONFIG_PAGE_SHIFT) - 1)) +#else +#define PAGE_MASK (~(PAGE_SIZE - 1)) +#endif + +#endif /* __VDSO_PAGE_H */ From 6febe0efb2df49105b839d6a3a45ab63d40f315a Mon Sep 17 00:00:00 2001 From: Vincenzo Frascino Date: Mon, 14 Oct 2024 16:13:40 +0100 Subject: [PATCH 12/42] s390: Remove remaining _PAGE_* macros The introduction of vdso/page.h made the definition of _PAGE_SHIFT, _PAGE_SIZE, _PAGE_MASK redundant. Refactor the code to remove the macros. Reported-by: kernel test robot Signed-off-by: Vincenzo Frascino Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241014151340.1639555-4-vincenzo.frascino@arm.com Closes: https://lore.kernel.org/oe-kbuild-all/202410112106.mvc2U2p0-lkp@intel.com/ --- arch/s390/include/asm/page.h | 3 --- arch/s390/include/asm/pgtable.h | 2 +- arch/s390/mm/fault.c | 2 +- arch/s390/mm/gmap.c | 6 +++--- arch/s390/mm/pgalloc.c | 4 ++-- 5 files changed, 7 insertions(+), 10 deletions(-) diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h index dbc25dc5fa0a3..b7ba87f897616 100644 --- a/arch/s390/include/asm/page.h +++ b/arch/s390/include/asm/page.h @@ -13,9 +13,6 @@ #include -#define _PAGE_SHIFT PAGE_SHIFT -#define _PAGE_SIZE PAGE_SIZE -#define _PAGE_MASK PAGE_MASK #define PAGE_DEFAULT_ACC _AC(0, UL) /* storage-protection override */ #define PAGE_SPO_ACC 9 diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 0ffbaf7419558..8b67036edb697 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -338,7 +338,7 @@ static inline int is_module_addr(void *addr) #define _REGION2_INDEX (0x7ffUL << _REGION2_SHIFT) #define _REGION3_INDEX (0x7ffUL << _REGION3_SHIFT) #define _SEGMENT_INDEX (0x7ffUL << _SEGMENT_SHIFT) -#define _PAGE_INDEX (0xffUL << _PAGE_SHIFT) +#define _PAGE_INDEX (0xffUL << PAGE_SHIFT) #define _REGION1_SIZE (1UL << _REGION1_SHIFT) #define _REGION2_SIZE (1UL << _REGION2_SHIFT) diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index ad8b0d6b77ea1..12e10269dfcd6 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -147,7 +147,7 @@ static void dump_pagetable(unsigned long asce, unsigned long address) goto out; table = __va(entry & _SEGMENT_ENTRY_ORIGIN); } - table += (address & _PAGE_INDEX) >> _PAGE_SHIFT; + table += (address & _PAGE_INDEX) >> PAGE_SHIFT; if (get_kernel_nofault(entry, table)) goto bad; pr_cont("P:%016lx ", entry); diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index eb0b51a36be01..346ec059c8bd7 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -851,7 +851,7 @@ static inline unsigned long *gmap_table_walk(struct gmap *gmap, if (*table & _REGION_ENTRY_INVALID) return NULL; table = __va(*table & _SEGMENT_ENTRY_ORIGIN); - table += (gaddr & _PAGE_INDEX) >> _PAGE_SHIFT; + table += (gaddr & _PAGE_INDEX) >> PAGE_SHIFT; } return table; } @@ -1317,7 +1317,7 @@ static void gmap_unshadow_page(struct gmap *sg, unsigned long raddr) table = gmap_table_walk(sg, raddr, 0); /* get page table pointer */ if (!table || *table & _PAGE_INVALID) return; - gmap_call_notifier(sg, raddr, raddr + _PAGE_SIZE - 1); + gmap_call_notifier(sg, raddr, raddr + PAGE_SIZE - 1); ptep_unshadow_pte(sg->mm, raddr, (pte_t *) table); } @@ -1335,7 +1335,7 @@ static void __gmap_unshadow_pgt(struct gmap *sg, unsigned long raddr, int i; BUG_ON(!gmap_is_shadow(sg)); - for (i = 0; i < _PAGE_ENTRIES; i++, raddr += _PAGE_SIZE) + for (i = 0; i < _PAGE_ENTRIES; i++, raddr += PAGE_SIZE) pgt[i] = _PAGE_INVALID; } diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c index f691e0fb66a25..58696a0c4e4ac 100644 --- a/arch/s390/mm/pgalloc.c +++ b/arch/s390/mm/pgalloc.c @@ -278,7 +278,7 @@ static inline unsigned long base_##NAME##_addr_end(unsigned long addr, \ return (next - 1) < (end - 1) ? next : end; \ } -BASE_ADDR_END_FUNC(page, _PAGE_SIZE) +BASE_ADDR_END_FUNC(page, PAGE_SIZE) BASE_ADDR_END_FUNC(segment, _SEGMENT_SIZE) BASE_ADDR_END_FUNC(region3, _REGION3_SIZE) BASE_ADDR_END_FUNC(region2, _REGION2_SIZE) @@ -302,7 +302,7 @@ static int base_page_walk(unsigned long *origin, unsigned long addr, if (!alloc) return 0; pte = origin; - pte += (addr & _PAGE_INDEX) >> _PAGE_SHIFT; + pte += (addr & _PAGE_INDEX) >> PAGE_SHIFT; do { next = base_page_addr_end(addr, end); *pte = base_lra(addr); From d4a65302dd849fade9e2ca712826c35b8d068ecb Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 24 Oct 2024 13:34:26 +0000 Subject: [PATCH 13/42] vdso: Change PAGE_MASK to signed on all 32-bit architectures With the introduction of an architecture-independent defintion of PAGE_MASK, we had to make a choice between defining it as 'unsigned long' as on 64-bit architectures, or as signed 'long' as required for architectures with a 64-bit phys_addr_t. To reduce the risk for regressions and minimize the changes in behavior, the result was using the signed value only when CONFIG_PHYS_ADDR_T_64BIT is set, but that ended up causing a regression after all in the early_init_dt_add_memory_arch() function that uses 64-bit integers for address calculation. Presumably the same regression also affects mips32 and powerpc32 when dealing with large amounts of memory on DT platforms: like arm32, they were using the signed version unconditionally. The two most sensible options for addressing the regression are either to go back to an architecture specific definition, using a signed constant on arm/powerpc/mips and unsigned on the others, or to use the same definition everywhere. Use the simpler of those two and change them all to the signed version, in the hope that this does not cause a different type of bug. Most of the other 32-bit architectures have no large physical address support and are rarely used, so it seems more likely that using the same definition helps than hurts here. In particular, x86-32 does have physical addressing extensions, so it already changed to the signed version after the previous patch, so it makes sense to use the same version on non-PAE as well. Fixes: efe8419ae78d ("vdso: Introduce vdso/page.h") Reported-by: Naresh Kamboju Signed-off-by: Arnd Bergmann Signed-off-by: Thomas Gleixner Tested-by: Anders Roxell Tested-by: Vincenzo Frascino Reviewed-by: Vincenzo Frascino Link: https://lore.kernel.org/all/20241024133447.3117273-1-arnd@kernel.org Link: https://lore.kernel.org/lkml/CA+G9fYt86bUAu_v5dXPWnDUwQNVipj+Wq3Djir1KUSKdr9QLNg@mail.gmail.com/ --- include/vdso/page.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/vdso/page.h b/include/vdso/page.h index 4ada1ba6bd1f8..710ae2414e68f 100644 --- a/include/vdso/page.h +++ b/include/vdso/page.h @@ -14,13 +14,14 @@ #define PAGE_SIZE (_AC(1,UL) << CONFIG_PAGE_SHIFT) -#if defined(CONFIG_PHYS_ADDR_T_64BIT) && !defined(CONFIG_64BIT) +#if !defined(CONFIG_64BIT) /* - * Applies only to 32-bit architectures with a 64-bit phys_addr_t. + * Applies only to 32-bit architectures. * * Subtle: (1 << CONFIG_PAGE_SHIFT) is an int, not an unsigned long. * So if we assign PAGE_MASK to a larger type it gets extended the - * way we want (i.e. with 1s in the high bits) + * way we want (i.e. with 1s in the high bits) while masking a + * 64-bit value such as phys_addr_t. */ #define PAGE_MASK (~((1 << CONFIG_PAGE_SHIFT) - 1)) #else From cf12469600fe50aa4ce720645fd31e97a5d2e87b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:03 +0200 Subject: [PATCH 14/42] csky/vdso: Remove gettimeofday() and friends from VDSO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The time-related VDSO functionality was introduced in 2021 in commit 87f3248cdb9a ("csky: Reconstruct VDSO framework") and commit 0d3b051adbb7 ("csky: Add VDSO with GENERIC_GETTIMEOFDAY, GENERIC_TIME_VSYSCALL, HAVE_GENERIC_VDSO"). However the corresponding aux-vector entry AT_SYSINFO_EHDR was never wired up, making these functions impossible to test or use. The VDSO itself is kept as it also provides rt_sigreturn which is exposed differently to userspace. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-1-b64f0842d512@linutronix.de --- arch/csky/Kconfig | 4 - arch/csky/include/asm/vdso/clocksource.h | 9 -- arch/csky/include/asm/vdso/gettimeofday.h | 114 ---------------------- arch/csky/include/asm/vdso/processor.h | 12 --- arch/csky/include/asm/vdso/vsyscall.h | 22 ----- arch/csky/kernel/vdso.c | 24 +---- arch/csky/kernel/vdso/Makefile | 1 - arch/csky/kernel/vdso/vdso.lds.S | 4 - arch/csky/kernel/vdso/vgettimeofday.c | 30 ------ 9 files changed, 2 insertions(+), 218 deletions(-) delete mode 100644 arch/csky/include/asm/vdso/clocksource.h delete mode 100644 arch/csky/include/asm/vdso/gettimeofday.h delete mode 100644 arch/csky/include/asm/vdso/processor.h delete mode 100644 arch/csky/include/asm/vdso/vsyscall.h delete mode 100644 arch/csky/kernel/vdso/vgettimeofday.c diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig index 5479707eb5d10..acc431c331b08 100644 --- a/arch/csky/Kconfig +++ b/arch/csky/Kconfig @@ -64,9 +64,6 @@ config CSKY select GENERIC_IRQ_MULTI_HANDLER select GENERIC_SCHED_CLOCK select GENERIC_SMP_IDLE_THREAD - select GENERIC_TIME_VSYSCALL - select GENERIC_VDSO_32 - select GENERIC_GETTIMEOFDAY select GX6605S_TIMER if CPU_CK610 select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_AUDITSYSCALL @@ -80,7 +77,6 @@ config CSKY select HAVE_DEBUG_KMEMLEAK select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE_WITH_REGS - select HAVE_GENERIC_VDSO select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_ERROR_INJECTION diff --git a/arch/csky/include/asm/vdso/clocksource.h b/arch/csky/include/asm/vdso/clocksource.h deleted file mode 100644 index dfca7b4724b79..0000000000000 --- a/arch/csky/include/asm/vdso/clocksource.h +++ /dev/null @@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ - -#ifndef __ASM_VDSO_CSKY_CLOCKSOURCE_H -#define __ASM_VDSO_CSKY_CLOCKSOURCE_H - -#define VDSO_ARCH_CLOCKMODES \ - VDSO_CLOCKMODE_ARCHTIMER - -#endif /* __ASM_VDSO_CSKY_CLOCKSOURCE_H */ diff --git a/arch/csky/include/asm/vdso/gettimeofday.h b/arch/csky/include/asm/vdso/gettimeofday.h deleted file mode 100644 index 6c4f1446944f9..0000000000000 --- a/arch/csky/include/asm/vdso/gettimeofday.h +++ /dev/null @@ -1,114 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ - -#ifndef __ASM_VDSO_CSKY_GETTIMEOFDAY_H -#define __ASM_VDSO_CSKY_GETTIMEOFDAY_H - -#ifndef __ASSEMBLY__ - -#include -#include -#include -#include - -#define VDSO_HAS_CLOCK_GETRES 1 - -static __always_inline -int gettimeofday_fallback(struct __kernel_old_timeval *_tv, - struct timezone *_tz) -{ - register struct __kernel_old_timeval *tv asm("a0") = _tv; - register struct timezone *tz asm("a1") = _tz; - register long ret asm("a0"); - register long nr asm(syscallid) = __NR_gettimeofday; - - asm volatile ("trap 0\n" - : "=r" (ret) - : "r"(tv), "r"(tz), "r"(nr) - : "memory"); - - return ret; -} - -static __always_inline -long clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) -{ - register clockid_t clkid asm("a0") = _clkid; - register struct __kernel_timespec *ts asm("a1") = _ts; - register long ret asm("a0"); - register long nr asm(syscallid) = __NR_clock_gettime64; - - asm volatile ("trap 0\n" - : "=r" (ret) - : "r"(clkid), "r"(ts), "r"(nr) - : "memory"); - - return ret; -} - -static __always_inline -long clock_gettime32_fallback(clockid_t _clkid, struct old_timespec32 *_ts) -{ - register clockid_t clkid asm("a0") = _clkid; - register struct old_timespec32 *ts asm("a1") = _ts; - register long ret asm("a0"); - register long nr asm(syscallid) = __NR_clock_gettime; - - asm volatile ("trap 0\n" - : "=r" (ret) - : "r"(clkid), "r"(ts), "r"(nr) - : "memory"); - - return ret; -} - -static __always_inline -int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) -{ - register clockid_t clkid asm("a0") = _clkid; - register struct __kernel_timespec *ts asm("a1") = _ts; - register long ret asm("a0"); - register long nr asm(syscallid) = __NR_clock_getres_time64; - - asm volatile ("trap 0\n" - : "=r" (ret) - : "r"(clkid), "r"(ts), "r"(nr) - : "memory"); - - return ret; -} - -static __always_inline -int clock_getres32_fallback(clockid_t _clkid, struct old_timespec32 *_ts) -{ - register clockid_t clkid asm("a0") = _clkid; - register struct old_timespec32 *ts asm("a1") = _ts; - register long ret asm("a0"); - register long nr asm(syscallid) = __NR_clock_getres; - - asm volatile ("trap 0\n" - : "=r" (ret) - : "r"(clkid), "r"(ts), "r"(nr) - : "memory"); - - return ret; -} - -uint64_t csky_pmu_read_cc(void); -static __always_inline u64 __arch_get_hw_counter(s32 clock_mode, - const struct vdso_data *vd) -{ -#ifdef CONFIG_CSKY_PMU_V1 - return csky_pmu_read_cc(); -#else - return 0; -#endif -} - -static __always_inline const struct vdso_data *__arch_get_vdso_data(void) -{ - return _vdso_data; -} - -#endif /* !__ASSEMBLY__ */ - -#endif /* __ASM_VDSO_CSKY_GETTIMEOFDAY_H */ diff --git a/arch/csky/include/asm/vdso/processor.h b/arch/csky/include/asm/vdso/processor.h deleted file mode 100644 index 39a6b561d0cc8..0000000000000 --- a/arch/csky/include/asm/vdso/processor.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef __ASM_VDSO_CSKY_PROCESSOR_H -#define __ASM_VDSO_CSKY_PROCESSOR_H - -#ifndef __ASSEMBLY__ - -#define cpu_relax() barrier() - -#endif /* __ASSEMBLY__ */ - -#endif /* __ASM_VDSO_CSKY_PROCESSOR_H */ diff --git a/arch/csky/include/asm/vdso/vsyscall.h b/arch/csky/include/asm/vdso/vsyscall.h deleted file mode 100644 index c276211a7c4d5..0000000000000 --- a/arch/csky/include/asm/vdso/vsyscall.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ - -#ifndef __ASM_VDSO_CSKY_VSYSCALL_H -#define __ASM_VDSO_CSKY_VSYSCALL_H - -#ifndef __ASSEMBLY__ - -#include - -extern struct vdso_data *vdso_data; - -static __always_inline struct vdso_data *__csky_get_k_vdso_data(void) -{ - return vdso_data; -} -#define __arch_get_k_vdso_data __csky_get_k_vdso_data - -#include - -#endif /* !__ASSEMBLY__ */ - -#endif /* __ASM_VDSO_CSKY_VSYSCALL_H */ diff --git a/arch/csky/kernel/vdso.c b/arch/csky/kernel/vdso.c index 5c9ef63c29f1d..92ab8ac6a5960 100644 --- a/arch/csky/kernel/vdso.c +++ b/arch/csky/kernel/vdso.c @@ -8,23 +8,19 @@ #include #include -#include extern char vdso_start[], vdso_end[]; static unsigned int vdso_pages; static struct page **vdso_pagelist; -static union vdso_data_store vdso_data_store __page_aligned_data; -struct vdso_data *vdso_data = vdso_data_store.data; - static int __init vdso_init(void) { unsigned int i; vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT; vdso_pagelist = - kcalloc(vdso_pages + 1, sizeof(struct page *), GFP_KERNEL); + kcalloc(vdso_pages, sizeof(struct page *), GFP_KERNEL); if (unlikely(vdso_pagelist == NULL)) { pr_err("vdso: pagelist allocation failed\n"); return -ENOMEM; @@ -36,7 +32,6 @@ static int __init vdso_init(void) pg = virt_to_page(vdso_start + (i << PAGE_SHIFT)); vdso_pagelist[i] = pg; } - vdso_pagelist[i] = virt_to_page(vdso_data); return 0; } @@ -52,11 +47,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, static struct vm_special_mapping vdso_mapping = { .name = "[vdso]", }; - static struct vm_special_mapping vvar_mapping = { - .name = "[vvar]", - }; - vdso_len = (vdso_pages + 1) << PAGE_SHIFT; + vdso_len = vdso_pages << PAGE_SHIFT; mmap_write_lock(mm); vdso_base = get_unmapped_area(NULL, 0, vdso_len, 0, 0); @@ -85,15 +77,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, } vdso_base += (vdso_pages << PAGE_SHIFT); - vvar_mapping.pages = &vdso_pagelist[vdso_pages]; - vma = _install_special_mapping(mm, vdso_base, PAGE_SIZE, - (VM_READ | VM_MAYREAD), &vvar_mapping); - - if (IS_ERR(vma)) { - ret = PTR_ERR(vma); - mm->context.vdso = NULL; - goto end; - } ret = 0; end: mmap_write_unlock(mm); @@ -104,8 +87,5 @@ const char *arch_vma_name(struct vm_area_struct *vma) { if (vma->vm_mm && (vma->vm_start == (long)vma->vm_mm->context.vdso)) return "[vdso]"; - if (vma->vm_mm && (vma->vm_start == - (long)vma->vm_mm->context.vdso + PAGE_SIZE)) - return "[vdso_data]"; return NULL; } diff --git a/arch/csky/kernel/vdso/Makefile b/arch/csky/kernel/vdso/Makefile index bc2261f5a8d43..069ef0b17fe52 100644 --- a/arch/csky/kernel/vdso/Makefile +++ b/arch/csky/kernel/vdso/Makefile @@ -5,7 +5,6 @@ include $(srctree)/lib/vdso/Makefile # Symbols present in the vdso vdso-syms += rt_sigreturn -vdso-syms += vgettimeofday # Files to link into the vdso obj-vdso = $(patsubst %, %.o, $(vdso-syms)) note.o diff --git a/arch/csky/kernel/vdso/vdso.lds.S b/arch/csky/kernel/vdso/vdso.lds.S index 590a6c79fff7d..8d226252d4394 100644 --- a/arch/csky/kernel/vdso/vdso.lds.S +++ b/arch/csky/kernel/vdso/vdso.lds.S @@ -49,10 +49,6 @@ VERSION LINUX_5.10 { global: __vdso_rt_sigreturn; - __vdso_clock_gettime; - __vdso_clock_gettime64; - __vdso_gettimeofday; - __vdso_clock_getres; local: *; }; } diff --git a/arch/csky/kernel/vdso/vgettimeofday.c b/arch/csky/kernel/vdso/vgettimeofday.c deleted file mode 100644 index 55af30e837528..0000000000000 --- a/arch/csky/kernel/vdso/vgettimeofday.c +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#include -#include -#include - -extern -int __vdso_clock_gettime(clockid_t clock, - struct old_timespec32 *ts) -{ - return __cvdso_clock_gettime32(clock, ts); -} - -int __vdso_clock_gettime64(clockid_t clock, - struct __kernel_timespec *ts) -{ - return __cvdso_clock_gettime(clock, ts); -} - -int __vdso_gettimeofday(struct __kernel_old_timeval *tv, - struct timezone *tz) -{ - return __cvdso_gettimeofday(tv, tz); -} - -int __vdso_clock_getres(clockid_t clock_id, - struct old_timespec32 *res) -{ - return __cvdso_clock_getres_time32(clock_id, res); -} From ff435493d67a2ca7b7be88c3feeca52893790391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:04 +0200 Subject: [PATCH 15/42] csky/vdso: Remove arch_vma_name() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All callers of arch_vma_name() also get the name via vm_ops, which for these VMAs will use the name from 'struct vma_special_mapping'. Therefore the custom implementation is unnecessary and can be removed in favor of the default implementation from kernel/signal.c. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-2-b64f0842d512@linutronix.de --- arch/csky/kernel/vdso.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/arch/csky/kernel/vdso.c b/arch/csky/kernel/vdso.c index 92ab8ac6a5960..c54d019d66bca 100644 --- a/arch/csky/kernel/vdso.c +++ b/arch/csky/kernel/vdso.c @@ -82,10 +82,3 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, mmap_write_unlock(mm); return ret; } - -const char *arch_vma_name(struct vm_area_struct *vma) -{ - if (vma->vm_mm && (vma->vm_start == (long)vma->vm_mm->context.vdso)) - return "[vdso]"; - return NULL; -} From 98333a84e3318a1dd08a3ec6def98abfb8215cdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:05 +0200 Subject: [PATCH 16/42] s390/vdso: Drop LBASE_VDSO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This constant is always "0", providing no value and making the logic harder to understand. Also prepare for a consolidation of the vdso linkerscript logic by aligning it with other architectures. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Acked-by: Heiko Carstens Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-3-b64f0842d512@linutronix.de --- arch/s390/include/asm/vdso.h | 3 --- arch/s390/kernel/vdso32/vdso32.lds.S | 2 +- arch/s390/kernel/vdso64/vdso64.lds.S | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/arch/s390/include/asm/vdso.h b/arch/s390/include/asm/vdso.h index 91061f0279be4..92c73e4d97a93 100644 --- a/arch/s390/include/asm/vdso.h +++ b/arch/s390/include/asm/vdso.h @@ -12,9 +12,6 @@ int vdso_getcpu_init(void); #endif /* __ASSEMBLY__ */ -/* Default link address for the vDSO */ -#define VDSO_LBASE 0 - #define __VVAR_PAGES 2 #define VDSO_VERSION_STRING LINUX_2.6.29 diff --git a/arch/s390/kernel/vdso32/vdso32.lds.S b/arch/s390/kernel/vdso32/vdso32.lds.S index 65b9513a5a0ee..c916c4f73f766 100644 --- a/arch/s390/kernel/vdso32/vdso32.lds.S +++ b/arch/s390/kernel/vdso32/vdso32.lds.S @@ -16,7 +16,7 @@ SECTIONS #ifdef CONFIG_TIME_NS PROVIDE(_timens_data = _vdso_data + PAGE_SIZE); #endif - . = VDSO_LBASE + SIZEOF_HEADERS; + . = SIZEOF_HEADERS; .hash : { *(.hash) } :text .gnu.hash : { *(.gnu.hash) } diff --git a/arch/s390/kernel/vdso64/vdso64.lds.S b/arch/s390/kernel/vdso64/vdso64.lds.S index 753040a4b5ab2..ec42b7d9cb530 100644 --- a/arch/s390/kernel/vdso64/vdso64.lds.S +++ b/arch/s390/kernel/vdso64/vdso64.lds.S @@ -18,7 +18,7 @@ SECTIONS #ifdef CONFIG_TIME_NS PROVIDE(_timens_data = _vdso_data + PAGE_SIZE); #endif - . = VDSO_LBASE + SIZEOF_HEADERS; + . = SIZEOF_HEADERS; .hash : { *(.hash) } :text .gnu.hash : { *(.gnu.hash) } From 0973fed6a5e58dd2515a83dd7f83ad674e91cc4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:06 +0200 Subject: [PATCH 17/42] arm64: vdso: Drop LBASE_VDSO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This constant is always "0", providing no value and making the logic harder to understand. Also prepare for a consolidation of the vdso linkerscript logic by aligning it with other architectures. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Acked-by: Will Deacon Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-4-b64f0842d512@linutronix.de --- arch/arm64/include/asm/vdso.h | 9 +-------- arch/arm64/kernel/vdso/vdso.lds.S | 2 +- arch/arm64/kernel/vdso32/vdso.lds.S | 2 +- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h index 4305995c8f82f..3e3c3fdb18427 100644 --- a/arch/arm64/include/asm/vdso.h +++ b/arch/arm64/include/asm/vdso.h @@ -5,13 +5,6 @@ #ifndef __ASM_VDSO_H #define __ASM_VDSO_H -/* - * Default link address for the vDSO. - * Since we randomise the VDSO mapping, there's little point in trying - * to prelink this. - */ -#define VDSO_LBASE 0x0 - #define __VVAR_PAGES 2 #ifndef __ASSEMBLY__ @@ -20,7 +13,7 @@ #define VDSO_SYMBOL(base, name) \ ({ \ - (void *)(vdso_offset_##name - VDSO_LBASE + (unsigned long)(base)); \ + (void *)(vdso_offset_##name + (unsigned long)(base)); \ }) extern char vdso_start[], vdso_end[]; diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S index f204a9ddc8335..4ec32e86a8da2 100644 --- a/arch/arm64/kernel/vdso/vdso.lds.S +++ b/arch/arm64/kernel/vdso/vdso.lds.S @@ -25,7 +25,7 @@ SECTIONS #ifdef CONFIG_TIME_NS PROVIDE(_timens_data = _vdso_data + PAGE_SIZE); #endif - . = VDSO_LBASE + SIZEOF_HEADERS; + . = SIZEOF_HEADERS; .hash : { *(.hash) } :text .gnu.hash : { *(.gnu.hash) } diff --git a/arch/arm64/kernel/vdso32/vdso.lds.S b/arch/arm64/kernel/vdso32/vdso.lds.S index 8d95d7d35057d..732702a187e9e 100644 --- a/arch/arm64/kernel/vdso32/vdso.lds.S +++ b/arch/arm64/kernel/vdso32/vdso.lds.S @@ -22,7 +22,7 @@ SECTIONS #ifdef CONFIG_TIME_NS PROVIDE_HIDDEN(_timens_data = _vdso_data + PAGE_SIZE); #endif - . = VDSO_LBASE + SIZEOF_HEADERS; + . = SIZEOF_HEADERS; .hash : { *(.hash) } :text .gnu.hash : { *(.gnu.hash) } From 461c96686625860e77b51d3f3226f9b0facf41a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:07 +0200 Subject: [PATCH 18/42] arm64: vdso: Use only one single vvar mapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The vvar mapping is the same for all processes. Use a single mapping to simplify the logic and align it with the other architectures. In addition this will enable the move of the vvar handling into generic code. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Tested-by: Will Deacon Acked-by: Will Deacon Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-5-b64f0842d512@linutronix.de --- arch/arm64/kernel/vdso.c | 43 ++++++++++++---------------------------- 1 file changed, 13 insertions(+), 30 deletions(-) diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 8ef20c16bc482..e8ed8e5b713b5 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -38,8 +38,6 @@ struct vdso_abi_info { const char *vdso_code_start; const char *vdso_code_end; unsigned long vdso_pages; - /* Data Mapping */ - struct vm_special_mapping *dm; /* Code Mapping */ struct vm_special_mapping *cm; }; @@ -112,6 +110,8 @@ struct vdso_data *arch_get_vdso_data(void *vvar_page) return (struct vdso_data *)(vvar_page); } +static const struct vm_special_mapping vvar_map; + /* * The vvar mapping contains data for a specific time namespace, so when a task * changes namespace we must unmap its vvar data for the old namespace. @@ -128,12 +128,8 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns) mmap_read_lock(mm); for_each_vma(vmi, vma) { - if (vma_is_special_mapping(vma, vdso_info[VDSO_ABI_AA64].dm)) - zap_vma_pages(vma); -#ifdef CONFIG_COMPAT_VDSO - if (vma_is_special_mapping(vma, vdso_info[VDSO_ABI_AA32].dm)) + if (vma_is_special_mapping(vma, &vvar_map)) zap_vma_pages(vma); -#endif } mmap_read_unlock(mm); @@ -175,6 +171,11 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm, return vmf_insert_pfn(vma, vmf->address, pfn); } +static const struct vm_special_mapping vvar_map = { + .name = "[vvar]", + .fault = vvar_fault, +}; + static int __setup_additional_pages(enum vdso_abi abi, struct mm_struct *mm, struct linux_binprm *bprm, @@ -198,7 +199,7 @@ static int __setup_additional_pages(enum vdso_abi abi, ret = _install_special_mapping(mm, vdso_base, VVAR_NR_PAGES * PAGE_SIZE, VM_READ|VM_MAYREAD|VM_PFNMAP, - vdso_info[abi].dm); + &vvar_map); if (IS_ERR(ret)) goto up_fail; @@ -228,7 +229,6 @@ static int __setup_additional_pages(enum vdso_abi abi, enum aarch32_map { AA32_MAP_VECTORS, /* kuser helpers */ AA32_MAP_SIGPAGE, - AA32_MAP_VVAR, AA32_MAP_VDSO, }; @@ -253,10 +253,6 @@ static struct vm_special_mapping aarch32_vdso_maps[] = { .pages = &aarch32_sig_page, .mremap = aarch32_sigpage_mremap, }, - [AA32_MAP_VVAR] = { - .name = "[vvar]", - .fault = vvar_fault, - }, [AA32_MAP_VDSO] = { .name = "[vdso]", .mremap = vdso_mremap, @@ -306,7 +302,6 @@ static int __init __aarch32_alloc_vdso_pages(void) if (!IS_ENABLED(CONFIG_COMPAT_VDSO)) return 0; - vdso_info[VDSO_ABI_AA32].dm = &aarch32_vdso_maps[AA32_MAP_VVAR]; vdso_info[VDSO_ABI_AA32].cm = &aarch32_vdso_maps[AA32_MAP_VDSO]; return __vdso_init(VDSO_ABI_AA32); @@ -401,26 +396,14 @@ int aarch32_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) } #endif /* CONFIG_COMPAT */ -enum aarch64_map { - AA64_MAP_VVAR, - AA64_MAP_VDSO, -}; - -static struct vm_special_mapping aarch64_vdso_maps[] __ro_after_init = { - [AA64_MAP_VVAR] = { - .name = "[vvar]", - .fault = vvar_fault, - }, - [AA64_MAP_VDSO] = { - .name = "[vdso]", - .mremap = vdso_mremap, - }, +static struct vm_special_mapping aarch64_vdso_map __ro_after_init = { + .name = "[vdso]", + .mremap = vdso_mremap, }; static int __init vdso_init(void) { - vdso_info[VDSO_ABI_AA64].dm = &aarch64_vdso_maps[AA64_MAP_VVAR]; - vdso_info[VDSO_ABI_AA64].cm = &aarch64_vdso_maps[AA64_MAP_VDSO]; + vdso_info[VDSO_ABI_AA64].cm = &aarch64_vdso_map; return __vdso_init(VDSO_ABI_AA64); } From d34b60752fcb3380d753268bfba6ebc1d3ba8468 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:08 +0200 Subject: [PATCH 19/42] riscv: vdso: Use only one single vvar mapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The vvar mapping is the same for all processes. Use a single mapping to simplify the logic and align it with the other architectures. In addition this will enable the move of the vvar handling into generic code. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-6-b64f0842d512@linutronix.de --- arch/riscv/kernel/vdso.c | 52 +++++++++++++--------------------------- 1 file changed, 17 insertions(+), 35 deletions(-) diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c index 98315b98256df..3ca3ae4277e18 100644 --- a/arch/riscv/kernel/vdso.c +++ b/arch/riscv/kernel/vdso.c @@ -23,11 +23,6 @@ enum vvar_pages { VVAR_NR_PAGES, }; -enum rv_vdso_map { - RV_VDSO_MAP_VVAR, - RV_VDSO_MAP_VDSO, -}; - #define VVAR_SIZE (VVAR_NR_PAGES << PAGE_SHIFT) static union vdso_data_store vdso_data_store __page_aligned_data; @@ -38,8 +33,6 @@ struct __vdso_info { const char *vdso_code_start; const char *vdso_code_end; unsigned long vdso_pages; - /* Data Mapping */ - struct vm_special_mapping *dm; /* Code Mapping */ struct vm_special_mapping *cm; }; @@ -92,6 +85,8 @@ struct vdso_data *arch_get_vdso_data(void *vvar_page) return (struct vdso_data *)(vvar_page); } +static const struct vm_special_mapping rv_vvar_map; + /* * The vvar mapping contains data for a specific time namespace, so when a task * changes namespace we must unmap its vvar data for the old namespace. @@ -108,12 +103,8 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns) mmap_read_lock(mm); for_each_vma(vmi, vma) { - if (vma_is_special_mapping(vma, vdso_info.dm)) - zap_vma_pages(vma); -#ifdef CONFIG_COMPAT - if (vma_is_special_mapping(vma, compat_vdso_info.dm)) + if (vma_is_special_mapping(vma, &rv_vvar_map)) zap_vma_pages(vma); -#endif } mmap_read_unlock(mm); @@ -155,43 +146,34 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm, return vmf_insert_pfn(vma, vmf->address, pfn); } -static struct vm_special_mapping rv_vdso_maps[] __ro_after_init = { - [RV_VDSO_MAP_VVAR] = { - .name = "[vvar]", - .fault = vvar_fault, - }, - [RV_VDSO_MAP_VDSO] = { - .name = "[vdso]", - .mremap = vdso_mremap, - }, +static const struct vm_special_mapping rv_vvar_map = { + .name = "[vvar]", + .fault = vvar_fault, +}; + +static struct vm_special_mapping rv_vdso_map __ro_after_init = { + .name = "[vdso]", + .mremap = vdso_mremap, }; static struct __vdso_info vdso_info __ro_after_init = { .name = "vdso", .vdso_code_start = vdso_start, .vdso_code_end = vdso_end, - .dm = &rv_vdso_maps[RV_VDSO_MAP_VVAR], - .cm = &rv_vdso_maps[RV_VDSO_MAP_VDSO], + .cm = &rv_vdso_map, }; #ifdef CONFIG_COMPAT -static struct vm_special_mapping rv_compat_vdso_maps[] __ro_after_init = { - [RV_VDSO_MAP_VVAR] = { - .name = "[vvar]", - .fault = vvar_fault, - }, - [RV_VDSO_MAP_VDSO] = { - .name = "[vdso]", - .mremap = vdso_mremap, - }, +static struct vm_special_mapping rv_compat_vdso_map __ro_after_init = { + .name = "[vdso]", + .mremap = vdso_mremap, }; static struct __vdso_info compat_vdso_info __ro_after_init = { .name = "compat_vdso", .vdso_code_start = compat_vdso_start, .vdso_code_end = compat_vdso_end, - .dm = &rv_compat_vdso_maps[RV_VDSO_MAP_VVAR], - .cm = &rv_compat_vdso_maps[RV_VDSO_MAP_VDSO], + .cm = &rv_compat_vdso_map, }; #endif @@ -227,7 +209,7 @@ static int __setup_additional_pages(struct mm_struct *mm, } ret = _install_special_mapping(mm, vdso_base, VVAR_SIZE, - (VM_READ | VM_MAYREAD | VM_PFNMAP), vdso_info->dm); + (VM_READ | VM_MAYREAD | VM_PFNMAP), &rv_vvar_map); if (IS_ERR(ret)) goto up_fail; From 2bb79470e5c87f211d05f0dd1c7a4291c9b7e1a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:09 +0200 Subject: [PATCH 20/42] ARM: vdso: Remove assembly for datapage access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit vdso/datapage.h provides a hidden declaration for _vdso_data. When using it the compiler will automatically generate PC-relative accesses which avoids the need for a custom assembly-based accessor. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-7-b64f0842d512@linutronix.de --- arch/arm/include/asm/vdso/gettimeofday.h | 4 +--- arch/arm/vdso/Makefile | 2 +- arch/arm/vdso/datapage.S | 16 ---------------- arch/arm/vdso/vdso.lds.S | 3 ++- 4 files changed, 4 insertions(+), 21 deletions(-) delete mode 100644 arch/arm/vdso/datapage.S diff --git a/arch/arm/include/asm/vdso/gettimeofday.h b/arch/arm/include/asm/vdso/gettimeofday.h index 2134cbd5469fe..592d3d015ca72 100644 --- a/arch/arm/include/asm/vdso/gettimeofday.h +++ b/arch/arm/include/asm/vdso/gettimeofday.h @@ -15,8 +15,6 @@ #define VDSO_HAS_CLOCK_GETRES 1 -extern struct vdso_data *__get_datapage(void); - static __always_inline int gettimeofday_fallback( struct __kernel_old_timeval *_tv, struct timezone *_tz) @@ -139,7 +137,7 @@ static __always_inline u64 __arch_get_hw_counter(int clock_mode, static __always_inline const struct vdso_data *__arch_get_vdso_data(void) { - return __get_datapage(); + return _vdso_data; } #endif /* !__ASSEMBLY__ */ diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile index 01067a2bc43b7..8a306bbec4a0c 100644 --- a/arch/arm/vdso/Makefile +++ b/arch/arm/vdso/Makefile @@ -5,7 +5,7 @@ include $(srctree)/lib/vdso/Makefile hostprogs := vdsomunge -obj-vdso := vgettimeofday.o datapage.o note.o +obj-vdso := vgettimeofday.o note.o # Build rules targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.so.raw vdso.lds diff --git a/arch/arm/vdso/datapage.S b/arch/arm/vdso/datapage.S deleted file mode 100644 index 9cd73b725d9fb..0000000000000 --- a/arch/arm/vdso/datapage.S +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#include -#include - - .align 2 -.L_vdso_data_ptr: - .long _start - . - VDSO_DATA_SIZE - -ENTRY(__get_datapage) - .fnstart - adr r0, .L_vdso_data_ptr - ldr r1, [r0] - add r0, r0, r1 - bx lr - .fnend -ENDPROC(__get_datapage) diff --git a/arch/arm/vdso/vdso.lds.S b/arch/arm/vdso/vdso.lds.S index 165d1d2eb76b3..9bfa0f52923c8 100644 --- a/arch/arm/vdso/vdso.lds.S +++ b/arch/arm/vdso/vdso.lds.S @@ -11,6 +11,7 @@ */ #include +#include #include #include @@ -19,7 +20,7 @@ OUTPUT_ARCH(arm) SECTIONS { - PROVIDE(_start = .); + PROVIDE(_vdso_data = . - VDSO_DATA_SIZE); . = SIZEOF_HEADERS; From dc32cb4ba6f408e05857fbbf0b2965deec1d5c92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:10 +0200 Subject: [PATCH 21/42] LoongArch: vDSO: Use vdso/datapage.h to access vDSO data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit vdso/datapage.h provides symbols and functions to ease the access to shared vDSO data from both the kernel and the vDSO. Make use of it to simplify the current code and also prepare for further changes unifying the vDSO data storage between architectures. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-8-b64f0842d512@linutronix.de --- arch/loongarch/include/asm/vdso/getrandom.h | 3 +-- arch/loongarch/include/asm/vdso/gettimeofday.h | 4 ++-- arch/loongarch/include/asm/vdso/vdso.h | 18 +----------------- arch/loongarch/kernel/asm-offsets.c | 9 +++++++++ arch/loongarch/vdso/vdso.lds.S | 8 +++++++- arch/loongarch/vdso/vgetcpu.c | 2 +- 6 files changed, 21 insertions(+), 23 deletions(-) diff --git a/arch/loongarch/include/asm/vdso/getrandom.h b/arch/loongarch/include/asm/vdso/getrandom.h index 02f36772541b7..e80f3c4ac7481 100644 --- a/arch/loongarch/include/asm/vdso/getrandom.h +++ b/arch/loongarch/include/asm/vdso/getrandom.h @@ -30,8 +30,7 @@ static __always_inline ssize_t getrandom_syscall(void *_buffer, size_t _len, uns static __always_inline const struct vdso_rng_data *__arch_get_vdso_rng_data(void) { - return (const struct vdso_rng_data *)(get_vdso_data() + VVAR_LOONGARCH_PAGES_START * - PAGE_SIZE + offsetof(struct loongarch_vdso_data, rng_data)); + return &_loongarch_data.rng_data; } #endif /* !__ASSEMBLY__ */ diff --git a/arch/loongarch/include/asm/vdso/gettimeofday.h b/arch/loongarch/include/asm/vdso/gettimeofday.h index 89e6b222c2f2d..7eb3f041af764 100644 --- a/arch/loongarch/include/asm/vdso/gettimeofday.h +++ b/arch/loongarch/include/asm/vdso/gettimeofday.h @@ -91,14 +91,14 @@ static inline bool loongarch_vdso_hres_capable(void) static __always_inline const struct vdso_data *__arch_get_vdso_data(void) { - return (const struct vdso_data *)get_vdso_data(); + return _vdso_data; } #ifdef CONFIG_TIME_NS static __always_inline const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd) { - return (const struct vdso_data *)(get_vdso_data() + VVAR_TIMENS_PAGE_OFFSET * PAGE_SIZE); + return _timens_data; } #endif #endif /* !__ASSEMBLY__ */ diff --git a/arch/loongarch/include/asm/vdso/vdso.h b/arch/loongarch/include/asm/vdso/vdso.h index e31ac7474513c..1c183a9b2115a 100644 --- a/arch/loongarch/include/asm/vdso/vdso.h +++ b/arch/loongarch/include/asm/vdso/vdso.h @@ -48,23 +48,7 @@ enum vvar_pages { #define VVAR_SIZE (VVAR_NR_PAGES << PAGE_SHIFT) -static inline unsigned long get_vdso_base(void) -{ - unsigned long addr; - - __asm__( - " la.pcrel %0, _start\n" - : "=r" (addr) - : - :); - - return addr; -} - -static inline unsigned long get_vdso_data(void) -{ - return get_vdso_base() - VVAR_SIZE; -} +extern struct loongarch_vdso_data _loongarch_data __attribute__((visibility("hidden"))); #endif /* __ASSEMBLY__ */ diff --git a/arch/loongarch/kernel/asm-offsets.c b/arch/loongarch/kernel/asm-offsets.c index bee9f7a3108f0..049c5c3e370cb 100644 --- a/arch/loongarch/kernel/asm-offsets.c +++ b/arch/loongarch/kernel/asm-offsets.c @@ -14,6 +14,7 @@ #include #include #include +#include static void __used output_ptreg_defines(void) { @@ -321,3 +322,11 @@ static void __used output_kvm_defines(void) OFFSET(KVM_GPGD, kvm, arch.pgd); BLANK(); } + +static void __used output_vdso_defines(void) +{ + COMMENT("LoongArch vDSO offsets."); + + DEFINE(__VVAR_PAGES, VVAR_NR_PAGES); + BLANK(); +} diff --git a/arch/loongarch/vdso/vdso.lds.S b/arch/loongarch/vdso/vdso.lds.S index 6b441bde4026e..160cfaef2de45 100644 --- a/arch/loongarch/vdso/vdso.lds.S +++ b/arch/loongarch/vdso/vdso.lds.S @@ -3,6 +3,8 @@ * Author: Huacai Chen * Copyright (C) 2020-2022 Loongson Technology Corporation Limited */ +#include +#include OUTPUT_FORMAT("elf64-loongarch", "elf64-loongarch", "elf64-loongarch") @@ -10,7 +12,11 @@ OUTPUT_ARCH(loongarch) SECTIONS { - PROVIDE(_start = .); + PROVIDE(_vdso_data = . - __VVAR_PAGES * PAGE_SIZE); +#ifdef CONFIG_TIME_NS + PROVIDE(_timens_data = _vdso_data + PAGE_SIZE); +#endif + PROVIDE(_loongarch_data = _vdso_data + 2 * PAGE_SIZE); . = SIZEOF_HEADERS; .hash : { *(.hash) } :text diff --git a/arch/loongarch/vdso/vgetcpu.c b/arch/loongarch/vdso/vgetcpu.c index 9e445be39763a..0db51258b2a7c 100644 --- a/arch/loongarch/vdso/vgetcpu.c +++ b/arch/loongarch/vdso/vgetcpu.c @@ -21,7 +21,7 @@ static __always_inline int read_cpu_id(void) static __always_inline const struct vdso_pcpu_data *get_pcpu_data(void) { - return (struct vdso_pcpu_data *)(get_vdso_data() + VVAR_LOONGARCH_PAGES_START * PAGE_SIZE); + return _loongarch_data.pdata; } extern From c9b5482d0e726826034fd6e2302d7458e685d2cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:11 +0200 Subject: [PATCH 22/42] MIPS: vdso: Avoid name conflict around "vdso_data" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The generic vdso/datapage.h declares a symbol named "vdso_data". Avoid a conflict by renaming the identically named variable in genvdso.c. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-9-b64f0842d512@linutronix.de --- arch/mips/vdso/genvdso.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/vdso/genvdso.c b/arch/mips/vdso/genvdso.c index 09e30eb4be860..d47412ea6e673 100644 --- a/arch/mips/vdso/genvdso.c +++ b/arch/mips/vdso/genvdso.c @@ -270,7 +270,7 @@ int main(int argc, char **argv) /* Write out the stripped VDSO data. */ fprintf(out_file, - "static unsigned char vdso_data[PAGE_ALIGN(%zu)] __page_aligned_data = {\n\t", + "static unsigned char vdso_image_data[PAGE_ALIGN(%zu)] __page_aligned_data = {\n\t", vdso_size); for (i = 0; i < vdso_size; i++) { if (!(i % 10)) @@ -286,7 +286,7 @@ int main(int argc, char **argv) fprintf(out_file, "struct mips_vdso_image vdso_image%s%s = {\n", (vdso_name[0]) ? "_" : "", vdso_name); - fprintf(out_file, "\t.data = vdso_data,\n"); + fprintf(out_file, "\t.data = vdso_image_data,\n"); fprintf(out_file, "\t.size = PAGE_ALIGN(%zu),\n", vdso_size); fprintf(out_file, "\t.mapping = {\n"); fprintf(out_file, "\t\t.name = \"[vdso]\",\n"); From f2182dc40a3133fb4308971d164b95d9c405101d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:12 +0200 Subject: [PATCH 23/42] x86/mm/mmap: Remove arch_vma_name() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function does not contain any logic, delete it so the equivalent weak definition from kernel/signal.c is used instead. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-10-b64f0842d512@linutronix.de --- arch/x86/mm/mmap.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c index a2cabb1c81e1a..b8a6ffffb4519 100644 --- a/arch/x86/mm/mmap.c +++ b/arch/x86/mm/mmap.c @@ -163,11 +163,6 @@ unsigned long get_mmap_base(int is_legacy) return is_legacy ? mm->mmap_legacy_base : mm->mmap_base; } -const char *arch_vma_name(struct vm_area_struct *vma) -{ - return NULL; -} - /** * mmap_address_hint_valid - Validate the address hint of mmap * @addr: Address hint From dd937454d905fad9fcbeccd35ecfc8c3c096fe76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:13 +0200 Subject: [PATCH 24/42] x86/vdso: Use __arch_get_vdso_data() to access vdso data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The implementation details of the vdso_data access will change. Prepare for that by using the existing helper function. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-11-b64f0842d512@linutronix.de --- arch/x86/include/asm/vdso/getrandom.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/vdso/getrandom.h b/arch/x86/include/asm/vdso/getrandom.h index ff5334ad32a0f..ecdcdbcd33925 100644 --- a/arch/x86/include/asm/vdso/getrandom.h +++ b/arch/x86/include/asm/vdso/getrandom.h @@ -32,8 +32,8 @@ static __always_inline ssize_t getrandom_syscall(void *buffer, size_t len, unsig static __always_inline const struct vdso_rng_data *__arch_get_vdso_rng_data(void) { - if (IS_ENABLED(CONFIG_TIME_NS) && __vdso_data->clock_mode == VDSO_CLOCKMODE_TIMENS) - return (void *)&__vdso_rng_data + ((void *)&__timens_vdso_data - (void *)&__vdso_data); + if (IS_ENABLED(CONFIG_TIME_NS) && __arch_get_vdso_data()->clock_mode == VDSO_CLOCKMODE_TIMENS) + return (void *)&__vdso_rng_data + ((void *)&__timens_vdso_data - (void *)__arch_get_vdso_data()); return &__vdso_rng_data; } From 9f8514cfcdf0d929e2d3d440c0d4991f16b7e53b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:14 +0200 Subject: [PATCH 25/42] x86/vdso: Place vdso_data at beginning of vvar page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The offset of the vdso_data only has historic reasons, as back then other vvars also existed and offset 0 was already used. (See commit 8c49d9a74bac ("x86-64: Clean up vdso/kernel shared variables")) Over time most other vvars got removed and offset 0 is free again. Moving vdso_data to the beginning of the vvar page aligns x86 with other architectures and opens up the way for the removal of the custom x86 vvar machinery. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-12-b64f0842d512@linutronix.de --- arch/x86/include/asm/vvar.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/vvar.h b/arch/x86/include/asm/vvar.h index 9d9af37f7cab9..01e60e0f671e9 100644 --- a/arch/x86/include/asm/vvar.h +++ b/arch/x86/include/asm/vvar.h @@ -58,7 +58,7 @@ extern char __vvar_page; /* DECLARE_VVAR(offset, type, name) */ -DECLARE_VVAR(128, struct vdso_data, _vdso_data) +DECLARE_VVAR(0, struct vdso_data, _vdso_data) #if !defined(_SINGLE_DATA) #define _SINGLE_DATA From 7821571be92f9c81f63d4639e652e85d258ce5f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:15 +0200 Subject: [PATCH 26/42] x86/vdso: Access rng data from kernel without vvar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the usage of the vvar _vdso_rng_data from the kernel-space code, as the x86 vvar machinery is about to be removed. The definition of the structure is unnecessary, as the data lives in a page pre-allocated by the linker anyways. The vdso user-space access to the rng data will be switched soon. DEFINE_VVAR_SINGLE() is now unused. It will be removed later togehter with the rest of vvar.h. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-13-b64f0842d512@linutronix.de --- arch/x86/entry/vdso/vma.c | 1 - arch/x86/include/asm/vdso/vsyscall.h | 2 +- arch/x86/include/asm/vvar.h | 4 +++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c index b8fed8b8b9ccd..8437906fd4b35 100644 --- a/arch/x86/entry/vdso/vma.c +++ b/arch/x86/entry/vdso/vma.c @@ -39,7 +39,6 @@ struct vdso_data *arch_get_vdso_data(void *vvar_page) #undef EMIT_VVAR DEFINE_VVAR(struct vdso_data, _vdso_data); -DEFINE_VVAR_SINGLE(struct vdso_rng_data, _vdso_rng_data); unsigned int vclocks_used __read_mostly; diff --git a/arch/x86/include/asm/vdso/vsyscall.h b/arch/x86/include/asm/vdso/vsyscall.h index a1f916b18400f..ce8d5c81ebf44 100644 --- a/arch/x86/include/asm/vdso/vsyscall.h +++ b/arch/x86/include/asm/vdso/vsyscall.h @@ -21,7 +21,7 @@ struct vdso_data *__x86_get_k_vdso_data(void) static __always_inline struct vdso_rng_data *__x86_get_k_vdso_rng_data(void) { - return &_vdso_rng_data; + return (void *)&__vvar_page + __VDSO_RND_DATA_OFFSET; } #define __arch_get_k_vdso_rng_data __x86_get_k_vdso_rng_data diff --git a/arch/x86/include/asm/vvar.h b/arch/x86/include/asm/vvar.h index 01e60e0f671e9..fe3434d3b5b1e 100644 --- a/arch/x86/include/asm/vvar.h +++ b/arch/x86/include/asm/vvar.h @@ -19,6 +19,8 @@ #ifndef _ASM_X86_VVAR_H #define _ASM_X86_VVAR_H +#define __VDSO_RND_DATA_OFFSET 640 + #ifdef EMIT_VVAR /* * EMIT_VVAR() is used by the kernel linker script to put vvars in the @@ -62,7 +64,7 @@ DECLARE_VVAR(0, struct vdso_data, _vdso_data) #if !defined(_SINGLE_DATA) #define _SINGLE_DATA -DECLARE_VVAR_SINGLE(640, struct vdso_rng_data, _vdso_rng_data) +DECLARE_VVAR_SINGLE(__VDSO_RND_DATA_OFFSET, struct vdso_rng_data, _vdso_rng_data) #endif #undef DECLARE_VVAR From 7175126a6d45fea82cb25f4d35b35a0999fd6dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:16 +0200 Subject: [PATCH 27/42] x86/vdso: Allocate vvar page from C code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allocate the vvar page through the standard union vdso_data_store and remove the custom linker script logic. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-14-b64f0842d512@linutronix.de --- arch/x86/entry/vdso/vma.c | 16 +++++----------- arch/x86/include/asm/vdso/vsyscall.h | 6 ++++-- arch/x86/kernel/vmlinux.lds.S | 23 ----------------------- arch/x86/tools/relocs.c | 1 - 4 files changed, 9 insertions(+), 37 deletions(-) diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c index 8437906fd4b35..5731dc35d1d2c 100644 --- a/arch/x86/entry/vdso/vma.c +++ b/arch/x86/entry/vdso/vma.c @@ -20,25 +20,19 @@ #include #include #include -#include #include #include #include #include #include -#undef _ASM_X86_VVAR_H -#define EMIT_VVAR(name, offset) \ - const size_t name ## _offset = offset; -#include - struct vdso_data *arch_get_vdso_data(void *vvar_page) { - return (struct vdso_data *)(vvar_page + _vdso_data_offset); + return (struct vdso_data *)vvar_page; } -#undef EMIT_VVAR -DEFINE_VVAR(struct vdso_data, _vdso_data); +static union vdso_data_store vdso_data_store __page_aligned_data; +struct vdso_data *vdso_data = vdso_data_store.data; unsigned int vclocks_used __read_mostly; @@ -153,7 +147,7 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm, if (sym_offset == image->sym_vvar_page) { struct page *timens_page = find_timens_vvar_page(vma); - pfn = __pa_symbol(&__vvar_page) >> PAGE_SHIFT; + pfn = __pa_symbol(vdso_data) >> PAGE_SHIFT; /* * If a task belongs to a time namespace then a namespace @@ -200,7 +194,7 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm, if (!timens_page) return VM_FAULT_SIGBUS; - pfn = __pa_symbol(&__vvar_page) >> PAGE_SHIFT; + pfn = __pa_symbol(vdso_data) >> PAGE_SHIFT; return vmf_insert_pfn(vma, vmf->address, pfn); } diff --git a/arch/x86/include/asm/vdso/vsyscall.h b/arch/x86/include/asm/vdso/vsyscall.h index ce8d5c81ebf44..aac7d2b7b9a8c 100644 --- a/arch/x86/include/asm/vdso/vsyscall.h +++ b/arch/x86/include/asm/vdso/vsyscall.h @@ -8,20 +8,22 @@ #include #include +extern struct vdso_data *vdso_data; + /* * Update the vDSO data page to keep in sync with kernel timekeeping. */ static __always_inline struct vdso_data *__x86_get_k_vdso_data(void) { - return _vdso_data; + return vdso_data; } #define __arch_get_k_vdso_data __x86_get_k_vdso_data static __always_inline struct vdso_rng_data *__x86_get_k_vdso_rng_data(void) { - return (void *)&__vvar_page + __VDSO_RND_DATA_OFFSET; + return (void *)vdso_data + __VDSO_RND_DATA_OFFSET; } #define __arch_get_k_vdso_rng_data __x86_get_k_vdso_rng_data diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 6726be89b7a66..e7e19842736a7 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -193,29 +193,6 @@ SECTIONS ORC_UNWIND_TABLE - . = ALIGN(PAGE_SIZE); - __vvar_page = .; - - .vvar : AT(ADDR(.vvar) - LOAD_OFFSET) { - /* work around gold bug 13023 */ - __vvar_beginning_hack = .; - - /* Place all vvars at the offsets in asm/vvar.h. */ -#define EMIT_VVAR(name, offset) \ - . = __vvar_beginning_hack + offset; \ - *(.vvar_ ## name) -#include -#undef EMIT_VVAR - - /* - * Pad the rest of the page with zeros. Otherwise the loader - * can leave garbage here. - */ - . = __vvar_beginning_hack + PAGE_SIZE; - } :data - - . = ALIGN(__vvar_page + PAGE_SIZE, PAGE_SIZE); - /* Init code and data - will be freed after init */ . = ALIGN(PAGE_SIZE); .init.begin : AT(ADDR(.init.begin) - LOAD_OFFSET) { diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c index c101bed619400..6afe2e5e91028 100644 --- a/arch/x86/tools/relocs.c +++ b/arch/x86/tools/relocs.c @@ -89,7 +89,6 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = { "init_per_cpu__.*|" "__end_rodata_hpage_align|" #endif - "__vvar_page|" "_end)$" }; From 59b7761638a3f299750c04f431f2b4e1bea9465c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:17 +0200 Subject: [PATCH 28/42] x86/vdso: Access timens vdso data without vvar.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The vdso_data is at the start of the timens page. Make use of this invariant to remove the usage of vvar.h. This also matches the logic for the pvclock and hvclock pages. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-15-b64f0842d512@linutronix.de --- arch/x86/entry/vdso/vdso-layout.lds.S | 6 ------ arch/x86/include/asm/vdso/getrandom.h | 2 +- arch/x86/include/asm/vdso/gettimeofday.h | 6 ++++-- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/arch/x86/entry/vdso/vdso-layout.lds.S b/arch/x86/entry/vdso/vdso-layout.lds.S index bafa73f09e928..51c0cc0119748 100644 --- a/arch/x86/entry/vdso/vdso-layout.lds.S +++ b/arch/x86/entry/vdso/vdso-layout.lds.S @@ -28,12 +28,6 @@ SECTIONS hvclock_page = vvar_start + 2 * PAGE_SIZE; timens_page = vvar_start + 3 * PAGE_SIZE; -#undef _ASM_X86_VVAR_H - /* Place all vvars in timens too at the offsets in asm/vvar.h. */ -#define EMIT_VVAR(name, offset) timens_ ## name = timens_page + offset; -#include -#undef EMIT_VVAR - . = SIZEOF_HEADERS; .hash : { *(.hash) } :text diff --git a/arch/x86/include/asm/vdso/getrandom.h b/arch/x86/include/asm/vdso/getrandom.h index ecdcdbcd33925..d0713c829254c 100644 --- a/arch/x86/include/asm/vdso/getrandom.h +++ b/arch/x86/include/asm/vdso/getrandom.h @@ -33,7 +33,7 @@ static __always_inline ssize_t getrandom_syscall(void *buffer, size_t len, unsig static __always_inline const struct vdso_rng_data *__arch_get_vdso_rng_data(void) { if (IS_ENABLED(CONFIG_TIME_NS) && __arch_get_vdso_data()->clock_mode == VDSO_CLOCKMODE_TIMENS) - return (void *)&__vdso_rng_data + ((void *)&__timens_vdso_data - (void *)__arch_get_vdso_data()); + return (void *)&__vdso_rng_data + ((void *)&timens_page - (void *)__arch_get_vdso_data()); return &__vdso_rng_data; } diff --git a/arch/x86/include/asm/vdso/gettimeofday.h b/arch/x86/include/asm/vdso/gettimeofday.h index b2d2df026f6e7..1e6116172a65c 100644 --- a/arch/x86/include/asm/vdso/gettimeofday.h +++ b/arch/x86/include/asm/vdso/gettimeofday.h @@ -21,7 +21,9 @@ #include #define __vdso_data (VVAR(_vdso_data)) -#define __timens_vdso_data (TIMENS(_vdso_data)) + +extern struct vdso_data timens_page + __attribute__((visibility("hidden"))); #define VDSO_HAS_TIME 1 @@ -61,7 +63,7 @@ extern struct ms_hyperv_tsc_page hvclock_page static __always_inline const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd) { - return __timens_vdso_data; + return &timens_page; } #endif From c3a190d425916e84bbda65873f9fc27ce4b82893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:18 +0200 Subject: [PATCH 29/42] x86/vdso: Access rng vdso data without vvar.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The vdso_rng_data is at a well-known offset in the vvar page. Make use of this invariant to remove the usage of vvar.h. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-16-b64f0842d512@linutronix.de --- arch/x86/entry/vdso/vdso-layout.lds.S | 2 ++ arch/x86/include/asm/vdso/getrandom.h | 8 ++++---- arch/x86/include/asm/vvar.h | 5 ----- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/arch/x86/entry/vdso/vdso-layout.lds.S b/arch/x86/entry/vdso/vdso-layout.lds.S index 51c0cc0119748..acce60732e541 100644 --- a/arch/x86/entry/vdso/vdso-layout.lds.S +++ b/arch/x86/entry/vdso/vdso-layout.lds.S @@ -24,6 +24,8 @@ SECTIONS #include #undef EMIT_VVAR + vdso_rng_data = vvar_page + __VDSO_RND_DATA_OFFSET; + pvclock_page = vvar_start + PAGE_SIZE; hvclock_page = vvar_start + 2 * PAGE_SIZE; timens_page = vvar_start + 3 * PAGE_SIZE; diff --git a/arch/x86/include/asm/vdso/getrandom.h b/arch/x86/include/asm/vdso/getrandom.h index d0713c829254c..2bf9c0e970c3e 100644 --- a/arch/x86/include/asm/vdso/getrandom.h +++ b/arch/x86/include/asm/vdso/getrandom.h @@ -8,7 +8,6 @@ #ifndef __ASSEMBLY__ #include -#include /** * getrandom_syscall - Invoke the getrandom() syscall. @@ -28,13 +27,14 @@ static __always_inline ssize_t getrandom_syscall(void *buffer, size_t len, unsig return ret; } -#define __vdso_rng_data (VVAR(_vdso_rng_data)) +extern struct vdso_rng_data vdso_rng_data + __attribute__((visibility("hidden"))); static __always_inline const struct vdso_rng_data *__arch_get_vdso_rng_data(void) { if (IS_ENABLED(CONFIG_TIME_NS) && __arch_get_vdso_data()->clock_mode == VDSO_CLOCKMODE_TIMENS) - return (void *)&__vdso_rng_data + ((void *)&timens_page - (void *)__arch_get_vdso_data()); - return &__vdso_rng_data; + return (void *)&vdso_rng_data + ((void *)&timens_page - (void *)__arch_get_vdso_data()); + return &vdso_rng_data; } #endif /* !__ASSEMBLY__ */ diff --git a/arch/x86/include/asm/vvar.h b/arch/x86/include/asm/vvar.h index fe3434d3b5b1e..b605914f4d434 100644 --- a/arch/x86/include/asm/vvar.h +++ b/arch/x86/include/asm/vvar.h @@ -62,11 +62,6 @@ extern char __vvar_page; DECLARE_VVAR(0, struct vdso_data, _vdso_data) -#if !defined(_SINGLE_DATA) -#define _SINGLE_DATA -DECLARE_VVAR_SINGLE(__VDSO_RND_DATA_OFFSET, struct vdso_rng_data, _vdso_rng_data) -#endif - #undef DECLARE_VVAR #undef DECLARE_VVAR_SINGLE From 75ceb49add376f3a37e96a278bdedc029afd0716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:19 +0200 Subject: [PATCH 30/42] x86/vdso: Move the rng offset to vsyscall.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit vvar.h will go away, so move the last useful bit into vsyscall.h. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-17-b64f0842d512@linutronix.de --- arch/x86/entry/vdso/vdso-layout.lds.S | 1 + arch/x86/include/asm/vdso/vsyscall.h | 3 ++- arch/x86/include/asm/vvar.h | 2 -- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/entry/vdso/vdso-layout.lds.S b/arch/x86/entry/vdso/vdso-layout.lds.S index acce60732e541..c7e194b6e47de 100644 --- a/arch/x86/entry/vdso/vdso-layout.lds.S +++ b/arch/x86/entry/vdso/vdso-layout.lds.S @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ #include +#include /* * Linker script for vDSO. This is an ELF shared object prelinked to diff --git a/arch/x86/include/asm/vdso/vsyscall.h b/arch/x86/include/asm/vdso/vsyscall.h index aac7d2b7b9a8c..6a933f0dacf18 100644 --- a/arch/x86/include/asm/vdso/vsyscall.h +++ b/arch/x86/include/asm/vdso/vsyscall.h @@ -2,11 +2,12 @@ #ifndef __ASM_VDSO_VSYSCALL_H #define __ASM_VDSO_VSYSCALL_H +#define __VDSO_RND_DATA_OFFSET 640 + #ifndef __ASSEMBLY__ #include #include -#include extern struct vdso_data *vdso_data; diff --git a/arch/x86/include/asm/vvar.h b/arch/x86/include/asm/vvar.h index b605914f4d434..d95cf92296ef6 100644 --- a/arch/x86/include/asm/vvar.h +++ b/arch/x86/include/asm/vvar.h @@ -19,8 +19,6 @@ #ifndef _ASM_X86_VVAR_H #define _ASM_X86_VVAR_H -#define __VDSO_RND_DATA_OFFSET 640 - #ifdef EMIT_VVAR /* * EMIT_VVAR() is used by the kernel linker script to put vvars in the From 7d4acbae2aca16eb269ade9078b7ebad729e27ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:20 +0200 Subject: [PATCH 31/42] x86/vdso: Access vdso data without vvar.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The vdso_data is at the start of the vvar page. Make use of this invariant to remove the usage of vvar.h. This also matches the logic for the timens data. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-18-b64f0842d512@linutronix.de --- arch/x86/entry/vdso/vdso-layout.lds.S | 5 ----- arch/x86/include/asm/vdso/gettimeofday.h | 6 +++--- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/arch/x86/entry/vdso/vdso-layout.lds.S b/arch/x86/entry/vdso/vdso-layout.lds.S index c7e194b6e47de..9e602c0615243 100644 --- a/arch/x86/entry/vdso/vdso-layout.lds.S +++ b/arch/x86/entry/vdso/vdso-layout.lds.S @@ -20,11 +20,6 @@ SECTIONS vvar_start = . - 4 * PAGE_SIZE; vvar_page = vvar_start; - /* Place all vvars at the offsets in asm/vvar.h. */ -#define EMIT_VVAR(name, offset) vvar_ ## name = vvar_page + offset; -#include -#undef EMIT_VVAR - vdso_rng_data = vvar_page + __VDSO_RND_DATA_OFFSET; pvclock_page = vvar_start + PAGE_SIZE; diff --git a/arch/x86/include/asm/vdso/gettimeofday.h b/arch/x86/include/asm/vdso/gettimeofday.h index 1e6116172a65c..375a34b0f3657 100644 --- a/arch/x86/include/asm/vdso/gettimeofday.h +++ b/arch/x86/include/asm/vdso/gettimeofday.h @@ -14,13 +14,13 @@ #include #include -#include #include #include #include #include -#define __vdso_data (VVAR(_vdso_data)) +extern struct vdso_data vvar_page + __attribute__((visibility("hidden"))); extern struct vdso_data timens_page __attribute__((visibility("hidden"))); @@ -277,7 +277,7 @@ static inline u64 __arch_get_hw_counter(s32 clock_mode, static __always_inline const struct vdso_data *__arch_get_vdso_data(void) { - return __vdso_data; + return &vvar_page; } static inline bool arch_vdso_clocksource_ok(const struct vdso_data *vd) From 05a6b8c190f00792d60243c89c7b487e2e50a8ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:21 +0200 Subject: [PATCH 32/42] x86/vdso: Delete vvar.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All users have been removed. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-19-b64f0842d512@linutronix.de --- arch/x86/include/asm/vvar.h | 66 ------------------------------------- 1 file changed, 66 deletions(-) delete mode 100644 arch/x86/include/asm/vvar.h diff --git a/arch/x86/include/asm/vvar.h b/arch/x86/include/asm/vvar.h deleted file mode 100644 index d95cf92296ef6..0000000000000 --- a/arch/x86/include/asm/vvar.h +++ /dev/null @@ -1,66 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * vvar.h: Shared vDSO/kernel variable declarations - * Copyright (c) 2011 Andy Lutomirski - * - * A handful of variables are accessible (read-only) from userspace - * code in the vsyscall page and the vdso. They are declared here. - * Some other file must define them with DEFINE_VVAR. - * - * In normal kernel code, they are used like any other variable. - * In user code, they are accessed through the VVAR macro. - * - * These variables live in a page of kernel data that has an extra RO - * mapping for userspace. Each variable needs a unique offset within - * that page; specify that offset with the DECLARE_VVAR macro. (If - * you mess up, the linker will catch it.) - */ - -#ifndef _ASM_X86_VVAR_H -#define _ASM_X86_VVAR_H - -#ifdef EMIT_VVAR -/* - * EMIT_VVAR() is used by the kernel linker script to put vvars in the - * right place. Also, it's used by kernel code to import offsets values. - */ -#define DECLARE_VVAR(offset, type, name) \ - EMIT_VVAR(name, offset) -#define DECLARE_VVAR_SINGLE(offset, type, name) \ - EMIT_VVAR(name, offset) - -#else - -extern char __vvar_page; - -#define DECLARE_VVAR(offset, type, name) \ - extern type vvar_ ## name[CS_BASES] \ - __attribute__((visibility("hidden"))); \ - extern type timens_ ## name[CS_BASES] \ - __attribute__((visibility("hidden"))); \ - -#define DECLARE_VVAR_SINGLE(offset, type, name) \ - extern type vvar_ ## name \ - __attribute__((visibility("hidden"))); \ - -#define VVAR(name) (vvar_ ## name) -#define TIMENS(name) (timens_ ## name) - -#define DEFINE_VVAR(type, name) \ - type name[CS_BASES] \ - __attribute__((section(".vvar_" #name), aligned(16))) __visible - -#define DEFINE_VVAR_SINGLE(type, name) \ - type name \ - __attribute__((section(".vvar_" #name), aligned(16))) __visible - -#endif - -/* DECLARE_VVAR(offset, type, name) */ - -DECLARE_VVAR(0, struct vdso_data, _vdso_data) - -#undef DECLARE_VVAR -#undef DECLARE_VVAR_SINGLE - -#endif From e93d2521b27f0439872dfa4e4b92a9be6d73496f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:22 +0200 Subject: [PATCH 33/42] x86/vdso: Split virtual clock pages into dedicated mapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The generic vdso data storage cannot handle the special pvclock and hvclock pages. Split them into their own mapping, so the other vdso storage can be migrated to the generic code. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-20-b64f0842d512@linutronix.de --- arch/x86/entry/vdso/vdso-layout.lds.S | 10 ++-- arch/x86/entry/vdso/vma.c | 70 ++++++++++++++++++++------- arch/x86/include/asm/vdso/vsyscall.h | 5 ++ 3 files changed, 64 insertions(+), 21 deletions(-) diff --git a/arch/x86/entry/vdso/vdso-layout.lds.S b/arch/x86/entry/vdso/vdso-layout.lds.S index 9e602c0615243..872947c1004c3 100644 --- a/arch/x86/entry/vdso/vdso-layout.lds.S +++ b/arch/x86/entry/vdso/vdso-layout.lds.S @@ -17,14 +17,16 @@ SECTIONS * segment. */ - vvar_start = . - 4 * PAGE_SIZE; + vvar_start = . - __VVAR_PAGES * PAGE_SIZE; vvar_page = vvar_start; vdso_rng_data = vvar_page + __VDSO_RND_DATA_OFFSET; - pvclock_page = vvar_start + PAGE_SIZE; - hvclock_page = vvar_start + 2 * PAGE_SIZE; - timens_page = vvar_start + 3 * PAGE_SIZE; + timens_page = vvar_start + PAGE_SIZE; + + vclock_pages = vvar_start + VDSO_NR_VCLOCK_PAGES * PAGE_SIZE; + pvclock_page = vclock_pages + VDSO_PAGE_PVCLOCK_OFFSET * PAGE_SIZE; + hvclock_page = vclock_pages + VDSO_PAGE_HVCLOCK_OFFSET * PAGE_SIZE; . = SIZEOF_HEADERS; diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c index 5731dc35d1d2c..7e5921adeed00 100644 --- a/arch/x86/entry/vdso/vma.c +++ b/arch/x86/entry/vdso/vma.c @@ -24,6 +24,7 @@ #include #include #include +#include #include struct vdso_data *arch_get_vdso_data(void *vvar_page) @@ -175,19 +176,7 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm, } return vmf_insert_pfn(vma, vmf->address, pfn); - } else if (sym_offset == image->sym_pvclock_page) { - struct pvclock_vsyscall_time_info *pvti = - pvclock_get_pvti_cpu0_va(); - if (pvti && vclock_was_used(VDSO_CLOCKMODE_PVCLOCK)) { - return vmf_insert_pfn_prot(vma, vmf->address, - __pa(pvti) >> PAGE_SHIFT, - pgprot_decrypted(vma->vm_page_prot)); - } - } else if (sym_offset == image->sym_hvclock_page) { - pfn = hv_get_tsc_pfn(); - if (pfn && vclock_was_used(VDSO_CLOCKMODE_HVCLOCK)) - return vmf_insert_pfn(vma, vmf->address, pfn); } else if (sym_offset == image->sym_timens_page) { struct page *timens_page = find_timens_vvar_page(vma); @@ -201,6 +190,33 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm, return VM_FAULT_SIGBUS; } +static vm_fault_t vvar_vclock_fault(const struct vm_special_mapping *sm, + struct vm_area_struct *vma, struct vm_fault *vmf) +{ + switch (vmf->pgoff) { +#ifdef CONFIG_PARAVIRT_CLOCK + case VDSO_PAGE_PVCLOCK_OFFSET: + struct pvclock_vsyscall_time_info *pvti = + pvclock_get_pvti_cpu0_va(); + if (pvti && vclock_was_used(VDSO_CLOCKMODE_PVCLOCK)) + return vmf_insert_pfn_prot(vma, vmf->address, + __pa(pvti) >> PAGE_SHIFT, + pgprot_decrypted(vma->vm_page_prot)); + break; +#endif /* CONFIG_PARAVIRT_CLOCK */ +#ifdef CONFIG_HYPERV_TIMER + case VDSO_PAGE_HVCLOCK_OFFSET: + unsigned long pfn = hv_get_tsc_pfn(); + + if (pfn && vclock_was_used(VDSO_CLOCKMODE_HVCLOCK)) + return vmf_insert_pfn(vma, vmf->address, pfn); + break; +#endif /* CONFIG_HYPERV_TIMER */ + } + + return VM_FAULT_SIGBUS; +} + static const struct vm_special_mapping vdso_mapping = { .name = "[vdso]", .fault = vdso_fault, @@ -210,6 +226,10 @@ static const struct vm_special_mapping vvar_mapping = { .name = "[vvar]", .fault = vvar_fault, }; +static const struct vm_special_mapping vvar_vclock_mapping = { + .name = "[vvar_vclock]", + .fault = vvar_vclock_fault, +}; /* * Add vdso and vvar mappings to current process. @@ -252,7 +272,7 @@ static int map_vdso(const struct vdso_image *image, unsigned long addr) vma = _install_special_mapping(mm, addr, - -image->sym_vvar_start, + (__VVAR_PAGES - VDSO_NR_VCLOCK_PAGES) * PAGE_SIZE, VM_READ|VM_MAYREAD|VM_IO|VM_DONTDUMP| VM_PFNMAP, &vvar_mapping); @@ -260,11 +280,26 @@ static int map_vdso(const struct vdso_image *image, unsigned long addr) if (IS_ERR(vma)) { ret = PTR_ERR(vma); do_munmap(mm, text_start, image->size, NULL); - } else { - current->mm->context.vdso = (void __user *)text_start; - current->mm->context.vdso_image = image; + goto up_fail; } + vma = _install_special_mapping(mm, + addr + (__VVAR_PAGES - VDSO_NR_VCLOCK_PAGES) * PAGE_SIZE, + VDSO_NR_VCLOCK_PAGES * PAGE_SIZE, + VM_READ|VM_MAYREAD|VM_IO|VM_DONTDUMP| + VM_PFNMAP, + &vvar_vclock_mapping); + + if (IS_ERR(vma)) { + ret = PTR_ERR(vma); + do_munmap(mm, text_start, image->size, NULL); + do_munmap(mm, addr, image->size, NULL); + goto up_fail; + } + + current->mm->context.vdso = (void __user *)text_start; + current->mm->context.vdso_image = image; + up_fail: mmap_write_unlock(mm); return ret; @@ -286,7 +321,8 @@ int map_vdso_once(const struct vdso_image *image, unsigned long addr) */ for_each_vma(vmi, vma) { if (vma_is_special_mapping(vma, &vdso_mapping) || - vma_is_special_mapping(vma, &vvar_mapping)) { + vma_is_special_mapping(vma, &vvar_mapping) || + vma_is_special_mapping(vma, &vvar_vclock_mapping)) { mmap_write_unlock(mm); return -EEXIST; } diff --git a/arch/x86/include/asm/vdso/vsyscall.h b/arch/x86/include/asm/vdso/vsyscall.h index 6a933f0dacf18..37b4a70559a82 100644 --- a/arch/x86/include/asm/vdso/vsyscall.h +++ b/arch/x86/include/asm/vdso/vsyscall.h @@ -3,6 +3,11 @@ #define __ASM_VDSO_VSYSCALL_H #define __VDSO_RND_DATA_OFFSET 640 +#define __VVAR_PAGES 4 + +#define VDSO_NR_VCLOCK_PAGES 2 +#define VDSO_PAGE_PVCLOCK_OFFSET 0 +#define VDSO_PAGE_HVCLOCK_OFFSET 1 #ifndef __ASSEMBLY__ From e449c83ac5b1d10cdde084e9d5da1902cde9e823 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:23 +0200 Subject: [PATCH 34/42] powerpc/vdso: Remove offset comment from 32bit vdso_arch_data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This offset was copy-pasted from the systemcfg structure. It has no meaning for the 32bit VDSO. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-21-b64f0842d512@linutronix.de --- arch/powerpc/include/asm/vdso_datapage.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h index 248dee138f7bf..3d5862d4c4e16 100644 --- a/arch/powerpc/include/asm/vdso_datapage.h +++ b/arch/powerpc/include/asm/vdso_datapage.h @@ -92,7 +92,7 @@ struct vdso_arch_data { * And here is the simpler 32 bits version */ struct vdso_arch_data { - __u64 tb_ticks_per_sec; /* Timebase tics / sec 0x38 */ + __u64 tb_ticks_per_sec; /* Timebase tics / sec */ __u32 syscall_map[SYSCALL_MAP_SIZE]; /* Map of syscalls */ __u32 compat_syscall_map[0]; /* No compat syscalls on PPC32 */ struct vdso_data data[CS_BASES]; From d4526a2d2d01e4dcb09c5535d3d4bb6ca763efeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:24 +0200 Subject: [PATCH 35/42] powerpc/procfs: Propagate error of remap_pfn_range() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the operation fails and userspace is unaware it will access unmapped memory, crashing the process. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-22-b64f0842d512@linutronix.de --- arch/powerpc/kernel/proc_powerpc.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/proc_powerpc.c b/arch/powerpc/kernel/proc_powerpc.c index b109cd7b5d01f..910d2082e05fd 100644 --- a/arch/powerpc/kernel/proc_powerpc.c +++ b/arch/powerpc/kernel/proc_powerpc.c @@ -33,10 +33,9 @@ static int page_map_mmap( struct file *file, struct vm_area_struct *vma ) if ((vma->vm_end - vma->vm_start) > PAGE_SIZE) return -EINVAL; - remap_pfn_range(vma, vma->vm_start, - __pa(pde_data(file_inode(file))) >> PAGE_SHIFT, - PAGE_SIZE, vma->vm_page_prot); - return 0; + return remap_pfn_range(vma, vma->vm_start, + __pa(pde_data(file_inode(file))) >> PAGE_SHIFT, + PAGE_SIZE, vma->vm_page_prot); } static const struct proc_ops page_map_proc_ops = { From af2c15920a114a7acea4dcbf9cd4a7b0ff469780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:25 +0200 Subject: [PATCH 36/42] powerpc/pseries/lparcfg: Fix printing of system_active_processors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When printing the information "system_active_processors", the variable partition_potential_processors is used instead of partition_active_processors. The wrong value is displayed. Use partition_active_processors instead. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-23-b64f0842d512@linutronix.de --- arch/powerpc/platforms/pseries/lparcfg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/pseries/lparcfg.c b/arch/powerpc/platforms/pseries/lparcfg.c index 62da20f9700a9..acc640fccca17 100644 --- a/arch/powerpc/platforms/pseries/lparcfg.c +++ b/arch/powerpc/platforms/pseries/lparcfg.c @@ -553,7 +553,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v) } else { /* non SPLPAR case */ seq_printf(m, "system_active_processors=%d\n", - partition_potential_processors); + partition_active_processors); seq_printf(m, "system_potential_processors=%d\n", partition_potential_processors); From e07359f171f2440f4dbc98339b10c8c3cdd48a20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:26 +0200 Subject: [PATCH 37/42] powerpc/pseries/lparcfg: Use num_possible_cpus() for potential processors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The systemcfg processorCount variable tracks currently online variables, not possible ones, so the stored value is wrong. The code preferably tries to use the ibm,lrdr-capacity field 4 which "represents the maximum number of processors that the guest can have." Switch from processorCount to the better matching num_possible_cpus(). Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-24-b64f0842d512@linutronix.de --- arch/powerpc/platforms/pseries/lparcfg.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/pseries/lparcfg.c b/arch/powerpc/platforms/pseries/lparcfg.c index acc640fccca17..cc22924f159f5 100644 --- a/arch/powerpc/platforms/pseries/lparcfg.c +++ b/arch/powerpc/platforms/pseries/lparcfg.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -530,7 +529,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v) lrdrp = of_get_property(rtas_node, "ibm,lrdr-capacity", NULL); if (lrdrp == NULL) { - partition_potential_processors = vdso_data->processorCount; + partition_potential_processors = num_possible_cpus(); } else { partition_potential_processors = be32_to_cpup(lrdrp + 4); } From c22c06b4cc3a7434f36dac9310604be3ebc6f4f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:27 +0200 Subject: [PATCH 38/42] powerpc: Add kconfig option for the systemcfg page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The systemcfg page through procfs is only a backwards-compatible interface for very old applications. Make it possible to be disabled. This also creates a convenient config #define to guard any accesses to the systemcfg page. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-25-b64f0842d512@linutronix.de --- arch/powerpc/Kconfig | 8 ++++++++ arch/powerpc/kernel/proc_powerpc.c | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 8094a01974cca..5d348e1f09d73 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -1298,6 +1298,14 @@ config MODULES_SIZE endmenu +config PPC64_PROC_SYSTEMCFG + def_bool y + depends on PPC64 && PROC_FS + help + This option enables the presence of /proc/ppc64/systemcfg through + which the systemcfg page can be accessed. + This interface only exists for backwards-compatibility. + if PPC64 # This value must have zeroes in the bottom 60 bits otherwise lots will break config PAGE_OFFSET diff --git a/arch/powerpc/kernel/proc_powerpc.c b/arch/powerpc/kernel/proc_powerpc.c index 910d2082e05fd..3bda365843e44 100644 --- a/arch/powerpc/kernel/proc_powerpc.c +++ b/arch/powerpc/kernel/proc_powerpc.c @@ -14,7 +14,7 @@ #include #include -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC64_PROC_SYSTEMCFG static loff_t page_map_seek(struct file *file, loff_t off, int whence) { @@ -59,7 +59,7 @@ static int __init proc_ppc64_init(void) } __initcall(proc_ppc64_init); -#endif /* CONFIG_PPC64 */ +#endif /* CONFIG_PPC64_PROC_SYSTEMCFG */ /* * Create the ppc64 and ppc64/rtas directories early. This allows us to From 1184674d6ef9368b9377213caad3aeb0d97ee1d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:28 +0200 Subject: [PATCH 39/42] powerpc: Split systemcfg data out of vdso data page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The systemcfg data only has minimal overlap with the vdso data. Splitting the two avoids mapping the implementation-defined vdso data into /proc/ppc64/systemcfg. It is also a preparation for the standardization of vdso data storage. The only field actually used by both systemcfg and vdso is tb_ticks_per_sec and it is only changed once during time_init(). Initialize it in both structures there. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-26-b64f0842d512@linutronix.de --- arch/powerpc/include/asm/vdso_datapage.h | 32 ++++---------------- arch/powerpc/kernel/proc_powerpc.c | 25 ++++++++++++++- arch/powerpc/kernel/setup-common.c | 4 ++- arch/powerpc/kernel/smp.c | 10 +++--- arch/powerpc/kernel/time.c | 3 ++ arch/powerpc/kernel/vdso.c | 20 ------------ arch/powerpc/platforms/powernv/smp.c | 4 ++- arch/powerpc/platforms/pseries/hotplug-cpu.c | 4 ++- 8 files changed, 48 insertions(+), 54 deletions(-) diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h index 3d5862d4c4e16..8b91b1d34ff63 100644 --- a/arch/powerpc/include/asm/vdso_datapage.h +++ b/arch/powerpc/include/asm/vdso_datapage.h @@ -10,21 +10,6 @@ */ -/* - * Note about this structure: - * - * This structure was historically called systemcfg and exposed to - * userland via /proc/ppc64/systemcfg. Unfortunately, this became an - * ABI issue as some proprietary software started relying on being able - * to mmap() it, thus we have to keep the base layout at least for a - * few kernel versions. - * - * However, since ppc32 doesn't suffer from this backward handicap, - * a simpler version of the data structure is used there with only the - * fields actually used by the vDSO. - * - */ - /* * If the major version changes we are incompatible. * Minor version changes are a hint. @@ -40,13 +25,9 @@ #define SYSCALL_MAP_SIZE ((NR_syscalls + 31) / 32) -/* - * So here is the ppc64 backward compatible version - */ - #ifdef CONFIG_PPC64 -struct vdso_arch_data { +struct systemcfg { __u8 eye_catcher[16]; /* Eyecatcher: SYSTEMCFG:PPC64 0x00 */ struct { /* Systemcfg version numbers */ __u32 major; /* Major number 0x10 */ @@ -71,10 +52,12 @@ struct vdso_arch_data { __u32 dcache_line_size; /* L1 d-cache line size 0x64 */ __u32 icache_size; /* L1 i-cache size 0x68 */ __u32 icache_line_size; /* L1 i-cache line size 0x6C */ +}; - /* those additional ones don't have to be located anywhere - * special as they were not part of the original systemcfg - */ +extern struct systemcfg *systemcfg; + +struct vdso_arch_data { + __u64 tb_ticks_per_sec; /* Timebase tics / sec */ __u32 dcache_block_size; /* L1 d-cache block size */ __u32 icache_block_size; /* L1 i-cache block size */ __u32 dcache_log_block_size; /* L1 d-cache log block size */ @@ -88,9 +71,6 @@ struct vdso_arch_data { #else /* CONFIG_PPC64 */ -/* - * And here is the simpler 32 bits version - */ struct vdso_arch_data { __u64 tb_ticks_per_sec; /* Timebase tics / sec */ __u32 syscall_map[SYSCALL_MAP_SIZE]; /* Map of syscalls */ diff --git a/arch/powerpc/kernel/proc_powerpc.c b/arch/powerpc/kernel/proc_powerpc.c index 3bda365843e44..e8083e05a1d03 100644 --- a/arch/powerpc/kernel/proc_powerpc.c +++ b/arch/powerpc/kernel/proc_powerpc.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -44,13 +45,35 @@ static const struct proc_ops page_map_proc_ops = { .proc_mmap = page_map_mmap, }; +static union { + struct systemcfg data; + u8 page[PAGE_SIZE]; +} systemcfg_data_store __page_aligned_data; +struct systemcfg *systemcfg = &systemcfg_data_store.data; static int __init proc_ppc64_init(void) { struct proc_dir_entry *pde; + strcpy((char *)systemcfg->eye_catcher, "SYSTEMCFG:PPC64"); + systemcfg->version.major = SYSTEMCFG_MAJOR; + systemcfg->version.minor = SYSTEMCFG_MINOR; + systemcfg->processor = mfspr(SPRN_PVR); + /* + * Fake the old platform number for pSeries and add + * in LPAR bit if necessary + */ + systemcfg->platform = 0x100; + if (firmware_has_feature(FW_FEATURE_LPAR)) + systemcfg->platform |= 1; + systemcfg->physicalMemorySize = memblock_phys_mem_size(); + systemcfg->dcache_size = ppc64_caches.l1d.size; + systemcfg->dcache_line_size = ppc64_caches.l1d.line_size; + systemcfg->icache_size = ppc64_caches.l1i.size; + systemcfg->icache_line_size = ppc64_caches.l1i.line_size; + pde = proc_create_data("powerpc/systemcfg", S_IFREG | 0444, NULL, - &page_map_proc_ops, vdso_data); + &page_map_proc_ops, systemcfg); if (!pde) return 1; proc_set_size(pde, PAGE_SIZE); diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 943430077375a..d0b32ff2bc8de 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -560,7 +560,9 @@ void __init smp_setup_cpu_maps(void) out: of_node_put(dn); } - vdso_data->processorCount = num_present_cpus(); +#endif +#ifdef CONFIG_PPC64_PROC_SYSTEMCFG + systemcfg->processorCount = num_present_cpus(); #endif /* CONFIG_PPC64 */ /* Initialize CPU <=> thread mapping/ diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 4ab9b8cee77a1..87ae45bf1045d 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -1186,8 +1186,8 @@ int generic_cpu_disable(void) return -EBUSY; set_cpu_online(cpu, false); -#ifdef CONFIG_PPC64 - vdso_data->processorCount--; +#ifdef CONFIG_PPC64_PROC_SYSTEMCFG + systemcfg->processorCount--; #endif /* Update affinity of all IRQs previously aimed at this CPU */ irq_migrate_all_off_this_cpu(); @@ -1642,10 +1642,12 @@ void start_secondary(void *unused) secondary_cpu_time_init(); -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC64_PROC_SYSTEMCFG if (system_state == SYSTEM_RUNNING) - vdso_data->processorCount++; + systemcfg->processorCount++; +#endif +#ifdef CONFIG_PPC64 vdso_getcpu_init(); #endif set_numa_node(numa_cpu_lookup_table[cpu]); diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 4a95654c1d36f..7d18eb83198b7 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -950,6 +950,9 @@ void __init time_init(void) } vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; +#ifdef CONFIG_PPC64_PROC_SYSTEMCFG + systemcfg->tb_ticks_per_sec = tb_ticks_per_sec; +#endif /* initialise and enable the large decrementer (if we have one) */ set_decrementer_max(); diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index ee4b9d676cff5..924f7f4fa597e 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -349,25 +348,6 @@ static struct page ** __init vdso_setup_pages(void *start, void *end) static int __init vdso_init(void) { #ifdef CONFIG_PPC64 - /* - * Fill up the "systemcfg" stuff for backward compatibility - */ - strcpy((char *)vdso_data->eye_catcher, "SYSTEMCFG:PPC64"); - vdso_data->version.major = SYSTEMCFG_MAJOR; - vdso_data->version.minor = SYSTEMCFG_MINOR; - vdso_data->processor = mfspr(SPRN_PVR); - /* - * Fake the old platform number for pSeries and add - * in LPAR bit if necessary - */ - vdso_data->platform = 0x100; - if (firmware_has_feature(FW_FEATURE_LPAR)) - vdso_data->platform |= 1; - vdso_data->physicalMemorySize = memblock_phys_mem_size(); - vdso_data->dcache_size = ppc64_caches.l1d.size; - vdso_data->dcache_line_size = ppc64_caches.l1d.line_size; - vdso_data->icache_size = ppc64_caches.l1i.size; - vdso_data->icache_line_size = ppc64_caches.l1i.line_size; vdso_data->dcache_block_size = ppc64_caches.l1d.block_size; vdso_data->icache_block_size = ppc64_caches.l1i.block_size; vdso_data->dcache_log_block_size = ppc64_caches.l1d.log_block_size; diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index 8f14f0581a21b..672209428b984 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c @@ -136,7 +136,9 @@ static int pnv_smp_cpu_disable(void) * the generic fixup_irqs. --BenH. */ set_cpu_online(cpu, false); - vdso_data->processorCount--; +#ifdef CONFIG_PPC64_PROC_SYSTEMCFG + systemcfg->processorCount--; +#endif if (cpu == boot_cpuid) boot_cpuid = cpumask_any(cpu_online_mask); if (xive_enabled()) diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 6838a0fcda296..7b80d35d045dc 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -83,7 +83,9 @@ static int pseries_cpu_disable(void) int cpu = smp_processor_id(); set_cpu_online(cpu, false); - vdso_data->processorCount--; +#ifdef CONFIG_PPC64_PROC_SYSTEMCFG + systemcfg->processorCount--; +#endif /*fix boot_cpuid here*/ if (cpu == boot_cpuid) From 6142be7ed7f3b0a8a0d6e7c2bb34598b4e7196a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 10 Oct 2024 09:01:29 +0200 Subject: [PATCH 40/42] powerpc: Split systemcfg struct definitions out from vdso MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The systemcfg data has nothing to do anymore with the vdso. Split it into a dedicated header file. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-27-b64f0842d512@linutronix.de --- arch/powerpc/include/asm/systemcfg.h | 52 ++++++++++++++++++++ arch/powerpc/include/asm/vdso_datapage.h | 37 -------------- arch/powerpc/kernel/proc_powerpc.c | 1 + arch/powerpc/kernel/setup-common.c | 1 + arch/powerpc/kernel/smp.c | 1 + arch/powerpc/kernel/time.c | 1 + arch/powerpc/platforms/powernv/smp.c | 1 + arch/powerpc/platforms/pseries/hotplug-cpu.c | 1 + 8 files changed, 58 insertions(+), 37 deletions(-) create mode 100644 arch/powerpc/include/asm/systemcfg.h diff --git a/arch/powerpc/include/asm/systemcfg.h b/arch/powerpc/include/asm/systemcfg.h new file mode 100644 index 0000000000000..2f9b1d6a5c98d --- /dev/null +++ b/arch/powerpc/include/asm/systemcfg.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _SYSTEMCFG_H +#define _SYSTEMCFG_H + +/* + * Copyright (C) 2002 Peter Bergner , IBM + * Copyright (C) 2005 Benjamin Herrenschmidy , + * IBM Corp. + */ + +#ifdef CONFIG_PPC64 + +/* + * If the major version changes we are incompatible. + * Minor version changes are a hint. + */ +#define SYSTEMCFG_MAJOR 1 +#define SYSTEMCFG_MINOR 1 + +#include + +struct systemcfg { + __u8 eye_catcher[16]; /* Eyecatcher: SYSTEMCFG:PPC64 0x00 */ + struct { /* Systemcfg version numbers */ + __u32 major; /* Major number 0x10 */ + __u32 minor; /* Minor number 0x14 */ + } version; + + /* Note about the platform flags: it now only contains the lpar + * bit. The actual platform number is dead and buried + */ + __u32 platform; /* Platform flags 0x18 */ + __u32 processor; /* Processor type 0x1C */ + __u64 processorCount; /* # of physical processors 0x20 */ + __u64 physicalMemorySize; /* Size of real memory(B) 0x28 */ + __u64 tb_orig_stamp; /* (NU) Timebase at boot 0x30 */ + __u64 tb_ticks_per_sec; /* Timebase tics / sec 0x38 */ + __u64 tb_to_xs; /* (NU) Inverse of TB to 2^20 0x40 */ + __u64 stamp_xsec; /* (NU) 0x48 */ + __u64 tb_update_count; /* (NU) Timebase atomicity ctr 0x50 */ + __u32 tz_minuteswest; /* (NU) Min. west of Greenwich 0x58 */ + __u32 tz_dsttime; /* (NU) Type of dst correction 0x5C */ + __u32 dcache_size; /* L1 d-cache size 0x60 */ + __u32 dcache_line_size; /* L1 d-cache line size 0x64 */ + __u32 icache_size; /* L1 i-cache size 0x68 */ + __u32 icache_line_size; /* L1 i-cache line size 0x6C */ +}; + +extern struct systemcfg *systemcfg; + +#endif /* CONFIG_PPC64 */ +#endif /* _SYSTEMCFG_H */ diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h index 8b91b1d34ff63..a9686310be2cb 100644 --- a/arch/powerpc/include/asm/vdso_datapage.h +++ b/arch/powerpc/include/asm/vdso_datapage.h @@ -9,14 +9,6 @@ * IBM Corp. */ - -/* - * If the major version changes we are incompatible. - * Minor version changes are a hint. - */ -#define SYSTEMCFG_MAJOR 1 -#define SYSTEMCFG_MINOR 1 - #ifndef __ASSEMBLY__ #include @@ -27,35 +19,6 @@ #ifdef CONFIG_PPC64 -struct systemcfg { - __u8 eye_catcher[16]; /* Eyecatcher: SYSTEMCFG:PPC64 0x00 */ - struct { /* Systemcfg version numbers */ - __u32 major; /* Major number 0x10 */ - __u32 minor; /* Minor number 0x14 */ - } version; - - /* Note about the platform flags: it now only contains the lpar - * bit. The actual platform number is dead and buried - */ - __u32 platform; /* Platform flags 0x18 */ - __u32 processor; /* Processor type 0x1C */ - __u64 processorCount; /* # of physical processors 0x20 */ - __u64 physicalMemorySize; /* Size of real memory(B) 0x28 */ - __u64 tb_orig_stamp; /* (NU) Timebase at boot 0x30 */ - __u64 tb_ticks_per_sec; /* Timebase tics / sec 0x38 */ - __u64 tb_to_xs; /* (NU) Inverse of TB to 2^20 0x40 */ - __u64 stamp_xsec; /* (NU) 0x48 */ - __u64 tb_update_count; /* (NU) Timebase atomicity ctr 0x50 */ - __u32 tz_minuteswest; /* (NU) Min. west of Greenwich 0x58 */ - __u32 tz_dsttime; /* (NU) Type of dst correction 0x5C */ - __u32 dcache_size; /* L1 d-cache size 0x60 */ - __u32 dcache_line_size; /* L1 d-cache line size 0x64 */ - __u32 icache_size; /* L1 i-cache size 0x68 */ - __u32 icache_line_size; /* L1 i-cache line size 0x6C */ -}; - -extern struct systemcfg *systemcfg; - struct vdso_arch_data { __u64 tb_ticks_per_sec; /* Timebase tics / sec */ __u32 dcache_block_size; /* L1 d-cache block size */ diff --git a/arch/powerpc/kernel/proc_powerpc.c b/arch/powerpc/kernel/proc_powerpc.c index e8083e05a1d03..3816a2bf2b844 100644 --- a/arch/powerpc/kernel/proc_powerpc.c +++ b/arch/powerpc/kernel/proc_powerpc.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #ifdef CONFIG_PPC64_PROC_SYSTEMCFG diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index d0b32ff2bc8de..0b732d3b283b1 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -67,6 +67,7 @@ #include #include #include +#include #include "setup.h" diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 87ae45bf1045d..5ac7084eebc0b 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -61,6 +61,7 @@ #include #include #include +#include #include diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 7d18eb83198b7..0727332ad86fb 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -71,6 +71,7 @@ #include #include #include +#include /* powerpc clocksource/clockevent code */ diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index 672209428b984..2e9da58195f51 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "powernv.h" diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 7b80d35d045dc..bc6926dbf1489 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "pseries.h" From a812eee0b68645e2916d4a4399280fe5471cac67 Mon Sep 17 00:00:00 2001 From: Nam Cao Date: Thu, 10 Oct 2024 09:01:30 +0200 Subject: [PATCH 41/42] vdso: Rename struct arch_vdso_data to arch_vdso_time_data The struct arch_vdso_data is only about vdso time data. So rename it to arch_vdso_time_data to make it obvious. Non time-related data will be migrated out of these structs soon. Signed-off-by: Nam Cao Signed-off-by: Thomas Gleixner Acked-by: Heiko Carstens # s390 Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-28-b64f0842d512@linutronix.de --- arch/Kconfig | 2 +- arch/riscv/Kconfig | 2 +- arch/riscv/include/asm/vdso/{data.h => time_data.h} | 8 ++++---- arch/riscv/kernel/sys_hwprobe.c | 2 +- arch/riscv/kernel/vdso/hwprobe.c | 4 ++-- arch/s390/Kconfig | 2 +- arch/s390/include/asm/vdso/data.h | 12 ------------ arch/s390/include/asm/vdso/time_data.h | 12 ++++++++++++ include/vdso/datapage.h | 8 ++++---- 9 files changed, 26 insertions(+), 26 deletions(-) rename arch/riscv/include/asm/vdso/{data.h => time_data.h} (71%) delete mode 100644 arch/s390/include/asm/vdso/data.h create mode 100644 arch/s390/include/asm/vdso/time_data.h diff --git a/arch/Kconfig b/arch/Kconfig index 8af374ea1adc2..7f1ec327b587c 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -1530,7 +1530,7 @@ config HAVE_SPARSE_SYSCALL_NR entries at 4000, 5000 and 6000 locations. This option turns on syscall related optimizations for a given architecture. -config ARCH_HAS_VDSO_DATA +config ARCH_HAS_VDSO_TIME_DATA bool config HAVE_STATIC_CALL diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 62545946ecf43..c278280c134f7 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -50,7 +50,7 @@ config RISCV select ARCH_HAS_SYSCALL_WRAPPER select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAS_UBSAN - select ARCH_HAS_VDSO_DATA + select ARCH_HAS_VDSO_TIME_DATA select ARCH_KEEP_MEMBLOCK if ACPI select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE if 64BIT && MMU select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX diff --git a/arch/riscv/include/asm/vdso/data.h b/arch/riscv/include/asm/vdso/time_data.h similarity index 71% rename from arch/riscv/include/asm/vdso/data.h rename to arch/riscv/include/asm/vdso/time_data.h index dc2f76f58b763..dfa65228999be 100644 --- a/arch/riscv/include/asm/vdso/data.h +++ b/arch/riscv/include/asm/vdso/time_data.h @@ -1,12 +1,12 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __RISCV_ASM_VDSO_DATA_H -#define __RISCV_ASM_VDSO_DATA_H +#ifndef __RISCV_ASM_VDSO_TIME_DATA_H +#define __RISCV_ASM_VDSO_TIME_DATA_H #include #include #include -struct arch_vdso_data { +struct arch_vdso_time_data { /* Stash static answers to the hwprobe queries when all CPUs are selected. */ __u64 all_cpu_hwprobe_values[RISCV_HWPROBE_MAX_KEY + 1]; @@ -14,4 +14,4 @@ struct arch_vdso_data { __u8 homogeneous_cpus; }; -#endif /* __RISCV_ASM_VDSO_DATA_H */ +#endif /* __RISCV_ASM_VDSO_TIME_DATA_H */ diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c index cea0ca2bf2a25..711a31f27c3d0 100644 --- a/arch/riscv/kernel/sys_hwprobe.c +++ b/arch/riscv/kernel/sys_hwprobe.c @@ -402,7 +402,7 @@ static int do_riscv_hwprobe(struct riscv_hwprobe __user *pairs, static int __init init_hwprobe_vdso_data(void) { struct vdso_data *vd = __arch_get_k_vdso_data(); - struct arch_vdso_data *avd = &vd->arch_data; + struct arch_vdso_time_data *avd = &vd->arch_data; u64 id_bitsmash = 0; struct riscv_hwprobe pair; int key; diff --git a/arch/riscv/kernel/vdso/hwprobe.c b/arch/riscv/kernel/vdso/hwprobe.c index 1e926e4b5881b..a158c029344f6 100644 --- a/arch/riscv/kernel/vdso/hwprobe.c +++ b/arch/riscv/kernel/vdso/hwprobe.c @@ -17,7 +17,7 @@ static int riscv_vdso_get_values(struct riscv_hwprobe *pairs, size_t pair_count, unsigned int flags) { const struct vdso_data *vd = __arch_get_vdso_data(); - const struct arch_vdso_data *avd = &vd->arch_data; + const struct arch_vdso_time_data *avd = &vd->arch_data; bool all_cpus = !cpusetsize && !cpus; struct riscv_hwprobe *p = pairs; struct riscv_hwprobe *end = pairs + pair_count; @@ -52,7 +52,7 @@ static int riscv_vdso_get_cpus(struct riscv_hwprobe *pairs, size_t pair_count, unsigned int flags) { const struct vdso_data *vd = __arch_get_vdso_data(); - const struct arch_vdso_data *avd = &vd->arch_data; + const struct arch_vdso_time_data *avd = &vd->arch_data; struct riscv_hwprobe *p = pairs; struct riscv_hwprobe *end = pairs + pair_count; unsigned char *c = (unsigned char *)cpus; diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index d339fe4fdedf8..8cdd8359e00c3 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -88,7 +88,7 @@ config S390 select ARCH_HAS_STRICT_MODULE_RWX select ARCH_HAS_SYSCALL_WRAPPER select ARCH_HAS_UBSAN - select ARCH_HAS_VDSO_DATA + select ARCH_HAS_VDSO_TIME_DATA select ARCH_HAVE_NMI_SAFE_CMPXCHG select ARCH_INLINE_READ_LOCK select ARCH_INLINE_READ_LOCK_BH diff --git a/arch/s390/include/asm/vdso/data.h b/arch/s390/include/asm/vdso/data.h deleted file mode 100644 index 0e2b40ef69b04..0000000000000 --- a/arch/s390/include/asm/vdso/data.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __S390_ASM_VDSO_DATA_H -#define __S390_ASM_VDSO_DATA_H - -#include - -struct arch_vdso_data { - __s64 tod_steering_delta; - __u64 tod_steering_end; -}; - -#endif /* __S390_ASM_VDSO_DATA_H */ diff --git a/arch/s390/include/asm/vdso/time_data.h b/arch/s390/include/asm/vdso/time_data.h new file mode 100644 index 0000000000000..8a08752422e60 --- /dev/null +++ b/arch/s390/include/asm/vdso/time_data.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __S390_ASM_VDSO_TIME_DATA_H +#define __S390_ASM_VDSO_TIME_DATA_H + +#include + +struct arch_vdso_time_data { + __s64 tod_steering_delta; + __u64 tod_steering_end; +}; + +#endif /* __S390_ASM_VDSO_TIME_DATA_H */ diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h index b85f24cac3f56..d967baa0cd0c6 100644 --- a/include/vdso/datapage.h +++ b/include/vdso/datapage.h @@ -19,10 +19,10 @@ #include #include -#ifdef CONFIG_ARCH_HAS_VDSO_DATA -#include +#ifdef CONFIG_ARCH_HAS_VDSO_TIME_DATA +#include #else -struct arch_vdso_data {}; +struct arch_vdso_time_data {}; #endif #define VDSO_BASES (CLOCK_TAI + 1) @@ -114,7 +114,7 @@ struct vdso_data { u32 hrtimer_res; u32 __unused; - struct arch_vdso_data arch_data; + struct arch_vdso_time_data arch_data; }; /** From 7fa3c36ea2707c495cf31ccab733ac8bf3f9d0c2 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 2 Nov 2024 22:11:24 +0100 Subject: [PATCH 42/42] x86/vdso: Add missing brackets in switch case 0-day reported: arch/x86/entry/vdso/vma.c:199:3: warning: label followed by a declaration is a C23 extension [-Wc23-extensions] Add the missing brackets. Fixes: e93d2521b27f ("x86/vdso: Split virtual clock pages into dedicated mapping") Reported-by: kernel test robot Signed-off-by: Thomas Gleixner Closes: https://lore.kernel.org/oe-kbuild-all/202411022359.fBPFTg2T-lkp@intel.com/ --- arch/x86/entry/vdso/vma.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c index 7e5921adeed00..bfc7cabf4017b 100644 --- a/arch/x86/entry/vdso/vma.c +++ b/arch/x86/entry/vdso/vma.c @@ -196,21 +196,26 @@ static vm_fault_t vvar_vclock_fault(const struct vm_special_mapping *sm, switch (vmf->pgoff) { #ifdef CONFIG_PARAVIRT_CLOCK case VDSO_PAGE_PVCLOCK_OFFSET: + { struct pvclock_vsyscall_time_info *pvti = pvclock_get_pvti_cpu0_va(); + if (pvti && vclock_was_used(VDSO_CLOCKMODE_PVCLOCK)) return vmf_insert_pfn_prot(vma, vmf->address, __pa(pvti) >> PAGE_SHIFT, pgprot_decrypted(vma->vm_page_prot)); break; + } #endif /* CONFIG_PARAVIRT_CLOCK */ #ifdef CONFIG_HYPERV_TIMER case VDSO_PAGE_HVCLOCK_OFFSET: + { unsigned long pfn = hv_get_tsc_pfn(); if (pfn && vclock_was_used(VDSO_CLOCKMODE_HVCLOCK)) return vmf_insert_pfn(vma, vmf->address, pfn); break; + } #endif /* CONFIG_HYPERV_TIMER */ }