ia64/xen-unstable

changeset 18070:3fe6df9afd5d

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@necst.nec.co.jp>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Jul 16 11:16:48 2008 +0100 (2008-07-16)
parents cec304746b36
children 0796aa57d297
files tools/ioemu/hw/pass-through.c tools/ioemu/hw/pt-msi.c tools/ioemu/hw/pt-msi.h
line diff
     1.1 --- a/tools/ioemu/hw/pass-through.c	Wed Jul 16 11:15:14 2008 +0100
     1.2 +++ b/tools/ioemu/hw/pass-through.c	Wed Jul 16 11:16:48 2008 +0100
     1.3 @@ -1686,6 +1686,33 @@ out:
     1.4      return err;
     1.5  }
     1.6  
     1.7 +/* delete all emulate register */
     1.8 +static void pt_config_delete(struct pt_dev *ptdev)
     1.9 +{
    1.10 +    struct pt_reg_grp_tbl *reg_grp_entry = NULL;
    1.11 +    struct pt_reg_tbl *reg_entry = NULL;
    1.12 +
    1.13 +    /* free MSI/MSI-X info table */
    1.14 +    if (ptdev->msix)
    1.15 +        pt_msix_delete(ptdev);
    1.16 +    if (ptdev->msi)
    1.17 +        free(ptdev->msi);
    1.18 +
    1.19 +    /* free all register group entry */
    1.20 +    while ((reg_grp_entry = ptdev->reg_grp_tbl_head.lh_first) != NULL)
    1.21 +    {
    1.22 +        /* free all register entry */
    1.23 +        while ((reg_entry = reg_grp_entry->reg_tbl_head.lh_first) != NULL)
    1.24 +        {
    1.25 +            QEMU_LIST_REMOVE(reg_entry, entries);
    1.26 +            qemu_free(reg_entry);
    1.27 +        }
    1.28 +
    1.29 +        QEMU_LIST_REMOVE(reg_grp_entry, entries);
    1.30 +        qemu_free(reg_grp_entry);
    1.31 +    }
    1.32 +}
    1.33 +
    1.34  /* initialize common register value */
    1.35  static uint32_t pt_common_reg_init(struct pt_dev *ptdev,
    1.36          struct pt_reg_info_tbl *reg, uint32_t real_offset)
    1.37 @@ -2821,7 +2848,8 @@ int unregister_real_device(int php_slot)
    1.38  
    1.39      /* Unbind interrupt */
    1.40      e_device = (assigned_device->dev.devfn >> 3) & 0x1f;
    1.41 -    e_intx = assigned_device->dev.config[0x3d]-1;
    1.42 +    /* fix virtual interrupt pin to INTA# */
    1.43 +    e_intx = 0;
    1.44      machine_irq = pci_dev->irq;
    1.45  
    1.46      if ( machine_irq != 0 ) {
    1.47 @@ -2834,6 +2862,9 @@ int unregister_real_device(int php_slot)
    1.48          }
    1.49      }
    1.50  
    1.51 +    /* delete all emulated config registers */
    1.52 +    pt_config_delete(assigned_device);
    1.53 +
    1.54      /* unregister real device's MMIO/PIO BARs */
    1.55      pt_unregister_regions(assigned_device);
    1.56      
     2.1 --- a/tools/ioemu/hw/pt-msi.c	Wed Jul 16 11:15:14 2008 +0100
     2.2 +++ b/tools/ioemu/hw/pt-msi.c	Wed Jul 16 11:16:48 2008 +0100
     2.3 @@ -332,3 +332,16 @@ int pt_msix_init(struct pt_dev *dev, int
     2.4             (unsigned long)dev->msix->phys_iomem_base);
     2.5      return 0;
     2.6  }
     2.7 +
     2.8 +void pt_msix_delete(struct pt_dev *dev)
     2.9 +{
    2.10 +    /* unmap the MSI-X memory mapped register area */
    2.11 +    if (dev->msix->phys_iomem_base)
    2.12 +    {
    2.13 +        PT_LOG("unmapping physical MSI-X table from %lx\n",
    2.14 +           (unsigned long)dev->msix->phys_iomem_base);
    2.15 +        munmap(dev->msix->phys_iomem_base, dev->msix->total_entries * 16);
    2.16 +    }
    2.17 +
    2.18 +    free(dev->msix);
    2.19 +}
     3.1 --- a/tools/ioemu/hw/pt-msi.h	Wed Jul 16 11:15:14 2008 +0100
     3.2 +++ b/tools/ioemu/hw/pt-msi.h	Wed Jul 16 11:16:48 2008 +0100
     3.3 @@ -94,4 +94,7 @@ add_msix_mapping(struct pt_dev *dev, int
     3.4  int
     3.5  pt_msix_init(struct pt_dev *dev, int pos);
     3.6  
     3.7 +void
     3.8 +pt_msix_delete(struct pt_dev *dev);
     3.9 +
    3.10  #endif