Skip to content

Commit d1a530a

Browse files
sean-jcgregkh
authored andcommitted
KVM: x86: Drop kvm_x86_ops.set_dr6() in favor of a new KVM_RUN flag
[ Upstream commit 80c64c7 ] Instruct vendor code to load the guest's DR6 into hardware via a new KVM_RUN flag, and remove kvm_x86_ops.set_dr6(), whose sole purpose was to load vcpu->arch.dr6 into hardware when DR6 can be read/written directly by the guest. Note, TDX already WARNs on any run_flag being set, i.e. will yell if KVM thinks DR6 needs to be reloaded. TDX vCPUs force KVM_DEBUGREG_AUTO_SWITCH and never clear the flag, i.e. should never observe KVM_RUN_LOAD_GUEST_DR6. Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sean Christopherson <[email protected]> [sean: drop TDX changes] Signed-off-by: Sean Christopherson <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 1fc1d9b commit d1a530a

File tree

6 files changed

+11
-14
lines changed

6 files changed

+11
-14
lines changed

arch/x86/include/asm/kvm-x86-ops.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ KVM_X86_OP(set_idt)
4747
KVM_X86_OP(get_gdt)
4848
KVM_X86_OP(set_gdt)
4949
KVM_X86_OP(sync_dirty_debug_regs)
50-
KVM_X86_OP(set_dr6)
5150
KVM_X86_OP(set_dr7)
5251
KVM_X86_OP(cache_reg)
5352
KVM_X86_OP(get_rflags)

arch/x86/include/asm/kvm_host.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1629,6 +1629,7 @@ static inline u16 kvm_lapic_irq_dest_mode(bool dest_mode_logical)
16291629

16301630
enum kvm_x86_run_flags {
16311631
KVM_RUN_FORCE_IMMEDIATE_EXIT = BIT(0),
1632+
KVM_RUN_LOAD_GUEST_DR6 = BIT(1),
16321633
};
16331634

16341635
struct kvm_x86_ops {
@@ -1679,7 +1680,6 @@ struct kvm_x86_ops {
16791680
void (*get_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt);
16801681
void (*set_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt);
16811682
void (*sync_dirty_debug_regs)(struct kvm_vcpu *vcpu);
1682-
void (*set_dr6)(struct kvm_vcpu *vcpu, unsigned long value);
16831683
void (*set_dr7)(struct kvm_vcpu *vcpu, unsigned long value);
16841684
void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg);
16851685
unsigned long (*get_rflags)(struct kvm_vcpu *vcpu);

arch/x86/kvm/svm/svm.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4270,10 +4270,13 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags)
42704270
svm_hv_update_vp_id(svm->vmcb, vcpu);
42714271

42724272
/*
4273-
* Run with all-zero DR6 unless needed, so that we can get the exact cause
4274-
* of a #DB.
4273+
* Run with all-zero DR6 unless the guest can write DR6 freely, so that
4274+
* KVM can get the exact cause of a #DB. Note, loading guest DR6 from
4275+
* KVM's snapshot is only necessary when DR accesses won't exit.
42754276
*/
4276-
if (likely(!(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)))
4277+
if (unlikely(run_flags & KVM_RUN_LOAD_GUEST_DR6))
4278+
svm_set_dr6(vcpu, vcpu->arch.dr6);
4279+
else if (likely(!(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)))
42774280
svm_set_dr6(vcpu, DR6_ACTIVE_LOW);
42784281

42794282
clgi();
@@ -5084,7 +5087,6 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
50845087
.set_idt = svm_set_idt,
50855088
.get_gdt = svm_get_gdt,
50865089
.set_gdt = svm_set_gdt,
5087-
.set_dr6 = svm_set_dr6,
50885090
.set_dr7 = svm_set_dr7,
50895091
.sync_dirty_debug_regs = svm_sync_dirty_debug_regs,
50905092
.cache_reg = svm_cache_reg,

arch/x86/kvm/vmx/main.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ struct kvm_x86_ops vt_x86_ops __initdata = {
6060
.set_idt = vmx_set_idt,
6161
.get_gdt = vmx_get_gdt,
6262
.set_gdt = vmx_set_gdt,
63-
.set_dr6 = vmx_set_dr6,
6463
.set_dr7 = vmx_set_dr7,
6564
.sync_dirty_debug_regs = vmx_sync_dirty_debug_regs,
6665
.cache_reg = vmx_cache_reg,

arch/x86/kvm/vmx/vmx.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5630,12 +5630,6 @@ void vmx_sync_dirty_debug_regs(struct kvm_vcpu *vcpu)
56305630
set_debugreg(DR6_RESERVED, 6);
56315631
}
56325632

5633-
void vmx_set_dr6(struct kvm_vcpu *vcpu, unsigned long val)
5634-
{
5635-
lockdep_assert_irqs_disabled();
5636-
set_debugreg(vcpu->arch.dr6, 6);
5637-
}
5638-
56395633
void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val)
56405634
{
56415635
vmcs_writel(GUEST_DR7, val);
@@ -7400,6 +7394,9 @@ fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags)
74007394
vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]);
74017395
vcpu->arch.regs_dirty = 0;
74027396

7397+
if (run_flags & KVM_RUN_LOAD_GUEST_DR6)
7398+
set_debugreg(vcpu->arch.dr6, 6);
7399+
74037400
/*
74047401
* Refresh vmcs.HOST_CR3 if necessary. This must be done immediately
74057402
* prior to VM-Enter, as the kernel may load a new ASID (PCID) any time

arch/x86/kvm/x86.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10977,7 +10977,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
1097710977
set_debugreg(vcpu->arch.eff_db[3], 3);
1097810978
/* When KVM_DEBUGREG_WONT_EXIT, dr6 is accessible in guest. */
1097910979
if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT))
10980-
kvm_x86_call(set_dr6)(vcpu, vcpu->arch.dr6);
10980+
run_flags |= KVM_RUN_LOAD_GUEST_DR6;
1098110981
} else if (unlikely(hw_breakpoint_active())) {
1098210982
set_debugreg(DR7_FIXED_1, 7);
1098310983
}

0 commit comments

Comments
 (0)