Sampled Instruction Event Register (SIER) field [46:48]
identifies the sampled instruction type. ISA v3.1 says value
of 0b111 for this field as reserved, but in POWER10 it denotes
LARX/STCX type which will hopefully be fixed in ISA v3.1 update.

Patch fixes the functions to handle type value 7 for
CPU_FTR_ARCH_31.

Fixes: a64e697cef23 ("powerpc/perf: power10 Performance Monitoring support")
Signed-off-by: Athira Rajeev <atraj...@linux.vnet.ibm.com>
---
 arch/powerpc/perf/isa207-common.c | 30 +++++++++++++++++++++++++++---
 arch/powerpc/perf/isa207-common.h |  1 +
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/perf/isa207-common.c 
b/arch/powerpc/perf/isa207-common.c
index e4f577da33d8..754f904d8d69 100644
--- a/arch/powerpc/perf/isa207-common.c
+++ b/arch/powerpc/perf/isa207-common.c
@@ -266,6 +266,8 @@ void isa207_get_mem_data_src(union perf_mem_data_src *dsrc, 
u32 flags,
        u32 sub_idx;
        u64 sier;
        u64 val;
+       u64 mmcra = mfspr(SPRN_MMCRA);
+       u32 op_type;
 
        /* Skip if no SIER support */
        if (!(flags & PPMU_HAS_SIER)) {
@@ -275,12 +277,34 @@ void isa207_get_mem_data_src(union perf_mem_data_src 
*dsrc, u32 flags,
 
        sier = mfspr(SPRN_SIER);
        val = (sier & ISA207_SIER_TYPE_MASK) >> ISA207_SIER_TYPE_SHIFT;
-       if (val == 1 || val == 2) {
+       if (val == 1 || val == 2 || (val == 7 && 
cpu_has_feature(CPU_FTR_ARCH_31))) {
                idx = (sier & ISA207_SIER_LDST_MASK) >> ISA207_SIER_LDST_SHIFT;
                sub_idx = (sier & ISA207_SIER_DATA_SRC_MASK) >> 
ISA207_SIER_DATA_SRC_SHIFT;
 
                dsrc->val = isa207_find_source(idx, sub_idx);
-               dsrc->val |= (val == 1) ? P(OP, LOAD) : P(OP, STORE);
+               if (val == 7) {
+                       /*
+                        * Type 0b111 denotes either larx or stcx instruction. 
Use the
+                        * MMCRA sampling bits [57:59] along with the type value
+                        * to determine the exact instruction type. If the 
sampling
+                        * criteria is neither load or store, set the type as 
default
+                        * to NA.
+                        */
+                       op_type = (mmcra >> MMCRA_SAMP_ELIG_SHIFT) & 
MMCRA_SAMP_ELIG_MASK;
+                       switch (op_type) {
+                       case 5:
+                               dsrc->val |= P(OP, LOAD);
+                               break;
+                       case 7:
+                               dsrc->val |= P(OP, STORE);
+                               break;
+                       default:
+                               dsrc->val |= P(OP, NA);
+                               break;
+                       }
+               } else {
+                       dsrc->val |= (val == 1) ? P(OP, LOAD) : P(OP, STORE);
+               }
        }
 }
 
@@ -295,7 +319,7 @@ void isa207_get_mem_weight(u64 *weight)
        if (cpu_has_feature(CPU_FTR_ARCH_31))
                mantissa = P10_MMCRA_THR_CTR_MANT(mmcra);
 
-       if (val == 0 || val == 7)
+       if (val == 0 || (val == 7 && !cpu_has_feature(CPU_FTR_ARCH_31)))
                *weight = 0;
        else
                *weight = mantissa << (2 * exp);
diff --git a/arch/powerpc/perf/isa207-common.h 
b/arch/powerpc/perf/isa207-common.h
index 1af0e8c97ac7..7b0242efe4b9 100644
--- a/arch/powerpc/perf/isa207-common.h
+++ b/arch/powerpc/perf/isa207-common.h
@@ -220,6 +220,7 @@
 /* Bits in MMCRA for PowerISA v2.07 */
 #define MMCRA_SAMP_MODE_SHIFT          1
 #define MMCRA_SAMP_ELIG_SHIFT          4
+#define MMCRA_SAMP_ELIG_MASK           7
 #define MMCRA_THR_CTL_SHIFT            8
 #define MMCRA_THR_SEL_SHIFT            16
 #define MMCRA_THR_CMP_SHIFT            32
-- 
1.8.3.1

Reply via email to