Skip to contentSkip to conversation

KVM: VMX: Conditionally reload debug register 6

PATCH Superseded Avi Kivity 2 participants 5 messages Sep 1, 2009

Subsystems (3)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

Avi Kivity

author
#0 lore raw

PATCH 1/1 KVM: VMX: Conditionally reload debug register 6

Only reload debug register 6 if we're running with the guest's debug registers. Saves around 150 cycles from the guest lightweight exit path.

---
 arch/x86/kvm/vmx.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)
arch/x86/kvm/vmx.c +4 -2
index 05cd554..70b0c54 100644
@@ -3629,7 +3629,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
 	 */
 	vmcs_writel(HOST_CR0, read_cr0());
 
-	set_debugreg(vcpu->arch.dr6, 6);
+	if (vcpu->arch.switch_db_regs)
+		set_debugreg(vcpu->arch.dr6, 6);
 
 	asm(
 		/* Store host registers */
@@ -3731,7 +3732,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
 				  | (1 << VCPU_EXREG_PDPTR));
 	vcpu->arch.regs_dirty = 0;
 
-	get_debugreg(vcpu->arch.dr6, 6);
+	if (vcpu->arch.switch_db_regs)
+		get_debugreg(vcpu->arch.dr6, 6);
 
 	vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
 	if (vmx->rmode.irq.pending)
Signature · 1 line
1.6.4.1
#1 lore raw
Quoted 24 lines · Avi Kivity

Only reload debug register 6 if we're running with the guest's debug registers. Saves around 150 cycles from the guest lightweight exit path.

---
 arch/x86/kvm/vmx.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)
arch/x86/kvm/vmx.c +2 -1
index 05cd554..70b0c54 100644
@@ -3629,7 +3629,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
 	 */
 	vmcs_writel(HOST_CR0, read_cr0());
 
-	set_debugreg(vcpu->arch.dr6, 6);
+	if (vcpu->arch.switch_db_regs)
+		set_debugreg(vcpu->arch.dr6, 6);
 
 	asm(
 		/* Store host registers */

arch/x86/kvm/vmx.c static void vmx_vcpu_run(struct kvm_vcpu *vcpu) · line 3739

Quoted 9 lines
arch/x86/kvm/vmx.c +2 -1
@@ -3731,7 +3732,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
 				  | (1 << VCPU_EXREG_PDPTR));
 	vcpu->arch.regs_dirty = 0;
 
-	get_debugreg(vcpu->arch.dr6, 6);
+	if (vcpu->arch.switch_db_regs)
+		get_debugreg(vcpu->arch.dr6, 6);
 
 	vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
 	if (vmx->rmode.irq.pending)

That reduces the emulation quality as vcpu->arch.switch_db_regs is only set if some breakpoint is active while dr6 has its use also when that is not the case).

Jan

Signature · 2 lines
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux
author
#2 lore raw
Quoted 8 lines · Jan Kiszka
(quoted diff) +0 -0
@@ -3731,7 +3732,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
 >   				| (1<<  VCPU_EXREG_PDPTR));
 >   	vcpu->arch.regs_dirty = 0;
Quoted 5 lines
arch/x86/kvm/vmx.c +2 -1
-	get_debugreg(vcpu->arch.dr6, 6);
+	if (vcpu->arch.switch_db_regs)
+		get_debugreg(vcpu->arch.dr6, 6);
Quoted 7 lines
Quoted 3 lines
  	vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
  	if (vmx->rmode.irq.pending)

That reduces the emulation quality as vcpu->arch.switch_db_regs is only set if some breakpoint is active while dr6 has its use also when that is not the case).

True - there's the TF reason reporting bits.

How about this then:

- if !switch_db_regs, trap #DB
- on #DB trap, copy DR6.BS and DR6.BT to vcpu->arch.dr6, and reinject the #DB

?

Signature · 1 line
error compiling committee.c: too many arguments to function
#3 lore raw
Quoted 19 lines · Avi Kivity
Quoted 8 lines · Jan Kiszka
(quoted diff) +0 -0
@@ -3731,7 +3732,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
 >   				| (1<<  VCPU_EXREG_PDPTR));
 >   	vcpu->arch.regs_dirty = 0;
Quoted 5 lines
arch/x86/kvm/vmx.c +2 -1
-	get_debugreg(vcpu->arch.dr6, 6);
+	if (vcpu->arch.switch_db_regs)
+		get_debugreg(vcpu->arch.dr6, 6);
Quoted 7 lines
Quoted 3 lines
  	vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
  	if (vmx->rmode.irq.pending)

That reduces the emulation quality as vcpu->arch.switch_db_regs is only set if some breakpoint is active while dr6 has its use also when that is not the case).

True - there's the TF reason reporting bits.

Quoted 7 lines

How about this then:

- if !switch_db_regs, trap #DB
- on #DB trap, copy DR6.BS and DR6.BT to vcpu->arch.dr6, and reinject the #DB

?

I'm worried about vm-exits that may take precedence over the #db trap. If we skip to save/restore dr6 for them, the value that the interception handler sees later on will be bogus. Or is this architecturally impossible?

Jan

Signature · 2 lines
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux
author
#4 lore raw
Quoted 4 lines · Jan Kiszka

I'm worried about vm-exits that may take precedence over the #db trap. If we skip to save/restore dr6 for them, the value that the interception handler sees later on will be bogus. Or is this architecturally impossible?

I think it's architectually impossible. Debug traps take effect after the instruction executed, so if we made it to that point, nothing else can cause the vmexit.

Signature · 1 line
error compiling committee.c: too many arguments to function