* [PATCH] sparc64: vdso: Flush the D-cache after updating the time data
@ 2026-09-17 8:25 Stian Halseth
2026-09-25 7:55 ` Thomas Weißschuh
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Stian Halseth @ 2026-09-17 8:25 UTC (permalink / raw)
To: davem, Andreas Larsson
Cc: Thomas Weißschuh, Thomas Gleixner, sparclinux, linux-kernel,
Stian Halseth
The vDSO time data page is written through the kernel linear mapping
and read through a user mapping placed without colour alignment. On
sun4u the L1 D-cache is virtually indexed, so when the two differ in
colour the timekeeping CPU's stores leave stale lines behind the user
alias in its own D-cache. The seqcount does not catch this: the line
holding seq and the lines holding the clock data are refreshed
independently, so a reader sees an even, unchanged seq together with a
mix of old and new fields.
On a Sun Fire V240 (UltraSPARC IIIi, clocksource stick) this makes
clock_gettime(CLOCK_MONOTONIC) via the vDSO wrong for most calls on
the tick CPU, by multiples of the 10 ms tick and up to a second, in
about half of all processes: those that drew the other colour at exec.
The syscall is correct, so a deadline derived from the vDSO can already
be in the past when handed to the kernel; MySQL's InnoDB
log_files_governor thread spun at ~24000 futex calls/s on ETIMEDOUT
this way.
Flush the page after every update, as arm does. The helper lives in
vma.c because asm/vdso/vsyscall.h is also compiled into the vDSO, where
asm/cacheflush.h is unavailable. On sun4v flush_dcache_folio() is a
no-op, the caches there being physically indexed.
The sparc-specific vDSO that v7.1-rc1 replaced had the same defect
(reproduced on 6.18), so the bug is as old as the sparc vDSO, but this
fix relies on __arch_sync_vdso_time_data() and applies from v7.1-rc1.
Verified on 7.2.6: 32 probe runs across mapping colours show no vDSO
deviation, and MySQL's governor idles at 0.2% CPU across five restarts
of an unpatched build.
Fixes: 9a08862a5d2e ("vDSO for sparc")
Closes: https://github.com/sparclinux/issues/issues/94
Signed-off-by: Stian Halseth <stian@itx.no>
---
arch/sparc/include/asm/vdso/vsyscall.h | 10 ++++++++++
arch/sparc/vdso/vma.c | 6 ++++++
2 files changed, 16 insertions(+)
diff --git a/arch/sparc/include/asm/vdso/vsyscall.h b/arch/sparc/include/asm/vdso/vsyscall.h
index 8bfe703fedc5..4852f122ce47 100644
--- a/arch/sparc/include/asm/vdso/vsyscall.h
+++ b/arch/sparc/include/asm/vdso/vsyscall.h
@@ -5,6 +5,16 @@
#define __VDSO_PAGES 4
+#ifndef __ASSEMBLER__
+
+/* The user mapping may alias the kernel one in the VIPT D-cache. */
+struct vdso_time_data;
+void __arch_sync_vdso_time_data(struct vdso_time_data *vdata);
+#define __arch_sync_vdso_time_data __arch_sync_vdso_time_data
+
+#endif /* !__ASSEMBLER__ */
+
+/* The asm-generic header needs to be included after the definitions above */
#include <asm-generic/vdso/vsyscall.h>
#endif /* _ASM_SPARC_VDSO_VSYSCALL_H */
diff --git a/arch/sparc/vdso/vma.c b/arch/sparc/vdso/vma.c
index 60029d60f4d3..fe6a47af6b05 100644
--- a/arch/sparc/vdso/vma.c
+++ b/arch/sparc/vdso/vma.c
@@ -27,6 +27,12 @@
unsigned int __read_mostly vdso_enabled = 1;
+/* Called by the timekeeping code after every update of the vDSO data. */
+void __arch_sync_vdso_time_data(struct vdso_time_data *vdata)
+{
+ flush_dcache_page(virt_to_page(vdata));
+}
+
#ifdef CONFIG_SPARC64
static struct vm_special_mapping vdso_mapping64 = {
.name = "[vdso]"
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] sparc64: vdso: Flush the D-cache after updating the time data
2026-09-17 8:25 [PATCH] sparc64: vdso: Flush the D-cache after updating the time data Stian Halseth
@ 2026-09-25 7:55 ` Thomas Weißschuh
2026-09-25 8:02 ` [PATCH v2] " Stian Halseth
2026-09-27 20:49 ` [PATCH] " Imre Kaloz
2 siblings, 0 replies; 4+ messages in thread
From: Thomas Weißschuh @ 2026-09-25 7:55 UTC (permalink / raw)
To: Stian Halseth
Cc: davem, Andreas Larsson, Thomas Gleixner, sparclinux, linux-kernel
On Thu, Sep 17, 2026 at 10:25:47AM +0200, Stian Halseth wrote:
> The vDSO time data page is written through the kernel linear mapping
> and read through a user mapping placed without colour alignment. On
> sun4u the L1 D-cache is virtually indexed, so when the two differ in
> colour the timekeeping CPU's stores leave stale lines behind the user
> alias in its own D-cache. The seqcount does not catch this: the line
> holding seq and the lines holding the clock data are refreshed
> independently, so a reader sees an even, unchanged seq together with a
> mix of old and new fields.
(...)
> Fixes: 9a08862a5d2e ("vDSO for sparc")
I'd like to *also* have a fixes tag for the migration to the generic
infrastructure here:
Fixes: 7c5fc16c7a56 ("sparc64: vdso: Switch to the generic vDSO library")
While it was broken before, the diff is against that commit.
> Closes: https://github.com/sparclinux/issues/issues/94
> Signed-off-by: Stian Halseth <stian@itx.no>
Reviewed-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> ---
> arch/sparc/include/asm/vdso/vsyscall.h | 10 ++++++++++
> arch/sparc/vdso/vma.c | 6 ++++++
> 2 files changed, 16 insertions(+)
(...)
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2] sparc64: vdso: Flush the D-cache after updating the time data
2026-09-17 8:25 [PATCH] sparc64: vdso: Flush the D-cache after updating the time data Stian Halseth
2026-09-25 7:55 ` Thomas Weißschuh
@ 2026-09-25 8:02 ` Stian Halseth
2026-09-27 20:49 ` [PATCH] " Imre Kaloz
2 siblings, 0 replies; 4+ messages in thread
From: Stian Halseth @ 2026-09-25 8:02 UTC (permalink / raw)
To: davem, Andreas Larsson
Cc: Thomas Weißschuh, Thomas Gleixner, sparclinux, linux-kernel,
Stian Halseth
The vDSO time data page is written through the kernel linear mapping
and read through a user mapping placed without colour alignment. On
sun4u the L1 D-cache is virtually indexed, so when the two differ in
colour the timekeeping CPU's stores leave stale lines behind the user
alias in its own D-cache. The seqcount does not catch this: the line
holding seq and the lines holding the clock data are refreshed
independently, so a reader sees an even, unchanged seq together with a
mix of old and new fields.
On a Sun Fire V240 (UltraSPARC IIIi, clocksource stick) this makes
clock_gettime(CLOCK_MONOTONIC) via the vDSO wrong for most calls on
the tick CPU, by multiples of the 10 ms tick and up to a second, in
about half of all processes: those that drew the other colour at exec.
The syscall is correct, so a deadline derived from the vDSO can already
be in the past when handed to the kernel; MySQL's InnoDB
log_files_governor thread spun at ~24000 futex calls/s on ETIMEDOUT
this way.
Flush the page after every update, as arm does. The helper lives in
vma.c because asm/vdso/vsyscall.h is also compiled into the vDSO, where
asm/cacheflush.h is unavailable. On sun4v flush_dcache_folio() is a
no-op, the caches there being physically indexed.
The sparc-specific vDSO that v7.1-rc1 replaced had the same defect
(reproduced on 6.18), so the bug is as old as the sparc vDSO, but this
fix relies on __arch_sync_vdso_time_data() and applies from v7.1-rc1.
Verified on 7.2.6: 32 probe runs across mapping colours show no vDSO
deviation, and MySQL's governor idles at 0.2% CPU across five restarts
of an unpatched build.
Fixes: 9a08862a5d2e ("vDSO for sparc")
Fixes: 7c5fc16c7a56 ("sparc64: vdso: Switch to the generic vDSO library")
Closes: https://github.com/sparclinux/issues/issues/94
Signed-off-by: Stian Halseth <stian@itx.no>
Reviewed-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
v2: add the Fixes: tag for the switch to the generic vDSO library, as
the diff is against that code (Thomas); collect Reviewed-by.
arch/sparc/include/asm/vdso/vsyscall.h | 10 ++++++++++
arch/sparc/vdso/vma.c | 6 ++++++
2 files changed, 16 insertions(+)
diff --git a/arch/sparc/include/asm/vdso/vsyscall.h b/arch/sparc/include/asm/vdso/vsyscall.h
index 8bfe703fedc5..4852f122ce47 100644
--- a/arch/sparc/include/asm/vdso/vsyscall.h
+++ b/arch/sparc/include/asm/vdso/vsyscall.h
@@ -5,6 +5,16 @@
#define __VDSO_PAGES 4
+#ifndef __ASSEMBLER__
+
+/* The user mapping may alias the kernel one in the VIPT D-cache. */
+struct vdso_time_data;
+void __arch_sync_vdso_time_data(struct vdso_time_data *vdata);
+#define __arch_sync_vdso_time_data __arch_sync_vdso_time_data
+
+#endif /* !__ASSEMBLER__ */
+
+/* The asm-generic header needs to be included after the definitions above */
#include <asm-generic/vdso/vsyscall.h>
#endif /* _ASM_SPARC_VDSO_VSYSCALL_H */
diff --git a/arch/sparc/vdso/vma.c b/arch/sparc/vdso/vma.c
index 60029d60f4d3..fe6a47af6b05 100644
--- a/arch/sparc/vdso/vma.c
+++ b/arch/sparc/vdso/vma.c
@@ -27,6 +27,12 @@
unsigned int __read_mostly vdso_enabled = 1;
+/* Called by the timekeeping code after every update of the vDSO data. */
+void __arch_sync_vdso_time_data(struct vdso_time_data *vdata)
+{
+ flush_dcache_page(virt_to_page(vdata));
+}
+
#ifdef CONFIG_SPARC64
static struct vm_special_mapping vdso_mapping64 = {
.name = "[vdso]"
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] sparc64: vdso: Flush the D-cache after updating the time data
2026-09-17 8:25 [PATCH] sparc64: vdso: Flush the D-cache after updating the time data Stian Halseth
2026-09-25 7:55 ` Thomas Weißschuh
2026-09-25 8:02 ` [PATCH v2] " Stian Halseth
@ 2026-09-27 20:49 ` Imre Kaloz
2 siblings, 0 replies; 4+ messages in thread
From: Imre Kaloz @ 2026-09-27 20:49 UTC (permalink / raw)
To: Stian Halseth
Cc: davem, Andreas Larsson, Thomas Weissschuh, Thomas Gleixner,
sparclinux, linux-kernel
On Thu, 17 Sep 2026 10:25:47 +0200
Stian Halseth <stian@itx.no> wrote:
> On a Sun Fire V240 (UltraSPARC IIIi, clocksource stick) this makes
> clock_gettime(CLOCK_MONOTONIC) via the vDSO wrong for most calls on
> the tick CPU, by multiples of the 10 ms tick and up to a second, in
> about half of all processes: those that drew the other colour at
> exec.
Hi Stian,
Confirmed on a Sun Ultra 45 (UltraSPARC IIIi, SMP). The unpatched
kernel's vDSO clock_gettime() went stale on 3 out of 3 boots, up to
85% of CLOCK_MONOTONIC/CLOCK_REALTIME reads on the affected CPU, with
a lag up to 1492 ms. A kernel carrying this patch showed 0% stale
reads on 3 out of 3 boots.
Tested-by: Imre Kaloz <kaloz@kernel.org>
Best,
Imre
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-09-27 20:50 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-17 8:25 [PATCH] sparc64: vdso: Flush the D-cache after updating the time data Stian Halseth
2026-09-25 7:55 ` Thomas Weißschuh
2026-09-25 8:02 ` [PATCH v2] " Stian Halseth
2026-09-27 20:49 ` [PATCH] " Imre Kaloz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®