aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2017-02-06 19:35:31 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-02-14 18:25:40 -0500
commite7f9f10bcc8dbbf0e09aba6765e9e07bc59910f1 (patch)
tree426c8148dfbf28a2f7ce3b209ec367198979f15c /arch/powerpc/sysdev
parent3433972d049f256a57b3538b2d29a7ee38748019 (diff)
powerpc/powernv: Fix CPU hotplug to handle waking on HVI
commit 9b256714979fad61ae11d90b53cf67dd5e6484eb upstream. The IPIs come in as HVI not EE, so we need to test the appropriate SRR1 bits. The encoding is such that it won't have false positives on P7 and P8 so we can just test it like that. We also need to handle the icp-opal variant of the flush. Fixes: d74361881f0d ("powerpc/xics: Add ICP OPAL backend") Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r--arch/powerpc/sysdev/xics/icp-opal.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/powerpc/sysdev/xics/icp-opal.c b/arch/powerpc/sysdev/xics/icp-opal.c
index 60c57657c772..c96c0cb95d87 100644
--- a/arch/powerpc/sysdev/xics/icp-opal.c
+++ b/arch/powerpc/sysdev/xics/icp-opal.c
@@ -132,6 +132,35 @@ static irqreturn_t icp_opal_ipi_action(int irq, void *dev_id)
132 return smp_ipi_demux(); 132 return smp_ipi_demux();
133} 133}
134 134
135/*
136 * Called when an interrupt is received on an off-line CPU to
137 * clear the interrupt, so that the CPU can go back to nap mode.
138 */
139void icp_opal_flush_interrupt(void)
140{
141 unsigned int xirr;
142 unsigned int vec;
143
144 do {
145 xirr = icp_opal_get_xirr();
146 vec = xirr & 0x00ffffff;
147 if (vec == XICS_IRQ_SPURIOUS)
148 break;
149 if (vec == XICS_IPI) {
150 /* Clear pending IPI */
151 int cpu = smp_processor_id();
152 kvmppc_set_host_ipi(cpu, 0);
153 opal_int_set_mfrr(get_hard_smp_processor_id(cpu), 0xff);
154 } else {
155 pr_err("XICS: hw interrupt 0x%x to offline cpu, "
156 "disabling\n", vec);
157 xics_mask_unknown_vec(vec);
158 }
159
160 /* EOI the interrupt */
161 } while (opal_int_eoi(xirr) > 0);
162}
163
135#endif /* CONFIG_SMP */ 164#endif /* CONFIG_SMP */
136 165
137static const struct icp_ops icp_opal_ops = { 166static const struct icp_ops icp_opal_ops = {