* [RFC PATCH 0/2] perf: user stack dump on sparc64 needs an arch hook
@ 2026-09-22 13:56 Stian Halseth
2026-09-22 13:56 ` [RFC PATCH 1/2] perf/core: Let an arch prepare the user stack before it is dumped Stian Halseth
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Stian Halseth @ 2026-09-22 13:56 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Andreas Larsson, David S. Miller
Cc: Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, linux-perf-users, sparclinux, linux-kernel,
Stian Halseth
I am adding HAVE_PERF_REGS and HAVE_PERF_USER_STACK_DUMP to sparc64, so
that perf record --call-graph dwarf and elfutils' eu-stackprof work
there. The sparc side (patch 2) is straightforward and follows parisc.
One thing does not fit in arch code, and I would like to get the shape
of that agreed before sending the rest.
The user stack dump copies the stack as it is in memory and assumes the
call chain is there. On sparc it may not be: the sampled register
window's %l/%i registers, which hold the frame pointer and return
address the unwinder starts from (the CFI after `save` defines the CFA
in terms of %i6), stay in the register file until a window spills. The
kernel already deals with this wherever it exposes user stack memory:
perf_callchain_user() on sparc calls flushw_user() before walking the
chain, and ptrace does the same. The stack dump has no arch entry
point where that could happen.
I looked for a sparc-only way and did not find a correct one:
- flushing in the sparc PMU interrupt handler misses software events
(cpu-clock, tracepoints), which reach perf_event_overflow() without
passing through it;
- perf_user_stack_pointer() is private to kernel/events/internal.h, so
the arch cannot override it;
- perf_reg_abi() is called at the right time but is a query, and a
flush as a side effect of it would be wrong.
So patch 1 adds a no-op hook in the style of perf_arch_misc_flags():
perf_arch_prepare_ustack(), called from perf_prepare_sample() when
PERF_SAMPLE_STACK_USER is requested and user regs exist. Patch 2 is the
sparc64 implementation and its user. Happy to take a different name or
placement.
Tested on an UltraSPARC T4-1 on 7.3-rc4 with a perf tool taught the
sparc registers (that patch, and the matching elfutils backend, follow
once the hook is settled): register values check out against known
contents, and --call-graph dwarf unwinds correctly for both cycles and
cpu-clock. perf stat/record/record -g are unchanged.
Link: https://github.com/sparclinux/issues/issues/99
Stian Halseth (2):
perf/core: Let an arch prepare the user stack before it is dumped
sparc64: Support PERF_SAMPLE_REGS_USER and PERF_SAMPLE_STACK_USER
arch/sparc/Kconfig | 2 +
arch/sparc/include/asm/perf_event.h | 3 ++
arch/sparc/include/uapi/asm/perf_regs.h | 33 +++++++++++++
arch/sparc/kernel/Makefile | 2 +-
arch/sparc/kernel/perf_regs.c | 65 +++++++++++++++++++++++++
include/linux/perf_event.h | 7 +++
kernel/events/core.c | 2 +
7 files changed, 113 insertions(+), 1 deletion(-)
create mode 100644 arch/sparc/include/uapi/asm/perf_regs.h
create mode 100644 arch/sparc/kernel/perf_regs.c
--
2.55.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [RFC PATCH 1/2] perf/core: Let an arch prepare the user stack before it is dumped
2026-09-22 13:56 [RFC PATCH 0/2] perf: user stack dump on sparc64 needs an arch hook Stian Halseth
@ 2026-09-22 13:56 ` Stian Halseth
2026-09-22 13:56 ` [RFC PATCH 2/2] sparc64: Support PERF_SAMPLE_REGS_USER and PERF_SAMPLE_STACK_USER Stian Halseth
2026-09-22 17:04 ` [RFC PATCH 0/2] perf: user stack dump on sparc64 needs an arch hook Magnus Lindholm
2 siblings, 0 replies; 5+ messages in thread
From: Stian Halseth @ 2026-09-22 13:56 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Andreas Larsson, David S. Miller
Cc: Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, linux-perf-users, sparclinux, linux-kernel,
Stian Halseth
PERF_SAMPLE_STACK_USER copies the user stack as it is in memory, which
assumes the whole call chain is there. On sparc the sampled window's
%l and %i registers, including the frame pointer and return address an
unwinder starts from, may still be in the register file: they only
reach the stack when a window spills. perf_callchain_user() already
handles this for the callchain by calling flushw_user() first; the user
stack dump has no equivalent arch entry point.
Add perf_arch_prepare_ustack(), a no-op by default, called from
perf_prepare_sample() before the dump size is computed, so an arch can
write back whatever part of the user's stack state it still holds in
registers. Doing this in the arch PMU interrupt handler would not do:
software events such as cpu-clock reach perf_event_overflow() without
passing through it.
Signed-off-by: Stian Halseth <stian@itx.no>
---
include/linux/perf_event.h | 7 +++++++
kernel/events/core.c | 2 ++
2 files changed, 9 insertions(+)
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 5842552294c1..758b98b75346 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1815,6 +1815,13 @@ extern unsigned long perf_instruction_pointer(struct perf_event *event,
#ifndef perf_arch_bpf_user_pt_regs
# define perf_arch_bpf_user_pt_regs(regs) regs
#endif
+/*
+ * Called before the user stack of the current task is dumped, for an arch
+ * that still holds part of the user's stack state in registers.
+ */
+#ifndef perf_arch_prepare_ustack
+static inline void perf_arch_prepare_ustack(void) { }
+#endif
#ifndef perf_arch_guest_misc_flags
static inline unsigned long perf_arch_guest_misc_flags(struct pt_regs *regs)
diff --git a/kernel/events/core.c b/kernel/events/core.c
index db7b76d6b68a..90fb35c7d279 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -8718,6 +8718,8 @@ void perf_prepare_sample(struct perf_sample_data *data,
u16 header_size = perf_sample_data_size(data, event);
u16 size = sizeof(u64);
+ if (data->regs_user.regs)
+ perf_arch_prepare_ustack();
stack_size = perf_sample_ustack_size(stack_size, header_size,
data->regs_user.regs);
--
2.55.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [RFC PATCH 2/2] sparc64: Support PERF_SAMPLE_REGS_USER and PERF_SAMPLE_STACK_USER
2026-09-22 13:56 [RFC PATCH 0/2] perf: user stack dump on sparc64 needs an arch hook Stian Halseth
2026-09-22 13:56 ` [RFC PATCH 1/2] perf/core: Let an arch prepare the user stack before it is dumped Stian Halseth
@ 2026-09-22 13:56 ` Stian Halseth
2026-09-22 17:04 ` [RFC PATCH 0/2] perf: user stack dump on sparc64 needs an arch hook Magnus Lindholm
2 siblings, 0 replies; 5+ messages in thread
From: Stian Halseth @ 2026-09-22 13:56 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Andreas Larsson, David S. Miller
Cc: Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, linux-perf-users, sparclinux, linux-kernel,
Stian Halseth
Select HAVE_PERF_REGS and HAVE_PERF_USER_STACK_DUMP and add the
perf_regs implementation. The exposed registers mirror struct pt_regs:
%g0-%g7, %o0-%o7 (named from the user's point of view; pt_regs calls
them UREG_I*), %tstate, PC, NPC and %y. %o6 is reported as held in the
register, i.e. with the 2047 stack bias for a 64-bit task, the same as
ptrace and user_stack_pointer(). Values of a 32-bit task are truncated
to 32 bits as genregs32_get() does, since the hardware does not
zero-extend them.
perf_arch_prepare_ustack() flushes the user register windows so the
sampled window's %l and %i registers are in the dumped stack, where a
DWARF unwinder needs them: the CFI of a function after `save` defines
the CFA in terms of %i6.
This makes perf record --call-graph dwarf and eu-stackprof usable on
sparc64.
Signed-off-by: Stian Halseth <stian@itx.no>
---
arch/sparc/Kconfig | 2 +
arch/sparc/include/asm/perf_event.h | 3 ++
arch/sparc/include/uapi/asm/perf_regs.h | 33 +++++++++++++
arch/sparc/kernel/Makefile | 2 +-
arch/sparc/kernel/perf_regs.c | 65 +++++++++++++++++++++++++
5 files changed, 104 insertions(+), 1 deletion(-)
create mode 100644 arch/sparc/include/uapi/asm/perf_regs.h
create mode 100644 arch/sparc/kernel/perf_regs.c
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index ab77d3f2536e..9d7f575f359d 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -93,6 +93,8 @@ config SPARC64
select RTC_DRV_SUN4V
select RTC_DRV_STARFIRE
select HAVE_PERF_EVENTS
+ select HAVE_PERF_REGS
+ select HAVE_PERF_USER_STACK_DUMP
select PERF_USE_VMALLOC
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select HAVE_C_RECORDMCOUNT
diff --git a/arch/sparc/include/asm/perf_event.h b/arch/sparc/include/asm/perf_event.h
index c2aec0c7f4f5..03f1ab1618b9 100644
--- a/arch/sparc/include/asm/perf_event.h
+++ b/arch/sparc/include/asm/perf_event.h
@@ -25,6 +25,9 @@ do { \
(regs)->u_regs[UREG_I6] = _fp; \
(regs)->u_regs[UREG_I7] = _i7; \
} while (0)
+
+void perf_arch_prepare_ustack(void);
+#define perf_arch_prepare_ustack perf_arch_prepare_ustack
#endif
#endif
diff --git a/arch/sparc/include/uapi/asm/perf_regs.h b/arch/sparc/include/uapi/asm/perf_regs.h
new file mode 100644
index 000000000000..17f14335d6c0
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/perf_regs.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_ASM_SPARC_PERF_REGS_H
+#define _UAPI_ASM_SPARC_PERF_REGS_H
+
+/*
+ * Mirrors struct pt_regs. O6 is %sp as held in the register, i.e. biased
+ * by 2047 for a 64-bit task.
+ */
+enum perf_event_sparc_regs {
+ PERF_REG_SPARC_G0,
+ PERF_REG_SPARC_G1,
+ PERF_REG_SPARC_G2,
+ PERF_REG_SPARC_G3,
+ PERF_REG_SPARC_G4,
+ PERF_REG_SPARC_G5,
+ PERF_REG_SPARC_G6,
+ PERF_REG_SPARC_G7,
+ PERF_REG_SPARC_O0,
+ PERF_REG_SPARC_O1,
+ PERF_REG_SPARC_O2,
+ PERF_REG_SPARC_O3,
+ PERF_REG_SPARC_O4,
+ PERF_REG_SPARC_O5,
+ PERF_REG_SPARC_O6,
+ PERF_REG_SPARC_O7,
+ PERF_REG_SPARC_TSTATE,
+ PERF_REG_SPARC_PC,
+ PERF_REG_SPARC_NPC,
+ PERF_REG_SPARC_Y,
+ PERF_REG_SPARC_MAX
+};
+
+#endif /* _UAPI_ASM_SPARC_PERF_REGS_H */
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 497b5714fa8f..a3dd92247c3b 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -113,7 +113,7 @@ obj-$(CONFIG_AUDIT) += audit.o
audit--$(CONFIG_AUDIT) := compat_audit.o
obj-$(CONFIG_COMPAT) += $(audit--y)
-pc--$(CONFIG_PERF_EVENTS) := perf_event.o
+pc--$(CONFIG_PERF_EVENTS) := perf_event.o perf_regs.o
obj-$(CONFIG_SPARC64) += $(pc--y)
obj-$(CONFIG_UPROBES) += uprobes.o
diff --git a/arch/sparc/kernel/perf_regs.c b/arch/sparc/kernel/perf_regs.c
new file mode 100644
index 000000000000..644a0a11cb90
--- /dev/null
+++ b/arch/sparc/kernel/perf_regs.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/perf_event.h>
+#include <linux/perf_regs.h>
+#include <linux/sched/task_stack.h>
+#include <asm/cacheflush.h>
+#include <asm/ptrace.h>
+
+u64 perf_reg_value(struct pt_regs *regs, int idx)
+{
+ u64 val;
+
+ switch (idx) {
+ case PERF_REG_SPARC_G0 ... PERF_REG_SPARC_O7:
+ val = regs->u_regs[idx];
+ break;
+ case PERF_REG_SPARC_TSTATE:
+ return regs->tstate;
+ case PERF_REG_SPARC_PC:
+ val = regs->tpc;
+ break;
+ case PERF_REG_SPARC_NPC:
+ val = regs->tnpc;
+ break;
+ case PERF_REG_SPARC_Y:
+ return regs->y;
+ default:
+ WARN_ON_ONCE(1);
+ return 0;
+ }
+
+ if (test_thread_flag(TIF_32BIT))
+ val = (u32)val;
+
+ return val;
+}
+
+#define REG_RESERVED (~((1ULL << PERF_REG_SPARC_MAX) - 1))
+
+int perf_reg_validate(u64 mask)
+{
+ if (!mask || mask & REG_RESERVED)
+ return -EINVAL;
+
+ return 0;
+}
+
+u64 perf_reg_abi(struct task_struct *task)
+{
+ if (test_tsk_thread_flag(task, TIF_32BIT))
+ return PERF_SAMPLE_REGS_ABI_32;
+
+ return PERF_SAMPLE_REGS_ABI_64;
+}
+
+void perf_get_regs_user(struct perf_regs *regs_user,
+ struct pt_regs *regs)
+{
+ regs_user->regs = task_pt_regs(current);
+ regs_user->abi = perf_reg_abi(current);
+}
+
+void perf_arch_prepare_ustack(void)
+{
+ flushw_user();
+}
--
2.55.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFC PATCH 0/2] perf: user stack dump on sparc64 needs an arch hook
2026-09-22 13:56 [RFC PATCH 0/2] perf: user stack dump on sparc64 needs an arch hook Stian Halseth
2026-09-22 13:56 ` [RFC PATCH 1/2] perf/core: Let an arch prepare the user stack before it is dumped Stian Halseth
2026-09-22 13:56 ` [RFC PATCH 2/2] sparc64: Support PERF_SAMPLE_REGS_USER and PERF_SAMPLE_STACK_USER Stian Halseth
@ 2026-09-22 17:04 ` Magnus Lindholm
2026-09-22 20:02 ` Stian Halseth
2 siblings, 1 reply; 5+ messages in thread
From: Magnus Lindholm @ 2026-09-22 17:04 UTC (permalink / raw)
To: Stian Halseth
Cc: Peter Zijlstra, Ingo Molnar, Andreas Larsson, David S. Miller,
Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, linux-perf-users, sparclinux, linux-kernel
Hi Stian,
On Tue, Sep 22, 2026 at 4:38 PM Stian Halseth <stian@itx.no> wrote:
>
> I am adding HAVE_PERF_REGS and HAVE_PERF_USER_STACK_DUMP to sparc64, so
> that perf record --call-graph dwarf and elfutils' eu-stackprof work
> there. The sparc side (patch 2) is straightforward and follows parisc.
> One thing does not fit in arch code, and I would like to get the shape
> of that agreed before sending the rest.
>
> The user stack dump copies the stack as it is in memory and assumes the
> call chain is there. On sparc it may not be: the sampled register
> window's %l/%i registers, which hold the frame pointer and return
> address the unwinder starts from (the CFI after `save` defines the CFA
> in terms of %i6), stay in the register file until a window spills. The
> kernel already deals with this wherever it exposes user stack memory:
> perf_callchain_user() on sparc calls flushw_user() before walking the
> chain, and ptrace does the same. The stack dump has no arch entry
> point where that could happen.
>
> I looked for a sparc-only way and did not find a correct one:
>
> - flushing in the sparc PMU interrupt handler misses software events
> (cpu-clock, tracepoints), which reach perf_event_overflow() without
> passing through it;
> - perf_user_stack_pointer() is private to kernel/events/internal.h, so
> the arch cannot override it;
> - perf_reg_abi() is called at the right time but is a query, and a
> flush as a side effect of it would be wrong.
>
> So patch 1 adds a no-op hook in the style of perf_arch_misc_flags():
> perf_arch_prepare_ustack(), called from perf_prepare_sample() when
> PERF_SAMPLE_STACK_USER is requested and user regs exist. Patch 2 is the
> sparc64 implementation and its user. Happy to take a different name or
> placement.
>
> Tested on an UltraSPARC T4-1 on 7.3-rc4 with a perf tool taught the
> sparc registers (that patch, and the matching elfutils backend, follow
> once the hook is settled): register values check out against known
> contents, and --call-graph dwarf unwinds correctly for both cycles and
> cpu-clock. perf stat/record/record -g are unchanged.
>
> Link: https://github.com/sparclinux/issues/issues/99
>
> Stian Halseth (2):
> perf/core: Let an arch prepare the user stack before it is dumped
> sparc64: Support PERF_SAMPLE_REGS_USER and PERF_SAMPLE_STACK_USER
>
> arch/sparc/Kconfig | 2 +
> arch/sparc/include/asm/perf_event.h | 3 ++
> arch/sparc/include/uapi/asm/perf_regs.h | 33 +++++++++++++
> arch/sparc/kernel/Makefile | 2 +-
> arch/sparc/kernel/perf_regs.c | 65 +++++++++++++++++++++++++
> include/linux/perf_event.h | 7 +++
> kernel/events/core.c | 2 +
> 7 files changed, 113 insertions(+), 1 deletion(-)
> create mode 100644 arch/sparc/include/uapi/asm/perf_regs.h
> create mode 100644 arch/sparc/kernel/perf_regs.c
>
> --
> 2.55.0
>
Very nice series, thanks for working on this!
I built and booted the series on a sparc64 box and haven't
noticed any regressions so far.
I also smoke-tested the new interfaces from 64-bit userspace with a
small standalone C program using perf_event_open() and software
cpu-clock events. The register-only, stack-only, and combined
register/stack tests all passed. The test does not use tools/perf or
request PERF_SAMPLE_CALLCHAIN. I haven't tested end-to-end DWARF
unwinding yet.
I see that you plan to post the userspace changes once the hook is
settled. Could you include the tools/perf support in the next revision,
or post it as a follow-up or linked companion series? Having that
available, along with a link to the matching elfutils changes, would
make testing easier and let us exercise the intended DWARF unwinding
use case directly.
Also, could you update the sparc entries from TODO to ok in:
Documentation/features/perf/perf-regs/arch-support.txt
Documentation/features/perf/perf-stackdump/arch-support.txt
Those updates would fit naturally in patch 2 alongside the
HAVE_PERF_REGS and HAVE_PERF_USER_STACK_DUMP selections.
Thanks,
Magnus
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFC PATCH 0/2] perf: user stack dump on sparc64 needs an arch hook
2026-09-22 17:04 ` [RFC PATCH 0/2] perf: user stack dump on sparc64 needs an arch hook Magnus Lindholm
@ 2026-09-22 20:02 ` Stian Halseth
0 siblings, 0 replies; 5+ messages in thread
From: Stian Halseth @ 2026-09-22 20:02 UTC (permalink / raw)
To: Magnus Lindholm
Cc: Peter Zijlstra, Ingo Molnar, Andreas Larsson, David S. Miller,
Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, linux-perf-users, sparclinux, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2245 bytes --]
Hi Magnus, thanks for the testing and feedback.
Almost done with a v2.
It has some minor changes based on the AI bot feedback, and my comments
to you below.
On Tue, 2026-09-22 at 19:04 +0200, Magnus Lindholm wrote:
>
> Very nice series, thanks for working on this!
>
> I built and booted the series on a sparc64 box and haven't
> noticed any regressions so far.
>
> I also smoke-tested the new interfaces from 64-bit userspace with a
> small standalone C program using perf_event_open() and software
> cpu-clock events. The register-only, stack-only, and combined
> register/stack tests all passed. The test does not use tools/perf or
> request PERF_SAMPLE_CALLCHAIN. I haven't tested end-to-end DWARF
> unwinding yet.
>
> I see that you plan to post the userspace changes once the hook is
> settled. Could you include the tools/perf support in the next
> revision,
> or post it as a follow-up or linked companion series? Having that
> available, along with a link to the matching elfutils changes, would
> make testing easier and let us exercise the intended DWARF unwinding
> use case directly.
Yes, I originally planned to post tools/perf after I got some feedback
on the first patches. Especially since it touches some generic code
that I'm not too familiar with, and I half expect that I have to
rewrite some of it based on maintainer feedback :-)
But since its "just" a RFC patch at this point, I guess I can post the
full series to allow end-to-end testing.
I have mainly focused on the first patches, and the rest was done a bit
faster as a means to validate the "core" changes. It works (TM). I'm
looking through it now, but I probably make a second thorough review of
the entire final series, once the I know what changes I need to make.
I will publish and link to the elfutils changes as well.
>
> Also, could you update the sparc entries from TODO to ok in:
>
> Documentation/features/perf/perf-regs/arch-support.txt
> Documentation/features/perf/perf-stackdump/arch-support.txt
>
> Those updates would fit naturally in patch 2 alongside the
> HAVE_PERF_REGS and HAVE_PERF_USER_STACK_DUMP selections.
Yes, agree.
--
Best regards
Stian Halseth
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-22 20:02 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-22 13:56 [RFC PATCH 0/2] perf: user stack dump on sparc64 needs an arch hook Stian Halseth
2026-09-22 13:56 ` [RFC PATCH 1/2] perf/core: Let an arch prepare the user stack before it is dumped Stian Halseth
2026-09-22 13:56 ` [RFC PATCH 2/2] sparc64: Support PERF_SAMPLE_REGS_USER and PERF_SAMPLE_STACK_USER Stian Halseth
2026-09-22 17:04 ` [RFC PATCH 0/2] perf: user stack dump on sparc64 needs an arch hook Magnus Lindholm
2026-09-22 20:02 ` Stian Halseth
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®