Skip to content

Commit 3db871f

Browse files
Dapeng Misean-jc
authored andcommitted
KVM: x86/pmu: Reprogram mediated PMU event selectors on event filter updates
Refresh the event selectors that are programmed into hardware when a PMC is "reprogrammed" for a mediated PMU, i.e. if userspace changes the PMU event filters Note, KVM doesn't utilize the reprogramming infrastructure to handle counter overflow for mediated PMUs, as there's no need to reprogram a non-existent perf event. Suggested-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com> Co-developed-by: Mingwei Zhang <mizhang@google.com> Signed-off-by: Mingwei Zhang <mizhang@google.com> [sean: add a helper to document behavior, split patch and rewrite changelog] Tested-by: Xudong Hao <xudong.hao@intel.com> Tested-by: Manali Shukla <manali.shukla@amd.com> Link: https://patch.msgid.link/20251206001720.468579-26-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 02918f0 commit 3db871f

1 file changed

Lines changed: 24 additions & 0 deletions

File tree

arch/x86/kvm/pmu.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,25 @@ static bool pmc_is_event_allowed(struct kvm_pmc *pmc)
520520
return is_fixed_event_allowed(filter, pmc->idx);
521521
}
522522

523+
static void kvm_mediated_pmu_refresh_event_filter(struct kvm_pmc *pmc)
524+
{
525+
bool allowed = pmc_is_event_allowed(pmc);
526+
struct kvm_pmu *pmu = pmc_to_pmu(pmc);
527+
528+
if (pmc_is_gp(pmc)) {
529+
pmc->eventsel_hw &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
530+
if (allowed)
531+
pmc->eventsel_hw |= pmc->eventsel &
532+
ARCH_PERFMON_EVENTSEL_ENABLE;
533+
} else {
534+
u64 mask = intel_fixed_bits_by_idx(pmc->idx - KVM_FIXED_PMC_BASE_IDX, 0xf);
535+
536+
pmu->fixed_ctr_ctrl_hw &= ~mask;
537+
if (allowed)
538+
pmu->fixed_ctr_ctrl_hw |= pmu->fixed_ctr_ctrl & mask;
539+
}
540+
}
541+
523542
static int reprogram_counter(struct kvm_pmc *pmc)
524543
{
525544
struct kvm_pmu *pmu = pmc_to_pmu(pmc);
@@ -528,6 +547,11 @@ static int reprogram_counter(struct kvm_pmc *pmc)
528547
bool emulate_overflow;
529548
u8 fixed_ctr_ctrl;
530549

550+
if (kvm_vcpu_has_mediated_pmu(pmu_to_vcpu(pmu))) {
551+
kvm_mediated_pmu_refresh_event_filter(pmc);
552+
return 0;
553+
}
554+
531555
emulate_overflow = pmc_pause_counter(pmc);
532556

533557
if (!pmc_is_globally_enabled(pmc) || !pmc_is_locally_enabled(pmc) ||

0 commit comments

Comments
 (0)