Commit bfee4f07 authored by Dapeng Mi's avatar Dapeng Mi Committed by Sean Christopherson
Browse files

KVM: x86/pmu: Implement Intel mediated PMU requirements and constraints



Implement Intel PMU requirements and constraints for mediated PMU support.
Require host PMU version 4+ so that PERF_GLOBAL_STATUS_SET can be used to
precisely load the guest's status value into hardware, and require full-
width writes so that KVM can precisely load guest counter values.

Disable PEBS and LBRs if mediated PMU support is enabled, as they won't be
supported in the initial implementation.

Signed-off-by: default avatarDapeng Mi <dapeng1.mi@linux.intel.com>
Co-developed-by: default avatarMingwei Zhang <mizhang@google.com>
Signed-off-by: default avatarMingwei Zhang <mizhang@google.com>
[sean: split to separate patch, add full-width writes dependency]
Tested-by: default avatarXudong Hao <xudong.hao@intel.com>
Tested-by: default avatarManali Shukla <manali.shukla@amd.com>
Link: https://patch.msgid.link/20251206001720.468579-18-seanjc@google.com


Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
parent 3e51822b
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -395,7 +395,8 @@ static inline bool vmx_pt_mode_is_host_guest(void)

static inline bool vmx_pebs_supported(void)
{
	return boot_cpu_has(X86_FEATURE_PEBS) && kvm_pmu_cap.pebs_ept;
	return boot_cpu_has(X86_FEATURE_PEBS) && kvm_pmu_cap.pebs_ept &&
	       !enable_mediated_pmu;
}

static inline bool cpu_has_notify_vmexit(void)
+17 −0
Original line number Diff line number Diff line
@@ -767,6 +767,20 @@ void intel_pmu_cross_mapped_check(struct kvm_pmu *pmu)
	}
}

static bool intel_pmu_is_mediated_pmu_supported(struct x86_pmu_capability *host_pmu)
{
	u64 host_perf_cap = 0;

	if (boot_cpu_has(X86_FEATURE_PDCM))
		rdmsrq(MSR_IA32_PERF_CAPABILITIES, host_perf_cap);

	/*
	 * Require v4+ for MSR_CORE_PERF_GLOBAL_STATUS_SET, and full-width
	 * writes so that KVM can precisely load guest counter values.
	 */
	return host_pmu->version >= 4 && host_perf_cap & PERF_CAP_FW_WRITES;
}

struct kvm_pmu_ops intel_pmu_ops __initdata = {
	.rdpmc_ecx_to_pmc = intel_rdpmc_ecx_to_pmc,
	.msr_idx_to_pmc = intel_msr_idx_to_pmc,
@@ -778,6 +792,9 @@ struct kvm_pmu_ops intel_pmu_ops __initdata = {
	.reset = intel_pmu_reset,
	.deliver_pmi = intel_pmu_deliver_pmi,
	.cleanup = intel_pmu_cleanup,

	.is_mediated_pmu_supported = intel_pmu_is_mediated_pmu_supported,

	.EVENTSEL_EVENT = ARCH_PERFMON_EVENTSEL_EVENT,
	.MAX_NR_GP_COUNTERS = KVM_MAX_NR_INTEL_GP_COUNTERS,
	.MIN_NR_GP_COUNTERS = 1,
+2 −1
Original line number Diff line number Diff line
@@ -7958,7 +7958,8 @@ static __init u64 vmx_get_perf_capabilities(void)
	if (boot_cpu_has(X86_FEATURE_PDCM))
		rdmsrq(MSR_IA32_PERF_CAPABILITIES, host_perf_cap);

	if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR)) {
	if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR) &&
	    !enable_mediated_pmu) {
		x86_perf_get_lbr(&vmx_lbr_caps);

		/*