[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] ioemu: Fix issues when passthrough device is hot-removed from HVM domain.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1216203408 -3600 # Node ID 3fe6df9afd5d42e655f0fa9ff009372fd8efa84d # Parent cec304746b360d0fccb2ab3944787bfb912902cb ioemu: Fix issues when passthrough device is hot-removed from HVM domain. When passthrough device is hot removed from HVM domain by "xm pci-detach" command, following issues occur. The patch fixes them. - Allocated memory is not deallocated. - Unbind interrupt with invalid interrupt pin. - MSI-X memory mapped register area is not unmapped. Signed-off-by: Yuji Shimada <shimada-yxb@xxxxxxxxxxxxxxx> --- tools/ioemu/hw/pass-through.c | 33 ++++++++++++++++++++++++++++++++- tools/ioemu/hw/pt-msi.c | 13 +++++++++++++ tools/ioemu/hw/pt-msi.h | 3 +++ 3 files changed, 48 insertions(+), 1 deletion(-) diff -r cec304746b36 -r 3fe6df9afd5d tools/ioemu/hw/pass-through.c --- a/tools/ioemu/hw/pass-through.c Wed Jul 16 11:15:14 2008 +0100 +++ b/tools/ioemu/hw/pass-through.c Wed Jul 16 11:16:48 2008 +0100 @@ -1686,6 +1686,33 @@ out: return err; } +/* delete all emulate register */ +static void pt_config_delete(struct pt_dev *ptdev) +{ + struct pt_reg_grp_tbl *reg_grp_entry = NULL; + struct pt_reg_tbl *reg_entry = NULL; + + /* free MSI/MSI-X info table */ + if (ptdev->msix) + pt_msix_delete(ptdev); + if (ptdev->msi) + free(ptdev->msi); + + /* free all register group entry */ + while ((reg_grp_entry = ptdev->reg_grp_tbl_head.lh_first) != NULL) + { + /* free all register entry */ + while ((reg_entry = reg_grp_entry->reg_tbl_head.lh_first) != NULL) + { + QEMU_LIST_REMOVE(reg_entry, entries); + qemu_free(reg_entry); + } + + QEMU_LIST_REMOVE(reg_grp_entry, entries); + qemu_free(reg_grp_entry); + } +} + /* initialize common register value */ static uint32_t pt_common_reg_init(struct pt_dev *ptdev, struct pt_reg_info_tbl *reg, uint32_t real_offset) @@ -2821,7 +2848,8 @@ int unregister_real_device(int php_slot) /* Unbind interrupt */ e_device = (assigned_device->dev.devfn >> 3) & 0x1f; - e_intx = assigned_device->dev.config[0x3d]-1; + /* fix virtual interrupt pin to INTA# */ + e_intx = 0; machine_irq = pci_dev->irq; if ( machine_irq != 0 ) { @@ -2833,6 +2861,9 @@ int unregister_real_device(int php_slot) PT_LOG("Error: Unbinding of interrupt failed! rc=%d\n", rc); } } + + /* delete all emulated config registers */ + pt_config_delete(assigned_device); /* unregister real device's MMIO/PIO BARs */ pt_unregister_regions(assigned_device); diff -r cec304746b36 -r 3fe6df9afd5d tools/ioemu/hw/pt-msi.c --- a/tools/ioemu/hw/pt-msi.c Wed Jul 16 11:15:14 2008 +0100 +++ b/tools/ioemu/hw/pt-msi.c Wed Jul 16 11:16:48 2008 +0100 @@ -332,3 +332,16 @@ int pt_msix_init(struct pt_dev *dev, int (unsigned long)dev->msix->phys_iomem_base); return 0; } + +void pt_msix_delete(struct pt_dev *dev) +{ + /* unmap the MSI-X memory mapped register area */ + if (dev->msix->phys_iomem_base) + { + PT_LOG("unmapping physical MSI-X table from %lx\n", + (unsigned long)dev->msix->phys_iomem_base); + munmap(dev->msix->phys_iomem_base, dev->msix->total_entries * 16); + } + + free(dev->msix); +} diff -r cec304746b36 -r 3fe6df9afd5d tools/ioemu/hw/pt-msi.h --- a/tools/ioemu/hw/pt-msi.h Wed Jul 16 11:15:14 2008 +0100 +++ b/tools/ioemu/hw/pt-msi.h Wed Jul 16 11:16:48 2008 +0100 @@ -94,4 +94,7 @@ int int pt_msix_init(struct pt_dev *dev, int pos); +void +pt_msix_delete(struct pt_dev *dev); + #endif _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |