From 408c0988b1596788bf4d33e196545088fd7f97fd Mon Sep 17 00:00:00 2001 From: Wei Li Date: Thu, 28 Mar 2019 14:27:21 +0800 Subject: [PATCH] arm64: perf: fix Invalid PMEV* index WARNING hulk inclusion category: bugfix bugzilla: NA CVE: NA ------------------------------------------------- When PMSELR_EL0.SEL == 31, the register PMXEVTYPER_EL0 accesses PMCCFILTR_EL0. Add a branch to process such condition. Fix: commit 2f10f935b6a6 ("arm64: perf: avoid PMXEV* indirection") Signed-off-by: Wei Li Reviewed-by: Cheng Jian Signed-off-by: Yang Yingliang --- arch/arm64/kernel/perf_event.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 669a28daf548..edf6928c9a0c 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -538,7 +538,7 @@ static inline bool armv8pmu_event_is_chained(struct perf_event *event) PMEVN_CASE(28, case_macro); \ PMEVN_CASE(29, case_macro); \ PMEVN_CASE(30, case_macro); \ - default: WARN(1, "Inavlid PMEV* index"); \ + default: WARN(1, "Invalid PMEV* index %#x", __x); \ } \ } while (0) @@ -706,7 +706,7 @@ static inline void armv8pmu_write_evtype(int idx, u32 val) } } -static inline void armv8pmu_write_event_type(struct perf_event *event) +static inline void armv8pmu_write_hw_type(struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; int idx = hwc->idx; @@ -727,6 +727,26 @@ static inline void armv8pmu_write_event_type(struct perf_event *event) } } +static inline void armv8pmu_write_event_type(struct perf_event *event) +{ + if (!pmu_nmi_enable) { + armv8pmu_write_hw_type(event); + } else { + struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); + struct hw_perf_event *hwc = &event->hw; + int idx = hwc->idx; + + if (!armv8pmu_counter_valid(cpu_pmu, idx)) + pr_err("CPU%u writing wrong event %d\n", + smp_processor_id(), idx); + else if (idx == ARMV8_IDX_CYCLE_COUNTER) + write_sysreg(hwc->config_base & ARMV8_PMU_EVTYPE_MASK, + pmccfiltr_el0); + else + armv8pmu_write_hw_type(event); + } +} + static inline int armv8pmu_enable_counter(int idx) { u32 counter = ARMV8_IDX_TO_COUNTER(idx); -- GitLab