KVM: SVM: fix interrupt injection (apic->isr_count always 0)
PATCH v2 1/1 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.
---
v2: set hwapic_isr_update to NULL implicitly [Paolo]
arch/x86/kvm/lapic.c | 4 ++-- arch/x86/kvm/svm.c | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-)
arch/x86/kvm/lapic.c +2 -2
@@ -1572,7 +1572,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)apic_set_reg (apic,APIC_TMR +0x10 * i,0 ); } apic->irr_pending =kvm_apic_vid_enabled (vcpu->kvm); - apic->isr_count =kvm_apic_vid_enabled (vcpu->kvm); + apic->isr_count = kvm_x86_ops->hwapic_isr_update ?1 :0 ; apic->highest_isr_cache =-1 ;update_divide_count (apic);atomic_set (&apic->lapic_timer.pending,0 );
@@ -1782,7 +1782,7 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu,update_divide_count (apic);start_apic_timer (apic); apic->irr_pending = true; - apic->isr_count =kvm_apic_vid_enabled (vcpu->kvm) ? + apic->isr_count = kvm_x86_ops->hwapic_isr_update ?1 :count_vectors (apic->regs +APIC_ISR ); apic->highest_isr_cache =-1 ;if (kvm_x86_ops->hwapic_irr_update)
arch/x86/kvm/svm.c +0 -6
@@ -3649,11 +3649,6 @@ static void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)return ; } -static void svm_hwapic_isr_update (struct kvm *kvm,int isr) -{ -return ; -} -static void svm_sync_pir_to_irr (struct kvm_vcpu *vcpu) {return ;
@@ -4403,7 +4398,6 @@ static struct kvm_x86_ops svm_x86_ops = { .set_virtual_x2apic_mode = svm_set_virtual_x2apic_mode, .vm_has_apicv = svm_vm_has_apicv, .load_eoi_exitmap = svm_load_eoi_exitmap, - .hwapic_isr_update = svm_hwapic_isr_update, .sync_pir_to_irr = svm_sync_pir_to_irr, .set_tss_addr = svm_set_tss_addr,
Signature · 1 line
2.3.0
Marcelo Tosatti
AppliedQuoted 14 lines · Radim Krčmář
In commit
b4eef9b36db4, we started to usehwapic_isr_update()!= NULL instead ofkvm_apic_vid_enabled(vcpu->kvm). This didn't work because SVM had it defined and "apicv" path in apic_{set,clear}_isr() does not changeapic->isr_count, because it should always be 1. The initial value ofapic->isr_countwas based onkvm_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_updateto NULL and make the initialisr_countdepend onhwapic_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 <[email protected]>Signed-off-by Radim Krčmář <[email protected]>
Quoted 6 lines
---
v2: sethwapic_isr_updateto NULL implicitly [Paolo]arch/x86/kvm/lapic.c | 4 ++-- arch/x86/kvm/svm.c | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-)
Applied, thanks.