提交 8f61aa32 编写于 作者: M Michael Ellerman 提交者: Benjamin Herrenschmidt

powerpc/perf: Add support for SIER

On power8 we have a new SIER (Sampled Instruction Event Register), which
captures information about instructions when we have random sampling
enabled.

Add support for loading the SIER into pt_regs, overloading regs->dar.
Also set the new NO_SIPR flag in regs->result if we don't have SIPR.

Update regs_sihv/sipr() to look for SIPR/SIHV in SIER.
Signed-off-by: NMichael Ellerman <michael@ellerman.id.au>
Acked-by: NPaul Mackerras <paulus@samba.org>
Signed-off-by: NBenjamin Herrenschmidt <benh@kernel.crashing.org>
上级 860aad71
...@@ -53,6 +53,7 @@ struct power_pmu { ...@@ -53,6 +53,7 @@ struct power_pmu {
#define PPMU_NO_CONT_SAMPLING 0x00000008 /* no continuous sampling */ #define PPMU_NO_CONT_SAMPLING 0x00000008 /* no continuous sampling */
#define PPMU_SIAR_VALID 0x00000010 /* Processor has SIAR Valid bit */ #define PPMU_SIAR_VALID 0x00000010 /* Processor has SIAR Valid bit */
#define PPMU_HAS_SSLOT 0x00000020 /* Has sampled slot in MMCRA */ #define PPMU_HAS_SSLOT 0x00000020 /* Has sampled slot in MMCRA */
#define PPMU_HAS_SIER 0x00000040 /* Has SIER */
/* /*
* Values for flags to get_alternatives() * Values for flags to get_alternatives()
......
...@@ -671,6 +671,11 @@ ...@@ -671,6 +671,11 @@
#define SPRN_PMC8 794 #define SPRN_PMC8 794
#define SPRN_SIAR 780 #define SPRN_SIAR 780
#define SPRN_SDAR 781 #define SPRN_SDAR 781
#define SPRN_SIER 784
#define SIER_SIPR 0x2000000 /* Sampled MSR_PR */
#define SIER_SIHV 0x1000000 /* Sampled MSR_HV */
#define SIER_SIAR_VALID 0x0400000 /* SIAR contents valid */
#define SIER_SDAR_VALID 0x0200000 /* SDAR contents valid */
#define SPRN_PA6T_MMCR0 795 #define SPRN_PA6T_MMCR0 795
#define PA6T_MMCR0_EN0 0x0000000000000001UL #define PA6T_MMCR0_EN0 0x0000000000000001UL
......
...@@ -140,6 +140,9 @@ static bool regs_sihv(struct pt_regs *regs) ...@@ -140,6 +140,9 @@ static bool regs_sihv(struct pt_regs *regs)
{ {
unsigned long sihv = MMCRA_SIHV; unsigned long sihv = MMCRA_SIHV;
if (ppmu->flags & PPMU_HAS_SIER)
return !!(regs->dar & SIER_SIHV);
if (ppmu->flags & PPMU_ALT_SIPR) if (ppmu->flags & PPMU_ALT_SIPR)
sihv = POWER6_MMCRA_SIHV; sihv = POWER6_MMCRA_SIHV;
...@@ -150,6 +153,9 @@ static bool regs_sipr(struct pt_regs *regs) ...@@ -150,6 +153,9 @@ static bool regs_sipr(struct pt_regs *regs)
{ {
unsigned long sipr = MMCRA_SIPR; unsigned long sipr = MMCRA_SIPR;
if (ppmu->flags & PPMU_HAS_SIER)
return !!(regs->dar & SIER_SIPR);
if (ppmu->flags & PPMU_ALT_SIPR) if (ppmu->flags & PPMU_ALT_SIPR)
sipr = POWER6_MMCRA_SIPR; sipr = POWER6_MMCRA_SIPR;
...@@ -203,6 +209,7 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs) ...@@ -203,6 +209,7 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs)
/* /*
* Overload regs->dsisr to store MMCRA so we only need to read it once * Overload regs->dsisr to store MMCRA so we only need to read it once
* on each interrupt. * on each interrupt.
* Overload regs->dar to store SIER if we have it.
* Overload regs->result to specify whether we should use the MSR (result * Overload regs->result to specify whether we should use the MSR (result
* is zero) or the SIAR (result is non zero). * is zero) or the SIAR (result is non zero).
*/ */
...@@ -218,6 +225,18 @@ static inline void perf_read_regs(struct pt_regs *regs) ...@@ -218,6 +225,18 @@ static inline void perf_read_regs(struct pt_regs *regs)
if (ppmu->flags & PPMU_NO_SIPR) if (ppmu->flags & PPMU_NO_SIPR)
regs->result |= 2; regs->result |= 2;
/*
* On power8 if we're in random sampling mode, the SIER is updated.
* If we're in continuous sampling mode, we don't have SIPR.
*/
if (ppmu->flags & PPMU_HAS_SIER) {
if (marked)
regs->dar = mfspr(SPRN_SIER);
else
regs->result |= 2;
}
/* /*
* If this isn't a PMU exception (eg a software event) the SIAR is * If this isn't a PMU exception (eg a software event) the SIAR is
* not valid. Use pt_regs. * not valid. Use pt_regs.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册