* [PATCH] perf regs: Add alpha support
@ 2026-10-11 20:37 Matt Turner
2026-10-11 20:42 ` sashiko-bot
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Matt Turner @ 2026-10-11 20:37 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, James Clark
Cc: linux-kernel, linux-perf-users, Magnus Lindholm,
Richard Henderson, linux-alpha, Matt Turner
Add the alpha perf register tables so that -I/--user-regs and
--call-graph dwarf work.
r9-r15 cannot be sampled and are left out of the mask. Perf register
numbers 0-30 are the DWARF numbers. The pc is DWARF 64, the column GCC
uses as the alternate return address column on alpha, so libdw's
frame_nregs is 65.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Matt Turner <mattst88@gmail.com>
---
This depends on the kernel side, "alpha: add HAVE_PERF_REGS and
HAVE_PERF_USER_STACK_DUMP support", posted as part of:
https://lore.kernel.org/r/20261011-alpha-perf-regs-v3-v1-0-3354d135d972@gmail.com
--call-graph dwarf also needs libdw alpha unwinding support (abi_cfi
and frame_nregs), which I am sending to elfutils-devel separately.
Without it, libdw rejects the thread and perf reports the error;
-I/--user-regs work regardless.
---
tools/arch/alpha/include/uapi/asm/perf_regs.h | 45 ++++++++++++++++++++++
tools/perf/arch/alpha/include/perf_regs.h | 16 ++++++++
| 1 +
tools/perf/util/dwarf-regs-arch/Build | 1 +
tools/perf/util/dwarf-regs-arch/dwarf-regs-alpha.c | 14 +++++++
tools/perf/util/dwarf-regs.c | 5 +++
tools/perf/util/include/dwarf-regs.h | 2 +
tools/perf/util/perf-regs-arch/Build | 1 +
tools/perf/util/perf-regs-arch/perf_regs_alpha.c | 34 ++++++++++++++++
tools/perf/util/perf_regs.c | 13 +++++++
tools/perf/util/perf_regs.h | 5 +++
11 files changed, 137 insertions(+)
diff --git a/tools/arch/alpha/include/uapi/asm/perf_regs.h b/tools/arch/alpha/include/uapi/asm/perf_regs.h
new file mode 100644
index 000000000000..da96a31b12fb
--- /dev/null
+++ b/tools/arch/alpha/include/uapi/asm/perf_regs.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_ASM_ALPHA_PERF_REGS_H
+#define _UAPI_ASM_ALPHA_PERF_REGS_H
+
+/*
+ * Indices 0-30 match the hardware (and DWARF) register numbers.
+ * r9-r15 are not saved in pt_regs and cannot be sampled.
+ */
+enum perf_event_alpha_regs {
+ PERF_REG_ALPHA_R0,
+ PERF_REG_ALPHA_R1,
+ PERF_REG_ALPHA_R2,
+ PERF_REG_ALPHA_R3,
+ PERF_REG_ALPHA_R4,
+ PERF_REG_ALPHA_R5,
+ PERF_REG_ALPHA_R6,
+ PERF_REG_ALPHA_R7,
+ PERF_REG_ALPHA_R8,
+ PERF_REG_ALPHA_R9,
+ PERF_REG_ALPHA_R10,
+ PERF_REG_ALPHA_R11,
+ PERF_REG_ALPHA_R12,
+ PERF_REG_ALPHA_R13,
+ PERF_REG_ALPHA_R14,
+ PERF_REG_ALPHA_R15,
+ PERF_REG_ALPHA_R16,
+ PERF_REG_ALPHA_R17,
+ PERF_REG_ALPHA_R18,
+ PERF_REG_ALPHA_R19,
+ PERF_REG_ALPHA_R20,
+ PERF_REG_ALPHA_R21,
+ PERF_REG_ALPHA_R22,
+ PERF_REG_ALPHA_R23,
+ PERF_REG_ALPHA_R24,
+ PERF_REG_ALPHA_R25,
+ PERF_REG_ALPHA_R26,
+ PERF_REG_ALPHA_R27,
+ PERF_REG_ALPHA_R28,
+ PERF_REG_ALPHA_GP,
+ PERF_REG_ALPHA_SP,
+ PERF_REG_ALPHA_PC,
+ PERF_REG_ALPHA_MAX,
+};
+
+#endif /* _UAPI_ASM_ALPHA_PERF_REGS_H */
diff --git a/tools/perf/arch/alpha/include/perf_regs.h b/tools/perf/arch/alpha/include/perf_regs.h
new file mode 100644
index 000000000000..409f3a08af9b
--- /dev/null
+++ b/tools/perf/arch/alpha/include/perf_regs.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef ARCH_PERF_REGS_H
+#define ARCH_PERF_REGS_H
+
+#include <stdlib.h>
+#include <linux/types.h>
+#include <linux/bits.h>
+#include "../../../../arch/alpha/include/uapi/asm/perf_regs.h"
+
+#define PERF_REGS_MAX PERF_REG_ALPHA_MAX
+
+/* The kernel rejects r9-r15. */
+#define PERF_REGS_MASK (GENMASK_ULL(PERF_REG_ALPHA_MAX - 1, 0) & \
+ ~GENMASK_ULL(PERF_REG_ALPHA_R15, PERF_REG_ALPHA_R9))
+
+#endif /* ARCH_PERF_REGS_H */
--git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 531c0e0e84df..9baf83f79e23 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -36,6 +36,7 @@ declare -a FILES=(
"arch/x86/include/asm/msr-index.h"
"arch/x86/lib/x86-opcode-map.txt"
"arch/x86/tools/gen-insn-attr-x86.awk"
+ "arch/alpha/include/uapi/asm/perf_regs.h"
"arch/arm/include/uapi/asm/perf_regs.h"
"arch/arm64/include/uapi/asm/perf_regs.h"
"arch/loongarch/include/uapi/asm/perf_regs.h"
diff --git a/tools/perf/util/dwarf-regs-arch/Build b/tools/perf/util/dwarf-regs-arch/Build
index ceb68ae86fd8..026b7b5ca895 100644
--- a/tools/perf/util/dwarf-regs-arch/Build
+++ b/tools/perf/util/dwarf-regs-arch/Build
@@ -1,3 +1,4 @@
+perf-util-$(CONFIG_LIBDW) += dwarf-regs-alpha.o
perf-util-$(CONFIG_LIBDW) += dwarf-regs-arm64.o
perf-util-$(CONFIG_LIBDW) += dwarf-regs-arm.o
perf-util-$(CONFIG_LIBDW) += dwarf-regs-csky.o
diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-alpha.c b/tools/perf/util/dwarf-regs-arch/dwarf-regs-alpha.c
new file mode 100644
index 000000000000..50fd17096597
--- /dev/null
+++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-alpha.c
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <errno.h>
+#include <dwarf-regs.h>
+#include "../../../arch/alpha/include/uapi/asm/perf_regs.h"
+
+int __get_dwarf_regnum_for_perf_regnum_alpha(int perf_regnum)
+{
+ if (perf_regnum >= PERF_REG_ALPHA_R0 && perf_regnum <= PERF_REG_ALPHA_SP)
+ return perf_regnum;
+ if (perf_regnum == PERF_REG_ALPHA_PC)
+ return 64;
+
+ return -ENOENT;
+}
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index 09aca6304002..3fd71787c658 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -185,6 +185,8 @@ static int get_libdw_frame_nregs(unsigned int machine, unsigned int flags __mayb
return 74;
case EM_MIPS:
return 71;
+ case EM_ALPHA:
+ return 65;
default:
return 0;
}
@@ -228,6 +230,9 @@ int get_dwarf_regnum_for_perf_regnum(int perf_regnum, unsigned int machine,
case EM_MIPS:
reg = __get_dwarf_regnum_for_perf_regnum_mips(perf_regnum);
break;
+ case EM_ALPHA:
+ reg = __get_dwarf_regnum_for_perf_regnum_alpha(perf_regnum);
+ break;
default:
pr_err("ELF MACHINE %x is not supported.\n", machine);
return -ENOENT;
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 1da915c2683a..8d1a981ab8aa 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -105,6 +105,8 @@ int __get_dwarf_regnum_x86_64(const char *name);
int __get_dwarf_regnum_for_perf_regnum_i386(int perf_regnum);
int __get_dwarf_regnum_for_perf_regnum_x86_64(int perf_regnum, int abi);
+int __get_dwarf_regnum_for_perf_regnum_alpha(int perf_regnum);
+
int __get_dwarf_regnum_arm64(const char *name);
int __get_dwarf_regnum_for_perf_regnum_arm(int perf_regnum);
int __get_dwarf_regnum_for_perf_regnum_arm64(int perf_regnum);
diff --git a/tools/perf/util/perf-regs-arch/Build b/tools/perf/util/perf-regs-arch/Build
index be95402aa540..1fbc299775f7 100644
--- a/tools/perf/util/perf-regs-arch/Build
+++ b/tools/perf/util/perf-regs-arch/Build
@@ -1,4 +1,5 @@
perf-util-y += perf_regs_aarch64.o
+perf-util-y += perf_regs_alpha.o
perf-util-y += perf_regs_arm.o
perf-util-y += perf_regs_csky.o
perf-util-y += perf_regs_loongarch.o
diff --git a/tools/perf/util/perf-regs-arch/perf_regs_alpha.c b/tools/perf/util/perf-regs-arch/perf_regs_alpha.c
new file mode 100644
index 000000000000..cb9c8a1cd74b
--- /dev/null
+++ b/tools/perf/util/perf-regs-arch/perf_regs_alpha.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "../perf_regs.h"
+#include "../../arch/alpha/include/perf_regs.h"
+
+static const char * const alpha_reg_names[PERF_REG_ALPHA_MAX] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "gp", "sp", "pc",
+};
+
+uint64_t __perf_reg_mask_alpha(bool intr __maybe_unused)
+{
+ return PERF_REGS_MASK;
+}
+
+const char *__perf_reg_name_alpha(int id)
+{
+ if (id < 0 || id >= PERF_REG_ALPHA_MAX)
+ return NULL;
+
+ return alpha_reg_names[id];
+}
+
+uint64_t __perf_reg_ip_alpha(void)
+{
+ return PERF_REG_ALPHA_PC;
+}
+
+uint64_t __perf_reg_sp_alpha(void)
+{
+ return PERF_REG_ALPHA_SP;
+}
diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c
index c8242b7e1db5..6eb5824f5521 100644
--- a/tools/perf/util/perf_regs.c
+++ b/tools/perf/util/perf_regs.c
@@ -43,6 +43,9 @@ uint64_t perf_intr_reg_mask(uint16_t e_machine, int *abi /*inout*/)
uint64_t mask = 0;
switch (e_machine) {
+ case EM_ALPHA:
+ mask = __perf_reg_mask_alpha(/*intr=*/true);
+ break;
case EM_ARM:
mask = __perf_reg_mask_arm(/*intr=*/true);
break;
@@ -86,6 +89,9 @@ uint64_t perf_user_reg_mask(uint16_t e_machine, int *abi /*inout*/)
uint64_t mask = 0;
switch (e_machine) {
+ case EM_ALPHA:
+ mask = __perf_reg_mask_alpha(/*intr=*/false);
+ break;
case EM_ARM:
mask = __perf_reg_mask_arm(/*intr=*/false);
break;
@@ -129,6 +135,9 @@ const char *perf_reg_name(int id, uint16_t e_machine, uint32_t e_flags, int abi)
const char *reg_name = NULL;
switch (e_machine) {
+ case EM_ALPHA:
+ reg_name = __perf_reg_name_alpha(id);
+ break;
case EM_ARM:
reg_name = __perf_reg_name_arm(id);
break;
@@ -198,6 +207,8 @@ int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
uint64_t perf_arch_reg_ip(uint16_t e_machine)
{
switch (e_machine) {
+ case EM_ALPHA:
+ return __perf_reg_ip_alpha();
case EM_ARM:
return __perf_reg_ip_arm();
case EM_AARCH64:
@@ -227,6 +238,8 @@ uint64_t perf_arch_reg_ip(uint16_t e_machine)
uint64_t perf_arch_reg_sp(uint16_t e_machine)
{
switch (e_machine) {
+ case EM_ALPHA:
+ return __perf_reg_sp_alpha();
case EM_ARM:
return __perf_reg_sp_arm();
case EM_AARCH64:
diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h
index c9f461b6f11f..4134e4eed802 100644
--- a/tools/perf/util/perf_regs.h
+++ b/tools/perf/util/perf_regs.h
@@ -34,6 +34,11 @@ const char *__perf_reg_name_arm64(int id);
uint64_t __perf_reg_ip_arm64(void);
uint64_t __perf_reg_sp_arm64(void);
+uint64_t __perf_reg_mask_alpha(bool intr);
+const char *__perf_reg_name_alpha(int id);
+uint64_t __perf_reg_ip_alpha(void);
+uint64_t __perf_reg_sp_alpha(void);
+
uint64_t __perf_reg_mask_arm(bool intr);
const char *__perf_reg_name_arm(int id);
uint64_t __perf_reg_ip_arm(void);
---
base-commit: bc01105ed65d15787b2eb93ac26e8624a2139e35
change-id: 20261001-alpha-perf-tools-regs-c206a84dec7f
Best regards,
--
Matt Turner <mattst88@gmail.com>
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] perf regs: Add alpha support
2026-10-11 20:37 [PATCH] perf regs: Add alpha support Matt Turner
@ 2026-10-11 20:42 ` sashiko-bot
2026-10-11 21:46 ` Ian Rogers
` (2 subsequent siblings)
3 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-10-11 20:42 UTC (permalink / raw)
To: Matt Turner; +Cc: linux-perf-users
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] perf: missing POSIX header inclusions in perf_regs_alpha.c
--
commit fd8853fd5c4e09ccccf58c76fbab7cdfcce13a97
Author: Matt Turner <mattst88@gmail.com>
perf regs: Add alpha support
Add the alpha perf register tables so that -I/--user-regs and
--call-graph dwarf work. r9-r15 cannot be sampled and are left out of the
mask.
> diff --git a/tools/perf/util/perf-regs-arch/perf_regs_alpha.c b/tools/perf/util/perf-regs-arch/perf_regs_alpha.c
> new file mode 100644
> index 0000000000000..cb9c8a1cd74b9
> --- /dev/null
> +++ b/tools/perf/util/perf-regs-arch/perf_regs_alpha.c
> @@ -0,0 +1,34 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include "../perf_regs.h"
> +#include "../../arch/alpha/include/perf_regs.h"
[Severity: Low]
Does this file need explicit inclusions for stdint.h, stdbool.h, and stddef.h?
The code below relies on uint64_t, bool, and NULL. Relying on implicit header
dependencies might cause build failures on systems using musl libc where these
headers are not automatically included by other subsystem headers.
> +
> +static const char * const alpha_reg_names[PERF_REG_ALPHA_MAX] = {
> + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
> + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
> + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
> + "r24", "r25", "r26", "r27", "r28", "gp", "sp", "pc",
> +};
> +
> +uint64_t __perf_reg_mask_alpha(bool intr __maybe_unused)
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261011-alpha-perf-tools-regs-v1-1-2a5940e22548@gmail.com?part=1
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] perf regs: Add alpha support
2026-10-11 20:37 [PATCH] perf regs: Add alpha support Matt Turner
2026-10-11 20:42 ` sashiko-bot
@ 2026-10-11 21:46 ` Ian Rogers
2026-10-11 21:50 ` Ian Rogers
2026-10-12 17:37 ` Magnus Lindholm
3 siblings, 0 replies; 9+ messages in thread
From: Ian Rogers @ 2026-10-11 21:46 UTC (permalink / raw)
To: Matt Turner
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, James Clark, linux-kernel, linux-perf-users,
Magnus Lindholm, Richard Henderson, linux-alpha
On Sun, Oct 11, 2026 at 1:37 PM Matt Turner <mattst88@gmail.com> wrote:
>
> Add the alpha perf register tables so that -I/--user-regs and
> --call-graph dwarf work.
>
> r9-r15 cannot be sampled and are left out of the mask. Perf register
> numbers 0-30 are the DWARF numbers. The pc is DWARF 64, the column GCC
> uses as the alternate return address column on alpha, so libdw's
> frame_nregs is 65.
>
> Assisted-by: Claude:claude-opus-5-5
> Signed-off-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Thanks!
Ian
> ---
> This depends on the kernel side, "alpha: add HAVE_PERF_REGS and
> HAVE_PERF_USER_STACK_DUMP support", posted as part of:
>
> https://lore.kernel.org/r/20261011-alpha-perf-regs-v3-v1-0-3354d135d972@gmail.com
>
> --call-graph dwarf also needs libdw alpha unwinding support (abi_cfi
> and frame_nregs), which I am sending to elfutils-devel separately.
> Without it, libdw rejects the thread and perf reports the error;
> -I/--user-regs work regardless.
> ---
> tools/arch/alpha/include/uapi/asm/perf_regs.h | 45 ++++++++++++++++++++++
> tools/perf/arch/alpha/include/perf_regs.h | 16 ++++++++
> tools/perf/check-headers.sh | 1 +
> tools/perf/util/dwarf-regs-arch/Build | 1 +
> tools/perf/util/dwarf-regs-arch/dwarf-regs-alpha.c | 14 +++++++
> tools/perf/util/dwarf-regs.c | 5 +++
> tools/perf/util/include/dwarf-regs.h | 2 +
> tools/perf/util/perf-regs-arch/Build | 1 +
> tools/perf/util/perf-regs-arch/perf_regs_alpha.c | 34 ++++++++++++++++
> tools/perf/util/perf_regs.c | 13 +++++++
> tools/perf/util/perf_regs.h | 5 +++
> 11 files changed, 137 insertions(+)
>
> diff --git a/tools/arch/alpha/include/uapi/asm/perf_regs.h b/tools/arch/alpha/include/uapi/asm/perf_regs.h
> new file mode 100644
> index 000000000000..da96a31b12fb
> --- /dev/null
> +++ b/tools/arch/alpha/include/uapi/asm/perf_regs.h
> @@ -0,0 +1,45 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +#ifndef _UAPI_ASM_ALPHA_PERF_REGS_H
> +#define _UAPI_ASM_ALPHA_PERF_REGS_H
> +
> +/*
> + * Indices 0-30 match the hardware (and DWARF) register numbers.
> + * r9-r15 are not saved in pt_regs and cannot be sampled.
> + */
> +enum perf_event_alpha_regs {
> + PERF_REG_ALPHA_R0,
> + PERF_REG_ALPHA_R1,
> + PERF_REG_ALPHA_R2,
> + PERF_REG_ALPHA_R3,
> + PERF_REG_ALPHA_R4,
> + PERF_REG_ALPHA_R5,
> + PERF_REG_ALPHA_R6,
> + PERF_REG_ALPHA_R7,
> + PERF_REG_ALPHA_R8,
> + PERF_REG_ALPHA_R9,
> + PERF_REG_ALPHA_R10,
> + PERF_REG_ALPHA_R11,
> + PERF_REG_ALPHA_R12,
> + PERF_REG_ALPHA_R13,
> + PERF_REG_ALPHA_R14,
> + PERF_REG_ALPHA_R15,
> + PERF_REG_ALPHA_R16,
> + PERF_REG_ALPHA_R17,
> + PERF_REG_ALPHA_R18,
> + PERF_REG_ALPHA_R19,
> + PERF_REG_ALPHA_R20,
> + PERF_REG_ALPHA_R21,
> + PERF_REG_ALPHA_R22,
> + PERF_REG_ALPHA_R23,
> + PERF_REG_ALPHA_R24,
> + PERF_REG_ALPHA_R25,
> + PERF_REG_ALPHA_R26,
> + PERF_REG_ALPHA_R27,
> + PERF_REG_ALPHA_R28,
> + PERF_REG_ALPHA_GP,
> + PERF_REG_ALPHA_SP,
> + PERF_REG_ALPHA_PC,
> + PERF_REG_ALPHA_MAX,
> +};
> +
> +#endif /* _UAPI_ASM_ALPHA_PERF_REGS_H */
> diff --git a/tools/perf/arch/alpha/include/perf_regs.h b/tools/perf/arch/alpha/include/perf_regs.h
> new file mode 100644
> index 000000000000..409f3a08af9b
> --- /dev/null
> +++ b/tools/perf/arch/alpha/include/perf_regs.h
> @@ -0,0 +1,16 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef ARCH_PERF_REGS_H
> +#define ARCH_PERF_REGS_H
> +
> +#include <stdlib.h>
> +#include <linux/types.h>
> +#include <linux/bits.h>
> +#include "../../../../arch/alpha/include/uapi/asm/perf_regs.h"
> +
> +#define PERF_REGS_MAX PERF_REG_ALPHA_MAX
> +
> +/* The kernel rejects r9-r15. */
> +#define PERF_REGS_MASK (GENMASK_ULL(PERF_REG_ALPHA_MAX - 1, 0) & \
> + ~GENMASK_ULL(PERF_REG_ALPHA_R15, PERF_REG_ALPHA_R9))
> +
> +#endif /* ARCH_PERF_REGS_H */
> diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
> index 531c0e0e84df..9baf83f79e23 100755
> --- a/tools/perf/check-headers.sh
> +++ b/tools/perf/check-headers.sh
> @@ -36,6 +36,7 @@ declare -a FILES=(
> "arch/x86/include/asm/msr-index.h"
> "arch/x86/lib/x86-opcode-map.txt"
> "arch/x86/tools/gen-insn-attr-x86.awk"
> + "arch/alpha/include/uapi/asm/perf_regs.h"
> "arch/arm/include/uapi/asm/perf_regs.h"
> "arch/arm64/include/uapi/asm/perf_regs.h"
> "arch/loongarch/include/uapi/asm/perf_regs.h"
> diff --git a/tools/perf/util/dwarf-regs-arch/Build b/tools/perf/util/dwarf-regs-arch/Build
> index ceb68ae86fd8..026b7b5ca895 100644
> --- a/tools/perf/util/dwarf-regs-arch/Build
> +++ b/tools/perf/util/dwarf-regs-arch/Build
> @@ -1,3 +1,4 @@
> +perf-util-$(CONFIG_LIBDW) += dwarf-regs-alpha.o
> perf-util-$(CONFIG_LIBDW) += dwarf-regs-arm64.o
> perf-util-$(CONFIG_LIBDW) += dwarf-regs-arm.o
> perf-util-$(CONFIG_LIBDW) += dwarf-regs-csky.o
> diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-alpha.c b/tools/perf/util/dwarf-regs-arch/dwarf-regs-alpha.c
> new file mode 100644
> index 000000000000..50fd17096597
> --- /dev/null
> +++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-alpha.c
> @@ -0,0 +1,14 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include <errno.h>
> +#include <dwarf-regs.h>
> +#include "../../../arch/alpha/include/uapi/asm/perf_regs.h"
> +
> +int __get_dwarf_regnum_for_perf_regnum_alpha(int perf_regnum)
> +{
> + if (perf_regnum >= PERF_REG_ALPHA_R0 && perf_regnum <= PERF_REG_ALPHA_SP)
> + return perf_regnum;
> + if (perf_regnum == PERF_REG_ALPHA_PC)
> + return 64;
> +
> + return -ENOENT;
> +}
> diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
> index 09aca6304002..3fd71787c658 100644
> --- a/tools/perf/util/dwarf-regs.c
> +++ b/tools/perf/util/dwarf-regs.c
> @@ -185,6 +185,8 @@ static int get_libdw_frame_nregs(unsigned int machine, unsigned int flags __mayb
> return 74;
> case EM_MIPS:
> return 71;
> + case EM_ALPHA:
> + return 65;
> default:
> return 0;
> }
> @@ -228,6 +230,9 @@ int get_dwarf_regnum_for_perf_regnum(int perf_regnum, unsigned int machine,
> case EM_MIPS:
> reg = __get_dwarf_regnum_for_perf_regnum_mips(perf_regnum);
> break;
> + case EM_ALPHA:
> + reg = __get_dwarf_regnum_for_perf_regnum_alpha(perf_regnum);
> + break;
> default:
> pr_err("ELF MACHINE %x is not supported.\n", machine);
> return -ENOENT;
> diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
> index 1da915c2683a..8d1a981ab8aa 100644
> --- a/tools/perf/util/include/dwarf-regs.h
> +++ b/tools/perf/util/include/dwarf-regs.h
> @@ -105,6 +105,8 @@ int __get_dwarf_regnum_x86_64(const char *name);
> int __get_dwarf_regnum_for_perf_regnum_i386(int perf_regnum);
> int __get_dwarf_regnum_for_perf_regnum_x86_64(int perf_regnum, int abi);
>
> +int __get_dwarf_regnum_for_perf_regnum_alpha(int perf_regnum);
> +
> int __get_dwarf_regnum_arm64(const char *name);
> int __get_dwarf_regnum_for_perf_regnum_arm(int perf_regnum);
> int __get_dwarf_regnum_for_perf_regnum_arm64(int perf_regnum);
> diff --git a/tools/perf/util/perf-regs-arch/Build b/tools/perf/util/perf-regs-arch/Build
> index be95402aa540..1fbc299775f7 100644
> --- a/tools/perf/util/perf-regs-arch/Build
> +++ b/tools/perf/util/perf-regs-arch/Build
> @@ -1,4 +1,5 @@
> perf-util-y += perf_regs_aarch64.o
> +perf-util-y += perf_regs_alpha.o
> perf-util-y += perf_regs_arm.o
> perf-util-y += perf_regs_csky.o
> perf-util-y += perf_regs_loongarch.o
> diff --git a/tools/perf/util/perf-regs-arch/perf_regs_alpha.c b/tools/perf/util/perf-regs-arch/perf_regs_alpha.c
> new file mode 100644
> index 000000000000..cb9c8a1cd74b
> --- /dev/null
> +++ b/tools/perf/util/perf-regs-arch/perf_regs_alpha.c
> @@ -0,0 +1,34 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include "../perf_regs.h"
> +#include "../../arch/alpha/include/perf_regs.h"
> +
> +static const char * const alpha_reg_names[PERF_REG_ALPHA_MAX] = {
> + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
> + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
> + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
> + "r24", "r25", "r26", "r27", "r28", "gp", "sp", "pc",
> +};
> +
> +uint64_t __perf_reg_mask_alpha(bool intr __maybe_unused)
> +{
> + return PERF_REGS_MASK;
> +}
> +
> +const char *__perf_reg_name_alpha(int id)
> +{
> + if (id < 0 || id >= PERF_REG_ALPHA_MAX)
> + return NULL;
> +
> + return alpha_reg_names[id];
> +}
> +
> +uint64_t __perf_reg_ip_alpha(void)
> +{
> + return PERF_REG_ALPHA_PC;
> +}
> +
> +uint64_t __perf_reg_sp_alpha(void)
> +{
> + return PERF_REG_ALPHA_SP;
> +}
> diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c
> index c8242b7e1db5..6eb5824f5521 100644
> --- a/tools/perf/util/perf_regs.c
> +++ b/tools/perf/util/perf_regs.c
> @@ -43,6 +43,9 @@ uint64_t perf_intr_reg_mask(uint16_t e_machine, int *abi /*inout*/)
> uint64_t mask = 0;
>
> switch (e_machine) {
> + case EM_ALPHA:
> + mask = __perf_reg_mask_alpha(/*intr=*/true);
> + break;
> case EM_ARM:
> mask = __perf_reg_mask_arm(/*intr=*/true);
> break;
> @@ -86,6 +89,9 @@ uint64_t perf_user_reg_mask(uint16_t e_machine, int *abi /*inout*/)
> uint64_t mask = 0;
>
> switch (e_machine) {
> + case EM_ALPHA:
> + mask = __perf_reg_mask_alpha(/*intr=*/false);
> + break;
> case EM_ARM:
> mask = __perf_reg_mask_arm(/*intr=*/false);
> break;
> @@ -129,6 +135,9 @@ const char *perf_reg_name(int id, uint16_t e_machine, uint32_t e_flags, int abi)
> const char *reg_name = NULL;
>
> switch (e_machine) {
> + case EM_ALPHA:
> + reg_name = __perf_reg_name_alpha(id);
> + break;
> case EM_ARM:
> reg_name = __perf_reg_name_arm(id);
> break;
> @@ -198,6 +207,8 @@ int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
> uint64_t perf_arch_reg_ip(uint16_t e_machine)
> {
> switch (e_machine) {
> + case EM_ALPHA:
> + return __perf_reg_ip_alpha();
> case EM_ARM:
> return __perf_reg_ip_arm();
> case EM_AARCH64:
> @@ -227,6 +238,8 @@ uint64_t perf_arch_reg_ip(uint16_t e_machine)
> uint64_t perf_arch_reg_sp(uint16_t e_machine)
> {
> switch (e_machine) {
> + case EM_ALPHA:
> + return __perf_reg_sp_alpha();
> case EM_ARM:
> return __perf_reg_sp_arm();
> case EM_AARCH64:
> diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h
> index c9f461b6f11f..4134e4eed802 100644
> --- a/tools/perf/util/perf_regs.h
> +++ b/tools/perf/util/perf_regs.h
> @@ -34,6 +34,11 @@ const char *__perf_reg_name_arm64(int id);
> uint64_t __perf_reg_ip_arm64(void);
> uint64_t __perf_reg_sp_arm64(void);
>
> +uint64_t __perf_reg_mask_alpha(bool intr);
> +const char *__perf_reg_name_alpha(int id);
> +uint64_t __perf_reg_ip_alpha(void);
> +uint64_t __perf_reg_sp_alpha(void);
> +
> uint64_t __perf_reg_mask_arm(bool intr);
> const char *__perf_reg_name_arm(int id);
> uint64_t __perf_reg_ip_arm(void);
>
> ---
> base-commit: bc01105ed65d15787b2eb93ac26e8624a2139e35
> change-id: 20261001-alpha-perf-tools-regs-c206a84dec7f
>
> Best regards,
> --
> Matt Turner <mattst88@gmail.com>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] perf regs: Add alpha support
2026-10-11 20:37 [PATCH] perf regs: Add alpha support Matt Turner
2026-10-11 20:42 ` sashiko-bot
2026-10-11 21:46 ` Ian Rogers
@ 2026-10-11 21:50 ` Ian Rogers
2026-10-12 17:37 ` Magnus Lindholm
3 siblings, 0 replies; 9+ messages in thread
From: Ian Rogers @ 2026-10-11 21:50 UTC (permalink / raw)
To: Matt Turner
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, James Clark, linux-kernel, linux-perf-users,
Magnus Lindholm, Richard Henderson, linux-alpha
On Sun, Oct 11, 2026 at 1:37 PM Matt Turner <mattst88@gmail.com> wrote:
>
> Add the alpha perf register tables so that -I/--user-regs and
> --call-graph dwarf work.
>
> r9-r15 cannot be sampled and are left out of the mask. Perf register
> numbers 0-30 are the DWARF numbers. The pc is DWARF 64, the column GCC
> uses as the alternate return address column on alpha, so libdw's
> frame_nregs is 65.
>
> Assisted-by: Claude:claude-opus-5-5
> Signed-off-by: Matt Turner <mattst88@gmail.com>
> ---
> This depends on the kernel side, "alpha: add HAVE_PERF_REGS and
> HAVE_PERF_USER_STACK_DUMP support", posted as part of:
>
> https://lore.kernel.org/r/20261011-alpha-perf-regs-v3-v1-0-3354d135d972@gmail.com
The link above failed for me, but the following link works:
https://lore.kernel.org/all/20261011-alpha-perf-regs-v3-v1-0-eaa625a39712@gmail.com/
Thanks,
Ian
> --call-graph dwarf also needs libdw alpha unwinding support (abi_cfi
> and frame_nregs), which I am sending to elfutils-devel separately.
> Without it, libdw rejects the thread and perf reports the error;
> -I/--user-regs work regardless.
> ---
> tools/arch/alpha/include/uapi/asm/perf_regs.h | 45 ++++++++++++++++++++++
> tools/perf/arch/alpha/include/perf_regs.h | 16 ++++++++
> tools/perf/check-headers.sh | 1 +
> tools/perf/util/dwarf-regs-arch/Build | 1 +
> tools/perf/util/dwarf-regs-arch/dwarf-regs-alpha.c | 14 +++++++
> tools/perf/util/dwarf-regs.c | 5 +++
> tools/perf/util/include/dwarf-regs.h | 2 +
> tools/perf/util/perf-regs-arch/Build | 1 +
> tools/perf/util/perf-regs-arch/perf_regs_alpha.c | 34 ++++++++++++++++
> tools/perf/util/perf_regs.c | 13 +++++++
> tools/perf/util/perf_regs.h | 5 +++
> 11 files changed, 137 insertions(+)
>
> diff --git a/tools/arch/alpha/include/uapi/asm/perf_regs.h b/tools/arch/alpha/include/uapi/asm/perf_regs.h
> new file mode 100644
> index 000000000000..da96a31b12fb
> --- /dev/null
> +++ b/tools/arch/alpha/include/uapi/asm/perf_regs.h
> @@ -0,0 +1,45 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +#ifndef _UAPI_ASM_ALPHA_PERF_REGS_H
> +#define _UAPI_ASM_ALPHA_PERF_REGS_H
> +
> +/*
> + * Indices 0-30 match the hardware (and DWARF) register numbers.
> + * r9-r15 are not saved in pt_regs and cannot be sampled.
> + */
> +enum perf_event_alpha_regs {
> + PERF_REG_ALPHA_R0,
> + PERF_REG_ALPHA_R1,
> + PERF_REG_ALPHA_R2,
> + PERF_REG_ALPHA_R3,
> + PERF_REG_ALPHA_R4,
> + PERF_REG_ALPHA_R5,
> + PERF_REG_ALPHA_R6,
> + PERF_REG_ALPHA_R7,
> + PERF_REG_ALPHA_R8,
> + PERF_REG_ALPHA_R9,
> + PERF_REG_ALPHA_R10,
> + PERF_REG_ALPHA_R11,
> + PERF_REG_ALPHA_R12,
> + PERF_REG_ALPHA_R13,
> + PERF_REG_ALPHA_R14,
> + PERF_REG_ALPHA_R15,
> + PERF_REG_ALPHA_R16,
> + PERF_REG_ALPHA_R17,
> + PERF_REG_ALPHA_R18,
> + PERF_REG_ALPHA_R19,
> + PERF_REG_ALPHA_R20,
> + PERF_REG_ALPHA_R21,
> + PERF_REG_ALPHA_R22,
> + PERF_REG_ALPHA_R23,
> + PERF_REG_ALPHA_R24,
> + PERF_REG_ALPHA_R25,
> + PERF_REG_ALPHA_R26,
> + PERF_REG_ALPHA_R27,
> + PERF_REG_ALPHA_R28,
> + PERF_REG_ALPHA_GP,
> + PERF_REG_ALPHA_SP,
> + PERF_REG_ALPHA_PC,
> + PERF_REG_ALPHA_MAX,
> +};
> +
> +#endif /* _UAPI_ASM_ALPHA_PERF_REGS_H */
> diff --git a/tools/perf/arch/alpha/include/perf_regs.h b/tools/perf/arch/alpha/include/perf_regs.h
> new file mode 100644
> index 000000000000..409f3a08af9b
> --- /dev/null
> +++ b/tools/perf/arch/alpha/include/perf_regs.h
> @@ -0,0 +1,16 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef ARCH_PERF_REGS_H
> +#define ARCH_PERF_REGS_H
> +
> +#include <stdlib.h>
> +#include <linux/types.h>
> +#include <linux/bits.h>
> +#include "../../../../arch/alpha/include/uapi/asm/perf_regs.h"
> +
> +#define PERF_REGS_MAX PERF_REG_ALPHA_MAX
> +
> +/* The kernel rejects r9-r15. */
> +#define PERF_REGS_MASK (GENMASK_ULL(PERF_REG_ALPHA_MAX - 1, 0) & \
> + ~GENMASK_ULL(PERF_REG_ALPHA_R15, PERF_REG_ALPHA_R9))
> +
> +#endif /* ARCH_PERF_REGS_H */
> diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
> index 531c0e0e84df..9baf83f79e23 100755
> --- a/tools/perf/check-headers.sh
> +++ b/tools/perf/check-headers.sh
> @@ -36,6 +36,7 @@ declare -a FILES=(
> "arch/x86/include/asm/msr-index.h"
> "arch/x86/lib/x86-opcode-map.txt"
> "arch/x86/tools/gen-insn-attr-x86.awk"
> + "arch/alpha/include/uapi/asm/perf_regs.h"
> "arch/arm/include/uapi/asm/perf_regs.h"
> "arch/arm64/include/uapi/asm/perf_regs.h"
> "arch/loongarch/include/uapi/asm/perf_regs.h"
> diff --git a/tools/perf/util/dwarf-regs-arch/Build b/tools/perf/util/dwarf-regs-arch/Build
> index ceb68ae86fd8..026b7b5ca895 100644
> --- a/tools/perf/util/dwarf-regs-arch/Build
> +++ b/tools/perf/util/dwarf-regs-arch/Build
> @@ -1,3 +1,4 @@
> +perf-util-$(CONFIG_LIBDW) += dwarf-regs-alpha.o
> perf-util-$(CONFIG_LIBDW) += dwarf-regs-arm64.o
> perf-util-$(CONFIG_LIBDW) += dwarf-regs-arm.o
> perf-util-$(CONFIG_LIBDW) += dwarf-regs-csky.o
> diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-alpha.c b/tools/perf/util/dwarf-regs-arch/dwarf-regs-alpha.c
> new file mode 100644
> index 000000000000..50fd17096597
> --- /dev/null
> +++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-alpha.c
> @@ -0,0 +1,14 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include <errno.h>
> +#include <dwarf-regs.h>
> +#include "../../../arch/alpha/include/uapi/asm/perf_regs.h"
> +
> +int __get_dwarf_regnum_for_perf_regnum_alpha(int perf_regnum)
> +{
> + if (perf_regnum >= PERF_REG_ALPHA_R0 && perf_regnum <= PERF_REG_ALPHA_SP)
> + return perf_regnum;
> + if (perf_regnum == PERF_REG_ALPHA_PC)
> + return 64;
> +
> + return -ENOENT;
> +}
> diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
> index 09aca6304002..3fd71787c658 100644
> --- a/tools/perf/util/dwarf-regs.c
> +++ b/tools/perf/util/dwarf-regs.c
> @@ -185,6 +185,8 @@ static int get_libdw_frame_nregs(unsigned int machine, unsigned int flags __mayb
> return 74;
> case EM_MIPS:
> return 71;
> + case EM_ALPHA:
> + return 65;
> default:
> return 0;
> }
> @@ -228,6 +230,9 @@ int get_dwarf_regnum_for_perf_regnum(int perf_regnum, unsigned int machine,
> case EM_MIPS:
> reg = __get_dwarf_regnum_for_perf_regnum_mips(perf_regnum);
> break;
> + case EM_ALPHA:
> + reg = __get_dwarf_regnum_for_perf_regnum_alpha(perf_regnum);
> + break;
> default:
> pr_err("ELF MACHINE %x is not supported.\n", machine);
> return -ENOENT;
> diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
> index 1da915c2683a..8d1a981ab8aa 100644
> --- a/tools/perf/util/include/dwarf-regs.h
> +++ b/tools/perf/util/include/dwarf-regs.h
> @@ -105,6 +105,8 @@ int __get_dwarf_regnum_x86_64(const char *name);
> int __get_dwarf_regnum_for_perf_regnum_i386(int perf_regnum);
> int __get_dwarf_regnum_for_perf_regnum_x86_64(int perf_regnum, int abi);
>
> +int __get_dwarf_regnum_for_perf_regnum_alpha(int perf_regnum);
> +
> int __get_dwarf_regnum_arm64(const char *name);
> int __get_dwarf_regnum_for_perf_regnum_arm(int perf_regnum);
> int __get_dwarf_regnum_for_perf_regnum_arm64(int perf_regnum);
> diff --git a/tools/perf/util/perf-regs-arch/Build b/tools/perf/util/perf-regs-arch/Build
> index be95402aa540..1fbc299775f7 100644
> --- a/tools/perf/util/perf-regs-arch/Build
> +++ b/tools/perf/util/perf-regs-arch/Build
> @@ -1,4 +1,5 @@
> perf-util-y += perf_regs_aarch64.o
> +perf-util-y += perf_regs_alpha.o
> perf-util-y += perf_regs_arm.o
> perf-util-y += perf_regs_csky.o
> perf-util-y += perf_regs_loongarch.o
> diff --git a/tools/perf/util/perf-regs-arch/perf_regs_alpha.c b/tools/perf/util/perf-regs-arch/perf_regs_alpha.c
> new file mode 100644
> index 000000000000..cb9c8a1cd74b
> --- /dev/null
> +++ b/tools/perf/util/perf-regs-arch/perf_regs_alpha.c
> @@ -0,0 +1,34 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include "../perf_regs.h"
> +#include "../../arch/alpha/include/perf_regs.h"
> +
> +static const char * const alpha_reg_names[PERF_REG_ALPHA_MAX] = {
> + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
> + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
> + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
> + "r24", "r25", "r26", "r27", "r28", "gp", "sp", "pc",
> +};
> +
> +uint64_t __perf_reg_mask_alpha(bool intr __maybe_unused)
> +{
> + return PERF_REGS_MASK;
> +}
> +
> +const char *__perf_reg_name_alpha(int id)
> +{
> + if (id < 0 || id >= PERF_REG_ALPHA_MAX)
> + return NULL;
> +
> + return alpha_reg_names[id];
> +}
> +
> +uint64_t __perf_reg_ip_alpha(void)
> +{
> + return PERF_REG_ALPHA_PC;
> +}
> +
> +uint64_t __perf_reg_sp_alpha(void)
> +{
> + return PERF_REG_ALPHA_SP;
> +}
> diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c
> index c8242b7e1db5..6eb5824f5521 100644
> --- a/tools/perf/util/perf_regs.c
> +++ b/tools/perf/util/perf_regs.c
> @@ -43,6 +43,9 @@ uint64_t perf_intr_reg_mask(uint16_t e_machine, int *abi /*inout*/)
> uint64_t mask = 0;
>
> switch (e_machine) {
> + case EM_ALPHA:
> + mask = __perf_reg_mask_alpha(/*intr=*/true);
> + break;
> case EM_ARM:
> mask = __perf_reg_mask_arm(/*intr=*/true);
> break;
> @@ -86,6 +89,9 @@ uint64_t perf_user_reg_mask(uint16_t e_machine, int *abi /*inout*/)
> uint64_t mask = 0;
>
> switch (e_machine) {
> + case EM_ALPHA:
> + mask = __perf_reg_mask_alpha(/*intr=*/false);
> + break;
> case EM_ARM:
> mask = __perf_reg_mask_arm(/*intr=*/false);
> break;
> @@ -129,6 +135,9 @@ const char *perf_reg_name(int id, uint16_t e_machine, uint32_t e_flags, int abi)
> const char *reg_name = NULL;
>
> switch (e_machine) {
> + case EM_ALPHA:
> + reg_name = __perf_reg_name_alpha(id);
> + break;
> case EM_ARM:
> reg_name = __perf_reg_name_arm(id);
> break;
> @@ -198,6 +207,8 @@ int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
> uint64_t perf_arch_reg_ip(uint16_t e_machine)
> {
> switch (e_machine) {
> + case EM_ALPHA:
> + return __perf_reg_ip_alpha();
> case EM_ARM:
> return __perf_reg_ip_arm();
> case EM_AARCH64:
> @@ -227,6 +238,8 @@ uint64_t perf_arch_reg_ip(uint16_t e_machine)
> uint64_t perf_arch_reg_sp(uint16_t e_machine)
> {
> switch (e_machine) {
> + case EM_ALPHA:
> + return __perf_reg_sp_alpha();
> case EM_ARM:
> return __perf_reg_sp_arm();
> case EM_AARCH64:
> diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h
> index c9f461b6f11f..4134e4eed802 100644
> --- a/tools/perf/util/perf_regs.h
> +++ b/tools/perf/util/perf_regs.h
> @@ -34,6 +34,11 @@ const char *__perf_reg_name_arm64(int id);
> uint64_t __perf_reg_ip_arm64(void);
> uint64_t __perf_reg_sp_arm64(void);
>
> +uint64_t __perf_reg_mask_alpha(bool intr);
> +const char *__perf_reg_name_alpha(int id);
> +uint64_t __perf_reg_ip_alpha(void);
> +uint64_t __perf_reg_sp_alpha(void);
> +
> uint64_t __perf_reg_mask_arm(bool intr);
> const char *__perf_reg_name_arm(int id);
> uint64_t __perf_reg_ip_arm(void);
>
> ---
> base-commit: bc01105ed65d15787b2eb93ac26e8624a2139e35
> change-id: 20261001-alpha-perf-tools-regs-c206a84dec7f
>
> Best regards,
> --
> Matt Turner <mattst88@gmail.com>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] perf regs: Add alpha support
2026-10-11 20:37 [PATCH] perf regs: Add alpha support Matt Turner
` (2 preceding siblings ...)
2026-10-11 21:50 ` Ian Rogers
@ 2026-10-12 17:37 ` Magnus Lindholm
2026-10-12 21:41 ` Magnus Lindholm
3 siblings, 1 reply; 9+ messages in thread
From: Magnus Lindholm @ 2026-10-12 17:37 UTC (permalink / raw)
To: Matt Turner
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, James Clark, linux-kernel,
linux-perf-users, Richard Henderson, linux-alpha
Hi Matt,
On Sun, Oct 11, 2026 at 10:37 PM Matt Turner <mattst88@gmail.com> wrote:
>
> Add the alpha perf register tables so that -I/--user-regs and
> --call-graph dwarf work.
>
> r9-r15 cannot be sampled and are left out of the mask. Perf register
> numbers 0-30 are the DWARF numbers. The pc is DWARF 64, the column GCC
> uses as the alternate return address column on alpha, so libdw's
> frame_nregs is 65.
>
> Assisted-by: Claude:claude-opus-5-5
> Signed-off-by: Matt Turner <mattst88@gmail.com>
> ---
> This depends on the kernel side, "alpha: add HAVE_PERF_REGS and
> HAVE_PERF_USER_STACK_DUMP support", posted as part of:
>
> https://lore.kernel.org/r/20261011-alpha-perf-regs-v3-v1-0-3354d135d972@gmail.com
>
> --call-graph dwarf also needs libdw alpha unwinding support (abi_cfi
> and frame_nregs), which I am sending to elfutils-devel separately.
> Without it, libdw rejects the thread and perf reports the error;
> -I/--user-regs work regardless.
> ---
> tools/arch/alpha/include/uapi/asm/perf_regs.h | 45 ++++++++++++++++++++++
> tools/perf/arch/alpha/include/perf_regs.h | 16 ++++++++
> tools/perf/check-headers.sh | 1 +
> tools/perf/util/dwarf-regs-arch/Build | 1 +
> tools/perf/util/dwarf-regs-arch/dwarf-regs-alpha.c | 14 +++++++
> tools/perf/util/dwarf-regs.c | 5 +++
> tools/perf/util/include/dwarf-regs.h | 2 +
> tools/perf/util/perf-regs-arch/Build | 1 +
> tools/perf/util/perf-regs-arch/perf_regs_alpha.c | 34 ++++++++++++++++
> tools/perf/util/perf_regs.c | 13 +++++++
> tools/perf/util/perf_regs.h | 5 +++
> 11 files changed, 137 insertions(+)
>
> diff --git a/tools/arch/alpha/include/uapi/asm/perf_regs.h b/tools/arch/alpha/include/uapi/asm/perf_regs.h
> new file mode 100644
> index 000000000000..da96a31b12fb
> --- /dev/null
> +++ b/tools/arch/alpha/include/uapi/asm/perf_regs.h
> @@ -0,0 +1,45 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +#ifndef _UAPI_ASM_ALPHA_PERF_REGS_H
> +#define _UAPI_ASM_ALPHA_PERF_REGS_H
> +
> +/*
> + * Indices 0-30 match the hardware (and DWARF) register numbers.
> + * r9-r15 are not saved in pt_regs and cannot be sampled.
> + */
> +enum perf_event_alpha_regs {
> + PERF_REG_ALPHA_R0,
> + PERF_REG_ALPHA_R1,
> + PERF_REG_ALPHA_R2,
> + PERF_REG_ALPHA_R3,
> + PERF_REG_ALPHA_R4,
> + PERF_REG_ALPHA_R5,
> + PERF_REG_ALPHA_R6,
> + PERF_REG_ALPHA_R7,
> + PERF_REG_ALPHA_R8,
> + PERF_REG_ALPHA_R9,
> + PERF_REG_ALPHA_R10,
> + PERF_REG_ALPHA_R11,
> + PERF_REG_ALPHA_R12,
> + PERF_REG_ALPHA_R13,
> + PERF_REG_ALPHA_R14,
> + PERF_REG_ALPHA_R15,
> + PERF_REG_ALPHA_R16,
> + PERF_REG_ALPHA_R17,
> + PERF_REG_ALPHA_R18,
> + PERF_REG_ALPHA_R19,
> + PERF_REG_ALPHA_R20,
> + PERF_REG_ALPHA_R21,
> + PERF_REG_ALPHA_R22,
> + PERF_REG_ALPHA_R23,
> + PERF_REG_ALPHA_R24,
> + PERF_REG_ALPHA_R25,
> + PERF_REG_ALPHA_R26,
> + PERF_REG_ALPHA_R27,
> + PERF_REG_ALPHA_R28,
> + PERF_REG_ALPHA_GP,
> + PERF_REG_ALPHA_SP,
> + PERF_REG_ALPHA_PC,
> + PERF_REG_ALPHA_MAX,
> +};
> +
> +#endif /* _UAPI_ASM_ALPHA_PERF_REGS_H */
> diff --git a/tools/perf/arch/alpha/include/perf_regs.h b/tools/perf/arch/alpha/include/perf_regs.h
> new file mode 100644
> index 000000000000..409f3a08af9b
> --- /dev/null
> +++ b/tools/perf/arch/alpha/include/perf_regs.h
> @@ -0,0 +1,16 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef ARCH_PERF_REGS_H
> +#define ARCH_PERF_REGS_H
> +
> +#include <stdlib.h>
> +#include <linux/types.h>
> +#include <linux/bits.h>
> +#include "../../../../arch/alpha/include/uapi/asm/perf_regs.h"
> +
> +#define PERF_REGS_MAX PERF_REG_ALPHA_MAX
> +
> +/* The kernel rejects r9-r15. */
> +#define PERF_REGS_MASK (GENMASK_ULL(PERF_REG_ALPHA_MAX - 1, 0) & \
> + ~GENMASK_ULL(PERF_REG_ALPHA_R15, PERF_REG_ALPHA_R9))
> +
> +#endif /* ARCH_PERF_REGS_H */
> diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
> index 531c0e0e84df..9baf83f79e23 100755
> --- a/tools/perf/check-headers.sh
> +++ b/tools/perf/check-headers.sh
> @@ -36,6 +36,7 @@ declare -a FILES=(
> "arch/x86/include/asm/msr-index.h"
> "arch/x86/lib/x86-opcode-map.txt"
> "arch/x86/tools/gen-insn-attr-x86.awk"
> + "arch/alpha/include/uapi/asm/perf_regs.h"
> "arch/arm/include/uapi/asm/perf_regs.h"
> "arch/arm64/include/uapi/asm/perf_regs.h"
> "arch/loongarch/include/uapi/asm/perf_regs.h"
> diff --git a/tools/perf/util/dwarf-regs-arch/Build b/tools/perf/util/dwarf-regs-arch/Build
> index ceb68ae86fd8..026b7b5ca895 100644
> --- a/tools/perf/util/dwarf-regs-arch/Build
> +++ b/tools/perf/util/dwarf-regs-arch/Build
> @@ -1,3 +1,4 @@
> +perf-util-$(CONFIG_LIBDW) += dwarf-regs-alpha.o
> perf-util-$(CONFIG_LIBDW) += dwarf-regs-arm64.o
> perf-util-$(CONFIG_LIBDW) += dwarf-regs-arm.o
> perf-util-$(CONFIG_LIBDW) += dwarf-regs-csky.o
> diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-alpha.c b/tools/perf/util/dwarf-regs-arch/dwarf-regs-alpha.c
> new file mode 100644
> index 000000000000..50fd17096597
> --- /dev/null
> +++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-alpha.c
> @@ -0,0 +1,14 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include <errno.h>
> +#include <dwarf-regs.h>
> +#include "../../../arch/alpha/include/uapi/asm/perf_regs.h"
> +
> +int __get_dwarf_regnum_for_perf_regnum_alpha(int perf_regnum)
> +{
> + if (perf_regnum >= PERF_REG_ALPHA_R0 && perf_regnum <= PERF_REG_ALPHA_SP)
> + return perf_regnum;
> + if (perf_regnum == PERF_REG_ALPHA_PC)
> + return 64;
> +
> + return -ENOENT;
> +}
> diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
> index 09aca6304002..3fd71787c658 100644
> --- a/tools/perf/util/dwarf-regs.c
> +++ b/tools/perf/util/dwarf-regs.c
> @@ -185,6 +185,8 @@ static int get_libdw_frame_nregs(unsigned int machine, unsigned int flags __mayb
> return 74;
> case EM_MIPS:
> return 71;
> + case EM_ALPHA:
> + return 65;
> default:
> return 0;
> }
> @@ -228,6 +230,9 @@ int get_dwarf_regnum_for_perf_regnum(int perf_regnum, unsigned int machine,
> case EM_MIPS:
> reg = __get_dwarf_regnum_for_perf_regnum_mips(perf_regnum);
> break;
> + case EM_ALPHA:
> + reg = __get_dwarf_regnum_for_perf_regnum_alpha(perf_regnum);
> + break;
> default:
> pr_err("ELF MACHINE %x is not supported.\n", machine);
> return -ENOENT;
> diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
> index 1da915c2683a..8d1a981ab8aa 100644
> --- a/tools/perf/util/include/dwarf-regs.h
> +++ b/tools/perf/util/include/dwarf-regs.h
> @@ -105,6 +105,8 @@ int __get_dwarf_regnum_x86_64(const char *name);
> int __get_dwarf_regnum_for_perf_regnum_i386(int perf_regnum);
> int __get_dwarf_regnum_for_perf_regnum_x86_64(int perf_regnum, int abi);
>
> +int __get_dwarf_regnum_for_perf_regnum_alpha(int perf_regnum);
> +
> int __get_dwarf_regnum_arm64(const char *name);
> int __get_dwarf_regnum_for_perf_regnum_arm(int perf_regnum);
> int __get_dwarf_regnum_for_perf_regnum_arm64(int perf_regnum);
> diff --git a/tools/perf/util/perf-regs-arch/Build b/tools/perf/util/perf-regs-arch/Build
> index be95402aa540..1fbc299775f7 100644
> --- a/tools/perf/util/perf-regs-arch/Build
> +++ b/tools/perf/util/perf-regs-arch/Build
> @@ -1,4 +1,5 @@
> perf-util-y += perf_regs_aarch64.o
> +perf-util-y += perf_regs_alpha.o
> perf-util-y += perf_regs_arm.o
> perf-util-y += perf_regs_csky.o
> perf-util-y += perf_regs_loongarch.o
> diff --git a/tools/perf/util/perf-regs-arch/perf_regs_alpha.c b/tools/perf/util/perf-regs-arch/perf_regs_alpha.c
> new file mode 100644
> index 000000000000..cb9c8a1cd74b
> --- /dev/null
> +++ b/tools/perf/util/perf-regs-arch/perf_regs_alpha.c
> @@ -0,0 +1,34 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include "../perf_regs.h"
> +#include "../../arch/alpha/include/perf_regs.h"
> +
> +static const char * const alpha_reg_names[PERF_REG_ALPHA_MAX] = {
> + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
> + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
> + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
> + "r24", "r25", "r26", "r27", "r28", "gp", "sp", "pc",
> +};
> +
> +uint64_t __perf_reg_mask_alpha(bool intr __maybe_unused)
> +{
> + return PERF_REGS_MASK;
> +}
> +
> +const char *__perf_reg_name_alpha(int id)
> +{
> + if (id < 0 || id >= PERF_REG_ALPHA_MAX)
> + return NULL;
> +
> + return alpha_reg_names[id];
> +}
> +
> +uint64_t __perf_reg_ip_alpha(void)
> +{
> + return PERF_REG_ALPHA_PC;
> +}
> +
> +uint64_t __perf_reg_sp_alpha(void)
> +{
> + return PERF_REG_ALPHA_SP;
> +}
> diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c
> index c8242b7e1db5..6eb5824f5521 100644
> --- a/tools/perf/util/perf_regs.c
> +++ b/tools/perf/util/perf_regs.c
> @@ -43,6 +43,9 @@ uint64_t perf_intr_reg_mask(uint16_t e_machine, int *abi /*inout*/)
> uint64_t mask = 0;
>
> switch (e_machine) {
> + case EM_ALPHA:
> + mask = __perf_reg_mask_alpha(/*intr=*/true);
> + break;
> case EM_ARM:
> mask = __perf_reg_mask_arm(/*intr=*/true);
> break;
> @@ -86,6 +89,9 @@ uint64_t perf_user_reg_mask(uint16_t e_machine, int *abi /*inout*/)
> uint64_t mask = 0;
>
> switch (e_machine) {
> + case EM_ALPHA:
> + mask = __perf_reg_mask_alpha(/*intr=*/false);
> + break;
> case EM_ARM:
> mask = __perf_reg_mask_arm(/*intr=*/false);
> break;
> @@ -129,6 +135,9 @@ const char *perf_reg_name(int id, uint16_t e_machine, uint32_t e_flags, int abi)
> const char *reg_name = NULL;
>
> switch (e_machine) {
> + case EM_ALPHA:
> + reg_name = __perf_reg_name_alpha(id);
> + break;
> case EM_ARM:
> reg_name = __perf_reg_name_arm(id);
> break;
> @@ -198,6 +207,8 @@ int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
> uint64_t perf_arch_reg_ip(uint16_t e_machine)
> {
> switch (e_machine) {
> + case EM_ALPHA:
> + return __perf_reg_ip_alpha();
> case EM_ARM:
> return __perf_reg_ip_arm();
> case EM_AARCH64:
> @@ -227,6 +238,8 @@ uint64_t perf_arch_reg_ip(uint16_t e_machine)
> uint64_t perf_arch_reg_sp(uint16_t e_machine)
> {
> switch (e_machine) {
> + case EM_ALPHA:
> + return __perf_reg_sp_alpha();
> case EM_ARM:
> return __perf_reg_sp_arm();
> case EM_AARCH64:
> diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h
> index c9f461b6f11f..4134e4eed802 100644
> --- a/tools/perf/util/perf_regs.h
> +++ b/tools/perf/util/perf_regs.h
> @@ -34,6 +34,11 @@ const char *__perf_reg_name_arm64(int id);
> uint64_t __perf_reg_ip_arm64(void);
> uint64_t __perf_reg_sp_arm64(void);
>
> +uint64_t __perf_reg_mask_alpha(bool intr);
> +const char *__perf_reg_name_alpha(int id);
> +uint64_t __perf_reg_ip_alpha(void);
> +uint64_t __perf_reg_sp_alpha(void);
> +
> uint64_t __perf_reg_mask_arm(bool intr);
> const char *__perf_reg_name_arm(int id);
> uint64_t __perf_reg_ip_arm(void);
>
> ---
> base-commit: bc01105ed65d15787b2eb93ac26e8624a2139e35
> change-id: 20261001-alpha-perf-tools-regs-c206a84dec7f
>
> Best regards,
> --
> Matt Turner <mattst88@gmail.com>
>
Thanks for doing this!
Register selection, recording, decoding and user stack dumps tested
on my ES40. End-to-end DWARF unwinding remains unverified because the
installed elfutils 0.195 lacks Alpha unwinding support.
Tested-by: Magnus Lindholm <linmag7@gmail.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] perf regs: Add alpha support
2026-10-12 17:37 ` Magnus Lindholm
@ 2026-10-12 21:41 ` Magnus Lindholm
2026-10-12 21:45 ` Ian Rogers
0 siblings, 1 reply; 9+ messages in thread
From: Magnus Lindholm @ 2026-10-12 21:41 UTC (permalink / raw)
To: Matt Turner
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, James Clark, linux-kernel,
linux-perf-users, Richard Henderson, linux-alpha
Hi again,
On Mon, Oct 12, 2026 at 7:37 PM Magnus Lindholm <linmag7@gmail.com> wrote:
> > base-commit: bc01105ed65d15787b2eb93ac26e8624a2139e35
> > change-id: 20261001-alpha-perf-tools-regs-c206a84dec7f
> >
> > Best regards,
> > --
> > Matt Turner <mattst88@gmail.com>
> >
>
> Thanks for doing this!
>
> Register selection, recording, decoding and user stack dumps tested
> on my ES40. End-to-end DWARF unwinding remains unverified because the
> installed elfutils 0.195 lacks Alpha unwinding support.
>
> Tested-by: Magnus Lindholm <linmag7@gmail.com>
I just pulled your elfutils patches and ran some more tests.
With your elfutils patches, DWARF unwinding now works on my ES40.
Both existing and fresh perf recordings recovered the expected
leaf -> middle -> outer -> main call chain.
As documented, samples whose CFA depends on r15 stopped at the
sampled frame, since r15 is unavailable. Tested-by tag already given
to this series.
Thanks,
Magnus
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] perf regs: Add alpha support
2026-10-12 21:41 ` Magnus Lindholm
@ 2026-10-12 21:45 ` Ian Rogers
2026-10-12 22:38 ` Magnus Lindholm
0 siblings, 1 reply; 9+ messages in thread
From: Ian Rogers @ 2026-10-12 21:45 UTC (permalink / raw)
To: Magnus Lindholm
Cc: Matt Turner, Peter Zijlstra, Ingo Molnar,
Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Adrian Hunter, James Clark,
linux-kernel, linux-perf-users, Richard Henderson, linux-alpha
On Mon, Oct 12, 2026 at 2:41 PM Magnus Lindholm <linmag7@gmail.com> wrote:
>
> Hi again,
>
> On Mon, Oct 12, 2026 at 7:37 PM Magnus Lindholm <linmag7@gmail.com> wrote:
> > > base-commit: bc01105ed65d15787b2eb93ac26e8624a2139e35
> > > change-id: 20261001-alpha-perf-tools-regs-c206a84dec7f
> > >
> > > Best regards,
> > > --
> > > Matt Turner <mattst88@gmail.com>
> > >
> >
> > Thanks for doing this!
> >
> > Register selection, recording, decoding and user stack dumps tested
> > on my ES40. End-to-end DWARF unwinding remains unverified because the
> > installed elfutils 0.195 lacks Alpha unwinding support.
> >
> > Tested-by: Magnus Lindholm <linmag7@gmail.com>
>
> I just pulled your elfutils patches and ran some more tests.
> With your elfutils patches, DWARF unwinding now works on my ES40.
> Both existing and fresh perf recordings recovered the expected
> leaf -> middle -> outer -> main call chain.
>
> As documented, samples whose CFA depends on r15 stopped at the
> sampled frame, since r15 is unavailable. Tested-by tag already given
> to this series.
I'm finding this fantastic and exciting to follow! Being greedy, does
the cross-platform DWARF unwinding work? perf record on an alpha and
perf report on, say, an x86. It would in no way block this work, but
I'm keen to check Matt/I wired this up properly :-)
Thanks,
Ian
> Thanks,
> Magnus
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] perf regs: Add alpha support
2026-10-12 21:45 ` Ian Rogers
@ 2026-10-12 22:38 ` Magnus Lindholm
2026-10-12 22:46 ` Ian Rogers
0 siblings, 1 reply; 9+ messages in thread
From: Magnus Lindholm @ 2026-10-12 22:38 UTC (permalink / raw)
To: Ian Rogers
Cc: Matt Turner, Peter Zijlstra, Ingo Molnar,
Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Adrian Hunter, James Clark,
linux-kernel, linux-perf-users, Richard Henderson, linux-alpha
Hi Ian,
On Mon, Oct 12, 2026 at 11:45 PM Ian Rogers <irogers@google.com> wrote:
>
> On Mon, Oct 12, 2026 at 2:41 PM Magnus Lindholm <linmag7@gmail.com> wrote:
> >
> > Hi again,
> >
> > On Mon, Oct 12, 2026 at 7:37 PM Magnus Lindholm <linmag7@gmail.com> wrote:
> > > > base-commit: bc01105ed65d15787b2eb93ac26e8624a2139e35
> > > > change-id: 20261001-alpha-perf-tools-regs-c206a84dec7f
> > > >
> > > > Best regards,
> > > > --
> > > > Matt Turner <mattst88@gmail.com>
> > > >
> > >
> > > Thanks for doing this!
> > >
> > > Register selection, recording, decoding and user stack dumps tested
> > > on my ES40. End-to-end DWARF unwinding remains unverified because the
> > > installed elfutils 0.195 lacks Alpha unwinding support.
> > >
> > > Tested-by: Magnus Lindholm <linmag7@gmail.com>
> >
> > I just pulled your elfutils patches and ran some more tests.
> > With your elfutils patches, DWARF unwinding now works on my ES40.
> > Both existing and fresh perf recordings recovered the expected
> > leaf -> middle -> outer -> main call chain.
> >
> > As documented, samples whose CFA depends on r15 stopped at the
> > sampled frame, since r15 is unavailable. Tested-by tag already given
> > to this series.
>
> I'm finding this fantastic and exciting to follow! Being greedy, does
> the cross-platform DWARF unwinding work? perf record on an alpha and
> perf report on, say, an x86. It would in no way block this work, but
> I'm keen to check Matt/I wired this up properly :-)
>
Tested recording on the ES40 and reporting on x86-64 with patched
perf and elfutils. I hit an existing offline architecture-detection
issue in my for-next-based perf tree: it selected x86 registers for
the Alpha samples.
After two local corrections, both perf report and perf script
recovered identical seven-frame chains for all 391 optimized samples.
The r15-dependent workload stopped at the leaf, just as on Alpha.
Both issues predate Matt's patch in this tree. The places to look
are machines__init() in tools/perf/util/machine.c, where the host's
machines pointer is left unset, and thread__e_machine_endian() in
tools/perf/util/thread.c, where the session->data check for is_live
appears, to me, inverted?
Locally, setting machines->host.machines = machines and changing
is_live = !!session->data to is_live = !session->data resolved this.
These changes still need broader review, but the Alpha cross-platform
unwinding itself looks good.
Thanks,
Magnus
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] perf regs: Add alpha support
2026-10-12 22:38 ` Magnus Lindholm
@ 2026-10-12 22:46 ` Ian Rogers
0 siblings, 0 replies; 9+ messages in thread
From: Ian Rogers @ 2026-10-12 22:46 UTC (permalink / raw)
To: Magnus Lindholm
Cc: Matt Turner, Peter Zijlstra, Ingo Molnar,
Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Adrian Hunter, James Clark,
linux-kernel, linux-perf-users, Richard Henderson, linux-alpha
On Mon, Oct 12, 2026 at 3:38 PM Magnus Lindholm <linmag7@gmail.com> wrote:
>
> Hi Ian,
>
> On Mon, Oct 12, 2026 at 11:45 PM Ian Rogers <irogers@google.com> wrote:
> >
> > On Mon, Oct 12, 2026 at 2:41 PM Magnus Lindholm <linmag7@gmail.com> wrote:
> > >
> > > Hi again,
> > >
> > > On Mon, Oct 12, 2026 at 7:37 PM Magnus Lindholm <linmag7@gmail.com> wrote:
> > > > > base-commit: bc01105ed65d15787b2eb93ac26e8624a2139e35
> > > > > change-id: 20261001-alpha-perf-tools-regs-c206a84dec7f
> > > > >
> > > > > Best regards,
> > > > > --
> > > > > Matt Turner <mattst88@gmail.com>
> > > > >
> > > >
> > > > Thanks for doing this!
> > > >
> > > > Register selection, recording, decoding and user stack dumps tested
> > > > on my ES40. End-to-end DWARF unwinding remains unverified because the
> > > > installed elfutils 0.195 lacks Alpha unwinding support.
> > > >
> > > > Tested-by: Magnus Lindholm <linmag7@gmail.com>
> > >
> > > I just pulled your elfutils patches and ran some more tests.
> > > With your elfutils patches, DWARF unwinding now works on my ES40.
> > > Both existing and fresh perf recordings recovered the expected
> > > leaf -> middle -> outer -> main call chain.
> > >
> > > As documented, samples whose CFA depends on r15 stopped at the
> > > sampled frame, since r15 is unavailable. Tested-by tag already given
> > > to this series.
> >
> > I'm finding this fantastic and exciting to follow! Being greedy, does
> > the cross-platform DWARF unwinding work? perf record on an alpha and
> > perf report on, say, an x86. It would in no way block this work, but
> > I'm keen to check Matt/I wired this up properly :-)
> >
>
> Tested recording on the ES40 and reporting on x86-64 with patched
> perf and elfutils. I hit an existing offline architecture-detection
> issue in my for-next-based perf tree: it selected x86 registers for
> the Alpha samples.
>
> After two local corrections, both perf report and perf script
> recovered identical seven-frame chains for all 391 optimized samples.
> The r15-dependent workload stopped at the leaf, just as on Alpha.
>
> Both issues predate Matt's patch in this tree. The places to look
> are machines__init() in tools/perf/util/machine.c, where the host's
> machines pointer is left unset, and thread__e_machine_endian() in
> tools/perf/util/thread.c, where the session->data check for is_live
> appears, to me, inverted?
>
> Locally, setting machines->host.machines = machines and changing
> is_live = !!session->data to is_live = !session->data resolved this.
> These changes still need broader review, but the Alpha cross-platform
> unwinding itself looks good.
That's great news! I think the is_live issue was addressed here:
https://lore.kernel.org/linux-perf-users/20260905-perf-alpha-annotate-v1-1-97380433ccb6@gmail.com/
and the machines issue maybe in:
https://lore.kernel.org/linux-perf-users/20260918062620.2145220-1-irogers@google.com/
Both these fixes are already queued up in perf-tools-next:
https://web.git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/
Thanks!
Ian
> Thanks,
> Magnus
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-10-12 22:46 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-11 20:37 [PATCH] perf regs: Add alpha support Matt Turner
2026-10-11 20:42 ` sashiko-bot
2026-10-11 21:46 ` Ian Rogers
2026-10-11 21:50 ` Ian Rogers
2026-10-12 17:37 ` Magnus Lindholm
2026-10-12 21:41 ` Magnus Lindholm
2026-10-12 21:45 ` Ian Rogers
2026-10-12 22:38 ` Magnus Lindholm
2026-10-12 22:46 ` Ian Rogers
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox