diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2014-12-08 13:48:02 +1100 |
---|---|---|
committer | Michael Roth <mdroth@linux.vnet.ibm.com> | 2015-02-22 12:28:01 -0600 |
commit | cb3360dbdd85ce2eb97805e4ce70932ab333e8d1 (patch) | |
tree | 69592cd06703e2808c4bc3137df26fd3b8972c65 | |
parent | f738adeb5edef023fde0c47c3dce47987d7f6982 (diff) |
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>
(cherry picked from commit 5f9490de566c5b092a6cfedc3c7a37a9c9dee917)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
-rw-r--r-- | hw/ppc/spapr_iommu.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c index 6c91d8edd8..da474740c0 100644 --- a/hw/ppc/spapr_iommu.c +++ b/hw/ppc/spapr_iommu.c @@ -173,9 +173,9 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, 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); @@ -420,6 +420,7 @@ static void spapr_tce_table_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->init = spapr_tce_table_realize; dc->reset = spapr_tce_reset; + dc->unrealize = spapr_tce_table_unrealize; QLIST_INIT(&spapr_tce_tables); @@ -435,7 +436,6 @@ static TypeInfo spapr_tce_table_info = { .parent = TYPE_DEVICE, .instance_size = sizeof(sPAPRTCETable), .class_init = spapr_tce_table_class_init, - .instance_finalize = spapr_tce_table_finalize, }; static void register_types(void) |