[PATCH] KVM: nVMX: clear nested_run_pending when emulating invalid guest state

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Clear nested_run_pending in handle_invalid_guest_state() after calling
emulate_instruction(), i.e. after attempting to emulate at least one
instruction.  This fixes an issue where L0 enters an infinite loop if
L2 hits an exception that is intercepted by L1 while L0 is emulating
L2's invalid guest state, effectively causing DoS on L1, e.g. the only
way to break the loop is to kill Qemu in L0.

    1. call handle_invalid_guest_state() for L2
    2. emulate_instruction() pends an exception, e.g. #UD
    3. L1 intercepts the exception, i.e. nested_vmx_check_exception
       returns 1
    4. vmx_check_nested_events() returns -EBUSY because L1 wants to
       intercept the exception and nested_run_pending is true
    5. handle_invalid_guest_state() never makes forward progress for
       L2 due to the pending exception
    6. L1 retries VMLAUNCH and VMExits to L0 indefinitely, i.e. the
       L1 vCPU trying VMLAUNCH effectively hangs

Signed-off-by: Sean Christopherson <sean.j.christopherson@xxxxxxxxx>
---
 arch/x86/kvm/vmx.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 591214843046..3073160e6bae 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -6835,6 +6835,8 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
 
 		err = emulate_instruction(vcpu, 0);
 
+		vmx->nested.nested_run_pending = 0;
+
 		if (err == EMULATE_USER_EXIT) {
 			++vcpu->stat.mmio_exits;
 			ret = 0;
-- 
2.16.2




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux