From: Kan Liang <kan.li...@linux.intel.com>

The RDPMC index is always re-calculated in RDPMC userspace support,
especially for fixed counters.

The RDPMC index value is stored in variable event_base_rdpmc for kernel
usage, which can be used for RDPMC userspace support as well. Only the
metrics event has to be specially handled.

Signed-off-by: Kan Liang <kan.li...@linux.intel.com>
---
 arch/x86/events/core.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 350c21aaea61..10ce4c381425 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -2197,20 +2197,16 @@ static void x86_pmu_event_unmapped(struct perf_event 
*event, struct mm_struct *m
 
 static int x86_pmu_event_idx(struct perf_event *event)
 {
-       int idx = event->hw.idx;
+       struct hw_perf_event *hwc = &event->hw;
 
-       if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
+       if (!(hwc->flags & PERF_X86_EVENT_RDPMC_ALLOWED))
                return 0;
 
        /* Return PERF_METRICS MSR value for metrics event */
-       if (is_metric_idx(idx))
-               idx = 1 << 29;
-       else if (x86_pmu.num_counters_fixed && idx >= INTEL_PMC_IDX_FIXED) {
-               idx -= INTEL_PMC_IDX_FIXED;
-               idx |= 1 << 30;
-       }
-
-       return idx + 1;
+       if (is_metric_idx(hwc->idx))
+               return (1 << 29) + 1;
+       else
+               return hwc->event_base_rdpmc + 1;
 }
 
 static ssize_t get_attr_rdpmc(struct device *cdev,
-- 
2.17.1

Reply via email to