Merge tag 'drm-fixes-2020-07-10' of git://anongit.freedesktop.org/drm/drm
[linux-2.6-microblaze.git] / drivers / irqchip / irq-gic-v3-its.c
index cd685f5..beac4ca 100644 (file)
@@ -3797,10 +3797,10 @@ static void its_wait_vpt_parse_complete(void)
        if (!gic_rdists->has_vpend_valid_dirty)
                return;
 
-       WARN_ON_ONCE(readq_relaxed_poll_timeout(vlpi_base + GICR_VPENDBASER,
-                                               val,
-                                               !(val & GICR_VPENDBASER_Dirty),
-                                               10, 500));
+       WARN_ON_ONCE(readq_relaxed_poll_timeout_atomic(vlpi_base + GICR_VPENDBASER,
+                                                      val,
+                                                      !(val & GICR_VPENDBASER_Dirty),
+                                                      10, 500));
 }
 
 static void its_vpe_schedule(struct its_vpe *vpe)
@@ -4054,16 +4054,24 @@ static void its_vpe_4_1_deschedule(struct its_vpe *vpe,
        u64 val;
 
        if (info->req_db) {
+               unsigned long flags;
+
                /*
                 * vPE is going to block: make the vPE non-resident with
                 * PendingLast clear and DB set. The GIC guarantees that if
                 * we read-back PendingLast clear, then a doorbell will be
                 * delivered when an interrupt comes.
+                *
+                * Note the locking to deal with the concurrent update of
+                * pending_last from the doorbell interrupt handler that can
+                * run concurrently.
                 */
+               raw_spin_lock_irqsave(&vpe->vpe_lock, flags);
                val = its_clear_vpend_valid(vlpi_base,
                                            GICR_VPENDBASER_PendingLast,
                                            GICR_VPENDBASER_4_1_DB);
                vpe->pending_last = !!(val & GICR_VPENDBASER_PendingLast);
+               raw_spin_unlock_irqrestore(&vpe->vpe_lock, flags);
        } else {
                /*
                 * We're not blocking, so just make the vPE non-resident