perf tools arm64: Add support for VG register
authorJames Clark <james.clark@arm.com>
Wed, 25 May 2022 15:41:14 +0000 (16:41 +0100)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 27 May 2022 16:21:33 +0000 (13:21 -0300)
Add the name of the VG register so it can be used in --user-regs

The event will fail to open if the register is requested but not
available so only add it to the mask if the kernel supports sve and also
if it supports that specific register.

Committer notes:

Add conditional definition of HWCAP_SVE, as suggested by Leo Yan, to
build on older systems where this is not available in the system
headers.

Reviewed-by: Leo Yan <leo.yan@linaro.org>
Signed-off-by: James Clark <james.clark@arm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: German Gomez <german.gomez@arm.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.garry@huawei.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Mike Leach <mike.leach@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Will Deacon <will@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Link: https://lore.kernel.org/r/20220525154114.718321-6-james.clark@arm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/arch/arm64/util/perf_regs.c
tools/perf/util/perf_regs.c

index 476b037..006692c 100644 (file)
@@ -2,13 +2,19 @@
 #include <errno.h>
 #include <regex.h>
 #include <string.h>
+#include <sys/auxv.h>
 #include <linux/kernel.h>
 #include <linux/zalloc.h>
 
+#include "../../../perf-sys.h"
 #include "../../../util/debug.h"
 #include "../../../util/event.h"
 #include "../../../util/perf_regs.h"
 
+#ifndef HWCAP_SVE
+#define HWCAP_SVE      (1 << 22)
+#endif
+
 const struct sample_reg sample_reg_masks[] = {
        SMPL_REG(x0, PERF_REG_ARM64_X0),
        SMPL_REG(x1, PERF_REG_ARM64_X1),
@@ -43,6 +49,7 @@ const struct sample_reg sample_reg_masks[] = {
        SMPL_REG(lr, PERF_REG_ARM64_LR),
        SMPL_REG(sp, PERF_REG_ARM64_SP),
        SMPL_REG(pc, PERF_REG_ARM64_PC),
+       SMPL_REG(vg, PERF_REG_ARM64_VG),
        SMPL_REG_END
 };
 
@@ -131,3 +138,34 @@ int arch_sdt_arg_parse_op(char *old_op, char **new_op)
 
        return SDT_ARG_VALID;
 }
+
+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;
+}
index a982e40..872dd3d 100644 (file)
@@ -103,6 +103,8 @@ static const char *__perf_reg_name_arm64(int id)
                return "lr";
        case PERF_REG_ARM64_PC:
                return "pc";
+       case PERF_REG_ARM64_VG:
+               return "vg";
        default:
                return NULL;
        }