spapr_rtas: Prevent QEMU crash during hotplug without a prior device_add

If drmgr is used in the guest to hotplug a device before a device_add
has been issued via the QEMU monitor, QEMU segfaults in configure_connector
call. This occurs due to accessing of NULL FDT which otherwise would have
been created and associated with the DRC during device_add command.

Check for NULL FDT and return failure from configure_connector call.
As per PAPR+, an error value of -9003 seems appropriate for this failure.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
Cc: Michael Roth <mdroth@linux.vnet.ibm.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Bharata B Rao 2015-09-01 09:53:52 +10:00 committed by David Gibson
parent aaf87c6616
commit e6fc9568c8
2 changed files with 14 additions and 7 deletions

View File

@ -522,6 +522,12 @@ static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
fdt = drck->get_fdt(drc, NULL); fdt = drck->get_fdt(drc, NULL);
if (!fdt) {
DPRINTF("rtas_ibm_configure_connector: Missing FDT for DRC index: %xh\n",
drc_index);
rc = SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE;
goto out;
}
ccs = spapr_ccs_find(spapr, drc_index); ccs = spapr_ccs_find(spapr, drc_index);
if (!ccs) { if (!ccs) {

View File

@ -119,13 +119,14 @@ typedef enum {
} sPAPRDREntitySense; } sPAPRDREntitySense;
typedef enum { typedef enum {
SPAPR_DR_CC_RESPONSE_NEXT_SIB = 1, /* currently unused */ SPAPR_DR_CC_RESPONSE_NEXT_SIB = 1, /* currently unused */
SPAPR_DR_CC_RESPONSE_NEXT_CHILD = 2, SPAPR_DR_CC_RESPONSE_NEXT_CHILD = 2,
SPAPR_DR_CC_RESPONSE_NEXT_PROPERTY = 3, SPAPR_DR_CC_RESPONSE_NEXT_PROPERTY = 3,
SPAPR_DR_CC_RESPONSE_PREV_PARENT = 4, SPAPR_DR_CC_RESPONSE_PREV_PARENT = 4,
SPAPR_DR_CC_RESPONSE_SUCCESS = 0, SPAPR_DR_CC_RESPONSE_SUCCESS = 0,
SPAPR_DR_CC_RESPONSE_ERROR = -1, SPAPR_DR_CC_RESPONSE_ERROR = -1,
SPAPR_DR_CC_RESPONSE_CONTINUE = -2, SPAPR_DR_CC_RESPONSE_CONTINUE = -2,
SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE = -9003,
} sPAPRDRCCResponse; } sPAPRDRCCResponse;
typedef void (spapr_drc_detach_cb)(DeviceState *d, void *opaque); typedef void (spapr_drc_detach_cb)(DeviceState *d, void *opaque);