| @@ -3532,17 +3532,32 @@ static int intel_alt_er(struct cpu_hw_events *cpuc, · 3531 unmodified lines |
| 3532 | 3532 | struct extra_reg *extra_regs = hybrid(cpuc->pmu, extra_regs); |
| 3533 | 3533 | int alt_idx = idx; |
| 3534 | 3534 | |
| 3535 | | − if (!(x86_pmu.flags & PMU_FL_HAS_RSP_1)) |
| 3536 | | − return idx; |
| 3537 | | − |
| 3538 | | − if (idx == EXTRA_REG_RSP_0) |
| 3539 | | − alt_idx = EXTRA_REG_RSP_1; |
| 3535 | + switch (idx) { |
| 3536 | + case EXTRA_REG_RSP_0 ... EXTRA_REG_RSP_1: |
| 3537 | + if (!(x86_pmu.flags & PMU_FL_HAS_RSP_1)) |
| 3538 | + return idx; |
| 3539 | + if (++alt_idx > EXTRA_REG_RSP_1) |
| 3540 | + alt_idx = EXTRA_REG_RSP_0; |
| 3541 | + if (config & ~extra_regs[alt_idx].valid_mask) |
| 3542 | + return idx; |
| 3543 | + break; |
| 3540 | 3544 | |
| 3541 | | − if (idx == EXTRA_REG_RSP_1) |
| 3542 | | − alt_idx = EXTRA_REG_RSP_0; |
| 3545 | + case EXTRA_REG_OMR_0 ... EXTRA_REG_OMR_3: |
| 3546 | + if (!(x86_pmu.flags & PMU_FL_HAS_OMR)) |
| 3547 | + return idx; |
| 3548 | + if (++alt_idx > EXTRA_REG_OMR_3) |
| 3549 | + alt_idx = EXTRA_REG_OMR_0; |
| 3550 | + /* |
| 3551 | + * Subtracting EXTRA_REG_OMR_0 ensures to get correct |
| 3552 | + * OMR extra_reg entries which start from 0. |
| 3553 | + */ |
| 3554 | + if (config & ~extra_regs[alt_idx - EXTRA_REG_OMR_0].valid_mask) |
| 3555 | + return idx; |
| 3556 | + break; |
| 3543 | 3557 | |
| 3544 | | − if (config & ~extra_regs[alt_idx].valid_mask) |
| 3545 | | − return idx; |
| 3558 | + default: |
| 3559 | + break; |
| 3560 | + } |
| 3546 | 3561 | |
| 3547 | 3562 | return alt_idx; |
| 3548 | 3563 | } |
| @@ -3550,16 +3565,26 @@ static int intel_alt_er(struct cpu_hw_events *cpuc, · 1 unmodified line |
| 3550 | 3565 | static void intel_fixup_er(struct perf_event *event, int idx) |
| 3551 | 3566 | { |
| 3552 | 3567 | struct extra_reg *extra_regs = hybrid(event->pmu, extra_regs); |
| 3553 | | − event->hw.extra_reg.idx = idx; |
| 3568 | + int er_idx; |
| 3554 | 3569 | |
| 3555 | | − if (idx == EXTRA_REG_RSP_0) { |
| 3556 | | − event->hw.config &= ~INTEL_ARCH_EVENT_MASK; |
| 3557 | | − event->hw.config |= extra_regs[EXTRA_REG_RSP_0].event; |
| 3558 | | − event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0; |
| 3559 | | − } else if (idx == EXTRA_REG_RSP_1) { |
| 3570 | + event->hw.extra_reg.idx = idx; |
| 3571 | + switch (idx) { |
| 3572 | + case EXTRA_REG_RSP_0 ... EXTRA_REG_RSP_1: |
| 3573 | + er_idx = idx - EXTRA_REG_RSP_0; |
| 3560 | 3574 | event->hw.config &= ~INTEL_ARCH_EVENT_MASK; |
| 3561 | | − event->hw.config |= extra_regs[EXTRA_REG_RSP_1].event; |
| 3562 | | − event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1; |
| 3575 | + event->hw.config |= extra_regs[er_idx].event; |
| 3576 | + event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0 + er_idx; |
| 3577 | + break; |
| 3578 | + |
| 3579 | + case EXTRA_REG_OMR_0 ... EXTRA_REG_OMR_3: |
| 3580 | + er_idx = idx - EXTRA_REG_OMR_0; |
| 3581 | + event->hw.config &= ~ARCH_PERFMON_EVENTSEL_UMASK; |
| 3582 | + event->hw.config |= 1ULL << (8 + er_idx); |
| 3583 | + event->hw.extra_reg.reg = MSR_OMR_0 + er_idx; |
| 3584 | + break; |
| 3585 | + |
| 3586 | + default: |
| 3587 | + pr_warn("The extra reg idx %d is not supported.\n", idx); |
| 3563 | 3588 | } |
| 3564 | 3589 | } |
| 3565 | 3590 | |