If the host has the PERF_METRICS capability but it's not present on the guest, RDPMC interception must be enabled and KVM should inject an #GP when the guest attempts a PERF_METRICS RDPMC. If the guest has PERF_METRICS but RDPMC interception is enabled for other reasons, KVM needs to emulate RDPMC with type 0x2000. For simplicity, Metrics Clear Mode is not supported. Signed-off-by: Zide Chen Reviewed-by: Dapeng Mi --- v8: - Move kvm_need_perf_metrics_intercept() to patch 5/9. v6: - Merge kvm_pmu_rdpmc_metrics() into intel_emulate_rdpmc(). - Reject non-zero index. v5: - new patch. --- arch/x86/kvm/pmu.c | 1 + arch/x86/kvm/vmx/pmu_intel.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c index 789624658e8f..dab0bcabaa8f 100644 --- a/arch/x86/kvm/pmu.c +++ b/arch/x86/kvm/pmu.c @@ -825,6 +825,7 @@ bool kvm_need_rdpmc_intercept(struct kvm_vcpu *vcpu) return true; return kvm_need_any_pmc_intercept(vcpu) || + kvm_need_perf_metrics_intercept(vcpu) || pmu->counter_bitmask[KVM_PMC_GP] != (BIT_ULL(kvm_host_pmu.bit_width_gp) - 1) || pmu->counter_bitmask[KVM_PMC_FIXED] != (BIT_ULL(kvm_host_pmu.bit_width_fixed) - 1); } diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index bbf4afcffafc..3ca61e4b0ba6 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -31,6 +31,7 @@ */ #define INTEL_RDPMC_GP 0 #define INTEL_RDPMC_FIXED INTEL_PMC_FIXED_RDPMC_BASE +#define INTEL_RDPMC_METRICS INTEL_PMC_FIXED_RDPMC_METRICS #define INTEL_RDPMC_TYPE_MASK GENMASK(31, 16) #define INTEL_RDPMC_INDEX_MASK GENMASK(15, 0) @@ -125,6 +126,19 @@ static int intel_emulate_rdpmc(struct kvm_vcpu *vcpu, unsigned int idx, counters = pmu->gp_counters; num_counters = pmu->nr_arch_gp_counters; break; + case INTEL_RDPMC_METRICS: + if (!kvm_vcpu_has_perf_metrics(vcpu)) + return 1; + + /* + * The index in ECX[15:0] is implementation specific, but no + * platform currently supports a non-zero index. + */ + if (idx) + return 1; + + *data = pmu->perf_metrics; + return 0; default: return 1; } -- 2.55.0