PPC: Fix crash on spapr_tce_table_finalize()

spapr_tce_table_finalize() can SEGV if the object was not previously
realized.  In particular this can be triggered by running
         qemu-system-ppc -device spapr-tce-table,?

The basic problem is that we have mismatched initialization versus
finalization: spapr_tce_table_finalize() is attempting to undo things that
are done in spapr_tce_table_realize(), not an instance_init function.

Therefore, replace spapr_tce_table_finalize() with
spapr_tce_table_unrealize().

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Cc: qemu-stable@nongnu.org
Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
David Gibson 2014-12-08 13:48:02 +11:00 committed by Alexander Graf
parent 77bad151fb
commit 5f9490de56
1 changed files with 3 additions and 3 deletions

View File

@ -173,9 +173,9 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn,
return tcet; return tcet;
} }
static void spapr_tce_table_finalize(Object *obj) static void spapr_tce_table_unrealize(DeviceState *dev, Error **errp)
{ {
sPAPRTCETable *tcet = SPAPR_TCE_TABLE(obj); sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
QLIST_REMOVE(tcet, list); QLIST_REMOVE(tcet, list);
@ -420,6 +420,7 @@ static void spapr_tce_table_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
dc->init = spapr_tce_table_realize; dc->init = spapr_tce_table_realize;
dc->reset = spapr_tce_reset; dc->reset = spapr_tce_reset;
dc->unrealize = spapr_tce_table_unrealize;
QLIST_INIT(&spapr_tce_tables); QLIST_INIT(&spapr_tce_tables);
@ -435,7 +436,6 @@ static TypeInfo spapr_tce_table_info = {
.parent = TYPE_DEVICE, .parent = TYPE_DEVICE,
.instance_size = sizeof(sPAPRTCETable), .instance_size = sizeof(sPAPRTCETable),
.class_init = spapr_tce_table_class_init, .class_init = spapr_tce_table_class_init,
.instance_finalize = spapr_tce_table_finalize,
}; };
static void register_types(void) static void register_types(void)