aboutsummaryrefslogtreecommitdiff
path: root/virt
diff options
context:
space:
mode:
authorAndre Przywara2018-04-17 11:23:49 +0100
committerMarc Zyngier2018-04-17 12:57:11 +0100
commitbf9a41377d14f565764022470e14aae72559589a (patch)
tree71960b60a82f84ceca0ff5e2f59c47cab23919d9 /virt
parent165d102905691891f85cb90736c25150b7b25d29 (diff)
KVM: arm/arm64: vgic: Kick new VCPU on interrupt migration
When vgic_prune_ap_list() finds an interrupt that needs to be migrated to a new VCPU, we should notify this VCPU of the pending interrupt, since it requires immediate action. Kick this VCPU once we have added the new IRQ to the list, but only after dropping the locks. Reported-by: Stefano Stabellini <sstabellini@kernel.org> Reviewed-by: Christoffer Dall <christoffer.dall@arm.com> Signed-off-by: Andre Przywara <andre.przywara@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/arm/vgic/vgic.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
index e74baec76361..4b6d72939c42 100644
--- a/virt/kvm/arm/vgic/vgic.c
+++ b/virt/kvm/arm/vgic/vgic.c
@@ -594,6 +594,7 @@ retry:
list_for_each_entry_safe(irq, tmp, &vgic_cpu->ap_list_head, ap_list) {
struct kvm_vcpu *target_vcpu, *vcpuA, *vcpuB;
+ bool target_vcpu_needs_kick = false;
spin_lock(&irq->irq_lock);
@@ -664,11 +665,18 @@ retry:
list_del(&irq->ap_list);
irq->vcpu = target_vcpu;
list_add_tail(&irq->ap_list, &new_cpu->ap_list_head);
+ target_vcpu_needs_kick = true;
}
spin_unlock(&irq->irq_lock);
spin_unlock(&vcpuB->arch.vgic_cpu.ap_list_lock);
spin_unlock_irqrestore(&vcpuA->arch.vgic_cpu.ap_list_lock, flags);
+
+ if (target_vcpu_needs_kick) {
+ kvm_make_request(KVM_REQ_IRQ_PENDING, target_vcpu);
+ kvm_vcpu_kick(target_vcpu);
+ }
+
goto retry;
}