aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@siemens.com>2014-01-04 12:47:16 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2014-01-17 04:22:10 -0500
commit73aaf249ee2287b4686ff079dcbdbbb658156e64 (patch)
tree6b32cc40f12e7a91827b77e5648e7bcff1e4efd6 /arch/x86/kvm
parent9926c9fdbdd54bb229fe6fdbd15ca3af2b8425ae (diff)
KVM: SVM: Fix reading of DR6
In contrast to VMX, SVM dose not automatically transfer DR6 into the VCPU's arch.dr6. So if we face a DR6 read, we must consult a new vendor hook to obtain the current value. And as SVM now picks the DR6 state from its VMCB, we also need a set callback in order to write updates of DR6 back. Fixes a regression of 020df0794f. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/svm.c15
-rw-r--r--arch/x86/kvm/vmx.c11
-rw-r--r--arch/x86/kvm/x86.c19
3 files changed, 43 insertions, 2 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index c7168a5cff1b..e81df8fce027 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1671,6 +1671,19 @@ static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd)
1671 mark_dirty(svm->vmcb, VMCB_ASID); 1671 mark_dirty(svm->vmcb, VMCB_ASID);
1672} 1672}
1673 1673
1674static u64 svm_get_dr6(struct kvm_vcpu *vcpu)
1675{
1676 return to_svm(vcpu)->vmcb->save.dr6;
1677}
1678
1679static void svm_set_dr6(struct kvm_vcpu *vcpu, unsigned long value)
1680{
1681 struct vcpu_svm *svm = to_svm(vcpu);
1682
1683 svm->vmcb->save.dr6 = value;
1684 mark_dirty(svm->vmcb, VMCB_DR);
1685}
1686
1674static void svm_set_dr7(struct kvm_vcpu *vcpu, unsigned long value) 1687static void svm_set_dr7(struct kvm_vcpu *vcpu, unsigned long value)
1675{ 1688{
1676 struct vcpu_svm *svm = to_svm(vcpu); 1689 struct vcpu_svm *svm = to_svm(vcpu);
@@ -4286,6 +4299,8 @@ static struct kvm_x86_ops svm_x86_ops = {
4286 .set_idt = svm_set_idt, 4299 .set_idt = svm_set_idt,
4287 .get_gdt = svm_get_gdt, 4300 .get_gdt = svm_get_gdt,
4288 .set_gdt = svm_set_gdt, 4301 .set_gdt = svm_set_gdt,
4302 .get_dr6 = svm_get_dr6,
4303 .set_dr6 = svm_set_dr6,
4289 .set_dr7 = svm_set_dr7, 4304 .set_dr7 = svm_set_dr7,
4290 .cache_reg = svm_cache_reg, 4305 .cache_reg = svm_cache_reg,
4291 .get_rflags = svm_get_rflags, 4306 .get_rflags = svm_get_rflags,
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 7661eb171936..79b360e4fed1 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -5149,6 +5149,15 @@ static int handle_dr(struct kvm_vcpu *vcpu)
5149 return 1; 5149 return 1;
5150} 5150}
5151 5151
5152static u64 vmx_get_dr6(struct kvm_vcpu *vcpu)
5153{
5154 return vcpu->arch.dr6;
5155}
5156
5157static void vmx_set_dr6(struct kvm_vcpu *vcpu, unsigned long val)
5158{
5159}
5160
5152static void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val) 5161static void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val)
5153{ 5162{
5154 vmcs_writel(GUEST_DR7, val); 5163 vmcs_writel(GUEST_DR7, val);
@@ -8556,6 +8565,8 @@ static struct kvm_x86_ops vmx_x86_ops = {
8556 .set_idt = vmx_set_idt, 8565 .set_idt = vmx_set_idt,
8557 .get_gdt = vmx_get_gdt, 8566 .get_gdt = vmx_get_gdt,
8558 .set_gdt = vmx_set_gdt, 8567 .set_gdt = vmx_set_gdt,
8568 .get_dr6 = vmx_get_dr6,
8569 .set_dr6 = vmx_set_dr6,
8559 .set_dr7 = vmx_set_dr7, 8570 .set_dr7 = vmx_set_dr7,
8560 .cache_reg = vmx_cache_reg, 8571 .cache_reg = vmx_cache_reg,
8561 .get_rflags = vmx_get_rflags, 8572 .get_rflags = vmx_get_rflags,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 59907c9a9d05..59b95b1a04dc 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -722,6 +722,12 @@ unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu)
722} 722}
723EXPORT_SYMBOL_GPL(kvm_get_cr8); 723EXPORT_SYMBOL_GPL(kvm_get_cr8);
724 724
725static void kvm_update_dr6(struct kvm_vcpu *vcpu)
726{
727 if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP))
728 kvm_x86_ops->set_dr6(vcpu, vcpu->arch.dr6);
729}
730
725static void kvm_update_dr7(struct kvm_vcpu *vcpu) 731static void kvm_update_dr7(struct kvm_vcpu *vcpu)
726{ 732{
727 unsigned long dr7; 733 unsigned long dr7;
@@ -750,6 +756,7 @@ static int __kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val)
750 if (val & 0xffffffff00000000ULL) 756 if (val & 0xffffffff00000000ULL)
751 return -1; /* #GP */ 757 return -1; /* #GP */
752 vcpu->arch.dr6 = (val & DR6_VOLATILE) | DR6_FIXED_1; 758 vcpu->arch.dr6 = (val & DR6_VOLATILE) | DR6_FIXED_1;
759 kvm_update_dr6(vcpu);
753 break; 760 break;
754 case 5: 761 case 5:
755 if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) 762 if (kvm_read_cr4_bits(vcpu, X86_CR4_DE))
@@ -791,7 +798,10 @@ static int _kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val)
791 return 1; 798 return 1;
792 /* fall through */ 799 /* fall through */
793 case 6: 800 case 6:
794 *val = vcpu->arch.dr6; 801 if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
802 *val = vcpu->arch.dr6;
803 else
804 *val = kvm_x86_ops->get_dr6(vcpu);
795 break; 805 break;
796 case 5: 806 case 5:
797 if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) 807 if (kvm_read_cr4_bits(vcpu, X86_CR4_DE))
@@ -2960,8 +2970,11 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
2960static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu, 2970static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu,
2961 struct kvm_debugregs *dbgregs) 2971 struct kvm_debugregs *dbgregs)
2962{ 2972{
2973 unsigned long val;
2974
2963 memcpy(dbgregs->db, vcpu->arch.db, sizeof(vcpu->arch.db)); 2975 memcpy(dbgregs->db, vcpu->arch.db, sizeof(vcpu->arch.db));
2964 dbgregs->dr6 = vcpu->arch.dr6; 2976 _kvm_get_dr(vcpu, 6, &val);
2977 dbgregs->dr6 = val;
2965 dbgregs->dr7 = vcpu->arch.dr7; 2978 dbgregs->dr7 = vcpu->arch.dr7;
2966 dbgregs->flags = 0; 2979 dbgregs->flags = 0;
2967 memset(&dbgregs->reserved, 0, sizeof(dbgregs->reserved)); 2980 memset(&dbgregs->reserved, 0, sizeof(dbgregs->reserved));
@@ -2975,6 +2988,7 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
2975 2988
2976 memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db)); 2989 memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db));
2977 vcpu->arch.dr6 = dbgregs->dr6; 2990 vcpu->arch.dr6 = dbgregs->dr6;
2991 kvm_update_dr6(vcpu);
2978 vcpu->arch.dr7 = dbgregs->dr7; 2992 vcpu->arch.dr7 = dbgregs->dr7;
2979 kvm_update_dr7(vcpu); 2993 kvm_update_dr7(vcpu);
2980 2994
@@ -6749,6 +6763,7 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu)
6749 6763
6750 memset(vcpu->arch.db, 0, sizeof(vcpu->arch.db)); 6764 memset(vcpu->arch.db, 0, sizeof(vcpu->arch.db));
6751 vcpu->arch.dr6 = DR6_FIXED_1; 6765 vcpu->arch.dr6 = DR6_FIXED_1;
6766 kvm_update_dr6(vcpu);
6752 vcpu->arch.dr7 = DR7_FIXED_1; 6767 vcpu->arch.dr7 = DR7_FIXED_1;
6753 kvm_update_dr7(vcpu); 6768 kvm_update_dr7(vcpu);
6754 6769