]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: x86: Set guest DR6 by kvm_queue_exception_p() in instruction emulation
authorHou Wenlong <houwenlong.hwl@antgroup.com>
Fri, 15 May 2026 22:26:31 +0000 (15:26 -0700)
committerSean Christopherson <seanjc@google.com>
Thu, 21 May 2026 21:31:01 +0000 (14:31 -0700)
Record DR6 in emulate_db() and use kvm_queue_exception_p() to set DR6
instead of directly using kvm_set_dr6() in emulation, i.e. rely on the
standard exception path to set DR6 via kvm_deliver_exception_payload().
This keeps the handling of DR6 during #DB injection consistent with other
code paths.

No functional change intended.

Signed-off-by: Hou Wenlong <houwenlong.hwl@antgroup.com>
[sean: fix e vs. p goof, add kvm_inject_emulated_db() right away]
Reviewed-by: Yosry Ahmed <yosry@kernel.org>
Link: https://patch.msgid.link/20260515222638.1949982-4-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/emulate.c
arch/x86/kvm/kvm_emulate.h
arch/x86/kvm/x86.c

index c8c6cc0406d6dd7264808b6a7a4c16e5e56fa74b..510244555a74bc54600b5f5ae61a0b5a6d53c6bd 100644 (file)
@@ -540,8 +540,9 @@ static int emulate_exception(struct x86_emulate_ctxt *ctxt, int vec,
        return X86EMUL_PROPAGATE_FAULT;
 }
 
-static int emulate_db(struct x86_emulate_ctxt *ctxt)
+static int emulate_db(struct x86_emulate_ctxt *ctxt, unsigned long dr6)
 {
+       ctxt->exception.dr6 = dr6;
        return emulate_exception(ctxt, DB_VECTOR, 0, false);
 }
 
@@ -3847,15 +3848,8 @@ static int check_dr_read(struct x86_emulate_ctxt *ctxt)
        if ((cr4 & X86_CR4_DE) && (dr == 4 || dr == 5))
                return emulate_ud(ctxt);
 
-       if (ctxt->ops->get_dr(ctxt, 7) & DR7_GD) {
-               ulong dr6;
-
-               dr6 = ctxt->ops->get_dr(ctxt, 6);
-               dr6 &= ~DR_TRAP_BITS;
-               dr6 |= DR6_BD | DR6_ACTIVE_LOW;
-               ctxt->ops->set_dr(ctxt, 6, dr6);
-               return emulate_db(ctxt);
-       }
+       if (ctxt->ops->get_dr(ctxt, 7) & DR7_GD)
+               return emulate_db(ctxt, DR6_BD);
 
        return X86EMUL_CONTINUE;
 }
index 0abff36d099429660bceb5888ab6abd9ccb7a3b0..bb2a2aee0e13cd48793f31efe005c7b33ae0a454 100644 (file)
@@ -24,7 +24,11 @@ struct x86_exception {
        bool error_code_valid;
        u16 error_code;
        bool nested_page_fault;
-       u64 address; /* cr2 or nested page fault gpa */
+       union {
+               u64 address; /* cr2 or nested page fault gpa */
+               unsigned long dr6;
+               u64 payload;
+       };
        u8 async_page_fault;
        unsigned long exit_qualification;
 };
index 6934c0d01419ffb6d45a260f5a9bf538161f9f17..af6f3b5d2f3d85cfa5a60206a63d847958c5776d 100644 (file)
@@ -8977,11 +8977,18 @@ static void toggle_interruptibility(struct kvm_vcpu *vcpu, u32 mask)
        }
 }
 
+static void kvm_inject_emulated_db(struct kvm_vcpu *vcpu, unsigned long dr6)
+{
+       kvm_queue_exception_p(vcpu, DB_VECTOR, dr6);
+}
+
 static void inject_emulated_exception(struct kvm_vcpu *vcpu)
 {
        struct x86_exception *ex = &vcpu->arch.emulate_ctxt->exception;
 
-       if (ex->vector == PF_VECTOR)
+       if (ex->vector == DB_VECTOR)
+               kvm_inject_emulated_db(vcpu, ex->dr6);
+       else if (ex->vector == PF_VECTOR)
                kvm_inject_emulated_page_fault(vcpu, ex);
        else if (ex->error_code_valid)
                kvm_queue_exception_e(vcpu, ex->vector, ex->error_code);
@@ -9026,6 +9033,7 @@ static void init_emulate_ctxt(struct kvm_vcpu *vcpu)
        ctxt->interruptibility = 0;
        ctxt->have_exception = false;
        ctxt->exception.vector = -1;
+       ctxt->exception.payload = 0;
        ctxt->perm_ok = false;
 
        init_decode_cache(ctxt);