@@ -805,7 +805,16 @@ static void xen_pt_unregister_device(PCIDevice *d)
}
}
+ xen_pt_msix_delete(s);
+}
+
+static void xen_pt_instance_finalize(Object *obj)
+{
+ PCIDevice *d = PCI_DEVICE(obj);
+ XenPCIPassthroughState *s = DO_UPCAST(XenPCIPassthroughState, dev, d);
+
/* delete all emulated config registers */
+ xen_pt_msix_free(s);
xen_pt_config_delete(s);
xen_pt_unregister_regions(s);
@@ -838,6 +847,7 @@ static const TypeInfo xen_pci_passthrough_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(XenPCIPassthroughState),
.class_init = xen_pci_passthrough_class_init,
+ .instance_finalize = xen_pt_instance_finalize,
};
static void xen_pci_passthrough_register_types(void)
@@ -1861,9 +1861,6 @@ void xen_pt_config_delete(XenPCIPassthroughState *s)
struct XenPTReg *reg, *next_reg;
/* free MSI/MSI-X info table */
- if (s->msix) {
- xen_pt_msix_delete(s);
- }
if (s->msi) {
g_free(s->msi);
}
@@ -604,6 +604,17 @@ void xen_pt_msix_delete(XenPCIPassthroughState *s)
return;
}
+ memory_region_del_subregion(&s->bar[msix->bar_index], &msix->mmio);
+}
+
+void xen_pt_msix_free(XenPCIPassthroughState *s)
+{
+ XenPTMSIX *msix = s->msix;
+
+ if (!msix) {
+ return;
+ }
+
/* unmap the MSI-X memory mapped register area */
if (msix->phys_iomem_base) {
XEN_PT_LOG(&s->dev, "unmapping physical MSI-X table from %p\n",
@@ -612,7 +619,6 @@ void xen_pt_msix_delete(XenPCIPassthroughState *s)
+ msix->table_offset_adjust);
}
- memory_region_del_subregion(&s->bar[msix->bar_index], &msix->mmio);
memory_region_destroy(&msix->mmio);
g_free(s->msix);
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- hw/xen/xen_pt.c | 10 ++++++++++ hw/xen/xen_pt_config_init.c | 3 --- hw/xen/xen_pt_msi.c | 8 +++++++- 3 files changed, 17 insertions(+), 4 deletions(-)