Commit e414e293 authored by Christophe JAILLET's avatar Christophe JAILLET Committed by Michael Ellerman

powerpc/xive: Add some error handling code to 'xive_spapr_init()'

'xive_irq_bitmap_add()' can return -ENOMEM.
In this case, we should free the memory already allocated and return
'false' to the caller.

Also add an error path which undoes the 'tima = ioremap(...)'
Signed-off-by: default avatarChristophe JAILLET <christophe.jaillet@wanadoo.fr>
Reviewed-by: default avatarCédric Le Goater <clg@kaod.org>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/564998101804886b151235c8a9f93020923bfd2c.1643718324.git.christophe.jaillet@wanadoo.fr
parent 01983223
...@@ -67,6 +67,17 @@ static int __init xive_irq_bitmap_add(int base, int count) ...@@ -67,6 +67,17 @@ static int __init xive_irq_bitmap_add(int base, int count)
return 0; return 0;
} }
static void xive_irq_bitmap_remove_all(void)
{
struct xive_irq_bitmap *xibm, *tmp;
list_for_each_entry_safe(xibm, tmp, &xive_irq_bitmaps, list) {
list_del(&xibm->list);
kfree(xibm->bitmap);
kfree(xibm);
}
}
static int __xive_irq_bitmap_alloc(struct xive_irq_bitmap *xibm) static int __xive_irq_bitmap_alloc(struct xive_irq_bitmap *xibm)
{ {
int irq; int irq;
...@@ -803,7 +814,7 @@ bool __init xive_spapr_init(void) ...@@ -803,7 +814,7 @@ bool __init xive_spapr_init(void)
u32 val; u32 val;
u32 len; u32 len;
const __be32 *reg; const __be32 *reg;
int i; int i, err;
if (xive_spapr_disabled()) if (xive_spapr_disabled())
return false; return false;
...@@ -828,23 +839,26 @@ bool __init xive_spapr_init(void) ...@@ -828,23 +839,26 @@ bool __init xive_spapr_init(void)
} }
if (!xive_get_max_prio(&max_prio)) if (!xive_get_max_prio(&max_prio))
return false; goto err_unmap;
/* Feed the IRQ number allocator with the ranges given in the DT */ /* Feed the IRQ number allocator with the ranges given in the DT */
reg = of_get_property(np, "ibm,xive-lisn-ranges", &len); reg = of_get_property(np, "ibm,xive-lisn-ranges", &len);
if (!reg) { if (!reg) {
pr_err("Failed to read 'ibm,xive-lisn-ranges' property\n"); pr_err("Failed to read 'ibm,xive-lisn-ranges' property\n");
return false; goto err_unmap;
} }
if (len % (2 * sizeof(u32)) != 0) { if (len % (2 * sizeof(u32)) != 0) {
pr_err("invalid 'ibm,xive-lisn-ranges' property\n"); pr_err("invalid 'ibm,xive-lisn-ranges' property\n");
return false; goto err_unmap;
} }
for (i = 0; i < len / (2 * sizeof(u32)); i++, reg += 2) for (i = 0; i < len / (2 * sizeof(u32)); i++, reg += 2) {
xive_irq_bitmap_add(be32_to_cpu(reg[0]), err = xive_irq_bitmap_add(be32_to_cpu(reg[0]),
be32_to_cpu(reg[1])); be32_to_cpu(reg[1]));
if (err < 0)
goto err_mem_free;
}
/* Iterate the EQ sizes and pick one */ /* Iterate the EQ sizes and pick one */
of_property_for_each_u32(np, "ibm,xive-eq-sizes", prop, reg, val) { of_property_for_each_u32(np, "ibm,xive-eq-sizes", prop, reg, val) {
...@@ -855,10 +869,16 @@ bool __init xive_spapr_init(void) ...@@ -855,10 +869,16 @@ bool __init xive_spapr_init(void)
/* Initialize XIVE core with our backend */ /* Initialize XIVE core with our backend */
if (!xive_core_init(np, &xive_spapr_ops, tima, TM_QW1_OS, max_prio)) if (!xive_core_init(np, &xive_spapr_ops, tima, TM_QW1_OS, max_prio))
return false; goto err_mem_free;
pr_info("Using %dkB queues\n", 1 << (xive_queue_shift - 10)); pr_info("Using %dkB queues\n", 1 << (xive_queue_shift - 10));
return true; return true;
err_mem_free:
xive_irq_bitmap_remove_all();
err_unmap:
iounmap(tima);
return false;
} }
machine_arch_initcall(pseries, xive_core_debug_init); machine_arch_initcall(pseries, xive_core_debug_init);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment