From: Jan Kiszka <[email protected]>

We were missing memory barriers before updating the lockless ring buffer
of pending interrupts, both on producer and consumer side. At the same
time, we can remove a barrier that is already provided implicitly by
spin_unlock on ARM.

Reported-by: Peng Fan <[email protected]>
Signed-off-by: Jan Kiszka <[email protected]>
---
 hypervisor/arch/arm-common/irqchip.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/hypervisor/arch/arm-common/irqchip.c 
b/hypervisor/arch/arm-common/irqchip.c
index 1c881b64..d0bd50c6 100644
--- a/hypervisor/arch/arm-common/irqchip.c
+++ b/hypervisor/arch/arm-common/irqchip.c
@@ -246,14 +246,18 @@ void irqchip_set_pending(struct public_per_cpu 
*cpu_public, u16 irq_id)
        if (new_tail != pending->head) {
                pending->irqs[pending->tail] = irq_id;
                pending->sender[pending->tail] = sender;
-               pending->tail = new_tail;
                /*
-                * Make the change to pending_irqs.tail visible before the
-                * caller sends SGI_INJECT.
+                * Make the entry content is visible before updating the tail
+                * index.
                 */
                memory_barrier();
+               pending->tail = new_tail;
        }

+       /*
+        * The unlock has memory barrier semantic on ARM v7 and v8. Therefore
+        * the change to tail will be visible when sending SGI_INJECT later on.
+        */
        spin_unlock(&pending->lock);

        /*
@@ -292,6 +296,11 @@ void irqchip_inject_pending(void)
                        return;
                }

+               /*
+                * Ensure that the entry was read before updating the head
+                * index.
+                */
+               memory_barrier();
                pending->head = (pending->head + 1) % MAX_PENDING_IRQS;
        }

@@ -389,6 +398,11 @@ void irqchip_cpu_shutdown(struct public_per_cpu 
*cpu_public)

                irqchip.inject_phys_irq(irq_id);

+               /*
+                * Ensure that the entry was read before updating the head
+                * index.
+                */
+               memory_barrier();
                pending->head = (pending->head + 1) % MAX_PENDING_IRQS;
        }
 }
--
2.16.4

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/940e194f3be655cc56929c70b3f7fa61cc89abed.1577125789.git.jan.kiszka%40web.de.

Reply via email to