mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 10:09:10 +02:00
KVM: x86: Add a switch_db_regs flag to handle TDX's auto-switched behavior
Add a flag KVM_DEBUGREG_AUTO_SWITCH to skip saving/restoring guest DRs. TDX-SEAM unconditionally saves/restores guest DRs on TD exit/enter, and resets DRs to architectural INIT state on TD exit. Use the new flag KVM_DEBUGREG_AUTO_SWITCH to indicate that KVM doesn't need to save/restore guest DRs. KVM still needs to restore host DRs after TD exit if there are active breakpoints in the host, which is covered by the existing code. MOV-DR exiting is always cleared for TDX guests, so the handler for DR access is never called, and KVM_DEBUGREG_WONT_EXIT is never set. Add a warning if both KVM_DEBUGREG_WONT_EXIT and KVM_DEBUGREG_AUTO_SWITCH are set. Opportunistically convert the KVM_DEBUGREG_* definitions to use BIT(). Reported-by: Xiaoyao Li <xiaoyao.li@intel.com> Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> Co-developed-by: Chao Gao <chao.gao@intel.com> Signed-off-by: Chao Gao <chao.gao@intel.com> Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com> [binbin: rework changelog] Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com> Message-ID: <20241210004946.3718496-2-binbin.wu@linux.intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-ID: <20250129095902.16391-13-adrian.hunter@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
8af0990375
commit
484612f1a7
|
|
@ -606,8 +606,15 @@ struct kvm_pmu {
|
|||
struct kvm_pmu_ops;
|
||||
|
||||
enum {
|
||||
KVM_DEBUGREG_BP_ENABLED = 1,
|
||||
KVM_DEBUGREG_WONT_EXIT = 2,
|
||||
KVM_DEBUGREG_BP_ENABLED = BIT(0),
|
||||
KVM_DEBUGREG_WONT_EXIT = BIT(1),
|
||||
/*
|
||||
* Guest debug registers (DR0-3, DR6 and DR7) are saved/restored by
|
||||
* hardware on exit from or enter to guest. KVM needn't switch them.
|
||||
* DR0-3, DR6 and DR7 are set to their architectural INIT value on VM
|
||||
* exit, host values need to be restored.
|
||||
*/
|
||||
KVM_DEBUGREG_AUTO_SWITCH = BIT(2),
|
||||
};
|
||||
|
||||
struct kvm_mtrr {
|
||||
|
|
|
|||
|
|
@ -630,6 +630,7 @@ int tdx_vcpu_create(struct kvm_vcpu *vcpu)
|
|||
|
||||
vcpu->arch.efer = EFER_SCE | EFER_LME | EFER_LMA | EFER_NX;
|
||||
|
||||
vcpu->arch.switch_db_regs = KVM_DEBUGREG_AUTO_SWITCH;
|
||||
vcpu->arch.cr0_guest_owned_bits = -1ul;
|
||||
vcpu->arch.cr4_guest_owned_bits = -1ul;
|
||||
|
||||
|
|
|
|||
|
|
@ -10985,7 +10985,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
|
|||
if (vcpu->arch.guest_fpu.xfd_err)
|
||||
wrmsrl(MSR_IA32_XFD_ERR, vcpu->arch.guest_fpu.xfd_err);
|
||||
|
||||
if (unlikely(vcpu->arch.switch_db_regs)) {
|
||||
if (unlikely(vcpu->arch.switch_db_regs &&
|
||||
!(vcpu->arch.switch_db_regs & KVM_DEBUGREG_AUTO_SWITCH))) {
|
||||
set_debugreg(0, 7);
|
||||
set_debugreg(vcpu->arch.eff_db[0], 0);
|
||||
set_debugreg(vcpu->arch.eff_db[1], 1);
|
||||
|
|
@ -11037,6 +11038,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
|
|||
*/
|
||||
if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)) {
|
||||
WARN_ON(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP);
|
||||
WARN_ON(vcpu->arch.switch_db_regs & KVM_DEBUGREG_AUTO_SWITCH);
|
||||
kvm_x86_call(sync_dirty_debug_regs)(vcpu);
|
||||
kvm_update_dr0123(vcpu);
|
||||
kvm_update_dr7(vcpu);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user