Skip to content

Commit f7a65e5

Browse files
committed
KVM: x86/pmu: Disallow emulation in the fastpath if mediated PMCs are active
Don't handle exits in the fastpath if emulation is required, i.e. if an instruction needs to be skipped, the mediated PMU is enabled, and one or more PMCs is counting instructions. With the mediated PMU, KVM's cache of PMU state is inconsistent with respect to hardware until KVM exits the inner run loop (when the mediated PMU is "put"). Reviewed-by: Sandipan Das <sandipan.das@amd.com> Tested-by: Xudong Hao <xudong.hao@intel.com> Tested-by: Manali Shukla <manali.shukla@amd.com> Link: https://patch.msgid.link/20251206001720.468579-29-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 56bb273 commit f7a65e5

2 files changed

Lines changed: 19 additions & 0 deletions

File tree

arch/x86/kvm/pmu.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,16 @@ static inline bool pmc_is_globally_enabled(struct kvm_pmc *pmc)
234234
return test_bit(pmc->idx, (unsigned long *)&pmu->global_ctrl);
235235
}
236236

237+
static inline bool kvm_pmu_is_fastpath_emulation_allowed(struct kvm_vcpu *vcpu)
238+
{
239+
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
240+
241+
return !kvm_vcpu_has_mediated_pmu(vcpu) ||
242+
!bitmap_intersects(pmu->pmc_counting_instructions,
243+
(unsigned long *)&pmu->global_ctrl,
244+
X86_PMC_IDX_MAX);
245+
}
246+
237247
void kvm_pmu_deliver_pmi(struct kvm_vcpu *vcpu);
238248
void kvm_pmu_handle_event(struct kvm_vcpu *vcpu);
239249
int kvm_pmu_rdpmc(struct kvm_vcpu *vcpu, unsigned pmc, u64 *data);

arch/x86/kvm/x86.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2215,6 +2215,9 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_emulate_invd);
22152215

22162216
fastpath_t handle_fastpath_invd(struct kvm_vcpu *vcpu)
22172217
{
2218+
if (!kvm_pmu_is_fastpath_emulation_allowed(vcpu))
2219+
return EXIT_FASTPATH_NONE;
2220+
22182221
if (!kvm_emulate_invd(vcpu))
22192222
return EXIT_FASTPATH_EXIT_USERSPACE;
22202223

@@ -2271,6 +2274,9 @@ static inline bool kvm_vcpu_exit_request(struct kvm_vcpu *vcpu)
22712274

22722275
static fastpath_t __handle_fastpath_wrmsr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
22732276
{
2277+
if (!kvm_pmu_is_fastpath_emulation_allowed(vcpu))
2278+
return EXIT_FASTPATH_NONE;
2279+
22742280
switch (msr) {
22752281
case APIC_BASE_MSR + (APIC_ICR >> 4):
22762282
if (!lapic_in_kernel(vcpu) || !apic_x2apic_mode(vcpu->arch.apic) ||
@@ -11714,6 +11720,9 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_emulate_halt);
1171411720

1171511721
fastpath_t handle_fastpath_hlt(struct kvm_vcpu *vcpu)
1171611722
{
11723+
if (!kvm_pmu_is_fastpath_emulation_allowed(vcpu))
11724+
return EXIT_FASTPATH_NONE;
11725+
1171711726
if (!kvm_emulate_halt(vcpu))
1171811727
return EXIT_FASTPATH_EXIT_USERSPACE;
1171911728

0 commit comments

Comments
 (0)