Skip to content

Commit b1a504a

Browse files
legoatermpe
authored andcommitted
powerpc/xive: Use XIVE_BAD_IRQ instead of zero to catch non configured IPIs
When a CPU is brought up, an IPI number is allocated and recorded under the XIVE CPU structure. Invalid IPI numbers are tracked with interrupt number 0x0. On the PowerNV platform, the interrupt number space starts at 0x10 and this works fine. However, on the sPAPR platform, it is possible to allocate the interrupt number 0x0 and this raises an issue when CPU 0 is unplugged. The XIVE spapr driver tracks allocated interrupt numbers in a bitmask and it is not correctly updated when interrupt number 0x0 is freed. It stays allocated and it is then impossible to reallocate. Fix by using the XIVE_BAD_IRQ value instead of zero on both platforms. Reported-by: David Gibson <[email protected]> Fixes: eac1e73 ("powerpc/xive: guest exploitation of the XIVE interrupt controller") Cc: [email protected] # v4.14+ Signed-off-by: Cédric Le Goater <[email protected]> Reviewed-by: David Gibson <[email protected]> Tested-by: David Gibson <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent a703263 commit b1a504a

File tree

4 files changed

+14
-13
lines changed

4 files changed

+14
-13
lines changed

arch/powerpc/sysdev/xive/common.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,6 @@ static u32 xive_ipi_irq;
6868
/* Xive state for each CPU */
6969
static DEFINE_PER_CPU(struct xive_cpu *, xive_cpu);
7070

71-
/*
72-
* A "disabled" interrupt should never fire, to catch problems
73-
* we set its logical number to this
74-
*/
75-
#define XIVE_BAD_IRQ 0x7fffffff
76-
#define XIVE_MAX_IRQ (XIVE_BAD_IRQ - 1)
77-
7871
/* An invalid CPU target */
7972
#define XIVE_INVALID_TARGET (-1)
8073

@@ -1150,7 +1143,7 @@ static int xive_setup_cpu_ipi(unsigned int cpu)
11501143
xc = per_cpu(xive_cpu, cpu);
11511144

11521145
/* Check if we are already setup */
1153-
if (xc->hw_ipi != 0)
1146+
if (xc->hw_ipi != XIVE_BAD_IRQ)
11541147
return 0;
11551148

11561149
/* Grab an IPI from the backend, this will populate xc->hw_ipi */
@@ -1187,7 +1180,7 @@ static void xive_cleanup_cpu_ipi(unsigned int cpu, struct xive_cpu *xc)
11871180
/* Disable the IPI and free the IRQ data */
11881181

11891182
/* Already cleaned up ? */
1190-
if (xc->hw_ipi == 0)
1183+
if (xc->hw_ipi == XIVE_BAD_IRQ)
11911184
return;
11921185

11931186
/* Mask the IPI */
@@ -1343,6 +1336,7 @@ static int xive_prepare_cpu(unsigned int cpu)
13431336
if (np)
13441337
xc->chip_id = of_get_ibm_chip_id(np);
13451338
of_node_put(np);
1339+
xc->hw_ipi = XIVE_BAD_IRQ;
13461340

13471341
per_cpu(xive_cpu, cpu) = xc;
13481342
}

arch/powerpc/sysdev/xive/native.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,15 +312,15 @@ static void xive_native_put_ipi(unsigned int cpu, struct xive_cpu *xc)
312312
s64 rc;
313313

314314
/* Free the IPI */
315-
if (!xc->hw_ipi)
315+
if (xc->hw_ipi == XIVE_BAD_IRQ)
316316
return;
317317
for (;;) {
318318
rc = opal_xive_free_irq(xc->hw_ipi);
319319
if (rc == OPAL_BUSY) {
320320
msleep(OPAL_BUSY_DELAY_MS);
321321
continue;
322322
}
323-
xc->hw_ipi = 0;
323+
xc->hw_ipi = XIVE_BAD_IRQ;
324324
break;
325325
}
326326
}

arch/powerpc/sysdev/xive/spapr.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -560,11 +560,11 @@ static int xive_spapr_get_ipi(unsigned int cpu, struct xive_cpu *xc)
560560

561561
static void xive_spapr_put_ipi(unsigned int cpu, struct xive_cpu *xc)
562562
{
563-
if (!xc->hw_ipi)
563+
if (xc->hw_ipi == XIVE_BAD_IRQ)
564564
return;
565565

566566
xive_irq_bitmap_free(xc->hw_ipi);
567-
xc->hw_ipi = 0;
567+
xc->hw_ipi = XIVE_BAD_IRQ;
568568
}
569569
#endif /* CONFIG_SMP */
570570

arch/powerpc/sysdev/xive/xive-internal.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
#ifndef __XIVE_INTERNAL_H
66
#define __XIVE_INTERNAL_H
77

8+
/*
9+
* A "disabled" interrupt should never fire, to catch problems
10+
* we set its logical number to this
11+
*/
12+
#define XIVE_BAD_IRQ 0x7fffffff
13+
#define XIVE_MAX_IRQ (XIVE_BAD_IRQ - 1)
14+
815
/* Each CPU carry one of these with various per-CPU state */
916
struct xive_cpu {
1017
#ifdef CONFIG_SMP

0 commit comments

Comments
 (0)