Re: [PATCH v3 5/8] KVM: VMX: Prioritize DR7.GD=1 #DB over CPL>0 #GP on Intel
From: Jim Mattson
Date: Mon Jun 15 2026 - 14:17:27 EST
On Fri, Jun 12, 2026 at 4:03 PM Sean Christopherson <seanjc@xxxxxxxxxx> wrote:
>
> When emulating a MOV DR on Intel with DR7.GD=1 at CPL>0, prioritize the #DB
> due to DR7.GD over the #GP due to CPL>0, as empirical testing shows that
> Intel CPUs (Skylake, Icelake and Emerald Rapids) prioritize the DR7.GD #DB
> over all #GPs, whereas AMD CPUs prioritize the CPL>0 #GP (but not illegal
> value #GPs) over the #DB.
Gnarly!
> Outside of the emulator, don't bother trying to provide the "correct"
> priority based on the virtual CPU model, as it's simply impossible to do
> so without intercepting *all* MOV DR accesses, which would result in a
> massive, unacceptable performance hit. Note, getting the priority right
> when advertising Intel on AMD would also require intercepting #GP, as SVM
> prioritizes all exceptions over the instruction intercept.
No sane person would attempt cross-vendor virtualization! :)
> Note, neither Intel's SDM nor AMD's APM says anything about the relative
> priority, hence the empirical testing. Arguably Intel's description of
> DR7.GD:
>
> causes a debug exception to be generated prior to any MOV instruction
> that accesses a debug register.
>
> implies that DR7.GD has higher priority. But that's a fairly weak argument
> as the statement would still hold true if the #GP due to CPL>0 had higher
> priority, as the #GP would prevent any access to a DR.
>
> Fixes: 3b88e41a4134 ("KVM: SVM: Add intercept check for accessing dr registers")
> Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
> ---
> arch/x86/kvm/emulate.c | 7 ++++++-
> arch/x86/kvm/vmx/vmx.c | 6 +++---
> 2 files changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index 127a21eeef66..b4dc57fe0bc9 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -3834,6 +3834,7 @@ static int check_cr_access(struct x86_emulate_ctxt *ctxt)
>
> static int check_dr_read(struct x86_emulate_ctxt *ctxt)
> {
> + bool is_intel = ctxt->ops->guest_cpuid_is_intel_compatible(ctxt);
Hmmm...Have you tested VIA? Or even Hygon? How compatible is
"<vendor>_compatible"?