aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/perf/core-book3s.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/perf/core-book3s.c')
-rw-r--r--arch/powerpc/perf/core-book3s.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 4520c9356b54..6b0641c3f03f 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -485,7 +485,7 @@ static bool is_ebb_event(struct perf_event *event)
485 * check that the PMU supports EBB, meaning those that don't can still 485 * check that the PMU supports EBB, meaning those that don't can still
486 * use bit 63 of the event code for something else if they wish. 486 * use bit 63 of the event code for something else if they wish.
487 */ 487 */
488 return (ppmu->flags & PPMU_EBB) && 488 return (ppmu->flags & PPMU_ARCH_207S) &&
489 ((event->attr.config >> PERF_EVENT_CONFIG_EBB_SHIFT) & 1); 489 ((event->attr.config >> PERF_EVENT_CONFIG_EBB_SHIFT) & 1);
490} 490}
491 491
@@ -777,7 +777,7 @@ void perf_event_print_debug(void)
777 if (ppmu->flags & PPMU_HAS_SIER) 777 if (ppmu->flags & PPMU_HAS_SIER)
778 sier = mfspr(SPRN_SIER); 778 sier = mfspr(SPRN_SIER);
779 779
780 if (ppmu->flags & PPMU_EBB) { 780 if (ppmu->flags & PPMU_ARCH_207S) {
781 pr_info("MMCR2: %016lx EBBHR: %016lx\n", 781 pr_info("MMCR2: %016lx EBBHR: %016lx\n",
782 mfspr(SPRN_MMCR2), mfspr(SPRN_EBBHR)); 782 mfspr(SPRN_MMCR2), mfspr(SPRN_EBBHR));
783 pr_info("EBBRR: %016lx BESCR: %016lx\n", 783 pr_info("EBBRR: %016lx BESCR: %016lx\n",
@@ -996,7 +996,22 @@ static void power_pmu_read(struct perf_event *event)
996 } while (local64_cmpxchg(&event->hw.prev_count, prev, val) != prev); 996 } while (local64_cmpxchg(&event->hw.prev_count, prev, val) != prev);
997 997
998 local64_add(delta, &event->count); 998 local64_add(delta, &event->count);
999 local64_sub(delta, &event->hw.period_left); 999
1000 /*
1001 * A number of places program the PMC with (0x80000000 - period_left).
1002 * We never want period_left to be less than 1 because we will program
1003 * the PMC with a value >= 0x800000000 and an edge detected PMC will
1004 * roll around to 0 before taking an exception. We have seen this
1005 * on POWER8.
1006 *
1007 * To fix this, clamp the minimum value of period_left to 1.
1008 */
1009 do {
1010 prev = local64_read(&event->hw.period_left);
1011 val = prev - delta;
1012 if (val < 1)
1013 val = 1;
1014 } while (local64_cmpxchg(&event->hw.period_left, prev, val) != prev);
1000} 1015}
1001 1016
1002/* 1017/*
@@ -1300,6 +1315,9 @@ static void power_pmu_enable(struct pmu *pmu)
1300 1315
1301 write_mmcr0(cpuhw, mmcr0); 1316 write_mmcr0(cpuhw, mmcr0);
1302 1317
1318 if (ppmu->flags & PPMU_ARCH_207S)
1319 mtspr(SPRN_MMCR2, 0);
1320
1303 /* 1321 /*
1304 * Enable instruction sampling if necessary 1322 * Enable instruction sampling if necessary
1305 */ 1323 */
@@ -1696,7 +1714,7 @@ static int power_pmu_event_init(struct perf_event *event)
1696 1714
1697 if (has_branch_stack(event)) { 1715 if (has_branch_stack(event)) {
1698 /* PMU has BHRB enabled */ 1716 /* PMU has BHRB enabled */
1699 if (!(ppmu->flags & PPMU_BHRB)) 1717 if (!(ppmu->flags & PPMU_ARCH_207S))
1700 return -EOPNOTSUPP; 1718 return -EOPNOTSUPP;
1701 } 1719 }
1702 1720