Skip to content

Commit 283a5aa

Browse files
Dapeng Misean-jc
authored andcommitted
KVM: x86/pmu: Handle emulated instruction for mediated vPMU
Mediated vPMU needs to accumulate the emulated instructions into counter and load the counter into HW at vm-entry. Moreover, if the accumulation leads to counter overflow, KVM needs to update GLOBAL_STATUS and inject PMI into guest as well. Suggested-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com> Signed-off-by: Mingwei Zhang <mizhang@google.com> Tested-by: Xudong Hao <xudong.hao@intel.com> Tested-by: Manali Shukla <manali.shukla@amd.com> Link: https://patch.msgid.link/20251206001720.468579-30-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent f7a65e5 commit 283a5aa

1 file changed

Lines changed: 37 additions & 2 deletions

File tree

arch/x86/kvm/pmu.c

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,10 +1031,45 @@ void kvm_pmu_destroy(struct kvm_vcpu *vcpu)
10311031
kvm_pmu_reset(vcpu);
10321032
}
10331033

1034+
static bool pmc_is_pmi_enabled(struct kvm_pmc *pmc)
1035+
{
1036+
u8 fixed_ctr_ctrl;
1037+
1038+
if (pmc_is_gp(pmc))
1039+
return pmc->eventsel & ARCH_PERFMON_EVENTSEL_INT;
1040+
1041+
fixed_ctr_ctrl = fixed_ctrl_field(pmc_to_pmu(pmc)->fixed_ctr_ctrl,
1042+
pmc->idx - KVM_FIXED_PMC_BASE_IDX);
1043+
return fixed_ctr_ctrl & INTEL_FIXED_0_ENABLE_PMI;
1044+
}
1045+
10341046
static void kvm_pmu_incr_counter(struct kvm_pmc *pmc)
10351047
{
1036-
pmc->emulated_counter++;
1037-
kvm_pmu_request_counter_reprogram(pmc);
1048+
struct kvm_vcpu *vcpu = pmc->vcpu;
1049+
1050+
/*
1051+
* For perf-based PMUs, accumulate software-emulated events separately
1052+
* from pmc->counter, as pmc->counter is offset by the count of the
1053+
* associated perf event. Request reprogramming, which will consult
1054+
* both emulated and hardware-generated events to detect overflow.
1055+
*/
1056+
if (!kvm_vcpu_has_mediated_pmu(vcpu)) {
1057+
pmc->emulated_counter++;
1058+
kvm_pmu_request_counter_reprogram(pmc);
1059+
return;
1060+
}
1061+
1062+
/*
1063+
* For mediated PMUs, pmc->counter is updated when the vCPU's PMU is
1064+
* put, and will be loaded into hardware when the PMU is loaded. Simply
1065+
* increment the counter and signal overflow if it wraps to zero.
1066+
*/
1067+
pmc->counter = (pmc->counter + 1) & pmc_bitmask(pmc);
1068+
if (!pmc->counter) {
1069+
pmc_to_pmu(pmc)->global_status |= BIT_ULL(pmc->idx);
1070+
if (pmc_is_pmi_enabled(pmc))
1071+
kvm_make_request(KVM_REQ_PMI, vcpu);
1072+
}
10381073
}
10391074

10401075
static inline bool cpl_is_matched(struct kvm_pmc *pmc)

0 commit comments

Comments
 (0)