diff options
author | Nadav Amit <namit@cs.technion.ac.il> | 2015-04-01 20:10:37 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-04-08 04:47:03 -0400 |
commit | ae561edeb421fbc24f97df7af8607c14009c16b2 (patch) | |
tree | 183145db1f3add0737a21f2b8220e8ce8d03a345 /arch | |
parent | 58d269d8cccc53643f1a0900cfc0940e85ec9691 (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.h | 1 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 14 |
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 { | |||
340 | enum { | 340 | enum { |
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 | ||
345 | struct kvm_vcpu_arch { | 346 | struct 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 | } |
802 | EXPORT_SYMBOL_GPL(kvm_get_cr8); | 802 | EXPORT_SYMBOL_GPL(kvm_get_cr8); |
803 | 803 | ||
804 | static 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 | |||
804 | static void kvm_update_dr6(struct kvm_vcpu *vcpu) | 815 | static 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; |