#define EXCPT_TRAP             1
 #define EXCPT_ABORT            2
 #define EXCPT_INTERRUPT                3
+#define EXCPT_DB               4
 
 static int exception_type(int vector)
 {
 
        mask = 1 << vector;
 
-       /* #DB is trap, as instruction watchpoints are handled elsewhere */
-       if (mask & ((1 << DB_VECTOR) | (1 << BP_VECTOR) | (1 << OF_VECTOR)))
+       /*
+        * #DBs can be trap-like or fault-like, the caller must check other CPU
+        * state, e.g. DR6, to determine whether a #DB is a trap or fault.
+        */
+       if (mask & (1 << DB_VECTOR))
+               return EXCPT_DB;
+
+       if (mask & ((1 << BP_VECTOR) | (1 << OF_VECTOR)))
                return EXCPT_TRAP;
 
        if (mask & ((1 << DF_VECTOR) | (1 << MC_VECTOR)))
                unsigned long rflags = static_call(kvm_x86_get_rflags)(vcpu);
                toggle_interruptibility(vcpu, ctxt->interruptibility);
                vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
+
+               /*
+                * Note, EXCPT_DB is assumed to be fault-like as the emulator
+                * only supports code breakpoints and general detect #DB, both
+                * of which are fault-like.
+                */
                if (!ctxt->have_exception ||
                    exception_type(ctxt->exception.vector) == EXCPT_TRAP) {
                        kvm_pmu_trigger_event(vcpu, PERF_COUNT_HW_INSTRUCTIONS);
 
        /* try to inject new event if pending */
        if (vcpu->arch.exception.pending) {
+               /*
+                * Fault-class exceptions, except #DBs, set RF=1 in the RFLAGS
+                * value pushed on the stack.  Trap-like exception and all #DBs
+                * leave RF as-is (KVM follows Intel's behavior in this regard;
+                * AMD states that code breakpoint #DBs excplitly clear RF=0).
+                *
+                * Note, most versions of Intel's SDM and AMD's APM incorrectly
+                * describe the behavior of General Detect #DBs, which are
+                * fault-like.  They do _not_ set RF, a la code breakpoints.
+                */
                if (exception_type(vcpu->arch.exception.nr) == EXCPT_FAULT)
                        __kvm_set_rflags(vcpu, kvm_get_rflags(vcpu) |
                                             X86_EFLAGS_RF);