[PATCH] powerpc/xics: Fix migrate_irqs_away - set CPPR to lowest priority

Balbir Singh bsingharora at gmail.com
Mon Feb 27 11:36:55 AEDT 2017


With XICS emulation, setting the CPPR to DEFAULT_PRIORITY
masks all interrupts including IPI's which map to a single
underlying priority. The fix does two things

1. It moves the setting of CPPR to after all IRQ migration
   is complete
2. It sets the CPPR to LOWEST_PRIORITY, so that interrupts
   and IPI's are effectively enabled. The expectation is that
   we'll see just IPI's after migration

The fix is quite generic in that it will work when we move
DEFAULT and IPI priorities to the same value in the kernel
later.

Cc: mikey at neuling.org
Cc: benh at kernel.crashing.org

Fixes: d74361881f0d ("powerpc/xics: Add ICP OPAL backend")
Cc: stable at vger.kernel.org # v4.8+

Reported-by: Vaidyanathan Srinivasan <svaidy at linux.vnet.ibm.com>
Tested-by: Vaidyanathan Srinivasan <svaidy at linux.vnet.ibm.com>
Signed-off-by: Balbir Singh <bsingharora at gmail.com>
---
 arch/powerpc/sysdev/xics/xics-common.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index c674a9d..31774e0 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -20,6 +20,7 @@
 #include <linux/of.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/delay.h>
 
 #include <asm/prom.h>
 #include <asm/io.h>
@@ -198,9 +199,6 @@ void xics_migrate_irqs_away(void)
 	/* Remove ourselves from the global interrupt queue */
 	xics_set_cpu_giq(xics_default_distrib_server, 0);
 
-	/* Allow IPIs again... */
-	icp_ops->set_priority(LOWEST_PRIORITY);
-
 	for_each_irq_desc(virq, desc) {
 		struct irq_chip *chip;
 		long server;
@@ -255,6 +253,19 @@ void xics_migrate_irqs_away(void)
 unlock:
 		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
+
+	/*
+	 * Allow sufficient time to drop any inflight IRQ's
+	 */
+	mdelay(1);
+
+	/*
+	 * Allow IPIs again. This is done at the very end, after
+	 * migrating all interrupts, the expectation is that we'll
+	 * only get woken up by an IPI interrupt beyond this point
+	 */
+	icp_ops->set_priority(LOWEST_PRIORITY);
+
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
-- 
2.9.3



More information about the Linuxppc-dev mailing list