KVM: x86: Manually check DR4/5 write values to fix SVM intercept priority

Manually (pre)check the values being written to DR4/5, i.e. the DR6/DR7
aliases, instead of relying on ->set_dr() => kvm_set_dr() to signal a #GP.
SVM unfortunately prioritizes all exceptions over an instruction intercept,
i.e. nSVM is relying on the emulator to perform *all* exception checks
prior to attempting to execute the instruction.

Fixes: 3b88e41a41 ("KVM: SVM: Add intercept check for accessing dr registers")
Reviewed-by: Jim Mattson <jmattson@google.com>
Link: https://patch.msgid.link/20260612230113.684301-4-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
This commit is contained in:
Sean Christopherson 2026-06-12 16:01:08 -07:00
parent 55ac576a9b
commit e27ca3dfbb

View File

@ -3853,15 +3853,23 @@ static int check_dr_read(struct x86_emulate_ctxt *ctxt)
static int check_dr_write(struct x86_emulate_ctxt *ctxt)
{
u64 new_val = ctxt->src.val64;
int dr = ctxt->modrm_reg;
int rc;
rc = check_dr_read(ctxt);
if (rc != X86EMUL_CONTINUE)
return rc;
if ((dr == 6 || dr == 7) && (new_val & 0xffffffff00000000ULL))
return emulate_gp(ctxt, 0);
switch (ctxt->modrm_reg) {
case 4:
case 5:
case 6:
case 7:
if (new_val & 0xffffffff00000000ULL)
return emulate_gp(ctxt, 0);
break;
default:
break;
}
return X86EMUL_CONTINUE;
}