This patch implements guest debug support for KVM running on AMD hardware.

Signed-off-by: Joerg Roedel <[EMAIL PROTECTED]>
---
 arch/x86/kvm/svm.c |   37 ++++++++++++++++++++++++++++++++++---
 1 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 094a9c2..ebf75bf 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -919,7 +919,30 @@ static void svm_set_segment(struct kvm_vcpu *vcpu,
 static int svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg,
                           unsigned long dr7)
 {
-       return -EOPNOTSUPP;
+       struct vcpu_svm *svm = to_svm(vcpu);
+
+       if (vcpu->guest_debug.enabled) {
+               vcpu->guest_debug.singlestep = dbg->singlestep;
+               svm->vmcb->control.intercept_exceptions |= (1 << DB_VECTOR);
+       } else {
+               vcpu->guest_debug.singlestep = 0;
+               svm->vmcb->control.intercept_exceptions &= ~(1 << DB_VECTOR);
+       }
+
+       if (!vcpu->guest_debug.singlestep)
+               svm->vmcb->save.rflags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF);
+
+       svm->vmcb->save.dr7 = dr7;
+
+       return 0;
+}
+
+static void svm_guest_debug_pre(struct kvm_vcpu *vcpu)
+{
+       struct vcpu_svm *svm = to_svm(vcpu);
+
+       if (vcpu->guest_debug.singlestep)
+               svm->vmcb->save.rflags |= X86_EFLAGS_TF | X86_EFLAGS_RF;
 }
 
 static int svm_get_irq(struct kvm_vcpu *vcpu)
@@ -1019,6 +1042,12 @@ static int pf_interception(struct vcpu_svm *svm, struct 
kvm_run *kvm_run)
        return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code);
 }
 
+static int db_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+       kvm_run->exit_reason = KVM_EXIT_DEBUG;
+       return 0;
+}
+
 static int ud_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
 {
        int er;
@@ -1350,6 +1379,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm,
        [SVM_EXIT_WRITE_DR3]                    = emulate_on_interception,
        [SVM_EXIT_WRITE_DR5]                    = emulate_on_interception,
        [SVM_EXIT_WRITE_DR7]                    = emulate_on_interception,
+       [SVM_EXIT_EXCP_BASE + DB_VECTOR]        = db_interception,
        [SVM_EXIT_EXCP_BASE + UD_VECTOR]        = ud_interception,
        [SVM_EXIT_EXCP_BASE + PF_VECTOR]        = pf_interception,
        [SVM_EXIT_EXCP_BASE + NM_VECTOR]        = nm_interception,
@@ -1612,7 +1642,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct 
kvm_run *kvm_run)
        if (npt_enabled)
                svm->vmcb->save.cr3 = vcpu->arch.cr3;
 
-       if (svm->vmcb->save.dr7 & 0xff) {
+       if (!vcpu->guest_debug.enabled && svm->vmcb->save.dr7 & 0xff) {
                write_dr7(0);
                save_db_regs(svm->host_db_regs);
                load_db_regs(svm->db_regs);
@@ -1727,7 +1757,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct 
kvm_run *kvm_run)
 #endif
                );
 
-       if ((svm->vmcb->save.dr7 & 0xff))
+       if (!vcpu->guest_debug.enabled && (svm->vmcb->save.dr7 & 0xff))
                load_db_regs(svm->host_db_regs);
 
        vcpu->arch.cr2 = svm->vmcb->save.cr2;
@@ -1822,6 +1852,7 @@ static struct kvm_x86_ops svm_x86_ops = {
        .vcpu_decache = svm_vcpu_decache,
 
        .set_guest_debug = svm_guest_debug,
+       .guest_debug_pre = svm_guest_debug_pre,
        .get_msr = svm_get_msr,
        .set_msr = svm_set_msr,
        .get_segment_base = svm_get_segment_base,
-- 
1.5.3.7




-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to