powerpc/perf: Update perf_regs structure to include SIER
authorMadhavan Srinivasan <maddy@linux.vnet.ibm.com>
Sun, 9 Dec 2018 09:25:35 +0000 (14:55 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 20 Dec 2018 09:53:11 +0000 (20:53 +1100)
On each sample, Sample Instruction Event Register (SIER) content
is saved in pt_regs. SIER does not have a entry as-is in the pt_regs
but instead, SIER content is saved in the "dar" register of pt_regs.

Patch adds another entry to the perf_regs structure to include the "SIER"
printing which internally maps to the "dar" of pt_regs.

It also check for the SIER availability in the platform and present
value accordingly

Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/perf_event.h
arch/powerpc/include/uapi/asm/perf_regs.h
arch/powerpc/perf/core-book3s.c
arch/powerpc/perf/perf_regs.c
tools/arch/powerpc/include/uapi/asm/perf_regs.h
tools/perf/arch/powerpc/include/perf_regs.h
tools/perf/arch/powerpc/util/perf_regs.c

index 16a49819da9a993046e5cf15c7de2ef523e7c2fe..35926cd6cd0b9907ec0e83c7c8df5d58c4a45d05 100644 (file)
@@ -39,4 +39,7 @@
                (regs)->gpr[1] = current_stack_pointer();       \
                asm volatile("mfmsr %0" : "=r" ((regs)->msr));  \
        } while (0)
+
+/* To support perf_regs sier update */
+extern bool is_sier_available(void);
 #endif
index 9e52c86ccbd3457af7124cf559204f5973d179a1..ff91192407d1b3c027257b5e32ac9b6956f8bb13 100644 (file)
@@ -46,6 +46,7 @@ enum perf_event_powerpc_regs {
        PERF_REG_POWERPC_TRAP,
        PERF_REG_POWERPC_DAR,
        PERF_REG_POWERPC_DSISR,
+       PERF_REG_POWERPC_SIER,
        PERF_REG_POWERPC_MAX,
 };
 #endif /* _UAPI_ASM_POWERPC_PERF_REGS_H */
index 81f8a0c838ae3899ae832f5bdd8e3527c2c55352..b4976cae1005b559dbd8cfc875285455f9c4b89e 100644 (file)
@@ -130,6 +130,14 @@ static inline void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) {}
 static void pmao_restore_workaround(bool ebb) { }
 #endif /* CONFIG_PPC32 */
 
+bool is_sier_available(void)
+{
+       if (ppmu->flags & PPMU_HAS_SIER)
+               return true;
+
+       return false;
+}
+
 static bool regs_use_siar(struct pt_regs *regs)
 {
        /*
index 09ceea6175ba9dc1d99b8b56eadae1367138b166..5c36b3a8d47aba640d5136dcdfca30469375a3a6 100644 (file)
@@ -69,6 +69,7 @@ static unsigned int pt_regs_offset[PERF_REG_POWERPC_MAX] = {
        PT_REGS_OFFSET(PERF_REG_POWERPC_TRAP, trap),
        PT_REGS_OFFSET(PERF_REG_POWERPC_DAR, dar),
        PT_REGS_OFFSET(PERF_REG_POWERPC_DSISR, dsisr),
+       PT_REGS_OFFSET(PERF_REG_POWERPC_SIER, dar),
 };
 
 u64 perf_reg_value(struct pt_regs *regs, int idx)
@@ -76,6 +77,12 @@ u64 perf_reg_value(struct pt_regs *regs, int idx)
        if (WARN_ON_ONCE(idx >= PERF_REG_POWERPC_MAX))
                return 0;
 
+       if (idx == PERF_REG_POWERPC_SIER &&
+          (IS_ENABLED(CONFIG_FSL_EMB_PERF_EVENT) ||
+           IS_ENABLED(CONFIG_PPC32) ||
+           !is_sier_available()))
+               return 0;
+
        return regs_get_register(regs, pt_regs_offset[idx]);
 }
 
index 9e52c86ccbd3457af7124cf559204f5973d179a1..ff91192407d1b3c027257b5e32ac9b6956f8bb13 100644 (file)
@@ -46,6 +46,7 @@ enum perf_event_powerpc_regs {
        PERF_REG_POWERPC_TRAP,
        PERF_REG_POWERPC_DAR,
        PERF_REG_POWERPC_DSISR,
+       PERF_REG_POWERPC_SIER,
        PERF_REG_POWERPC_MAX,
 };
 #endif /* _UAPI_ASM_POWERPC_PERF_REGS_H */
index 00e37b10691382b80ce05d84812bd0056993dc23..1076393e6f43e2ef1d694918ba433ea625339263 100644 (file)
@@ -62,7 +62,8 @@ static const char *reg_names[] = {
        [PERF_REG_POWERPC_SOFTE] = "softe",
        [PERF_REG_POWERPC_TRAP] = "trap",
        [PERF_REG_POWERPC_DAR] = "dar",
-       [PERF_REG_POWERPC_DSISR] = "dsisr"
+       [PERF_REG_POWERPC_DSISR] = "dsisr",
+       [PERF_REG_POWERPC_SIER] = "sier"
 };
 
 static inline const char *perf_reg_name(int id)
index ec50939b0418a78ec3402896d1a648b84e5f6450..07fcd977d93e4e713c3492274c77f4b70606fa08 100644 (file)
@@ -52,6 +52,7 @@ const struct sample_reg sample_reg_masks[] = {
        SMPL_REG(trap, PERF_REG_POWERPC_TRAP),
        SMPL_REG(dar, PERF_REG_POWERPC_DAR),
        SMPL_REG(dsisr, PERF_REG_POWERPC_DSISR),
+       SMPL_REG(sier, PERF_REG_POWERPC_SIER),
        SMPL_REG_END
 };