diff options
author | Cédric Le Goater <clg@kaod.org> | 2019-09-05 17:59:10 +0200 |
---|---|---|
committer | Oliver O'Halloran <oohall@gmail.com> | 2019-09-06 16:59:42 +1000 |
commit | e97391ae2bb5a146a5041453f9185326654264d9 (patch) | |
tree | d7865be41498602962686fa839353fc2039bc9d0 /hw/xive.c | |
parent | e023d6b9095073f0105243de862fd8d408d842d5 (diff) | |
download | skiboot-e97391ae2bb5a146a5041453f9185326654264d9.zip skiboot-e97391ae2bb5a146a5041453f9185326654264d9.tar.gz skiboot-e97391ae2bb5a146a5041453f9185326654264d9.tar.bz2 |
xive: fix return value of opal_xive_allocate_irq()
When the maximum number of interrupts per chip is reached,
xive_try_allocate_irq() returns an internal XIVE error:
XIVE_ALLOC_NO_SPACE. But its value 0xffffffff is interpreted as a
positive value by its caller opal_xive_allocate_irq() and not as an
error.
opal_xive_allocate_irq() returns this value to Linux which also
considers 0xffffffff as a valid interrupt number and tries to get the
interrupt characteritics using opal_xive_get_irq_info(). This OPAL
calls finally fails leading to all sort of errors on the host which is
not prepared for such a scenario. Code impacted are the IPI setup and
the both XIVE KVM devices.
Fix by returning OPAL_RESOURCE from xive_try_allocate_irq() which is
consistent with the other errors returned by this routine. This fixes
the behavior in opal_xive_allocate_irq() and in Linux.
A workaround could be introduced in Linux to consider 0xffffffff as a
OPAL_RESOURCE value. This assumption is valid with the current XIVE
IRQ number encoding.
Fixes: 07946e68f47a ("xive: Add interrupt allocator")
Reported-by: Greg Kurz <groug@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
[oliver: Added fixes tag]
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Diffstat (limited to 'hw/xive.c')
-rw-r--r-- | hw/xive.c | 2 |
1 files changed, 1 insertions, 1 deletions
@@ -5059,7 +5059,7 @@ static int64_t xive_try_allocate_irq(struct xive *x) idx = bitmap_find_zero_bit(*x->ipi_alloc_map, base_idx, max_count); if (idx < 0) { unlock(&x->lock); - return XIVE_ALLOC_NO_SPACE; + return OPAL_RESOURCE; } bitmap_set_bit(*x->ipi_alloc_map, idx); girq = x->int_base + idx; |