summaryrefslogtreecommitdiff
path: root/virt/kvm/arm/vgic/vgic.c
diff options
context:
space:
mode:
authorChristoffer Dall <cdall@linaro.org>2017-05-06 20:01:24 +0200
committerChristoffer Dall <cdall@linaro.org>2017-05-23 12:48:22 +0200
commitabd7229626b9339e378a8cfcdebe0c0943b06a7f (patch)
treee50cebd5e9f2e9386da1b39e7bfbc6138cd72b4b /virt/kvm/arm/vgic/vgic.c
parent3197191e5525ea7cf8b3fdd9afc75ab5779d21fd (diff)
KVM: arm/arm64: Simplify active_change_prepare and plug race
We don't need to stop a specific VCPU when changing the active state, because private IRQs can only be modified by a running VCPU for the VCPU itself and it is therefore already stopped. However, it is also possible for two VCPUs to be modifying the active state of SPIs at the same time, which can cause the thread being stuck in the loop that checks other VCPU threads for a potentially very long time, or to modify the active state of a running VCPU. Fix this by serializing all accesses to setting and clearing the active state of interrupts using the KVM mutex. Reported-by: Andrew Jones <drjones@redhat.com> Signed-off-by: Christoffer Dall <cdall@linaro.org> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'virt/kvm/arm/vgic/vgic.c')
-rw-r--r--virt/kvm/arm/vgic/vgic.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
index 83b24d20ff8f..aea080a2c443 100644
--- a/virt/kvm/arm/vgic/vgic.c
+++ b/virt/kvm/arm/vgic/vgic.c
@@ -35,11 +35,12 @@ struct vgic_global kvm_vgic_global_state __ro_after_init = {
/*
* Locking order is always:
- * its->cmd_lock (mutex)
- * its->its_lock (mutex)
- * vgic_cpu->ap_list_lock
- * kvm->lpi_list_lock
- * vgic_irq->irq_lock
+ * kvm->lock (mutex)
+ * its->cmd_lock (mutex)
+ * its->its_lock (mutex)
+ * vgic_cpu->ap_list_lock
+ * kvm->lpi_list_lock
+ * vgic_irq->irq_lock
*
* If you need to take multiple locks, always take the upper lock first,
* then the lower ones, e.g. first take the its_lock, then the irq_lock.