aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorNadav Amit <namit@cs.technion.ac.il>2015-04-01 20:10:37 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2015-04-08 04:47:03 -0400
commitae561edeb421fbc24f97df7af8607c14009c16b2 (patch)
tree183145db1f3add0737a21f2b8220e8ce8d03a345 /arch
parent58d269d8cccc53643f1a0900cfc0940e85ec9691 (diff)
KVM: x86: DR0-DR3 are not clear on reset
DR0-DR3 are not cleared as they should during reset and when they are set from userspace. It appears to be caused by c77fb5fe6f03 ("KVM: x86: Allow the guest to run with dirty debug registers"). Force their reload on these situations. Signed-off-by: Nadav Amit <namit@cs.technion.ac.il> Message-Id: <1427933438-12782-4-git-send-email-namit@cs.technion.ac.il> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/kvm_host.h1
-rw-r--r--arch/x86/kvm/x86.c14
2 files changed, 15 insertions, 0 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index d0cfdb08b4c2..9f1d66e2e3b5 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -340,6 +340,7 @@ struct kvm_pmu {
340enum { 340enum {
341 KVM_DEBUGREG_BP_ENABLED = 1, 341 KVM_DEBUGREG_BP_ENABLED = 1,
342 KVM_DEBUGREG_WONT_EXIT = 2, 342 KVM_DEBUGREG_WONT_EXIT = 2,
343 KVM_DEBUGREG_RELOAD = 4,
343}; 344};
344 345
345struct kvm_vcpu_arch { 346struct kvm_vcpu_arch {
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index f7a78c62ab87..ad3809df7d0a 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -801,6 +801,17 @@ unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu)
801} 801}
802EXPORT_SYMBOL_GPL(kvm_get_cr8); 802EXPORT_SYMBOL_GPL(kvm_get_cr8);
803 803
804static void kvm_update_dr0123(struct kvm_vcpu *vcpu)
805{
806 int i;
807
808 if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) {
809 for (i = 0; i < KVM_NR_DB_REGS; i++)
810 vcpu->arch.eff_db[i] = vcpu->arch.db[i];
811 vcpu->arch.switch_db_regs |= KVM_DEBUGREG_RELOAD;
812 }
813}
814
804static void kvm_update_dr6(struct kvm_vcpu *vcpu) 815static void kvm_update_dr6(struct kvm_vcpu *vcpu)
805{ 816{
806 if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) 817 if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP))
@@ -3150,6 +3161,7 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
3150 return -EINVAL; 3161 return -EINVAL;
3151 3162
3152 memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db)); 3163 memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db));
3164 kvm_update_dr0123(vcpu);
3153 vcpu->arch.dr6 = dbgregs->dr6; 3165 vcpu->arch.dr6 = dbgregs->dr6;
3154 kvm_update_dr6(vcpu); 3166 kvm_update_dr6(vcpu);
3155 vcpu->arch.dr7 = dbgregs->dr7; 3167 vcpu->arch.dr7 = dbgregs->dr7;
@@ -6323,6 +6335,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
6323 set_debugreg(vcpu->arch.eff_db[2], 2); 6335 set_debugreg(vcpu->arch.eff_db[2], 2);
6324 set_debugreg(vcpu->arch.eff_db[3], 3); 6336 set_debugreg(vcpu->arch.eff_db[3], 3);
6325 set_debugreg(vcpu->arch.dr6, 6); 6337 set_debugreg(vcpu->arch.dr6, 6);
6338 vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD;
6326 } 6339 }
6327 6340
6328 trace_kvm_entry(vcpu->vcpu_id); 6341 trace_kvm_entry(vcpu->vcpu_id);
@@ -7104,6 +7117,7 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu)
7104 kvm_clear_exception_queue(vcpu); 7117 kvm_clear_exception_queue(vcpu);
7105 7118
7106 memset(vcpu->arch.db, 0, sizeof(vcpu->arch.db)); 7119 memset(vcpu->arch.db, 0, sizeof(vcpu->arch.db));
7120 kvm_update_dr0123(vcpu);
7107 vcpu->arch.dr6 = DR6_INIT; 7121 vcpu->arch.dr6 = DR6_INIT;
7108 kvm_update_dr6(vcpu); 7122 kvm_update_dr6(vcpu);
7109 vcpu->arch.dr7 = DR7_FIXED_1; 7123 vcpu->arch.dr7 = DR7_FIXED_1;