Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 90ae2ca2 authored by Jim Mattson's avatar Jim Mattson Committed by Greg Kroah-Hartman
Browse files

KVM: x86/svm: Clear reserved bits written to PerfEvtSeln MSRs



[ Upstream commit 9b026073db2f1ad0e4d8b61c83316c8497981037 ]

AMD EPYC CPUs never raise a #GP for a WRMSR to a PerfEvtSeln MSR. Some
reserved bits are cleared, and some are not. Specifically, on
Zen3/Milan, bits 19 and 42 are not cleared.

When emulating such a WRMSR, KVM should not synthesize a #GP,
regardless of which bits are set. However, undocumented bits should
not be passed through to the hardware MSR. So, rather than checking
for reserved bits and synthesizing a #GP, just clear the reserved
bits.

This may seem pedantic, but since KVM currently does not support the
"Host/Guest Only" bits (41:40), it is necessary to clear these bits
rather than synthesizing #GP, because some popular guests (e.g Linux)
will set the "Host Only" bit even on CPUs that don't support
EFER.SVME, and they don't expect a #GP.

For example,

root@Ubuntu1804:~# perf stat -e r26 -a sleep 1

 Performance counter stats for 'system wide':

                 0      r26

       1.001070977 seconds time elapsed

Feb 23 03:59:58 Ubuntu1804 kernel: [  405.379957] unchecked MSR access error: WRMSR to 0xc0010200 (tried to write 0x0000020000130026) at rIP: 0xffffffff9b276a28 (native_write_msr+0x8/0x30)
Feb 23 03:59:58 Ubuntu1804 kernel: [  405.379958] Call Trace:
Feb 23 03:59:58 Ubuntu1804 kernel: [  405.379963]  amd_pmu_disable_event+0x27/0x90

Fixes: ca724305 ("KVM: x86/vPMU: Implement AMD vPMU code for KVM")
Reported-by: default avatarLotus Fenn <lotusf@google.com>
Signed-off-by: default avatarJim Mattson <jmattson@google.com>
Reviewed-by: default avatarLike Xu <likexu@tencent.com>
Reviewed-by: default avatarDavid Dunn <daviddunn@google.com>
Message-Id: <20220226234131.2167175-1-jmattson@google.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent fe8aaab8
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
@@ -139,13 +139,11 @@ static int amd_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
	/* MSR_K7_EVNTSELn */
	pmc = get_gp_pmc(pmu, msr, MSR_K7_EVNTSEL0);
	if (pmc) {
		if (data == pmc->eventsel)
			return 0;
		if (!(data & pmu->reserved_bits)) {
		data &= ~pmu->reserved_bits;
		if (data != pmc->eventsel)
			reprogram_gp_counter(pmc, data);
		return 0;
	}
	}

	return 1;
}