* [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock
@ 2025-03-03 11:11 Thomas Weißschuh
2025-03-03 11:11 ` Thomas Weißschuh
` (19 more replies)
0 siblings, 20 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be an array of it.
This series is based on and intended to be merged through tip/timers/vdso.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
Anna-Maria Behnsen (15):
vdso: Make vdso_time_data cacheline aligned
vdso/datapage: Define for vdso_data to make rework of vdso possible
vdso/helpers: Prepare introduction of struct vdso_clock
vdso/gettimeofday: Prepare introduction of struct vdso_clock
vdso/gettimeofday: Prepare do_hres() for introduction of struct vdso_clock
vdso/gettimeofday: Prepare do_hres_timens() for introduction of struct vdso_clock
vdso/gettimeofday: Prepare do_coarse() for introduction of struct vdso_clock
vdso/gettimeofday: Prepare do_coarse_timens() for introduction of struct vdso_clock
vdso/gettimeofday: Prepare helper functions for introduction of struct vdso_clock
vdso/vsyscall: Prepare introduction of struct vdso_clock
vdso/namespace: Rename timens_setup_vdso_data() to reflect new vdso_clock struct
time/namespace: Prepare introduction of struct vdso_clock
x86/vdso: Prepare introduction of struct vdso_clock
vdso: Move arch related data before basetime
vdso: Rework struct vdso_time_data and introduce struct vdso_clock
Nam Cao (2):
arm64/vdso: Prepare introduction of struct vdso_clock
powerpc/vdso: Prepare introduction of struct vdso_clock
Thomas Weißschuh (2):
vdso: Introduce vdso/cache.h
arm64: Make asm/cache.h compatible with vDSO
arch/arm64/include/asm/cache.h | 4 +-
arch/arm64/include/asm/vdso/compat_gettimeofday.h | 6 +-
arch/arm64/include/asm/vdso/vsyscall.h | 4 +-
arch/powerpc/include/asm/vdso/gettimeofday.h | 2 +-
arch/s390/kernel/time.c | 11 +-
arch/x86/include/asm/vdso/gettimeofday.h | 16 +--
include/asm-generic/vdso/vsyscall.h | 2 +-
include/linux/cache.h | 9 +-
include/vdso/cache.h | 15 +++
include/vdso/datapage.h | 48 ++++---
include/vdso/helpers.h | 20 +--
kernel/time/namespace.c | 20 +--
kernel/time/vsyscall.c | 47 +++----
lib/vdso/datastore.c | 6 +-
lib/vdso/gettimeofday.c | 146 ++++++++++++----------
15 files changed, 196 insertions(+), 160 deletions(-)
---
base-commit: ac1a42f4e4e296b5ba5fdb39444f65d6e5196240
change-id: 20250224-vdso-clock-f10f017c4b80
Best regards,
--
Thomas Weißschuh <thomas.weissschuh@linutronix.de>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 01/19] vdso: Introduce vdso/cache.h Thomas Weißschuh
` (18 subsequent siblings)
19 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be an array of it.
This series is based on and intended to be merged through tip/timers/vdso
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 01/19] vdso: Introduce vdso/cache.h
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
2025-03-03 11:11 ` Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 02/19] arm64: Make asm/cache.h compatible with vDSO Thomas Weißschuh
` (17 subsequent siblings)
19 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
The vDSO implementation can only include headers from the vdso/
namespace. To enable the usage of ____cacheline_aligned from
the vDSO, move it and its dependencies into a new header vdso/cache.h.
Keep compatibility by including vdso/cache.h from linux/cache.h.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
include/linux/cache.h | 9 +--------
include/vdso/cache.h | 15 +++++++++++++++
2 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/include/linux/cache.h b/include/linux/cache.h
index ca2a05682a54b51af991154a99f57a00c88fc5a8..e69768f50d5327b874ba4bd56609300526511a69 100644
--- a/include/linux/cache.h
+++ b/include/linux/cache.h
@@ -3,16 +3,13 @@
#define __LINUX_CACHE_H
#include <uapi/linux/kernel.h>
+#include <vdso/cache.h>
#include <asm/cache.h>
#ifndef L1_CACHE_ALIGN
#define L1_CACHE_ALIGN(x) __ALIGN_KERNEL(x, L1_CACHE_BYTES)
#endif
-#ifndef SMP_CACHE_BYTES
-#define SMP_CACHE_BYTES L1_CACHE_BYTES
-#endif
-
/**
* SMP_CACHE_ALIGN - align a value to the L2 cacheline size
* @x: value to align
@@ -63,10 +60,6 @@
#define __ro_after_init __section(".data..ro_after_init")
#endif
-#ifndef ____cacheline_aligned
-#define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
-#endif
-
#ifndef ____cacheline_aligned_in_smp
#ifdef CONFIG_SMP
#define ____cacheline_aligned_in_smp ____cacheline_aligned
diff --git a/include/vdso/cache.h b/include/vdso/cache.h
new file mode 100644
index 0000000000000000000000000000000000000000..f89d48304bf8f101df581aee0e32a2efa9d2fb2d
--- /dev/null
+++ b/include/vdso/cache.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __VDSO_CACHE_H
+#define __VDSO_CACHE_H
+
+#include <asm/cache.h>
+
+#ifndef SMP_CACHE_BYTES
+#define SMP_CACHE_BYTES L1_CACHE_BYTES
+#endif
+
+#ifndef ____cacheline_aligned
+#define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
+#endif
+
+#endif /* __VDSO_ALIGN_H */
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 02/19] arm64: Make asm/cache.h compatible with vDSO
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 01/19] vdso: Introduce vdso/cache.h Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 03/19] vdso: Make vdso_time_data cacheline aligned Thomas Weißschuh
` (16 subsequent siblings)
19 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
asm/cache.h can be used during the vDSO build through vdso/cache.h.
Not all definitions in it are compatible with the vDSO, especially the
compat vDSO.
Hide the more complex definitions from the vDSO build.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
arch/arm64/include/asm/cache.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h
index 06a4670bdb0b9b7552d553cee3cc70a6e15b2b93..99cd6546e72e35cfbceec7ce0a0f64498dfadd38 100644
--- a/arch/arm64/include/asm/cache.h
+++ b/arch/arm64/include/asm/cache.h
@@ -35,7 +35,7 @@
#define ARCH_DMA_MINALIGN (128)
#define ARCH_KMALLOC_MINALIGN (8)
-#ifndef __ASSEMBLY__
+#if !defined(__ASSEMBLY__) && !defined(BUILD_VDSO)
#include <linux/bitops.h>
#include <linux/kasan-enabled.h>
@@ -118,6 +118,6 @@ static inline u32 __attribute_const__ read_cpuid_effective_cachetype(void)
return ctr;
}
-#endif /* __ASSEMBLY__ */
+#endif /* !defined(__ASSEMBLY__) && !defined(BUILD_VDSO) */
#endif
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 03/19] vdso: Make vdso_time_data cacheline aligned
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
` (2 preceding siblings ...)
2025-03-03 11:11 ` [PATCH 02/19] arm64: Make asm/cache.h compatible with vDSO Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 04/19] vdso/datapage: Define for vdso_data to make rework of vdso possible Thomas Weißschuh
` (15 subsequent siblings)
19 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Anna-Maria Behnsen <anna-maria@linutronix.de>
vdso_time_data is not cacheline aligned at the moment. When instantiating
an array, the start of the second array member is not cache line aligned.
This increases the number of the required cache lines which needs to be
read when handling e.g. CLOCK_MONOTONIC_RAW, because the data spawns an
extra cache line if the previous data does not end at a cache line
boundary.
Therefore make struct vdso_time_data cacheline aligned.
Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
include/vdso/datapage.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index ed4fb4c06e3ee6423fe68ccb476565213f234863..dfd98f969f151eca3c551c3e90f69af9ee8f22bb 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -11,6 +11,7 @@
#include <vdso/align.h>
#include <vdso/bits.h>
+#include <vdso/cache.h>
#include <vdso/clocksource.h>
#include <vdso/ktime.h>
#include <vdso/limits.h>
@@ -126,7 +127,7 @@ struct vdso_time_data {
u32 __unused;
struct arch_vdso_time_data arch_data;
-};
+} ____cacheline_aligned;
/**
* struct vdso_rng_data - vdso RNG state information
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 04/19] vdso/datapage: Define for vdso_data to make rework of vdso possible
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
` (3 preceding siblings ...)
2025-03-03 11:11 ` [PATCH 03/19] vdso: Make vdso_time_data cacheline aligned Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 05/19] vdso/helpers: Prepare introduction of struct vdso_clock Thomas Weißschuh
` (14 subsequent siblings)
19 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Anna-Maria Behnsen <anna-maria@linutronix.de>
PTP clocks could also be supported by the vdso to use the advantages of
this implementation. Therefore the struct must be reworked. For a
transition to the new structure of the vdso, add a define which maps
vdso_clock to vdso_data. This will be removed when all users are updated
step by step.
No functional change.
Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
include/vdso/datapage.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index dfd98f969f151eca3c551c3e90f69af9ee8f22bb..1df22e8bb9b31153546b72b1e8b8c8aeaed7d9e3 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -129,6 +129,8 @@ struct vdso_time_data {
struct arch_vdso_time_data arch_data;
} ____cacheline_aligned;
+#define vdso_clock vdso_time_data
+
/**
* struct vdso_rng_data - vdso RNG state information
* @generation: counter representing the number of RNG reseeds
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 05/19] vdso/helpers: Prepare introduction of struct vdso_clock
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
` (4 preceding siblings ...)
2025-03-03 11:11 ` [PATCH 04/19] vdso/datapage: Define for vdso_data to make rework of vdso possible Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 06/19] vdso/gettimeofday: " Thomas Weißschuh
` (13 subsequent siblings)
19 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Anna-Maria Behnsen <anna-maria@linutronix.de>
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be array of it. By now, vdso_clock is
simply a define which maps vdso_clock to vdso_time_data.
Prepare all functions which need the pointer to the vdso_clock array to
work well after the structures get reworked. Replace struct vdso_time_data
pointer with struct vdso_clock pointer whenever applicable.
No functional change.
Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
include/vdso/helpers.h | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/include/vdso/helpers.h b/include/vdso/helpers.h
index 41c3087070c7ab21d7adec04e6cd30c4b32ea221..28f0707a46c62187ad7500543e169f5b99deee70 100644
--- a/include/vdso/helpers.h
+++ b/include/vdso/helpers.h
@@ -7,49 +7,53 @@
#include <asm/barrier.h>
#include <vdso/datapage.h>
-static __always_inline u32 vdso_read_begin(const struct vdso_time_data *vd)
+static __always_inline u32 vdso_read_begin(const struct vdso_clock *vc)
{
u32 seq;
- while (unlikely((seq = READ_ONCE(vd->seq)) & 1))
+ while (unlikely((seq = READ_ONCE(vc->seq)) & 1))
cpu_relax();
smp_rmb();
return seq;
}
-static __always_inline u32 vdso_read_retry(const struct vdso_time_data *vd,
+static __always_inline u32 vdso_read_retry(const struct vdso_clock *vc,
u32 start)
{
u32 seq;
smp_rmb();
- seq = READ_ONCE(vd->seq);
+ seq = READ_ONCE(vc->seq);
return seq != start;
}
static __always_inline void vdso_write_begin(struct vdso_time_data *vd)
{
+ struct vdso_clock *vc = vd;
+
/*
* WRITE_ONCE() is required otherwise the compiler can validly tear
* updates to vd[x].seq and it is possible that the value seen by the
* reader is inconsistent.
*/
- WRITE_ONCE(vd[CS_HRES_COARSE].seq, vd[CS_HRES_COARSE].seq + 1);
- WRITE_ONCE(vd[CS_RAW].seq, vd[CS_RAW].seq + 1);
+ WRITE_ONCE(vc[CS_HRES_COARSE].seq, vc[CS_HRES_COARSE].seq + 1);
+ WRITE_ONCE(vc[CS_RAW].seq, vc[CS_RAW].seq + 1);
smp_wmb();
}
static __always_inline void vdso_write_end(struct vdso_time_data *vd)
{
+ struct vdso_clock *vc = vd;
+
smp_wmb();
/*
* WRITE_ONCE() is required otherwise the compiler can validly tear
* updates to vd[x].seq and it is possible that the value seen by the
* reader is inconsistent.
*/
- WRITE_ONCE(vd[CS_HRES_COARSE].seq, vd[CS_HRES_COARSE].seq + 1);
- WRITE_ONCE(vd[CS_RAW].seq, vd[CS_RAW].seq + 1);
+ WRITE_ONCE(vc[CS_HRES_COARSE].seq, vc[CS_HRES_COARSE].seq + 1);
+ WRITE_ONCE(vc[CS_RAW].seq, vc[CS_RAW].seq + 1);
}
#endif /* !__ASSEMBLY__ */
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 06/19] vdso/gettimeofday: Prepare introduction of struct vdso_clock
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
` (5 preceding siblings ...)
2025-03-03 11:11 ` [PATCH 05/19] vdso/helpers: Prepare introduction of struct vdso_clock Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 07/19] vdso/gettimeofday: Prepare do_hres() for " Thomas Weißschuh
` (12 subsequent siblings)
19 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Anna-Maria Behnsen <anna-maria@linutronix.de>
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be array of it. At the moment, vdso_clock
is simply a define which maps vdso_clock to vdso_time_data.
Prepare all functions which need the pointer to the vdso_clock array to
work well after introducing the new struct. Whenever applicable, struct
vdso_time_data pointer is replaced by struct vdso_clock pointer.
No functional change.
Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
lib/vdso/gettimeofday.c | 24 +++++++++++++++---------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 299f027116ee0e50a69c5a8a17218004e4af0ea1..59369a4e9f25f937eb8d9aed3201ebd340097a9d 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -257,6 +257,7 @@ static __always_inline int
__cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *ts)
{
+ const struct vdso_clock *vc = vd;
u32 msk;
/* Check for negative values or invalid clocks */
@@ -269,15 +270,15 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
*/
msk = 1U << clock;
if (likely(msk & VDSO_HRES))
- vd = &vd[CS_HRES_COARSE];
+ vc = &vc[CS_HRES_COARSE];
else if (msk & VDSO_COARSE)
- return do_coarse(&vd[CS_HRES_COARSE], clock, ts);
+ return do_coarse(&vc[CS_HRES_COARSE], clock, ts);
else if (msk & VDSO_RAW)
- vd = &vd[CS_RAW];
+ vc = &vc[CS_RAW];
else
return -1;
- return do_hres(vd, clock, ts);
+ return do_hres(vc, clock, ts);
}
static __maybe_unused int
@@ -328,11 +329,12 @@ static __maybe_unused int
__cvdso_gettimeofday_data(const struct vdso_time_data *vd,
struct __kernel_old_timeval *tv, struct timezone *tz)
{
+ const struct vdso_clock *vc = vd;
if (likely(tv != NULL)) {
struct __kernel_timespec ts;
- if (do_hres(&vd[CS_HRES_COARSE], CLOCK_REALTIME, &ts))
+ if (do_hres(&vc[CS_HRES_COARSE], CLOCK_REALTIME, &ts))
return gettimeofday_fallback(tv, tz);
tv->tv_sec = ts.tv_sec;
@@ -341,7 +343,7 @@ __cvdso_gettimeofday_data(const struct vdso_time_data *vd,
if (unlikely(tz != NULL)) {
if (IS_ENABLED(CONFIG_TIME_NS) &&
- vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
+ vc->clock_mode == VDSO_CLOCKMODE_TIMENS)
vd = __arch_get_vdso_u_timens_data(vd);
tz->tz_minuteswest = vd[CS_HRES_COARSE].tz_minuteswest;
@@ -361,13 +363,16 @@ __cvdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
static __maybe_unused __kernel_old_time_t
__cvdso_time_data(const struct vdso_time_data *vd, __kernel_old_time_t *time)
{
+ const struct vdso_clock *vc = vd;
__kernel_old_time_t t;
if (IS_ENABLED(CONFIG_TIME_NS) &&
- vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
+ vc->clock_mode == VDSO_CLOCKMODE_TIMENS) {
vd = __arch_get_vdso_u_timens_data(vd);
+ vc = vd;
+ }
- t = READ_ONCE(vd[CS_HRES_COARSE].basetime[CLOCK_REALTIME].sec);
+ t = READ_ONCE(vc[CS_HRES_COARSE].basetime[CLOCK_REALTIME].sec);
if (time)
*time = t;
@@ -386,6 +391,7 @@ static __maybe_unused
int __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *res)
{
+ const struct vdso_clock *vc = vd;
u32 msk;
u64 ns;
@@ -394,7 +400,7 @@ int __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock
return -1;
if (IS_ENABLED(CONFIG_TIME_NS) &&
- vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
+ vc->clock_mode == VDSO_CLOCKMODE_TIMENS)
vd = __arch_get_vdso_u_timens_data(vd);
/*
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 07/19] vdso/gettimeofday: Prepare do_hres() for introduction of struct vdso_clock
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
` (6 preceding siblings ...)
2025-03-03 11:11 ` [PATCH 06/19] vdso/gettimeofday: " Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 08/19] vdso/gettimeofday: Prepare do_hres_timens() " Thomas Weißschuh
` (11 subsequent siblings)
19 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Anna-Maria Behnsen <anna-maria@linutronix.de>
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be array of it. By now, vdso_clock is
simply a define which maps vdso_clock to vdso_time_data.
Prepare for the rework of these structures by adding struct vdso_clock
pointer argument to do_hres(), and replace the struct vdso_time_data
pointer with the new pointer arugment whenever applicable.
No functional change.
Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
lib/vdso/gettimeofday.c | 33 +++++++++++++++++----------------
1 file changed, 17 insertions(+), 16 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 59369a4e9f25f937eb8d9aed3201ebd340097a9d..15611ab650232f2e847b7de80c7293c4fb7f84f2 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -139,10 +139,11 @@ static __always_inline int do_hres_timens(const struct vdso_time_data *vdns, clo
}
#endif
-static __always_inline int do_hres(const struct vdso_time_data *vd, clockid_t clk,
- struct __kernel_timespec *ts)
+static __always_inline
+int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
+ clockid_t clk, struct __kernel_timespec *ts)
{
- const struct vdso_timestamp *vdso_ts = &vd->basetime[clk];
+ const struct vdso_timestamp *vdso_ts = &vc->basetime[clk];
u64 cycles, sec, ns;
u32 seq;
@@ -154,31 +155,31 @@ static __always_inline int do_hres(const struct vdso_time_data *vd, clockid_t cl
/*
* Open coded function vdso_read_begin() to handle
* VDSO_CLOCKMODE_TIMENS. Time namespace enabled tasks have a
- * special VVAR page installed which has vd->seq set to 1 and
- * vd->clock_mode set to VDSO_CLOCKMODE_TIMENS. For non time
+ * special VVAR page installed which has vc->seq set to 1 and
+ * vc->clock_mode set to VDSO_CLOCKMODE_TIMENS. For non time
* namespace affected tasks this does not affect performance
- * because if vd->seq is odd, i.e. a concurrent update is in
- * progress the extra check for vd->clock_mode is just a few
- * extra instructions while spin waiting for vd->seq to become
+ * because if vc->seq is odd, i.e. a concurrent update is in
+ * progress the extra check for vc->clock_mode is just a few
+ * extra instructions while spin waiting for vc->seq to become
* even again.
*/
- while (unlikely((seq = READ_ONCE(vd->seq)) & 1)) {
+ while (unlikely((seq = READ_ONCE(vc->seq)) & 1)) {
if (IS_ENABLED(CONFIG_TIME_NS) &&
- vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
+ vc->clock_mode == VDSO_CLOCKMODE_TIMENS)
return do_hres_timens(vd, clk, ts);
cpu_relax();
}
smp_rmb();
- if (unlikely(!vdso_clocksource_ok(vd)))
+ if (unlikely(!vdso_clocksource_ok(vc)))
return -1;
- cycles = __arch_get_hw_counter(vd->clock_mode, vd);
+ cycles = __arch_get_hw_counter(vc->clock_mode, vd);
if (unlikely(!vdso_cycles_ok(cycles)))
return -1;
- ns = vdso_calc_ns(vd, cycles, vdso_ts->nsec);
+ ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
sec = vdso_ts->sec;
- } while (unlikely(vdso_read_retry(vd, seq)));
+ } while (unlikely(vdso_read_retry(vc, seq)));
/*
* Do this outside the loop: a race inside the loop could result
@@ -278,7 +279,7 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
else
return -1;
- return do_hres(vc, clock, ts);
+ return do_hres(vd, vc, clock, ts);
}
static __maybe_unused int
@@ -334,7 +335,7 @@ __cvdso_gettimeofday_data(const struct vdso_time_data *vd,
if (likely(tv != NULL)) {
struct __kernel_timespec ts;
- if (do_hres(&vc[CS_HRES_COARSE], CLOCK_REALTIME, &ts))
+ if (do_hres(vd, &vc[CS_HRES_COARSE], CLOCK_REALTIME, &ts))
return gettimeofday_fallback(tv, tz);
tv->tv_sec = ts.tv_sec;
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 08/19] vdso/gettimeofday: Prepare do_hres_timens() for introduction of struct vdso_clock
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
` (7 preceding siblings ...)
2025-03-03 11:11 ` [PATCH 07/19] vdso/gettimeofday: Prepare do_hres() for " Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-04-24 14:10 ` Jan Stancek
2025-03-03 11:11 ` [PATCH 09/19] vdso/gettimeofday: Prepare do_coarse() " Thomas Weißschuh
` (10 subsequent siblings)
19 siblings, 1 reply; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Anna-Maria Behnsen <anna-maria@linutronix.de>
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be array of it. By now, vdso_clock is
simply a define which maps vdso_clock to vdso_time_data.
Prepare for the rework of these structures by adding struct vdso_clock
pointer argument to do_hres_timens(), and replace the struct vdso_time_data
pointer with the new pointer arugment whenever applicable.
No functional change.
Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
lib/vdso/gettimeofday.c | 35 ++++++++++++++++++-----------------
1 file changed, 18 insertions(+), 17 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 15611ab650232f2e847b7de80c7293c4fb7f84f2..e8d4b02bcb616af19f1e794b14fb4419809408da 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -81,36 +81,36 @@ const struct vdso_time_data *__arch_get_vdso_u_timens_data(const struct vdso_tim
}
#endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
-static __always_inline int do_hres_timens(const struct vdso_time_data *vdns, clockid_t clk,
- struct __kernel_timespec *ts)
+static __always_inline
+int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
- const struct timens_offset *offs = &vdns->offset[clk];
+ const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
+ const struct timens_offset *offs = &vcns->offset[clk];
const struct vdso_timestamp *vdso_ts;
- const struct vdso_time_data *vd;
+ const struct vdso_clock *vc = vd;
u64 cycles, ns;
u32 seq;
s64 sec;
- vd = vdns - (clk == CLOCK_MONOTONIC_RAW ? CS_RAW : CS_HRES_COARSE);
- vd = __arch_get_vdso_u_timens_data(vd);
if (clk != CLOCK_MONOTONIC_RAW)
- vd = &vd[CS_HRES_COARSE];
+ vc = &vc[CS_HRES_COARSE];
else
- vd = &vd[CS_RAW];
- vdso_ts = &vd->basetime[clk];
+ vc = &vc[CS_RAW];
+ vdso_ts = &vc->basetime[clk];
do {
- seq = vdso_read_begin(vd);
+ seq = vdso_read_begin(vc);
- if (unlikely(!vdso_clocksource_ok(vd)))
+ if (unlikely(!vdso_clocksource_ok(vc)))
return -1;
- cycles = __arch_get_hw_counter(vd->clock_mode, vd);
+ cycles = __arch_get_hw_counter(vc->clock_mode, vd);
if (unlikely(!vdso_cycles_ok(cycles)))
return -1;
- ns = vdso_calc_ns(vd, cycles, vdso_ts->nsec);
+ ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
sec = vdso_ts->sec;
- } while (unlikely(vdso_read_retry(vd, seq)));
+ } while (unlikely(vdso_read_retry(vc, seq)));
/* Add the namespace offset */
sec += offs->sec;
@@ -132,8 +132,9 @@ const struct vdso_time_data *__arch_get_vdso_u_timens_data(const struct vdso_tim
return NULL;
}
-static __always_inline int do_hres_timens(const struct vdso_time_data *vdns, clockid_t clk,
- struct __kernel_timespec *ts)
+static __always_inline
+int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
return -EINVAL;
}
@@ -166,7 +167,7 @@ int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
while (unlikely((seq = READ_ONCE(vc->seq)) & 1)) {
if (IS_ENABLED(CONFIG_TIME_NS) &&
vc->clock_mode == VDSO_CLOCKMODE_TIMENS)
- return do_hres_timens(vd, clk, ts);
+ return do_hres_timens(vd, vc, clk, ts);
cpu_relax();
}
smp_rmb();
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 09/19] vdso/gettimeofday: Prepare do_coarse() for introduction of struct vdso_clock
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
` (8 preceding siblings ...)
2025-03-03 11:11 ` [PATCH 08/19] vdso/gettimeofday: Prepare do_hres_timens() " Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 10/19] vdso/gettimeofday: Prepare do_coarse_timens() " Thomas Weißschuh
` (9 subsequent siblings)
19 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Anna-Maria Behnsen <anna-maria@linutronix.de>
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be array of it. By now, vdso_clock is
simply a define which maps vdso_clock to vdso_time_data.
Prepare for the rework of these structures by adding struct vdso_clock
pointer argument to do_coarse(), and replace the struct vdso_time_data
pointer with the new pointer arugment whenever applicable.
No functional change.
Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
lib/vdso/gettimeofday.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index e8d4b02bcb616af19f1e794b14fb4419809408da..36ef7de097e6137832605928a155a0ff78123fb4 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -229,10 +229,11 @@ static __always_inline int do_coarse_timens(const struct vdso_time_data *vdns, c
}
#endif
-static __always_inline int do_coarse(const struct vdso_time_data *vd, clockid_t clk,
- struct __kernel_timespec *ts)
+static __always_inline
+int do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
+ clockid_t clk, struct __kernel_timespec *ts)
{
- const struct vdso_timestamp *vdso_ts = &vd->basetime[clk];
+ const struct vdso_timestamp *vdso_ts = &vc->basetime[clk];
u32 seq;
do {
@@ -240,17 +241,17 @@ static __always_inline int do_coarse(const struct vdso_time_data *vd, clockid_t
* Open coded function vdso_read_begin() to handle
* VDSO_CLOCK_TIMENS. See comment in do_hres().
*/
- while ((seq = READ_ONCE(vd->seq)) & 1) {
+ while ((seq = READ_ONCE(vc->seq)) & 1) {
if (IS_ENABLED(CONFIG_TIME_NS) &&
- vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
- return do_coarse_timens(vd, clk, ts);
+ vc->clock_mode == VDSO_CLOCKMODE_TIMENS)
+ return do_coarse_timens(vc, clk, ts);
cpu_relax();
}
smp_rmb();
ts->tv_sec = vdso_ts->sec;
ts->tv_nsec = vdso_ts->nsec;
- } while (unlikely(vdso_read_retry(vd, seq)));
+ } while (unlikely(vdso_read_retry(vc, seq)));
return 0;
}
@@ -274,7 +275,7 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
if (likely(msk & VDSO_HRES))
vc = &vc[CS_HRES_COARSE];
else if (msk & VDSO_COARSE)
- return do_coarse(&vc[CS_HRES_COARSE], clock, ts);
+ return do_coarse(vd, &vc[CS_HRES_COARSE], clock, ts);
else if (msk & VDSO_RAW)
vc = &vc[CS_RAW];
else
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 10/19] vdso/gettimeofday: Prepare do_coarse_timens() for introduction of struct vdso_clock
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
` (9 preceding siblings ...)
2025-03-03 11:11 ` [PATCH 09/19] vdso/gettimeofday: Prepare do_coarse() " Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 11/19] vdso/gettimeofday: Prepare helper functions " Thomas Weißschuh
` (8 subsequent siblings)
19 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Anna-Maria Behnsen <anna-maria@linutronix.de>
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be array of it. At the moment, vdso_clock
is simply a define which maps vdso_clock to vdso_time_data.
Prepare for the rework of these structures by adding struct vdso_clock
pointer argument to do_coarse_timens(), and replace the struct
vdso_time_data pointer with the new pointer arugment whenever applicable.
No functional change.
Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
lib/vdso/gettimeofday.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 36ef7de097e6137832605928a155a0ff78123fb4..03fa0393645ac0f5ee465ddc19d84b330913da65 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -193,21 +193,25 @@ int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
}
#ifdef CONFIG_TIME_NS
-static __always_inline int do_coarse_timens(const struct vdso_time_data *vdns, clockid_t clk,
- struct __kernel_timespec *ts)
+static __always_inline
+int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
- const struct vdso_timestamp *vdso_ts = &vd->basetime[clk];
- const struct timens_offset *offs = &vdns->offset[clk];
+ const struct timens_offset *offs = &vcns->offset[clk];
+ const struct vdso_timestamp *vdso_ts;
+ const struct vdso_clock *vc = vd;
u64 nsec;
s64 sec;
s32 seq;
+ vdso_ts = &vc->basetime[clk];
+
do {
- seq = vdso_read_begin(vd);
+ seq = vdso_read_begin(vc);
sec = vdso_ts->sec;
nsec = vdso_ts->nsec;
- } while (unlikely(vdso_read_retry(vd, seq)));
+ } while (unlikely(vdso_read_retry(vc, seq)));
/* Add the namespace offset */
sec += offs->sec;
@@ -222,8 +226,9 @@ static __always_inline int do_coarse_timens(const struct vdso_time_data *vdns, c
return 0;
}
#else
-static __always_inline int do_coarse_timens(const struct vdso_time_data *vdns, clockid_t clk,
- struct __kernel_timespec *ts)
+static __always_inline
+int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
return -1;
}
@@ -244,7 +249,7 @@ int do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
while ((seq = READ_ONCE(vc->seq)) & 1) {
if (IS_ENABLED(CONFIG_TIME_NS) &&
vc->clock_mode == VDSO_CLOCKMODE_TIMENS)
- return do_coarse_timens(vc, clk, ts);
+ return do_coarse_timens(vd, vc, clk, ts);
cpu_relax();
}
smp_rmb();
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 11/19] vdso/gettimeofday: Prepare helper functions for introduction of struct vdso_clock
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
` (10 preceding siblings ...)
2025-03-03 11:11 ` [PATCH 10/19] vdso/gettimeofday: Prepare do_coarse_timens() " Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 12/19] vdso/vsyscall: Prepare " Thomas Weißschuh
` (7 subsequent siblings)
19 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Anna-Maria Behnsen <anna-maria@linutronix.de>
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be array of it. By now, vdso_clock is
simply a define which maps vdso_clock to vdso_time_data.
To prepare for the rework of the data structures, replace the struct
vdso_time_data pointer argument of the helper functions with struct
vdso_clock pointer if applicable.
No functional change.
Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
lib/vdso/gettimeofday.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 03fa0393645ac0f5ee465ddc19d84b330913da65..c6ff6934558658f9e280d5b84cfb034f4828893d 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -17,12 +17,12 @@
#endif
#ifdef CONFIG_GENERIC_VDSO_OVERFLOW_PROTECT
-static __always_inline bool vdso_delta_ok(const struct vdso_time_data *vd, u64 delta)
+static __always_inline bool vdso_delta_ok(const struct vdso_clock *vc, u64 delta)
{
- return delta < vd->max_cycles;
+ return delta < vc->max_cycles;
}
#else
-static __always_inline bool vdso_delta_ok(const struct vdso_time_data *vd, u64 delta)
+static __always_inline bool vdso_delta_ok(const struct vdso_clock *vc, u64 delta)
{
return true;
}
@@ -39,14 +39,14 @@ static __always_inline u64 vdso_shift_ns(u64 ns, u32 shift)
* Default implementation which works for all sane clocksources. That
* obviously excludes x86/TSC.
*/
-static __always_inline u64 vdso_calc_ns(const struct vdso_time_data *vd, u64 cycles, u64 base)
+static __always_inline u64 vdso_calc_ns(const struct vdso_clock *vc, u64 cycles, u64 base)
{
- u64 delta = (cycles - vd->cycle_last) & VDSO_DELTA_MASK(vd);
+ u64 delta = (cycles - vc->cycle_last) & VDSO_DELTA_MASK(vc);
- if (likely(vdso_delta_ok(vd, delta)))
- return vdso_shift_ns((delta * vd->mult) + base, vd->shift);
+ if (likely(vdso_delta_ok(vc, delta)))
+ return vdso_shift_ns((delta * vc->mult) + base, vc->shift);
- return mul_u64_u32_add_u64_shr(delta, vd->mult, base, vd->shift);
+ return mul_u64_u32_add_u64_shr(delta, vc->mult, base, vc->shift);
}
#endif /* vdso_calc_ns */
@@ -58,9 +58,9 @@ static inline bool __arch_vdso_hres_capable(void)
#endif
#ifndef vdso_clocksource_ok
-static inline bool vdso_clocksource_ok(const struct vdso_time_data *vd)
+static inline bool vdso_clocksource_ok(const struct vdso_clock *vc)
{
- return vd->clock_mode != VDSO_CLOCKMODE_NONE;
+ return vc->clock_mode != VDSO_CLOCKMODE_NONE;
}
#endif
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 12/19] vdso/vsyscall: Prepare introduction of struct vdso_clock
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
` (11 preceding siblings ...)
2025-03-03 11:11 ` [PATCH 11/19] vdso/gettimeofday: Prepare helper functions " Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 13/19] vdso/namespace: Rename timens_setup_vdso_data() to reflect new vdso_clock struct Thomas Weißschuh
` (6 subsequent siblings)
19 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Anna-Maria Behnsen <anna-maria@linutronix.de>
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be array of it. By now, vdso_clock is
simply a define which maps vdso_clock to vdso_time_data.
To prepare for the rework of the data structures, replace the struct
vdso_time_data pointer with struct vdso_clock pointer whenever applicable.
No functional change.
Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
kernel/time/vsyscall.c | 40 +++++++++++++++++++++-------------------
1 file changed, 21 insertions(+), 19 deletions(-)
diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c
index 418192296ef7dd3c1772d50f129e7838883cf00c..dd85b41a70bee7decbd943c35197c091916ee4c7 100644
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -18,25 +18,26 @@
static inline void update_vdso_time_data(struct vdso_time_data *vdata, struct timekeeper *tk)
{
struct vdso_timestamp *vdso_ts;
+ struct vdso_clock *vc = vdata;
u64 nsec, sec;
- vdata[CS_HRES_COARSE].cycle_last = tk->tkr_mono.cycle_last;
+ vc[CS_HRES_COARSE].cycle_last = tk->tkr_mono.cycle_last;
#ifdef CONFIG_GENERIC_VDSO_OVERFLOW_PROTECT
- vdata[CS_HRES_COARSE].max_cycles = tk->tkr_mono.clock->max_cycles;
+ vc[CS_HRES_COARSE].max_cycles = tk->tkr_mono.clock->max_cycles;
#endif
- vdata[CS_HRES_COARSE].mask = tk->tkr_mono.mask;
- vdata[CS_HRES_COARSE].mult = tk->tkr_mono.mult;
- vdata[CS_HRES_COARSE].shift = tk->tkr_mono.shift;
- vdata[CS_RAW].cycle_last = tk->tkr_raw.cycle_last;
+ vc[CS_HRES_COARSE].mask = tk->tkr_mono.mask;
+ vc[CS_HRES_COARSE].mult = tk->tkr_mono.mult;
+ vc[CS_HRES_COARSE].shift = tk->tkr_mono.shift;
+ vc[CS_RAW].cycle_last = tk->tkr_raw.cycle_last;
#ifdef CONFIG_GENERIC_VDSO_OVERFLOW_PROTECT
- vdata[CS_RAW].max_cycles = tk->tkr_raw.clock->max_cycles;
+ vc[CS_RAW].max_cycles = tk->tkr_raw.clock->max_cycles;
#endif
- vdata[CS_RAW].mask = tk->tkr_raw.mask;
- vdata[CS_RAW].mult = tk->tkr_raw.mult;
- vdata[CS_RAW].shift = tk->tkr_raw.shift;
+ vc[CS_RAW].mask = tk->tkr_raw.mask;
+ vc[CS_RAW].mult = tk->tkr_raw.mult;
+ vc[CS_RAW].shift = tk->tkr_raw.shift;
/* CLOCK_MONOTONIC */
- vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC];
+ vdso_ts = &vc[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC];
vdso_ts->sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
nsec = tk->tkr_mono.xtime_nsec;
@@ -54,7 +55,7 @@ static inline void update_vdso_time_data(struct vdso_time_data *vdata, struct ti
nsec += (u64)tk->monotonic_to_boot.tv_nsec << tk->tkr_mono.shift;
/* CLOCK_BOOTTIME */
- vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_BOOTTIME];
+ vdso_ts = &vc[CS_HRES_COARSE].basetime[CLOCK_BOOTTIME];
vdso_ts->sec = sec;
while (nsec >= (((u64)NSEC_PER_SEC) << tk->tkr_mono.shift)) {
@@ -64,12 +65,12 @@ static inline void update_vdso_time_data(struct vdso_time_data *vdata, struct ti
vdso_ts->nsec = nsec;
/* CLOCK_MONOTONIC_RAW */
- vdso_ts = &vdata[CS_RAW].basetime[CLOCK_MONOTONIC_RAW];
+ vdso_ts = &vc[CS_RAW].basetime[CLOCK_MONOTONIC_RAW];
vdso_ts->sec = tk->raw_sec;
vdso_ts->nsec = tk->tkr_raw.xtime_nsec;
/* CLOCK_TAI */
- vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_TAI];
+ vdso_ts = &vc[CS_HRES_COARSE].basetime[CLOCK_TAI];
vdso_ts->sec = tk->xtime_sec + (s64)tk->tai_offset;
vdso_ts->nsec = tk->tkr_mono.xtime_nsec;
}
@@ -78,6 +79,7 @@ void update_vsyscall(struct timekeeper *tk)
{
struct vdso_time_data *vdata = vdso_k_time_data;
struct vdso_timestamp *vdso_ts;
+ struct vdso_clock *vc = vdata;
s32 clock_mode;
u64 nsec;
@@ -85,21 +87,21 @@ void update_vsyscall(struct timekeeper *tk)
vdso_write_begin(vdata);
clock_mode = tk->tkr_mono.clock->vdso_clock_mode;
- vdata[CS_HRES_COARSE].clock_mode = clock_mode;
- vdata[CS_RAW].clock_mode = clock_mode;
+ vc[CS_HRES_COARSE].clock_mode = clock_mode;
+ vc[CS_RAW].clock_mode = clock_mode;
/* CLOCK_REALTIME also required for time() */
- vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
+ vdso_ts = &vc[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
vdso_ts->sec = tk->xtime_sec;
vdso_ts->nsec = tk->tkr_mono.xtime_nsec;
/* CLOCK_REALTIME_COARSE */
- vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME_COARSE];
+ vdso_ts = &vc[CS_HRES_COARSE].basetime[CLOCK_REALTIME_COARSE];
vdso_ts->sec = tk->xtime_sec;
vdso_ts->nsec = tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift;
/* CLOCK_MONOTONIC_COARSE */
- vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC_COARSE];
+ vdso_ts = &vc[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC_COARSE];
vdso_ts->sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
nsec = tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift;
nsec = nsec + tk->wall_to_monotonic.tv_nsec;
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 13/19] vdso/namespace: Rename timens_setup_vdso_data() to reflect new vdso_clock struct
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
` (12 preceding siblings ...)
2025-03-03 11:11 ` [PATCH 12/19] vdso/vsyscall: Prepare " Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 14/19] time/namespace: Prepare introduction of struct vdso_clock Thomas Weißschuh
` (5 subsequent siblings)
19 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Anna-Maria Behnsen <anna-maria@linutronix.de>
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be array of it.
For time namespace, vdso_time_data needs to be set up. But this is only the
clock related part of the vdso_data thats requires this setup. To reflect
the future struct vdso_clock, rename timens_setup_vdso_data() to
timns_setup_vdso_clock_data().
No functional change.
Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
kernel/time/namespace.c | 6 +++---
lib/vdso/datastore.c | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c
index 12f55aa539adbc11cce4055f519dbeca8a73320c..f02430a73be8f081618792c8968bf0c112c54505 100644
--- a/kernel/time/namespace.c
+++ b/kernel/time/namespace.c
@@ -176,8 +176,8 @@ static struct timens_offset offset_from_ts(struct timespec64 off)
* Timens page has vdso_time_data->clock_mode set to VDSO_CLOCKMODE_TIMENS which
* enforces the time namespace handling path.
*/
-static void timens_setup_vdso_data(struct vdso_time_data *vdata,
- struct time_namespace *ns)
+static void timens_setup_vdso_clock_data(struct vdso_time_data *vdata,
+ struct time_namespace *ns)
{
struct timens_offset *offset = vdata->offset;
struct timens_offset monotonic = offset_from_ts(ns->offsets.monotonic);
@@ -238,7 +238,7 @@ static void timens_set_vvar_page(struct task_struct *task,
vdata = page_address(ns->vvar_page);
for (i = 0; i < CS_BASES; i++)
- timens_setup_vdso_data(&vdata[i], ns);
+ timens_setup_vdso_clock_data(&vdata[i], ns);
out:
mutex_unlock(&offset_lock);
diff --git a/lib/vdso/datastore.c b/lib/vdso/datastore.c
index e227fbbcb79694f9a40606ac864f52cf1fdbfcf4..4e350f56ace335b7ebca8af7663b5731fae27334 100644
--- a/lib/vdso/datastore.c
+++ b/lib/vdso/datastore.c
@@ -109,7 +109,7 @@ struct vm_area_struct *vdso_install_vvar_mapping(struct mm_struct *mm, unsigned
* non-root time namespace. Whenever a task changes its namespace, the VVAR
* page tables are cleared and then they will be re-faulted with a
* corresponding layout.
- * See also the comment near timens_setup_vdso_data() for details.
+ * See also the comment near timens_setup_vdso_clock_data() for details.
*/
int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
{
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 14/19] time/namespace: Prepare introduction of struct vdso_clock
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
` (13 preceding siblings ...)
2025-03-03 11:11 ` [PATCH 13/19] vdso/namespace: Rename timens_setup_vdso_data() to reflect new vdso_clock struct Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 15/19] x86/vdso: " Thomas Weißschuh
` (4 subsequent siblings)
19 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Anna-Maria Behnsen <anna-maria@linutronix.de>
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be array of it. By now, vdso_clock is
simply a define which maps vdso_clock to vdso_time_data.
To prepare for the rework of the data structures, replace the struct
vdso_time_data pointer with struct vdso_clock pointer whenever applicable.
No functional change.
Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
kernel/time/namespace.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c
index f02430a73be8f081618792c8968bf0c112c54505..09bc4fb39f24ccdaa1e6e7f7238660a4f2a63b54 100644
--- a/kernel/time/namespace.c
+++ b/kernel/time/namespace.c
@@ -165,26 +165,26 @@ static struct timens_offset offset_from_ts(struct timespec64 off)
* HVCLOCK
* VVAR
*
- * The check for vdso_time_data->clock_mode is in the unlikely path of
+ * The check for vdso_clock->clock_mode is in the unlikely path of
* the seq begin magic. So for the non-timens case most of the time
* 'seq' is even, so the branch is not taken.
*
* If 'seq' is odd, i.e. a concurrent update is in progress, the extra check
- * for vdso_time_data->clock_mode is a non-issue. The task is spin waiting for the
+ * for vdso_clock->clock_mode is a non-issue. The task is spin waiting for the
* update to finish and for 'seq' to become even anyway.
*
- * Timens page has vdso_time_data->clock_mode set to VDSO_CLOCKMODE_TIMENS which
+ * Timens page has vdso_clock->clock_mode set to VDSO_CLOCKMODE_TIMENS which
* enforces the time namespace handling path.
*/
-static void timens_setup_vdso_clock_data(struct vdso_time_data *vdata,
+static void timens_setup_vdso_clock_data(struct vdso_clock *vc,
struct time_namespace *ns)
{
- struct timens_offset *offset = vdata->offset;
+ struct timens_offset *offset = vc->offset;
struct timens_offset monotonic = offset_from_ts(ns->offsets.monotonic);
struct timens_offset boottime = offset_from_ts(ns->offsets.boottime);
- vdata->seq = 1;
- vdata->clock_mode = VDSO_CLOCKMODE_TIMENS;
+ vc->seq = 1;
+ vc->clock_mode = VDSO_CLOCKMODE_TIMENS;
offset[CLOCK_MONOTONIC] = monotonic;
offset[CLOCK_MONOTONIC_RAW] = monotonic;
offset[CLOCK_MONOTONIC_COARSE] = monotonic;
@@ -220,6 +220,7 @@ static void timens_set_vvar_page(struct task_struct *task,
struct time_namespace *ns)
{
struct vdso_time_data *vdata;
+ struct vdso_clock *vc;
unsigned int i;
if (ns == &init_time_ns)
@@ -236,9 +237,10 @@ static void timens_set_vvar_page(struct task_struct *task,
ns->frozen_offsets = true;
vdata = page_address(ns->vvar_page);
+ vc = vdata;
for (i = 0; i < CS_BASES; i++)
- timens_setup_vdso_clock_data(&vdata[i], ns);
+ timens_setup_vdso_clock_data(&vc[i], ns);
out:
mutex_unlock(&offset_lock);
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 15/19] x86/vdso: Prepare introduction of struct vdso_clock
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
` (14 preceding siblings ...)
2025-03-03 11:11 ` [PATCH 14/19] time/namespace: Prepare introduction of struct vdso_clock Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 16/19] arm64/vdso: " Thomas Weißschuh
` (3 subsequent siblings)
19 siblings, 1 reply; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Anna-Maria Behnsen <anna-maria@linutronix.de>
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be array of it. By now, vdso_clock is
simply a define which maps vdso_clock to vdso_time_data.
To prepare for the rework of the data structures, replace the struct
vdso_time_data pointer with struct vdso_clock pointer whenever applicable.
No functional change.
Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
arch/x86/include/asm/vdso/gettimeofday.h | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/x86/include/asm/vdso/gettimeofday.h b/arch/x86/include/asm/vdso/gettimeofday.h
index edec796832e08b73d6d58bda6408957048f4e80e..9e52cc46e1da99114312d85b34ae52e539dac9b6 100644
--- a/arch/x86/include/asm/vdso/gettimeofday.h
+++ b/arch/x86/include/asm/vdso/gettimeofday.h
@@ -261,7 +261,7 @@ static inline u64 __arch_get_hw_counter(s32 clock_mode,
return U64_MAX;
}
-static inline bool arch_vdso_clocksource_ok(const struct vdso_time_data *vd)
+static inline bool arch_vdso_clocksource_ok(const struct vdso_clock *vc)
{
return true;
}
@@ -300,34 +300,34 @@ static inline bool arch_vdso_cycles_ok(u64 cycles)
* declares everything with the MSB/Sign-bit set as invalid. Therefore the
* effective mask is S64_MAX.
*/
-static __always_inline u64 vdso_calc_ns(const struct vdso_time_data *vd, u64 cycles, u64 base)
+static __always_inline u64 vdso_calc_ns(const struct vdso_clock *vc, u64 cycles, u64 base)
{
- u64 delta = cycles - vd->cycle_last;
+ u64 delta = cycles - vc->cycle_last;
/*
* Negative motion and deltas which can cause multiplication
* overflow require special treatment. This check covers both as
- * negative motion is guaranteed to be greater than @vd::max_cycles
+ * negative motion is guaranteed to be greater than @vc::max_cycles
* due to unsigned comparison.
*
* Due to the MSB/Sign-bit being used as invalid marker (see
* arch_vdso_cycles_ok() above), the effective mask is S64_MAX, but that
* case is also unlikely and will also take the unlikely path here.
*/
- if (unlikely(delta > vd->max_cycles)) {
+ if (unlikely(delta > vc->max_cycles)) {
/*
* Due to the above mentioned TSC wobbles, filter out
* negative motion. Per the above masking, the effective
* sign bit is now bit 62.
*/
if (delta & (1ULL << 62))
- return base >> vd->shift;
+ return base >> vc->shift;
/* Handle multiplication overflow gracefully */
- return mul_u64_u32_add_u64_shr(delta & S64_MAX, vd->mult, base, vd->shift);
+ return mul_u64_u32_add_u64_shr(delta & S64_MAX, vc->mult, base, vc->shift);
}
- return ((delta * vd->mult) + base) >> vd->shift;
+ return ((delta * vc->mult) + base) >> vc->shift;
}
#define vdso_calc_ns vdso_calc_ns
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 15/19] x86/vdso: Prepare introduction of struct vdso_clock
2025-03-03 11:11 ` [PATCH 15/19] x86/vdso: " Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
0 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Anna-Maria Behnsen <anna-maria@linutronix.de>
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be array of it. By now, vdso_clock is
simply a define which maps vdso_clock to vdso_time_data.
To prepare for the rework of the data structures, replace the struct
vdso_time_data pointer with struct vdso_clock pointer whenever applicable
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 16/19] arm64/vdso: Prepare introduction of struct vdso_clock
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
` (15 preceding siblings ...)
2025-03-03 11:11 ` [PATCH 15/19] x86/vdso: " Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 17/19] powerpc/vdso: " Thomas Weißschuh
` (2 subsequent siblings)
19 siblings, 1 reply; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Nam Cao <namcao@linutronix.de>
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be array of it. By now, vdso_clock is
simply a define which maps vdso_clock to vdso_time_data.
To prepare for the rework of the data structures, replace the struct
vdso_time_data pointer with struct vdso_clock pointer whenever applicable.
No functional change.
Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
arch/arm64/include/asm/vdso/compat_gettimeofday.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/vdso/compat_gettimeofday.h b/arch/arm64/include/asm/vdso/compat_gettimeofday.h
index 957ee12fcc54bd7f978fbcd8945bce62327b037a..2c6b90d26bc8fd6d4be87bf6a4178472581f56d3 100644
--- a/arch/arm64/include/asm/vdso/compat_gettimeofday.h
+++ b/arch/arm64/include/asm/vdso/compat_gettimeofday.h
@@ -155,9 +155,9 @@ static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(
}
#define __arch_get_vdso_u_time_data __arch_get_vdso_u_time_data
-static inline bool vdso_clocksource_ok(const struct vdso_time_data *vd)
+static inline bool vdso_clocksource_ok(const struct vdso_clock *vc)
{
- return vd->clock_mode == VDSO_CLOCKMODE_ARCHTIMER;
+ return vc->clock_mode == VDSO_CLOCKMODE_ARCHTIMER;
}
#define vdso_clocksource_ok vdso_clocksource_ok
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 16/19] arm64/vdso: Prepare introduction of struct vdso_clock
2025-03-03 11:11 ` [PATCH 16/19] arm64/vdso: " Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
0 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Nam Cao <namcao@linutronix.de>
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be array of it. By now, vdso_clock is
simply a define which maps vdso_clock to vdso_time_data.
To prepare for the rework of the data structures, replace the struct
vdso_time_data pointer with struct vdso_clock pointer whenever applicable
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 17/19] powerpc/vdso: Prepare introduction of struct vdso_clock
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
` (16 preceding siblings ...)
2025-03-03 11:11 ` [PATCH 16/19] arm64/vdso: " Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 18/19] vdso: Move arch related data before basetime Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 19/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
19 siblings, 1 reply; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Nam Cao <namcao@linutronix.de>
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be array of it. By now, vdso_clock is
simply a define which maps vdso_clock to vdso_time_data.
To prepare for the rework of the data structures, replace the struct
vdso_time_data pointer with struct vdso_clock pointer whenever applicable.
No functional change.
Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
arch/powerpc/include/asm/vdso/gettimeofday.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/vdso/gettimeofday.h b/arch/powerpc/include/asm/vdso/gettimeofday.h
index dc955f2e0cc51f44d46f488a292aa0dbee3dc16c..99c9d6f43fde2efaf92d4777d3a5510677da7c92 100644
--- a/arch/powerpc/include/asm/vdso/gettimeofday.h
+++ b/arch/powerpc/include/asm/vdso/gettimeofday.h
@@ -99,7 +99,7 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
return get_tb();
}
-static inline bool vdso_clocksource_ok(const struct vdso_time_data *vd)
+static inline bool vdso_clocksource_ok(const struct vdso_clock *vc)
{
return true;
}
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 17/19] powerpc/vdso: Prepare introduction of struct vdso_clock
2025-03-03 11:11 ` [PATCH 17/19] powerpc/vdso: " Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
0 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Nam Cao <namcao@linutronix.de>
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be array of it. By now, vdso_clock is
simply a define which maps vdso_clock to vdso_time_data.
To prepare for the rework of the data structures, replace the struct
vdso_time_data pointer with struct vdso_clock pointer whenever applicable
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 18/19] vdso: Move arch related data before basetime
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
` (17 preceding siblings ...)
2025-03-03 11:11 ` [PATCH 17/19] powerpc/vdso: " Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 19/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
19 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Anna-Maria Behnsen <anna-maria@linutronix.de>
Architecture related vdso data is required in fastpath when acquiring
CLOCK_MONOTONIC or CLOCK_REALTIME. At the moment, this information is
located at the end of the vdso_time_data structure. The whole structure has
to be loaded into cache to be able to access this information.
To minimize the number of required cachelines, the architecture specific
vdso data struct is moved right before the basetime (basetime information
is required anyway). This change does not have an impact on architectures
with CONFIG_ARCH_HAS_VDSO_DATA=n. All other architectures could spare
reading unnecessary cachelines.
Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
include/vdso/datapage.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index 1df22e8bb9b31153546b72b1e8b8c8aeaed7d9e3..bcd19c223783be7c22f90120330e7dddd0496f1a 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -70,6 +70,8 @@ struct vdso_timestamp {
/**
* struct vdso_time_data - vdso datapage representation
+ * @arch_data: architecture specific data (optional, defaults
+ * to an empty struct)
* @seq: timebase sequence counter
* @clock_mode: clock mode
* @cycle_last: timebase at clocksource init
@@ -83,8 +85,6 @@ struct vdso_timestamp {
* @tz_dsttime: type of DST correction
* @hrtimer_res: hrtimer resolution
* @__unused: unused
- * @arch_data: architecture specific data (optional, defaults
- * to an empty struct)
*
* vdso_time_data will be accessed by 64 bit and compat code at the same time
* so we should be careful before modifying this structure.
@@ -105,6 +105,8 @@ struct vdso_timestamp {
* offset must be zero.
*/
struct vdso_time_data {
+ struct arch_vdso_time_data arch_data;
+
u32 seq;
s32 clock_mode;
@@ -125,8 +127,6 @@ struct vdso_time_data {
s32 tz_dsttime;
u32 hrtimer_res;
u32 __unused;
-
- struct arch_vdso_time_data arch_data;
} ____cacheline_aligned;
#define vdso_clock vdso_time_data
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 19/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
` (18 preceding siblings ...)
2025-03-03 11:11 ` [PATCH 18/19] vdso: Move arch related data before basetime Thomas Weißschuh
@ 2025-03-03 11:11 ` Thomas Weißschuh
19 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-03-03 11:11 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
linux-arch, Nam Cao, Thomas Weißschuh
From: Anna-Maria Behnsen <anna-maria@linutronix.de>
To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be an array of it.
Now all preparation is in place: Split the clock related struct members
into a separate struct vdso_clock. Make sure all users are aware, that
vdso_time_data is no longer initialized as an array and vdso_clock is now
the array inside vdso_data. Remove also the define of vdso_clock which made
preparation possible in smaller steps.
Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
arch/arm64/include/asm/vdso/compat_gettimeofday.h | 2 +-
arch/arm64/include/asm/vdso/vsyscall.h | 4 +-
arch/s390/kernel/time.c | 11 ++----
include/asm-generic/vdso/vsyscall.h | 2 +-
include/vdso/datapage.h | 47 ++++++++++++++---------
include/vdso/helpers.h | 4 +-
kernel/time/namespace.c | 2 +-
kernel/time/vsyscall.c | 11 +++---
lib/vdso/datastore.c | 4 +-
lib/vdso/gettimeofday.c | 16 ++++----
10 files changed, 53 insertions(+), 50 deletions(-)
diff --git a/arch/arm64/include/asm/vdso/compat_gettimeofday.h b/arch/arm64/include/asm/vdso/compat_gettimeofday.h
index 2c6b90d26bc8fd6d4be87bf6a4178472581f56d3..d60ea7a72a9cb3457c412d0ece21ed76ae77782d 100644
--- a/arch/arm64/include/asm/vdso/compat_gettimeofday.h
+++ b/arch/arm64/include/asm/vdso/compat_gettimeofday.h
@@ -149,7 +149,7 @@ static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(
* where __aarch64_get_vdso_u_time_data() is called, and then keep the
* result in a register.
*/
- asm volatile("mov %0, %1" : "=r"(ret) : "r"(vdso_u_time_data));
+ asm volatile("mov %0, %1" : "=r"(ret) : "r"(&vdso_u_time_data));
return ret;
}
diff --git a/arch/arm64/include/asm/vdso/vsyscall.h b/arch/arm64/include/asm/vdso/vsyscall.h
index 3f65cbd00635aab50a4e0c6058d38b39fd6d43a9..de58951b8df6a4bb9afd411878793c79c30adbf2 100644
--- a/arch/arm64/include/asm/vdso/vsyscall.h
+++ b/arch/arm64/include/asm/vdso/vsyscall.h
@@ -15,8 +15,8 @@
static __always_inline
void __arm64_update_vsyscall(struct vdso_time_data *vdata)
{
- vdata[CS_HRES_COARSE].mask = VDSO_PRECISION_MASK;
- vdata[CS_RAW].mask = VDSO_PRECISION_MASK;
+ vdata->clock_data[CS_HRES_COARSE].mask = VDSO_PRECISION_MASK;
+ vdata->clock_data[CS_RAW].mask = VDSO_PRECISION_MASK;
}
#define __arch_update_vsyscall __arm64_update_vsyscall
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 41ca3586b19f6cac3753b52f0b99be62a33e1cb1..699a18f1c54eb7ec09f7f1cceecd1118aed37ab2 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -79,12 +79,10 @@ void __init time_early_init(void)
{
struct ptff_qto qto;
struct ptff_qui qui;
- int cs;
/* Initialize TOD steering parameters */
tod_steering_end = tod_clock_base.tod;
- for (cs = 0; cs < CS_BASES; cs++)
- vdso_k_time_data[cs].arch_data.tod_steering_end = tod_steering_end;
+ vdso_k_time_data->arch_data.tod_steering_end = tod_steering_end;
if (!test_facility(28))
return;
@@ -373,7 +371,6 @@ static void clock_sync_global(long delta)
{
unsigned long now, adj;
struct ptff_qto qto;
- int cs;
/* Fixup the monotonic sched clock. */
tod_clock_base.eitod += delta;
@@ -389,10 +386,8 @@ static void clock_sync_global(long delta)
panic("TOD clock sync offset %li is too large to drift\n",
tod_steering_delta);
tod_steering_end = now + (abs(tod_steering_delta) << 15);
- for (cs = 0; cs < CS_BASES; cs++) {
- vdso_k_time_data[cs].arch_data.tod_steering_end = tod_steering_end;
- vdso_k_time_data[cs].arch_data.tod_steering_delta = tod_steering_delta;
- }
+ vdso_k_time_data->arch_data.tod_steering_end = tod_steering_end;
+ vdso_k_time_data->arch_data.tod_steering_delta = tod_steering_delta;
/* Update LPAR offset. */
if (ptff_query(PTFF_QTO) && ptff(&qto, sizeof(qto), PTFF_QTO) == 0)
diff --git a/include/asm-generic/vdso/vsyscall.h b/include/asm-generic/vdso/vsyscall.h
index 1fb3000f50364feeaaa9348d438b3ab8091bb265..b550afa15ecd101d821f51ce9105903978dced40 100644
--- a/include/asm-generic/vdso/vsyscall.h
+++ b/include/asm-generic/vdso/vsyscall.h
@@ -9,7 +9,7 @@
#ifndef __arch_get_vdso_u_time_data
static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(void)
{
- return vdso_u_time_data;
+ return &vdso_u_time_data;
}
#endif
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index bcd19c223783be7c22f90120330e7dddd0496f1a..9e419394b32443c9e6af67afd9d97ef2b316d8be 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -69,9 +69,7 @@ struct vdso_timestamp {
};
/**
- * struct vdso_time_data - vdso datapage representation
- * @arch_data: architecture specific data (optional, defaults
- * to an empty struct)
+ * struct vdso_clock - vdso per clocksource datapage representation
* @seq: timebase sequence counter
* @clock_mode: clock mode
* @cycle_last: timebase at clocksource init
@@ -81,17 +79,9 @@ struct vdso_timestamp {
* @shift: clocksource shift
* @basetime[clock_id]: basetime per clock_id
* @offset[clock_id]: time namespace offset per clock_id
- * @tz_minuteswest: minutes west of Greenwich
- * @tz_dsttime: type of DST correction
- * @hrtimer_res: hrtimer resolution
- * @__unused: unused
- *
- * vdso_time_data will be accessed by 64 bit and compat code at the same time
- * so we should be careful before modifying this structure.
*
- * The ordering of the struct members is optimized to have fast access to the
- * often required struct members which are related to CLOCK_REALTIME and
- * CLOCK_MONOTONIC. This information is stored in the first cache lines.
+ * See also struct vdso_time_data for basic access and ordering information as
+ * struct vdso_clock is used there.
*
* @basetime is used to store the base time for the system wide time getter
* VVAR page.
@@ -104,9 +94,7 @@ struct vdso_timestamp {
* For clocks which are not affected by time namespace adjustment the
* offset must be zero.
*/
-struct vdso_time_data {
- struct arch_vdso_time_data arch_data;
-
+struct vdso_clock {
u32 seq;
s32 clock_mode;
@@ -122,6 +110,29 @@ struct vdso_time_data {
struct vdso_timestamp basetime[VDSO_BASES];
struct timens_offset offset[VDSO_BASES];
};
+};
+
+/**
+ * struct vdso_time_data - vdso datapage representation
+ * @arch_data: architecture specific data (optional, defaults
+ * to an empty struct)
+ * @clock_data: clocksource related data (array)
+ * @tz_minuteswest: minutes west of Greenwich
+ * @tz_dsttime: type of DST correction
+ * @hrtimer_res: hrtimer resolution
+ * @__unused: unused
+ *
+ * vdso_time_data will be accessed by 64 bit and compat code at the same time
+ * so we should be careful before modifying this structure.
+ *
+ * The ordering of the struct members is optimized to have fast acces to the
+ * often required struct members which are related to CLOCK_REALTIME and
+ * CLOCK_MONOTONIC. This information is stored in the first cache lines.
+ */
+struct vdso_time_data {
+ struct arch_vdso_time_data arch_data;
+
+ struct vdso_clock clock_data[CS_BASES];
s32 tz_minuteswest;
s32 tz_dsttime;
@@ -129,8 +140,6 @@ struct vdso_time_data {
u32 __unused;
} ____cacheline_aligned;
-#define vdso_clock vdso_time_data
-
/**
* struct vdso_rng_data - vdso RNG state information
* @generation: counter representing the number of RNG reseeds
@@ -151,7 +160,7 @@ struct vdso_rng_data {
* relocation, and this is what we need.
*/
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
-extern struct vdso_time_data vdso_u_time_data[CS_BASES] __attribute__((visibility("hidden")));
+extern struct vdso_time_data vdso_u_time_data __attribute__((visibility("hidden")));
extern struct vdso_rng_data vdso_u_rng_data __attribute__((visibility("hidden")));
extern struct vdso_arch_data vdso_u_arch_data __attribute__((visibility("hidden")));
diff --git a/include/vdso/helpers.h b/include/vdso/helpers.h
index 28f0707a46c62187ad7500543e169f5b99deee70..0a98fed550ba66a84a620fbbd6aee3e3029b4772 100644
--- a/include/vdso/helpers.h
+++ b/include/vdso/helpers.h
@@ -30,7 +30,7 @@ static __always_inline u32 vdso_read_retry(const struct vdso_clock *vc,
static __always_inline void vdso_write_begin(struct vdso_time_data *vd)
{
- struct vdso_clock *vc = vd;
+ struct vdso_clock *vc = vd->clock_data;
/*
* WRITE_ONCE() is required otherwise the compiler can validly tear
@@ -44,7 +44,7 @@ static __always_inline void vdso_write_begin(struct vdso_time_data *vd)
static __always_inline void vdso_write_end(struct vdso_time_data *vd)
{
- struct vdso_clock *vc = vd;
+ struct vdso_clock *vc = vd->clock_data;
smp_wmb();
/*
diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c
index 09bc4fb39f24ccdaa1e6e7f7238660a4f2a63b54..e3642278df433c41654ffb6a8043c3fcecc2994a 100644
--- a/kernel/time/namespace.c
+++ b/kernel/time/namespace.c
@@ -237,7 +237,7 @@ static void timens_set_vvar_page(struct task_struct *task,
ns->frozen_offsets = true;
vdata = page_address(ns->vvar_page);
- vc = vdata;
+ vc = vdata->clock_data;
for (i = 0; i < CS_BASES; i++)
timens_setup_vdso_clock_data(&vc[i], ns);
diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c
index dd85b41a70bee7decbd943c35197c091916ee4c7..01c2ab1e897193e12be9b981790147ad018e19f3 100644
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -17,8 +17,8 @@
static inline void update_vdso_time_data(struct vdso_time_data *vdata, struct timekeeper *tk)
{
+ struct vdso_clock *vc = vdata->clock_data;
struct vdso_timestamp *vdso_ts;
- struct vdso_clock *vc = vdata;
u64 nsec, sec;
vc[CS_HRES_COARSE].cycle_last = tk->tkr_mono.cycle_last;
@@ -78,8 +78,8 @@ static inline void update_vdso_time_data(struct vdso_time_data *vdata, struct ti
void update_vsyscall(struct timekeeper *tk)
{
struct vdso_time_data *vdata = vdso_k_time_data;
+ struct vdso_clock *vc = vdata->clock_data;
struct vdso_timestamp *vdso_ts;
- struct vdso_clock *vc = vdata;
s32 clock_mode;
u64 nsec;
@@ -109,9 +109,8 @@ void update_vsyscall(struct timekeeper *tk)
/*
* Read without the seqlock held by clock_getres().
- * Note: No need to have a second copy.
*/
- WRITE_ONCE(vdata[CS_HRES_COARSE].hrtimer_res, hrtimer_resolution);
+ WRITE_ONCE(vdata->hrtimer_res, hrtimer_resolution);
/*
* If the current clocksource is not VDSO capable, then spare the
@@ -131,8 +130,8 @@ void update_vsyscall_tz(void)
{
struct vdso_time_data *vdata = vdso_k_time_data;
- vdata[CS_HRES_COARSE].tz_minuteswest = sys_tz.tz_minuteswest;
- vdata[CS_HRES_COARSE].tz_dsttime = sys_tz.tz_dsttime;
+ vdata->tz_minuteswest = sys_tz.tz_minuteswest;
+ vdata->tz_dsttime = sys_tz.tz_dsttime;
__arch_sync_vdso_time_data(vdata);
}
diff --git a/lib/vdso/datastore.c b/lib/vdso/datastore.c
index 4e350f56ace335b7ebca8af7663b5731fae27334..c715e217ec6576c34795ad76730faddf6b4c9f8b 100644
--- a/lib/vdso/datastore.c
+++ b/lib/vdso/datastore.c
@@ -13,10 +13,10 @@
*/
#ifdef CONFIG_HAVE_GENERIC_VDSO
static union {
- struct vdso_time_data data[CS_BASES];
+ struct vdso_time_data data;
u8 page[PAGE_SIZE];
} vdso_time_data_store __page_aligned_data;
-struct vdso_time_data *vdso_k_time_data = vdso_time_data_store.data;
+struct vdso_time_data *vdso_k_time_data = &vdso_time_data_store.data;
static_assert(sizeof(vdso_time_data_store) == PAGE_SIZE);
#endif /* CONFIG_HAVE_GENERIC_VDSO */
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index c6ff6934558658f9e280d5b84cfb034f4828893d..93ef801a97ef25f66195490d14e41bebcd41982b 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -87,8 +87,8 @@ int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *v
{
const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
const struct timens_offset *offs = &vcns->offset[clk];
+ const struct vdso_clock *vc = vd->clock_data;
const struct vdso_timestamp *vdso_ts;
- const struct vdso_clock *vc = vd;
u64 cycles, ns;
u32 seq;
s64 sec;
@@ -199,8 +199,8 @@ int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock
{
const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
const struct timens_offset *offs = &vcns->offset[clk];
+ const struct vdso_clock *vc = vd->clock_data;
const struct vdso_timestamp *vdso_ts;
- const struct vdso_clock *vc = vd;
u64 nsec;
s64 sec;
s32 seq;
@@ -265,7 +265,7 @@ static __always_inline int
__cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *ts)
{
- const struct vdso_clock *vc = vd;
+ const struct vdso_clock *vc = vd->clock_data;
u32 msk;
/* Check for negative values or invalid clocks */
@@ -337,7 +337,7 @@ static __maybe_unused int
__cvdso_gettimeofday_data(const struct vdso_time_data *vd,
struct __kernel_old_timeval *tv, struct timezone *tz)
{
- const struct vdso_clock *vc = vd;
+ const struct vdso_clock *vc = vd->clock_data;
if (likely(tv != NULL)) {
struct __kernel_timespec ts;
@@ -371,13 +371,13 @@ __cvdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
static __maybe_unused __kernel_old_time_t
__cvdso_time_data(const struct vdso_time_data *vd, __kernel_old_time_t *time)
{
- const struct vdso_clock *vc = vd;
+ const struct vdso_clock *vc = vd->clock_data;
__kernel_old_time_t t;
if (IS_ENABLED(CONFIG_TIME_NS) &&
vc->clock_mode == VDSO_CLOCKMODE_TIMENS) {
vd = __arch_get_vdso_u_timens_data(vd);
- vc = vd;
+ vc = vd->clock_data;
}
t = READ_ONCE(vc[CS_HRES_COARSE].basetime[CLOCK_REALTIME].sec);
@@ -399,7 +399,7 @@ static __maybe_unused
int __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *res)
{
- const struct vdso_clock *vc = vd;
+ const struct vdso_clock *vc = vd->clock_data;
u32 msk;
u64 ns;
@@ -420,7 +420,7 @@ int __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock
/*
* Preserves the behaviour of posix_get_hrtimer_res().
*/
- ns = READ_ONCE(vd[CS_HRES_COARSE].hrtimer_res);
+ ns = READ_ONCE(vd->hrtimer_res);
} else if (msk & VDSO_COARSE) {
/*
* Preserves the behaviour of posix_get_coarse_res().
--
2.48.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH 08/19] vdso/gettimeofday: Prepare do_hres_timens() for introduction of struct vdso_clock
2025-03-03 11:11 ` [PATCH 08/19] vdso/gettimeofday: Prepare do_hres_timens() " Thomas Weißschuh
@ 2025-04-24 14:10 ` Jan Stancek
2025-04-24 15:43 ` Thomas Weißschuh
0 siblings, 1 reply; 32+ messages in thread
From: Jan Stancek @ 2025-04-24 14:10 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann, linux-kernel, linux-arm-kernel,
linuxppc-dev, linux-s390, linux-arch, Nam Cao, jstancek
On Mon, Mar 03, 2025 at 12:11:10PM +0100, Thomas Weißschuh wrote:
>From: Anna-Maria Behnsen <anna-maria@linutronix.de>
>
>To support multiple PTP clocks, the VDSO data structure needs to be
>reworked. All clock specific data will end up in struct vdso_clock and in
>struct vdso_time_data there will be array of it. By now, vdso_clock is
>simply a define which maps vdso_clock to vdso_time_data.
>
>Prepare for the rework of these structures by adding struct vdso_clock
>pointer argument to do_hres_timens(), and replace the struct vdso_time_data
>pointer with the new pointer arugment whenever applicable.
>
>No functional change.
>
>Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
>Signed-off-by: Nam Cao <namcao@linutronix.de>
>Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
>---
> lib/vdso/gettimeofday.c | 35 ++++++++++++++++++-----------------
> 1 file changed, 18 insertions(+), 17 deletions(-)
>
Hi,
starting with this patch, I'm seeing user-space crashes when using clock_gettime():
BAD -> 83a2a6b8cfc5 vdso/gettimeofday: Prepare do_hres_timens() for introduction of struct vdso_clock
GOOD -> 64c3613ce31a vdso/gettimeofday: Prepare do_hres() for introduction of struct vdso_clock
It appears to be unique to aarch64 with 64k pages, and can be reproduced with
LTP clock_gettime03 [1]:
command: clock_gettime03
tst_kconfig.c:88: TINFO: Parsing kernel config '/lib/modules/6.15.0-0.rc3.20250423gitbc3372351d0c.30.eln147.aarch64+64k/build/.config'
tst_test.c:1903: TINFO: LTP version: 20250130-231-gd02c2aea3
tst_test.c:1907: TINFO: Tested kernel: 6.15.0-0.rc3.20250423gitbc3372351d0c.30.eln147.aarch64+64k #1 SMP PREEMPT_DYNAMIC Wed Apr 23 23:23:54 UTC 2025 aarch64
tst_kconfig.c:88: TINFO: Parsing kernel config '/lib/modules/6.15.0-0.rc3.20250423gitbc3372351d0c.30.eln147.aarch64+64k/build/.config'
tst_test.c:1720: TINFO: Overall timeout per run is 0h 05m 24s
clock_gettime03.c:121: TINFO: Testing variant: vDSO or syscall with libc spec
clock_gettime03.c:76: TPASS: Offset (CLOCK_MONOTONIC) is correct 10000ms
clock_gettime03.c:86: TPASS: Offset (CLOCK_MONOTONIC) is correct 0ms
clock_gettime03.c:76: TPASS: Offset (CLOCK_BOOTTIME) is correct 10000ms
clock_gettime03.c:86: TPASS: Offset (CLOCK_BOOTTIME) is correct 0ms
clock_gettime03.c:76: TPASS: Offset (CLOCK_MONOTONIC) is correct -10000ms
clock_gettime03.c:86: TPASS: Offset (CLOCK_MONOTONIC) is correct 0ms
clock_gettime03.c:76: TPASS: Offset (CLOCK_BOOTTIME) is correct -10000ms
clock_gettime03.c:86: TPASS: Offset (CLOCK_BOOTTIME) is correct 0ms
tst_test.c:438: TBROK: Child (233649) killed by signal SIGSEGV
or with:
--------------------- 8< ----------------------
#define _GNU_SOURCE
#include <sched.h>
#include <time.h>
#include <unistd.h> #include <sys/wait.h>
int main(void)
{
struct timespec tp;
pid_t child;
int status;
unshare(CLONE_NEWTIME);
child = fork();
if (child == 0) {
clock_gettime(CLOCK_MONOTONIC_RAW, &tp);
}
wait(&status);
return status;
}
# ./a.out ; echo $?
139
--------------------- >8 ----------------------
RPMs and configs can be found at Fedora koji, latest build is at [2] (look for kernel-64k).
Regards,
Jan
[1] https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/syscalls/clock_gettime/clock_gettime03.c
[2] https://koji.fedoraproject.org/koji/buildinfo?buildID=2704401
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 08/19] vdso/gettimeofday: Prepare do_hres_timens() for introduction of struct vdso_clock
2025-04-24 14:10 ` Jan Stancek
@ 2025-04-24 15:43 ` Thomas Weißschuh
2025-04-24 21:57 ` Jan Stancek
0 siblings, 1 reply; 32+ messages in thread
From: Thomas Weißschuh @ 2025-04-24 15:43 UTC (permalink / raw)
To: Jan Stancek
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann, linux-kernel, linux-arm-kernel,
linuxppc-dev, linux-s390, linux-arch, Nam Cao
On Thu, Apr 24, 2025 at 04:10:04PM +0200, Jan Stancek wrote:
> On Mon, Mar 03, 2025 at 12:11:10PM +0100, Thomas Weißschuh wrote:
> > From: Anna-Maria Behnsen <anna-maria@linutronix.de>
> >
> > To support multiple PTP clocks, the VDSO data structure needs to be
> > reworked. All clock specific data will end up in struct vdso_clock and in
> > struct vdso_time_data there will be array of it. By now, vdso_clock is
> > simply a define which maps vdso_clock to vdso_time_data.
> >
> > Prepare for the rework of these structures by adding struct vdso_clock
> > pointer argument to do_hres_timens(), and replace the struct vdso_time_data
> > pointer with the new pointer arugment whenever applicable.
> >
> > No functional change.
> >
> > Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
> > Signed-off-by: Nam Cao <namcao@linutronix.de>
> > Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> > ---
> > lib/vdso/gettimeofday.c | 35 ++++++++++++++++++-----------------
> > 1 file changed, 18 insertions(+), 17 deletions(-)
> >
>
> starting with this patch, I'm seeing user-space crashes when using clock_gettime():
> BAD -> 83a2a6b8cfc5 vdso/gettimeofday: Prepare do_hres_timens() for introduction of struct vdso_clock
> GOOD -> 64c3613ce31a vdso/gettimeofday: Prepare do_hres() for introduction of struct vdso_clock
>
> It appears to be unique to aarch64 with 64k pages, and can be reproduced with
> LTP clock_gettime03 [1]:
> command: clock_gettime03 tst_kconfig.c:88: TINFO: Parsing kernel config '/lib/modules/6.15.0-0.rc3.20250423gitbc3372351d0c.30.eln147.aarch64+64k/build/.config'
> tst_test.c:1903: TINFO: LTP version: 20250130-231-gd02c2aea3
> tst_test.c:1907: TINFO: Tested kernel: 6.15.0-0.rc3.20250423gitbc3372351d0c.30.eln147.aarch64+64k #1 SMP PREEMPT_DYNAMIC Wed Apr 23 23:23:54 UTC 2025 aarch64
> tst_kconfig.c:88: TINFO: Parsing kernel config '/lib/modules/6.15.0-0.rc3.20250423gitbc3372351d0c.30.eln147.aarch64+64k/build/.config'
> tst_test.c:1720: TINFO: Overall timeout per run is 0h 05m 24s
> clock_gettime03.c:121: TINFO: Testing variant: vDSO or syscall with libc spec
> clock_gettime03.c:76: TPASS: Offset (CLOCK_MONOTONIC) is correct 10000ms
> clock_gettime03.c:86: TPASS: Offset (CLOCK_MONOTONIC) is correct 0ms
> clock_gettime03.c:76: TPASS: Offset (CLOCK_BOOTTIME) is correct 10000ms
> clock_gettime03.c:86: TPASS: Offset (CLOCK_BOOTTIME) is correct 0ms
> clock_gettime03.c:76: TPASS: Offset (CLOCK_MONOTONIC) is correct -10000ms
> clock_gettime03.c:86: TPASS: Offset (CLOCK_MONOTONIC) is correct 0ms
> clock_gettime03.c:76: TPASS: Offset (CLOCK_BOOTTIME) is correct -10000ms
> clock_gettime03.c:86: TPASS: Offset (CLOCK_BOOTTIME) is correct 0ms
> tst_test.c:438: TBROK: Child (233649) killed by signal SIGSEGV
>
> or with:
> --------------------- 8< ----------------------
> #define _GNU_SOURCE
> #include <sched.h>
> #include <time.h>
> #include <unistd.h> #include <sys/wait.h>
>
> int main(void)
> {
> struct timespec tp;
> pid_t child;
> int status;
>
> unshare(CLONE_NEWTIME);
>
> child = fork();
> if (child == 0) {
> clock_gettime(CLOCK_MONOTONIC_RAW, &tp);
> }
>
> wait(&status);
> return status;
> }
>
> # ./a.out ; echo $?
> 139
> --------------------- >8 ----------------------
>
> RPMs and configs can be found at Fedora koji, latest build is at [2] (look for kernel-64k).
Hi Jan,
Thanks for the great error report.
Can you try the following change (on top of v6.15-rc1, should also work with current master)?
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 93ef801a97ef..867ce53cca94 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -85,14 +85,18 @@ static __always_inline
int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
clockid_t clk, struct __kernel_timespec *ts)
{
- const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
const struct timens_offset *offs = &vcns->offset[clk];
- const struct vdso_clock *vc = vd->clock_data;
+ const struct vdso_time_data *vd;
+ const struct vdso_clock *vc;
const struct vdso_timestamp *vdso_ts;
u64 cycles, ns;
u32 seq;
s64 sec;
+ vd = vdns - (clk == CLOCK_MONOTONIC_RAW ? CS_RAW : CS_HRES_COARSE);
+ vd = __arch_get_vdso_u_timens_data(vd);
+ vc = vd->clock_data;
+
if (clk != CLOCK_MONOTONIC_RAW)
vc = &vc[CS_HRES_COARSE];
else
I'll do some proper testing tomorrow.
Thomas
> [1] https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/syscalls/clock_gettime/clock_gettime03.c
> [2] https://koji.fedoraproject.org/koji/buildinfo?buildID=2704401
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH 08/19] vdso/gettimeofday: Prepare do_hres_timens() for introduction of struct vdso_clock
2025-04-24 15:43 ` Thomas Weißschuh
@ 2025-04-24 21:57 ` Jan Stancek
2025-04-25 8:58 ` Thomas Weißschuh
0 siblings, 1 reply; 32+ messages in thread
From: Jan Stancek @ 2025-04-24 21:57 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann, linux-kernel, linux-arm-kernel,
linuxppc-dev, linux-s390, linux-arch, Nam Cao
On Thu, Apr 24, 2025 at 5:49 PM Thomas Weißschuh
<thomas.weissschuh@linutronix.de> wrote:
>
> On Thu, Apr 24, 2025 at 04:10:04PM +0200, Jan Stancek wrote:
> > On Mon, Mar 03, 2025 at 12:11:10PM +0100, Thomas Weißschuh wrote:
> > > From: Anna-Maria Behnsen <anna-maria@linutronix.de>
> > >
> > > To support multiple PTP clocks, the VDSO data structure needs to be
> > > reworked. All clock specific data will end up in struct vdso_clock and in
> > > struct vdso_time_data there will be array of it. By now, vdso_clock is
> > > simply a define which maps vdso_clock to vdso_time_data.
> > >
> > > Prepare for the rework of these structures by adding struct vdso_clock
> > > pointer argument to do_hres_timens(), and replace the struct vdso_time_data
> > > pointer with the new pointer arugment whenever applicable.
> > >
> > > No functional change.
> > >
> > > Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
> > > Signed-off-by: Nam Cao <namcao@linutronix.de>
> > > Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> > > ---
> > > lib/vdso/gettimeofday.c | 35 ++++++++++++++++++-----------------
> > > 1 file changed, 18 insertions(+), 17 deletions(-)
> > >
> >
> > starting with this patch, I'm seeing user-space crashes when using clock_gettime():
> > BAD -> 83a2a6b8cfc5 vdso/gettimeofday: Prepare do_hres_timens() for introduction of struct vdso_clock
> > GOOD -> 64c3613ce31a vdso/gettimeofday: Prepare do_hres() for introduction of struct vdso_clock
> >
> > It appears to be unique to aarch64 with 64k pages, and can be reproduced with
> > LTP clock_gettime03 [1]:
> > command: clock_gettime03 tst_kconfig.c:88: TINFO: Parsing kernel config '/lib/modules/6.15.0-0.rc3.20250423gitbc3372351d0c.30.eln147.aarch64+64k/build/.config'
> > tst_test.c:1903: TINFO: LTP version: 20250130-231-gd02c2aea3
> > tst_test.c:1907: TINFO: Tested kernel: 6.15.0-0.rc3.20250423gitbc3372351d0c.30.eln147.aarch64+64k #1 SMP PREEMPT_DYNAMIC Wed Apr 23 23:23:54 UTC 2025 aarch64
> > tst_kconfig.c:88: TINFO: Parsing kernel config '/lib/modules/6.15.0-0.rc3.20250423gitbc3372351d0c.30.eln147.aarch64+64k/build/.config'
> > tst_test.c:1720: TINFO: Overall timeout per run is 0h 05m 24s
> > clock_gettime03.c:121: TINFO: Testing variant: vDSO or syscall with libc spec
> > clock_gettime03.c:76: TPASS: Offset (CLOCK_MONOTONIC) is correct 10000ms
> > clock_gettime03.c:86: TPASS: Offset (CLOCK_MONOTONIC) is correct 0ms
> > clock_gettime03.c:76: TPASS: Offset (CLOCK_BOOTTIME) is correct 10000ms
> > clock_gettime03.c:86: TPASS: Offset (CLOCK_BOOTTIME) is correct 0ms
> > clock_gettime03.c:76: TPASS: Offset (CLOCK_MONOTONIC) is correct -10000ms
> > clock_gettime03.c:86: TPASS: Offset (CLOCK_MONOTONIC) is correct 0ms
> > clock_gettime03.c:76: TPASS: Offset (CLOCK_BOOTTIME) is correct -10000ms
> > clock_gettime03.c:86: TPASS: Offset (CLOCK_BOOTTIME) is correct 0ms
> > tst_test.c:438: TBROK: Child (233649) killed by signal SIGSEGV
> >
> > or with:
> > --------------------- 8< ----------------------
> > #define _GNU_SOURCE
> > #include <sched.h>
> > #include <time.h>
> > #include <unistd.h> #include <sys/wait.h>
> >
> > int main(void)
> > {
> > struct timespec tp;
> > pid_t child;
> > int status;
> >
> > unshare(CLONE_NEWTIME);
> >
> > child = fork();
> > if (child == 0) {
> > clock_gettime(CLOCK_MONOTONIC_RAW, &tp);
> > }
> >
> > wait(&status);
> > return status;
> > }
> >
> > # ./a.out ; echo $?
> > 139
> > --------------------- >8 ----------------------
> >
> > RPMs and configs can be found at Fedora koji, latest build is at [2] (look for kernel-64k).
>
> Hi Jan,
>
> Thanks for the great error report.
>
> Can you try the following change (on top of v6.15-rc1, should also work with current master)?
>
> diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
> index 93ef801a97ef..867ce53cca94 100644
> --- a/lib/vdso/gettimeofday.c
> +++ b/lib/vdso/gettimeofday.c
> @@ -85,14 +85,18 @@ static __always_inline
> int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
> clockid_t clk, struct __kernel_timespec *ts)
> {
> - const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
> const struct timens_offset *offs = &vcns->offset[clk];
> - const struct vdso_clock *vc = vd->clock_data;
> + const struct vdso_time_data *vd;
> + const struct vdso_clock *vc;
> const struct vdso_timestamp *vdso_ts;
> u64 cycles, ns;
> u32 seq;
> s64 sec;
>
> + vd = vdns - (clk == CLOCK_MONOTONIC_RAW ? CS_RAW : CS_HRES_COARSE);
> + vd = __arch_get_vdso_u_timens_data(vd);
> + vc = vd->clock_data;
> +
> if (clk != CLOCK_MONOTONIC_RAW)
> vc = &vc[CS_HRES_COARSE];
> else
>
>
> I'll do some proper testing tomorrow.
That does seem to work for the 2 reproducers I have.
But why is this change needed? Isn't 'vdns' here equal to 'vdso_u_time_data'?
>
>
> Thomas
>
> > [1] https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/syscalls/clock_gettime/clock_gettime03.c
> > [2] https://koji.fedoraproject.org/koji/buildinfo?buildID=2704401
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 08/19] vdso/gettimeofday: Prepare do_hres_timens() for introduction of struct vdso_clock
2025-04-24 21:57 ` Jan Stancek
@ 2025-04-25 8:58 ` Thomas Weißschuh
2025-04-25 10:03 ` Jan Stancek
0 siblings, 1 reply; 32+ messages in thread
From: Thomas Weißschuh @ 2025-04-25 8:58 UTC (permalink / raw)
To: Jan Stancek
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann, linux-kernel, linux-arm-kernel,
linuxppc-dev, linux-s390, linux-arch, Nam Cao
On Thu, Apr 24, 2025 at 11:57:02PM +0200, Jan Stancek wrote:
> On Thu, Apr 24, 2025 at 5:49 PM Thomas Weißschuh
> <thomas.weissschuh@linutronix.de> wrote:
> >
> > On Thu, Apr 24, 2025 at 04:10:04PM +0200, Jan Stancek wrote:
> > > On Mon, Mar 03, 2025 at 12:11:10PM +0100, Thomas Weißschuh wrote:
> > > > From: Anna-Maria Behnsen <anna-maria@linutronix.de>
> > > >
> > > > To support multiple PTP clocks, the VDSO data structure needs to be
> > > > reworked. All clock specific data will end up in struct vdso_clock and in
> > > > struct vdso_time_data there will be array of it. By now, vdso_clock is
> > > > simply a define which maps vdso_clock to vdso_time_data.
> > > >
> > > > Prepare for the rework of these structures by adding struct vdso_clock
> > > > pointer argument to do_hres_timens(), and replace the struct vdso_time_data
> > > > pointer with the new pointer arugment whenever applicable.
> > > >
> > > > No functional change.
> > > >
> > > > Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
> > > > Signed-off-by: Nam Cao <namcao@linutronix.de>
> > > > Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> > > > ---
> > > > lib/vdso/gettimeofday.c | 35 ++++++++++++++++++-----------------
> > > > 1 file changed, 18 insertions(+), 17 deletions(-)
> > > >
> > >
> > > starting with this patch, I'm seeing user-space crashes when using clock_gettime():
> > > BAD -> 83a2a6b8cfc5 vdso/gettimeofday: Prepare do_hres_timens() for introduction of struct vdso_clock
> > > GOOD -> 64c3613ce31a vdso/gettimeofday: Prepare do_hres() for introduction of struct vdso_clock
> > >
> > > It appears to be unique to aarch64 with 64k pages, and can be reproduced with
> > > LTP clock_gettime03 [1]:
> > > command: clock_gettime03 tst_kconfig.c:88: TINFO: Parsing kernel config '/lib/modules/6.15.0-0.rc3.20250423gitbc3372351d0c.30.eln147.aarch64+64k/build/.config'
> > > tst_test.c:1903: TINFO: LTP version: 20250130-231-gd02c2aea3
> > > tst_test.c:1907: TINFO: Tested kernel: 6.15.0-0.rc3.20250423gitbc3372351d0c.30.eln147.aarch64+64k #1 SMP PREEMPT_DYNAMIC Wed Apr 23 23:23:54 UTC 2025 aarch64
> > > tst_kconfig.c:88: TINFO: Parsing kernel config '/lib/modules/6.15.0-0.rc3.20250423gitbc3372351d0c.30.eln147.aarch64+64k/build/.config'
> > > tst_test.c:1720: TINFO: Overall timeout per run is 0h 05m 24s
> > > clock_gettime03.c:121: TINFO: Testing variant: vDSO or syscall with libc spec
> > > clock_gettime03.c:76: TPASS: Offset (CLOCK_MONOTONIC) is correct 10000ms
> > > clock_gettime03.c:86: TPASS: Offset (CLOCK_MONOTONIC) is correct 0ms
> > > clock_gettime03.c:76: TPASS: Offset (CLOCK_BOOTTIME) is correct 10000ms
> > > clock_gettime03.c:86: TPASS: Offset (CLOCK_BOOTTIME) is correct 0ms
> > > clock_gettime03.c:76: TPASS: Offset (CLOCK_MONOTONIC) is correct -10000ms
> > > clock_gettime03.c:86: TPASS: Offset (CLOCK_MONOTONIC) is correct 0ms
> > > clock_gettime03.c:76: TPASS: Offset (CLOCK_BOOTTIME) is correct -10000ms
> > > clock_gettime03.c:86: TPASS: Offset (CLOCK_BOOTTIME) is correct 0ms
> > > tst_test.c:438: TBROK: Child (233649) killed by signal SIGSEGV
> > >
> > > or with:
> > > --------------------- 8< ----------------------
> > > #define _GNU_SOURCE
> > > #include <sched.h>
> > > #include <time.h>
> > > #include <unistd.h> #include <sys/wait.h>
> > >
> > > int main(void)
> > > {
> > > struct timespec tp;
> > > pid_t child;
> > > int status;
> > >
> > > unshare(CLONE_NEWTIME);
> > >
> > > child = fork();
> > > if (child == 0) {
> > > clock_gettime(CLOCK_MONOTONIC_RAW, &tp);
> > > }
> > >
> > > wait(&status);
> > > return status;
> > > }
> > >
> > > # ./a.out ; echo $?
> > > 139
> > > --------------------- >8 ----------------------
> > >
> > > RPMs and configs can be found at Fedora koji, latest build is at [2] (look for kernel-64k).
> >
> > Hi Jan,
> >
> > Thanks for the great error report.
> >
> > Can you try the following change (on top of v6.15-rc1, should also work with current master)?
> >
> > diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
> > index 93ef801a97ef..867ce53cca94 100644
> > --- a/lib/vdso/gettimeofday.c
> > +++ b/lib/vdso/gettimeofday.c
> > @@ -85,14 +85,18 @@ static __always_inline
> > int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
> > clockid_t clk, struct __kernel_timespec *ts)
> > {
> > - const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
> > const struct timens_offset *offs = &vcns->offset[clk];
> > - const struct vdso_clock *vc = vd->clock_data;
> > + const struct vdso_time_data *vd;
> > + const struct vdso_clock *vc;
> > const struct vdso_timestamp *vdso_ts;
> > u64 cycles, ns;
> > u32 seq;
> > s64 sec;
> >
> > + vd = vdns - (clk == CLOCK_MONOTONIC_RAW ? CS_RAW : CS_HRES_COARSE);
> > + vd = __arch_get_vdso_u_timens_data(vd);
> > + vc = vd->clock_data;
> > +
> > if (clk != CLOCK_MONOTONIC_RAW)
> > vc = &vc[CS_HRES_COARSE];
> > else
> >
> >
> > I'll do some proper testing tomorrow.
>
> That does seem to work for the 2 reproducers I have.
Thanks for testing.
> But why is this change needed?
So far the only thing that I can say is that this logic was there before the
patch and was removed accidentally, so it should be restored.
Why the logic was there in the first place I'll have to investigate.
> Isn't 'vdns' here equal to 'vdso_u_time_data'?
That is true, but in a time namespace the namespaced time structure is mapped
in place of the normal structure and vice-versa.
So __arch_get_vdso_u_timens_data() will get the "real" time datastructure based
on a namespaced one.
I can't explain the special logic for CLOCK_MONOTONIC_RAW yet.
To me it looks wrong to calculate on a 'struct vdso_time_data *' in terms of
CS_RAW/CS_HRES_COARSE.
Another change that "fixes" the crash for me is:
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 93ef801a97ef..cdc3988a0ace 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -93,6 +118,8 @@ int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *v
u32 seq;
s64 sec;
+ OPTIMIZER_HIDE_VAR(vc);
+
if (clk != CLOCK_MONOTONIC_RAW)
vc = &vc[CS_HRES_COARSE];
else
This is obviously not an actual fix but indicates that something weird is going on.
Could you run this second change also through LTP to see if it would pass?
Thomas
> > > [1] https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/syscalls/clock_gettime/clock_gettime03.c
> > > [2] https://koji.fedoraproject.org/koji/buildinfo?buildID=2704401
> >
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH 08/19] vdso/gettimeofday: Prepare do_hres_timens() for introduction of struct vdso_clock
2025-04-25 8:58 ` Thomas Weißschuh
@ 2025-04-25 10:03 ` Jan Stancek
2025-04-25 13:40 ` Thomas Weißschuh
0 siblings, 1 reply; 32+ messages in thread
From: Jan Stancek @ 2025-04-25 10:03 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann, linux-kernel, linux-arm-kernel,
linuxppc-dev, linux-s390, linux-arch, Nam Cao
On Fri, Apr 25, 2025 at 10:58 AM Thomas Weißschuh
<thomas.weissschuh@linutronix.de> wrote:
>
> On Thu, Apr 24, 2025 at 11:57:02PM +0200, Jan Stancek wrote:
> > On Thu, Apr 24, 2025 at 5:49 PM Thomas Weißschuh
> > <thomas.weissschuh@linutronix.de> wrote:
> > >
> > > On Thu, Apr 24, 2025 at 04:10:04PM +0200, Jan Stancek wrote:
> > > > On Mon, Mar 03, 2025 at 12:11:10PM +0100, Thomas Weißschuh wrote:
> > > > > From: Anna-Maria Behnsen <anna-maria@linutronix.de>
> > > > >
> > > > > To support multiple PTP clocks, the VDSO data structure needs to be
> > > > > reworked. All clock specific data will end up in struct vdso_clock and in
> > > > > struct vdso_time_data there will be array of it. By now, vdso_clock is
> > > > > simply a define which maps vdso_clock to vdso_time_data.
> > > > >
> > > > > Prepare for the rework of these structures by adding struct vdso_clock
> > > > > pointer argument to do_hres_timens(), and replace the struct vdso_time_data
> > > > > pointer with the new pointer arugment whenever applicable.
> > > > >
> > > > > No functional change.
> > > > >
> > > > > Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
> > > > > Signed-off-by: Nam Cao <namcao@linutronix.de>
> > > > > Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> > > > > ---
> > > > > lib/vdso/gettimeofday.c | 35 ++++++++++++++++++-----------------
> > > > > 1 file changed, 18 insertions(+), 17 deletions(-)
> > > > >
> > > >
> > > > starting with this patch, I'm seeing user-space crashes when using clock_gettime():
> > > > BAD -> 83a2a6b8cfc5 vdso/gettimeofday: Prepare do_hres_timens() for introduction of struct vdso_clock
> > > > GOOD -> 64c3613ce31a vdso/gettimeofday: Prepare do_hres() for introduction of struct vdso_clock
> > > >
> > > > It appears to be unique to aarch64 with 64k pages, and can be reproduced with
> > > > LTP clock_gettime03 [1]:
> > > > command: clock_gettime03 tst_kconfig.c:88: TINFO: Parsing kernel config '/lib/modules/6.15.0-0.rc3.20250423gitbc3372351d0c.30.eln147.aarch64+64k/build/.config'
> > > > tst_test.c:1903: TINFO: LTP version: 20250130-231-gd02c2aea3
> > > > tst_test.c:1907: TINFO: Tested kernel: 6.15.0-0.rc3.20250423gitbc3372351d0c.30.eln147.aarch64+64k #1 SMP PREEMPT_DYNAMIC Wed Apr 23 23:23:54 UTC 2025 aarch64
> > > > tst_kconfig.c:88: TINFO: Parsing kernel config '/lib/modules/6.15.0-0.rc3.20250423gitbc3372351d0c.30.eln147.aarch64+64k/build/.config'
> > > > tst_test.c:1720: TINFO: Overall timeout per run is 0h 05m 24s
> > > > clock_gettime03.c:121: TINFO: Testing variant: vDSO or syscall with libc spec
> > > > clock_gettime03.c:76: TPASS: Offset (CLOCK_MONOTONIC) is correct 10000ms
> > > > clock_gettime03.c:86: TPASS: Offset (CLOCK_MONOTONIC) is correct 0ms
> > > > clock_gettime03.c:76: TPASS: Offset (CLOCK_BOOTTIME) is correct 10000ms
> > > > clock_gettime03.c:86: TPASS: Offset (CLOCK_BOOTTIME) is correct 0ms
> > > > clock_gettime03.c:76: TPASS: Offset (CLOCK_MONOTONIC) is correct -10000ms
> > > > clock_gettime03.c:86: TPASS: Offset (CLOCK_MONOTONIC) is correct 0ms
> > > > clock_gettime03.c:76: TPASS: Offset (CLOCK_BOOTTIME) is correct -10000ms
> > > > clock_gettime03.c:86: TPASS: Offset (CLOCK_BOOTTIME) is correct 0ms
> > > > tst_test.c:438: TBROK: Child (233649) killed by signal SIGSEGV
> > > >
> > > > or with:
> > > > --------------------- 8< ----------------------
> > > > #define _GNU_SOURCE
> > > > #include <sched.h>
> > > > #include <time.h>
> > > > #include <unistd.h> #include <sys/wait.h>
> > > >
> > > > int main(void)
> > > > {
> > > > struct timespec tp;
> > > > pid_t child;
> > > > int status;
> > > >
> > > > unshare(CLONE_NEWTIME);
> > > >
> > > > child = fork();
> > > > if (child == 0) {
> > > > clock_gettime(CLOCK_MONOTONIC_RAW, &tp);
> > > > }
> > > >
> > > > wait(&status);
> > > > return status;
> > > > }
> > > >
> > > > # ./a.out ; echo $?
> > > > 139
> > > > --------------------- >8 ----------------------
> > > >
> > > > RPMs and configs can be found at Fedora koji, latest build is at [2] (look for kernel-64k).
> > >
> > > Hi Jan,
> > >
> > > Thanks for the great error report.
> > >
> > > Can you try the following change (on top of v6.15-rc1, should also work with current master)?
> > >
> > > diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
> > > index 93ef801a97ef..867ce53cca94 100644
> > > --- a/lib/vdso/gettimeofday.c
> > > +++ b/lib/vdso/gettimeofday.c
> > > @@ -85,14 +85,18 @@ static __always_inline
> > > int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
> > > clockid_t clk, struct __kernel_timespec *ts)
> > > {
> > > - const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
> > > const struct timens_offset *offs = &vcns->offset[clk];
> > > - const struct vdso_clock *vc = vd->clock_data;
> > > + const struct vdso_time_data *vd;
> > > + const struct vdso_clock *vc;
> > > const struct vdso_timestamp *vdso_ts;
> > > u64 cycles, ns;
> > > u32 seq;
> > > s64 sec;
> > >
> > > + vd = vdns - (clk == CLOCK_MONOTONIC_RAW ? CS_RAW : CS_HRES_COARSE);
> > > + vd = __arch_get_vdso_u_timens_data(vd);
> > > + vc = vd->clock_data;
> > > +
> > > if (clk != CLOCK_MONOTONIC_RAW)
> > > vc = &vc[CS_HRES_COARSE];
> > > else
> > >
> > >
> > > I'll do some proper testing tomorrow.
> >
> > That does seem to work for the 2 reproducers I have.
>
> Thanks for testing.
>
> > But why is this change needed?
>
> So far the only thing that I can say is that this logic was there before the
> patch and was removed accidentally, so it should be restored.
> Why the logic was there in the first place I'll have to investigate.
I think it paired with "vd advancing" based on "clock" in original code:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/lib/vdso/gettimeofday.c?h=v6.14#n264
and to get back to "base", you needed to subtract same value:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/lib/vdso/gettimeofday.c?h=v6.14#n82
After this series, "vd" isn't manipulated this way, so the removal of
that subtraction seemed deliberate to me.
>
> > Isn't 'vdns' here equal to 'vdso_u_time_data'?
>
> That is true, but in a time namespace the namespaced time structure is mapped
> in place of the normal structure and vice-versa.
> So __arch_get_vdso_u_timens_data() will get the "real" time datastructure based
> on a namespaced one.
>
> I can't explain the special logic for CLOCK_MONOTONIC_RAW yet.
> To me it looks wrong to calculate on a 'struct vdso_time_data *' in terms of
> CS_RAW/CS_HRES_COARSE.
>
>
> Another change that "fixes" the crash for me is:
>
> diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
> index 93ef801a97ef..cdc3988a0ace 100644
> --- a/lib/vdso/gettimeofday.c
> +++ b/lib/vdso/gettimeofday.c
> @@ -93,6 +118,8 @@ int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *v
> u32 seq;
> s64 sec;
>
> + OPTIMIZER_HIDE_VAR(vc);
> +
> if (clk != CLOCK_MONOTONIC_RAW)
> vc = &vc[CS_HRES_COARSE];
> else
>
>
> This is obviously not an actual fix but indicates that something weird is going on.
> Could you run this second change also through LTP to see if it would pass?
Agreed, this does "fixes" it for me as well.
>
>
> Thomas
>
> > > > [1] https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/syscalls/clock_gettime/clock_gettime03.c
> > > > [2] https://koji.fedoraproject.org/koji/buildinfo?buildID=2704401
> > >
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 08/19] vdso/gettimeofday: Prepare do_hres_timens() for introduction of struct vdso_clock
2025-04-25 10:03 ` Jan Stancek
@ 2025-04-25 13:40 ` Thomas Weißschuh
2025-04-25 14:37 ` Jan Stancek
0 siblings, 1 reply; 32+ messages in thread
From: Thomas Weißschuh @ 2025-04-25 13:40 UTC (permalink / raw)
To: Jan Stancek
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann, linux-kernel, linux-arm-kernel,
linuxppc-dev, linux-s390, linux-arch, Nam Cao
On Fri, Apr 25, 2025 at 12:03:14PM +0200, Jan Stancek wrote:
> On Fri, Apr 25, 2025 at 10:58 AM Thomas Weißschuh
> <thomas.weissschuh@linutronix.de> wrote:
> >
> > On Thu, Apr 24, 2025 at 11:57:02PM +0200, Jan Stancek wrote:
> > > On Thu, Apr 24, 2025 at 5:49 PM Thomas Weißschuh
> > > <thomas.weissschuh@linutronix.de> wrote:
> > > >
> > > > On Thu, Apr 24, 2025 at 04:10:04PM +0200, Jan Stancek wrote:
> > > > > On Mon, Mar 03, 2025 at 12:11:10PM +0100, Thomas Weißschuh wrote:
> > > > > > From: Anna-Maria Behnsen <anna-maria@linutronix.de>
> > > > > >
> > > > > > To support multiple PTP clocks, the VDSO data structure needs to be
> > > > > > reworked. All clock specific data will end up in struct vdso_clock and in
> > > > > > struct vdso_time_data there will be array of it. By now, vdso_clock is
> > > > > > simply a define which maps vdso_clock to vdso_time_data.
> > > > > >
> > > > > > Prepare for the rework of these structures by adding struct vdso_clock
> > > > > > pointer argument to do_hres_timens(), and replace the struct vdso_time_data
> > > > > > pointer with the new pointer arugment whenever applicable.
> > > > > >
> > > > > > No functional change.
> > > > > >
> > > > > > Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
> > > > > > Signed-off-by: Nam Cao <namcao@linutronix.de>
> > > > > > Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> > > > > > ---
> > > > > > lib/vdso/gettimeofday.c | 35 ++++++++++++++++++-----------------
> > > > > > 1 file changed, 18 insertions(+), 17 deletions(-)
> > > > > >
> > > > >
> > > > > starting with this patch, I'm seeing user-space crashes when using clock_gettime():
> > > > > BAD -> 83a2a6b8cfc5 vdso/gettimeofday: Prepare do_hres_timens() for introduction of struct vdso_clock
> > > > > GOOD -> 64c3613ce31a vdso/gettimeofday: Prepare do_hres() for introduction of struct vdso_clock
> > > > >
> > > > > It appears to be unique to aarch64 with 64k pages, and can be reproduced with
> > > > > LTP clock_gettime03 [1]:
> > > > > command: clock_gettime03 tst_kconfig.c:88: TINFO: Parsing kernel config '/lib/modules/6.15.0-0.rc3.20250423gitbc3372351d0c.30.eln147.aarch64+64k/build/.config'
> > > > > tst_test.c:1903: TINFO: LTP version: 20250130-231-gd02c2aea3
> > > > > tst_test.c:1907: TINFO: Tested kernel: 6.15.0-0.rc3.20250423gitbc3372351d0c.30.eln147.aarch64+64k #1 SMP PREEMPT_DYNAMIC Wed Apr 23 23:23:54 UTC 2025 aarch64
> > > > > tst_kconfig.c:88: TINFO: Parsing kernel config '/lib/modules/6.15.0-0.rc3.20250423gitbc3372351d0c.30.eln147.aarch64+64k/build/.config'
> > > > > tst_test.c:1720: TINFO: Overall timeout per run is 0h 05m 24s
> > > > > clock_gettime03.c:121: TINFO: Testing variant: vDSO or syscall with libc spec
> > > > > clock_gettime03.c:76: TPASS: Offset (CLOCK_MONOTONIC) is correct 10000ms
> > > > > clock_gettime03.c:86: TPASS: Offset (CLOCK_MONOTONIC) is correct 0ms
> > > > > clock_gettime03.c:76: TPASS: Offset (CLOCK_BOOTTIME) is correct 10000ms
> > > > > clock_gettime03.c:86: TPASS: Offset (CLOCK_BOOTTIME) is correct 0ms
> > > > > clock_gettime03.c:76: TPASS: Offset (CLOCK_MONOTONIC) is correct -10000ms
> > > > > clock_gettime03.c:86: TPASS: Offset (CLOCK_MONOTONIC) is correct 0ms
> > > > > clock_gettime03.c:76: TPASS: Offset (CLOCK_BOOTTIME) is correct -10000ms
> > > > > clock_gettime03.c:86: TPASS: Offset (CLOCK_BOOTTIME) is correct 0ms
> > > > > tst_test.c:438: TBROK: Child (233649) killed by signal SIGSEGV
> > > > >
> > > > > or with:
> > > > > --------------------- 8< ----------------------
> > > > > #define _GNU_SOURCE
> > > > > #include <sched.h>
> > > > > #include <time.h>
> > > > > #include <unistd.h> #include <sys/wait.h>
> > > > >
> > > > > int main(void)
> > > > > {
> > > > > struct timespec tp;
> > > > > pid_t child;
> > > > > int status;
> > > > >
> > > > > unshare(CLONE_NEWTIME);
> > > > >
> > > > > child = fork();
> > > > > if (child == 0) {
> > > > > clock_gettime(CLOCK_MONOTONIC_RAW, &tp);
> > > > > }
> > > > >
> > > > > wait(&status);
> > > > > return status;
> > > > > }
> > > > >
> > > > > # ./a.out ; echo $?
> > > > > 139
> > > > > --------------------- >8 ----------------------
> > > > >
> > > > > RPMs and configs can be found at Fedora koji, latest build is at [2] (look for kernel-64k).
> > > >
> > > > Hi Jan,
> > > >
> > > > Thanks for the great error report.
> > > >
> > > > Can you try the following change (on top of v6.15-rc1, should also work with current master)?
> > > >
> > > > diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
> > > > index 93ef801a97ef..867ce53cca94 100644
> > > > --- a/lib/vdso/gettimeofday.c
> > > > +++ b/lib/vdso/gettimeofday.c
> > > > @@ -85,14 +85,18 @@ static __always_inline
> > > > int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
> > > > clockid_t clk, struct __kernel_timespec *ts)
> > > > {
> > > > - const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
> > > > const struct timens_offset *offs = &vcns->offset[clk];
> > > > - const struct vdso_clock *vc = vd->clock_data;
> > > > + const struct vdso_time_data *vd;
> > > > + const struct vdso_clock *vc;
> > > > const struct vdso_timestamp *vdso_ts;
> > > > u64 cycles, ns;
> > > > u32 seq;
> > > > s64 sec;
> > > >
> > > > + vd = vdns - (clk == CLOCK_MONOTONIC_RAW ? CS_RAW : CS_HRES_COARSE);
> > > > + vd = __arch_get_vdso_u_timens_data(vd);
> > > > + vc = vd->clock_data;
> > > > +
> > > > if (clk != CLOCK_MONOTONIC_RAW)
> > > > vc = &vc[CS_HRES_COARSE];
> > > > else
> > > >
> > > >
> > > > I'll do some proper testing tomorrow.
> > >
> > > That does seem to work for the 2 reproducers I have.
> >
> > Thanks for testing.
> >
> > > But why is this change needed?
> >
> > So far the only thing that I can say is that this logic was there before the
> > patch and was removed accidentally, so it should be restored.
> > Why the logic was there in the first place I'll have to investigate.
>
> I think it paired with "vd advancing" based on "clock" in original code:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/lib/vdso/gettimeofday.c?h=v6.14#n264
> and to get back to "base", you needed to subtract same value:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/lib/vdso/gettimeofday.c?h=v6.14#n82
>
> After this series, "vd" isn't manipulated this way, so the removal of
> that subtraction seemed deliberate to me.
Indeed. This change "works" because vsdo_clocksource_ok() rejects the clock and
instead falls backs to the syscall.
> > > Isn't 'vdns' here equal to 'vdso_u_time_data'?
> >
> > That is true, but in a time namespace the namespaced time structure is mapped
> > in place of the normal structure and vice-versa.
> > So __arch_get_vdso_u_timens_data() will get the "real" time datastructure based
> > on a namespaced one.
> >
> > I can't explain the special logic for CLOCK_MONOTONIC_RAW yet.
> > To me it looks wrong to calculate on a 'struct vdso_time_data *' in terms of
> > CS_RAW/CS_HRES_COARSE.
> >
> >
> > Another change that "fixes" the crash for me is:
> >
> > diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
> > index 93ef801a97ef..cdc3988a0ace 100644
> > --- a/lib/vdso/gettimeofday.c
> > +++ b/lib/vdso/gettimeofday.c
> > @@ -93,6 +118,8 @@ int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *v
> > u32 seq;
> > s64 sec;
> >
> > + OPTIMIZER_HIDE_VAR(vc);
> > +
> > if (clk != CLOCK_MONOTONIC_RAW)
> > vc = &vc[CS_HRES_COARSE];
> > else
> >
> >
> > This is obviously not an actual fix but indicates that something weird is going on.
> > Could you run this second change also through LTP to see if it would pass?
>
> Agreed, this does "fixes" it for me as well.
Some more information:
The crash comes from the address arithmetic in "vc = &vc[CS_RAW]" going wrong.
This should just do "vc = vc + 1", advancing the pointer by sizeof(*vc).
But I get these example values of "vc" before and after the arithmetic:
0x00ffffbc060000 -> 0xfffffffffffd00e8
Which is obviously wrong.
The arithmetic can be fixed with any one of the following changes:
* OPTIMIZER_HIDE_VAR() as above
* Replacement of -mcmodel=tiny with -mcmode=small in arch/arm64/kernel/vdso/Makefile
-mcmodel=tiny is supposed to cover 1MiB programs, the vDSO only needs 300KiB here
* Removal of the (clk != CLOCK_MONOTONIC_RAW) case
Shuffling code around, even without any impact on semantics, sometimes fixes
the issue. Compiling the vDSO with UBSAN didn't show anything.
Thomas
> > > > > [1] https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/syscalls/clock_gettime/clock_gettime03.c
> > > > > [2] https://koji.fedoraproject.org/koji/buildinfo?buildID=2704401
> > > >
> >
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 08/19] vdso/gettimeofday: Prepare do_hres_timens() for introduction of struct vdso_clock
2025-04-25 13:40 ` Thomas Weißschuh
@ 2025-04-25 14:37 ` Jan Stancek
2025-04-25 15:34 ` Thomas Weißschuh
0 siblings, 1 reply; 32+ messages in thread
From: Jan Stancek @ 2025-04-25 14:37 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann, linux-kernel, linux-arm-kernel,
linuxppc-dev, linux-s390, linux-arch, Nam Cao
On Fri, Apr 25, 2025 at 03:40:55PM +0200, Thomas Weißschuh wrote:
<snip>
>
>Some more information:
>
>The crash comes from the address arithmetic in "vc = &vc[CS_RAW]" going wrong.
That appears to be because it's not doing any arithmetic, but using value
from some linker-generated symbol (I'll refer to it as "7a8").
The below is presumably the check that compares clk != CLOCK_MONOTONIC_RAW,
CLOCK_MONOTONIC_RAW is 4. And it should choose between first and second vdso_clock
in 2nd vvar page:
# readelf -a /root/kernel-ark/arch/arm64/kernel/vdso/vdso.so.dbg | grep 7a8
25: 00000000000007a8 0 NOTYPE LOCAL DEFAULT 7 $d
objdump -d -S:
658: 17ffffef b 614 <__cvdso_clock_gettime_data.constprop.0+0x104>
vc = &vc[CS_HRES_COARSE];
65c: 58000a62 ldr x2, 7a8 <__cvdso_clock_gettime_data.constprop.0+0x298>
660: 7100101f cmp w0, #0x4
664: 10e7cce3 adr x3, fffffffffffd0000 <vdso_u_data+0x10000>
668: 9a821063 csel x3, x3, x2, ne // ne = any
while (unlikely((seq = READ_ONCE(vc->seq)) & 1))
66c: b9400065 ldr w5, [x3]
...
7a8: fffd00e0 .word 0xfffd00e0
7ac: ffffffff .word 0xffffffff
(gdb) r
Thread 2.1 "a.out" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xfffff7ff2dc0 (LWP 44638)]
0x0000fffff7fa066c in ?? ()
(gdb) disassemble 0x0000fffff7fa0658,0x0000fffff7fa067c
--Type <RET> for more, q to quit, c to continue without paging--
0x0000fffff7fa0658: b 0xfffff7fa0614
0x0000fffff7fa065c: ldr x2, 0xfffff7fa07a8
0x0000fffff7fa0660: cmp w0, #0x4
0x0000fffff7fa0664: adr x3, 0xfffff7f70000
0x0000fffff7fa0668: csel x3, x3, x2, ne // ne = any
=> 0x0000fffff7fa066c: ldr w5, [x3]
$x3 here is using correct vvar runtime address, but $x2 uses
a bogus one from "7a8". And when it tries to load from it, it crashes:
(gdb) info proc map
process 44638
Mapped address spaces:
Start Addr End Addr Size Offset Perms File
0x0000000000400000 0x0000000000410000 0x10000 0x0 r-xp /root/ltp/testcases/kernel/syscalls/clock_gettime/a.out
0x0000000000410000 0x0000000000420000 0x10000 0x0 r--p /root/ltp/testcases/kernel/syscalls/clock_gettime/a.out
0x0000000000420000 0x0000000000430000 0x10000 0x10000 rw-p /root/ltp/testcases/kernel/syscalls/clock_gettime/a.out
0x0000fffff7d80000 0x0000fffff7f30000 0x1b0000 0x0 r-xp /usr/lib64/libc.so.6
0x0000fffff7f30000 0x0000fffff7f40000 0x10000 0x1a0000 r--p /usr/lib64/libc.so.6
0x0000fffff7f40000 0x0000fffff7f50000 0x10000 0x1b0000 rw-p /usr/lib64/libc.so.6
0x0000fffff7f60000 0x0000fffff7fa0000 0x40000 0x0 r--p [vvar]
0x0000fffff7fa0000 0x0000fffff7fb0000 0x10000 0x0 r-xp [vdso]
0x0000fffff7fb0000 0x0000fffff7fe0000 0x30000 0x0 r-xp /usr/lib/ld-linux-aarch64.so.1
0x0000fffff7fe0000 0x0000fffff7ff0000 0x10000 0x20000 r--p /usr/lib/ld-linux-aarch64.so.1
0x0000fffff7ff0000 0x0000fffff8000000 0x10000 0x30000 rw-p /usr/lib/ld-linux-aarch64.so.1
0x0000fffffffd0000 0x0001000000000000 0x30000 0x0 rw-p [stack]
$x3 was the beginning of 2nd vvar page (1st vdso_clock), and $x2 looks
like it should have been 2nd vdso_clock, but the value that is used is not
the address of vvar during runtime.
vdso_clock has size 224 == 0xe0 (according to pahole)
(gdb) x/2x 0xfffff7fa07a8
0xfffff7fa07a8: 0xfffd00e0 0xffffffff
(gdb) p/x $x2
$1 = 0xfffffffffffd00e0
(gdb) x/1x $x2
0xfffffffffffd00e0: Cannot access memory at address 0xfffffffffffd00e0
But it does match the symbol value from vdso.so:
# readelf -a /root/kernel-ark/arch/arm64/kernel/vdso/vdso.so.dbg | grep vdso_u
37: fffffffffffc0000 0 NOTYPE LOCAL DEFAULT 1 vdso_u_data
39: fffffffffffc0000 0 NOTYPE LOCAL DEFAULT ABS vdso_u_time_data
40: fffffffffffe0000 0 NOTYPE LOCAL DEFAULT ABS vdso_u_rng_data
>>> print(hex(0xfffffffffffc0000+65536+224))
0xfffffffffffd00e0 -> and this is address where it crashes
Regards,
Jan
>This should just do "vc = vc + 1", advancing the pointer by sizeof(*vc).
>But I get these example values of "vc" before and after the arithmetic:
>0x00ffffbc060000 -> 0xfffffffffffd00e8
>Which is obviously wrong.
>
>The arithmetic can be fixed with any one of the following changes:
>* OPTIMIZER_HIDE_VAR() as above
>* Replacement of -mcmodel=tiny with -mcmode=small in arch/arm64/kernel/vdso/Makefile
> -mcmodel=tiny is supposed to cover 1MiB programs, the vDSO only needs 300KiB here
>* Removal of the (clk != CLOCK_MONOTONIC_RAW) case
>
>Shuffling code around, even without any impact on semantics, sometimes fixes
>the issue. Compiling the vDSO with UBSAN didn't show anything.
>
>
>Thomas
>
>> > > > > [1] https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/syscalls/clock_gettime/clock_gettime03.c
>> > > > > [2] https://koji.fedoraproject.org/koji/buildinfo?buildID=2704401
>> > > >
>> >
>>
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 08/19] vdso/gettimeofday: Prepare do_hres_timens() for introduction of struct vdso_clock
2025-04-25 14:37 ` Jan Stancek
@ 2025-04-25 15:34 ` Thomas Weißschuh
0 siblings, 0 replies; 32+ messages in thread
From: Thomas Weißschuh @ 2025-04-25 15:34 UTC (permalink / raw)
To: Jan Stancek
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino,
Catalin Marinas, Will Deacon, Anna-Maria Behnsen,
Frederic Weisbecker, Ingo Molnar, Borislav Petkov, Dave Hansen,
x86, H. Peter Anvin, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Arnd Bergmann, linux-kernel, linux-arm-kernel,
linuxppc-dev, linux-s390, linux-arch, Nam Cao
On Fri, Apr 25, 2025 at 04:37:47PM +0200, Jan Stancek wrote:
> On Fri, Apr 25, 2025 at 03:40:55PM +0200, Thomas Weißschuh wrote:
>
> <snip>
>
> >
> > Some more information:
> >
> > The crash comes from the address arithmetic in "vc = &vc[CS_RAW]" going wrong.
>
> That appears to be because it's not doing any arithmetic, but using value
> from some linker-generated symbol (I'll refer to it as "7a8").
The compiler emits a absolute relocation:
$ objdump -r --disassemble-all -z arch/arm64/kernel/vdso/vgettimeofday.o
...
Disassembly of section .text:
0000000000000000 <__kernel_clock_gettime>:
...
29c: d503201f nop
2a0: 00000000 udf #0
2a0: R_AARCH64_ABS64 vdso_u_time_data+0x100e0
2a4: 00000000 udf #0
Which then gets resolved by the linker to the absolute address from the
symbol table.
As the vDSO is placed completely dynamically this can't work.
One central idea behind the vDSO is that the compiler will only ever generate
PC-relative relocations. To force this the symbols are marked as "hidden".
But apparently that assumption is not always true.
One way around would be to add an implementation of __arch_get_vdso_u_time_data()
to arch/arm64/include/asm/vdso/gettimeofday.h which mirrors the one from
arch/arm64/include/asm/vdso/compat_gettimeofday.h.
The generated code does look a lot better (to my untrained eye).
(Another workaround I stumbled upon was -fno-ipa-cp)
__arch_get_vdso_u_time_data() can also be simplifed with OPTIMIZER_HIDE_VAR().
I have been wondering before if this should be done in the generic vDSO code.
And on top of that we should validate at buildtime that no absolute relocations
sneak in.
Thomas
^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2025-04-25 15:34 UTC | newest]
Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-03 11:11 [PATCH 00/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock Thomas Weißschuh
2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 01/19] vdso: Introduce vdso/cache.h Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 02/19] arm64: Make asm/cache.h compatible with vDSO Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 03/19] vdso: Make vdso_time_data cacheline aligned Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 04/19] vdso/datapage: Define for vdso_data to make rework of vdso possible Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 05/19] vdso/helpers: Prepare introduction of struct vdso_clock Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 06/19] vdso/gettimeofday: " Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 07/19] vdso/gettimeofday: Prepare do_hres() for " Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 08/19] vdso/gettimeofday: Prepare do_hres_timens() " Thomas Weißschuh
2025-04-24 14:10 ` Jan Stancek
2025-04-24 15:43 ` Thomas Weißschuh
2025-04-24 21:57 ` Jan Stancek
2025-04-25 8:58 ` Thomas Weißschuh
2025-04-25 10:03 ` Jan Stancek
2025-04-25 13:40 ` Thomas Weißschuh
2025-04-25 14:37 ` Jan Stancek
2025-04-25 15:34 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 09/19] vdso/gettimeofday: Prepare do_coarse() " Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 10/19] vdso/gettimeofday: Prepare do_coarse_timens() " Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 11/19] vdso/gettimeofday: Prepare helper functions " Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 12/19] vdso/vsyscall: Prepare " Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 13/19] vdso/namespace: Rename timens_setup_vdso_data() to reflect new vdso_clock struct Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 14/19] time/namespace: Prepare introduction of struct vdso_clock Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 15/19] x86/vdso: " Thomas Weißschuh
2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 16/19] arm64/vdso: " Thomas Weißschuh
2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 17/19] powerpc/vdso: " Thomas Weißschuh
2025-03-03 11:11 ` Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 18/19] vdso: Move arch related data before basetime Thomas Weißschuh
2025-03-03 11:11 ` [PATCH 19/19] vdso: Rework struct vdso_time_data and introduce struct vdso_clock 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).