diff options
author | Greg Kurz <gkurz@linux.vnet.ibm.com> | 2016-02-26 10:44:07 +0100 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2016-02-28 16:19:02 +1100 |
commit | a005b3ef50439b5bc6b2eb0b5bda8e8c7c2368bf (patch) | |
tree | f85003e9eefe79a947415dd3cca69a6f3293cd9f /hw/ppc | |
parent | 902c053d834e3b802ec736f170edf226d4a841ff (diff) |
xics: report errors with the QEMU Error API
Using the return value to report errors is error prone:
- xics_alloc() returns -1 on error but spapr_vio_busdev_realize() errors
on 0
- xics_alloc_block() returns the unclear value of ics->offset - 1 on error
but both rtas_ibm_change_msi() and spapr_phb_realize() error on 0
This patch adds an errp argument to xics_alloc() and xics_alloc_block() to
report errors. The return value of these functions is a valid IRQ number
if errp is NULL. It is undefined otherwise.
The corresponding error traces get promotted to error messages. Note that
the "can't allocate IRQ" error message in spapr_vio_busdev_realize() also
moves to xics_alloc(). Similar error message consolidation isn't really
applicable to xics_alloc_block() because callers have extra context (device
config address, MSI or MSIX).
This fixes the issues mentioned above.
Based on previous work from Brian W. Hart.
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'hw/ppc')
-rw-r--r-- | hw/ppc/spapr_events.c | 3 | ||||
-rw-r--r-- | hw/ppc/spapr_pci.c | 16 | ||||
-rw-r--r-- | hw/ppc/spapr_vio.c | 7 |
3 files changed, 16 insertions, 10 deletions
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c index f5eac4b544..39f4682f95 100644 --- a/hw/ppc/spapr_events.c +++ b/hw/ppc/spapr_events.c @@ -588,7 +588,8 @@ out_no_events: void spapr_events_init(sPAPRMachineState *spapr) { QTAILQ_INIT(&spapr->pending_events); - spapr->check_exception_irq = xics_alloc(spapr->icp, 0, 0, false); + spapr->check_exception_irq = xics_alloc(spapr->icp, 0, 0, false, + &error_fatal); spapr->epow_notifier.notify = spapr_powerdown_req; qemu_register_powerdown_notifier(&spapr->epow_notifier); spapr_rtas_register(RTAS_CHECK_EXCEPTION, "check-exception", diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 9b2b546b54..e8edad3ab7 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -280,6 +280,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr, PCIDevice *pdev = NULL; spapr_pci_msi *msi; int *config_addr_key; + Error *err = NULL; switch (func) { case RTAS_CHANGE_MSI_FN: @@ -354,9 +355,10 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr, /* Allocate MSIs */ irq = xics_alloc_block(spapr->icp, 0, req_num, false, - ret_intr_type == RTAS_TYPE_MSI); - if (!irq) { - error_report("Cannot allocate MSIs for device %x", config_addr); + ret_intr_type == RTAS_TYPE_MSI, &err); + if (err) { + error_reportf_err(err, "Can't allocate MSIs for device %x: ", + config_addr); rtas_st(rets, 0, RTAS_OUT_HW_ERROR); return; } @@ -1367,10 +1369,12 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) /* Initialize the LSI table */ for (i = 0; i < PCI_NUM_PINS; i++) { uint32_t irq; + Error *local_err = NULL; - irq = xics_alloc_block(spapr->icp, 0, 1, true, false); - if (!irq) { - error_setg(errp, "spapr_allocate_lsi failed"); + irq = xics_alloc_block(spapr->icp, 0, 1, true, false, &local_err); + if (local_err) { + error_propagate(errp, local_err); + error_prepend(errp, "can't allocate LSIs: "); return; } diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index ac6666a90b..0f61a550cb 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -431,6 +431,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp) VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev; VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev); char *id; + Error *local_err = NULL; if (dev->reg != -1) { /* @@ -463,9 +464,9 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp) dev->qdev.id = id; } - dev->irq = xics_alloc(spapr->icp, 0, dev->irq, false); - if (!dev->irq) { - error_setg(errp, "can't allocate IRQ"); + dev->irq = xics_alloc(spapr->icp, 0, dev->irq, false, &local_err); + if (local_err) { + error_propagate(errp, local_err); return; } |