Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8f61aa32 authored by Michael Ellerman's avatar Michael Ellerman Committed by Benjamin Herrenschmidt
Browse files

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: default avatarMichael Ellerman <michael@ellerman.id.au>
Acked-by: default avatarPaul Mackerras <paulus@samba.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 860aad71
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ struct power_pmu {
#define PPMU_NO_CONT_SAMPLING	0x00000008 /* no continuous sampling */
#define PPMU_SIAR_VALID		0x00000010 /* Processor has SIAR Valid bit */
#define PPMU_HAS_SSLOT		0x00000020 /* Has sampled slot in MMCRA */
#define PPMU_HAS_SIER		0x00000040 /* Has SIER */

/*
 * Values for flags to get_alternatives()
+5 −0
Original line number Diff line number Diff line
@@ -671,6 +671,11 @@
#define SPRN_PMC8	794
#define SPRN_SIAR	780
#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   PA6T_MMCR0_EN0	0x0000000000000001UL
+19 −0
Original line number Diff line number Diff line
@@ -140,6 +140,9 @@ static bool regs_sihv(struct pt_regs *regs)
{
	unsigned long sihv = MMCRA_SIHV;

	if (ppmu->flags & PPMU_HAS_SIER)
		return !!(regs->dar & SIER_SIHV);

	if (ppmu->flags & PPMU_ALT_SIPR)
		sihv = POWER6_MMCRA_SIHV;

@@ -150,6 +153,9 @@ static bool regs_sipr(struct pt_regs *regs)
{
	unsigned long sipr = MMCRA_SIPR;

	if (ppmu->flags & PPMU_HAS_SIER)
		return !!(regs->dar & SIER_SIPR);

	if (ppmu->flags & PPMU_ALT_SIPR)
		sipr = POWER6_MMCRA_SIPR;

@@ -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
 * 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
 * is zero) or the SIAR (result is non zero).
 */
@@ -218,6 +225,18 @@ static inline void perf_read_regs(struct pt_regs *regs)
	if (ppmu->flags & PPMU_NO_SIPR)
		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
	 * not valid. Use pt_regs.