diff options
author | Radim Krčmář <rkrcmar@redhat.com> | 2015-02-27 10:32:38 -0500 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2015-03-02 17:04:40 -0500 |
commit | f563db4bdb8ef5ea73d0f5ea2b20384c10fbd617 (patch) | |
tree | 1536e267fe320ec62c2b6b788a88c8c831a37f3f /arch/x86 | |
parent | 4ff6f8e61eb7f96d3ca535c6d240f863ccd6fb7d (diff) |
KVM: SVM: fix interrupt injection (apic->isr_count always 0)
In commit b4eef9b36db4, we started to use hwapic_isr_update() != NULL
instead of kvm_apic_vid_enabled(vcpu->kvm). This didn't work because
SVM had it defined and "apicv" path in apic_{set,clear}_isr() does not
change apic->isr_count, because it should always be 1. The initial
value of apic->isr_count was based on kvm_apic_vid_enabled(vcpu->kvm),
which is always 0 for SVM, so KVM could have injected interrupts when it
shouldn't.
Fix it by implicitly setting SVM's hwapic_isr_update to NULL and make the
initial isr_count depend on hwapic_isr_update() for good measure.
Fixes: b4eef9b36db4 ("kvm: x86: vmx: NULL out hwapic_isr_update() in case of !enable_apicv")
Reported-and-tested-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kvm/lapic.c | 4 | ||||
-rw-r--r-- | arch/x86/kvm/svm.c | 6 |
2 files changed, 2 insertions, 8 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index e55b5fc344eb..bd4e34de24c7 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -1572,7 +1572,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) | |||
1572 | apic_set_reg(apic, APIC_TMR + 0x10 * i, 0); | 1572 | apic_set_reg(apic, APIC_TMR + 0x10 * i, 0); |
1573 | } | 1573 | } |
1574 | apic->irr_pending = kvm_apic_vid_enabled(vcpu->kvm); | 1574 | apic->irr_pending = kvm_apic_vid_enabled(vcpu->kvm); |
1575 | apic->isr_count = kvm_apic_vid_enabled(vcpu->kvm); | 1575 | apic->isr_count = kvm_x86_ops->hwapic_isr_update ? 1 : 0; |
1576 | apic->highest_isr_cache = -1; | 1576 | apic->highest_isr_cache = -1; |
1577 | update_divide_count(apic); | 1577 | update_divide_count(apic); |
1578 | atomic_set(&apic->lapic_timer.pending, 0); | 1578 | atomic_set(&apic->lapic_timer.pending, 0); |
@@ -1782,7 +1782,7 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu, | |||
1782 | update_divide_count(apic); | 1782 | update_divide_count(apic); |
1783 | start_apic_timer(apic); | 1783 | start_apic_timer(apic); |
1784 | apic->irr_pending = true; | 1784 | apic->irr_pending = true; |
1785 | apic->isr_count = kvm_apic_vid_enabled(vcpu->kvm) ? | 1785 | apic->isr_count = kvm_x86_ops->hwapic_isr_update ? |
1786 | 1 : count_vectors(apic->regs + APIC_ISR); | 1786 | 1 : count_vectors(apic->regs + APIC_ISR); |
1787 | apic->highest_isr_cache = -1; | 1787 | apic->highest_isr_cache = -1; |
1788 | if (kvm_x86_ops->hwapic_irr_update) | 1788 | if (kvm_x86_ops->hwapic_irr_update) |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index d319e0c24758..cc618c882f90 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -3649,11 +3649,6 @@ static void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap) | |||
3649 | return; | 3649 | return; |
3650 | } | 3650 | } |
3651 | 3651 | ||
3652 | static void svm_hwapic_isr_update(struct kvm *kvm, int isr) | ||
3653 | { | ||
3654 | return; | ||
3655 | } | ||
3656 | |||
3657 | static void svm_sync_pir_to_irr(struct kvm_vcpu *vcpu) | 3652 | static void svm_sync_pir_to_irr(struct kvm_vcpu *vcpu) |
3658 | { | 3653 | { |
3659 | return; | 3654 | return; |
@@ -4403,7 +4398,6 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
4403 | .set_virtual_x2apic_mode = svm_set_virtual_x2apic_mode, | 4398 | .set_virtual_x2apic_mode = svm_set_virtual_x2apic_mode, |
4404 | .vm_has_apicv = svm_vm_has_apicv, | 4399 | .vm_has_apicv = svm_vm_has_apicv, |
4405 | .load_eoi_exitmap = svm_load_eoi_exitmap, | 4400 | .load_eoi_exitmap = svm_load_eoi_exitmap, |
4406 | .hwapic_isr_update = svm_hwapic_isr_update, | ||
4407 | .sync_pir_to_irr = svm_sync_pir_to_irr, | 4401 | .sync_pir_to_irr = svm_sync_pir_to_irr, |
4408 | 4402 | ||
4409 | .set_tss_addr = svm_set_tss_addr, | 4403 | .set_tss_addr = svm_set_tss_addr, |