perf arm-spe: Extend branch operations
authorLeo Yan <leo.yan@arm.com>
Tue, 4 Mar 2025 11:12:35 +0000 (11:12 +0000)
committerNamhyung Kim <namhyung@kernel.org>
Wed, 5 Mar 2025 17:13:19 +0000 (09:13 -0800)
In Arm ARM (ARM DDI 0487, L.a), the section "D18.2.7 Operation Type
packet", the branch subclass is extended for Call Return (CR), Guarded
control stack data access (GCS).

This commit adds support CR and GCS operations.  The IND (indirect)
operation is defined only in bit [1], its macro is updated accordingly.

Move the COND (Conditional) macro into the same group with other
operations for better maintenance.

Reviewed-by: Ian Rogers <irogers@google.com>
Reviewed-by: James Clark <james.clark@linaro.org>
Signed-off-by: Leo Yan <leo.yan@arm.com>
Link: https://lore.kernel.org/r/20250304111240.3378214-8-leo.yan@arm.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h

index 4cef10a83962fb1b33471783c3796f73f0d44995..625834da7e20ec89132a92f913df019a8cf2298e 100644 (file)
@@ -397,10 +397,16 @@ static int arm_spe_pkt_desc_op_type(const struct arm_spe_pkt *packet,
 
                if (payload & SPE_OP_PKT_COND)
                        arm_spe_pkt_out_string(&err, &buf, &buf_len, " COND");
-
-               if (SPE_OP_PKT_IS_INDIRECT_BRANCH(payload))
+               if (payload & SPE_OP_PKT_INDIRECT_BRANCH)
                        arm_spe_pkt_out_string(&err, &buf, &buf_len, " IND");
-
+               if (payload & SPE_OP_PKT_GCS)
+                       arm_spe_pkt_out_string(&err, &buf, &buf_len, " GCS");
+               if (SPE_OP_PKT_CR_BL(payload))
+                       arm_spe_pkt_out_string(&err, &buf, &buf_len, " CR-BL");
+               if (SPE_OP_PKT_CR_RET(payload))
+                       arm_spe_pkt_out_string(&err, &buf, &buf_len, " CR-RET");
+               if (SPE_OP_PKT_CR_NON_BL_RET(payload))
+                       arm_spe_pkt_out_string(&err, &buf, &buf_len, " CR-NON-BL-RET");
                break;
        default:
                /* Unknown index */
index 464a912b221cd3777e82271d25d4765418254f4c..32d760ede70133db285d5f632432ab3232a87b9e 100644 (file)
@@ -7,6 +7,7 @@
 #ifndef INCLUDE__ARM_SPE_PKT_DECODER_H__
 #define INCLUDE__ARM_SPE_PKT_DECODER_H__
 
+#include <linux/bitfield.h>
 #include <stddef.h>
 #include <stdint.h>
 
@@ -116,8 +117,6 @@ enum arm_spe_events {
 
 #define SPE_OP_PKT_IS_OTHER_SVE_OP(v)          (((v) & (BIT(7) | BIT(3) | BIT(0))) == 0x8)
 
-#define SPE_OP_PKT_COND                                BIT(0)
-
 #define SPE_OP_PKT_LDST_SUBCLASS_GET(v)                ((v) & GENMASK_ULL(7, 1))
 #define SPE_OP_PKT_LDST_SUBCLASS_GP_REG                0x0
 #define SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP       0x4
@@ -148,7 +147,13 @@ enum arm_spe_events {
 #define SPE_OP_PKT_SVE_PRED                    BIT(2)
 #define SPE_OP_PKT_SVE_FP                      BIT(1)
 
-#define SPE_OP_PKT_IS_INDIRECT_BRANCH(v)       (((v) & GENMASK_ULL(7, 1)) == 0x2)
+#define SPE_OP_PKT_CR_MASK                     GENMASK_ULL(4, 3)
+#define SPE_OP_PKT_CR_BL(v)                    (FIELD_GET(SPE_OP_PKT_CR_MASK, (v)) == 1)
+#define SPE_OP_PKT_CR_RET(v)                   (FIELD_GET(SPE_OP_PKT_CR_MASK, (v)) == 2)
+#define SPE_OP_PKT_CR_NON_BL_RET(v)            (FIELD_GET(SPE_OP_PKT_CR_MASK, (v)) == 3)
+#define SPE_OP_PKT_GCS                         BIT(2)
+#define SPE_OP_PKT_INDIRECT_BRANCH             BIT(1)
+#define SPE_OP_PKT_COND                                BIT(0)
 
 const char *arm_spe_pkt_name(enum arm_spe_pkt_type);