* [PATCH v2 00/13] sparc64: vdso: Switch to generic vDSO library
@ 2025-08-15 10:41 Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 01/13] vdso: Add struct __kernel_old_timeval forward declaration to gettime.h Thomas Weißschuh
` (12 more replies)
0 siblings, 13 replies; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-15 10:41 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Andreas Larsson,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
John Paul Adrian Glaubitz
Cc: linux-kernel, sparclinux, Thomas Weißschuh, Arnd Bergmann
The generic vDSO provides a lot common functionality shared between
different architectures. SPARC is the last architecture not using it,
preventing some necessary code cleanup.
Make use of the generic infrastructure.
Follow-up to and replacement for Arnd's SPARC vDSO removal patches:
https://lore.kernel.org/lkml/20250707144726.4008707-1-arnd@kernel.org/
Only tested on QEMU.
This has a semantic conflict with my series "vdso: Reject absolute
relocations during build". The last patch of this series expects all users
of the generic vDSO library to use the vdsocheck tool.
This is not the case (yet) for SPARC64. I do have the patches for the
integration, the specifics will depend on which series is applied first.
[0] https://lore.kernel.org/lkml/20250812-vdso-absolute-reloc-v4-0-61a8b615e5ec@linutronix.de/
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
Changes in v2:
- Rebase on v6.17-rc1
- Drop RFC state
- Fix typo in commit message
- Drop duplicate 'select GENERIC_TIME_VSYSCALL'
- Merge "sparc64: time: Remove architecture-specific clocksource data" into the
main conversion patch. It violated the check in __clocksource_register_scale()
- Link to v1: https://lore.kernel.org/r/20250724-vdso-sparc64-generic-2-v1-0-e376a3bd24d1@linutronix.de
---
Arnd Bergmann (1):
clocksource: remove ARCH_CLOCKSOURCE_DATA
Thomas Weißschuh (12):
vdso: Add struct __kernel_old_timeval forward declaration to gettime.h
sparc64: vdso: Link with -z noexecstack
sparc64: vdso: Remove obsolete "fake section table" reservation
sparc64: vdso: Replace code patching with runtime conditional
sparc64: vdso: Move hardware counter read into header
sparc64: vdso: Move syscall fallbacks into header
sparc64: vdso: Introduce vdso/processor.h
sparc64: vdso: Switch to the generic vDSO library
sparc64: vdso2c: Drop sym_vvar_start handling
sparc64: vdso2c: Remove symbol handling
sparc64: vdso: Implement clock_gettime64()
sparc64: vdso: Implement clock_getres()
arch/sparc/Kconfig | 4 +-
arch/sparc/include/asm/clocksource.h | 9 -
arch/sparc/include/asm/processor.h | 3 +
arch/sparc/include/asm/processor_32.h | 2 -
arch/sparc/include/asm/processor_64.h | 25 --
arch/sparc/include/asm/vdso.h | 2 -
arch/sparc/include/asm/vdso/clocksource.h | 10 +
arch/sparc/include/asm/vdso/gettimeofday.h | 208 ++++++++++++++++
arch/sparc/include/asm/vdso/processor.h | 41 ++++
arch/sparc/include/asm/vdso/vsyscall.h | 10 +
arch/sparc/include/asm/vvar.h | 75 ------
arch/sparc/kernel/Makefile | 1 -
arch/sparc/kernel/time_64.c | 6 +-
arch/sparc/kernel/vdso.c | 69 ------
arch/sparc/vdso/Makefile | 8 +-
arch/sparc/vdso/vclock_gettime.c | 382 +++--------------------------
arch/sparc/vdso/vdso-layout.lds.S | 26 +-
arch/sparc/vdso/vdso.lds.S | 4 +-
arch/sparc/vdso/vdso2c.c | 24 --
arch/sparc/vdso/vdso2c.h | 45 +---
arch/sparc/vdso/vdso32/vdso32.lds.S | 6 +-
arch/sparc/vdso/vma.c | 274 ++-------------------
include/linux/clocksource.h | 6 +-
include/vdso/gettime.h | 1 +
kernel/time/Kconfig | 4 -
25 files changed, 343 insertions(+), 902 deletions(-)
---
base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585
change-id: 20250722-vdso-sparc64-generic-2-25f2e058e92c
Best regards,
--
Thomas Weißschuh <thomas.weissschuh@linutronix.de>
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH v2 01/13] vdso: Add struct __kernel_old_timeval forward declaration to gettime.h
2025-08-15 10:41 [PATCH v2 00/13] sparc64: vdso: Switch to generic vDSO library Thomas Weißschuh
@ 2025-08-15 10:41 ` Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 02/13] sparc64: vdso: Link with -z noexecstack Thomas Weißschuh
` (11 subsequent siblings)
12 siblings, 0 replies; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-15 10:41 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Andreas Larsson,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
John Paul Adrian Glaubitz
Cc: linux-kernel, sparclinux, Thomas Weißschuh
The prototype of __vdso_gettimeofday() uses this struct.
However gettime.h's own includes do not provide a definition for it.
Add a forward declaration, similar to other used structs.
Fixes: 42874e4eb35b ("arch: vdso: consolidate gettime prototypes")
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
include/vdso/gettime.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/vdso/gettime.h b/include/vdso/gettime.h
index c50d152e7b3e0670ea87cb51452c0a03b98403a0..9ac161866653a01c2a54702cb72fe5bda488ee2c 100644
--- a/include/vdso/gettime.h
+++ b/include/vdso/gettime.h
@@ -5,6 +5,7 @@
#include <linux/types.h>
struct __kernel_timespec;
+struct __kernel_old_timeval;
struct timezone;
#if !defined(CONFIG_64BIT) || defined(BUILD_VDSO32_64)
--
2.50.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v2 02/13] sparc64: vdso: Link with -z noexecstack
2025-08-15 10:41 [PATCH v2 00/13] sparc64: vdso: Switch to generic vDSO library Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 01/13] vdso: Add struct __kernel_old_timeval forward declaration to gettime.h Thomas Weißschuh
@ 2025-08-15 10:41 ` Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 03/13] sparc64: vdso: Remove obsolete "fake section table" reservation Thomas Weißschuh
` (10 subsequent siblings)
12 siblings, 0 replies; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-15 10:41 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Andreas Larsson,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
John Paul Adrian Glaubitz
Cc: linux-kernel, sparclinux, Thomas Weißschuh, Arnd Bergmann
The vDSO stack does not need to be executable. Prevent the linker from
creating executable. For more background see commit ffcf9c5700e4 ("x86:
link vdso and boot with -z noexecstack --no-warn-rwx-segments").
Also prevent the following warning from the linker:
sparc64-linux-ld: warning: arch/sparc/vdso/vdso-note.o: missing .note.GNU-stack section implies executable stack
sparc64-linux-ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker
Suggested-by: Arnd Bergmann <arnd@kernel.org>
Link: https://lore.kernel.org/lkml/20250707144726.4008707-1-arnd@kernel.org/
Fixes: 9a08862a5d2e ("vDSO for sparc")
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
arch/sparc/vdso/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/sparc/vdso/Makefile b/arch/sparc/vdso/Makefile
index 683b2d40822447849d1b4a8e3f85d35dcf9d727e..400529acd1c10e7f05fdb6c330593acc3c06b6f0 100644
--- a/arch/sparc/vdso/Makefile
+++ b/arch/sparc/vdso/Makefile
@@ -104,4 +104,4 @@ quiet_cmd_vdso = VDSO $@
$(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
-T $(filter %.lds,$^) $(filter %.o,$^)
-VDSO_LDFLAGS = -shared --hash-style=both --build-id=sha1 -Bsymbolic --no-undefined
+VDSO_LDFLAGS = -shared --hash-style=both --build-id=sha1 -Bsymbolic --no-undefined -z noexecstack
--
2.50.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v2 03/13] sparc64: vdso: Remove obsolete "fake section table" reservation
2025-08-15 10:41 [PATCH v2 00/13] sparc64: vdso: Switch to generic vDSO library Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 01/13] vdso: Add struct __kernel_old_timeval forward declaration to gettime.h Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 02/13] sparc64: vdso: Link with -z noexecstack Thomas Weißschuh
@ 2025-08-15 10:41 ` Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 04/13] sparc64: vdso: Replace code patching with runtime conditional Thomas Weißschuh
` (9 subsequent siblings)
12 siblings, 0 replies; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-15 10:41 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Andreas Larsson,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
John Paul Adrian Glaubitz
Cc: linux-kernel, sparclinux, Thomas Weißschuh
When the vDSO logic was copied from x86 to SPARC some unused remnants of
the fake section handling were copied, too. In x86 the original fake
section handling had already been removed incompletely in commit
da861e18eccc ("x86, vdso: Get rid of the fake section mechanism").
On x86 the reservation was only cleaned up in commit 24b7c77bbb24
("x86/vdso: Remove obsolete "fake section table" reservation").
Remove the reservation for SPARC, too.
Fixes: 9a08862a5d2e ("vDSO for sparc")
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
arch/sparc/vdso/vdso-layout.lds.S | 21 ---------------------
arch/sparc/vdso/vdso2c.c | 8 --------
2 files changed, 29 deletions(-)
diff --git a/arch/sparc/vdso/vdso-layout.lds.S b/arch/sparc/vdso/vdso-layout.lds.S
index d31e57e8a3bbffd3afb187cd631e2491fde64148..9e0804789d11696948f11be367480b530a1f18d9 100644
--- a/arch/sparc/vdso/vdso-layout.lds.S
+++ b/arch/sparc/vdso/vdso-layout.lds.S
@@ -4,16 +4,6 @@
* This script controls its layout.
*/
-#if defined(BUILD_VDSO64)
-# define SHDR_SIZE 64
-#elif defined(BUILD_VDSO32)
-# define SHDR_SIZE 40
-#else
-# error unknown VDSO target
-#endif
-
-#define NUM_FAKE_SHDRS 7
-
SECTIONS
{
/*
@@ -47,19 +37,8 @@ SECTIONS
*(.bss*)
*(.dynbss*)
*(.gnu.linkonce.b.*)
-
- /*
- * Ideally this would live in a C file: kept in here for
- * compatibility with x86-64.
- */
- VDSO_FAKE_SECTION_TABLE_START = .;
- . = . + NUM_FAKE_SHDRS * SHDR_SIZE;
- VDSO_FAKE_SECTION_TABLE_END = .;
} :text
- .fake_shstrtab : { *(.fake_shstrtab) } :text
-
-
.note : { *(.note.*) } :text :note
.eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
diff --git a/arch/sparc/vdso/vdso2c.c b/arch/sparc/vdso/vdso2c.c
index dc81240aab6fd31a72b8a751cc2a4a821a3c4e4e..b97af5ec9f35c01f2a976b6213b1768b677ad231 100644
--- a/arch/sparc/vdso/vdso2c.c
+++ b/arch/sparc/vdso/vdso2c.c
@@ -61,8 +61,6 @@ const char *outfilename;
/* Symbols that we need in vdso2c. */
enum {
sym_vvar_start,
- sym_VDSO_FAKE_SECTION_TABLE_START,
- sym_VDSO_FAKE_SECTION_TABLE_END,
};
struct vdso_sym {
@@ -72,12 +70,6 @@ struct vdso_sym {
struct vdso_sym required_syms[] = {
[sym_vvar_start] = {"vvar_start", 1},
- [sym_VDSO_FAKE_SECTION_TABLE_START] = {
- "VDSO_FAKE_SECTION_TABLE_START", 0
- },
- [sym_VDSO_FAKE_SECTION_TABLE_END] = {
- "VDSO_FAKE_SECTION_TABLE_END", 0
- },
};
__attribute__((format(printf, 1, 2))) __attribute__((noreturn))
--
2.50.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v2 04/13] sparc64: vdso: Replace code patching with runtime conditional
2025-08-15 10:41 [PATCH v2 00/13] sparc64: vdso: Switch to generic vDSO library Thomas Weißschuh
` (2 preceding siblings ...)
2025-08-15 10:41 ` [PATCH v2 03/13] sparc64: vdso: Remove obsolete "fake section table" reservation Thomas Weißschuh
@ 2025-08-15 10:41 ` Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 05/13] sparc64: vdso: Move hardware counter read into header Thomas Weißschuh
` (8 subsequent siblings)
12 siblings, 0 replies; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-15 10:41 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Andreas Larsson,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
John Paul Adrian Glaubitz
Cc: linux-kernel, sparclinux, Thomas Weißschuh
The patching logic is unnecessarily complicated and stands in the way of
the adoption of the generic vDSO framework.
Replace it by a simple runtime switch, similar to other architectures.
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/lkml/87ecu9tfhw.ffs@tglx/
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
arch/sparc/vdso/vclock_gettime.c | 112 +-------------------
arch/sparc/vdso/vdso.lds.S | 2 -
arch/sparc/vdso/vdso32/vdso32.lds.S | 2 -
arch/sparc/vdso/vma.c | 204 ------------------------------------
4 files changed, 4 insertions(+), 316 deletions(-)
diff --git a/arch/sparc/vdso/vclock_gettime.c b/arch/sparc/vdso/vclock_gettime.c
index 79607804ea1b0f321215a9c4b5ead1edeb912e64..643608bffe13d904c5f77edd585b2e58277491fb 100644
--- a/arch/sparc/vdso/vclock_gettime.c
+++ b/arch/sparc/vdso/vclock_gettime.c
@@ -148,17 +148,11 @@ notrace static __always_inline u64 vgetsns(struct vvar_data *vvar)
u64 v;
u64 cycles;
- cycles = vread_tick();
- v = (cycles - vvar->clock.cycle_last) & vvar->clock.mask;
- return v * vvar->clock.mult;
-}
-
-notrace static __always_inline u64 vgetsns_stick(struct vvar_data *vvar)
-{
- u64 v;
- u64 cycles;
+ if (likely(vvar->vclock_mode == VCLOCK_STICK))
+ cycles = vread_tick_stick();
+ else
+ cycles = vread_tick();
- cycles = vread_tick_stick();
v = (cycles - vvar->clock.cycle_last) & vvar->clock.mask;
return v * vvar->clock.mult;
}
@@ -183,26 +177,6 @@ notrace static __always_inline int do_realtime(struct vvar_data *vvar,
return 0;
}
-notrace static __always_inline int do_realtime_stick(struct vvar_data *vvar,
- struct __kernel_old_timespec *ts)
-{
- unsigned long seq;
- u64 ns;
-
- do {
- seq = vvar_read_begin(vvar);
- ts->tv_sec = vvar->wall_time_sec;
- ns = vvar->wall_time_snsec;
- ns += vgetsns_stick(vvar);
- ns = __shr64(ns, vvar->clock.shift);
- } while (unlikely(vvar_read_retry(vvar, seq)));
-
- ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
- ts->tv_nsec = ns;
-
- return 0;
-}
-
notrace static __always_inline int do_monotonic(struct vvar_data *vvar,
struct __kernel_old_timespec *ts)
{
@@ -223,26 +197,6 @@ notrace static __always_inline int do_monotonic(struct vvar_data *vvar,
return 0;
}
-notrace static __always_inline int do_monotonic_stick(struct vvar_data *vvar,
- struct __kernel_old_timespec *ts)
-{
- unsigned long seq;
- u64 ns;
-
- do {
- seq = vvar_read_begin(vvar);
- ts->tv_sec = vvar->monotonic_time_sec;
- ns = vvar->monotonic_time_snsec;
- ns += vgetsns_stick(vvar);
- ns = __shr64(ns, vvar->clock.shift);
- } while (unlikely(vvar_read_retry(vvar, seq)));
-
- ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
- ts->tv_nsec = ns;
-
- return 0;
-}
-
notrace static int do_realtime_coarse(struct vvar_data *vvar,
struct __kernel_old_timespec *ts)
{
@@ -298,31 +252,6 @@ int
clock_gettime(clockid_t, struct __kernel_old_timespec *)
__attribute__((weak, alias("__vdso_clock_gettime")));
-notrace int
-__vdso_clock_gettime_stick(clockid_t clock, struct __kernel_old_timespec *ts)
-{
- struct vvar_data *vvd = get_vvar_data();
-
- switch (clock) {
- case CLOCK_REALTIME:
- if (unlikely(vvd->vclock_mode == VCLOCK_NONE))
- break;
- return do_realtime_stick(vvd, ts);
- case CLOCK_MONOTONIC:
- if (unlikely(vvd->vclock_mode == VCLOCK_NONE))
- break;
- return do_monotonic_stick(vvd, ts);
- case CLOCK_REALTIME_COARSE:
- return do_realtime_coarse(vvd, ts);
- case CLOCK_MONOTONIC_COARSE:
- return do_monotonic_coarse(vvd, ts);
- }
- /*
- * Unknown clock ID ? Fall back to the syscall.
- */
- return vdso_fallback_gettime(clock, ts);
-}
-
notrace int
__vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
{
@@ -358,36 +287,3 @@ __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
int
gettimeofday(struct __kernel_old_timeval *, struct timezone *)
__attribute__((weak, alias("__vdso_gettimeofday")));
-
-notrace int
-__vdso_gettimeofday_stick(struct __kernel_old_timeval *tv, struct timezone *tz)
-{
- struct vvar_data *vvd = get_vvar_data();
-
- if (likely(vvd->vclock_mode != VCLOCK_NONE)) {
- if (likely(tv != NULL)) {
- union tstv_t {
- struct __kernel_old_timespec ts;
- struct __kernel_old_timeval tv;
- } *tstv = (union tstv_t *) tv;
- do_realtime_stick(vvd, &tstv->ts);
- /*
- * Assign before dividing to ensure that the division is
- * done in the type of tv_usec, not tv_nsec.
- *
- * There cannot be > 1 billion usec in a second:
- * do_realtime() has already distributed such overflow
- * into tv_sec. So we can assign it to an int safely.
- */
- tstv->tv.tv_usec = tstv->ts.tv_nsec;
- tstv->tv.tv_usec /= 1000;
- }
- if (unlikely(tz != NULL)) {
- /* Avoid memcpy. Some old compilers fail to inline it */
- tz->tz_minuteswest = vvd->tz_minuteswest;
- tz->tz_dsttime = vvd->tz_dsttime;
- }
- return 0;
- }
- return vdso_fallback_gettimeofday(tv, tz);
-}
diff --git a/arch/sparc/vdso/vdso.lds.S b/arch/sparc/vdso/vdso.lds.S
index 629ab6900df7156fc18b450dc3bbfba1bbd20e65..f3caa29a331c58175b67ea60d7ac15cd467fe5ff 100644
--- a/arch/sparc/vdso/vdso.lds.S
+++ b/arch/sparc/vdso/vdso.lds.S
@@ -18,10 +18,8 @@ VERSION {
global:
clock_gettime;
__vdso_clock_gettime;
- __vdso_clock_gettime_stick;
gettimeofday;
__vdso_gettimeofday;
- __vdso_gettimeofday_stick;
local: *;
};
}
diff --git a/arch/sparc/vdso/vdso32/vdso32.lds.S b/arch/sparc/vdso/vdso32/vdso32.lds.S
index 218930fdff03d598d74a991657c109c3b15ce752..53575ee154c492f9503efdd8f995ac2a035203c7 100644
--- a/arch/sparc/vdso/vdso32/vdso32.lds.S
+++ b/arch/sparc/vdso/vdso32/vdso32.lds.S
@@ -17,10 +17,8 @@ VERSION {
global:
clock_gettime;
__vdso_clock_gettime;
- __vdso_clock_gettime_stick;
gettimeofday;
__vdso_gettimeofday;
- __vdso_gettimeofday_stick;
local: *;
};
}
diff --git a/arch/sparc/vdso/vma.c b/arch/sparc/vdso/vma.c
index bab7a59575e882d911c5d1b0903f45cec353aef0..582d84e2e5ba8932f39948bb0ca2678fc8f06a10 100644
--- a/arch/sparc/vdso/vma.c
+++ b/arch/sparc/vdso/vma.c
@@ -42,203 +42,6 @@ static struct vm_special_mapping vdso_mapping32 = {
struct vvar_data *vvar_data;
-struct vdso_elfinfo32 {
- Elf32_Ehdr *hdr;
- Elf32_Sym *dynsym;
- unsigned long dynsymsize;
- const char *dynstr;
- unsigned long text;
-};
-
-struct vdso_elfinfo64 {
- Elf64_Ehdr *hdr;
- Elf64_Sym *dynsym;
- unsigned long dynsymsize;
- const char *dynstr;
- unsigned long text;
-};
-
-struct vdso_elfinfo {
- union {
- struct vdso_elfinfo32 elf32;
- struct vdso_elfinfo64 elf64;
- } u;
-};
-
-static void *one_section64(struct vdso_elfinfo64 *e, const char *name,
- unsigned long *size)
-{
- const char *snames;
- Elf64_Shdr *shdrs;
- unsigned int i;
-
- shdrs = (void *)e->hdr + e->hdr->e_shoff;
- snames = (void *)e->hdr + shdrs[e->hdr->e_shstrndx].sh_offset;
- for (i = 1; i < e->hdr->e_shnum; i++) {
- if (!strcmp(snames+shdrs[i].sh_name, name)) {
- if (size)
- *size = shdrs[i].sh_size;
- return (void *)e->hdr + shdrs[i].sh_offset;
- }
- }
- return NULL;
-}
-
-static int find_sections64(const struct vdso_image *image, struct vdso_elfinfo *_e)
-{
- struct vdso_elfinfo64 *e = &_e->u.elf64;
-
- e->hdr = image->data;
- e->dynsym = one_section64(e, ".dynsym", &e->dynsymsize);
- e->dynstr = one_section64(e, ".dynstr", NULL);
-
- if (!e->dynsym || !e->dynstr) {
- pr_err("VDSO64: Missing symbol sections.\n");
- return -ENODEV;
- }
- return 0;
-}
-
-static Elf64_Sym *find_sym64(const struct vdso_elfinfo64 *e, const char *name)
-{
- unsigned int i;
-
- for (i = 0; i < (e->dynsymsize / sizeof(Elf64_Sym)); i++) {
- Elf64_Sym *s = &e->dynsym[i];
- if (s->st_name == 0)
- continue;
- if (!strcmp(e->dynstr + s->st_name, name))
- return s;
- }
- return NULL;
-}
-
-static int patchsym64(struct vdso_elfinfo *_e, const char *orig,
- const char *new)
-{
- struct vdso_elfinfo64 *e = &_e->u.elf64;
- Elf64_Sym *osym = find_sym64(e, orig);
- Elf64_Sym *nsym = find_sym64(e, new);
-
- if (!nsym || !osym) {
- pr_err("VDSO64: Missing symbols.\n");
- return -ENODEV;
- }
- osym->st_value = nsym->st_value;
- osym->st_size = nsym->st_size;
- osym->st_info = nsym->st_info;
- osym->st_other = nsym->st_other;
- osym->st_shndx = nsym->st_shndx;
-
- return 0;
-}
-
-static void *one_section32(struct vdso_elfinfo32 *e, const char *name,
- unsigned long *size)
-{
- const char *snames;
- Elf32_Shdr *shdrs;
- unsigned int i;
-
- shdrs = (void *)e->hdr + e->hdr->e_shoff;
- snames = (void *)e->hdr + shdrs[e->hdr->e_shstrndx].sh_offset;
- for (i = 1; i < e->hdr->e_shnum; i++) {
- if (!strcmp(snames+shdrs[i].sh_name, name)) {
- if (size)
- *size = shdrs[i].sh_size;
- return (void *)e->hdr + shdrs[i].sh_offset;
- }
- }
- return NULL;
-}
-
-static int find_sections32(const struct vdso_image *image, struct vdso_elfinfo *_e)
-{
- struct vdso_elfinfo32 *e = &_e->u.elf32;
-
- e->hdr = image->data;
- e->dynsym = one_section32(e, ".dynsym", &e->dynsymsize);
- e->dynstr = one_section32(e, ".dynstr", NULL);
-
- if (!e->dynsym || !e->dynstr) {
- pr_err("VDSO32: Missing symbol sections.\n");
- return -ENODEV;
- }
- return 0;
-}
-
-static Elf32_Sym *find_sym32(const struct vdso_elfinfo32 *e, const char *name)
-{
- unsigned int i;
-
- for (i = 0; i < (e->dynsymsize / sizeof(Elf32_Sym)); i++) {
- Elf32_Sym *s = &e->dynsym[i];
- if (s->st_name == 0)
- continue;
- if (!strcmp(e->dynstr + s->st_name, name))
- return s;
- }
- return NULL;
-}
-
-static int patchsym32(struct vdso_elfinfo *_e, const char *orig,
- const char *new)
-{
- struct vdso_elfinfo32 *e = &_e->u.elf32;
- Elf32_Sym *osym = find_sym32(e, orig);
- Elf32_Sym *nsym = find_sym32(e, new);
-
- if (!nsym || !osym) {
- pr_err("VDSO32: Missing symbols.\n");
- return -ENODEV;
- }
- osym->st_value = nsym->st_value;
- osym->st_size = nsym->st_size;
- osym->st_info = nsym->st_info;
- osym->st_other = nsym->st_other;
- osym->st_shndx = nsym->st_shndx;
-
- return 0;
-}
-
-static int find_sections(const struct vdso_image *image, struct vdso_elfinfo *e,
- bool elf64)
-{
- if (elf64)
- return find_sections64(image, e);
- else
- return find_sections32(image, e);
-}
-
-static int patch_one_symbol(struct vdso_elfinfo *e, const char *orig,
- const char *new_target, bool elf64)
-{
- if (elf64)
- return patchsym64(e, orig, new_target);
- else
- return patchsym32(e, orig, new_target);
-}
-
-static int stick_patch(const struct vdso_image *image, struct vdso_elfinfo *e, bool elf64)
-{
- int err;
-
- err = find_sections(image, e, elf64);
- if (err)
- return err;
-
- err = patch_one_symbol(e,
- "__vdso_gettimeofday",
- "__vdso_gettimeofday_stick", elf64);
- if (err)
- return err;
-
- return patch_one_symbol(e,
- "__vdso_clock_gettime",
- "__vdso_clock_gettime_stick", elf64);
- return 0;
-}
-
/*
* Allocate pages for the vdso and vvar, and copy in the vdso text from the
* kernel image.
@@ -250,15 +53,8 @@ static int __init init_vdso_image(const struct vdso_image *image,
int cnpages = (image->size) / PAGE_SIZE;
struct page *dp, **dpp = NULL;
struct page *cp, **cpp = NULL;
- struct vdso_elfinfo ei;
int i, dnpages = 0;
- if (tlb_type != spitfire) {
- int err = stick_patch(image, &ei, elf64);
- if (err)
- return err;
- }
-
/*
* First, the vdso text. This is initialied data, an integral number of
* pages long.
--
2.50.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v2 05/13] sparc64: vdso: Move hardware counter read into header
2025-08-15 10:41 [PATCH v2 00/13] sparc64: vdso: Switch to generic vDSO library Thomas Weißschuh
` (3 preceding siblings ...)
2025-08-15 10:41 ` [PATCH v2 04/13] sparc64: vdso: Replace code patching with runtime conditional Thomas Weißschuh
@ 2025-08-15 10:41 ` Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 06/13] sparc64: vdso: Move syscall fallbacks " Thomas Weißschuh
` (7 subsequent siblings)
12 siblings, 0 replies; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-15 10:41 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Andreas Larsson,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
John Paul Adrian Glaubitz
Cc: linux-kernel, sparclinux, Thomas Weißschuh
The generic vDSO libraries expected the architecture glue around hardware
counter reading in asm/vdso/gettimeofday.h. To prepare the adoption of the
generic library, move the existing functions there.
While at it, perform some trivial alignment with the generic vDSO library:
* Drop 'notrace', as the functions are __always_inline anyways
* Use the same parameter types
* Use the same function names
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
arch/sparc/include/asm/vdso/gettimeofday.h | 78 ++++++++++++++++++++++++++++++
arch/sparc/vdso/vclock_gettime.c | 70 ++-------------------------
2 files changed, 82 insertions(+), 66 deletions(-)
diff --git a/arch/sparc/include/asm/vdso/gettimeofday.h b/arch/sparc/include/asm/vdso/gettimeofday.h
new file mode 100644
index 0000000000000000000000000000000000000000..31f6505d3ab5dde9e02eca6da9182e5fb91031c4
--- /dev/null
+++ b/arch/sparc/include/asm/vdso/gettimeofday.h
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2006 Andi Kleen, SUSE Labs.
+ */
+
+#ifndef _ASM_SPARC_VDSO_GETTIMEOFDAY_H
+#define _ASM_SPARC_VDSO_GETTIMEOFDAY_H
+
+#include <linux/types.h>
+#include <asm/vvar.h>
+
+#ifdef CONFIG_SPARC64
+static __always_inline u64 vdso_shift_ns(u64 val, u32 amt)
+{
+ return val >> amt;
+}
+
+static __always_inline u64 vread_tick(void)
+{
+ u64 ret;
+
+ __asm__ __volatile__("rd %%tick, %0" : "=r" (ret));
+ return ret;
+}
+
+static __always_inline u64 vread_tick_stick(void)
+{
+ u64 ret;
+
+ __asm__ __volatile__("rd %%asr24, %0" : "=r" (ret));
+ return ret;
+}
+#else
+static __always_inline u64 vdso_shift_ns(u64 val, u32 amt)
+{
+ u64 ret;
+
+ __asm__ __volatile__("sllx %H1, 32, %%g1\n\t"
+ "srl %L1, 0, %L1\n\t"
+ "or %%g1, %L1, %%g1\n\t"
+ "srlx %%g1, %2, %L0\n\t"
+ "srlx %L0, 32, %H0"
+ : "=r" (ret)
+ : "r" (val), "r" (amt)
+ : "g1");
+ return ret;
+}
+
+static __always_inline u64 vread_tick(void)
+{
+ register unsigned long long ret asm("o4");
+
+ __asm__ __volatile__("rd %%tick, %L0\n\t"
+ "srlx %L0, 32, %H0"
+ : "=r" (ret));
+ return ret;
+}
+
+static __always_inline u64 vread_tick_stick(void)
+{
+ register unsigned long long ret asm("o4");
+
+ __asm__ __volatile__("rd %%asr24, %L0\n\t"
+ "srlx %L0, 32, %H0"
+ : "=r" (ret));
+ return ret;
+}
+#endif
+
+static __always_inline u64 __arch_get_hw_counter(struct vvar_data *vvar)
+{
+ if (likely(vvar->vclock_mode == VCLOCK_STICK))
+ return vread_tick_stick();
+ else
+ return vread_tick();
+}
+
+#endif /* _ASM_SPARC_VDSO_GETTIMEOFDAY_H */
diff --git a/arch/sparc/vdso/vclock_gettime.c b/arch/sparc/vdso/vclock_gettime.c
index 643608bffe13d904c5f77edd585b2e58277491fb..16ac80982a00b9f965453b89a0cc111312baa9b2 100644
--- a/arch/sparc/vdso/vclock_gettime.c
+++ b/arch/sparc/vdso/vclock_gettime.c
@@ -19,6 +19,7 @@
#include <asm/unistd.h>
#include <asm/timex.h>
#include <asm/clocksource.h>
+#include <asm/vdso/gettimeofday.h>
#include <asm/vvar.h>
#ifdef CONFIG_SPARC64
@@ -85,73 +86,10 @@ notrace static long vdso_fallback_gettimeofday(struct __kernel_old_timeval *tv,
return o0;
}
-#ifdef CONFIG_SPARC64
-notrace static __always_inline u64 __shr64(u64 val, int amt)
-{
- return val >> amt;
-}
-
-notrace static __always_inline u64 vread_tick(void)
-{
- u64 ret;
-
- __asm__ __volatile__("rd %%tick, %0" : "=r" (ret));
- return ret;
-}
-
-notrace static __always_inline u64 vread_tick_stick(void)
-{
- u64 ret;
-
- __asm__ __volatile__("rd %%asr24, %0" : "=r" (ret));
- return ret;
-}
-#else
-notrace static __always_inline u64 __shr64(u64 val, int amt)
-{
- u64 ret;
-
- __asm__ __volatile__("sllx %H1, 32, %%g1\n\t"
- "srl %L1, 0, %L1\n\t"
- "or %%g1, %L1, %%g1\n\t"
- "srlx %%g1, %2, %L0\n\t"
- "srlx %L0, 32, %H0"
- : "=r" (ret)
- : "r" (val), "r" (amt)
- : "g1");
- return ret;
-}
-
-notrace static __always_inline u64 vread_tick(void)
-{
- register unsigned long long ret asm("o4");
-
- __asm__ __volatile__("rd %%tick, %L0\n\t"
- "srlx %L0, 32, %H0"
- : "=r" (ret));
- return ret;
-}
-
-notrace static __always_inline u64 vread_tick_stick(void)
-{
- register unsigned long long ret asm("o4");
-
- __asm__ __volatile__("rd %%asr24, %L0\n\t"
- "srlx %L0, 32, %H0"
- : "=r" (ret));
- return ret;
-}
-#endif
-
notrace static __always_inline u64 vgetsns(struct vvar_data *vvar)
{
u64 v;
- u64 cycles;
-
- if (likely(vvar->vclock_mode == VCLOCK_STICK))
- cycles = vread_tick_stick();
- else
- cycles = vread_tick();
+ u64 cycles = __arch_get_hw_counter(vvar);
v = (cycles - vvar->clock.cycle_last) & vvar->clock.mask;
return v * vvar->clock.mult;
@@ -168,7 +106,7 @@ notrace static __always_inline int do_realtime(struct vvar_data *vvar,
ts->tv_sec = vvar->wall_time_sec;
ns = vvar->wall_time_snsec;
ns += vgetsns(vvar);
- ns = __shr64(ns, vvar->clock.shift);
+ ns = vdso_shift_ns(ns, vvar->clock.shift);
} while (unlikely(vvar_read_retry(vvar, seq)));
ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
@@ -188,7 +126,7 @@ notrace static __always_inline int do_monotonic(struct vvar_data *vvar,
ts->tv_sec = vvar->monotonic_time_sec;
ns = vvar->monotonic_time_snsec;
ns += vgetsns(vvar);
- ns = __shr64(ns, vvar->clock.shift);
+ ns = vdso_shift_ns(ns, vvar->clock.shift);
} while (unlikely(vvar_read_retry(vvar, seq)));
ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
--
2.50.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v2 06/13] sparc64: vdso: Move syscall fallbacks into header
2025-08-15 10:41 [PATCH v2 00/13] sparc64: vdso: Switch to generic vDSO library Thomas Weißschuh
` (4 preceding siblings ...)
2025-08-15 10:41 ` [PATCH v2 05/13] sparc64: vdso: Move hardware counter read into header Thomas Weißschuh
@ 2025-08-15 10:41 ` Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 07/13] sparc64: vdso: Introduce vdso/processor.h Thomas Weißschuh
` (6 subsequent siblings)
12 siblings, 0 replies; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-15 10:41 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Andreas Larsson,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
John Paul Adrian Glaubitz
Cc: linux-kernel, sparclinux, Thomas Weißschuh
The generic vDSO libraries expected the syscall fallbacks in
asm/vdso/gettimeofday.h. To prepare the adoption of the generic library,
move the existing functions there.
While at it, rename them so they match what the generic library expects.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
arch/sparc/include/asm/vdso/gettimeofday.h | 50 +++++++++++++++++++++++++++++
arch/sparc/vdso/vclock_gettime.c | 51 ++----------------------------
2 files changed, 52 insertions(+), 49 deletions(-)
diff --git a/arch/sparc/include/asm/vdso/gettimeofday.h b/arch/sparc/include/asm/vdso/gettimeofday.h
index 31f6505d3ab5dde9e02eca6da9182e5fb91031c4..429dc080568f59145cc0bc696060adeb60ac177a 100644
--- a/arch/sparc/include/asm/vdso/gettimeofday.h
+++ b/arch/sparc/include/asm/vdso/gettimeofday.h
@@ -6,6 +6,9 @@
#ifndef _ASM_SPARC_VDSO_GETTIMEOFDAY_H
#define _ASM_SPARC_VDSO_GETTIMEOFDAY_H
+#include <uapi/linux/time.h>
+#include <uapi/linux/unistd.h>
+
#include <linux/types.h>
#include <asm/vvar.h>
@@ -75,4 +78,51 @@ static __always_inline u64 __arch_get_hw_counter(struct vvar_data *vvar)
return vread_tick();
}
+#ifdef CONFIG_SPARC64
+#define SYSCALL_STRING \
+ "ta 0x6d;" \
+ "bcs,a 1f;" \
+ " sub %%g0, %%o0, %%o0;" \
+ "1:"
+#else
+#define SYSCALL_STRING \
+ "ta 0x10;" \
+ "bcs,a 1f;" \
+ " sub %%g0, %%o0, %%o0;" \
+ "1:"
+#endif
+
+#define SYSCALL_CLOBBERS \
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
+ "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", \
+ "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", \
+ "cc", "memory"
+
+static __always_inline
+long clock_gettime_fallback(clockid_t clock, struct __kernel_old_timespec *ts)
+{
+ register long num __asm__("g1") = __NR_clock_gettime;
+ register long o0 __asm__("o0") = clock;
+ register long o1 __asm__("o1") = (long) ts;
+
+ __asm__ __volatile__(SYSCALL_STRING : "=r" (o0) : "r" (num),
+ "0" (o0), "r" (o1) : SYSCALL_CLOBBERS);
+ return o0;
+}
+
+static __always_inline
+long gettimeofday_fallback(struct __kernel_old_timeval *tv, struct timezone *tz)
+{
+ register long num __asm__("g1") = __NR_gettimeofday;
+ register long o0 __asm__("o0") = (long) tv;
+ register long o1 __asm__("o1") = (long) tz;
+
+ __asm__ __volatile__(SYSCALL_STRING : "=r" (o0) : "r" (num),
+ "0" (o0), "r" (o1) : SYSCALL_CLOBBERS);
+ return o0;
+}
+
#endif /* _ASM_SPARC_VDSO_GETTIMEOFDAY_H */
diff --git a/arch/sparc/vdso/vclock_gettime.c b/arch/sparc/vdso/vclock_gettime.c
index 16ac80982a00b9f965453b89a0cc111312baa9b2..e768c0b84b3420deab2f74335892d40a5b515ee7 100644
--- a/arch/sparc/vdso/vclock_gettime.c
+++ b/arch/sparc/vdso/vclock_gettime.c
@@ -13,38 +13,13 @@
*/
#include <linux/kernel.h>
-#include <linux/time.h>
#include <linux/string.h>
#include <asm/io.h>
-#include <asm/unistd.h>
#include <asm/timex.h>
#include <asm/clocksource.h>
#include <asm/vdso/gettimeofday.h>
#include <asm/vvar.h>
-#ifdef CONFIG_SPARC64
-#define SYSCALL_STRING \
- "ta 0x6d;" \
- "bcs,a 1f;" \
- " sub %%g0, %%o0, %%o0;" \
- "1:"
-#else
-#define SYSCALL_STRING \
- "ta 0x10;" \
- "bcs,a 1f;" \
- " sub %%g0, %%o0, %%o0;" \
- "1:"
-#endif
-
-#define SYSCALL_CLOBBERS \
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
- "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", \
- "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", \
- "cc", "memory"
-
/*
* Compute the vvar page's address in the process address space, and return it
* as a pointer to the vvar_data.
@@ -64,28 +39,6 @@ notrace static __always_inline struct vvar_data *get_vvar_data(void)
return (struct vvar_data *) ret;
}
-notrace static long vdso_fallback_gettime(long clock, struct __kernel_old_timespec *ts)
-{
- register long num __asm__("g1") = __NR_clock_gettime;
- register long o0 __asm__("o0") = clock;
- register long o1 __asm__("o1") = (long) ts;
-
- __asm__ __volatile__(SYSCALL_STRING : "=r" (o0) : "r" (num),
- "0" (o0), "r" (o1) : SYSCALL_CLOBBERS);
- return o0;
-}
-
-notrace static long vdso_fallback_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
-{
- register long num __asm__("g1") = __NR_gettimeofday;
- register long o0 __asm__("o0") = (long) tv;
- register long o1 __asm__("o1") = (long) tz;
-
- __asm__ __volatile__(SYSCALL_STRING : "=r" (o0) : "r" (num),
- "0" (o0), "r" (o1) : SYSCALL_CLOBBERS);
- return o0;
-}
-
notrace static __always_inline u64 vgetsns(struct vvar_data *vvar)
{
u64 v;
@@ -184,7 +137,7 @@ __vdso_clock_gettime(clockid_t clock, struct __kernel_old_timespec *ts)
/*
* Unknown clock ID ? Fall back to the syscall.
*/
- return vdso_fallback_gettime(clock, ts);
+ return clock_gettime_fallback(clock, ts);
}
int
clock_gettime(clockid_t, struct __kernel_old_timespec *)
@@ -220,7 +173,7 @@ __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
}
return 0;
}
- return vdso_fallback_gettimeofday(tv, tz);
+ return gettimeofday_fallback(tv, tz);
}
int
gettimeofday(struct __kernel_old_timeval *, struct timezone *)
--
2.50.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v2 07/13] sparc64: vdso: Introduce vdso/processor.h
2025-08-15 10:41 [PATCH v2 00/13] sparc64: vdso: Switch to generic vDSO library Thomas Weißschuh
` (5 preceding siblings ...)
2025-08-15 10:41 ` [PATCH v2 06/13] sparc64: vdso: Move syscall fallbacks " Thomas Weißschuh
@ 2025-08-15 10:41 ` Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library Thomas Weißschuh
` (5 subsequent siblings)
12 siblings, 0 replies; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-15 10:41 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Andreas Larsson,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
John Paul Adrian Glaubitz
Cc: linux-kernel, sparclinux, Thomas Weißschuh
The generic vDSO library expects a vdso/processor.h with an definition of
cpu_relax().
Split out cpu_relax() into this dedicated header.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
arch/sparc/include/asm/processor.h | 3 +++
arch/sparc/include/asm/processor_32.h | 2 --
arch/sparc/include/asm/processor_64.h | 25 --------------------
arch/sparc/include/asm/vdso/processor.h | 41 +++++++++++++++++++++++++++++++++
4 files changed, 44 insertions(+), 27 deletions(-)
diff --git a/arch/sparc/include/asm/processor.h b/arch/sparc/include/asm/processor.h
index 18295ea625dd7271617c15caa003a173099dd4d0..e34de956519aaca0e9bf82a22000d9096f868968 100644
--- a/arch/sparc/include/asm/processor.h
+++ b/arch/sparc/include/asm/processor.h
@@ -1,6 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef ___ASM_SPARC_PROCESSOR_H
#define ___ASM_SPARC_PROCESSOR_H
+
+#include <asm/vdso/processor.h>
+
#if defined(__sparc__) && defined(__arch64__)
#include <asm/processor_64.h>
#else
diff --git a/arch/sparc/include/asm/processor_32.h b/arch/sparc/include/asm/processor_32.h
index ba8b70ffec085feb17de9050f37de98e0039f7c3..a074d313f4f80621c1bc42733529c6d9450b1275 100644
--- a/arch/sparc/include/asm/processor_32.h
+++ b/arch/sparc/include/asm/processor_32.h
@@ -91,8 +91,6 @@ unsigned long __get_wchan(struct task_struct *);
extern struct task_struct *last_task_used_math;
int do_mathemu(struct pt_regs *regs, struct task_struct *fpt);
-#define cpu_relax() barrier()
-
extern void (*sparc_idle)(void);
#endif
diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h
index 0a0d5c3d184c751d232a00e73357c0e345695a94..3de65ad6d78592013b1d1158a58497f3821d003c 100644
--- a/arch/sparc/include/asm/processor_64.h
+++ b/arch/sparc/include/asm/processor_64.h
@@ -182,31 +182,6 @@ unsigned long __get_wchan(struct task_struct *task);
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc)
#define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP])
-/* Please see the commentary in asm/backoff.h for a description of
- * what these instructions are doing and how they have been chosen.
- * To make a long story short, we are trying to yield the current cpu
- * strand during busy loops.
- */
-#ifdef BUILD_VDSO
-#define cpu_relax() asm volatile("\n99:\n\t" \
- "rd %%ccr, %%g0\n\t" \
- "rd %%ccr, %%g0\n\t" \
- "rd %%ccr, %%g0\n\t" \
- ::: "memory")
-#else /* ! BUILD_VDSO */
-#define cpu_relax() asm volatile("\n99:\n\t" \
- "rd %%ccr, %%g0\n\t" \
- "rd %%ccr, %%g0\n\t" \
- "rd %%ccr, %%g0\n\t" \
- ".section .pause_3insn_patch,\"ax\"\n\t"\
- ".word 99b\n\t" \
- "wr %%g0, 128, %%asr27\n\t" \
- "nop\n\t" \
- "nop\n\t" \
- ".previous" \
- ::: "memory")
-#endif
-
/* Prefetch support. This is tuned for UltraSPARC-III and later.
* UltraSPARC-I will treat these as nops, and UltraSPARC-II has
* a shallower prefetch queue than later chips.
diff --git a/arch/sparc/include/asm/vdso/processor.h b/arch/sparc/include/asm/vdso/processor.h
new file mode 100644
index 0000000000000000000000000000000000000000..f7a9adc807f7c9a0444afa51aeb47649a9bdb079
--- /dev/null
+++ b/arch/sparc/include/asm/vdso/processor.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _ASM_SPARC_VDSO_PROCESSOR_H
+#define _ASM_SPARC_VDSO_PROCESSOR_H
+
+#include <linux/compiler.h>
+
+#if defined(__arch64__)
+
+/* Please see the commentary in asm/backoff.h for a description of
+ * what these instructions are doing and how they have been chosen.
+ * To make a long story short, we are trying to yield the current cpu
+ * strand during busy loops.
+ */
+#ifdef BUILD_VDSO
+#define cpu_relax() asm volatile("\n99:\n\t" \
+ "rd %%ccr, %%g0\n\t" \
+ "rd %%ccr, %%g0\n\t" \
+ "rd %%ccr, %%g0\n\t" \
+ ::: "memory")
+#else /* ! BUILD_VDSO */
+#define cpu_relax() asm volatile("\n99:\n\t" \
+ "rd %%ccr, %%g0\n\t" \
+ "rd %%ccr, %%g0\n\t" \
+ "rd %%ccr, %%g0\n\t" \
+ ".section .pause_3insn_patch,\"ax\"\n\t"\
+ ".word 99b\n\t" \
+ "wr %%g0, 128, %%asr27\n\t" \
+ "nop\n\t" \
+ "nop\n\t" \
+ ".previous" \
+ ::: "memory")
+#endif /* BUILD_VDSO */
+
+#else /* ! __arch64__ */
+
+#define cpu_relax() barrier()
+
+#endif /* __arch64__ */
+
+#endif /* _ASM_SPARC_VDSO_PROCESSOR_H */
--
2.50.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-08-15 10:41 [PATCH v2 00/13] sparc64: vdso: Switch to generic vDSO library Thomas Weißschuh
` (6 preceding siblings ...)
2025-08-15 10:41 ` [PATCH v2 07/13] sparc64: vdso: Introduce vdso/processor.h Thomas Weißschuh
@ 2025-08-15 10:41 ` Thomas Weißschuh
2025-08-25 15:55 ` Andreas Larsson
2025-08-15 10:41 ` [PATCH v2 09/13] sparc64: vdso2c: Drop sym_vvar_start handling Thomas Weißschuh
` (4 subsequent siblings)
12 siblings, 1 reply; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-15 10:41 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Andreas Larsson,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
John Paul Adrian Glaubitz
Cc: linux-kernel, sparclinux, Thomas Weißschuh
The generic vDSO provides a lot common functionality shared between
different architectures. SPARC is the last architecture not using it,
preventing some necessary code cleanup.
Make use of the generic infrastructure.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
arch/sparc/Kconfig | 4 +-
arch/sparc/include/asm/clocksource.h | 9 --
arch/sparc/include/asm/vdso/clocksource.h | 10 ++
arch/sparc/include/asm/vdso/gettimeofday.h | 58 ++++++++--
arch/sparc/include/asm/vdso/vsyscall.h | 10 ++
arch/sparc/include/asm/vvar.h | 75 -------------
arch/sparc/kernel/Makefile | 1 -
arch/sparc/kernel/time_64.c | 6 +-
arch/sparc/kernel/vdso.c | 69 ------------
arch/sparc/vdso/Makefile | 6 +-
arch/sparc/vdso/vclock_gettime.c | 169 ++++-------------------------
arch/sparc/vdso/vdso-layout.lds.S | 7 +-
arch/sparc/vdso/vma.c | 70 +++---------
13 files changed, 119 insertions(+), 375 deletions(-)
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 7b595092cbfb65bf196fdae7039be38f7d201a7a..065bd30d321dbb089df79696dae63e97f781cb87 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -102,7 +102,6 @@ config SPARC64
select ARCH_USE_QUEUED_RWLOCKS
select ARCH_USE_QUEUED_SPINLOCKS
select GENERIC_TIME_VSYSCALL
- select ARCH_CLOCKSOURCE_DATA
select ARCH_HAS_PTE_SPECIAL
select PCI_DOMAINS if PCI
select ARCH_HAS_GIGANTIC_PAGE
@@ -110,6 +109,9 @@ config SPARC64
select HAVE_SETUP_PER_CPU_AREA
select NEED_PER_CPU_EMBED_FIRST_CHUNK
select NEED_PER_CPU_PAGE_FIRST_CHUNK
+ select HAVE_GENERIC_VDSO
+ select GENERIC_GETTIMEOFDAY
+ select GENERIC_VDSO_DATA_STORE
config ARCH_PROC_KCORE_TEXT
def_bool y
diff --git a/arch/sparc/include/asm/clocksource.h b/arch/sparc/include/asm/clocksource.h
index d63ef224befebd68637d0be5d19c5cbf657d590d..68303ad26eb26e99180bb71789f1d6fafe4a2225 100644
--- a/arch/sparc/include/asm/clocksource.h
+++ b/arch/sparc/include/asm/clocksource.h
@@ -5,13 +5,4 @@
#ifndef _ASM_SPARC_CLOCKSOURCE_H
#define _ASM_SPARC_CLOCKSOURCE_H
-/* VDSO clocksources */
-#define VCLOCK_NONE 0 /* Nothing userspace can do. */
-#define VCLOCK_TICK 1 /* Use %tick. */
-#define VCLOCK_STICK 2 /* Use %stick. */
-
-struct arch_clocksource_data {
- int vclock_mode;
-};
-
#endif /* _ASM_SPARC_CLOCKSOURCE_H */
diff --git a/arch/sparc/include/asm/vdso/clocksource.h b/arch/sparc/include/asm/vdso/clocksource.h
new file mode 100644
index 0000000000000000000000000000000000000000..007aa8ceaf522ebc11b05dd46dfcdf72a328822f
--- /dev/null
+++ b/arch/sparc/include/asm/vdso/clocksource.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_VDSO_CLOCKSOURCE_H
+#define __ASM_VDSO_CLOCKSOURCE_H
+
+/* VDSO clocksources */
+#define VDSO_ARCH_CLOCKMODES \
+ VDSO_CLOCKMODE_TICK, \
+ VDSO_CLOCKMODE_STICK
+
+#endif /* __ASM_VDSO_CLOCKSOURCE_H */
diff --git a/arch/sparc/include/asm/vdso/gettimeofday.h b/arch/sparc/include/asm/vdso/gettimeofday.h
index 429dc080568f59145cc0bc696060adeb60ac177a..a35875fba45470ba961a7df3ae52bc17d2a4a4a0 100644
--- a/arch/sparc/include/asm/vdso/gettimeofday.h
+++ b/arch/sparc/include/asm/vdso/gettimeofday.h
@@ -9,15 +9,14 @@
#include <uapi/linux/time.h>
#include <uapi/linux/unistd.h>
+#include <vdso/align.h>
+#include <vdso/clocksource.h>
+#include <vdso/datapage.h>
+#include <vdso/page.h>
+
#include <linux/types.h>
-#include <asm/vvar.h>
#ifdef CONFIG_SPARC64
-static __always_inline u64 vdso_shift_ns(u64 val, u32 amt)
-{
- return val >> amt;
-}
-
static __always_inline u64 vread_tick(void)
{
u64 ret;
@@ -48,6 +47,7 @@ static __always_inline u64 vdso_shift_ns(u64 val, u32 amt)
: "g1");
return ret;
}
+#define vdso_shift_ns vdso_shift_ns
static __always_inline u64 vread_tick(void)
{
@@ -70,9 +70,9 @@ static __always_inline u64 vread_tick_stick(void)
}
#endif
-static __always_inline u64 __arch_get_hw_counter(struct vvar_data *vvar)
+static __always_inline u64 __arch_get_hw_counter(s32 clock_mode, const struct vdso_time_data *vd)
{
- if (likely(vvar->vclock_mode == VCLOCK_STICK))
+ if (likely(clock_mode == VDSO_CLOCKMODE_STICK))
return vread_tick_stick();
else
return vread_tick();
@@ -102,7 +102,20 @@ static __always_inline u64 __arch_get_hw_counter(struct vvar_data *vvar)
"cc", "memory"
static __always_inline
-long clock_gettime_fallback(clockid_t clock, struct __kernel_old_timespec *ts)
+long clock_gettime_fallback(clockid_t clock, struct __kernel_timespec *ts)
+{
+ register long num __asm__("g1") = __NR_clock_gettime;
+ register long o0 __asm__("o0") = clock;
+ register long o1 __asm__("o1") = (long) ts;
+
+ __asm__ __volatile__(SYSCALL_STRING : "=r" (o0) : "r" (num),
+ "0" (o0), "r" (o1) : SYSCALL_CLOBBERS);
+ return o0;
+}
+
+#ifndef CONFIG_SPARC64
+static __always_inline
+long clock_gettime32_fallback(clockid_t clock, struct old_timespec32 *ts)
{
register long num __asm__("g1") = __NR_clock_gettime;
register long o0 __asm__("o0") = clock;
@@ -112,6 +125,7 @@ long clock_gettime_fallback(clockid_t clock, struct __kernel_old_timespec *ts)
"0" (o0), "r" (o1) : SYSCALL_CLOBBERS);
return o0;
}
+#endif
static __always_inline
long gettimeofday_fallback(struct __kernel_old_timeval *tv, struct timezone *tz)
@@ -125,4 +139,30 @@ long gettimeofday_fallback(struct __kernel_old_timeval *tv, struct timezone *tz)
return o0;
}
+static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(void)
+{
+ unsigned long ret;
+
+ /*
+ * SPARC does not support native PC-relative code relocations.
+ * Calculate the address manually, works for 32 and 64 bit code.
+ */
+ __asm__ __volatile__(
+ "1:\n"
+ "call 3f\n" // Jump over the embedded data and set up %o7
+ "nop\n" // Delay slot
+ "2:\n"
+ ".word vdso_u_time_data - .\n" // Embedded offset to external symbol
+ "3:\n"
+ "add %%o7, 2b - 1b, %%o7\n" // Point %o7 to the embedded offset
+ "ldsw [%%o7], %0\n" // Load the offset
+ "add %0, %%o7, %0\n" // Calculate the absolute address
+ : "=r" (ret)
+ :
+ : "o7");
+
+ return (const struct vdso_time_data *)ret;
+}
+#define __arch_get_vdso_u_time_data __arch_get_vdso_u_time_data
+
#endif /* _ASM_SPARC_VDSO_GETTIMEOFDAY_H */
diff --git a/arch/sparc/include/asm/vdso/vsyscall.h b/arch/sparc/include/asm/vdso/vsyscall.h
new file mode 100644
index 0000000000000000000000000000000000000000..8bfe703fedc56f9334773b26b5e1ecec42781378
--- /dev/null
+++ b/arch/sparc/include/asm/vdso/vsyscall.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _ASM_SPARC_VDSO_VSYSCALL_H
+#define _ASM_SPARC_VDSO_VSYSCALL_H
+
+#define __VDSO_PAGES 4
+
+#include <asm-generic/vdso/vsyscall.h>
+
+#endif /* _ASM_SPARC_VDSO_VSYSCALL_H */
diff --git a/arch/sparc/include/asm/vvar.h b/arch/sparc/include/asm/vvar.h
deleted file mode 100644
index 6eaf5cfcaae1319808e63884d624899895d9b6a5..0000000000000000000000000000000000000000
--- a/arch/sparc/include/asm/vvar.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
- */
-
-#ifndef _ASM_SPARC_VVAR_DATA_H
-#define _ASM_SPARC_VVAR_DATA_H
-
-#include <asm/clocksource.h>
-#include <asm/processor.h>
-#include <asm/barrier.h>
-#include <linux/time.h>
-#include <linux/types.h>
-
-struct vvar_data {
- unsigned int seq;
-
- int vclock_mode;
- struct { /* extract of a clocksource struct */
- u64 cycle_last;
- u64 mask;
- int mult;
- int shift;
- } clock;
- /* open coded 'struct timespec' */
- u64 wall_time_sec;
- u64 wall_time_snsec;
- u64 monotonic_time_snsec;
- u64 monotonic_time_sec;
- u64 monotonic_time_coarse_sec;
- u64 monotonic_time_coarse_nsec;
- u64 wall_time_coarse_sec;
- u64 wall_time_coarse_nsec;
-
- int tz_minuteswest;
- int tz_dsttime;
-};
-
-extern struct vvar_data *vvar_data;
-extern int vdso_fix_stick;
-
-static inline unsigned int vvar_read_begin(const struct vvar_data *s)
-{
- unsigned int ret;
-
-repeat:
- ret = READ_ONCE(s->seq);
- if (unlikely(ret & 1)) {
- cpu_relax();
- goto repeat;
- }
- smp_rmb(); /* Finish all reads before we return seq */
- return ret;
-}
-
-static inline int vvar_read_retry(const struct vvar_data *s,
- unsigned int start)
-{
- smp_rmb(); /* Finish all reads before checking the value of seq */
- return unlikely(s->seq != start);
-}
-
-static inline void vvar_write_begin(struct vvar_data *s)
-{
- ++s->seq;
- smp_wmb(); /* Makes sure that increment of seq is reflected */
-}
-
-static inline void vvar_write_end(struct vvar_data *s)
-{
- smp_wmb(); /* Makes the value of seq current before we increment */
- ++s->seq;
-}
-
-
-#endif /* _ASM_SPARC_VVAR_DATA_H */
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 36f2727e1445d0ea6e1c1a9ed716e04338a0c9a6..7a063cd4b6d3600e8e77efad5d69ac1d9fad2f75 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -43,7 +43,6 @@ obj-$(CONFIG_SPARC32) += systbls_32.o
obj-y += time_$(BITS).o
obj-$(CONFIG_SPARC32) += windows.o
obj-y += cpu.o
-obj-$(CONFIG_SPARC64) += vdso.o
obj-$(CONFIG_SPARC32) += devices.o
obj-y += ptrace_$(BITS).o
obj-y += unaligned_$(BITS).o
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c
index b32f27f929d1ab49a5aa05cde60d3b88e90928ba..87b267043ccd21b9397e316b017f0ae3ab8585c6 100644
--- a/arch/sparc/kernel/time_64.c
+++ b/arch/sparc/kernel/time_64.c
@@ -838,14 +838,14 @@ void __init time_init_early(void)
if (tlb_type == spitfire) {
if (is_hummingbird()) {
init_tick_ops(&hbtick_operations);
- clocksource_tick.archdata.vclock_mode = VCLOCK_NONE;
+ clocksource_tick.vdso_clock_mode = VDSO_CLOCKMODE_NONE;
} else {
init_tick_ops(&tick_operations);
- clocksource_tick.archdata.vclock_mode = VCLOCK_TICK;
+ clocksource_tick.vdso_clock_mode = VDSO_CLOCKMODE_TICK;
}
} else {
init_tick_ops(&stick_operations);
- clocksource_tick.archdata.vclock_mode = VCLOCK_STICK;
+ clocksource_tick.vdso_clock_mode = VDSO_CLOCKMODE_STICK;
}
}
diff --git a/arch/sparc/kernel/vdso.c b/arch/sparc/kernel/vdso.c
deleted file mode 100644
index 0e27437eb97bff16aba53b1634c7e9fa7db20b46..0000000000000000000000000000000000000000
--- a/arch/sparc/kernel/vdso.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE
- * Copyright 2003 Andi Kleen, SuSE Labs.
- *
- * Thanks to hpa@transmeta.com for some useful hint.
- * Special thanks to Ingo Molnar for his early experience with
- * a different vsyscall implementation for Linux/IA32 and for the name.
- */
-
-#include <linux/time.h>
-#include <linux/timekeeper_internal.h>
-
-#include <asm/vvar.h>
-
-void update_vsyscall_tz(void)
-{
- if (unlikely(vvar_data == NULL))
- return;
-
- vvar_data->tz_minuteswest = sys_tz.tz_minuteswest;
- vvar_data->tz_dsttime = sys_tz.tz_dsttime;
-}
-
-void update_vsyscall(struct timekeeper *tk)
-{
- struct vvar_data *vdata = vvar_data;
-
- if (unlikely(vdata == NULL))
- return;
-
- vvar_write_begin(vdata);
- vdata->vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode;
- vdata->clock.cycle_last = tk->tkr_mono.cycle_last;
- vdata->clock.mask = tk->tkr_mono.mask;
- vdata->clock.mult = tk->tkr_mono.mult;
- vdata->clock.shift = tk->tkr_mono.shift;
-
- vdata->wall_time_sec = tk->xtime_sec;
- vdata->wall_time_snsec = tk->tkr_mono.xtime_nsec;
-
- vdata->monotonic_time_sec = tk->xtime_sec +
- tk->wall_to_monotonic.tv_sec;
- vdata->monotonic_time_snsec = tk->tkr_mono.xtime_nsec +
- (tk->wall_to_monotonic.tv_nsec <<
- tk->tkr_mono.shift);
-
- while (vdata->monotonic_time_snsec >=
- (((u64)NSEC_PER_SEC) << tk->tkr_mono.shift)) {
- vdata->monotonic_time_snsec -=
- ((u64)NSEC_PER_SEC) << tk->tkr_mono.shift;
- vdata->monotonic_time_sec++;
- }
-
- vdata->wall_time_coarse_sec = tk->xtime_sec;
- vdata->wall_time_coarse_nsec =
- (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift);
-
- vdata->monotonic_time_coarse_sec =
- vdata->wall_time_coarse_sec + tk->wall_to_monotonic.tv_sec;
- vdata->monotonic_time_coarse_nsec =
- vdata->wall_time_coarse_nsec + tk->wall_to_monotonic.tv_nsec;
-
- while (vdata->monotonic_time_coarse_nsec >= NSEC_PER_SEC) {
- vdata->monotonic_time_coarse_nsec -= NSEC_PER_SEC;
- vdata->monotonic_time_coarse_sec++;
- }
-
- vvar_write_end(vdata);
-}
diff --git a/arch/sparc/vdso/Makefile b/arch/sparc/vdso/Makefile
index 400529acd1c10e7f05fdb6c330593acc3c06b6f0..38c5b4550a0943e6960d9fadfa6336dfb96072a2 100644
--- a/arch/sparc/vdso/Makefile
+++ b/arch/sparc/vdso/Makefile
@@ -3,6 +3,9 @@
# Building vDSO images for sparc.
#
+# Include the generic Makefile to check the built vDSO:
+include $(srctree)/lib/vdso/Makefile.include
+
# files to link into the vdso
vobjs-y := vdso-note.o vclock_gettime.o
@@ -102,6 +105,7 @@ $(obj)/vdso32.so.dbg: FORCE \
quiet_cmd_vdso = VDSO $@
cmd_vdso = $(LD) -nostdlib -o $@ \
$(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
- -T $(filter %.lds,$^) $(filter %.o,$^)
+ -T $(filter %.lds,$^) $(filter %.o,$^); \
+ $(cmd_vdso_check)
VDSO_LDFLAGS = -shared --hash-style=both --build-id=sha1 -Bsymbolic --no-undefined -z noexecstack
diff --git a/arch/sparc/vdso/vclock_gettime.c b/arch/sparc/vdso/vclock_gettime.c
index e768c0b84b3420deab2f74335892d40a5b515ee7..093a7ff4dafce1cf0af5af4c303bef86e159858a 100644
--- a/arch/sparc/vdso/vclock_gettime.c
+++ b/arch/sparc/vdso/vclock_gettime.c
@@ -12,169 +12,40 @@
* Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
*/
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <asm/io.h>
-#include <asm/timex.h>
-#include <asm/clocksource.h>
-#include <asm/vdso/gettimeofday.h>
-#include <asm/vvar.h>
+#include <linux/compiler.h>
+#include <linux/types.h>
-/*
- * Compute the vvar page's address in the process address space, and return it
- * as a pointer to the vvar_data.
- */
-notrace static __always_inline struct vvar_data *get_vvar_data(void)
-{
- unsigned long ret;
+#include <vdso/gettime.h>
- /*
- * vdso data page is the first vDSO page so grab the PC
- * and move up a page to get to the data page.
- */
- __asm__("rd %%pc, %0" : "=r" (ret));
- ret &= ~(8192 - 1);
- ret -= 8192;
+#include <asm/vdso/gettimeofday.h>
- return (struct vvar_data *) ret;
-}
+#include "../../../../lib/vdso/gettimeofday.c"
-notrace static __always_inline u64 vgetsns(struct vvar_data *vvar)
+int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
{
- u64 v;
- u64 cycles = __arch_get_hw_counter(vvar);
-
- v = (cycles - vvar->clock.cycle_last) & vvar->clock.mask;
- return v * vvar->clock.mult;
+ return __cvdso_gettimeofday(tv, tz);
}
-notrace static __always_inline int do_realtime(struct vvar_data *vvar,
- struct __kernel_old_timespec *ts)
-{
- unsigned long seq;
- u64 ns;
-
- do {
- seq = vvar_read_begin(vvar);
- ts->tv_sec = vvar->wall_time_sec;
- ns = vvar->wall_time_snsec;
- ns += vgetsns(vvar);
- ns = vdso_shift_ns(ns, vvar->clock.shift);
- } while (unlikely(vvar_read_retry(vvar, seq)));
-
- ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
- ts->tv_nsec = ns;
+int gettimeofday(struct __kernel_old_timeval *, struct timezone *)
+ __weak __alias(__vdso_gettimeofday);
- return 0;
-}
-
-notrace static __always_inline int do_monotonic(struct vvar_data *vvar,
- struct __kernel_old_timespec *ts)
+#if defined(CONFIG_SPARC64)
+int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts)
{
- unsigned long seq;
- u64 ns;
-
- do {
- seq = vvar_read_begin(vvar);
- ts->tv_sec = vvar->monotonic_time_sec;
- ns = vvar->monotonic_time_snsec;
- ns += vgetsns(vvar);
- ns = vdso_shift_ns(ns, vvar->clock.shift);
- } while (unlikely(vvar_read_retry(vvar, seq)));
-
- ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
- ts->tv_nsec = ns;
-
- return 0;
-}
-
-notrace static int do_realtime_coarse(struct vvar_data *vvar,
- struct __kernel_old_timespec *ts)
-{
- unsigned long seq;
-
- do {
- seq = vvar_read_begin(vvar);
- ts->tv_sec = vvar->wall_time_coarse_sec;
- ts->tv_nsec = vvar->wall_time_coarse_nsec;
- } while (unlikely(vvar_read_retry(vvar, seq)));
- return 0;
+ return __cvdso_clock_gettime(clock, ts);
}
-notrace static int do_monotonic_coarse(struct vvar_data *vvar,
- struct __kernel_old_timespec *ts)
-{
- unsigned long seq;
-
- do {
- seq = vvar_read_begin(vvar);
- ts->tv_sec = vvar->monotonic_time_coarse_sec;
- ts->tv_nsec = vvar->monotonic_time_coarse_nsec;
- } while (unlikely(vvar_read_retry(vvar, seq)));
+int clock_gettime(clockid_t, struct __kernel_timespec *)
+ __weak __alias(__vdso_clock_gettime);
- return 0;
-}
+#else
-notrace int
-__vdso_clock_gettime(clockid_t clock, struct __kernel_old_timespec *ts)
+int __vdso_clock_gettime(clockid_t clock, struct old_timespec32 *ts)
{
- struct vvar_data *vvd = get_vvar_data();
-
- switch (clock) {
- case CLOCK_REALTIME:
- if (unlikely(vvd->vclock_mode == VCLOCK_NONE))
- break;
- return do_realtime(vvd, ts);
- case CLOCK_MONOTONIC:
- if (unlikely(vvd->vclock_mode == VCLOCK_NONE))
- break;
- return do_monotonic(vvd, ts);
- case CLOCK_REALTIME_COARSE:
- return do_realtime_coarse(vvd, ts);
- case CLOCK_MONOTONIC_COARSE:
- return do_monotonic_coarse(vvd, ts);
- }
- /*
- * Unknown clock ID ? Fall back to the syscall.
- */
- return clock_gettime_fallback(clock, ts);
+ return __cvdso_clock_gettime32(clock, ts);
}
-int
-clock_gettime(clockid_t, struct __kernel_old_timespec *)
- __attribute__((weak, alias("__vdso_clock_gettime")));
-notrace int
-__vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
-{
- struct vvar_data *vvd = get_vvar_data();
+int clock_gettime(clockid_t, struct old_timespec32 *)
+ __weak __alias(__vdso_clock_gettime);
- if (likely(vvd->vclock_mode != VCLOCK_NONE)) {
- if (likely(tv != NULL)) {
- union tstv_t {
- struct __kernel_old_timespec ts;
- struct __kernel_old_timeval tv;
- } *tstv = (union tstv_t *) tv;
- do_realtime(vvd, &tstv->ts);
- /*
- * Assign before dividing to ensure that the division is
- * done in the type of tv_usec, not tv_nsec.
- *
- * There cannot be > 1 billion usec in a second:
- * do_realtime() has already distributed such overflow
- * into tv_sec. So we can assign it to an int safely.
- */
- tstv->tv.tv_usec = tstv->ts.tv_nsec;
- tstv->tv.tv_usec /= 1000;
- }
- if (unlikely(tz != NULL)) {
- /* Avoid memcpy. Some old compilers fail to inline it */
- tz->tz_minuteswest = vvd->tz_minuteswest;
- tz->tz_dsttime = vvd->tz_dsttime;
- }
- return 0;
- }
- return gettimeofday_fallback(tv, tz);
-}
-int
-gettimeofday(struct __kernel_old_timeval *, struct timezone *)
- __attribute__((weak, alias("__vdso_gettimeofday")));
+#endif
diff --git a/arch/sparc/vdso/vdso-layout.lds.S b/arch/sparc/vdso/vdso-layout.lds.S
index 9e0804789d11696948f11be367480b530a1f18d9..180e5d0ee07170a5dec88016a304a44f87eb8d88 100644
--- a/arch/sparc/vdso/vdso-layout.lds.S
+++ b/arch/sparc/vdso/vdso-layout.lds.S
@@ -4,6 +4,10 @@
* This script controls its layout.
*/
+#include <vdso/datapage.h>
+#include <vdso/page.h>
+#include <asm/vdso/vsyscall.h>
+
SECTIONS
{
/*
@@ -13,8 +17,7 @@ SECTIONS
* segment. Page size is 8192 for both 64-bit and 32-bit vdso binaries
*/
- vvar_start = . -8192;
- vvar_data = vvar_start;
+ VDSO_VVAR_SYMS
. = SIZEOF_HEADERS;
diff --git a/arch/sparc/vdso/vma.c b/arch/sparc/vdso/vma.c
index 582d84e2e5ba8932f39948bb0ca2678fc8f06a10..38a664d697829b8203f0c7cd9e6d7cc8bed4796f 100644
--- a/arch/sparc/vdso/vma.c
+++ b/arch/sparc/vdso/vma.c
@@ -16,17 +16,16 @@
#include <linux/linkage.h>
#include <linux/random.h>
#include <linux/elf.h>
+#include <linux/vdso_datastore.h>
#include <asm/cacheflush.h>
#include <asm/spitfire.h>
#include <asm/vdso.h>
-#include <asm/vvar.h>
#include <asm/page.h>
-unsigned int __read_mostly vdso_enabled = 1;
+#include <vdso/datapage.h>
+#include <asm/vdso/vsyscall.h>
-static struct vm_special_mapping vvar_mapping = {
- .name = "[vvar]"
-};
+unsigned int __read_mostly vdso_enabled = 1;
#ifdef CONFIG_SPARC64
static struct vm_special_mapping vdso_mapping64 = {
@@ -40,10 +39,8 @@ static struct vm_special_mapping vdso_mapping32 = {
};
#endif
-struct vvar_data *vvar_data;
-
/*
- * Allocate pages for the vdso and vvar, and copy in the vdso text from the
+ * Allocate pages for the vdso and copy in the vdso text from the
* kernel image.
*/
static int __init init_vdso_image(const struct vdso_image *image,
@@ -51,9 +48,8 @@ static int __init init_vdso_image(const struct vdso_image *image,
bool elf64)
{
int cnpages = (image->size) / PAGE_SIZE;
- struct page *dp, **dpp = NULL;
struct page *cp, **cpp = NULL;
- int i, dnpages = 0;
+ int i;
/*
* First, the vdso text. This is initialied data, an integral number of
@@ -76,31 +72,6 @@ static int __init init_vdso_image(const struct vdso_image *image,
copy_page(page_address(cp), image->data + i * PAGE_SIZE);
}
- /*
- * Now the vvar page. This is uninitialized data.
- */
-
- if (vvar_data == NULL) {
- dnpages = (sizeof(struct vvar_data) / PAGE_SIZE) + 1;
- if (WARN_ON(dnpages != 1))
- goto oom;
- dpp = kcalloc(dnpages, sizeof(struct page *), GFP_KERNEL);
- vvar_mapping.pages = dpp;
-
- if (!dpp)
- goto oom;
-
- dp = alloc_page(GFP_KERNEL);
- if (!dp)
- goto oom;
-
- dpp[0] = dp;
- vvar_data = page_address(dp);
- memset(vvar_data, 0, PAGE_SIZE);
-
- vvar_data->seq = 0;
- }
-
return 0;
oom:
if (cpp != NULL) {
@@ -112,15 +83,6 @@ static int __init init_vdso_image(const struct vdso_image *image,
vdso_mapping->pages = NULL;
}
- if (dpp != NULL) {
- for (i = 0; i < dnpages; i++) {
- if (dpp[i] != NULL)
- __free_page(dpp[i]);
- }
- kfree(dpp);
- vvar_mapping.pages = NULL;
- }
-
pr_warn("Cannot allocate vdso\n");
vdso_enabled = 0;
return -ENOMEM;
@@ -155,9 +117,12 @@ static unsigned long vdso_addr(unsigned long start, unsigned int len)
return start + (offset << PAGE_SHIFT);
}
+static_assert(VDSO_NR_PAGES == __VDSO_PAGES);
+
static int map_vdso(const struct vdso_image *image,
struct vm_special_mapping *vdso_mapping)
{
+ const size_t area_size = image->size + VDSO_NR_PAGES * PAGE_SIZE;
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
unsigned long text_start, addr = 0;
@@ -170,23 +135,20 @@ static int map_vdso(const struct vdso_image *image,
* region is free.
*/
if (current->flags & PF_RANDOMIZE) {
- addr = get_unmapped_area(NULL, 0,
- image->size - image->sym_vvar_start,
- 0, 0);
+ addr = get_unmapped_area(NULL, 0, area_size, 0, 0);
if (IS_ERR_VALUE(addr)) {
ret = addr;
goto up_fail;
}
- addr = vdso_addr(addr, image->size - image->sym_vvar_start);
+ addr = vdso_addr(addr, area_size);
}
- addr = get_unmapped_area(NULL, addr,
- image->size - image->sym_vvar_start, 0, 0);
+ addr = get_unmapped_area(NULL, addr, area_size, 0, 0);
if (IS_ERR_VALUE(addr)) {
ret = addr;
goto up_fail;
}
- text_start = addr - image->sym_vvar_start;
+ text_start = addr + VDSO_NR_PAGES * PAGE_SIZE;
current->mm->context.vdso = (void __user *)text_start;
/*
@@ -204,11 +166,7 @@ static int map_vdso(const struct vdso_image *image,
goto up_fail;
}
- vma = _install_special_mapping(mm,
- addr,
- -image->sym_vvar_start,
- VM_READ|VM_MAYREAD,
- &vvar_mapping);
+ vma = vdso_install_vvar_mapping(mm, addr);
if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
--
2.50.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v2 09/13] sparc64: vdso2c: Drop sym_vvar_start handling
2025-08-15 10:41 [PATCH v2 00/13] sparc64: vdso: Switch to generic vDSO library Thomas Weißschuh
` (7 preceding siblings ...)
2025-08-15 10:41 ` [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library Thomas Weißschuh
@ 2025-08-15 10:41 ` Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 10/13] sparc64: vdso2c: Remove symbol handling Thomas Weißschuh
` (3 subsequent siblings)
12 siblings, 0 replies; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-15 10:41 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Andreas Larsson,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
John Paul Adrian Glaubitz
Cc: linux-kernel, sparclinux, Thomas Weißschuh
After the adoption of the generic vDSO library this symbol does not exist.
The alignment invariant is now guaranteed by the generic code.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
arch/sparc/include/asm/vdso.h | 2 --
arch/sparc/vdso/vdso2c.c | 6 ------
arch/sparc/vdso/vdso2c.h | 4 ----
3 files changed, 12 deletions(-)
diff --git a/arch/sparc/include/asm/vdso.h b/arch/sparc/include/asm/vdso.h
index 59e79d35cd7384e2dd752e92d20bc599e38cb8b0..f08562d10215bd3e9a2d4eaa0aadc8400b40e256 100644
--- a/arch/sparc/include/asm/vdso.h
+++ b/arch/sparc/include/asm/vdso.h
@@ -8,8 +8,6 @@
struct vdso_image {
void *data;
unsigned long size; /* Always a multiple of PAGE_SIZE */
-
- long sym_vvar_start; /* Negative offset to the vvar area */
};
#ifdef CONFIG_SPARC64
diff --git a/arch/sparc/vdso/vdso2c.c b/arch/sparc/vdso/vdso2c.c
index b97af5ec9f35c01f2a976b6213b1768b677ad231..70b14a436fe2297ab446f778ab0d43155c272421 100644
--- a/arch/sparc/vdso/vdso2c.c
+++ b/arch/sparc/vdso/vdso2c.c
@@ -58,18 +58,12 @@
const char *outfilename;
-/* Symbols that we need in vdso2c. */
-enum {
- sym_vvar_start,
-};
-
struct vdso_sym {
const char *name;
int export;
};
struct vdso_sym required_syms[] = {
- [sym_vvar_start] = {"vvar_start", 1},
};
__attribute__((format(printf, 1, 2))) __attribute__((noreturn))
diff --git a/arch/sparc/vdso/vdso2c.h b/arch/sparc/vdso/vdso2c.h
index 60d69acc748f2401156a730027fe34abfb9fb6bc..ba0794659eb5af53b8c86b24f3221a5d0b3f74ab 100644
--- a/arch/sparc/vdso/vdso2c.h
+++ b/arch/sparc/vdso/vdso2c.h
@@ -104,10 +104,6 @@ static void BITSFUNC(go)(void *raw_addr, size_t raw_len,
}
}
- /* Validate mapping addresses. */
- if (syms[sym_vvar_start] % 8192)
- fail("vvar_begin must be a multiple of 8192\n");
-
if (!name) {
fwrite(stripped_addr, stripped_len, 1, outfile);
return;
--
2.50.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v2 10/13] sparc64: vdso2c: Remove symbol handling
2025-08-15 10:41 [PATCH v2 00/13] sparc64: vdso: Switch to generic vDSO library Thomas Weißschuh
` (8 preceding siblings ...)
2025-08-15 10:41 ` [PATCH v2 09/13] sparc64: vdso2c: Drop sym_vvar_start handling Thomas Weißschuh
@ 2025-08-15 10:41 ` Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 11/13] sparc64: vdso: Implement clock_gettime64() Thomas Weißschuh
` (2 subsequent siblings)
12 siblings, 0 replies; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-15 10:41 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Andreas Larsson,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
John Paul Adrian Glaubitz
Cc: linux-kernel, sparclinux, Thomas Weißschuh
There are no handled symbols left.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
arch/sparc/vdso/vdso2c.c | 10 ----------
arch/sparc/vdso/vdso2c.h | 41 +----------------------------------------
2 files changed, 1 insertion(+), 50 deletions(-)
diff --git a/arch/sparc/vdso/vdso2c.c b/arch/sparc/vdso/vdso2c.c
index 70b14a436fe2297ab446f778ab0d43155c272421..e5c61214a0e285547ac57c9997542546464bde23 100644
--- a/arch/sparc/vdso/vdso2c.c
+++ b/arch/sparc/vdso/vdso2c.c
@@ -58,14 +58,6 @@
const char *outfilename;
-struct vdso_sym {
- const char *name;
- int export;
-};
-
-struct vdso_sym required_syms[] = {
-};
-
__attribute__((format(printf, 1, 2))) __attribute__((noreturn))
static void fail(const char *format, ...)
{
@@ -105,8 +97,6 @@ static void fail(const char *format, ...)
#define PUT_BE(x, val) \
PBE(x, val, 64, PBE(x, val, 32, PBE(x, val, 16, LAST_PBE(x, val))))
-#define NSYMS ARRAY_SIZE(required_syms)
-
#define BITSFUNC3(name, bits, suffix) name##bits##suffix
#define BITSFUNC2(name, bits, suffix) BITSFUNC3(name, bits, suffix)
#define BITSFUNC(name) BITSFUNC2(name, ELF_BITS, )
diff --git a/arch/sparc/vdso/vdso2c.h b/arch/sparc/vdso/vdso2c.h
index ba0794659eb5af53b8c86b24f3221a5d0b3f74ab..bad6a0593f4ca293feca201a6343833268ad1cb8 100644
--- a/arch/sparc/vdso/vdso2c.h
+++ b/arch/sparc/vdso/vdso2c.h
@@ -17,11 +17,9 @@ static void BITSFUNC(go)(void *raw_addr, size_t raw_len,
unsigned long mapping_size;
int i;
unsigned long j;
- ELF(Shdr) *symtab_hdr = NULL, *strtab_hdr;
+ ELF(Shdr) *symtab_hdr = NULL;
ELF(Ehdr) *hdr = (ELF(Ehdr) *)raw_addr;
ELF(Dyn) *dyn = 0, *dyn_end = 0;
- INT_BITS syms[NSYMS] = {};
-
ELF(Phdr) *pt = (ELF(Phdr) *)(raw_addr + GET_BE(&hdr->e_phoff));
/* Walk the segment table. */
@@ -72,38 +70,6 @@ static void BITSFUNC(go)(void *raw_addr, size_t raw_len,
if (!symtab_hdr)
fail("no symbol table\n");
- strtab_hdr = raw_addr + GET_BE(&hdr->e_shoff) +
- GET_BE(&hdr->e_shentsize) * GET_BE(&symtab_hdr->sh_link);
-
- /* Walk the symbol table */
- for (i = 0;
- i < GET_BE(&symtab_hdr->sh_size) / GET_BE(&symtab_hdr->sh_entsize);
- i++) {
- int k;
-
- ELF(Sym) *sym = raw_addr + GET_BE(&symtab_hdr->sh_offset) +
- GET_BE(&symtab_hdr->sh_entsize) * i;
- const char *name = raw_addr + GET_BE(&strtab_hdr->sh_offset) +
- GET_BE(&sym->st_name);
-
- for (k = 0; k < NSYMS; k++) {
- if (!strcmp(name, required_syms[k].name)) {
- if (syms[k]) {
- fail("duplicate symbol %s\n",
- required_syms[k].name);
- }
-
- /*
- * Careful: we use negative addresses, but
- * st_value is unsigned, so we rely
- * on syms[k] being a signed type of the
- * correct width.
- */
- syms[k] = GET_BE(&sym->st_value);
- }
- }
- }
-
if (!name) {
fwrite(stripped_addr, stripped_len, 1, outfile);
return;
@@ -129,10 +95,5 @@ static void BITSFUNC(go)(void *raw_addr, size_t raw_len,
fprintf(outfile, "const struct vdso_image %s_builtin = {\n", name);
fprintf(outfile, "\t.data = raw_data,\n");
fprintf(outfile, "\t.size = %lu,\n", mapping_size);
- for (i = 0; i < NSYMS; i++) {
- if (required_syms[i].export && syms[i])
- fprintf(outfile, "\t.sym_%s = %" PRIi64 ",\n",
- required_syms[i].name, (int64_t)syms[i]);
- }
fprintf(outfile, "};\n");
}
--
2.50.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v2 11/13] sparc64: vdso: Implement clock_gettime64()
2025-08-15 10:41 [PATCH v2 00/13] sparc64: vdso: Switch to generic vDSO library Thomas Weißschuh
` (9 preceding siblings ...)
2025-08-15 10:41 ` [PATCH v2 10/13] sparc64: vdso2c: Remove symbol handling Thomas Weißschuh
@ 2025-08-15 10:41 ` Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 12/13] sparc64: vdso: Implement clock_getres() Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 13/13] clocksource: remove ARCH_CLOCKSOURCE_DATA Thomas Weißschuh
12 siblings, 0 replies; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-15 10:41 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Andreas Larsson,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
John Paul Adrian Glaubitz
Cc: linux-kernel, sparclinux, Thomas Weißschuh
To be y2038-safe, 32-bit userspace needs to explicitly call the 64-bit safe
time APIs.
Implement clock_gettime64() in the 32-bit vDSO.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
arch/sparc/vdso/vclock_gettime.c | 8 ++++++++
arch/sparc/vdso/vdso32/vdso32.lds.S | 2 ++
2 files changed, 10 insertions(+)
diff --git a/arch/sparc/vdso/vclock_gettime.c b/arch/sparc/vdso/vclock_gettime.c
index 093a7ff4dafce1cf0af5af4c303bef86e159858a..1d9859392e4cfd285349cf9155ca1fc25d3a7b41 100644
--- a/arch/sparc/vdso/vclock_gettime.c
+++ b/arch/sparc/vdso/vclock_gettime.c
@@ -48,4 +48,12 @@ int __vdso_clock_gettime(clockid_t clock, struct old_timespec32 *ts)
int clock_gettime(clockid_t, struct old_timespec32 *)
__weak __alias(__vdso_clock_gettime);
+int __vdso_clock_gettime64(clockid_t clock, struct __kernel_timespec *ts)
+{
+ return __cvdso_clock_gettime(clock, ts);
+}
+
+int clock_gettime64(clockid_t, struct __kernel_timespec *)
+ __weak __alias(__vdso_clock_gettime64);
+
#endif
diff --git a/arch/sparc/vdso/vdso32/vdso32.lds.S b/arch/sparc/vdso/vdso32/vdso32.lds.S
index 53575ee154c492f9503efdd8f995ac2a035203c7..a14e4f77e6f2222b855df27cc7a0d0a4f98bd4ac 100644
--- a/arch/sparc/vdso/vdso32/vdso32.lds.S
+++ b/arch/sparc/vdso/vdso32/vdso32.lds.S
@@ -17,6 +17,8 @@ VERSION {
global:
clock_gettime;
__vdso_clock_gettime;
+ clock_gettime64;
+ __vdso_clock_gettime64;
gettimeofday;
__vdso_gettimeofday;
local: *;
--
2.50.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v2 12/13] sparc64: vdso: Implement clock_getres()
2025-08-15 10:41 [PATCH v2 00/13] sparc64: vdso: Switch to generic vDSO library Thomas Weißschuh
` (10 preceding siblings ...)
2025-08-15 10:41 ` [PATCH v2 11/13] sparc64: vdso: Implement clock_gettime64() Thomas Weißschuh
@ 2025-08-15 10:41 ` Thomas Weißschuh
2025-08-15 12:13 ` Arnd Bergmann
2025-08-15 10:41 ` [PATCH v2 13/13] clocksource: remove ARCH_CLOCKSOURCE_DATA Thomas Weißschuh
12 siblings, 1 reply; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-15 10:41 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Andreas Larsson,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
John Paul Adrian Glaubitz
Cc: linux-kernel, sparclinux, Thomas Weißschuh
Add a vDSO fastpath for clock_getres().
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
arch/sparc/include/asm/vdso/gettimeofday.h | 42 +++++++++++++++++++++++++++++-
arch/sparc/vdso/vclock_gettime.c | 16 ++++++++++++
arch/sparc/vdso/vdso.lds.S | 2 ++
arch/sparc/vdso/vdso32/vdso32.lds.S | 2 ++
4 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/arch/sparc/include/asm/vdso/gettimeofday.h b/arch/sparc/include/asm/vdso/gettimeofday.h
index a35875fba45470ba961a7df3ae52bc17d2a4a4a0..ccd2bda0a0c42ec826eb0464b7a41f98b4cea993 100644
--- a/arch/sparc/include/asm/vdso/gettimeofday.h
+++ b/arch/sparc/include/asm/vdso/gettimeofday.h
@@ -16,6 +16,8 @@
#include <linux/types.h>
+#define VDSO_HAS_CLOCK_GETRES 1
+
#ifdef CONFIG_SPARC64
static __always_inline u64 vread_tick(void)
{
@@ -125,7 +127,45 @@ long clock_gettime32_fallback(clockid_t clock, struct old_timespec32 *ts)
"0" (o0), "r" (o1) : SYSCALL_CLOBBERS);
return o0;
}
-#endif
+
+static __always_inline
+long clock_getres_fallback(clockid_t clock, struct __kernel_timespec *ts)
+{
+ register long num __asm__("g1") = __NR_clock_getres_time64;
+ register long o0 __asm__("o0") = clock;
+ register long o1 __asm__("o1") = (long) ts;
+
+ __asm__ __volatile__(SYSCALL_STRING : "=r" (o0) : "r" (num),
+ "0" (o0), "r" (o1) : SYSCALL_CLOBBERS);
+ return o0;
+}
+
+static __always_inline
+long clock_getres32_fallback(clockid_t clock, struct old_timespec32 *ts)
+{
+ register long num __asm__("g1") = __NR_clock_getres;
+ register long o0 __asm__("o0") = clock;
+ register long o1 __asm__("o1") = (long) ts;
+
+ __asm__ __volatile__(SYSCALL_STRING : "=r" (o0) : "r" (num),
+ "0" (o0), "r" (o1) : SYSCALL_CLOBBERS);
+ return o0;
+}
+#else /* !CONFIG_SPARC64 */
+
+static __always_inline
+long clock_getres_fallback(clockid_t clock, struct __kernel_timespec *ts)
+{
+ register long num __asm__("g1") = __NR_clock_getres;
+ register long o0 __asm__("o0") = clock;
+ register long o1 __asm__("o1") = (long) ts;
+
+ __asm__ __volatile__(SYSCALL_STRING : "=r" (o0) : "r" (num),
+ "0" (o0), "r" (o1) : SYSCALL_CLOBBERS);
+ return o0;
+}
+
+#endif /* CONFIG_SPARC64 */
static __always_inline
long gettimeofday_fallback(struct __kernel_old_timeval *tv, struct timezone *tz)
diff --git a/arch/sparc/vdso/vclock_gettime.c b/arch/sparc/vdso/vclock_gettime.c
index 1d9859392e4cfd285349cf9155ca1fc25d3a7b41..3cadf94e6cee5392586755e97f629092d4bcab1e 100644
--- a/arch/sparc/vdso/vclock_gettime.c
+++ b/arch/sparc/vdso/vclock_gettime.c
@@ -38,6 +38,14 @@ int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts)
int clock_gettime(clockid_t, struct __kernel_timespec *)
__weak __alias(__vdso_clock_gettime);
+int __vdso_clock_getres(clockid_t clock, struct __kernel_timespec *res)
+{
+ return __cvdso_clock_getres(clock, res);
+}
+
+int clock_getres(clockid_t, struct __kernel_timespec *)
+ __weak __alias(__vdso_clock_getres);
+
#else
int __vdso_clock_gettime(clockid_t clock, struct old_timespec32 *ts)
@@ -56,4 +64,12 @@ int __vdso_clock_gettime64(clockid_t clock, struct __kernel_timespec *ts)
int clock_gettime64(clockid_t, struct __kernel_timespec *)
__weak __alias(__vdso_clock_gettime64);
+int __vdso_clock_getres(clockid_t clock, struct old_timespec32 *res)
+{
+ return __cvdso_clock_getres_time32(clock, res);
+}
+
+int clock_getres(clockid_t, struct old_timespec32 *)
+ __weak __alias(__vdso_clock_getres);
+
#endif
diff --git a/arch/sparc/vdso/vdso.lds.S b/arch/sparc/vdso/vdso.lds.S
index f3caa29a331c58175b67ea60d7ac15cd467fe5ff..67c64a3adfa94f61356ce11081df442c18d6d8d5 100644
--- a/arch/sparc/vdso/vdso.lds.S
+++ b/arch/sparc/vdso/vdso.lds.S
@@ -20,6 +20,8 @@ VERSION {
__vdso_clock_gettime;
gettimeofday;
__vdso_gettimeofday;
+ clock_getres;
+ __vdso_clock_getres;
local: *;
};
}
diff --git a/arch/sparc/vdso/vdso32/vdso32.lds.S b/arch/sparc/vdso/vdso32/vdso32.lds.S
index a14e4f77e6f2222b855df27cc7a0d0a4f98bd4ac..d09b1893ee1411f450df935335e6fe8d8c8b2632 100644
--- a/arch/sparc/vdso/vdso32/vdso32.lds.S
+++ b/arch/sparc/vdso/vdso32/vdso32.lds.S
@@ -21,6 +21,8 @@ VERSION {
__vdso_clock_gettime64;
gettimeofday;
__vdso_gettimeofday;
+ clock_getres;
+ __vdso_clock_getres;
local: *;
};
}
--
2.50.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v2 13/13] clocksource: remove ARCH_CLOCKSOURCE_DATA
2025-08-15 10:41 [PATCH v2 00/13] sparc64: vdso: Switch to generic vDSO library Thomas Weißschuh
` (11 preceding siblings ...)
2025-08-15 10:41 ` [PATCH v2 12/13] sparc64: vdso: Implement clock_getres() Thomas Weißschuh
@ 2025-08-15 10:41 ` Thomas Weißschuh
12 siblings, 0 replies; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-15 10:41 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Andreas Larsson,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
John Paul Adrian Glaubitz
Cc: linux-kernel, sparclinux, Thomas Weißschuh
From: Arnd Bergmann <arnd@arndb.de>
After sparc64, there are no remaining users of ARCH_CLOCKSOURCE_DATA
and it can just be removed.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: John Stultz <jstultz@google.com>
[Thomas: drop sparc64 bits from the patch]
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
include/linux/clocksource.h | 6 +-----
kernel/time/Kconfig | 4 ----
2 files changed, 1 insertion(+), 9 deletions(-)
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index 65b7c41471c390463770c2da13694e58e83b84ea..12d853b1883265cb47d93e33d8370e3957e7e695 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -25,8 +25,7 @@ struct clocksource_base;
struct clocksource;
struct module;
-#if defined(CONFIG_ARCH_CLOCKSOURCE_DATA) || \
- defined(CONFIG_GENERIC_GETTIMEOFDAY)
+#if defined(CONFIG_GENERIC_GETTIMEOFDAY)
#include <asm/clocksource.h>
#endif
@@ -106,9 +105,6 @@ struct clocksource {
u64 max_idle_ns;
u32 maxadj;
u32 uncertainty_margin;
-#ifdef CONFIG_ARCH_CLOCKSOURCE_DATA
- struct arch_clocksource_data archdata;
-#endif
u64 max_cycles;
u64 max_raw_delta;
const char *name;
diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig
index 7c6a52f7836cef248e0949060b50baa293f446cf..fe33118770978682d0ff6c6e7990896f42703b50 100644
--- a/kernel/time/Kconfig
+++ b/kernel/time/Kconfig
@@ -9,10 +9,6 @@
config CLOCKSOURCE_WATCHDOG
bool
-# Architecture has extra clocksource data
-config ARCH_CLOCKSOURCE_DATA
- bool
-
# Architecture has extra clocksource init called from registration
config ARCH_CLOCKSOURCE_INIT
bool
--
2.50.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* Re: [PATCH v2 12/13] sparc64: vdso: Implement clock_getres()
2025-08-15 10:41 ` [PATCH v2 12/13] sparc64: vdso: Implement clock_getres() Thomas Weißschuh
@ 2025-08-15 12:13 ` Arnd Bergmann
2025-08-15 12:34 ` Thomas Weißschuh
0 siblings, 1 reply; 40+ messages in thread
From: Arnd Bergmann @ 2025-08-15 12:13 UTC (permalink / raw)
To: Thomas Weißschuh, Andy Lutomirski, Thomas Gleixner,
Vincenzo Frascino, David S . Miller, Andreas Larsson,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
John Paul Adrian Glaubitz
Cc: linux-kernel, sparclinux
On Fri, Aug 15, 2025, at 12:41, Thomas Weißschuh wrote:
>
> +#define VDSO_HAS_CLOCK_GETRES 1
> +
> #ifdef CONFIG_SPARC64
> +static __always_inline
> +long clock_getres_fallback(clockid_t clock, struct __kernel_timespec
> *ts)
> +
> +static __always_inline
> +long clock_getres32_fallback(clockid_t clock, struct old_timespec32
> *ts)
> +{
> +}
> +#else /* !CONFIG_SPARC64 */
> +
> +static __always_inline
> +long clock_getres_fallback(clockid_t clock, struct __kernel_timespec
> *ts)
> +
> +#endif /* CONFIG_SPARC64 */
>
Something doesn't quite line up here: I think the check for
CONFIG_SPARC64 needs to be for "#ifndef BUILD_VDSO32", since
sparc32 kernels don't have a vdso at all yet.
On sparc64 kernels, I think you only need the
clock_getres_fallback() for 64-bit userspace, while
the compat path probably doesn't care about getres, neither
the time32 nor time64 variant.
Arnd
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 12/13] sparc64: vdso: Implement clock_getres()
2025-08-15 12:13 ` Arnd Bergmann
@ 2025-08-15 12:34 ` Thomas Weißschuh
2025-08-15 20:09 ` Arnd Bergmann
0 siblings, 1 reply; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-15 12:34 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
David S . Miller, Andreas Larsson, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, John Paul Adrian Glaubitz,
linux-kernel, sparclinux
On Fri, Aug 15, 2025 at 02:13:46PM +0200, Arnd Bergmann wrote:
> On Fri, Aug 15, 2025, at 12:41, Thomas Weißschuh wrote:
> >
> > +#define VDSO_HAS_CLOCK_GETRES 1
> > +
> > #ifdef CONFIG_SPARC64
>
> > +static __always_inline
> > +long clock_getres_fallback(clockid_t clock, struct __kernel_timespec
> > *ts)
>
> > +
> > +static __always_inline
> > +long clock_getres32_fallback(clockid_t clock, struct old_timespec32
> > *ts)
> > +{
>
> > +}
> > +#else /* !CONFIG_SPARC64 */
> > +
> > +static __always_inline
> > +long clock_getres_fallback(clockid_t clock, struct __kernel_timespec
> > *ts)
>
> > +
> > +#endif /* CONFIG_SPARC64 */
> >
>
> Something doesn't quite line up here: I think the check for
> CONFIG_SPARC64 needs to be for "#ifndef BUILD_VDSO32", since
> sparc32 kernels don't have a vdso at all yet.
arch/sparc/vdso/vdso32/vclock_gettime.c translates BUILD_VDSO32 into more
"standard" defines, CONFIG_SPARC64 in this case. I have a follow-up series
to get rid of this pattern in all architectures.
> On sparc64 kernels, I think you only need the
> clock_getres_fallback() for 64-bit userspace, while
> the compat path probably doesn't care about getres, neither
> the time32 nor time64 variant.
Why?
Thomas
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 12/13] sparc64: vdso: Implement clock_getres()
2025-08-15 12:34 ` Thomas Weißschuh
@ 2025-08-15 20:09 ` Arnd Bergmann
2025-08-18 5:50 ` Thomas Weißschuh
0 siblings, 1 reply; 40+ messages in thread
From: Arnd Bergmann @ 2025-08-15 20:09 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
David S . Miller, Andreas Larsson, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, John Paul Adrian Glaubitz,
linux-kernel, sparclinux
On Fri, Aug 15, 2025, at 14:34, Thomas Weißschuh wrote:
> On Fri, Aug 15, 2025 at 02:13:46PM +0200, Arnd Bergmann wrote:
>> On Fri, Aug 15, 2025, at 12:41, Thomas Weißschuh wrote:
>> >
>>
>> Something doesn't quite line up here: I think the check for
>> CONFIG_SPARC64 needs to be for "#ifndef BUILD_VDSO32", since
>> sparc32 kernels don't have a vdso at all yet.
>
> arch/sparc/vdso/vdso32/vclock_gettime.c translates BUILD_VDSO32 into more
> "standard" defines, CONFIG_SPARC64 in this case. I have a follow-up series
> to get rid of this pattern in all architectures.
Ok
>> On sparc64 kernels, I think you only need the
>> clock_getres_fallback() for 64-bit userspace, while
>> the compat path probably doesn't care about getres, neither
>> the time32 nor time64 variant.
>
> Why?
The clock_getres() vdso call is questionable even on 64-bit
systems, though we appear to have ended up with one on all
the major ones. Realistically if an application needs the
resolution often enough to want a fast way to get it, it can
just store it in a variable.
On 32-bit, we decided against adding a clock_getres_time64()
syscall when we added clock_gettime64() because of this.
For time64 userspace, this means that glibc always calls
the system call instead of the vdso, and old time32
userspace wouldn't use the clock_getres() vdso because
there was no vdso implementation when it was compiled.
Arnd
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 12/13] sparc64: vdso: Implement clock_getres()
2025-08-15 20:09 ` Arnd Bergmann
@ 2025-08-18 5:50 ` Thomas Weißschuh
2025-08-18 6:54 ` Arnd Bergmann
0 siblings, 1 reply; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-18 5:50 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
David S . Miller, Andreas Larsson, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, John Paul Adrian Glaubitz,
linux-kernel, sparclinux
On Fri, Aug 15, 2025 at 10:09:23PM +0200, Arnd Bergmann wrote:
> On Fri, Aug 15, 2025, at 14:34, Thomas Weißschuh wrote:
> > On Fri, Aug 15, 2025 at 02:13:46PM +0200, Arnd Bergmann wrote:
> >> On Fri, Aug 15, 2025, at 12:41, Thomas Weißschuh wrote:
(...)
> >> On sparc64 kernels, I think you only need the
> >> clock_getres_fallback() for 64-bit userspace, while
> >> the compat path probably doesn't care about getres, neither
> >> the time32 nor time64 variant.
> >
> > Why?
>
> The clock_getres() vdso call is questionable even on 64-bit
> systems, though we appear to have ended up with one on all
> the major ones. Realistically if an application needs the
> resolution often enough to want a fast way to get it, it can
> just store it in a variable.
Agreed.
> On 32-bit, we decided against adding a clock_getres_time64()
> syscall when we added clock_gettime64() because of this.
My assumption was that clock_getres_time64() wouldn't make sense in the
first place, as no clock would have a resolution this big.
> For time64 userspace, this means that glibc always calls
> the system call instead of the vdso, and old time32
> userspace wouldn't use the clock_getres() vdso because
> there was no vdso implementation when it was compiled.
Is this paragraph meant to be specific for SPARC? Glibc does use the
clock_getres() vdso fastpath on time64 architectures. But on SPARC no
application would ever use clock_getres() through the vdso today,
as it doesn't exist yet.
In any case, I have no strong opinions about this patch and am happy to drop it
or support only SPARC64. Most likely nobody will bother to update glibc anyways.
Thomas
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 12/13] sparc64: vdso: Implement clock_getres()
2025-08-18 5:50 ` Thomas Weißschuh
@ 2025-08-18 6:54 ` Arnd Bergmann
2025-08-18 13:00 ` Thomas Weißschuh
0 siblings, 1 reply; 40+ messages in thread
From: Arnd Bergmann @ 2025-08-18 6:54 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
David S . Miller, Andreas Larsson, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, John Paul Adrian Glaubitz,
linux-kernel, sparclinux
On Mon, Aug 18, 2025, at 07:50, Thomas Weißschuh wrote:
> On Fri, Aug 15, 2025 at 10:09:23PM +0200, Arnd Bergmann wrote:
>> On Fri, Aug 15, 2025, at 14:34, Thomas Weißschuh wrote:
>> > On Fri, Aug 15, 2025 at 02:13:46PM +0200, Arnd Bergmann wrote:
>> >> On Fri, Aug 15, 2025, at 12:41, Thomas Weißschuh wrote:
>
>> On 32-bit, we decided against adding a clock_getres_time64()
>> syscall when we added clock_gettime64() because of this.
>
> My assumption was that clock_getres_time64() wouldn't make sense in the
> first place, as no clock would have a resolution this big.
While the type conversion is trivial, the general approach has
been to use the new types consistently, so this would be an odd
place to make an exception and require an explicit conversion
from __kernel_old_timespec32 back to __kernel_timespec or the
libc timespec.
>> For time64 userspace, this means that glibc always calls
>> the system call instead of the vdso, and old time32
>> userspace wouldn't use the clock_getres() vdso because
>> there was no vdso implementation when it was compiled.
>
> Is this paragraph meant to be specific for SPARC? Glibc does use the
> clock_getres() vdso fastpath on time64 architectures. But on SPARC no
> application would ever use clock_getres() through the vdso today,
> as it doesn't exist yet.
The glibc code has a weird mixup of the time32 and time64
function names, but from what I can tell, it only ever sets
dl_vdso_clock_getres_time64 on 64-bit architectures, where it
gets set to the normal clock_getres vdso symbol. On 32-bit,
glibc always skips vdso_clock_getres_time64() since it
does not exist, and then it always calls clock_getres_time64()
through the syscall interface, unless it runs on pre-5.6
kernels that fall back to the time32 vdso or syscall.
From the kernel's perspective there is no such thing as a
'time64 architecture', all 32-bit architectures (except x32)
implement the time64 syscalls, most 32-bit architectures also
have the old syscalls, and all 64-bit architectures (plus x32)
only have the old syscalls.
glibc introduced a different view of the same thing, the
internal names on some 32-bit architectures (rv32, arc) get
redirected so they look more like x32. However, those
architectures don't use vdso.
> In any case, I have no strong opinions about this patch and am happy to drop it or support only SPARC64. Most likely nobody will bother to update glibc anyways.
Agreed, I think the only real concern is maintainability here, so
if you think it helps to have __vdso_clock_getres(), please keep
that for sparc64, but let's leave it out for 32-bit altogether.
Two related points:
- something we could add on all 32-bit architectures after
everything uses the generic vdso implementation is
vdso_gettimeofday_time64(), this can shave off a few cycles
because it avoids a division that may be expensive on some
architectures, making it marginally more useful than
vdso_clock_getres_time64().
- there is one catch on sparc64 in the way it defines
__kernel_old_timeval with a 32-bit __kernel_suseconds_t,
unlike all other 64-bit architectures. This is incompatible
with glibc's __timeval64 definition on sparc32, so there
would need to be a special case for sparc32 somewhere,
either in the kernel or in glibc.
Arnd
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 12/13] sparc64: vdso: Implement clock_getres()
2025-08-18 6:54 ` Arnd Bergmann
@ 2025-08-18 13:00 ` Thomas Weißschuh
2025-08-18 13:17 ` Arnd Bergmann
0 siblings, 1 reply; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-18 13:00 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
David S . Miller, Andreas Larsson, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, John Paul Adrian Glaubitz,
linux-kernel, sparclinux
On Mon, Aug 18, 2025 at 08:54:53AM +0200, Arnd Bergmann wrote:
> On Mon, Aug 18, 2025, at 07:50, Thomas Weißschuh wrote:
> > On Fri, Aug 15, 2025 at 10:09:23PM +0200, Arnd Bergmann wrote:
> >> On Fri, Aug 15, 2025, at 14:34, Thomas Weißschuh wrote:
> >> > On Fri, Aug 15, 2025 at 02:13:46PM +0200, Arnd Bergmann wrote:
> >> >> On Fri, Aug 15, 2025, at 12:41, Thomas Weißschuh wrote:
(...)
> >> For time64 userspace, this means that glibc always calls
> >> the system call instead of the vdso, and old time32
> >> userspace wouldn't use the clock_getres() vdso because
> >> there was no vdso implementation when it was compiled.
> >
> > Is this paragraph meant to be specific for SPARC? Glibc does use the
> > clock_getres() vdso fastpath on time64 architectures. But on SPARC no
> > application would ever use clock_getres() through the vdso today,
> > as it doesn't exist yet.
>
> The glibc code has a weird mixup of the time32 and time64
> function names, but from what I can tell, it only ever sets
> dl_vdso_clock_getres_time64 on 64-bit architectures, where it
> gets set to the normal clock_getres vdso symbol. On 32-bit,
> glibc always skips vdso_clock_getres_time64() since it
> does not exist, and then it always calls clock_getres_time64()
> through the syscall interface, unless it runs on pre-5.6
> kernels that fall back to the time32 vdso or syscall.
Ack.
So with 'time64 userspace', you mean '32-bit, time64 userspace', correct?
This was my misunderstanding.
> From the kernel's perspective there is no such thing as a
> 'time64 architecture', all 32-bit architectures (except x32)
> implement the time64 syscalls, most 32-bit architectures also
> have the old syscalls, and all 64-bit architectures (plus x32)
> only have the old syscalls.
>
> glibc introduced a different view of the same thing, the
> internal names on some 32-bit architectures (rv32, arc) get
> redirected so they look more like x32. However, those
> architectures don't use vdso.
Ack.
> > In any case, I have no strong opinions about this patch and am happy to drop it or support only SPARC64. Most likely nobody will bother to update glibc anyways.
>
> Agreed, I think the only real concern is maintainability here, so
> if you think it helps to have __vdso_clock_getres(), please keep
> that for sparc64, but let's leave it out for 32-bit altogether.
Let's drop it altogether; the code is out there if anybody ever cares.
> Two related points:
>
> - something we could add on all 32-bit architectures after
> everything uses the generic vdso implementation is
> vdso_gettimeofday_time64(), this can shave off a few cycles
> because it avoids a division that may be expensive on some
> architectures, making it marginally more useful than
> vdso_clock_getres_time64().
You mean this division in __cvdso_gettimeofday_data()?
tv->tv_usec = (u32)ts.tv_nsec / NSEC_PER_USEC;
Switching the subseconds field to nanoseconds to avoid the division and the
seconds field to 64bit to avoid overflows brings us back to
'struct __kernel_timespec' again, no? What would be the advantage of this over
vdso_clock_gettime(CLOCK_REALTIME, &ts)?
> - there is one catch on sparc64 in the way it defines
> __kernel_old_timeval with a 32-bit __kernel_suseconds_t,
> unlike all other 64-bit architectures. This is incompatible
> with glibc's __timeval64 definition on sparc32, so there
> would need to be a special case for sparc32 somewhere,
> either in the kernel or in glibc.
This is only a problem together with vdso_gettimeofday() from above, right?
Thomas
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 12/13] sparc64: vdso: Implement clock_getres()
2025-08-18 13:00 ` Thomas Weißschuh
@ 2025-08-18 13:17 ` Arnd Bergmann
0 siblings, 0 replies; 40+ messages in thread
From: Arnd Bergmann @ 2025-08-18 13:17 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
David S . Miller, Andreas Larsson, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, John Paul Adrian Glaubitz,
linux-kernel, sparclinux
On Mon, Aug 18, 2025, at 15:00, Thomas Weißschuh wrote:
> On Mon, Aug 18, 2025 at 08:54:53AM +0200, Arnd Bergmann wrote:
>> On Mon, Aug 18, 2025, at 07:50, Thomas Weißschuh wrote:
>> > On Fri, Aug 15, 2025 at 10:09:23PM +0200, Arnd Bergmann wrote:
>>
>> The glibc code has a weird mixup of the time32 and time64
>> function names, but from what I can tell, it only ever sets
>> dl_vdso_clock_getres_time64 on 64-bit architectures, where it
>> gets set to the normal clock_getres vdso symbol. On 32-bit,
>> glibc always skips vdso_clock_getres_time64() since it
>> does not exist, and then it always calls clock_getres_time64()
>> through the syscall interface, unless it runs on pre-5.6
>> kernels that fall back to the time32 vdso or syscall.
>
> Ack.
>
> So with 'time64 userspace', you mean '32-bit, time64 userspace', correct?
Yes
>> Two related points:
>>
>> - something we could add on all 32-bit architectures after
>> everything uses the generic vdso implementation is
>> vdso_gettimeofday_time64(), this can shave off a few cycles
>> because it avoids a division that may be expensive on some
>> architectures, making it marginally more useful than
>> vdso_clock_getres_time64().
>
> You mean this division in __cvdso_gettimeofday_data()?
>
> tv->tv_usec = (u32)ts.tv_nsec / NSEC_PER_USEC;
>
> Switching the subseconds field to nanoseconds to avoid the division and the
> seconds field to 64bit to avoid overflows brings us back to
> 'struct __kernel_timespec' again, no? What would be the advantage of this over
> vdso_clock_gettime(CLOCK_REALTIME, &ts)?
I misremembered what the current code does. As you point out,
there is a division by NSEC_PER_USEC in the vdso as well, so
there is no difference between libc calling vdso_clock_gettime()
and vdso_gettimeofday() in the number of divisions.
If we wanted to optimize this bit, the division would need
to be folded into vdso_calc_ns()/mul_u64_u32_add_u64_shr(),
which is nontrivial.
>> - there is one catch on sparc64 in the way it defines
>> __kernel_old_timeval with a 32-bit __kernel_suseconds_t,
>> unlike all other 64-bit architectures. This is incompatible
>> with glibc's __timeval64 definition on sparc32, so there
>> would need to be a special case for sparc32 somewhere,
>> either in the kernel or in glibc.
>
> This is only a problem together with vdso_gettimeofday() from above, right?
Correct. I took a look at your sparc64 gettimeofday() to make
sure it uses the correct types and that seems fine since it
gets the __kernel_old_timeval structure definition from the
the sparc64 uapi headers.
Arnd
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-08-15 10:41 ` [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library Thomas Weißschuh
@ 2025-08-25 15:55 ` Andreas Larsson
2025-08-26 5:56 ` Thomas Weißschuh
0 siblings, 1 reply; 40+ messages in thread
From: Andreas Larsson @ 2025-08-25 15:55 UTC (permalink / raw)
To: Thomas Weißschuh, Andy Lutomirski, Thomas Gleixner,
Vincenzo Frascino, Arnd Bergmann, David S. Miller,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
John Paul Adrian Glaubitz
Cc: linux-kernel, sparclinux
On 2025-08-15 12:41, Thomas Weißschuh wrote:
> The generic vDSO provides a lot common functionality shared between
> different architectures. SPARC is the last architecture not using it,
> preventing some necessary code cleanup.
>
> Make use of the generic infrastructure.
>
> Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> ---
> arch/sparc/Kconfig | 4 +-
> arch/sparc/include/asm/clocksource.h | 9 --
> arch/sparc/include/asm/vdso/clocksource.h | 10 ++
> arch/sparc/include/asm/vdso/gettimeofday.h | 58 ++++++++--
> arch/sparc/include/asm/vdso/vsyscall.h | 10 ++
> arch/sparc/include/asm/vvar.h | 75 -------------
> arch/sparc/kernel/Makefile | 1 -
> arch/sparc/kernel/time_64.c | 6 +-
> arch/sparc/kernel/vdso.c | 69 ------------
> arch/sparc/vdso/Makefile | 6 +-
> arch/sparc/vdso/vclock_gettime.c | 169 ++++-------------------------
> arch/sparc/vdso/vdso-layout.lds.S | 7 +-
> arch/sparc/vdso/vma.c | 70 +++---------
> 13 files changed, 119 insertions(+), 375 deletions(-)
Hi,
With the first seven patches (applied on v6.17-rc1) I don't run into any
problems, but from this patch (and onwards) things do not work properly.
With patches 1-8 applied, Debian running on a sun4v (in a Solaris LDOM)
stops being able to mount the root filesystem with the patches applied
up to and including this patch.
As an aside, with all patches applied, it panics when the kernel
attempts to kill init.
Cheers,
Andreas
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-08-25 15:55 ` Andreas Larsson
@ 2025-08-26 5:56 ` Thomas Weißschuh
2025-08-28 15:38 ` Andreas Larsson
0 siblings, 1 reply; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-26 5:56 UTC (permalink / raw)
To: Andreas Larsson
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, John Paul Adrian Glaubitz,
linux-kernel, sparclinux
Hi Andreas,
thaks for testing!
On Mon, Aug 25, 2025 at 05:55:20PM +0200, Andreas Larsson wrote:
> On 2025-08-15 12:41, Thomas Weißschuh wrote:
> > The generic vDSO provides a lot common functionality shared between
> > different architectures. SPARC is the last architecture not using it,
> > preventing some necessary code cleanup.
> >
> > Make use of the generic infrastructure.
> >
> > Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> > ---
> > arch/sparc/Kconfig | 4 +-
> > arch/sparc/include/asm/clocksource.h | 9 --
> > arch/sparc/include/asm/vdso/clocksource.h | 10 ++
> > arch/sparc/include/asm/vdso/gettimeofday.h | 58 ++++++++--
> > arch/sparc/include/asm/vdso/vsyscall.h | 10 ++
> > arch/sparc/include/asm/vvar.h | 75 -------------
> > arch/sparc/kernel/Makefile | 1 -
> > arch/sparc/kernel/time_64.c | 6 +-
> > arch/sparc/kernel/vdso.c | 69 ------------
> > arch/sparc/vdso/Makefile | 6 +-
> > arch/sparc/vdso/vclock_gettime.c | 169 ++++-------------------------
> > arch/sparc/vdso/vdso-layout.lds.S | 7 +-
> > arch/sparc/vdso/vma.c | 70 +++---------
> > 13 files changed, 119 insertions(+), 375 deletions(-)
>
> With the first seven patches (applied on v6.17-rc1) I don't run into any
> problems, but from this patch (and onwards) things do not work properly.
> With patches 1-8 applied, Debian running on a sun4v (in a Solaris LDOM)
> stops being able to mount the root filesystem with the patches applied
> up to and including this patch.
Could you give me the kernel log of the failures? Is there any chance to get
access to the machine? Can you reproduce this issue on sun4u? sun4v in QEMU is
"work in progress" and instantly crashes for me. Can you provide me your Debian
image?
> As an aside, with all patches applied, it panics when the kernel
> attempts to kill init.
It is suprising that the error changes between patches.
The later patches don't change any lowlevel stuff, so if rootfs mounting
was broken earlier I don't see how it could go on to start init later.
Are these results repeatable?
Thomas
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-08-26 5:56 ` Thomas Weißschuh
@ 2025-08-28 15:38 ` Andreas Larsson
2025-08-29 10:02 ` Andreas Larsson
0 siblings, 1 reply; 40+ messages in thread
From: Andreas Larsson @ 2025-08-28 15:38 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, John Paul Adrian Glaubitz,
linux-kernel, sparclinux
On 2025-08-26 07:56, Thomas Weißschuh wrote:
> Hi Andreas,
>
> thaks for testing!
>
> On Mon, Aug 25, 2025 at 05:55:20PM +0200, Andreas Larsson wrote:
>> On 2025-08-15 12:41, Thomas Weißschuh wrote:
>>> The generic vDSO provides a lot common functionality shared between
>>> different architectures. SPARC is the last architecture not using it,
>>> preventing some necessary code cleanup.
>>>
>>> Make use of the generic infrastructure.
>>>
>>> Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
>>> ---
>>> arch/sparc/Kconfig | 4 +-
>>> arch/sparc/include/asm/clocksource.h | 9 --
>>> arch/sparc/include/asm/vdso/clocksource.h | 10 ++
>>> arch/sparc/include/asm/vdso/gettimeofday.h | 58 ++++++++--
>>> arch/sparc/include/asm/vdso/vsyscall.h | 10 ++
>>> arch/sparc/include/asm/vvar.h | 75 -------------
>>> arch/sparc/kernel/Makefile | 1 -
>>> arch/sparc/kernel/time_64.c | 6 +-
>>> arch/sparc/kernel/vdso.c | 69 ------------
>>> arch/sparc/vdso/Makefile | 6 +-
>>> arch/sparc/vdso/vclock_gettime.c | 169 ++++-------------------------
>>> arch/sparc/vdso/vdso-layout.lds.S | 7 +-
>>> arch/sparc/vdso/vma.c | 70 +++---------
>>> 13 files changed, 119 insertions(+), 375 deletions(-)
>>
>> With the first seven patches (applied on v6.17-rc1) I don't run into any
>> problems, but from this patch (and onwards) things do not work properly.
>> With patches 1-8 applied, Debian running on a sun4v (in a Solaris LDOM)
>> stops being able to mount the root filesystem with the patches applied
>> up to and including this patch.
>
> Could you give me the kernel log of the failures?
Not sure if fuller logs would help, but with the 8 first patches applied
I get this behaviour when the kernel is trying to run /init:
----------------%<----------------
[ 1.850062] Run /init as init process
Loading, please wait...
Starting systemd-udevd version 257.7-1
Begin: Loading essential drivers ... done.
Begin: Running /scripts/init-premount ... done.
Begin: Mounting root file system ... Begin: Running /scripts/local-top ... done.
Begin: Running /scripts/local-premount ... Begin: Waiting for suspend/resume device ... Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
[ 5.386073] sched: DL replenish lagged too much
Begin: Running /scripts/local-block ... done.
--%<-- <25 identical lines> --%<--
Begin: Running /scripts/local-block ... done.
done.
Gave up waiting for suspend/resume device
done.
Begin: Waiting for root file system ... Begin: Running /scripts/local-block ... done.
done.
Gave up waiting for root file system device. Common problems:
- Boot args (cat /proc/cmdline)
- Check rootdelay= (did the system wait long enough?)
- Missing modules (cat /proc/modules; ls /dev)
ALERT! UUID=2351ccc2-3dbd-4de6-9221-255a8e1fb132 does not exist. Dropping to a shell!
----------------%<----------------
and with all of them applied I got:
----------------%<----------------
[ 1.849344] Run /init as init process
[ 1.851309] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
[ 1.851339] CPU: 4 UID: 0 PID: 1 Comm: init Not tainted 6.17.0-rc1+ #3 VOLUNTARY
[ 1.851363] Call Trace:
[ 1.851374] [<0000000000436524>] dump_stack+0x8/0x18
[ 1.851400] [<00000000004291f4>] vpanic+0xdc/0x320
[ 1.851420] [<000000000042945c>] panic+0x24/0x30
[ 1.851437] [<00000000004844a4>] do_exit+0xac4/0xae0
[ 1.851458] [<0000000000484684>] do_group_exit+0x24/0xa0
[ 1.851476] [<0000000000494c60>] get_signal+0x900/0x940
[ 1.851495] [<000000000043ecb8>] do_notify_resume+0xf8/0x600
[ 1.851514] [<0000000000404b48>] __handle_signal+0xc/0x30
[ 1.852291] Press Stop-A (L1-A) from sun keyboard or send break
[ 1.852291] twice on console to return to the boot prom
[ 1.852310] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---
----------------%<----------------
but given that I don't have the kernel anymore I'm starting to
question myself if that run was really with the same base
commit. I'll do a rebuild and see.
> Is there any chance to get access to the machine?
Such access is not mine to give I'm afraid.
> Can you reproduce this issue on sun4u? sun4v in QEMU is
> "work in progress" and instantly crashes for me.
My current vDSO testing kernels aiming for this Debian setup are not
playing well with QEMU right now. I have to look into this.
> Can you provide me your Debian image?
What do you mean with image here? Disk image? Kernel image? This is a 25
GiB installation.
>
>> As an aside, with all patches applied, it panics when the kernel
>> attempts to kill init.
>
> It is suprising that the error changes between patches.
> The later patches don't change any lowlevel stuff, so if rootfs mounting
> was broken earlier I don't see how it could go on to start init later.
> Are these results repeatable?
The one with 8 patches is reliably repeatable. The one with all patches
seems to have been purged for space reasons, but I saw the same problem
multiple/all times as far as I remember. In any case, at least 7 patches
works reliably every time when 8 patches fails in the same way every
time.
Cheers,
Andreas
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-08-28 15:38 ` Andreas Larsson
@ 2025-08-29 10:02 ` Andreas Larsson
2025-08-29 10:37 ` Thomas Weißschuh
0 siblings, 1 reply; 40+ messages in thread
From: Andreas Larsson @ 2025-08-29 10:02 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, John Paul Adrian Glaubitz,
linux-kernel, sparclinux
On 2025-08-28 17:38, Andreas Larsson wrote:
> and with all of them applied I got:
>
> ----------------%<----------------
> [ 1.849344] Run /init as init process
> [ 1.851309] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
> [ 1.851339] CPU: 4 UID: 0 PID: 1 Comm: init Not tainted 6.17.0-rc1+ #3 VOLUNTARY
> [ 1.851363] Call Trace:
> [ 1.851374] [<0000000000436524>] dump_stack+0x8/0x18
> [ 1.851400] [<00000000004291f4>] vpanic+0xdc/0x320
> [ 1.851420] [<000000000042945c>] panic+0x24/0x30
> [ 1.851437] [<00000000004844a4>] do_exit+0xac4/0xae0
> [ 1.851458] [<0000000000484684>] do_group_exit+0x24/0xa0
> [ 1.851476] [<0000000000494c60>] get_signal+0x900/0x940
> [ 1.851495] [<000000000043ecb8>] do_notify_resume+0xf8/0x600
> [ 1.851514] [<0000000000404b48>] __handle_signal+0xc/0x30
> [ 1.852291] Press Stop-A (L1-A) from sun keyboard or send break
> [ 1.852291] twice on console to return to the boot prom
> [ 1.852310] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---
> ----------------%<----------------
>
> but given that I don't have the kernel anymore I'm starting to
> question myself if that run was really with the same base
> commit. I'll do a rebuild and see.
I found out that my previous kernel installation for the kernel with the first 8
patches was a broken mess. Sorry about the confusion. With that sorted out and a
rebuilt kernel with all patches, the failure above is the one I get for both 8
and 13 patches, and it is repeatable.
Cheers,
Andreas
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-08-29 10:02 ` Andreas Larsson
@ 2025-08-29 10:37 ` Thomas Weißschuh
2025-08-29 10:40 ` John Paul Adrian Glaubitz
2025-08-29 13:41 ` Andreas Larsson
0 siblings, 2 replies; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-29 10:37 UTC (permalink / raw)
To: Andreas Larsson
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, John Paul Adrian Glaubitz,
linux-kernel, sparclinux
On Fri, Aug 29, 2025 at 12:02:39PM +0200, Andreas Larsson wrote:
> On 2025-08-28 17:38, Andreas Larsson wrote:
> > and with all of them applied I got:
> >
> > ----------------%<----------------
> > [ 1.849344] Run /init as init process
> > [ 1.851309] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
> > [ 1.851339] CPU: 4 UID: 0 PID: 1 Comm: init Not tainted 6.17.0-rc1+ #3 VOLUNTARY
> > [ 1.851363] Call Trace:
> > [ 1.851374] [<0000000000436524>] dump_stack+0x8/0x18
> > [ 1.851400] [<00000000004291f4>] vpanic+0xdc/0x320
> > [ 1.851420] [<000000000042945c>] panic+0x24/0x30
> > [ 1.851437] [<00000000004844a4>] do_exit+0xac4/0xae0
> > [ 1.851458] [<0000000000484684>] do_group_exit+0x24/0xa0
> > [ 1.851476] [<0000000000494c60>] get_signal+0x900/0x940
> > [ 1.851495] [<000000000043ecb8>] do_notify_resume+0xf8/0x600
> > [ 1.851514] [<0000000000404b48>] __handle_signal+0xc/0x30
> > [ 1.852291] Press Stop-A (L1-A) from sun keyboard or send break
> > [ 1.852291] twice on console to return to the boot prom
> > [ 1.852310] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---
> > ----------------%<----------------
> >
> > but given that I don't have the kernel anymore I'm starting to
> > question myself if that run was really with the same base
> > commit. I'll do a rebuild and see.
>
> I found out that my previous kernel installation for the kernel with the first 8
> patches was a broken mess. Sorry about the confusion. With that sorted out and a
> rebuilt kernel with all patches, the failure above is the one I get for both 8
> and 13 patches, and it is repeatable.
This splat means that init got killed by SIGSEGV, so that makes some sense in
the context of the code being touched. Then let's focus on patch 8 for now.
In the meantime I installed a full Debian, but the bug is still not
reproducible in QEMU.
* Did you use the SMP or UP kernel config from Debian?
* Can the fixed up kernel now run on QEMU?
* Which toolchain are you using?
* This is a 64-bit userland?
What difference does the following change make:
diff --git a/arch/sparc/vdso/vma.c b/arch/sparc/vdso/vma.c
index 38a664d69782..efc3fef8f9bc 100644
--- a/arch/sparc/vdso/vma.c
+++ b/arch/sparc/vdso/vma.c
@@ -25,7 +25,7 @@
#include <vdso/datapage.h>
#include <asm/vdso/vsyscall.h>
-unsigned int __read_mostly vdso_enabled = 1;
+unsigned int __read_mostly vdso_enabled = 0;
#ifdef CONFIG_SPARC64
static struct vm_special_mapping vdso_mapping64 = {
Or this one, independently from the one above:
diff --git a/arch/sparc/vdso/vdso.lds.S b/arch/sparc/vdso/vdso.lds.S
index f3caa29a331c..a4669f7feada 100644
--- a/arch/sparc/vdso/vdso.lds.S
+++ b/arch/sparc/vdso/vdso.lds.S
@@ -16,10 +16,7 @@
VERSION {
LINUX_2.6 {
global:
- clock_gettime;
- __vdso_clock_gettime;
- gettimeofday;
- __vdso_gettimeofday;
+ __nothing;
local: *;
};
}
Or this one, independently from the ones above:
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 02ea19f67164..ae87888fef8a 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -318,6 +318,8 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
const struct vdso_clock *vc = vd->clock_data;
u32 msk;
+ return false;
+
if (!vdso_clockid_valid(clock))
return false;
^ permalink raw reply related [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-08-29 10:37 ` Thomas Weißschuh
@ 2025-08-29 10:40 ` John Paul Adrian Glaubitz
2025-08-29 10:52 ` Thomas Weißschuh
2025-08-29 13:41 ` Andreas Larsson
1 sibling, 1 reply; 40+ messages in thread
From: John Paul Adrian Glaubitz @ 2025-08-29 10:40 UTC (permalink / raw)
To: Thomas Weißschuh, Andreas Larsson
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, linux-kernel, sparclinux
Hi Thomas,
On Fri, 2025-08-29 at 12:37 +0200, Thomas Weißschuh wrote:
> In the meantime I installed a full Debian, but the bug is still not
> reproducible in QEMU.
Please keep in mind that QEMU emulates sun4u (on UltraSPARC II) while
Andreas was testing on sun4v (on Niagara 4). There might be differences.
Adrian
--
.''`. John Paul Adrian Glaubitz
: :' : Debian Developer
`. `' Physicist
`- GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-08-29 10:40 ` John Paul Adrian Glaubitz
@ 2025-08-29 10:52 ` Thomas Weißschuh
2025-08-29 15:24 ` John Paul Adrian Glaubitz
2025-09-01 15:17 ` Arnd Bergmann
0 siblings, 2 replies; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-29 10:52 UTC (permalink / raw)
To: John Paul Adrian Glaubitz
Cc: Andreas Larsson, Andy Lutomirski, Thomas Gleixner,
Vincenzo Frascino, Arnd Bergmann, David S. Miller,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
linux-kernel, sparclinux
On Fri, Aug 29, 2025 at 12:40:59PM +0200, John Paul Adrian Glaubitz wrote:
> On Fri, 2025-08-29 at 12:37 +0200, Thomas Weißschuh wrote:
> > In the meantime I installed a full Debian, but the bug is still not
> > reproducible in QEMU.
>
> Please keep in mind that QEMU emulates sun4u (on UltraSPARC II) while
> Andreas was testing on sun4v (on Niagara 4). There might be differences.
I am aware. Unfortuntely I don't have anything else available.
If anybody could test this on real sun4u that would be great.
Or teach me how to use sun4v QEMU without it crashing on me.
In the past you offered access to a physical machine.
Does this offer still stand? Does it also run into the bug?
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-08-29 10:37 ` Thomas Weißschuh
2025-08-29 10:40 ` John Paul Adrian Glaubitz
@ 2025-08-29 13:41 ` Andreas Larsson
2025-08-29 13:51 ` Thomas Weißschuh
` (2 more replies)
1 sibling, 3 replies; 40+ messages in thread
From: Andreas Larsson @ 2025-08-29 13:41 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, John Paul Adrian Glaubitz,
linux-kernel, sparclinux
On 2025-08-29 12:37, Thomas Weißschuh wrote:
> On Fri, Aug 29, 2025 at 12:02:39PM +0200, Andreas Larsson wrote:
>> On 2025-08-28 17:38, Andreas Larsson wrote:
>>> and with all of them applied I got:
>>>
>>> ----------------%<----------------
>>> [ 1.849344] Run /init as init process
>>> [ 1.851309] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
>>> [ 1.851339] CPU: 4 UID: 0 PID: 1 Comm: init Not tainted 6.17.0-rc1+ #3 VOLUNTARY
>>> [ 1.851363] Call Trace:
>>> [ 1.851374] [<0000000000436524>] dump_stack+0x8/0x18
>>> [ 1.851400] [<00000000004291f4>] vpanic+0xdc/0x320
>>> [ 1.851420] [<000000000042945c>] panic+0x24/0x30
>>> [ 1.851437] [<00000000004844a4>] do_exit+0xac4/0xae0
>>> [ 1.851458] [<0000000000484684>] do_group_exit+0x24/0xa0
>>> [ 1.851476] [<0000000000494c60>] get_signal+0x900/0x940
>>> [ 1.851495] [<000000000043ecb8>] do_notify_resume+0xf8/0x600
>>> [ 1.851514] [<0000000000404b48>] __handle_signal+0xc/0x30
>>> [ 1.852291] Press Stop-A (L1-A) from sun keyboard or send break
>>> [ 1.852291] twice on console to return to the boot prom
>>> [ 1.852310] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---
>>> ----------------%<----------------
>>>
>>> but given that I don't have the kernel anymore I'm starting to
>>> question myself if that run was really with the same base
>>> commit. I'll do a rebuild and see.
>>
>> I found out that my previous kernel installation for the kernel with the first 8
>> patches was a broken mess. Sorry about the confusion. With that sorted out and a
>> rebuilt kernel with all patches, the failure above is the one I get for both 8
>> and 13 patches, and it is repeatable.
>
> This splat means that init got killed by SIGSEGV, so that makes some sense in
> the context of the code being touched. Then let's focus on patch 8 for now.
>
> In the meantime I installed a full Debian, but the bug is still not
> reproducible in QEMU.
>
> * Did you use the SMP or UP kernel config from Debian?
I based my config on the SMP config that was in use on the system.
Produces an tremendous amount of modules unfortunately, so I'll have
to cut down in the config. Right now the turnaround time for testing
a new kernel with this setup for this system is quite bad.
> * Can the fixed up kernel now run on QEMU?
No, there is something else going on with my QEMU setup, unrelated to
these patches.
> * Which toolchain are you using?
A toolchain built in Buildroot with GCC 13.2.0. Old kernel headers, but
I only use it to build kernels. Do you think the kernel headers of the
toolchain would play a role for vDSO?
> * This is a 64-bit userland?
Yes.
>
> What difference does the following change make:
>
> diff --git a/arch/sparc/vdso/vma.c b/arch/sparc/vdso/vma.c
> index 38a664d69782..efc3fef8f9bc 100644
> --- a/arch/sparc/vdso/vma.c
> +++ b/arch/sparc/vdso/vma.c
> @@ -25,7 +25,7 @@
> #include <vdso/datapage.h>
> #include <asm/vdso/vsyscall.h>
>
> -unsigned int __read_mostly vdso_enabled = 1;
> +unsigned int __read_mostly vdso_enabled = 0;
>
> #ifdef CONFIG_SPARC64
> static struct vm_special_mapping vdso_mapping64 = {
>
>
> Or this one, independently from the one above:
>
>
> diff --git a/arch/sparc/vdso/vdso.lds.S b/arch/sparc/vdso/vdso.lds.S
> index f3caa29a331c..a4669f7feada 100644
> --- a/arch/sparc/vdso/vdso.lds.S
> +++ b/arch/sparc/vdso/vdso.lds.S
> @@ -16,10 +16,7 @@
> VERSION {
> LINUX_2.6 {
> global:
> - clock_gettime;
> - __vdso_clock_gettime;
> - gettimeofday;
> - __vdso_gettimeofday;
> + __nothing;
> local: *;
> };
> }
>
>
> Or this one, independently from the ones above:
>
> diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
> index 02ea19f67164..ae87888fef8a 100644
> --- a/lib/vdso/gettimeofday.c
> +++ b/lib/vdso/gettimeofday.c
> @@ -318,6 +318,8 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
> const struct vdso_clock *vc = vd->clock_data;
> u32 msk;
>
> + return false;
> +
> if (!vdso_clockid_valid(clock))
> return false;
>
I will check.
Cheers,
Andreas
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-08-29 13:41 ` Andreas Larsson
@ 2025-08-29 13:51 ` Thomas Weißschuh
2025-08-29 14:05 ` Thomas Weißschuh
2025-08-29 15:44 ` John Paul Adrian Glaubitz
2 siblings, 0 replies; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-29 13:51 UTC (permalink / raw)
To: Andreas Larsson
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, John Paul Adrian Glaubitz,
linux-kernel, sparclinux
On Fri, Aug 29, 2025 at 03:41:22PM +0200, Andreas Larsson wrote:
> On 2025-08-29 12:37, Thomas Weißschuh wrote:
> > On Fri, Aug 29, 2025 at 12:02:39PM +0200, Andreas Larsson wrote:
> >> On 2025-08-28 17:38, Andreas Larsson wrote:
> >>> and with all of them applied I got:
> >>>
> >>> ----------------%<----------------
> >>> [ 1.849344] Run /init as init process
> >>> [ 1.851309] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
> >>> [ 1.851339] CPU: 4 UID: 0 PID: 1 Comm: init Not tainted 6.17.0-rc1+ #3 VOLUNTARY
> >>> [ 1.851363] Call Trace:
> >>> [ 1.851374] [<0000000000436524>] dump_stack+0x8/0x18
> >>> [ 1.851400] [<00000000004291f4>] vpanic+0xdc/0x320
> >>> [ 1.851420] [<000000000042945c>] panic+0x24/0x30
> >>> [ 1.851437] [<00000000004844a4>] do_exit+0xac4/0xae0
> >>> [ 1.851458] [<0000000000484684>] do_group_exit+0x24/0xa0
> >>> [ 1.851476] [<0000000000494c60>] get_signal+0x900/0x940
> >>> [ 1.851495] [<000000000043ecb8>] do_notify_resume+0xf8/0x600
> >>> [ 1.851514] [<0000000000404b48>] __handle_signal+0xc/0x30
> >>> [ 1.852291] Press Stop-A (L1-A) from sun keyboard or send break
> >>> [ 1.852291] twice on console to return to the boot prom
> >>> [ 1.852310] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---
> >>> ----------------%<----------------
> >>>
> >>> but given that I don't have the kernel anymore I'm starting to
> >>> question myself if that run was really with the same base
> >>> commit. I'll do a rebuild and see.
> >>
> >> I found out that my previous kernel installation for the kernel with the first 8
> >> patches was a broken mess. Sorry about the confusion. With that sorted out and a
> >> rebuilt kernel with all patches, the failure above is the one I get for both 8
> >> and 13 patches, and it is repeatable.
> >
> > This splat means that init got killed by SIGSEGV, so that makes some sense in
> > the context of the code being touched. Then let's focus on patch 8 for now.
> >
> > In the meantime I installed a full Debian, but the bug is still not
> > reproducible in QEMU.
> >
> > * Did you use the SMP or UP kernel config from Debian?
>
> I based my config on the SMP config that was in use on the system.
> Produces an tremendous amount of modules unfortunately, so I'll have
> to cut down in the config. Right now the turnaround time for testing
> a new kernel with this setup for this system is quite bad.
Ack. I am aware :-(
> > * Can the fixed up kernel now run on QEMU?
>
> No, there is something else going on with my QEMU setup, unrelated to
> these patches.
Ack. FWIW for me it works (for sun4u) with my distro's QEMU 10.0.3.
> > * Which toolchain are you using?
>
> A toolchain built in Buildroot with GCC 13.2.0. Old kernel headers, but
> I only use it to build kernels. Do you think the kernel headers of the
> toolchain would play a role for vDSO?
No, the headers from the toolchain are not used. It could have been that you are
using a wildly different compiler. But I am also using GCC 13.2.0, although from
the kernel.org crosstools.
> > * This is a 64-bit userland?
>
> Yes.
Ack.
> > What difference does the following change make:
(...)
> I will check.
Thanks!
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-08-29 13:41 ` Andreas Larsson
2025-08-29 13:51 ` Thomas Weißschuh
@ 2025-08-29 14:05 ` Thomas Weißschuh
2025-08-29 16:35 ` Andreas Larsson
2025-08-29 15:44 ` John Paul Adrian Glaubitz
2 siblings, 1 reply; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-29 14:05 UTC (permalink / raw)
To: Andreas Larsson
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, John Paul Adrian Glaubitz,
linux-kernel, sparclinux
On Fri, Aug 29, 2025 at 03:41:22PM +0200, Andreas Larsson wrote:
> On 2025-08-29 12:37, Thomas Weißschuh wrote:
> > On Fri, Aug 29, 2025 at 12:02:39PM +0200, Andreas Larsson wrote:
> >> On 2025-08-28 17:38, Andreas Larsson wrote:
> >>> and with all of them applied I got:
> >>>
> >>> ----------------%<----------------
> >>> [ 1.849344] Run /init as init process
> >>> [ 1.851309] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
> >>> [ 1.851339] CPU: 4 UID: 0 PID: 1 Comm: init Not tainted 6.17.0-rc1+ #3 VOLUNTARY
> >>> [ 1.851363] Call Trace:
> >>> [ 1.851374] [<0000000000436524>] dump_stack+0x8/0x18
> >>> [ 1.851400] [<00000000004291f4>] vpanic+0xdc/0x320
> >>> [ 1.851420] [<000000000042945c>] panic+0x24/0x30
> >>> [ 1.851437] [<00000000004844a4>] do_exit+0xac4/0xae0
> >>> [ 1.851458] [<0000000000484684>] do_group_exit+0x24/0xa0
> >>> [ 1.851476] [<0000000000494c60>] get_signal+0x900/0x940
> >>> [ 1.851495] [<000000000043ecb8>] do_notify_resume+0xf8/0x600
> >>> [ 1.851514] [<0000000000404b48>] __handle_signal+0xc/0x30
> >>> [ 1.852291] Press Stop-A (L1-A) from sun keyboard or send break
> >>> [ 1.852291] twice on console to return to the boot prom
> >>> [ 1.852310] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---
> >>> ----------------%<----------------
> >>>
> >>> but given that I don't have the kernel anymore I'm starting to
> >>> question myself if that run was really with the same base
> >>> commit. I'll do a rebuild and see.
> >>
> >> I found out that my previous kernel installation for the kernel with the first 8
> >> patches was a broken mess. Sorry about the confusion. With that sorted out and a
> >> rebuilt kernel with all patches, the failure above is the one I get for both 8
> >> and 13 patches, and it is repeatable.
> >
> > This splat means that init got killed by SIGSEGV, so that makes some sense in
> > the context of the code being touched. Then let's focus on patch 8 for now.
> >
> > In the meantime I installed a full Debian, but the bug is still not
> > reproducible in QEMU.
> >
> > * Did you use the SMP or UP kernel config from Debian?
>
> I based my config on the SMP config that was in use on the system.
> Produces an tremendous amount of modules unfortunately, so I'll have
> to cut down in the config. Right now the turnaround time for testing
> a new kernel with this setup for this system is quite bad.
How are you currently building these kernels? Are you using the packaging
from Debian and doing full rebuilds every time?
You can also build Debian binary packages directly from a git checkout with
'make bindeb-pkg'. This gives you nice incremental rebuilds.
Another hunk to test, to see from where the SIGSEGV comes from.
diff --git a/kernel/signal.c b/kernel/signal.c
index e2c928de7d2c..0b2777e88f44 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1299,6 +1299,9 @@ force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t,
struct k_sigaction *action;
int sig = info->si_signo;
+ if (unlikely(is_global_init(t)) && sig == SIGSEGV)
+ panic("killing init");
+
spin_lock_irqsave(&t->sighand->siglock, flags);
action = &t->sighand->action[sig-1];
ignored = action->sa.sa_handler == SIG_IGN;
Sorry for the response spam...
Thomas
^ permalink raw reply related [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-08-29 10:52 ` Thomas Weißschuh
@ 2025-08-29 15:24 ` John Paul Adrian Glaubitz
2025-09-01 15:17 ` Arnd Bergmann
1 sibling, 0 replies; 40+ messages in thread
From: John Paul Adrian Glaubitz @ 2025-08-29 15:24 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Andreas Larsson, Andy Lutomirski, Thomas Gleixner,
Vincenzo Frascino, Arnd Bergmann, David S. Miller,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
linux-kernel, sparclinux
Hi Thomas,
On Fri, 2025-08-29 at 12:52 +0200, Thomas Weißschuh wrote:
> On Fri, Aug 29, 2025 at 12:40:59PM +0200, John Paul Adrian Glaubitz wrote:
> > On Fri, 2025-08-29 at 12:37 +0200, Thomas Weißschuh wrote:
> > > In the meantime I installed a full Debian, but the bug is still not
> > > reproducible in QEMU.
> >
> > Please keep in mind that QEMU emulates sun4u (on UltraSPARC II) while
> > Andreas was testing on sun4v (on Niagara 4). There might be differences.
>
> I am aware. Unfortuntely I don't have anything else available.
> If anybody could test this on real sun4u that would be great.
> Or teach me how to use sun4v QEMU without it crashing on me.
> In the past you offered access to a physical machine.
> Does this offer still stand? Does it also run into the bug?
We have a SPARC T5 in the Debian project that can also be used for that matter.
It's currently out of service and will be back online next week if all goes well.
Adrian
--
.''`. John Paul Adrian Glaubitz
: :' : Debian Developer
`. `' Physicist
`- GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-08-29 13:41 ` Andreas Larsson
2025-08-29 13:51 ` Thomas Weißschuh
2025-08-29 14:05 ` Thomas Weißschuh
@ 2025-08-29 15:44 ` John Paul Adrian Glaubitz
2 siblings, 0 replies; 40+ messages in thread
From: John Paul Adrian Glaubitz @ 2025-08-29 15:44 UTC (permalink / raw)
To: Andreas Larsson, Thomas Weißschuh
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, linux-kernel, sparclinux
Hi Andreas,
On Fri, 2025-08-29 at 15:41 +0200, Andreas Larsson wrote:
> I based my config on the SMP config that was in use on the system.
> Produces an tremendous amount of modules unfortunately, so I'll have
> to cut down in the config. Right now the turnaround time for testing
> a new kernel with this setup for this system is quite bad.
You can just use sparc64_defconfig, just make sure you enable support
for CGroups, Sun Partition tables and the Sun virtual disk and console
drivers as well as hypervisor support.
Also, make sure to disable kernel debugging support unless you need it.
>
> > * Which toolchain are you using?
>
> A toolchain built in Buildroot with GCC 13.2.0. Old kernel headers, but
> I only use it to build kernels. Do you think the kernel headers of the
> toolchain would play a role for vDSO?
FWIW, the latest toolchain is always available from kernel.org:
https://mirrors.edge.kernel.org/pub/tools/crosstool/
> > * This is a 64-bit userland?
>
> Yes.
Most if not all SPARC-V9-compatible distributions use a 64-bit userland these days.
>
Adrian
--
.''`. John Paul Adrian Glaubitz
: :' : Debian Developer
`. `' Physicist
`- GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-08-29 14:05 ` Thomas Weißschuh
@ 2025-08-29 16:35 ` Andreas Larsson
2025-08-29 17:07 ` Thomas Weißschuh
0 siblings, 1 reply; 40+ messages in thread
From: Andreas Larsson @ 2025-08-29 16:35 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, John Paul Adrian Glaubitz,
linux-kernel, sparclinux
On 2025-08-29 16:05, Thomas Weißschuh wrote:
> How are you currently building these kernels? Are you using the packaging
> from Debian and doing full rebuilds every time?
No, I cross build it separately with incremental builds for builtin stuff.
The modules are rebuilding every time however, I guess because I want to
have the git SHA in the version to not risk messing up which modules goes
with what kernel.
Then I scp over the image and modules and install in the Debian system.
> You can also build Debian binary packages directly from a git checkout with
> 'make bindeb-pkg'. This gives you nice incremental rebuilds.
>
> Another hunk to test, to see from where the SIGSEGV comes from.
>
> diff --git a/kernel/signal.c b/kernel/signal.c
> index e2c928de7d2c..0b2777e88f44 100644
> --- a/kernel/signal.c
> +++ b/kernel/signal.c
> @@ -1299,6 +1299,9 @@ force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t,
> struct k_sigaction *action;
> int sig = info->si_signo;
>
> + if (unlikely(is_global_init(t)) && sig == SIGSEGV)
> + panic("killing init");
> +
> spin_lock_irqsave(&t->sighand->siglock, flags);
> action = &t->sighand->action[sig-1];
> ignored = action->sa.sa_handler == SIG_IGN;
This results in:
[ 1.661344] Run /init as init process
[ 1.663057] Kernel panic - not syncing: killing init
[ 1.663077] CPU: 0 UID: 0 PID: 1 Comm: init Not tainted 6.17.0-rc1-00009-gc619bda6cd8d #10 VOLUNTARY
[ 1.663102] Call Trace:
[ 1.663113] [<0000000000436524>] dump_stack+0x8/0x18
[ 1.663138] [<00000000004291f4>] vpanic+0xdc/0x320
[ 1.663160] [<000000000042945c>] panic+0x24/0x30
[ 1.663176] [<0000000000493228>] force_sig_info_to_task+0x1e8/0x200
[ 1.663198] [<0000000000493700>] force_sig_fault+0x40/0x60
[ 1.663217] [<0000000000439e28>] sun4v_data_access_exception+0xa8/0x140
[ 1.663236] [<00000000004066d4>] sun4v_dacc+0x28/0x34
[ 1.663991] Press Stop-A (L1-A) from sun keyboard or send break
[ 1.663991] twice on console to return to the boot prom
[ 1.664010] ---[ end Kernel panic - not syncing: killing init ]---
> diff --git a/arch/sparc/vdso/vma.c b/arch/sparc/vdso/vma.c
> index 38a664d69782..efc3fef8f9bc 100644
> --- a/arch/sparc/vdso/vma.c
> +++ b/arch/sparc/vdso/vma.c
> @@ -25,7 +25,7 @@
> #include <vdso/datapage.h>
> #include <asm/vdso/vsyscall.h>
>
> -unsigned int __read_mostly vdso_enabled = 1;
> +unsigned int __read_mostly vdso_enabled = 0;
>
> #ifdef CONFIG_SPARC64
> static struct vm_special_mapping vdso_mapping64 = {
The analogue to this, booting with kernel parameter vdso=0,
makes the system boot fine.
> diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
> index 02ea19f67164..ae87888fef8a 100644
> --- a/lib/vdso/gettimeofday.c
> +++ b/lib/vdso/gettimeofday.c
> @@ -318,6 +318,8 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
> const struct vdso_clock *vc = vd->clock_data;
> u32 msk;
>
> + return false;
> +
> if (!vdso_clockid_valid(clock))
> return false;
This (independently) makes the system boot fine.
> diff --git a/arch/sparc/vdso/vdso.lds.S b/arch/sparc/vdso/vdso.lds.S
> index f3caa29a331c..a4669f7feada 100644
> --- a/arch/sparc/vdso/vdso.lds.S
> +++ b/arch/sparc/vdso/vdso.lds.S
> @@ -16,10 +16,7 @@
> VERSION {
> LINUX_2.6 {
> global:
> - clock_gettime;
> - __vdso_clock_gettime;
> - gettimeofday;
> - __vdso_gettimeofday;
> + __nothing;
> local: *;
> };
> }
I have not tried this one yet.
Cheers,
Andreas
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-08-29 16:35 ` Andreas Larsson
@ 2025-08-29 17:07 ` Thomas Weißschuh
2025-09-01 14:28 ` Andreas Larsson
0 siblings, 1 reply; 40+ messages in thread
From: Thomas Weißschuh @ 2025-08-29 17:07 UTC (permalink / raw)
To: Andreas Larsson
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, John Paul Adrian Glaubitz,
linux-kernel, sparclinux
On Fri, Aug 29, 2025 at 06:35:51PM +0200, Andreas Larsson wrote:
> On 2025-08-29 16:05, Thomas Weißschuh wrote:
> > How are you currently building these kernels? Are you using the packaging
> > from Debian and doing full rebuilds every time?
>
> No, I cross build it separately with incremental builds for builtin stuff.
> The modules are rebuilding every time however, I guess because I want to
> have the git SHA in the version to not risk messing up which modules goes
> with what kernel.
>
> Then I scp over the image and modules and install in the Debian system.
Ack.
> > You can also build Debian binary packages directly from a git checkout with
> > 'make bindeb-pkg'. This gives you nice incremental rebuilds.
> >
> > Another hunk to test, to see from where the SIGSEGV comes from.
> >
> > diff --git a/kernel/signal.c b/kernel/signal.c
> > index e2c928de7d2c..0b2777e88f44 100644
> > --- a/kernel/signal.c
> > +++ b/kernel/signal.c
> > @@ -1299,6 +1299,9 @@ force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t,
> > struct k_sigaction *action;
> > int sig = info->si_signo;
> >
> > + if (unlikely(is_global_init(t)) && sig == SIGSEGV)
> > + panic("killing init");
> > +
> > spin_lock_irqsave(&t->sighand->siglock, flags);
> > action = &t->sighand->action[sig-1];
> > ignored = action->sa.sa_handler == SIG_IGN;
>
> This results in:
>
> [ 1.661344] Run /init as init process
> [ 1.663057] Kernel panic - not syncing: killing init
> [ 1.663077] CPU: 0 UID: 0 PID: 1 Comm: init Not tainted 6.17.0-rc1-00009-gc619bda6cd8d #10 VOLUNTARY
> [ 1.663102] Call Trace:
> [ 1.663113] [<0000000000436524>] dump_stack+0x8/0x18
> [ 1.663138] [<00000000004291f4>] vpanic+0xdc/0x320
> [ 1.663160] [<000000000042945c>] panic+0x24/0x30
> [ 1.663176] [<0000000000493228>] force_sig_info_to_task+0x1e8/0x200
> [ 1.663198] [<0000000000493700>] force_sig_fault+0x40/0x60
> [ 1.663217] [<0000000000439e28>] sun4v_data_access_exception+0xa8/0x140
> [ 1.663236] [<00000000004066d4>] sun4v_dacc+0x28/0x34
> [ 1.663991] Press Stop-A (L1-A) from sun keyboard or send break
> [ 1.663991] twice on console to return to the boot prom
> [ 1.664010] ---[ end Kernel panic - not syncing: killing init ]---
What does this do?
diff --git a/kernel/signal.c b/kernel/signal.c
index e2c928de7d2c..6ae7afae948c 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1299,6 +1299,11 @@ force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t,
struct k_sigaction *action;
int sig = info->si_signo;
+ if (unlikely(is_global_init(t)) && sig == SIGSEGV)
+ panic("killing init, sig=%d errno=%d code=%d addr=%d vdso=%px",
+ info->si_signo, info->si_errno, info->si_code, info->si_addr,
+ t->mm->context.vdso);
+
spin_lock_irqsave(&t->sighand->siglock, flags);
action = &t->sighand->action[sig-1];
ignored = action->sa.sa_handler == SIG_IGN;
(...)
> > diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
> > index 02ea19f67164..ae87888fef8a 100644
> > --- a/lib/vdso/gettimeofday.c
> > +++ b/lib/vdso/gettimeofday.c
> > @@ -318,6 +318,8 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
> > const struct vdso_clock *vc = vd->clock_data;
> > u32 msk;
> >
> > + return false;
> > +
> > if (!vdso_clockid_valid(clock))
> > return false;
>
> This (independently) makes the system boot fine.
>
>
> > diff --git a/arch/sparc/vdso/vdso.lds.S b/arch/sparc/vdso/vdso.lds.S
> > index f3caa29a331c..a4669f7feada 100644
> > --- a/arch/sparc/vdso/vdso.lds.S
> > +++ b/arch/sparc/vdso/vdso.lds.S
> > @@ -16,10 +16,7 @@
> > VERSION {
> > LINUX_2.6 {
> > global:
> > - clock_gettime;
> > - __vdso_clock_gettime;
> > - gettimeofday;
> > - __vdso_gettimeofday;
> > + __nothing;
> > local: *;
> > };
> > }
>
> I have not tried this one yet.
If the above works, then this one is not necessary.
Thomas
^ permalink raw reply related [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-08-29 17:07 ` Thomas Weißschuh
@ 2025-09-01 14:28 ` Andreas Larsson
2025-09-01 14:59 ` Thomas Weißschuh
0 siblings, 1 reply; 40+ messages in thread
From: Andreas Larsson @ 2025-09-01 14:28 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, John Paul Adrian Glaubitz,
linux-kernel, sparclinux
On 2025-08-29 19:07, Thomas Weißschuh wrote:
> What does this do?
>
> diff --git a/kernel/signal.c b/kernel/signal.c
> index e2c928de7d2c..6ae7afae948c 100644
> --- a/kernel/signal.c
> +++ b/kernel/signal.c
> @@ -1299,6 +1299,11 @@ force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t,
> struct k_sigaction *action;
> int sig = info->si_signo;
>
> + if (unlikely(is_global_init(t)) && sig == SIGSEGV)
> + panic("killing init, sig=%d errno=%d code=%d addr=%d vdso=%px",
> + info->si_signo, info->si_errno, info->si_code, info->si_addr,
> + t->mm->context.vdso);
> +
> spin_lock_irqsave(&t->sighand->siglock, flags);
> action = &t->sighand->action[sig-1];
> ignored = action->sa.sa_handler == SIG_IGN;
This (with addr=%px) results in:
[ 2.073506] Run /init as init process
[ 2.076547] Kernel panic - not syncing: killing init, sig=11 errno=0 code=1 addr=0000000000000000 vdso=fff8000100384000
[ 2.076594] CPU: 7 UID: 0 PID: 1 Comm: init Not tainted 6.17.0-rc1-00010-gf63e40394cec #11 VOLUNTARY
[ 2.076620] Call Trace:
[ 2.076632] [<0000000000436524>] dump_stack+0x8/0x18
[ 2.076660] [<00000000004291f4>] vpanic+0xdc/0x320
[ 2.076682] [<000000000042945c>] panic+0x24/0x30
[ 2.076700] [<0000000000493240>] force_sig_info_to_task+0x200/0x220
[ 2.076726] [<0000000000493720>] force_sig_fault+0x40/0x60
[ 2.076747] [<0000000000439e28>] sun4v_data_access_exception+0xa8/0x140
[ 2.076770] [<00000000004066d4>] sun4v_dacc+0x28/0x34
[ 2.077940] Press Stop-A (L1-A) from sun keyboard or send break
[ 2.077940] twice on console to return to the boot prom
[ 2.077981] ---[ end Kernel panic - not syncing: killing init, sig=11 errno=0 code=1 addr=0000000000000000 vdso=fff8000100384000 ]---
Cheers,
Andreas
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-09-01 14:28 ` Andreas Larsson
@ 2025-09-01 14:59 ` Thomas Weißschuh
2025-09-01 19:05 ` Andreas Larsson
0 siblings, 1 reply; 40+ messages in thread
From: Thomas Weißschuh @ 2025-09-01 14:59 UTC (permalink / raw)
To: Andreas Larsson
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, John Paul Adrian Glaubitz,
linux-kernel, sparclinux
Hi Andreas,
thanks!
On Mon, Sep 01, 2025 at 04:28:52PM +0200, Andreas Larsson wrote:
> On 2025-08-29 19:07, Thomas Weißschuh wrote:
> > What does this do?
> >
> > diff --git a/kernel/signal.c b/kernel/signal.c
> > index e2c928de7d2c..6ae7afae948c 100644
> > --- a/kernel/signal.c
> > +++ b/kernel/signal.c
> > @@ -1299,6 +1299,11 @@ force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t,
> > struct k_sigaction *action;
> > int sig = info->si_signo;
> >
> > + if (unlikely(is_global_init(t)) && sig == SIGSEGV)
> > + panic("killing init, sig=%d errno=%d code=%d addr=%d vdso=%px",
> > + info->si_signo, info->si_errno, info->si_code, info->si_addr,
> > + t->mm->context.vdso);
> > +
> > spin_lock_irqsave(&t->sighand->siglock, flags);
> > action = &t->sighand->action[sig-1];
> > ignored = action->sa.sa_handler == SIG_IGN;
>
> This (with addr=%px) results in:
>
> [ 2.073506] Run /init as init process
> [ 2.076547] Kernel panic - not syncing: killing init, sig=11 errno=0 code=1 addr=0000000000000000 vdso=fff8000100384000
> [ 2.076594] CPU: 7 UID: 0 PID: 1 Comm: init Not tainted 6.17.0-rc1-00010-gf63e40394cec #11 VOLUNTARY
> [ 2.076620] Call Trace:
> [ 2.076632] [<0000000000436524>] dump_stack+0x8/0x18
> [ 2.076660] [<00000000004291f4>] vpanic+0xdc/0x320
> [ 2.076682] [<000000000042945c>] panic+0x24/0x30
> [ 2.076700] [<0000000000493240>] force_sig_info_to_task+0x200/0x220
> [ 2.076726] [<0000000000493720>] force_sig_fault+0x40/0x60
> [ 2.076747] [<0000000000439e28>] sun4v_data_access_exception+0xa8/0x140
> [ 2.076770] [<00000000004066d4>] sun4v_dacc+0x28/0x34
> [ 2.077940] Press Stop-A (L1-A) from sun keyboard or send break
> [ 2.077940] twice on console to return to the boot prom
> [ 2.077981] ---[ end Kernel panic - not syncing: killing init, sig=11 errno=0 code=1 addr=0000000000000000 vdso=fff8000100384000 ]---
So a NULL-pointer deref. Please also try the following, to get the trapping code.
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1299,6 +1299,14 @@ force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t,
struct k_sigaction *action;
int sig = info->si_signo;
+ if (unlikely(is_global_init(t)) && sig == SIGSEGV) {
+ struct pt_regs *regs = task_pt_regs(t);
+
+ panic("killing init, sig=%d errno=%d code=%d addr=%px vdso=%px pc=0x%lx vdsopc=0x%lx",
+ info->si_signo, info->si_errno, info->si_code, info->si_addr,
+ t->mm->context.vdso, regs->tpc, regs->tpc - (unsigned long)t->mm->context.vdso);
+ }
+
spin_lock_irqsave(&t->sighand->siglock, flags);
action = &t->sighand->action[sig-1];
ignored = action->sa.sa_handler == SIG_IGN;
Please give me the disassembly for the address printed as "vdsopc" from
arch/sparc/vdso/vdso64.so.dbg starting from its function entrypoint.
Thomas
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-08-29 10:52 ` Thomas Weißschuh
2025-08-29 15:24 ` John Paul Adrian Glaubitz
@ 2025-09-01 15:17 ` Arnd Bergmann
2025-09-02 6:21 ` Thomas Weißschuh
1 sibling, 1 reply; 40+ messages in thread
From: Arnd Bergmann @ 2025-09-01 15:17 UTC (permalink / raw)
To: Thomas Weißschuh, John Paul Adrian Glaubitz
Cc: Andreas Larsson, Andy Lutomirski, Thomas Gleixner,
Vincenzo Frascino, David S . Miller, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, linux-kernel, sparclinux
On Fri, Aug 29, 2025, at 12:52, Thomas Weißschuh wrote:
> On Fri, Aug 29, 2025 at 12:40:59PM +0200, John Paul Adrian Glaubitz wrote:
>> On Fri, 2025-08-29 at 12:37 +0200, Thomas Weißschuh wrote:
>> > In the meantime I installed a full Debian, but the bug is still not
>> > reproducible in QEMU.
>>
>> Please keep in mind that QEMU emulates sun4u (on UltraSPARC II) while
>> Andreas was testing on sun4v (on Niagara 4). There might be differences.
>
> I am aware. Unfortuntely I don't have anything else available.
> If anybody could test this on real sun4u that would be great.
> Or teach me how to use sun4v QEMU without it crashing on me.
> In the past you offered access to a physical machine.
> Does this offer still stand? Does it also run into the bug?
It should be enough to set the cpu to a different type. As far
as I can tell, the three different cases are all determined by the
MMU/CPU ID, not the platform type (sun4u/sun4v).
As far as I can tell, the options are:
- JPS1 (UltraSPARCIII, SPARC64 V) and later use modern 'stick' operations
- UltraSparc IIe (Hummingbird) uses 'hbtick' without VDSO
- All other plain V9 implementations use 'tick'
To test all three cases, it should be enough to run qemu with e.g.
"-cpu Sun-UltraSparc-IV", "-cpu TI-UltraSparc-IIe", and
"-cpu TI-UltraSparc-II", respectively.
Arnd
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-09-01 14:59 ` Thomas Weißschuh
@ 2025-09-01 19:05 ` Andreas Larsson
0 siblings, 0 replies; 40+ messages in thread
From: Andreas Larsson @ 2025-09-01 19:05 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Arnd Bergmann, David S. Miller, Nagarathnam Muthusamy,
Nick Alcock, John Stultz, Stephen Boyd, John Paul Adrian Glaubitz,
linux-kernel, sparclinux
On 2025-09-01 16:59, Thomas Weißschuh wrote:
> So a NULL-pointer deref. Please also try the following, to get the trapping code.
>
> --- a/kernel/signal.c
> +++ b/kernel/signal.c
> @@ -1299,6 +1299,14 @@ force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t,
> struct k_sigaction *action;
> int sig = info->si_signo;
>
> + if (unlikely(is_global_init(t)) && sig == SIGSEGV) {
> + struct pt_regs *regs = task_pt_regs(t);
> +
> + panic("killing init, sig=%d errno=%d code=%d addr=%px vdso=%px pc=0x%lx vdsopc=0x%lx",
> + info->si_signo, info->si_errno, info->si_code, info->si_addr,
> + t->mm->context.vdso, regs->tpc, regs->tpc - (unsigned long)t->mm->context.vdso);
> + }
> +
> spin_lock_irqsave(&t->sighand->siglock, flags);
> action = &t->sighand->action[sig-1];
> ignored = action->sa.sa_handler == SIG_IGN;
>
>
> Please give me the disassembly for the address printed as "vdsopc" from
> arch/sparc/vdso/vdso64.so.dbg starting from its function entrypoint.
I get
[ 1.680341] Run /init as init process
[ 1.682256] Kernel panic - not syncing: killing init, sig=11 errno=0 code=1 addr=0000000000000000 vdso=fff800010081e000 pc=0xfff800010081e684 vdsopc=0x684
[ 1.682289] CPU: 2 UID: 0 PID: 1 Comm: init Not tainted 6.17.0-rc1-00011-g1f71a73bede3 #12 VOLUNTARY
[ 1.682313] Call Trace:
[ 1.682324] [<0000000000436524>] dump_stack+0x8/0x18
[ 1.682351] [<00000000004291f4>] vpanic+0xdc/0x320
[ 1.682373] [<000000000042945c>] panic+0x24/0x30
[ 1.682389] [<0000000000493258>] force_sig_info_to_task+0x218/0x240
[ 1.682412] [<0000000000493740>] force_sig_fault+0x40/0x60
[ 1.682430] [<0000000000439e28>] sun4v_data_access_exception+0xa8/0x140
[ 1.682449] [<00000000004066d4>] sun4v_dacc+0x28/0x34
[ 1.683232] Press Stop-A (L1-A) from sun keyboard or send break
[ 1.683232] twice on console to return to the boot prom
[ 1.683252] ---[ end Kernel panic - not syncing: killing init, sig=11 errno=0 code=1 addr=0000000000000000 vdso=fff800010081e000 pc=0xfff800010081e684 vdsopc=0x684 ]---
and we have
#if defined(CONFIG_SPARC64)
int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts)
{
640: 9d e3 bf 50 save %sp, -176, %sp
__asm__ __volatile__(
644: 40 00 00 03 call 650 <__vdso_clock_gettime+0x10>
648: 01 00 00 00 nop
64c: ff ff 79 b4 unknown
650: 9e 03 e0 08 add %o7, 8, %o7
654: c6 43 c0 00 ldsw [ %o7 ], %g3
658: 86 00 c0 0f add %g3, %o7, %g3
if (!vdso_clockid_valid(clock))
65c: 80 a6 20 17 cmp %i0, 0x17
660: 18 40 00 3b bgu,pn %icc, 74c <__vdso_clock_gettime+0x10c>
664: 84 10 00 03 mov %g3, %g2
msk = 1U << clock;
668: 82 10 20 01 mov 1, %g1
66c: 83 28 40 18 sll %g1, %i0, %g1
if (likely(msk & VDSO_HRES))
670: 80 88 68 83 btst 0x883, %g1
674: 02 40 00 30 be,pn %icc, 734 <__vdso_clock_gettime+0xf4>
678: 80 88 60 60 btst 0x60, %g1
if (!__arch_vdso_hres_capable())
67c: 87 2e 30 04 sllx %i0, 4, %g3
680: 86 00 80 03 add %g2, %g3, %g3
while (unlikely((seq = READ_ONCE(vc->seq)) & 1)) {
684: fa 00 80 00 ld [ %g2 ], %i5 <-- this one
688: 80 8f 60 01 btst 1, %i5
68c: 12 60 00 39 bne,pn %xcc, 770 <__vdso_clock_gettime+0x130>
690: 01 00 00 00 nop
...
where the READ_ONCE that does the trapping load is the READ_ONCE(vc->seq)
in do_hres() in lib/vdso/gettimeofday.c. So we seem to have a NULL vc.
With patches 1-8 applied on v6.17-rc1, addr2line gives us:
0x640: arch/sparc/vdso/vclock_gettime.c:34
0x644: arch/sparc/include/asm/vdso/gettimeofday.h:150
0x648: arch/sparc/include/asm/vdso/gettimeofday.h:150
0x64c: arch/sparc/include/asm/vdso/gettimeofday.h:150
0x650: arch/sparc/include/asm/vdso/gettimeofday.h:150
0x654: arch/sparc/include/asm/vdso/gettimeofday.h:150
0x658: arch/sparc/include/asm/vdso/gettimeofday.h:150
0x65c: lib/vdso/gettimeofday.c:321 (discriminator 1)
0x660: lib/vdso/gettimeofday.c:321 (discriminator 1)
0x664: lib/vdso/gettimeofday.c:321 (discriminator 1)
0x668: lib/vdso/gettimeofday.c:328
0x66c: lib/vdso/gettimeofday.c:328
0x670: lib/vdso/gettimeofday.c:329 (discriminator 1)
0x674: lib/vdso/gettimeofday.c:329 (discriminator 1)
0x678: lib/vdso/gettimeofday.c:329 (discriminator 1)
0x67c: lib/vdso/gettimeofday.c:175
0x680: lib/vdso/gettimeofday.c:175
0x684: lib/vdso/gettimeofday.c:190 (discriminator 2)
Cheers,
Andreas
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
2025-09-01 15:17 ` Arnd Bergmann
@ 2025-09-02 6:21 ` Thomas Weißschuh
0 siblings, 0 replies; 40+ messages in thread
From: Thomas Weißschuh @ 2025-09-02 6:21 UTC (permalink / raw)
To: Arnd Bergmann
Cc: John Paul Adrian Glaubitz, Andreas Larsson, Andy Lutomirski,
Thomas Gleixner, Vincenzo Frascino, David S . Miller,
Nagarathnam Muthusamy, Nick Alcock, John Stultz, Stephen Boyd,
linux-kernel, sparclinux
On Mon, Sep 01, 2025 at 05:17:13PM +0200, Arnd Bergmann wrote:
> On Fri, Aug 29, 2025, at 12:52, Thomas Weißschuh wrote:
> > On Fri, Aug 29, 2025 at 12:40:59PM +0200, John Paul Adrian Glaubitz wrote:
> >> On Fri, 2025-08-29 at 12:37 +0200, Thomas Weißschuh wrote:
> >> > In the meantime I installed a full Debian, but the bug is still not
> >> > reproducible in QEMU.
> >>
> >> Please keep in mind that QEMU emulates sun4u (on UltraSPARC II) while
> >> Andreas was testing on sun4v (on Niagara 4). There might be differences.
> >
> > I am aware. Unfortuntely I don't have anything else available.
> > If anybody could test this on real sun4u that would be great.
> > Or teach me how to use sun4v QEMU without it crashing on me.
> > In the past you offered access to a physical machine.
> > Does this offer still stand? Does it also run into the bug?
>
> It should be enough to set the cpu to a different type. As far
> as I can tell, the three different cases are all determined by the
> MMU/CPU ID, not the platform type (sun4u/sun4v).
>
> As far as I can tell, the options are:
>
> - JPS1 (UltraSPARCIII, SPARC64 V) and later use modern 'stick' operations
> - UltraSparc IIe (Hummingbird) uses 'hbtick' without VDSO
> - All other plain V9 implementations use 'tick'
>
> To test all three cases, it should be enough to run qemu with e.g.
> "-cpu Sun-UltraSparc-IV", "-cpu TI-UltraSparc-IIe", and
> "-cpu TI-UltraSparc-II", respectively.
Sun-UltraSparc-IV and TI-UltraSparc-IIe don't boot for me with either my
Debian-derived config nor sparc64_defconfig, for details see below.
But looking at Andreas' reports, the issue is not in the tick reading but my
asm implementation of __arch_get_vdso_u_time_data().
Sun-UltraSparc-IV dies in the second instruction of cheetah_generic_boot:
OpenBIOS for Sparc64
Configuration device id QEMU version 1 machine id 0
kernel phys 404000 virt 40004000 size 0x1358650
initrd phys 175a000 virt 40c00000 size 0x1727675
kernel cmdline root=UUID=ac350b43-e843-40ad-bd55-ec4c2eaeb468
CPUs: 1 x SUNW,UltraSPARC-IV
UUID: 00000000-0000-0000-0000-000000000000
Welcome to OpenBIOS v1.1 built on Sep 24 2024 19:56
Type 'help' for detailed information
[sparc64] Kernel already loaded
Unhandled Exception 0x0000000000000032
PC = 0x0000000040004654 NPC = 0x0000000040004658
Stopping execution
QEMU debugging:
533: Data Access Error (v=0032)
pc: 0000000040004654 npc: 0000000040004658
%g0-3: 0000000000000000 0018310005070000 0000000000000076 0000000000000048
%g4-7: 0000000000000075 00000000ffe81000 0000000000000000 0000000000000018
%o0-3: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
%o4-7: 00000000ffd0d904 00000000ffecb5e0 00000000ffecafc1 0000000040004398
%l0-3: 0000000040004190 0000000000000036 0000000000000000 0000000000400000
%l4-7: 00000000003fffff 00000000fef84930 0000000000000000 00000000ffd0d904
%i0-3: 0000000000000000 0000000000000000 0000000000000000 00000000ffeb5400
%i4-7: 00000000ffd85800 0000000000000000 00000000ffecb071 00000000ffd0e8c8
pstate: 00000016 ccr: 00 (icc: ---- xcc: ----) asi: 00 tl: 0 pil: 0 gl: 2
tbr: 00000000ffd00000 hpstate: 0000000000000000 htba: 0000000000000000
cansave: 6 canrestore: 0 otherwin: 0 wstate: 0 cleanwin: 7 cwp: 5
fsr: 0000000000000000 y: 0000000000000000 fprs: 0000000000000000
Disassembly:
0000000000404650 <cheetah_generic_boot>:
; mov TSB_EXTENSION_P, %g3
404650: 86 10 20 48 mov 72, %g3
; stxa %g0, [%g3] ASI_DMMU
404654: c0 f0 cb 00 stxa %g0, [%g3] 88
; stxa %g0, [%g3] ASI_IMMU
404658: c0 f0 ca 00 stxa %g0, [%g3] 80
; membar #Sync
40465c: 81 43 e0 40 membar #Sync
; mov TSB_EXTENSION_S, %g3
404660: 86 10 20 50 mov 80, %g3
; stxa %g0, [%g3] ASI_DMMU
404664: c0 f0 cb 00 stxa %g0, [%g3] 88
; membar #Sync
404668: 81 43 e0 40 membar #Sync
; mov TSB_EXTENSION_N, %g3
40466c: 86 10 20 58 mov 88, %g3
; stxa %g0, [%g3] ASI_DMMU
404670: c0 f0 cb 00 stxa %g0, [%g3] 88
; stxa %g0, [%g3] ASI_IMMU
404674: c0 f0 ca 00 stxa %g0, [%g3] 80
; membar #Sync
404678: 81 43 e0 40 membar #Sync
; ba,a,pt %xcc, jump_to_sun4u_init
40467c: 30 68 00 04 ba,a %xcc, 4
TI-UltraSparc-IIe dies in a division by zero in init_tick_ops:
OpenBIOS for Sparc64
Configuration device id QEMU version 1 machine id 0
kernel phys 404000 virt 40004000 size 0x1358650
initrd phys 175a000 virt 40c00000 size 0x1727675
kernel cmdline root=UUID=ac350b43-e843-40ad-bd55-ec4c2eaeb468
CPUs: 1 x SUNW,UltraSPARC-IIe
UUID: 00000000-0000-0000-0000-000000000000
Welcome to OpenBIOS v1.1 built on Sep 24 2024 19:56
Type 'help' for detailed information
[sparc64] Kernel already loaded
Unhandled Exception 0x0000000000000028
PC = 0x00000000015f4444 NPC = 0x00000000015f4448
Stopping execution
QEMU debugging:
892: Division By Zero (v=0028)
pc: 00000000015f4444 npc: 00000000015f4448
%g0-3: 0000000000000000 00000000ffffffff 000000ee6b280000 0000000000441400
%g4-7: 0000000001456280 0000000000000000 0000000001434000 0000000000000000
%o0-3: 0000000000000000 0000000000000000 ffffffffffffffff 00000000012c2d08
%o4-7: 0000000000000000 0000000001757c00 0000000001437491 00000000015f4418
%l0-3: 0000000001757c00 00000000ffe80dc8 00000000ffd84c00 00000000ffecb7bb
%l4-7: 0000000000000000 00000000ffeb5400 000000000000ffff 0000000000000000
%i0-3: 0000000001444c98 000000000000000d 0000000001757c00 0000000000000000
%i4-7: 0000000000000000 000000ee6b280000 0000000001437541 00000000015f4610
pstate: 00000016 ccr: 44 (icc: -Z-- xcc: -Z--) asi: 80 tl: 0 pil: 0 gl: 2
tbr: 00000000ffd00000 hpstate: 0000000000000000 htba: 0000000000000000
cansave: 6 canrestore: 0 otherwin: 0 wstate: 0 cleanwin: 7 cwp: 0
fsr: 0000000000000000 y: 0000000000000000 fprs: 0000000000000000
Disassembly:
00000000015f4410 <init_tick_ops>:
; {
15f4410: 9d e3 bf 50 save %sp, -176, %sp
; freq = ops->get_frequency();
15f4414: c2 5e 20 40 ldx [%i0+64], %g1
15f4418: 9f c0 40 00 call %g1
15f441c: 01 00 00 00 nop
; do_div(tmp, freq);
15f4420: 82 10 3f ff mov -1, %g1
; tmp += freq/2; /* round for do_div */
15f4424: 05 1d cd 65 sethi 1953125, %g2
; tick = ops->get_tick();
15f4428: c6 5e 20 10 ldx [%i0+16], %g3
; do_div(tmp, freq);
15f442c: 83 30 70 20 srlx %g1, 32, %g1
; tmp += freq/2; /* round for do_div */
15f4430: 85 28 b0 09 sllx %g2, 9, %g2
15f4434: bb 32 20 01 srl %o0, 1, %i5
; do_div(tmp, freq);
15f4438: 8e 0a 00 01 and %o0, %g1, %g7
; tmp += freq/2; /* round for do_div */
15f443c: ba 07 40 02 add %i5, %g2, %i5
; freq = ops->get_frequency();
15f4440: b8 10 00 08 mov %o0, %i4
; do_div(tmp, freq);
15f4444: ba 6f 40 07 udivx %i5, %g7, %i5
...
^ permalink raw reply [flat|nested] 40+ messages in thread
end of thread, other threads:[~2025-09-02 6:22 UTC | newest]
Thread overview: 40+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-15 10:41 [PATCH v2 00/13] sparc64: vdso: Switch to generic vDSO library Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 01/13] vdso: Add struct __kernel_old_timeval forward declaration to gettime.h Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 02/13] sparc64: vdso: Link with -z noexecstack Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 03/13] sparc64: vdso: Remove obsolete "fake section table" reservation Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 04/13] sparc64: vdso: Replace code patching with runtime conditional Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 05/13] sparc64: vdso: Move hardware counter read into header Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 06/13] sparc64: vdso: Move syscall fallbacks " Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 07/13] sparc64: vdso: Introduce vdso/processor.h Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library Thomas Weißschuh
2025-08-25 15:55 ` Andreas Larsson
2025-08-26 5:56 ` Thomas Weißschuh
2025-08-28 15:38 ` Andreas Larsson
2025-08-29 10:02 ` Andreas Larsson
2025-08-29 10:37 ` Thomas Weißschuh
2025-08-29 10:40 ` John Paul Adrian Glaubitz
2025-08-29 10:52 ` Thomas Weißschuh
2025-08-29 15:24 ` John Paul Adrian Glaubitz
2025-09-01 15:17 ` Arnd Bergmann
2025-09-02 6:21 ` Thomas Weißschuh
2025-08-29 13:41 ` Andreas Larsson
2025-08-29 13:51 ` Thomas Weißschuh
2025-08-29 14:05 ` Thomas Weißschuh
2025-08-29 16:35 ` Andreas Larsson
2025-08-29 17:07 ` Thomas Weißschuh
2025-09-01 14:28 ` Andreas Larsson
2025-09-01 14:59 ` Thomas Weißschuh
2025-09-01 19:05 ` Andreas Larsson
2025-08-29 15:44 ` John Paul Adrian Glaubitz
2025-08-15 10:41 ` [PATCH v2 09/13] sparc64: vdso2c: Drop sym_vvar_start handling Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 10/13] sparc64: vdso2c: Remove symbol handling Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 11/13] sparc64: vdso: Implement clock_gettime64() Thomas Weißschuh
2025-08-15 10:41 ` [PATCH v2 12/13] sparc64: vdso: Implement clock_getres() Thomas Weißschuh
2025-08-15 12:13 ` Arnd Bergmann
2025-08-15 12:34 ` Thomas Weißschuh
2025-08-15 20:09 ` Arnd Bergmann
2025-08-18 5:50 ` Thomas Weißschuh
2025-08-18 6:54 ` Arnd Bergmann
2025-08-18 13:00 ` Thomas Weißschuh
2025-08-18 13:17 ` Arnd Bergmann
2025-08-15 10:41 ` [PATCH v2 13/13] clocksource: remove ARCH_CLOCKSOURCE_DATA Thomas Weißschuh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).