Currently, some architecture-specific perf-regs functions, such as
arch__intr_reg_mask() and arch__user_reg_mask(), are defined with the
__weak attribute. This approach ensures that only functions matching
the architecture of the build/run host are compiled and executed,
reducing build time and binary size.
However, this __weak attribute restricts these functions to be called
only on the same architecture, preventing cross-architecture
functionality. For example, a perf.data file captured on x86 cannot be
parsed on an ARM platform.
To address this limitation, this patch removes the __weak attribute from
these perf-regs functions. The architecture-specific code is moved from
the arch/ directory to the util/perf-regs-arch/ directory. The
appropriate architectural functions are then called based on the EM_HOST.
No functional changes are intended.
Suggested-by: Ian Rogers <irogers@google.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
tools/perf/arch/arm/util/Build | 2 -
tools/perf/arch/arm/util/perf_regs.c | 13 ---
tools/perf/arch/arm64/util/perf_regs.c | 36 --------
tools/perf/arch/csky/Build | 1 -
tools/perf/arch/csky/util/Build | 1 -
tools/perf/arch/csky/util/perf_regs.c | 13 ---
tools/perf/arch/loongarch/util/Build | 1 -
tools/perf/arch/loongarch/util/perf_regs.c | 13 ---
tools/perf/arch/mips/util/Build | 1 -
tools/perf/arch/mips/util/perf_regs.c | 13 ---
tools/perf/arch/powerpc/util/perf_regs.c | 47 -----------
tools/perf/arch/riscv/include/perf_regs.h | 7 +-
tools/perf/arch/riscv/util/Build | 1 -
tools/perf/arch/riscv/util/perf_regs.c | 13 ---
tools/perf/arch/s390/util/Build | 1 -
tools/perf/arch/s390/util/perf_regs.c | 13 ---
tools/perf/arch/x86/util/perf_regs.c | 48 -----------
tools/perf/util/evsel.c | 4 +-
tools/perf/util/parse-regs-options.c | 2 +-
.../util/perf-regs-arch/perf_regs_aarch64.c | 53 +++++++++++-
.../perf/util/perf-regs-arch/perf_regs_arm.c | 7 +-
.../perf/util/perf-regs-arch/perf_regs_csky.c | 7 +-
.../util/perf-regs-arch/perf_regs_loongarch.c | 7 +-
.../perf/util/perf-regs-arch/perf_regs_mips.c | 7 +-
.../util/perf-regs-arch/perf_regs_powerpc.c | 77 ++++++++++++++++-
.../util/perf-regs-arch/perf_regs_riscv.c | 7 +-
.../perf/util/perf-regs-arch/perf_regs_s390.c | 7 +-
.../perf/util/perf-regs-arch/perf_regs_x86.c | 60 ++++++++++++-
tools/perf/util/perf_regs.c | 84 ++++++++++++++++++-
tools/perf/util/perf_regs.h | 22 ++++-
30 files changed, 332 insertions(+), 236 deletions(-)
delete mode 100644 tools/perf/arch/arm/util/perf_regs.c
delete mode 100644 tools/perf/arch/csky/Build
delete mode 100644 tools/perf/arch/csky/util/Build
delete mode 100644 tools/perf/arch/csky/util/perf_regs.c
delete mode 100644 tools/perf/arch/loongarch/util/perf_regs.c
delete mode 100644 tools/perf/arch/mips/util/perf_regs.c
delete mode 100644 tools/perf/arch/riscv/util/perf_regs.c
delete mode 100644 tools/perf/arch/s390/util/perf_regs.c
diff --git a/tools/perf/arch/arm/util/Build b/tools/perf/arch/arm/util/Build
index 3291f893b943..b94bf3c5279a 100644
--- a/tools/perf/arch/arm/util/Build
+++ b/tools/perf/arch/arm/util/Build
@@ -1,5 +1,3 @@
-perf-util-y += perf_regs.o
-
perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
perf-util-y += pmu.o auxtrace.o cs-etm.o
diff --git a/tools/perf/arch/arm/util/perf_regs.c b/tools/perf/arch/arm/util/perf_regs.c
deleted file mode 100644
index 03a5bc0cf64c..000000000000
--- a/tools/perf/arch/arm/util/perf_regs.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include "perf_regs.h"
-#include "../../../util/perf_regs.h"
-
-uint64_t arch__intr_reg_mask(void)
-{
- return PERF_REGS_MASK;
-}
-
-uint64_t arch__user_reg_mask(void)
-{
- return PERF_REGS_MASK;
-}
diff --git a/tools/perf/arch/arm64/util/perf_regs.c b/tools/perf/arch/arm64/util/perf_regs.c
index 9bb768e1bea1..47f58eaba032 100644
--- a/tools/perf/arch/arm64/util/perf_regs.c
+++ b/tools/perf/arch/arm64/util/perf_regs.c
@@ -103,39 +103,3 @@ int arch_sdt_arg_parse_op(char *old_op, char **new_op)
return SDT_ARG_VALID;
}
-
-uint64_t arch__intr_reg_mask(void)
-{
- return PERF_REGS_MASK;
-}
-
-uint64_t arch__user_reg_mask(void)
-{
- struct perf_event_attr attr = {
- .type = PERF_TYPE_HARDWARE,
- .config = PERF_COUNT_HW_CPU_CYCLES,
- .sample_type = PERF_SAMPLE_REGS_USER,
- .disabled = 1,
- .exclude_kernel = 1,
- .sample_period = 1,
- .sample_regs_user = PERF_REGS_MASK
- };
- int fd;
-
- if (getauxval(AT_HWCAP) & HWCAP_SVE)
- attr.sample_regs_user |= SMPL_REG_MASK(PERF_REG_ARM64_VG);
-
- /*
- * Check if the pmu supports perf extended regs, before
- * returning the register mask to sample.
- */
- if (attr.sample_regs_user != PERF_REGS_MASK) {
- event_attr_init(&attr);
- fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
- if (fd != -1) {
- close(fd);
- return attr.sample_regs_user;
- }
- }
- return PERF_REGS_MASK;
-}
diff --git a/tools/perf/arch/csky/Build b/tools/perf/arch/csky/Build
deleted file mode 100644
index e63eabc2c8f4..000000000000
--- a/tools/perf/arch/csky/Build
+++ /dev/null
@@ -1 +0,0 @@
-perf-util-y += util/
diff --git a/tools/perf/arch/csky/util/Build b/tools/perf/arch/csky/util/Build
deleted file mode 100644
index 6b2d0e021b11..000000000000
--- a/tools/perf/arch/csky/util/Build
+++ /dev/null
@@ -1 +0,0 @@
-perf-util-y += perf_regs.o
diff --git a/tools/perf/arch/csky/util/perf_regs.c b/tools/perf/arch/csky/util/perf_regs.c
deleted file mode 100644
index 2cf7a54106e0..000000000000
--- a/tools/perf/arch/csky/util/perf_regs.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include "perf_regs.h"
-#include "../../util/perf_regs.h"
-
-uint64_t arch__intr_reg_mask(void)
-{
- return PERF_REGS_MASK;
-}
-
-uint64_t arch__user_reg_mask(void)
-{
- return PERF_REGS_MASK;
-}
diff --git a/tools/perf/arch/loongarch/util/Build b/tools/perf/arch/loongarch/util/Build
index 0aa31986ecb5..0c958c8e0718 100644
--- a/tools/perf/arch/loongarch/util/Build
+++ b/tools/perf/arch/loongarch/util/Build
@@ -1,5 +1,4 @@
perf-util-y += header.o
-perf-util-y += perf_regs.o
perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
diff --git a/tools/perf/arch/loongarch/util/perf_regs.c b/tools/perf/arch/loongarch/util/perf_regs.c
deleted file mode 100644
index 03a5bc0cf64c..000000000000
--- a/tools/perf/arch/loongarch/util/perf_regs.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include "perf_regs.h"
-#include "../../../util/perf_regs.h"
-
-uint64_t arch__intr_reg_mask(void)
-{
- return PERF_REGS_MASK;
-}
-
-uint64_t arch__user_reg_mask(void)
-{
- return PERF_REGS_MASK;
-}
diff --git a/tools/perf/arch/mips/util/Build b/tools/perf/arch/mips/util/Build
index 691fa2051958..818b808a8247 100644
--- a/tools/perf/arch/mips/util/Build
+++ b/tools/perf/arch/mips/util/Build
@@ -1,2 +1 @@
-perf-util-y += perf_regs.o
perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
diff --git a/tools/perf/arch/mips/util/perf_regs.c b/tools/perf/arch/mips/util/perf_regs.c
deleted file mode 100644
index 2cf7a54106e0..000000000000
--- a/tools/perf/arch/mips/util/perf_regs.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include "perf_regs.h"
-#include "../../util/perf_regs.h"
-
-uint64_t arch__intr_reg_mask(void)
-{
- return PERF_REGS_MASK;
-}
-
-uint64_t arch__user_reg_mask(void)
-{
- return PERF_REGS_MASK;
-}
diff --git a/tools/perf/arch/powerpc/util/perf_regs.c b/tools/perf/arch/powerpc/util/perf_regs.c
index 779073f7e992..93f929fc32e3 100644
--- a/tools/perf/arch/powerpc/util/perf_regs.c
+++ b/tools/perf/arch/powerpc/util/perf_regs.c
@@ -123,50 +123,3 @@ int arch_sdt_arg_parse_op(char *old_op, char **new_op)
return SDT_ARG_VALID;
}
-
-uint64_t arch__intr_reg_mask(void)
-{
- struct perf_event_attr attr = {
- .type = PERF_TYPE_HARDWARE,
- .config = PERF_COUNT_HW_CPU_CYCLES,
- .sample_type = PERF_SAMPLE_REGS_INTR,
- .precise_ip = 1,
- .disabled = 1,
- .exclude_kernel = 1,
- };
- int fd;
- u32 version;
- u64 extended_mask = 0, mask = PERF_REGS_MASK;
-
- /*
- * Get the PVR value to set the extended
- * mask specific to platform.
- */
- version = (((mfspr(SPRN_PVR)) >> 16) & 0xFFFF);
- if (version == PVR_POWER9)
- extended_mask = PERF_REG_PMU_MASK_300;
- else if ((version == PVR_POWER10) || (version == PVR_POWER11))
- extended_mask = PERF_REG_PMU_MASK_31;
- else
- return mask;
-
- attr.sample_regs_intr = extended_mask;
- attr.sample_period = 1;
- event_attr_init(&attr);
-
- /*
- * check if the pmu supports perf extended regs, before
- * returning the register mask to sample.
- */
- fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
- if (fd != -1) {
- close(fd);
- mask |= extended_mask;
- }
- return mask;
-}
-
-uint64_t arch__user_reg_mask(void)
-{
- return PERF_REGS_MASK;
-}
diff --git a/tools/perf/arch/riscv/include/perf_regs.h b/tools/perf/arch/riscv/include/perf_regs.h
index 89d5bbb8d2b8..af7a1b47bf66 100644
--- a/tools/perf/arch/riscv/include/perf_regs.h
+++ b/tools/perf/arch/riscv/include/perf_regs.h
@@ -10,10 +10,15 @@
#define PERF_REGS_MASK ((1ULL << PERF_REG_RISCV_MAX) - 1)
#define PERF_REGS_MAX PERF_REG_RISCV_MAX
+
+#if defined(__riscv_xlen)
#if __riscv_xlen == 64
-#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64
+#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64
#else
#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32
#endif
+#else
+#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_NONE
+#endif
#endif /* ARCH_PERF_REGS_H */
diff --git a/tools/perf/arch/riscv/util/Build b/tools/perf/arch/riscv/util/Build
index 628b9ebd418b..da5b12e7f862 100644
--- a/tools/perf/arch/riscv/util/Build
+++ b/tools/perf/arch/riscv/util/Build
@@ -1,4 +1,3 @@
-perf-util-y += perf_regs.o
perf-util-y += header.o
perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
diff --git a/tools/perf/arch/riscv/util/perf_regs.c b/tools/perf/arch/riscv/util/perf_regs.c
deleted file mode 100644
index 2cf7a54106e0..000000000000
--- a/tools/perf/arch/riscv/util/perf_regs.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include "perf_regs.h"
-#include "../../util/perf_regs.h"
-
-uint64_t arch__intr_reg_mask(void)
-{
- return PERF_REGS_MASK;
-}
-
-uint64_t arch__user_reg_mask(void)
-{
- return PERF_REGS_MASK;
-}
diff --git a/tools/perf/arch/s390/util/Build b/tools/perf/arch/s390/util/Build
index 5391d26fedd4..3b09c058e0ec 100644
--- a/tools/perf/arch/s390/util/Build
+++ b/tools/perf/arch/s390/util/Build
@@ -1,6 +1,5 @@
perf-util-y += header.o
perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
-perf-util-y += perf_regs.o
perf-util-y += machine.o
perf-util-y += pmu.o
diff --git a/tools/perf/arch/s390/util/perf_regs.c b/tools/perf/arch/s390/util/perf_regs.c
deleted file mode 100644
index 2cf7a54106e0..000000000000
--- a/tools/perf/arch/s390/util/perf_regs.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include "perf_regs.h"
-#include "../../util/perf_regs.h"
-
-uint64_t arch__intr_reg_mask(void)
-{
- return PERF_REGS_MASK;
-}
-
-uint64_t arch__user_reg_mask(void)
-{
- return PERF_REGS_MASK;
-}
diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c
index a7ca4154fdf9..41141cebe226 100644
--- a/tools/perf/arch/x86/util/perf_regs.c
+++ b/tools/perf/arch/x86/util/perf_regs.c
@@ -233,51 +233,3 @@ int arch_sdt_arg_parse_op(char *old_op, char **new_op)
return SDT_ARG_VALID;
}
-
-uint64_t arch__intr_reg_mask(void)
-{
- struct perf_event_attr attr = {
- .type = PERF_TYPE_HARDWARE,
- .config = PERF_COUNT_HW_CPU_CYCLES,
- .sample_type = PERF_SAMPLE_REGS_INTR,
- .sample_regs_intr = PERF_REG_EXTENDED_MASK,
- .precise_ip = 1,
- .disabled = 1,
- .exclude_kernel = 1,
- };
- int fd;
- /*
- * In an unnamed union, init it here to build on older gcc versions
- */
- attr.sample_period = 1;
-
- if (perf_pmus__num_core_pmus() > 1) {
- struct perf_pmu *pmu = NULL;
- __u64 type = PERF_TYPE_RAW;
-
- /*
- * The same register set is supported among different hybrid PMUs.
- * Only check the first available one.
- */
- while ((pmu = perf_pmus__scan_core(pmu)) != NULL) {
- type = pmu->type;
- break;
- }
- attr.config |= type << PERF_PMU_TYPE_SHIFT;
- }
-
- event_attr_init(&attr);
-
- fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
- if (fd != -1) {
- close(fd);
- return (PERF_REG_EXTENDED_MASK | PERF_REGS_MASK);
- }
-
- return PERF_REGS_MASK;
-}
-
-uint64_t arch__user_reg_mask(void)
-{
- return PERF_REGS_MASK;
-}
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 5ac1a05601b1..a36528fd41c6 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1055,13 +1055,13 @@ static void __evsel__config_callchain(struct evsel *evsel, struct record_opts *o
evsel__set_sample_bit(evsel, REGS_USER);
evsel__set_sample_bit(evsel, STACK_USER);
if (opts->sample_user_regs &&
- DWARF_MINIMAL_REGS(e_machine) != arch__user_reg_mask()) {
+ DWARF_MINIMAL_REGS(e_machine) != perf_user_reg_mask(EM_HOST)) {
attr->sample_regs_user |= DWARF_MINIMAL_REGS(e_machine);
pr_warning("WARNING: The use of --call-graph=dwarf may require all the user registers, "
"specifying a subset with --user-regs may render DWARF unwinding unreliable, "
"so the minimal registers set (IP, SP) is explicitly forced.\n");
} else {
- attr->sample_regs_user |= arch__user_reg_mask();
+ attr->sample_regs_user |= perf_user_reg_mask(EM_HOST);
}
attr->sample_stack_user = param->dump_size;
attr->exclude_callchain_user = 1;
diff --git a/tools/perf/util/parse-regs-options.c b/tools/perf/util/parse-regs-options.c
index b44b47d9059f..c93c2f0c8105 100644
--- a/tools/perf/util/parse-regs-options.c
+++ b/tools/perf/util/parse-regs-options.c
@@ -66,7 +66,7 @@ __parse_regs(const struct option *opt, const char *str, int unset, bool intr)
if (*mode)
return -1;
- mask = intr ? arch__intr_reg_mask() : arch__user_reg_mask();
+ mask = intr ? perf_intr_reg_mask(EM_HOST) : perf_user_reg_mask(EM_HOST);
/* str may be NULL in case no arg is passed to -I */
if (!str) {
diff --git a/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c b/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c
index 9dcda80d310f..666874f625b6 100644
--- a/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c
+++ b/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c
@@ -1,7 +1,58 @@
// SPDX-License-Identifier: GPL-2.0
+#include <errno.h>
+#include <regex.h>
+#include <string.h>
+#include <sys/auxv.h>
+#include <linux/kernel.h>
+#include <linux/zalloc.h>
+#include "../debug.h"
+#include "../event.h"
#include "../perf_regs.h"
-#include "../../../arch/arm64/include/uapi/asm/perf_regs.h"
+#include "../../perf-sys.h"
+#include "../../arch/arm64/include/perf_regs.h"
+
+#define SMPL_REG_MASK(b) (1ULL << (b))
+
+#ifndef HWCAP_SVE
+#define HWCAP_SVE (1 << 22)
+#endif
+
+uint64_t __perf_reg_mask_arm64(bool intr)
+{
+ struct perf_event_attr attr = {
+ .type = PERF_TYPE_HARDWARE,
+ .config = PERF_COUNT_HW_CPU_CYCLES,
+ .sample_type = PERF_SAMPLE_REGS_USER,
+ .disabled = 1,
+ .exclude_kernel = 1,
+ .sample_period = 1,
+ .sample_regs_user = PERF_REGS_MASK
+ };
+ int fd;
+
+ if (intr)
+ return PERF_REGS_MASK;
+
+ if (getauxval(AT_HWCAP) & HWCAP_SVE)
+ attr.sample_regs_user |= SMPL_REG_MASK(PERF_REG_ARM64_VG);
+
+ /*
+ * Check if the pmu supports perf extended regs, before
+ * returning the register mask to sample. Open the event
+ * on the perf process to check this.
+ */
+ if (attr.sample_regs_user != PERF_REGS_MASK) {
+ event_attr_init(&attr);
+ fd = sys_perf_event_open(&attr, /*pid=*/0, /*cpu=*/-1,
+ /*group_fd=*/-1, /*flags=*/0);
+ if (fd != -1) {
+ close(fd);
+ return attr.sample_regs_user;
+ }
+ }
+ return PERF_REGS_MASK;
+}
const char *__perf_reg_name_arm64(int id)
{
diff --git a/tools/perf/util/perf-regs-arch/perf_regs_arm.c b/tools/perf/util/perf-regs-arch/perf_regs_arm.c
index e29d130a587a..184d6e248dfc 100644
--- a/tools/perf/util/perf-regs-arch/perf_regs_arm.c
+++ b/tools/perf/util/perf-regs-arch/perf_regs_arm.c
@@ -1,7 +1,12 @@
// SPDX-License-Identifier: GPL-2.0
#include "../perf_regs.h"
-#include "../../../arch/arm/include/uapi/asm/perf_regs.h"
+#include "../../arch/arm/include/perf_regs.h"
+
+uint64_t __perf_reg_mask_arm(bool intr __maybe_unused)
+{
+ return PERF_REGS_MASK;
+}
const char *__perf_reg_name_arm(int id)
{
diff --git a/tools/perf/util/perf-regs-arch/perf_regs_csky.c b/tools/perf/util/perf-regs-arch/perf_regs_csky.c
index 95808f93d45b..16cbd8303acf 100644
--- a/tools/perf/util/perf-regs-arch/perf_regs_csky.c
+++ b/tools/perf/util/perf-regs-arch/perf_regs_csky.c
@@ -9,7 +9,12 @@
#include "../perf_regs.h"
#undef __CSKYABIV2__
#define __CSKYABIV2__ 1 // Always want the V2 register definitions.
-#include "../../arch/csky/include/uapi/asm/perf_regs.h"
+#include "../../arch/csky/include/perf_regs.h"
+
+uint64_t __perf_reg_mask_csky(bool intr __maybe_unused)
+{
+ return PERF_REGS_MASK;
+}
const char *__perf_reg_name_csky(int id, uint32_t e_flags)
{
diff --git a/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c b/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c
index 043f97f4e3ac..478ee889afa1 100644
--- a/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c
+++ b/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c
@@ -1,7 +1,12 @@
// SPDX-License-Identifier: GPL-2.0
#include "../perf_regs.h"
-#include "../../../arch/loongarch/include/uapi/asm/perf_regs.h"
+#include "../../arch/loongarch/include/perf_regs.h"
+
+uint64_t __perf_reg_mask_loongarch(bool intr __maybe_unused)
+{
+ return PERF_REGS_MASK;
+}
const char *__perf_reg_name_loongarch(int id)
{
diff --git a/tools/perf/util/perf-regs-arch/perf_regs_mips.c b/tools/perf/util/perf-regs-arch/perf_regs_mips.c
index 793178fc3c78..c5a475f6ec64 100644
--- a/tools/perf/util/perf-regs-arch/perf_regs_mips.c
+++ b/tools/perf/util/perf-regs-arch/perf_regs_mips.c
@@ -1,7 +1,12 @@
// SPDX-License-Identifier: GPL-2.0
#include "../perf_regs.h"
-#include "../../../arch/mips/include/uapi/asm/perf_regs.h"
+#include "../../arch/mips/include/perf_regs.h"
+
+uint64_t __perf_reg_mask_mips(bool intr __maybe_unused)
+{
+ return PERF_REGS_MASK;
+}
const char *__perf_reg_name_mips(int id)
{
diff --git a/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c b/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c
index 08636bb09a3a..f0a547ad809b 100644
--- a/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c
+++ b/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c
@@ -1,7 +1,82 @@
// SPDX-License-Identifier: GPL-2.0
+#include <errno.h>
+#include <string.h>
+#include <regex.h>
+#include <linux/zalloc.h>
+
+#include "../debug.h"
+#include "../event.h"
+#include "../header.h"
#include "../perf_regs.h"
-#include "../../../arch/powerpc/include/uapi/asm/perf_regs.h"
+#include "../../perf-sys.h"
+#include "../../arch/powerpc/util/utils_header.h"
+#include "../../arch/powerpc/include/perf_regs.h"
+
+#include <linux/kernel.h>
+
+#define PVR_POWER9 0x004E
+#define PVR_POWER10 0x0080
+#define PVR_POWER11 0x0082
+
+/*
+ * mfspr is a POWERPC specific instruction, ensure it's only
+ * built and called on POWERPC by guarding with __powerpc64__
+ * or __powerpc__.
+ */
+#if defined(__powerpc64__) && defined(__powerpc__)
+uint64_t __perf_reg_mask_powerpc(bool intr)
+{
+ struct perf_event_attr attr = {
+ .type = PERF_TYPE_HARDWARE,
+ .config = PERF_COUNT_HW_CPU_CYCLES,
+ .sample_type = PERF_SAMPLE_REGS_INTR,
+ .precise_ip = 1,
+ .disabled = 1,
+ .exclude_kernel = 1,
+ };
+ int fd;
+ u32 version;
+ u64 extended_mask = 0, mask = PERF_REGS_MASK;
+
+ if (!intr)
+ return PERF_REGS_MASK;
+
+ /*
+ * Get the PVR value to set the extended
+ * mask specific to platform.
+ */
+ version = (((mfspr(SPRN_PVR)) >> 16) & 0xFFFF);
+ if (version == PVR_POWER9)
+ extended_mask = PERF_REG_PMU_MASK_300;
+ else if ((version == PVR_POWER10) || (version == PVR_POWER11))
+ extended_mask = PERF_REG_PMU_MASK_31;
+ else
+ return mask;
+
+ attr.sample_regs_intr = extended_mask;
+ attr.sample_period = 1;
+ event_attr_init(&attr);
+
+ /*
+ * Check if the pmu supports perf extended regs, before
+ * returning the register mask to sample. Open the event
+ * on the perf process to check this.
+ */
+ fd = sys_perf_event_open(&attr, /*pid=*/0, /*cpu=*/-1,
+ /*group_fd=*/-1, /*flags=*/0);
+ if (fd != -1) {
+ close(fd);
+ mask |= extended_mask;
+ }
+ return mask;
+}
+#else
+uint64_t __perf_reg_mask_powerpc(bool intr __maybe_unused)
+{
+ return PERF_REGS_MASK;
+}
+#endif
const char *__perf_reg_name_powerpc(int id)
{
diff --git a/tools/perf/util/perf-regs-arch/perf_regs_riscv.c b/tools/perf/util/perf-regs-arch/perf_regs_riscv.c
index 337b687c655d..5b5f21fcba8c 100644
--- a/tools/perf/util/perf-regs-arch/perf_regs_riscv.c
+++ b/tools/perf/util/perf-regs-arch/perf_regs_riscv.c
@@ -1,7 +1,12 @@
// SPDX-License-Identifier: GPL-2.0
#include "../perf_regs.h"
-#include "../../../arch/riscv/include/uapi/asm/perf_regs.h"
+#include "../../arch/riscv/include/perf_regs.h"
+
+uint64_t __perf_reg_mask_riscv(bool intr __maybe_unused)
+{
+ return PERF_REGS_MASK;
+}
const char *__perf_reg_name_riscv(int id)
{
diff --git a/tools/perf/util/perf-regs-arch/perf_regs_s390.c b/tools/perf/util/perf-regs-arch/perf_regs_s390.c
index d69bba881080..c61df24edf0f 100644
--- a/tools/perf/util/perf-regs-arch/perf_regs_s390.c
+++ b/tools/perf/util/perf-regs-arch/perf_regs_s390.c
@@ -1,7 +1,12 @@
// SPDX-License-Identifier: GPL-2.0
#include "../perf_regs.h"
-#include "../../../arch/s390/include/uapi/asm/perf_regs.h"
+#include "../../arch/s390/include/perf_regs.h"
+
+uint64_t __perf_reg_mask_s390(bool intr __maybe_unused)
+{
+ return PERF_REGS_MASK;
+}
const char *__perf_reg_name_s390(int id)
{
diff --git a/tools/perf/util/perf-regs-arch/perf_regs_x86.c b/tools/perf/util/perf-regs-arch/perf_regs_x86.c
index 708954a9d35d..d573f9a9ca46 100644
--- a/tools/perf/util/perf-regs-arch/perf_regs_x86.c
+++ b/tools/perf/util/perf-regs-arch/perf_regs_x86.c
@@ -1,7 +1,65 @@
// SPDX-License-Identifier: GPL-2.0
+#include <errno.h>
+#include <string.h>
+#include <regex.h>
+#include <linux/kernel.h>
+#include <linux/zalloc.h>
+
+#include "../debug.h"
+#include "../event.h"
+#include "../pmu.h"
+#include "../pmus.h"
#include "../perf_regs.h"
-#include "../../../arch/x86/include/uapi/asm/perf_regs.h"
+#include "../../perf-sys.h"
+#include "../../arch/x86/include/perf_regs.h"
+
+uint64_t __perf_reg_mask_x86(bool intr)
+{
+ struct perf_event_attr attr = {
+ .type = PERF_TYPE_HARDWARE,
+ .config = PERF_COUNT_HW_CPU_CYCLES,
+ .sample_type = PERF_SAMPLE_REGS_INTR,
+ .sample_regs_intr = PERF_REG_EXTENDED_MASK,
+ .precise_ip = 1,
+ .disabled = 1,
+ .exclude_kernel = 1,
+ };
+ int fd;
+
+ if (!intr)
+ return PERF_REGS_MASK;
+
+ /*
+ * In an unnamed union, init it here to build on older gcc versions
+ */
+ attr.sample_period = 1;
+
+ if (perf_pmus__num_core_pmus() > 1) {
+ struct perf_pmu *pmu = NULL;
+ __u64 type = PERF_TYPE_RAW;
+
+ /*
+ * The same register set is supported among different hybrid PMUs.
+ * Only check the first available one.
+ */
+ while ((pmu = perf_pmus__scan_core(pmu)) != NULL) {
+ type = pmu->type;
+ break;
+ }
+ attr.config |= type << PERF_PMU_TYPE_SHIFT;
+ }
+
+ event_attr_init(&attr);
+ fd = sys_perf_event_open(&attr, /*pid=*/0, /*cpu=*/-1,
+ /*group_fd=*/-1, /*flags=*/0);
+ if (fd != -1) {
+ close(fd);
+ return (PERF_REG_EXTENDED_MASK | PERF_REGS_MASK);
+ }
+
+ return PERF_REGS_MASK;
+}
const char *__perf_reg_name_x86(int id)
{
diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c
index 14b7be30ab20..4d9a286a0e56 100644
--- a/tools/perf/util/perf_regs.c
+++ b/tools/perf/util/perf_regs.c
@@ -13,14 +13,90 @@ int __weak arch_sdt_arg_parse_op(char *old_op __maybe_unused,
return SDT_ARG_SKIP;
}
-uint64_t __weak arch__intr_reg_mask(void)
+uint64_t perf_intr_reg_mask(uint16_t e_machine)
{
- return 0;
+ uint64_t mask = 0;
+
+ switch (e_machine) {
+ case EM_ARM:
+ mask = __perf_reg_mask_arm(/*intr=*/true);
+ break;
+ case EM_AARCH64:
+ mask = __perf_reg_mask_arm64(/*intr=*/true);
+ break;
+ case EM_CSKY:
+ mask = __perf_reg_mask_csky(/*intr=*/true);
+ break;
+ case EM_LOONGARCH:
+ mask = __perf_reg_mask_loongarch(/*intr=*/true);
+ break;
+ case EM_MIPS:
+ mask = __perf_reg_mask_mips(/*intr=*/true);
+ break;
+ case EM_PPC:
+ case EM_PPC64:
+ mask = __perf_reg_mask_powerpc(/*intr=*/true);
+ break;
+ case EM_RISCV:
+ mask = __perf_reg_mask_riscv(/*intr=*/true);
+ break;
+ case EM_S390:
+ mask = __perf_reg_mask_s390(/*intr=*/true);
+ break;
+ case EM_386:
+ case EM_X86_64:
+ mask = __perf_reg_mask_x86(/*intr=*/true);
+ break;
+ default:
+ pr_debug("Unknown ELF machine %d, interrupt sampling register mask will be empty.\n",
+ e_machine);
+ break;
+ }
+
+ return mask;
}
-uint64_t __weak arch__user_reg_mask(void)
+uint64_t perf_user_reg_mask(uint16_t e_machine)
{
- return 0;
+ uint64_t mask = 0;
+
+ switch (e_machine) {
+ case EM_ARM:
+ mask = __perf_reg_mask_arm(/*intr=*/false);
+ break;
+ case EM_AARCH64:
+ mask = __perf_reg_mask_arm64(/*intr=*/false);
+ break;
+ case EM_CSKY:
+ mask = __perf_reg_mask_csky(/*intr=*/false);
+ break;
+ case EM_LOONGARCH:
+ mask = __perf_reg_mask_loongarch(/*intr=*/false);
+ break;
+ case EM_MIPS:
+ mask = __perf_reg_mask_mips(/*intr=*/false);
+ break;
+ case EM_PPC:
+ case EM_PPC64:
+ mask = __perf_reg_mask_powerpc(/*intr=*/false);
+ break;
+ case EM_RISCV:
+ mask = __perf_reg_mask_riscv(/*intr=*/false);
+ break;
+ case EM_S390:
+ mask = __perf_reg_mask_s390(/*intr=*/false);
+ break;
+ case EM_386:
+ case EM_X86_64:
+ mask = __perf_reg_mask_x86(/*intr=*/false);
+ break;
+ default:
+ pr_debug("Unknown ELF machine %d, user sampling register mask will be empty.\n",
+ e_machine);
+ break;
+ }
+
+ return mask;
}
const char *perf_reg_name(int id, uint16_t e_machine, uint32_t e_flags)
diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h
index ed7c1b1358fa..2b27139acadb 100644
--- a/tools/perf/util/perf_regs.h
+++ b/tools/perf/util/perf_regs.h
@@ -13,37 +13,55 @@ enum {
};
int arch_sdt_arg_parse_op(char *old_op, char **new_op);
-uint64_t arch__intr_reg_mask(void);
-uint64_t arch__user_reg_mask(void);
+uint64_t perf_intr_reg_mask(uint16_t e_machine);
+uint64_t perf_user_reg_mask(uint16_t e_machine);
const char *perf_reg_name(int id, uint16_t e_machine, uint32_t e_flags);
int perf_reg_value(u64 *valp, struct regs_dump *regs, int id);
uint64_t perf_arch_reg_ip(uint16_t e_machine);
uint64_t perf_arch_reg_sp(uint16_t e_machine);
+
+uint64_t __perf_reg_mask_arm64(bool intr);
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_arm(bool intr);
const char *__perf_reg_name_arm(int id);
uint64_t __perf_reg_ip_arm(void);
uint64_t __perf_reg_sp_arm(void);
+
+uint64_t __perf_reg_mask_csky(bool intr);
const char *__perf_reg_name_csky(int id, uint32_t e_flags);
uint64_t __perf_reg_ip_csky(void);
uint64_t __perf_reg_sp_csky(void);
+
+uint64_t __perf_reg_mask_loongarch(bool intr);
const char *__perf_reg_name_loongarch(int id);
uint64_t __perf_reg_ip_loongarch(void);
uint64_t __perf_reg_sp_loongarch(void);
+
+uint64_t __perf_reg_mask_mips(bool intr);
const char *__perf_reg_name_mips(int id);
uint64_t __perf_reg_ip_mips(void);
uint64_t __perf_reg_sp_mips(void);
+
+uint64_t __perf_reg_mask_powerpc(bool intr);
const char *__perf_reg_name_powerpc(int id);
uint64_t __perf_reg_ip_powerpc(void);
uint64_t __perf_reg_sp_powerpc(void);
+
+uint64_t __perf_reg_mask_riscv(bool intr);
const char *__perf_reg_name_riscv(int id);
uint64_t __perf_reg_ip_riscv(void);
uint64_t __perf_reg_sp_riscv(void);
+
+uint64_t __perf_reg_mask_s390(bool intr);
const char *__perf_reg_name_s390(int id);
uint64_t __perf_reg_ip_s390(void);
uint64_t __perf_reg_sp_s390(void);
+
+uint64_t __perf_reg_mask_x86(bool intr);
const char *__perf_reg_name_x86(int id);
uint64_t __perf_reg_ip_x86(void);
uint64_t __perf_reg_sp_x86(void);
--
2.34.1
On Mon, Feb 2, 2026 at 6:48 PM Dapeng Mi <dapeng1.mi@linux.intel.com> wrote:
>
> Currently, some architecture-specific perf-regs functions, such as
> arch__intr_reg_mask() and arch__user_reg_mask(), are defined with the
> __weak attribute. This approach ensures that only functions matching
> the architecture of the build/run host are compiled and executed,
> reducing build time and binary size.
>
> However, this __weak attribute restricts these functions to be called
> only on the same architecture, preventing cross-architecture
> functionality. For example, a perf.data file captured on x86 cannot be
> parsed on an ARM platform.
>
> To address this limitation, this patch removes the __weak attribute from
> these perf-regs functions. The architecture-specific code is moved from
> the arch/ directory to the util/perf-regs-arch/ directory. The
> appropriate architectural functions are then called based on the EM_HOST.
>
> No functional changes are intended.
>
> Suggested-by: Ian Rogers <irogers@google.com>
> Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Thanks,
Ian
> ---
> tools/perf/arch/arm/util/Build | 2 -
> tools/perf/arch/arm/util/perf_regs.c | 13 ---
> tools/perf/arch/arm64/util/perf_regs.c | 36 --------
> tools/perf/arch/csky/Build | 1 -
> tools/perf/arch/csky/util/Build | 1 -
> tools/perf/arch/csky/util/perf_regs.c | 13 ---
> tools/perf/arch/loongarch/util/Build | 1 -
> tools/perf/arch/loongarch/util/perf_regs.c | 13 ---
> tools/perf/arch/mips/util/Build | 1 -
> tools/perf/arch/mips/util/perf_regs.c | 13 ---
> tools/perf/arch/powerpc/util/perf_regs.c | 47 -----------
> tools/perf/arch/riscv/include/perf_regs.h | 7 +-
> tools/perf/arch/riscv/util/Build | 1 -
> tools/perf/arch/riscv/util/perf_regs.c | 13 ---
> tools/perf/arch/s390/util/Build | 1 -
> tools/perf/arch/s390/util/perf_regs.c | 13 ---
> tools/perf/arch/x86/util/perf_regs.c | 48 -----------
> tools/perf/util/evsel.c | 4 +-
> tools/perf/util/parse-regs-options.c | 2 +-
> .../util/perf-regs-arch/perf_regs_aarch64.c | 53 +++++++++++-
> .../perf/util/perf-regs-arch/perf_regs_arm.c | 7 +-
> .../perf/util/perf-regs-arch/perf_regs_csky.c | 7 +-
> .../util/perf-regs-arch/perf_regs_loongarch.c | 7 +-
> .../perf/util/perf-regs-arch/perf_regs_mips.c | 7 +-
> .../util/perf-regs-arch/perf_regs_powerpc.c | 77 ++++++++++++++++-
> .../util/perf-regs-arch/perf_regs_riscv.c | 7 +-
> .../perf/util/perf-regs-arch/perf_regs_s390.c | 7 +-
> .../perf/util/perf-regs-arch/perf_regs_x86.c | 60 ++++++++++++-
> tools/perf/util/perf_regs.c | 84 ++++++++++++++++++-
> tools/perf/util/perf_regs.h | 22 ++++-
> 30 files changed, 332 insertions(+), 236 deletions(-)
> delete mode 100644 tools/perf/arch/arm/util/perf_regs.c
> delete mode 100644 tools/perf/arch/csky/Build
> delete mode 100644 tools/perf/arch/csky/util/Build
> delete mode 100644 tools/perf/arch/csky/util/perf_regs.c
> delete mode 100644 tools/perf/arch/loongarch/util/perf_regs.c
> delete mode 100644 tools/perf/arch/mips/util/perf_regs.c
> delete mode 100644 tools/perf/arch/riscv/util/perf_regs.c
> delete mode 100644 tools/perf/arch/s390/util/perf_regs.c
>
> diff --git a/tools/perf/arch/arm/util/Build b/tools/perf/arch/arm/util/Build
> index 3291f893b943..b94bf3c5279a 100644
> --- a/tools/perf/arch/arm/util/Build
> +++ b/tools/perf/arch/arm/util/Build
> @@ -1,5 +1,3 @@
> -perf-util-y += perf_regs.o
> -
> perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
>
> perf-util-y += pmu.o auxtrace.o cs-etm.o
> diff --git a/tools/perf/arch/arm/util/perf_regs.c b/tools/perf/arch/arm/util/perf_regs.c
> deleted file mode 100644
> index 03a5bc0cf64c..000000000000
> --- a/tools/perf/arch/arm/util/perf_regs.c
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -#include "perf_regs.h"
> -#include "../../../util/perf_regs.h"
> -
> -uint64_t arch__intr_reg_mask(void)
> -{
> - return PERF_REGS_MASK;
> -}
> -
> -uint64_t arch__user_reg_mask(void)
> -{
> - return PERF_REGS_MASK;
> -}
> diff --git a/tools/perf/arch/arm64/util/perf_regs.c b/tools/perf/arch/arm64/util/perf_regs.c
> index 9bb768e1bea1..47f58eaba032 100644
> --- a/tools/perf/arch/arm64/util/perf_regs.c
> +++ b/tools/perf/arch/arm64/util/perf_regs.c
> @@ -103,39 +103,3 @@ int arch_sdt_arg_parse_op(char *old_op, char **new_op)
>
> return SDT_ARG_VALID;
> }
> -
> -uint64_t arch__intr_reg_mask(void)
> -{
> - return PERF_REGS_MASK;
> -}
> -
> -uint64_t arch__user_reg_mask(void)
> -{
> - struct perf_event_attr attr = {
> - .type = PERF_TYPE_HARDWARE,
> - .config = PERF_COUNT_HW_CPU_CYCLES,
> - .sample_type = PERF_SAMPLE_REGS_USER,
> - .disabled = 1,
> - .exclude_kernel = 1,
> - .sample_period = 1,
> - .sample_regs_user = PERF_REGS_MASK
> - };
> - int fd;
> -
> - if (getauxval(AT_HWCAP) & HWCAP_SVE)
> - attr.sample_regs_user |= SMPL_REG_MASK(PERF_REG_ARM64_VG);
> -
> - /*
> - * Check if the pmu supports perf extended regs, before
> - * returning the register mask to sample.
> - */
> - if (attr.sample_regs_user != PERF_REGS_MASK) {
> - event_attr_init(&attr);
> - fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
> - if (fd != -1) {
> - close(fd);
> - return attr.sample_regs_user;
> - }
> - }
> - return PERF_REGS_MASK;
> -}
> diff --git a/tools/perf/arch/csky/Build b/tools/perf/arch/csky/Build
> deleted file mode 100644
> index e63eabc2c8f4..000000000000
> --- a/tools/perf/arch/csky/Build
> +++ /dev/null
> @@ -1 +0,0 @@
> -perf-util-y += util/
> diff --git a/tools/perf/arch/csky/util/Build b/tools/perf/arch/csky/util/Build
> deleted file mode 100644
> index 6b2d0e021b11..000000000000
> --- a/tools/perf/arch/csky/util/Build
> +++ /dev/null
> @@ -1 +0,0 @@
> -perf-util-y += perf_regs.o
> diff --git a/tools/perf/arch/csky/util/perf_regs.c b/tools/perf/arch/csky/util/perf_regs.c
> deleted file mode 100644
> index 2cf7a54106e0..000000000000
> --- a/tools/perf/arch/csky/util/perf_regs.c
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -#include "perf_regs.h"
> -#include "../../util/perf_regs.h"
> -
> -uint64_t arch__intr_reg_mask(void)
> -{
> - return PERF_REGS_MASK;
> -}
> -
> -uint64_t arch__user_reg_mask(void)
> -{
> - return PERF_REGS_MASK;
> -}
> diff --git a/tools/perf/arch/loongarch/util/Build b/tools/perf/arch/loongarch/util/Build
> index 0aa31986ecb5..0c958c8e0718 100644
> --- a/tools/perf/arch/loongarch/util/Build
> +++ b/tools/perf/arch/loongarch/util/Build
> @@ -1,5 +1,4 @@
> perf-util-y += header.o
> -perf-util-y += perf_regs.o
>
> perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
> perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
> diff --git a/tools/perf/arch/loongarch/util/perf_regs.c b/tools/perf/arch/loongarch/util/perf_regs.c
> deleted file mode 100644
> index 03a5bc0cf64c..000000000000
> --- a/tools/perf/arch/loongarch/util/perf_regs.c
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -#include "perf_regs.h"
> -#include "../../../util/perf_regs.h"
> -
> -uint64_t arch__intr_reg_mask(void)
> -{
> - return PERF_REGS_MASK;
> -}
> -
> -uint64_t arch__user_reg_mask(void)
> -{
> - return PERF_REGS_MASK;
> -}
> diff --git a/tools/perf/arch/mips/util/Build b/tools/perf/arch/mips/util/Build
> index 691fa2051958..818b808a8247 100644
> --- a/tools/perf/arch/mips/util/Build
> +++ b/tools/perf/arch/mips/util/Build
> @@ -1,2 +1 @@
> -perf-util-y += perf_regs.o
> perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
> diff --git a/tools/perf/arch/mips/util/perf_regs.c b/tools/perf/arch/mips/util/perf_regs.c
> deleted file mode 100644
> index 2cf7a54106e0..000000000000
> --- a/tools/perf/arch/mips/util/perf_regs.c
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -#include "perf_regs.h"
> -#include "../../util/perf_regs.h"
> -
> -uint64_t arch__intr_reg_mask(void)
> -{
> - return PERF_REGS_MASK;
> -}
> -
> -uint64_t arch__user_reg_mask(void)
> -{
> - return PERF_REGS_MASK;
> -}
> diff --git a/tools/perf/arch/powerpc/util/perf_regs.c b/tools/perf/arch/powerpc/util/perf_regs.c
> index 779073f7e992..93f929fc32e3 100644
> --- a/tools/perf/arch/powerpc/util/perf_regs.c
> +++ b/tools/perf/arch/powerpc/util/perf_regs.c
> @@ -123,50 +123,3 @@ int arch_sdt_arg_parse_op(char *old_op, char **new_op)
>
> return SDT_ARG_VALID;
> }
> -
> -uint64_t arch__intr_reg_mask(void)
> -{
> - struct perf_event_attr attr = {
> - .type = PERF_TYPE_HARDWARE,
> - .config = PERF_COUNT_HW_CPU_CYCLES,
> - .sample_type = PERF_SAMPLE_REGS_INTR,
> - .precise_ip = 1,
> - .disabled = 1,
> - .exclude_kernel = 1,
> - };
> - int fd;
> - u32 version;
> - u64 extended_mask = 0, mask = PERF_REGS_MASK;
> -
> - /*
> - * Get the PVR value to set the extended
> - * mask specific to platform.
> - */
> - version = (((mfspr(SPRN_PVR)) >> 16) & 0xFFFF);
> - if (version == PVR_POWER9)
> - extended_mask = PERF_REG_PMU_MASK_300;
> - else if ((version == PVR_POWER10) || (version == PVR_POWER11))
> - extended_mask = PERF_REG_PMU_MASK_31;
> - else
> - return mask;
> -
> - attr.sample_regs_intr = extended_mask;
> - attr.sample_period = 1;
> - event_attr_init(&attr);
> -
> - /*
> - * check if the pmu supports perf extended regs, before
> - * returning the register mask to sample.
> - */
> - fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
> - if (fd != -1) {
> - close(fd);
> - mask |= extended_mask;
> - }
> - return mask;
> -}
> -
> -uint64_t arch__user_reg_mask(void)
> -{
> - return PERF_REGS_MASK;
> -}
> diff --git a/tools/perf/arch/riscv/include/perf_regs.h b/tools/perf/arch/riscv/include/perf_regs.h
> index 89d5bbb8d2b8..af7a1b47bf66 100644
> --- a/tools/perf/arch/riscv/include/perf_regs.h
> +++ b/tools/perf/arch/riscv/include/perf_regs.h
> @@ -10,10 +10,15 @@
>
> #define PERF_REGS_MASK ((1ULL << PERF_REG_RISCV_MAX) - 1)
> #define PERF_REGS_MAX PERF_REG_RISCV_MAX
> +
> +#if defined(__riscv_xlen)
> #if __riscv_xlen == 64
> -#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64
> +#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64
> #else
> #define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32
> #endif
> +#else
> +#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_NONE
> +#endif
>
> #endif /* ARCH_PERF_REGS_H */
> diff --git a/tools/perf/arch/riscv/util/Build b/tools/perf/arch/riscv/util/Build
> index 628b9ebd418b..da5b12e7f862 100644
> --- a/tools/perf/arch/riscv/util/Build
> +++ b/tools/perf/arch/riscv/util/Build
> @@ -1,4 +1,3 @@
> -perf-util-y += perf_regs.o
> perf-util-y += header.o
>
> perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
> diff --git a/tools/perf/arch/riscv/util/perf_regs.c b/tools/perf/arch/riscv/util/perf_regs.c
> deleted file mode 100644
> index 2cf7a54106e0..000000000000
> --- a/tools/perf/arch/riscv/util/perf_regs.c
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -#include "perf_regs.h"
> -#include "../../util/perf_regs.h"
> -
> -uint64_t arch__intr_reg_mask(void)
> -{
> - return PERF_REGS_MASK;
> -}
> -
> -uint64_t arch__user_reg_mask(void)
> -{
> - return PERF_REGS_MASK;
> -}
> diff --git a/tools/perf/arch/s390/util/Build b/tools/perf/arch/s390/util/Build
> index 5391d26fedd4..3b09c058e0ec 100644
> --- a/tools/perf/arch/s390/util/Build
> +++ b/tools/perf/arch/s390/util/Build
> @@ -1,6 +1,5 @@
> perf-util-y += header.o
> perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
> -perf-util-y += perf_regs.o
>
> perf-util-y += machine.o
> perf-util-y += pmu.o
> diff --git a/tools/perf/arch/s390/util/perf_regs.c b/tools/perf/arch/s390/util/perf_regs.c
> deleted file mode 100644
> index 2cf7a54106e0..000000000000
> --- a/tools/perf/arch/s390/util/perf_regs.c
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -#include "perf_regs.h"
> -#include "../../util/perf_regs.h"
> -
> -uint64_t arch__intr_reg_mask(void)
> -{
> - return PERF_REGS_MASK;
> -}
> -
> -uint64_t arch__user_reg_mask(void)
> -{
> - return PERF_REGS_MASK;
> -}
> diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c
> index a7ca4154fdf9..41141cebe226 100644
> --- a/tools/perf/arch/x86/util/perf_regs.c
> +++ b/tools/perf/arch/x86/util/perf_regs.c
> @@ -233,51 +233,3 @@ int arch_sdt_arg_parse_op(char *old_op, char **new_op)
>
> return SDT_ARG_VALID;
> }
> -
> -uint64_t arch__intr_reg_mask(void)
> -{
> - struct perf_event_attr attr = {
> - .type = PERF_TYPE_HARDWARE,
> - .config = PERF_COUNT_HW_CPU_CYCLES,
> - .sample_type = PERF_SAMPLE_REGS_INTR,
> - .sample_regs_intr = PERF_REG_EXTENDED_MASK,
> - .precise_ip = 1,
> - .disabled = 1,
> - .exclude_kernel = 1,
> - };
> - int fd;
> - /*
> - * In an unnamed union, init it here to build on older gcc versions
> - */
> - attr.sample_period = 1;
> -
> - if (perf_pmus__num_core_pmus() > 1) {
> - struct perf_pmu *pmu = NULL;
> - __u64 type = PERF_TYPE_RAW;
> -
> - /*
> - * The same register set is supported among different hybrid PMUs.
> - * Only check the first available one.
> - */
> - while ((pmu = perf_pmus__scan_core(pmu)) != NULL) {
> - type = pmu->type;
> - break;
> - }
> - attr.config |= type << PERF_PMU_TYPE_SHIFT;
> - }
> -
> - event_attr_init(&attr);
> -
> - fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
> - if (fd != -1) {
> - close(fd);
> - return (PERF_REG_EXTENDED_MASK | PERF_REGS_MASK);
> - }
> -
> - return PERF_REGS_MASK;
> -}
> -
> -uint64_t arch__user_reg_mask(void)
> -{
> - return PERF_REGS_MASK;
> -}
> diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
> index 5ac1a05601b1..a36528fd41c6 100644
> --- a/tools/perf/util/evsel.c
> +++ b/tools/perf/util/evsel.c
> @@ -1055,13 +1055,13 @@ static void __evsel__config_callchain(struct evsel *evsel, struct record_opts *o
> evsel__set_sample_bit(evsel, REGS_USER);
> evsel__set_sample_bit(evsel, STACK_USER);
> if (opts->sample_user_regs &&
> - DWARF_MINIMAL_REGS(e_machine) != arch__user_reg_mask()) {
> + DWARF_MINIMAL_REGS(e_machine) != perf_user_reg_mask(EM_HOST)) {
> attr->sample_regs_user |= DWARF_MINIMAL_REGS(e_machine);
> pr_warning("WARNING: The use of --call-graph=dwarf may require all the user registers, "
> "specifying a subset with --user-regs may render DWARF unwinding unreliable, "
> "so the minimal registers set (IP, SP) is explicitly forced.\n");
> } else {
> - attr->sample_regs_user |= arch__user_reg_mask();
> + attr->sample_regs_user |= perf_user_reg_mask(EM_HOST);
> }
> attr->sample_stack_user = param->dump_size;
> attr->exclude_callchain_user = 1;
> diff --git a/tools/perf/util/parse-regs-options.c b/tools/perf/util/parse-regs-options.c
> index b44b47d9059f..c93c2f0c8105 100644
> --- a/tools/perf/util/parse-regs-options.c
> +++ b/tools/perf/util/parse-regs-options.c
> @@ -66,7 +66,7 @@ __parse_regs(const struct option *opt, const char *str, int unset, bool intr)
> if (*mode)
> return -1;
>
> - mask = intr ? arch__intr_reg_mask() : arch__user_reg_mask();
> + mask = intr ? perf_intr_reg_mask(EM_HOST) : perf_user_reg_mask(EM_HOST);
>
> /* str may be NULL in case no arg is passed to -I */
> if (!str) {
> diff --git a/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c b/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c
> index 9dcda80d310f..666874f625b6 100644
> --- a/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c
> +++ b/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c
> @@ -1,7 +1,58 @@
> // SPDX-License-Identifier: GPL-2.0
> +#include <errno.h>
> +#include <regex.h>
> +#include <string.h>
> +#include <sys/auxv.h>
> +#include <linux/kernel.h>
> +#include <linux/zalloc.h>
>
> +#include "../debug.h"
> +#include "../event.h"
> #include "../perf_regs.h"
> -#include "../../../arch/arm64/include/uapi/asm/perf_regs.h"
> +#include "../../perf-sys.h"
> +#include "../../arch/arm64/include/perf_regs.h"
> +
> +#define SMPL_REG_MASK(b) (1ULL << (b))
> +
> +#ifndef HWCAP_SVE
> +#define HWCAP_SVE (1 << 22)
> +#endif
> +
> +uint64_t __perf_reg_mask_arm64(bool intr)
> +{
> + struct perf_event_attr attr = {
> + .type = PERF_TYPE_HARDWARE,
> + .config = PERF_COUNT_HW_CPU_CYCLES,
> + .sample_type = PERF_SAMPLE_REGS_USER,
> + .disabled = 1,
> + .exclude_kernel = 1,
> + .sample_period = 1,
> + .sample_regs_user = PERF_REGS_MASK
> + };
> + int fd;
> +
> + if (intr)
> + return PERF_REGS_MASK;
> +
> + if (getauxval(AT_HWCAP) & HWCAP_SVE)
> + attr.sample_regs_user |= SMPL_REG_MASK(PERF_REG_ARM64_VG);
> +
> + /*
> + * Check if the pmu supports perf extended regs, before
> + * returning the register mask to sample. Open the event
> + * on the perf process to check this.
> + */
> + if (attr.sample_regs_user != PERF_REGS_MASK) {
> + event_attr_init(&attr);
> + fd = sys_perf_event_open(&attr, /*pid=*/0, /*cpu=*/-1,
> + /*group_fd=*/-1, /*flags=*/0);
> + if (fd != -1) {
> + close(fd);
> + return attr.sample_regs_user;
> + }
> + }
> + return PERF_REGS_MASK;
> +}
>
> const char *__perf_reg_name_arm64(int id)
> {
> diff --git a/tools/perf/util/perf-regs-arch/perf_regs_arm.c b/tools/perf/util/perf-regs-arch/perf_regs_arm.c
> index e29d130a587a..184d6e248dfc 100644
> --- a/tools/perf/util/perf-regs-arch/perf_regs_arm.c
> +++ b/tools/perf/util/perf-regs-arch/perf_regs_arm.c
> @@ -1,7 +1,12 @@
> // SPDX-License-Identifier: GPL-2.0
>
> #include "../perf_regs.h"
> -#include "../../../arch/arm/include/uapi/asm/perf_regs.h"
> +#include "../../arch/arm/include/perf_regs.h"
> +
> +uint64_t __perf_reg_mask_arm(bool intr __maybe_unused)
> +{
> + return PERF_REGS_MASK;
> +}
>
> const char *__perf_reg_name_arm(int id)
> {
> diff --git a/tools/perf/util/perf-regs-arch/perf_regs_csky.c b/tools/perf/util/perf-regs-arch/perf_regs_csky.c
> index 95808f93d45b..16cbd8303acf 100644
> --- a/tools/perf/util/perf-regs-arch/perf_regs_csky.c
> +++ b/tools/perf/util/perf-regs-arch/perf_regs_csky.c
> @@ -9,7 +9,12 @@
> #include "../perf_regs.h"
> #undef __CSKYABIV2__
> #define __CSKYABIV2__ 1 // Always want the V2 register definitions.
> -#include "../../arch/csky/include/uapi/asm/perf_regs.h"
> +#include "../../arch/csky/include/perf_regs.h"
> +
> +uint64_t __perf_reg_mask_csky(bool intr __maybe_unused)
> +{
> + return PERF_REGS_MASK;
> +}
>
> const char *__perf_reg_name_csky(int id, uint32_t e_flags)
> {
> diff --git a/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c b/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c
> index 043f97f4e3ac..478ee889afa1 100644
> --- a/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c
> +++ b/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c
> @@ -1,7 +1,12 @@
> // SPDX-License-Identifier: GPL-2.0
>
> #include "../perf_regs.h"
> -#include "../../../arch/loongarch/include/uapi/asm/perf_regs.h"
> +#include "../../arch/loongarch/include/perf_regs.h"
> +
> +uint64_t __perf_reg_mask_loongarch(bool intr __maybe_unused)
> +{
> + return PERF_REGS_MASK;
> +}
>
> const char *__perf_reg_name_loongarch(int id)
> {
> diff --git a/tools/perf/util/perf-regs-arch/perf_regs_mips.c b/tools/perf/util/perf-regs-arch/perf_regs_mips.c
> index 793178fc3c78..c5a475f6ec64 100644
> --- a/tools/perf/util/perf-regs-arch/perf_regs_mips.c
> +++ b/tools/perf/util/perf-regs-arch/perf_regs_mips.c
> @@ -1,7 +1,12 @@
> // SPDX-License-Identifier: GPL-2.0
>
> #include "../perf_regs.h"
> -#include "../../../arch/mips/include/uapi/asm/perf_regs.h"
> +#include "../../arch/mips/include/perf_regs.h"
> +
> +uint64_t __perf_reg_mask_mips(bool intr __maybe_unused)
> +{
> + return PERF_REGS_MASK;
> +}
>
> const char *__perf_reg_name_mips(int id)
> {
> diff --git a/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c b/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c
> index 08636bb09a3a..f0a547ad809b 100644
> --- a/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c
> +++ b/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c
> @@ -1,7 +1,82 @@
> // SPDX-License-Identifier: GPL-2.0
>
> +#include <errno.h>
> +#include <string.h>
> +#include <regex.h>
> +#include <linux/zalloc.h>
> +
> +#include "../debug.h"
> +#include "../event.h"
> +#include "../header.h"
> #include "../perf_regs.h"
> -#include "../../../arch/powerpc/include/uapi/asm/perf_regs.h"
> +#include "../../perf-sys.h"
> +#include "../../arch/powerpc/util/utils_header.h"
> +#include "../../arch/powerpc/include/perf_regs.h"
> +
> +#include <linux/kernel.h>
> +
> +#define PVR_POWER9 0x004E
> +#define PVR_POWER10 0x0080
> +#define PVR_POWER11 0x0082
> +
> +/*
> + * mfspr is a POWERPC specific instruction, ensure it's only
> + * built and called on POWERPC by guarding with __powerpc64__
> + * or __powerpc__.
> + */
> +#if defined(__powerpc64__) && defined(__powerpc__)
> +uint64_t __perf_reg_mask_powerpc(bool intr)
> +{
> + struct perf_event_attr attr = {
> + .type = PERF_TYPE_HARDWARE,
> + .config = PERF_COUNT_HW_CPU_CYCLES,
> + .sample_type = PERF_SAMPLE_REGS_INTR,
> + .precise_ip = 1,
> + .disabled = 1,
> + .exclude_kernel = 1,
> + };
> + int fd;
> + u32 version;
> + u64 extended_mask = 0, mask = PERF_REGS_MASK;
> +
> + if (!intr)
> + return PERF_REGS_MASK;
> +
> + /*
> + * Get the PVR value to set the extended
> + * mask specific to platform.
> + */
> + version = (((mfspr(SPRN_PVR)) >> 16) & 0xFFFF);
> + if (version == PVR_POWER9)
> + extended_mask = PERF_REG_PMU_MASK_300;
> + else if ((version == PVR_POWER10) || (version == PVR_POWER11))
> + extended_mask = PERF_REG_PMU_MASK_31;
> + else
> + return mask;
> +
> + attr.sample_regs_intr = extended_mask;
> + attr.sample_period = 1;
> + event_attr_init(&attr);
> +
> + /*
> + * Check if the pmu supports perf extended regs, before
> + * returning the register mask to sample. Open the event
> + * on the perf process to check this.
> + */
> + fd = sys_perf_event_open(&attr, /*pid=*/0, /*cpu=*/-1,
> + /*group_fd=*/-1, /*flags=*/0);
> + if (fd != -1) {
> + close(fd);
> + mask |= extended_mask;
> + }
> + return mask;
> +}
> +#else
> +uint64_t __perf_reg_mask_powerpc(bool intr __maybe_unused)
> +{
> + return PERF_REGS_MASK;
> +}
> +#endif
>
> const char *__perf_reg_name_powerpc(int id)
> {
> diff --git a/tools/perf/util/perf-regs-arch/perf_regs_riscv.c b/tools/perf/util/perf-regs-arch/perf_regs_riscv.c
> index 337b687c655d..5b5f21fcba8c 100644
> --- a/tools/perf/util/perf-regs-arch/perf_regs_riscv.c
> +++ b/tools/perf/util/perf-regs-arch/perf_regs_riscv.c
> @@ -1,7 +1,12 @@
> // SPDX-License-Identifier: GPL-2.0
>
> #include "../perf_regs.h"
> -#include "../../../arch/riscv/include/uapi/asm/perf_regs.h"
> +#include "../../arch/riscv/include/perf_regs.h"
> +
> +uint64_t __perf_reg_mask_riscv(bool intr __maybe_unused)
> +{
> + return PERF_REGS_MASK;
> +}
>
> const char *__perf_reg_name_riscv(int id)
> {
> diff --git a/tools/perf/util/perf-regs-arch/perf_regs_s390.c b/tools/perf/util/perf-regs-arch/perf_regs_s390.c
> index d69bba881080..c61df24edf0f 100644
> --- a/tools/perf/util/perf-regs-arch/perf_regs_s390.c
> +++ b/tools/perf/util/perf-regs-arch/perf_regs_s390.c
> @@ -1,7 +1,12 @@
> // SPDX-License-Identifier: GPL-2.0
>
> #include "../perf_regs.h"
> -#include "../../../arch/s390/include/uapi/asm/perf_regs.h"
> +#include "../../arch/s390/include/perf_regs.h"
> +
> +uint64_t __perf_reg_mask_s390(bool intr __maybe_unused)
> +{
> + return PERF_REGS_MASK;
> +}
>
> const char *__perf_reg_name_s390(int id)
> {
> diff --git a/tools/perf/util/perf-regs-arch/perf_regs_x86.c b/tools/perf/util/perf-regs-arch/perf_regs_x86.c
> index 708954a9d35d..d573f9a9ca46 100644
> --- a/tools/perf/util/perf-regs-arch/perf_regs_x86.c
> +++ b/tools/perf/util/perf-regs-arch/perf_regs_x86.c
> @@ -1,7 +1,65 @@
> // SPDX-License-Identifier: GPL-2.0
>
> +#include <errno.h>
> +#include <string.h>
> +#include <regex.h>
> +#include <linux/kernel.h>
> +#include <linux/zalloc.h>
> +
> +#include "../debug.h"
> +#include "../event.h"
> +#include "../pmu.h"
> +#include "../pmus.h"
> #include "../perf_regs.h"
> -#include "../../../arch/x86/include/uapi/asm/perf_regs.h"
> +#include "../../perf-sys.h"
> +#include "../../arch/x86/include/perf_regs.h"
> +
> +uint64_t __perf_reg_mask_x86(bool intr)
> +{
> + struct perf_event_attr attr = {
> + .type = PERF_TYPE_HARDWARE,
> + .config = PERF_COUNT_HW_CPU_CYCLES,
> + .sample_type = PERF_SAMPLE_REGS_INTR,
> + .sample_regs_intr = PERF_REG_EXTENDED_MASK,
> + .precise_ip = 1,
> + .disabled = 1,
> + .exclude_kernel = 1,
> + };
> + int fd;
> +
> + if (!intr)
> + return PERF_REGS_MASK;
> +
> + /*
> + * In an unnamed union, init it here to build on older gcc versions
> + */
> + attr.sample_period = 1;
> +
> + if (perf_pmus__num_core_pmus() > 1) {
> + struct perf_pmu *pmu = NULL;
> + __u64 type = PERF_TYPE_RAW;
> +
> + /*
> + * The same register set is supported among different hybrid PMUs.
> + * Only check the first available one.
> + */
> + while ((pmu = perf_pmus__scan_core(pmu)) != NULL) {
> + type = pmu->type;
> + break;
> + }
> + attr.config |= type << PERF_PMU_TYPE_SHIFT;
> + }
> +
> + event_attr_init(&attr);
> + fd = sys_perf_event_open(&attr, /*pid=*/0, /*cpu=*/-1,
> + /*group_fd=*/-1, /*flags=*/0);
> + if (fd != -1) {
> + close(fd);
> + return (PERF_REG_EXTENDED_MASK | PERF_REGS_MASK);
> + }
> +
> + return PERF_REGS_MASK;
> +}
>
> const char *__perf_reg_name_x86(int id)
> {
> diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c
> index 14b7be30ab20..4d9a286a0e56 100644
> --- a/tools/perf/util/perf_regs.c
> +++ b/tools/perf/util/perf_regs.c
> @@ -13,14 +13,90 @@ int __weak arch_sdt_arg_parse_op(char *old_op __maybe_unused,
> return SDT_ARG_SKIP;
> }
>
> -uint64_t __weak arch__intr_reg_mask(void)
> +uint64_t perf_intr_reg_mask(uint16_t e_machine)
> {
> - return 0;
> + uint64_t mask = 0;
> +
> + switch (e_machine) {
> + case EM_ARM:
> + mask = __perf_reg_mask_arm(/*intr=*/true);
> + break;
> + case EM_AARCH64:
> + mask = __perf_reg_mask_arm64(/*intr=*/true);
> + break;
> + case EM_CSKY:
> + mask = __perf_reg_mask_csky(/*intr=*/true);
> + break;
> + case EM_LOONGARCH:
> + mask = __perf_reg_mask_loongarch(/*intr=*/true);
> + break;
> + case EM_MIPS:
> + mask = __perf_reg_mask_mips(/*intr=*/true);
> + break;
> + case EM_PPC:
> + case EM_PPC64:
> + mask = __perf_reg_mask_powerpc(/*intr=*/true);
> + break;
> + case EM_RISCV:
> + mask = __perf_reg_mask_riscv(/*intr=*/true);
> + break;
> + case EM_S390:
> + mask = __perf_reg_mask_s390(/*intr=*/true);
> + break;
> + case EM_386:
> + case EM_X86_64:
> + mask = __perf_reg_mask_x86(/*intr=*/true);
> + break;
> + default:
> + pr_debug("Unknown ELF machine %d, interrupt sampling register mask will be empty.\n",
> + e_machine);
> + break;
> + }
> +
> + return mask;
> }
>
> -uint64_t __weak arch__user_reg_mask(void)
> +uint64_t perf_user_reg_mask(uint16_t e_machine)
> {
> - return 0;
> + uint64_t mask = 0;
> +
> + switch (e_machine) {
> + case EM_ARM:
> + mask = __perf_reg_mask_arm(/*intr=*/false);
> + break;
> + case EM_AARCH64:
> + mask = __perf_reg_mask_arm64(/*intr=*/false);
> + break;
> + case EM_CSKY:
> + mask = __perf_reg_mask_csky(/*intr=*/false);
> + break;
> + case EM_LOONGARCH:
> + mask = __perf_reg_mask_loongarch(/*intr=*/false);
> + break;
> + case EM_MIPS:
> + mask = __perf_reg_mask_mips(/*intr=*/false);
> + break;
> + case EM_PPC:
> + case EM_PPC64:
> + mask = __perf_reg_mask_powerpc(/*intr=*/false);
> + break;
> + case EM_RISCV:
> + mask = __perf_reg_mask_riscv(/*intr=*/false);
> + break;
> + case EM_S390:
> + mask = __perf_reg_mask_s390(/*intr=*/false);
> + break;
> + case EM_386:
> + case EM_X86_64:
> + mask = __perf_reg_mask_x86(/*intr=*/false);
> + break;
> + default:
> + pr_debug("Unknown ELF machine %d, user sampling register mask will be empty.\n",
> + e_machine);
> + break;
> + }
> +
> + return mask;
> }
>
> const char *perf_reg_name(int id, uint16_t e_machine, uint32_t e_flags)
> diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h
> index ed7c1b1358fa..2b27139acadb 100644
> --- a/tools/perf/util/perf_regs.h
> +++ b/tools/perf/util/perf_regs.h
> @@ -13,37 +13,55 @@ enum {
> };
>
> int arch_sdt_arg_parse_op(char *old_op, char **new_op);
> -uint64_t arch__intr_reg_mask(void);
> -uint64_t arch__user_reg_mask(void);
> +uint64_t perf_intr_reg_mask(uint16_t e_machine);
> +uint64_t perf_user_reg_mask(uint16_t e_machine);
>
> const char *perf_reg_name(int id, uint16_t e_machine, uint32_t e_flags);
> int perf_reg_value(u64 *valp, struct regs_dump *regs, int id);
> uint64_t perf_arch_reg_ip(uint16_t e_machine);
> uint64_t perf_arch_reg_sp(uint16_t e_machine);
> +
> +uint64_t __perf_reg_mask_arm64(bool intr);
> 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_arm(bool intr);
> const char *__perf_reg_name_arm(int id);
> uint64_t __perf_reg_ip_arm(void);
> uint64_t __perf_reg_sp_arm(void);
> +
> +uint64_t __perf_reg_mask_csky(bool intr);
> const char *__perf_reg_name_csky(int id, uint32_t e_flags);
> uint64_t __perf_reg_ip_csky(void);
> uint64_t __perf_reg_sp_csky(void);
> +
> +uint64_t __perf_reg_mask_loongarch(bool intr);
> const char *__perf_reg_name_loongarch(int id);
> uint64_t __perf_reg_ip_loongarch(void);
> uint64_t __perf_reg_sp_loongarch(void);
> +
> +uint64_t __perf_reg_mask_mips(bool intr);
> const char *__perf_reg_name_mips(int id);
> uint64_t __perf_reg_ip_mips(void);
> uint64_t __perf_reg_sp_mips(void);
> +
> +uint64_t __perf_reg_mask_powerpc(bool intr);
> const char *__perf_reg_name_powerpc(int id);
> uint64_t __perf_reg_ip_powerpc(void);
> uint64_t __perf_reg_sp_powerpc(void);
> +
> +uint64_t __perf_reg_mask_riscv(bool intr);
> const char *__perf_reg_name_riscv(int id);
> uint64_t __perf_reg_ip_riscv(void);
> uint64_t __perf_reg_sp_riscv(void);
> +
> +uint64_t __perf_reg_mask_s390(bool intr);
> const char *__perf_reg_name_s390(int id);
> uint64_t __perf_reg_ip_s390(void);
> uint64_t __perf_reg_sp_s390(void);
> +
> +uint64_t __perf_reg_mask_x86(bool intr);
> const char *__perf_reg_name_x86(int id);
> uint64_t __perf_reg_ip_x86(void);
> uint64_t __perf_reg_sp_x86(void);
> --
> 2.34.1
>
© 2016 - 2026 Red Hat, Inc.