[PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library

Thomas Weißschuh posted 13 patches 1 month, 2 weeks ago
[PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
Posted by Thomas Weißschuh 1 month, 2 weeks ago
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

Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
Posted by Andreas Larsson 1 month, 1 week ago
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

Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
Posted by Thomas Weißschuh 1 month, 1 week ago
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
Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
Posted by Andreas Larsson 1 month ago
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
Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
Posted by Andreas Larsson 1 month ago
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
Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
Posted by Thomas Weißschuh 1 month ago
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;
Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
Posted by Andreas Larsson 1 month ago
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

Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
Posted by John Paul Adrian Glaubitz 1 month ago
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
Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
Posted by Thomas Weißschuh 1 month ago
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
Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
Posted by Andreas Larsson 1 month ago
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

Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
Posted by Thomas Weißschuh 1 month ago
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
Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
Posted by Andreas Larsson 1 month ago
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

Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
Posted by Thomas Weißschuh 1 month ago
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
Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
Posted by Andreas Larsson 1 month ago
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
Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
Posted by Thomas Weißschuh 1 month ago
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!
Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
Posted by John Paul Adrian Glaubitz 1 month ago
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
Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
Posted by Thomas Weißschuh 1 month ago
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?
Re: [PATCH v2 08/13] sparc64: vdso: Switch to the generic vDSO library
Posted by John Paul Adrian Glaubitz 1 month ago
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