diff options
author | Greg Kurz <groug@kaod.org> | 2017-10-12 18:30:14 +0200 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2017-10-17 10:34:01 +1100 |
commit | f7d6bfcdc0fe49040aac3ac131a319cb5427957e (patch) | |
tree | 158661a268c3fa4d42bf2d2f8f01f962d1d2cffa /hw/ppc/spapr_pci.c | |
parent | db50f280cf5f714e64ff2b134aae138908f07502 (diff) |
spapr_pci: fail gracefully with non-pseries machine types
QEMU currently crashes when the user tries to add an spapr-pci-host-bridge
on a non-pseries machine:
$ qemu-system-ppc64 -M ppce500 -device spapr-pci-host-bridge,index=1
hw/ppc/spapr_pci.c:1535:spapr_phb_realize:
Object 0x1003dacae60 is not an instance of type spapr-machine
Aborted (core dumped)
The same thing happens with the deprecated but still available child type
spapr-pci-vfio-host-bridge.
Fix both by checking the machine type with object_dynamic_cast().
Reviewed-by: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
Signed-off-by: Greg Kurz <groug@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'hw/ppc/spapr_pci.c')
-rw-r--r-- | hw/ppc/spapr_pci.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 5049ced4e8..5a3122a9f9 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -1507,7 +1507,12 @@ static void spapr_pci_unplug_request(HotplugHandler *plug_handler, static void spapr_phb_realize(DeviceState *dev, Error **errp) { - sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); + /* We don't use SPAPR_MACHINE() in order to exit gracefully if the user + * tries to add a sPAPR PHB to a non-pseries machine. + */ + sPAPRMachineState *spapr = + (sPAPRMachineState *) object_dynamic_cast(qdev_get_machine(), + TYPE_SPAPR_MACHINE); SysBusDevice *s = SYS_BUS_DEVICE(dev); sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s); PCIHostState *phb = PCI_HOST_BRIDGE(s); @@ -1519,6 +1524,11 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) const unsigned windows_supported = sphb->ddw_enabled ? SPAPR_PCI_DMA_MAX_WINDOWS : 1; + if (!spapr) { + error_setg(errp, TYPE_SPAPR_PCI_HOST_BRIDGE " needs a pseries machine"); + return; + } + if (sphb->index != (uint32_t)-1) { sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); Error *local_err = NULL; |