aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/ppc/spapr_drc.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 2851e16a26..cc2400bcd5 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -519,6 +519,60 @@ static void reset(DeviceState *d)
}
}
+static bool spapr_drc_needed(void *opaque)
+{
+ sPAPRDRConnector *drc = (sPAPRDRConnector *)opaque;
+ sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+ bool rc = false;
+ sPAPRDREntitySense value;
+ drck->entity_sense(drc, &value);
+
+ /* If no dev is plugged in there is no need to migrate the DRC state */
+ if (value != SPAPR_DR_ENTITY_SENSE_PRESENT) {
+ return false;
+ }
+
+ /*
+ * If there is dev plugged in, we need to migrate the DRC state when
+ * it is different from cold-plugged state
+ */
+ switch (drc->type) {
+ case SPAPR_DR_CONNECTOR_TYPE_PCI:
+ rc = !((drc->isolation_state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) &&
+ (drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_USABLE) &&
+ drc->configured && drc->signalled && !drc->awaiting_release);
+ break;
+ case SPAPR_DR_CONNECTOR_TYPE_CPU:
+ case SPAPR_DR_CONNECTOR_TYPE_LMB:
+ rc = !((drc->isolation_state == SPAPR_DR_ISOLATION_STATE_ISOLATED) &&
+ (drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) &&
+ drc->configured && drc->signalled && !drc->awaiting_release);
+ break;
+ case SPAPR_DR_CONNECTOR_TYPE_PHB:
+ case SPAPR_DR_CONNECTOR_TYPE_VIO:
+ default:
+ g_assert(false);
+ }
+ return rc;
+}
+
+static const VMStateDescription vmstate_spapr_drc = {
+ .name = "spapr_drc",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = spapr_drc_needed,
+ .fields = (VMStateField []) {
+ VMSTATE_UINT32(isolation_state, sPAPRDRConnector),
+ VMSTATE_UINT32(allocation_state, sPAPRDRConnector),
+ VMSTATE_UINT32(indicator_state, sPAPRDRConnector),
+ VMSTATE_BOOL(configured, sPAPRDRConnector),
+ VMSTATE_BOOL(awaiting_release, sPAPRDRConnector),
+ VMSTATE_BOOL(awaiting_allocation, sPAPRDRConnector),
+ VMSTATE_BOOL(signalled, sPAPRDRConnector),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static void realize(DeviceState *d, Error **errp)
{
sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
@@ -547,6 +601,8 @@ static void realize(DeviceState *d, Error **errp)
object_unref(OBJECT(drc));
}
g_free(child_name);
+ vmstate_register(DEVICE(drc), drck->get_index(drc), &vmstate_spapr_drc,
+ drc);
trace_spapr_drc_realize_complete(drck->get_index(drc));
}