diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2015-11-10 03:14:39 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-11-10 06:06:24 -0500 |
commit | cbdb967af3d54993f5814f1cee0ed311a055377d (patch) | |
tree | b5774c71fc96cb10560267ca47655abde5ceb401 | |
parent | 54a20552e1eae07aa240fa370a0293e006b5faed (diff) |
KVM: svm: unconditionally intercept #DB
This is needed to avoid the possibility that the guest triggers
an infinite stream of #DB exceptions (CVE-2015-8104).
VMX is not affected: because it does not save DR6 in the VMCS,
it already intercepts #DB unconditionally.
Reported-by: Jan Beulich <jbeulich@suse.com>
Cc: stable@vger.kernel.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | arch/x86/kvm/svm.c | 14 |
1 files changed, 3 insertions, 11 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 183926483c3a..1cc1ffca0d8c 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -1020,6 +1020,7 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
1020 | set_exception_intercept(svm, UD_VECTOR); | 1020 | set_exception_intercept(svm, UD_VECTOR); |
1021 | set_exception_intercept(svm, MC_VECTOR); | 1021 | set_exception_intercept(svm, MC_VECTOR); |
1022 | set_exception_intercept(svm, AC_VECTOR); | 1022 | set_exception_intercept(svm, AC_VECTOR); |
1023 | set_exception_intercept(svm, DB_VECTOR); | ||
1023 | 1024 | ||
1024 | set_intercept(svm, INTERCEPT_INTR); | 1025 | set_intercept(svm, INTERCEPT_INTR); |
1025 | set_intercept(svm, INTERCEPT_NMI); | 1026 | set_intercept(svm, INTERCEPT_NMI); |
@@ -1554,20 +1555,13 @@ static void svm_set_segment(struct kvm_vcpu *vcpu, | |||
1554 | mark_dirty(svm->vmcb, VMCB_SEG); | 1555 | mark_dirty(svm->vmcb, VMCB_SEG); |
1555 | } | 1556 | } |
1556 | 1557 | ||
1557 | static void update_db_bp_intercept(struct kvm_vcpu *vcpu) | 1558 | static void update_bp_intercept(struct kvm_vcpu *vcpu) |
1558 | { | 1559 | { |
1559 | struct vcpu_svm *svm = to_svm(vcpu); | 1560 | struct vcpu_svm *svm = to_svm(vcpu); |
1560 | 1561 | ||
1561 | clr_exception_intercept(svm, DB_VECTOR); | ||
1562 | clr_exception_intercept(svm, BP_VECTOR); | 1562 | clr_exception_intercept(svm, BP_VECTOR); |
1563 | 1563 | ||
1564 | if (svm->nmi_singlestep) | ||
1565 | set_exception_intercept(svm, DB_VECTOR); | ||
1566 | |||
1567 | if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) { | 1564 | if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) { |
1568 | if (vcpu->guest_debug & | ||
1569 | (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) | ||
1570 | set_exception_intercept(svm, DB_VECTOR); | ||
1571 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) | 1565 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) |
1572 | set_exception_intercept(svm, BP_VECTOR); | 1566 | set_exception_intercept(svm, BP_VECTOR); |
1573 | } else | 1567 | } else |
@@ -1673,7 +1667,6 @@ static int db_interception(struct vcpu_svm *svm) | |||
1673 | if (!(svm->vcpu.guest_debug & KVM_GUESTDBG_SINGLESTEP)) | 1667 | if (!(svm->vcpu.guest_debug & KVM_GUESTDBG_SINGLESTEP)) |
1674 | svm->vmcb->save.rflags &= | 1668 | svm->vmcb->save.rflags &= |
1675 | ~(X86_EFLAGS_TF | X86_EFLAGS_RF); | 1669 | ~(X86_EFLAGS_TF | X86_EFLAGS_RF); |
1676 | update_db_bp_intercept(&svm->vcpu); | ||
1677 | } | 1670 | } |
1678 | 1671 | ||
1679 | if (svm->vcpu.guest_debug & | 1672 | if (svm->vcpu.guest_debug & |
@@ -3661,7 +3654,6 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu) | |||
3661 | */ | 3654 | */ |
3662 | svm->nmi_singlestep = true; | 3655 | svm->nmi_singlestep = true; |
3663 | svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF); | 3656 | svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF); |
3664 | update_db_bp_intercept(vcpu); | ||
3665 | } | 3657 | } |
3666 | 3658 | ||
3667 | static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr) | 3659 | static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr) |
@@ -4287,7 +4279,7 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
4287 | .vcpu_load = svm_vcpu_load, | 4279 | .vcpu_load = svm_vcpu_load, |
4288 | .vcpu_put = svm_vcpu_put, | 4280 | .vcpu_put = svm_vcpu_put, |
4289 | 4281 | ||
4290 | .update_db_bp_intercept = update_db_bp_intercept, | 4282 | .update_db_bp_intercept = update_bp_intercept, |
4291 | .get_msr = svm_get_msr, | 4283 | .get_msr = svm_get_msr, |
4292 | .set_msr = svm_set_msr, | 4284 | .set_msr = svm_set_msr, |
4293 | .get_segment_base = svm_get_segment_base, | 4285 | .get_segment_base = svm_get_segment_base, |