diff mbox

KVM: x86: Mask DR7 correctly on task-switch while debugging

Message ID 1429445904-5105-1-git-send-email-namit@cs.technion.ac.il (mailing list archive)
State New, archived
Headers show

Commit Message

Nadav Amit April 19, 2015, 12:18 p.m. UTC
If the host sets hardware breakpoints to debug the guest, and a task-switch
occurs in the guest, the architectural DR7 will not be updated. The effective
DR7 would be updated instead.

This fix uses the standard DR setting mechanism instead of the one that was
previously used. As a bonus, the update of DR7 will now be effective for AMD as
well.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
---
 arch/x86/kvm/vmx.c | 3 ---
 arch/x86/kvm/x86.c | 3 +++
 2 files changed, 3 insertions(+), 3 deletions(-)

Comments

Paolo Bonzini April 19, 2015, 5:08 p.m. UTC | #1
On 19/04/2015 14:18, Nadav Amit wrote:
> If the host sets hardware breakpoints to debug the guest, and a task-switch
> occurs in the guest, the architectural DR7 will not be updated. The effective
> DR7 would be updated instead.
> 
> This fix uses the standard DR setting mechanism instead of the one that was
> previously used. As a bonus, the update of DR7 will now be effective for AMD as
> well.

Is there a reason not to do it in emulate.c instead?

Paolo

> Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
> ---
>  arch/x86/kvm/vmx.c | 3 ---
>  arch/x86/kvm/x86.c | 3 +++
>  2 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index f7a0a7f..8f731c0 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -5703,9 +5703,6 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
>  		return 0;
>  	}
>  
> -	/* clear all local breakpoint enable flags */
> -	vmcs_writel(GUEST_DR7, vmcs_readl(GUEST_DR7) & ~0x155);
> -
>  	/*
>  	 * TODO: What about debug traps on tss switch?
>  	 *       Are we supposed to inject them and update dr6?
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 2046be4..a170c35 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -6816,6 +6816,9 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int idt_index,
>  
>  	kvm_rip_write(vcpu, ctxt->eip);
>  	kvm_set_rflags(vcpu, ctxt->eflags);
> +	ret = __kvm_set_dr(vcpu, 7, vcpu->arch.dr7 & ~(DR_LOCAL_ENABLE_MASK |
> +						       DR_LOCAL_SLOWDOWN));
> +	WARN_ON(ret != 0);
>  	kvm_make_request(KVM_REQ_EVENT, vcpu);
>  	return EMULATE_DONE;
>  }
> 
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Nadav Amit April 19, 2015, 5:13 p.m. UTC | #2
Paolo Bonzini <pbonzini@redhat.com> wrote:

> 
> 
> On 19/04/2015 14:18, Nadav Amit wrote:
>> If the host sets hardware breakpoints to debug the guest, and a task-switch
>> occurs in the guest, the architectural DR7 will not be updated. The effective
>> DR7 would be updated instead.
>> 
>> This fix uses the standard DR setting mechanism instead of the one that was
>> previously used. As a bonus, the update of DR7 will now be effective for AMD as
>> well.
> 
> Is there a reason not to do it in emulate.c instead?

Not that I can think of. I will make a new version.

Nadav--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index f7a0a7f..8f731c0 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -5703,9 +5703,6 @@  static int handle_task_switch(struct kvm_vcpu *vcpu)
 		return 0;
 	}
 
-	/* clear all local breakpoint enable flags */
-	vmcs_writel(GUEST_DR7, vmcs_readl(GUEST_DR7) & ~0x155);
-
 	/*
 	 * TODO: What about debug traps on tss switch?
 	 *       Are we supposed to inject them and update dr6?
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 2046be4..a170c35 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6816,6 +6816,9 @@  int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int idt_index,
 
 	kvm_rip_write(vcpu, ctxt->eip);
 	kvm_set_rflags(vcpu, ctxt->eflags);
+	ret = __kvm_set_dr(vcpu, 7, vcpu->arch.dr7 & ~(DR_LOCAL_ENABLE_MASK |
+						       DR_LOCAL_SLOWDOWN));
+	WARN_ON(ret != 0);
 	kvm_make_request(KVM_REQ_EVENT, vcpu);
 	return EMULATE_DONE;
 }