Skip to content

Commit 807cb9c

Browse files
committed
KVM: SVM: Don't rely on DebugSwap to restore host DR0..DR3
Never rely on the CPU to restore/load host DR0..DR3 values, even if the CPU supports DebugSwap, as there are no guarantees that SNP guests will actually enable DebugSwap on APs. E.g. if KVM were to rely on the CPU to load DR0..DR3 and skipped them during hw_breakpoint_restore(), KVM would run with clobbered-to-zero DRs if an SNP guest created APs without DebugSwap enabled. Update the comment to explain the dangers, and hopefully prevent breaking KVM in the future. Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com> Link: https://lore.kernel.org/r/20250227012541.3234589-3-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent b2653cd commit 807cb9c

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

arch/x86/kvm/svm/sev.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4606,18 +4606,21 @@ void sev_es_prepare_switch_to_guest(struct vcpu_svm *svm, struct sev_es_save_are
46064606
/*
46074607
* If DebugSwap is enabled, debug registers are loaded but NOT saved by
46084608
* the CPU (Type-B). If DebugSwap is disabled/unsupported, the CPU does
4609-
* not save or load debug registers. Sadly, on CPUs without
4610-
* ALLOWED_SEV_FEATURES, KVM can't prevent SNP guests from enabling
4611-
* DebugSwap on secondary vCPUs without KVM's knowledge via "AP Create".
4612-
* Save all registers if DebugSwap is supported to prevent host state
4613-
* from being clobbered by a misbehaving guest.
4609+
* not save or load debug registers. Sadly, KVM can't prevent SNP
4610+
* guests from lying about DebugSwap on secondary vCPUs, i.e. the
4611+
* SEV_FEATURES provided at "AP Create" isn't guaranteed to match what
4612+
* the guest has actually enabled (or not!) in the VMSA.
4613+
*
4614+
* If DebugSwap is *possible*, save the masks so that they're restored
4615+
* if the guest enables DebugSwap. But for the DRs themselves, do NOT
4616+
* rely on the CPU to restore the host values; KVM will restore them as
4617+
* needed in common code, via hw_breakpoint_restore(). Note, KVM does
4618+
* NOT support virtualizing Breakpoint Extensions, i.e. the mask MSRs
4619+
* don't need to be restored per se, KVM just needs to ensure they are
4620+
* loaded with the correct values *if* the CPU writes the MSRs.
46144621
*/
46154622
if (sev_vcpu_has_debug_swap(svm) ||
46164623
(sev_snp_guest(kvm) && cpu_feature_enabled(X86_FEATURE_DEBUG_SWAP))) {
4617-
hostsa->dr0 = native_get_debugreg(0);
4618-
hostsa->dr1 = native_get_debugreg(1);
4619-
hostsa->dr2 = native_get_debugreg(2);
4620-
hostsa->dr3 = native_get_debugreg(3);
46214624
hostsa->dr0_addr_mask = amd_get_dr_addr_mask(0);
46224625
hostsa->dr1_addr_mask = amd_get_dr_addr_mask(1);
46234626
hostsa->dr2_addr_mask = amd_get_dr_addr_mask(2);

0 commit comments

Comments
 (0)