KVM: VMX: Fix guest debugging while in L2
authorJan Kiszka <jan.kiszka@siemens.com>
Tue, 9 Feb 2016 19:15:18 +0000 (20:15 +0100)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 16 Feb 2016 17:48:32 +0000 (18:48 +0100)
When we take a #DB or #BP vmexit while in guest mode, we first of all
need to check if there is ongoing guest debugging that might be
interested in the event. Currently, we unconditionally leave L2 and
inject the event into L1 if it is intercepting the exceptions. That
breaks things marvelously.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/vmx.c

index 7852092b82aea2d8d11d96d30180f2d559c3bccd..cb501d306416c369416b48a1c85cce09bdd5ac97 100644 (file)
@@ -968,6 +968,16 @@ static inline bool is_exception_n(u32 intr_info, u8 vector)
                (INTR_TYPE_HARD_EXCEPTION | vector | INTR_INFO_VALID_MASK);
 }
 
+static inline bool is_debug(u32 intr_info)
+{
+       return is_exception_n(intr_info, DB_VECTOR);
+}
+
+static inline bool is_breakpoint(u32 intr_info)
+{
+       return is_exception_n(intr_info, BP_VECTOR);
+}
+
 static inline bool is_page_fault(u32 intr_info)
 {
        return is_exception_n(intr_info, PF_VECTOR);
@@ -7753,6 +7763,13 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
                else if (is_no_device(intr_info) &&
                         !(vmcs12->guest_cr0 & X86_CR0_TS))
                        return false;
+               else if (is_debug(intr_info) &&
+                        vcpu->guest_debug &
+                        (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))
+                       return false;
+               else if (is_breakpoint(intr_info) &&
+                        vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
+                       return false;
                return vmcs12->exception_bitmap &
                                (1u << (intr_info & INTR_INFO_VECTOR_MASK));
        case EXIT_REASON_EXTERNAL_INTERRUPT: