Hi Athira,

+/* Function to return the extended register values */
+static u64 get_ext_regs_value(int idx)
+{
+       switch (idx) {
+       case PERF_REG_POWERPC_MMCR0:
+               return mfspr(SPRN_MMCR0);
+       case PERF_REG_POWERPC_MMCR1:
+               return mfspr(SPRN_MMCR1);
+       case PERF_REG_POWERPC_MMCR2:
+               return mfspr(SPRN_MMCR2);
+       default: return 0;
+       }
+}
+
  u64 perf_reg_value(struct pt_regs *regs, int idx)
  {
-       if (WARN_ON_ONCE(idx >= PERF_REG_POWERPC_MAX))
-               return 0;
+       u64 perf_reg_extended_max = 0;

This should be initialized to PERF_REG_POWERPC_MAX. Default to 0 will always
trigger below WARN_ON_ONCE(idx >= perf_reg_extended_max) on non p9/p10 systems.

+
+       if (cpu_has_feature(CPU_FTR_ARCH_300))
+               perf_reg_extended_max = PERF_REG_MAX_ISA_300;
if (idx == PERF_REG_POWERPC_SIER &&
           (IS_ENABLED(CONFIG_FSL_EMB_PERF_EVENT) ||
@@ -85,6 +103,16 @@ u64 perf_reg_value(struct pt_regs *regs, int idx)
            IS_ENABLED(CONFIG_PPC32)))
                return 0;
+ if (idx >= PERF_REG_POWERPC_MAX && idx < perf_reg_extended_max)
+               return get_ext_regs_value(idx);
+
+       /*
+        * If the idx is referring to value beyond the
+        * supported registers, return 0 with a warning
+        */
+       if (WARN_ON_ONCE(idx >= perf_reg_extended_max))
+               return 0;
+
        return regs_get_register(regs, pt_regs_offset[idx]);
  }

Ravi

Reply via email to