Skip to content

Commit 53221fa

Browse files
sean-jcgregkh
authored andcommitted
KVM: nVMX: Snapshot pre-VM-Enter DEBUGCTL for !nested_run_pending case
commit 764643a upstream. If a nested run isn't pending, snapshot vmcs01.GUEST_IA32_DEBUGCTL irrespective of whether or not VM_ENTRY_LOAD_DEBUG_CONTROLS is set in vmcs12. When restoring nested state, e.g. after migration, without a nested run pending, prepare_vmcs02() will propagate nested.vmcs01_debugctl to vmcs02, i.e. will load garbage/zeros into vmcs02.GUEST_IA32_DEBUGCTL. If userspace restores nested state before MSRs, then loading garbage is a non-issue as loading DEBUGCTL will also update vmcs02. But if usersepace restores MSRs first, then KVM is responsible for propagating L2's value, which is actually thrown into vmcs01, into vmcs02. Restoring L2 MSRs into vmcs01, i.e. loading all MSRs before nested state is all kinds of bizarre and ideally would not be supported. Sadly, some VMMs do exactly that and rely on KVM to make things work. Note, there's still a lurking SMM bug, as propagating vmcs01's DEBUGCTL to vmcs02 across RSM may corrupt L2's DEBUGCTL. But KVM's entire VMX+SMM emulation is flawed as SMI+RSM should not toouch _any_ VMCS when use the "default treatment of SMIs", i.e. when not using an SMI Transfer Monitor. Link: https://lore.kernel.org/all/[email protected] Fixes: 8fcc4b5 ("kvm: nVMX: Introduce KVM_CAP_NESTED_STATE") Cc: [email protected] Signed-off-by: Sean Christopherson <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 8f8aa30 commit 53221fa

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

arch/x86/kvm/vmx/nested.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3373,7 +3373,8 @@ enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu,
33733373
if (likely(!evaluate_pending_interrupts) && kvm_vcpu_apicv_active(vcpu))
33743374
evaluate_pending_interrupts |= vmx_has_apicv_interrupt(vcpu);
33753375

3376-
if (!(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS))
3376+
if (!vmx->nested.nested_run_pending ||
3377+
!(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS))
33773378
vmx->nested.vmcs01_debugctl = vmcs_read64(GUEST_IA32_DEBUGCTL);
33783379
if (kvm_mpx_supported() &&
33793380
(!vmx->nested.nested_run_pending ||

0 commit comments

Comments
 (0)