diff options
| -rw-r--r-- | arch/x86/kvm/vmx/pmu_intel.c | 15 | 
1 files changed, 14 insertions, 1 deletions
| diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index a6216c874729..8207f8c03585 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -108,11 +108,24 @@ static bool intel_hw_event_available(struct kvm_pmc *pmc)  	u8 unit_mask = (pmc->eventsel & ARCH_PERFMON_EVENTSEL_UMASK) >> 8;  	int i; +	/* +	 * Fixed counters are always available if KVM reaches this point.  If a +	 * fixed counter is unsupported in hardware or guest CPUID, KVM doesn't +	 * allow the counter's corresponding MSR to be written.  KVM does use +	 * architectural events to program fixed counters, as the interface to +	 * perf doesn't allow requesting a specific fixed counter, e.g. perf +	 * may (sadly) back a guest fixed PMC with a general purposed counter. +	 * But if _hardware_ doesn't support the associated event, KVM simply +	 * doesn't enumerate support for the fixed counter. +	 */ +	if (pmc_is_fixed(pmc)) +		return true; +  	BUILD_BUG_ON(ARRAY_SIZE(intel_arch_events) != NR_INTEL_ARCH_EVENTS);  	/*  	 * Disallow events reported as unavailable in guest CPUID.  Note, this -	 * doesn't apply to pseudo-architectural events. +	 * doesn't apply to pseudo-architectural events (see above).  	 */  	for (i = 0; i < NR_REAL_INTEL_ARCH_EVENTS; i++) {  		if (intel_arch_events[i].eventsel != event_select || | 
