diff options
| -rw-r--r-- | arch/x86/include/asm/kvm_host.h | 4 | ||||
| -rw-r--r-- | arch/x86/kvm/svm.c | 23 | ||||
| -rw-r--r-- | arch/x86/kvm/vmx.c | 14 | ||||
| -rw-r--r-- | arch/x86/kvm/x86.c | 26 |
4 files changed, 24 insertions, 43 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 0b902c98f279..c9a91368fc5e 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
| @@ -471,6 +471,7 @@ struct kvm_vcpu_arch { | |||
| 471 | unsigned long dr6; | 471 | unsigned long dr6; |
| 472 | unsigned long dr7; | 472 | unsigned long dr7; |
| 473 | unsigned long eff_db[KVM_NR_DB_REGS]; | 473 | unsigned long eff_db[KVM_NR_DB_REGS]; |
| 474 | unsigned long guest_debug_dr7; | ||
| 474 | 475 | ||
| 475 | u64 mcg_cap; | 476 | u64 mcg_cap; |
| 476 | u64 mcg_status; | 477 | u64 mcg_status; |
| @@ -647,8 +648,7 @@ struct kvm_x86_ops { | |||
| 647 | void (*vcpu_load)(struct kvm_vcpu *vcpu, int cpu); | 648 | void (*vcpu_load)(struct kvm_vcpu *vcpu, int cpu); |
| 648 | void (*vcpu_put)(struct kvm_vcpu *vcpu); | 649 | void (*vcpu_put)(struct kvm_vcpu *vcpu); |
| 649 | 650 | ||
| 650 | void (*set_guest_debug)(struct kvm_vcpu *vcpu, | 651 | void (*update_db_bp_intercept)(struct kvm_vcpu *vcpu); |
| 651 | struct kvm_guest_debug *dbg); | ||
| 652 | int (*get_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata); | 652 | int (*get_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata); |
| 653 | int (*set_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 data); | 653 | int (*set_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 data); |
| 654 | u64 (*get_segment_base)(struct kvm_vcpu *vcpu, int seg); | 654 | u64 (*get_segment_base)(struct kvm_vcpu *vcpu, int seg); |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 818fceb3091e..d017df3899ef 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
| @@ -1146,7 +1146,6 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
| 1146 | 1146 | ||
| 1147 | svm_set_efer(&svm->vcpu, 0); | 1147 | svm_set_efer(&svm->vcpu, 0); |
| 1148 | save->dr6 = 0xffff0ff0; | 1148 | save->dr6 = 0xffff0ff0; |
| 1149 | save->dr7 = 0x400; | ||
| 1150 | kvm_set_rflags(&svm->vcpu, 2); | 1149 | kvm_set_rflags(&svm->vcpu, 2); |
| 1151 | save->rip = 0x0000fff0; | 1150 | save->rip = 0x0000fff0; |
| 1152 | svm->vcpu.arch.regs[VCPU_REGS_RIP] = save->rip; | 1151 | svm->vcpu.arch.regs[VCPU_REGS_RIP] = save->rip; |
| @@ -1643,7 +1642,7 @@ static void svm_set_segment(struct kvm_vcpu *vcpu, | |||
| 1643 | mark_dirty(svm->vmcb, VMCB_SEG); | 1642 | mark_dirty(svm->vmcb, VMCB_SEG); |
| 1644 | } | 1643 | } |
| 1645 | 1644 | ||
| 1646 | static void update_db_intercept(struct kvm_vcpu *vcpu) | 1645 | static void update_db_bp_intercept(struct kvm_vcpu *vcpu) |
| 1647 | { | 1646 | { |
| 1648 | struct vcpu_svm *svm = to_svm(vcpu); | 1647 | struct vcpu_svm *svm = to_svm(vcpu); |
| 1649 | 1648 | ||
| @@ -1663,20 +1662,6 @@ static void update_db_intercept(struct kvm_vcpu *vcpu) | |||
| 1663 | vcpu->guest_debug = 0; | 1662 | vcpu->guest_debug = 0; |
| 1664 | } | 1663 | } |
| 1665 | 1664 | ||
| 1666 | static void svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg) | ||
| 1667 | { | ||
| 1668 | struct vcpu_svm *svm = to_svm(vcpu); | ||
| 1669 | |||
| 1670 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) | ||
| 1671 | svm->vmcb->save.dr7 = dbg->arch.debugreg[7]; | ||
| 1672 | else | ||
| 1673 | svm->vmcb->save.dr7 = vcpu->arch.dr7; | ||
| 1674 | |||
| 1675 | mark_dirty(svm->vmcb, VMCB_DR); | ||
| 1676 | |||
| 1677 | update_db_intercept(vcpu); | ||
| 1678 | } | ||
| 1679 | |||
| 1680 | static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd) | 1665 | static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd) |
| 1681 | { | 1666 | { |
| 1682 | if (sd->next_asid > sd->max_asid) { | 1667 | if (sd->next_asid > sd->max_asid) { |
| @@ -1748,7 +1733,7 @@ static int db_interception(struct vcpu_svm *svm) | |||
| 1748 | if (!(svm->vcpu.guest_debug & KVM_GUESTDBG_SINGLESTEP)) | 1733 | if (!(svm->vcpu.guest_debug & KVM_GUESTDBG_SINGLESTEP)) |
| 1749 | svm->vmcb->save.rflags &= | 1734 | svm->vmcb->save.rflags &= |
| 1750 | ~(X86_EFLAGS_TF | X86_EFLAGS_RF); | 1735 | ~(X86_EFLAGS_TF | X86_EFLAGS_RF); |
| 1751 | update_db_intercept(&svm->vcpu); | 1736 | update_db_bp_intercept(&svm->vcpu); |
| 1752 | } | 1737 | } |
| 1753 | 1738 | ||
| 1754 | if (svm->vcpu.guest_debug & | 1739 | if (svm->vcpu.guest_debug & |
| @@ -3659,7 +3644,7 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu) | |||
| 3659 | */ | 3644 | */ |
| 3660 | svm->nmi_singlestep = true; | 3645 | svm->nmi_singlestep = true; |
| 3661 | svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF); | 3646 | svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF); |
| 3662 | update_db_intercept(vcpu); | 3647 | update_db_bp_intercept(vcpu); |
| 3663 | } | 3648 | } |
| 3664 | 3649 | ||
| 3665 | static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr) | 3650 | static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr) |
| @@ -4253,7 +4238,7 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
| 4253 | .vcpu_load = svm_vcpu_load, | 4238 | .vcpu_load = svm_vcpu_load, |
| 4254 | .vcpu_put = svm_vcpu_put, | 4239 | .vcpu_put = svm_vcpu_put, |
| 4255 | 4240 | ||
| 4256 | .set_guest_debug = svm_guest_debug, | 4241 | .update_db_bp_intercept = update_db_bp_intercept, |
| 4257 | .get_msr = svm_get_msr, | 4242 | .get_msr = svm_get_msr, |
| 4258 | .set_msr = svm_set_msr, | 4243 | .set_msr = svm_set_msr, |
| 4259 | .get_segment_base = svm_get_segment_base, | 4244 | .get_segment_base = svm_get_segment_base, |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 30bcb953afee..5d46c905e06f 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
| @@ -2288,16 +2288,6 @@ static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg) | |||
| 2288 | } | 2288 | } |
| 2289 | } | 2289 | } |
| 2290 | 2290 | ||
| 2291 | static void set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg) | ||
| 2292 | { | ||
| 2293 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) | ||
| 2294 | vmcs_writel(GUEST_DR7, dbg->arch.debugreg[7]); | ||
| 2295 | else | ||
| 2296 | vmcs_writel(GUEST_DR7, vcpu->arch.dr7); | ||
| 2297 | |||
| 2298 | update_exception_bitmap(vcpu); | ||
| 2299 | } | ||
| 2300 | |||
| 2301 | static __init int cpu_has_kvm_support(void) | 2291 | static __init int cpu_has_kvm_support(void) |
| 2302 | { | 2292 | { |
| 2303 | return cpu_has_vmx(); | 2293 | return cpu_has_vmx(); |
| @@ -3960,8 +3950,6 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu) | |||
| 3960 | kvm_rip_write(vcpu, 0); | 3950 | kvm_rip_write(vcpu, 0); |
| 3961 | kvm_register_write(vcpu, VCPU_REGS_RSP, 0); | 3951 | kvm_register_write(vcpu, VCPU_REGS_RSP, 0); |
| 3962 | 3952 | ||
| 3963 | vmcs_writel(GUEST_DR7, 0x400); | ||
| 3964 | |||
| 3965 | vmcs_writel(GUEST_GDTR_BASE, 0); | 3953 | vmcs_writel(GUEST_GDTR_BASE, 0); |
| 3966 | vmcs_write32(GUEST_GDTR_LIMIT, 0xffff); | 3954 | vmcs_write32(GUEST_GDTR_LIMIT, 0xffff); |
| 3967 | 3955 | ||
| @@ -7237,7 +7225,7 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
| 7237 | .vcpu_load = vmx_vcpu_load, | 7225 | .vcpu_load = vmx_vcpu_load, |
| 7238 | .vcpu_put = vmx_vcpu_put, | 7226 | .vcpu_put = vmx_vcpu_put, |
| 7239 | 7227 | ||
| 7240 | .set_guest_debug = set_guest_debug, | 7228 | .update_db_bp_intercept = update_exception_bitmap, |
| 7241 | .get_msr = vmx_get_msr, | 7229 | .get_msr = vmx_get_msr, |
| 7242 | .set_msr = vmx_set_msr, | 7230 | .set_msr = vmx_set_msr, |
| 7243 | .get_segment_base = vmx_get_segment_base, | 7231 | .get_segment_base = vmx_get_segment_base, |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 7d44204c6041..b16d4a5bfa41 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -692,6 +692,18 @@ unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu) | |||
| 692 | } | 692 | } |
| 693 | EXPORT_SYMBOL_GPL(kvm_get_cr8); | 693 | EXPORT_SYMBOL_GPL(kvm_get_cr8); |
| 694 | 694 | ||
| 695 | static void kvm_update_dr7(struct kvm_vcpu *vcpu) | ||
| 696 | { | ||
| 697 | unsigned long dr7; | ||
| 698 | |||
| 699 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) | ||
| 700 | dr7 = vcpu->arch.guest_debug_dr7; | ||
| 701 | else | ||
| 702 | dr7 = vcpu->arch.dr7; | ||
| 703 | kvm_x86_ops->set_dr7(vcpu, dr7); | ||
| 704 | vcpu->arch.switch_db_regs = (dr7 & DR7_BP_EN_MASK); | ||
| 705 | } | ||
| 706 | |||
| 695 | static int __kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val) | 707 | static int __kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val) |
| 696 | { | 708 | { |
| 697 | switch (dr) { | 709 | switch (dr) { |
| @@ -717,10 +729,7 @@ static int __kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val) | |||
| 717 | if (val & 0xffffffff00000000ULL) | 729 | if (val & 0xffffffff00000000ULL) |
| 718 | return -1; /* #GP */ | 730 | return -1; /* #GP */ |
| 719 | vcpu->arch.dr7 = (val & DR7_VOLATILE) | DR7_FIXED_1; | 731 | vcpu->arch.dr7 = (val & DR7_VOLATILE) | DR7_FIXED_1; |
| 720 | if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) { | 732 | kvm_update_dr7(vcpu); |
| 721 | kvm_x86_ops->set_dr7(vcpu, vcpu->arch.dr7); | ||
| 722 | vcpu->arch.switch_db_regs = (val & DR7_BP_EN_MASK); | ||
| 723 | } | ||
| 724 | break; | 733 | break; |
| 725 | } | 734 | } |
| 726 | 735 | ||
| @@ -5851,13 +5860,12 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, | |||
| 5851 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) { | 5860 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) { |
| 5852 | for (i = 0; i < KVM_NR_DB_REGS; ++i) | 5861 | for (i = 0; i < KVM_NR_DB_REGS; ++i) |
| 5853 | vcpu->arch.eff_db[i] = dbg->arch.debugreg[i]; | 5862 | vcpu->arch.eff_db[i] = dbg->arch.debugreg[i]; |
| 5854 | vcpu->arch.switch_db_regs = | 5863 | vcpu->arch.guest_debug_dr7 = dbg->arch.debugreg[7]; |
| 5855 | (dbg->arch.debugreg[7] & DR7_BP_EN_MASK); | ||
| 5856 | } else { | 5864 | } else { |
| 5857 | for (i = 0; i < KVM_NR_DB_REGS; i++) | 5865 | for (i = 0; i < KVM_NR_DB_REGS; i++) |
| 5858 | vcpu->arch.eff_db[i] = vcpu->arch.db[i]; | 5866 | vcpu->arch.eff_db[i] = vcpu->arch.db[i]; |
| 5859 | vcpu->arch.switch_db_regs = (vcpu->arch.dr7 & DR7_BP_EN_MASK); | ||
| 5860 | } | 5867 | } |
| 5868 | kvm_update_dr7(vcpu); | ||
| 5861 | 5869 | ||
| 5862 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) | 5870 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) |
| 5863 | vcpu->arch.singlestep_rip = kvm_rip_read(vcpu) + | 5871 | vcpu->arch.singlestep_rip = kvm_rip_read(vcpu) + |
| @@ -5869,7 +5877,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, | |||
| 5869 | */ | 5877 | */ |
| 5870 | kvm_set_rflags(vcpu, rflags); | 5878 | kvm_set_rflags(vcpu, rflags); |
| 5871 | 5879 | ||
| 5872 | kvm_x86_ops->set_guest_debug(vcpu, dbg); | 5880 | kvm_x86_ops->update_db_bp_intercept(vcpu); |
| 5873 | 5881 | ||
| 5874 | r = 0; | 5882 | r = 0; |
| 5875 | 5883 | ||
| @@ -6045,10 +6053,10 @@ int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu) | |||
| 6045 | vcpu->arch.nmi_pending = 0; | 6053 | vcpu->arch.nmi_pending = 0; |
| 6046 | vcpu->arch.nmi_injected = false; | 6054 | vcpu->arch.nmi_injected = false; |
| 6047 | 6055 | ||
| 6048 | vcpu->arch.switch_db_regs = 0; | ||
| 6049 | memset(vcpu->arch.db, 0, sizeof(vcpu->arch.db)); | 6056 | memset(vcpu->arch.db, 0, sizeof(vcpu->arch.db)); |
| 6050 | vcpu->arch.dr6 = DR6_FIXED_1; | 6057 | vcpu->arch.dr6 = DR6_FIXED_1; |
| 6051 | vcpu->arch.dr7 = DR7_FIXED_1; | 6058 | vcpu->arch.dr7 = DR7_FIXED_1; |
| 6059 | kvm_update_dr7(vcpu); | ||
| 6052 | 6060 | ||
| 6053 | kvm_make_request(KVM_REQ_EVENT, vcpu); | 6061 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
| 6054 | vcpu->arch.apf.msr_val = 0; | 6062 | vcpu->arch.apf.msr_val = 0; |
