From 8f98a868aa76a87ba2f0c03a296be79368848deb Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh@NetBSD.org>
Date: Fri, 11 Feb 2022 21:10:47 +0000
Subject: [PATCH] hppa: Membar audit in ipifuncs.c.

---
 sys/arch/hppa/hppa/ipifuncs.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/sys/arch/hppa/hppa/ipifuncs.c b/sys/arch/hppa/hppa/ipifuncs.c
index f0b3b3576c6b..4a8b932ed925 100644
--- a/sys/arch/hppa/hppa/ipifuncs.c
+++ b/sys/arch/hppa/hppa/ipifuncs.c
@@ -83,6 +83,7 @@ hppa_ipi_intr(void *arg)
 
 	/* Handle an IPI. */
 	ipi_pending = atomic_swap_ulong(&ci->ci_ipi, 0);
+	membar_enter();	/* matches membar_exit in xc_send_ipi, cpu_ipi */
 
 	KASSERT(ipi_pending);
 
@@ -108,10 +109,16 @@ hppa_ipi_send(struct cpu_info *ci, u_long ipi)
 
 	atomic_or_ulong(&ci->ci_ipi, (1L << ipi));
 
-	/* Send an IPI to the specified CPU by triggering EIR{1} (irq 30). */
+	/*
+	 * Send an IPI to the specified CPU by triggering EIR{1} (irq 30).
+	 *
+	 * The `matching memory barrier' is somewhere inside the
+	 * silicon -- the point is that the store to ci->ci_ipi above
+	 * must happen before the delivery of the interrupt triggered
+	 * by writing to EIR{1}.
+	 */
 	cpu = (struct iomod *)(ci->ci_hpa);
-	cpu->io_eir = 1;
-	membar_sync();
+	atomic_store_release(&cpu->io_eir, 1);
 
 	return 0;
 }
@@ -156,6 +163,7 @@ xc_send_ipi(struct cpu_info *ci)
 	KASSERT(kpreempt_disabled());
 	KASSERT(curcpu() != ci);
 
+	membar_exit();		/* matches membar_enter in hppa_ipi_intr */
 	if (ci) {
 		/* Unicast: remote CPU. */
 		hppa_ipi_send(ci, HPPA_IPI_XCALL);
@@ -171,6 +179,7 @@ cpu_ipi(struct cpu_info *ci)
 	KASSERT(kpreempt_disabled());
 	KASSERT(curcpu() != ci);
 
+	membar_exit();		/* matches membar_enter in hppa_ipi_intr */
 	if (ci) {
 		/* Unicast: remote CPU. */
 		hppa_ipi_send(ci, HPPA_IPI_GENERIC);