ia64/xen-unstable

changeset 17945:0076f6691b09

x86: Fix MSI cleanup.

Fixes bugzilla bug #1279.

From: Haitao Shan <haitao.shan@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Jul 02 09:44:09 2008 +0100 (2008-07-02)
parents 40e7329105fa
children dd3b693dd39a
files xen/arch/x86/msi.c xen/drivers/passthrough/io.c
line diff
     1.1 --- a/xen/arch/x86/msi.c	Wed Jul 02 09:42:37 2008 +0100
     1.2 +++ b/xen/arch/x86/msi.c	Wed Jul 02 09:44:09 2008 +0100
     1.3 @@ -435,14 +435,6 @@ static void msi_free_vector(int vector)
     1.4      xfree(entry);
     1.5  }
     1.6  
     1.7 -void msi_free_vectors(struct pci_dev* dev)
     1.8 -{
     1.9 -    struct msi_desc *entry, *tmp;
    1.10 -
    1.11 -    list_for_each_entry_safe( entry, tmp, &dev->msi_list, list )
    1.12 -        msi_free_vector(entry->vector);
    1.13 -}
    1.14 -
    1.15  static struct msi_desc *find_msi_entry(struct pci_dev *dev,
    1.16                                         int vector, int cap_id)
    1.17  {
    1.18 @@ -790,16 +782,40 @@ void pci_disable_msi(int vector)
    1.19          __pci_disable_msix(vector);
    1.20  }
    1.21  
    1.22 +extern struct hw_interrupt_type pci_msi_type;
    1.23 +static void msi_free_vectors(struct pci_dev* dev)
    1.24 +{
    1.25 +    struct msi_desc *entry, *tmp;
    1.26 +    irq_desc_t *desc;
    1.27 +    unsigned long flags;
    1.28 +
    1.29 +    list_for_each_entry_safe( entry, tmp, &dev->msi_list, list )
    1.30 +    {
    1.31 +        desc = &irq_desc[entry->vector];
    1.32 +
    1.33 +        spin_lock_irqsave(&desc->lock, flags);
    1.34 +        if ( desc->handler == &pci_msi_type )
    1.35 +        {
    1.36 +            /* MSI is not shared, so should be released already */
    1.37 +            BUG_ON(desc->status & IRQ_GUEST);
    1.38 +            desc->handler = &no_irq_type;
    1.39 +        }
    1.40 +        spin_unlock_irqrestore(&desc->lock, flags);
    1.41 +
    1.42 +        msi_free_vector(entry->vector);
    1.43 +    }
    1.44 +}
    1.45 +
    1.46  void pci_cleanup_msi(u8 bus, u8 devfn)
    1.47  {
    1.48      struct pci_dev *dev = get_msi_pdev(bus, devfn);
    1.49  
    1.50      if ( !dev )
    1.51          return;
    1.52 -    msi_free_vectors(dev);
    1.53  
    1.54      /* Disable MSI and/or MSI-X */
    1.55      msi_set_enable(dev, 0);
    1.56      msix_set_enable(dev, 0);
    1.57 +    msi_free_vectors(dev);
    1.58  }
    1.59  
     2.1 --- a/xen/drivers/passthrough/io.c	Wed Jul 02 09:42:37 2008 +0100
     2.2 +++ b/xen/drivers/passthrough/io.c	Wed Jul 02 09:44:09 2008 +0100
     2.3 @@ -75,13 +75,18 @@ int pt_irq_create_bind_vtd(
     2.4      {
     2.5          int pirq = pt_irq_bind->machine_irq;
     2.6  
     2.7 +        if ( !(hvm_irq_dpci->mirq[pirq].flags & HVM_IRQ_DPCI_VALID ) )
     2.8 +        {
     2.9 +            hvm_irq_dpci->mirq[pirq].flags |= HVM_IRQ_DPCI_VALID |
    2.10 +                                              HVM_IRQ_DPCI_MSI ;
    2.11 +            pirq_guest_bind(d->vcpu[0], pirq, 0);
    2.12 +        }
    2.13 +
    2.14          hvm_irq_dpci->mirq[pirq].flags |= HVM_IRQ_DPCI_VALID |HVM_IRQ_DPCI_MSI ;
    2.15          hvm_irq_dpci->mirq[pirq].gmsi.gvec = pt_irq_bind->u.msi.gvec;
    2.16          hvm_irq_dpci->mirq[pirq].gmsi.gflags = pt_irq_bind->u.msi.gflags;
    2.17 -
    2.18          hvm_irq_dpci->msi_gvec_pirq[pt_irq_bind->u.msi.gvec] = pirq;
    2.19  
    2.20 -        pirq_guest_bind(d->vcpu[0], pirq, BIND_PIRQ__WILL_SHARE);
    2.21      }
    2.22      else
    2.23      {