Skip to content

Commit e7bab98

Browse files
jsmattsonjrgregkh
authored andcommitted
KVM: x86/svm: Clear reserved bits written to PerfEvtSeln MSRs
[ Upstream commit 9b02607 ] 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: ca72430 ("KVM: x86/vPMU: Implement AMD vPMU code for KVM") Reported-by: Lotus Fenn <[email protected]> Signed-off-by: Jim Mattson <[email protected]> Reviewed-by: Like Xu <[email protected]> Reviewed-by: David Dunn <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 5483640 commit e7bab98

File tree

1 file changed

+3
-5
lines changed

1 file changed

+3
-5
lines changed

arch/x86/kvm/svm/pmu.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,12 +261,10 @@ static int amd_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
261261
/* MSR_EVNTSELn */
262262
pmc = get_gp_pmc_amd(pmu, msr, PMU_TYPE_EVNTSEL);
263263
if (pmc) {
264-
if (data == pmc->eventsel)
265-
return 0;
266-
if (!(data & pmu->reserved_bits)) {
264+
data &= ~pmu->reserved_bits;
265+
if (data != pmc->eventsel)
267266
reprogram_gp_counter(pmc, data);
268-
return 0;
269-
}
267+
return 0;
270268
}
271269

272270
return 1;

0 commit comments

Comments
 (0)