[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] vtd: Fix bug #1306: Dom0 hangs when destroying guest with MSI NIC assigned



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1217494266 -3600
# Node ID 82edb8c9ae178e32aaffc21c821767633e030b6f
# Parent  b8c7d7e0ba7ff6623060e4255687e38bb6ac5d13
vtd: Fix bug #1306: Dom0 hangs when destroying guest with MSI NIC assigned

Signed-off-by: Shan Haitao <haitao.shan@xxxxxxxxx>
---
 xen/arch/x86/msi.c              |   15 +++++++--------
 xen/drivers/passthrough/iommu.c |   30 ++----------------------------
 xen/drivers/passthrough/pci.c   |   39 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 48 insertions(+), 36 deletions(-)

diff -r b8c7d7e0ba7f -r 82edb8c9ae17 xen/arch/x86/msi.c
--- a/xen/arch/x86/msi.c        Thu Jul 31 09:49:28 2008 +0100
+++ b/xen/arch/x86/msi.c        Thu Jul 31 09:51:06 2008 +0100
@@ -761,14 +761,13 @@ retry:
     {
         desc = &irq_desc[entry->vector];
 
-       local_irq_save(flags);
-       if ( !spin_trylock(&desc->lock) )
-       {
-           local_irq_restore(flags);
-           goto retry;
-       }
-
-        spin_lock_irqsave(&desc->lock, flags);
+        local_irq_save(flags);
+        if ( !spin_trylock(&desc->lock) )
+        {
+             local_irq_restore(flags);
+            goto retry;
+        }
+
         if ( desc->handler == &pci_msi_type )
         {
             /* MSI is not shared, so should be released already */
diff -r b8c7d7e0ba7f -r 82edb8c9ae17 xen/drivers/passthrough/iommu.c
--- a/xen/drivers/passthrough/iommu.c   Thu Jul 31 09:49:28 2008 +0100
+++ b/xen/drivers/passthrough/iommu.c   Thu Jul 31 09:51:06 2008 +0100
@@ -126,14 +126,12 @@ static int iommu_populate_page_table(str
     return 0;
 }
 
+
 void iommu_domain_destroy(struct domain *d)
 {
-    struct hvm_irq_dpci *hvm_irq_dpci = domain_get_irq_dpci(d);
-    uint32_t i;
     struct hvm_iommu *hd  = domain_hvm_iommu(d);
-    struct list_head *ioport_list, *digl_list, *tmp;
+    struct list_head *ioport_list, *tmp;
     struct g2m_ioport *ioport;
-    struct dev_intx_gsi_link *digl;
 
     if ( !iommu_enabled || !hd->platform_ops )
         return;
@@ -146,30 +144,6 @@ void iommu_domain_destroy(struct domain 
         d->need_iommu = 0;
         hd->platform_ops->teardown(d);
         return;
-    }
-
-    if ( hvm_irq_dpci != NULL )
-    {
-        for ( i = 0; i < NR_IRQS; i++ )
-        {
-            if ( !(hvm_irq_dpci->mirq[i].flags & HVM_IRQ_DPCI_VALID) )
-                continue;
-
-            pirq_guest_unbind(d, i);
-            kill_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(i)]);
-
-            list_for_each_safe ( digl_list, tmp,
-                                 &hvm_irq_dpci->mirq[i].digl_list )
-            {
-                digl = list_entry(digl_list,
-                                  struct dev_intx_gsi_link, list);
-                list_del(&digl->list);
-                xfree(digl);
-            }
-        }
-
-        d->arch.hvm_domain.irq.dpci = NULL;
-        xfree(hvm_irq_dpci);
     }
 
     if ( hd )
diff -r b8c7d7e0ba7f -r 82edb8c9ae17 xen/drivers/passthrough/pci.c
--- a/xen/drivers/passthrough/pci.c     Thu Jul 31 09:49:28 2008 +0100
+++ b/xen/drivers/passthrough/pci.c     Thu Jul 31 09:51:06 2008 +0100
@@ -152,11 +152,50 @@ int pci_remove_device(u8 bus, u8 devfn)
     return ret;
 }
 
+static void pci_clean_dpci_irqs(struct domain *d)
+{
+    struct hvm_irq_dpci *hvm_irq_dpci = domain_get_irq_dpci(d);
+    uint32_t i;
+    struct list_head *digl_list, *tmp;
+    struct dev_intx_gsi_link *digl;
+
+    if ( !iommu_enabled )
+        return;
+
+    if ( !is_hvm_domain(d) && !need_iommu(d) )
+        return;
+
+    if ( hvm_irq_dpci != NULL )
+    {
+        for ( i = 0; i < NR_IRQS; i++ )
+        {
+            if ( !(hvm_irq_dpci->mirq[i].flags & HVM_IRQ_DPCI_VALID) )
+                continue;
+
+            pirq_guest_unbind(d, i);
+            kill_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(i)]);
+
+            list_for_each_safe ( digl_list, tmp,
+                                 &hvm_irq_dpci->mirq[i].digl_list )
+            {
+                digl = list_entry(digl_list,
+                                  struct dev_intx_gsi_link, list);
+                list_del(&digl->list);
+                xfree(digl);
+            }
+        }
+
+        d->arch.hvm_domain.irq.dpci = NULL;
+        xfree(hvm_irq_dpci);
+    }
+}
+
 void pci_release_devices(struct domain *d)
 {
     struct pci_dev *pdev;
     u8 bus, devfn;
 
+    pci_clean_dpci_irqs(d);
     while ( (pdev = pci_lock_domain_pdev(d, -1, -1)) )
     {
         pci_cleanup_msi(pdev);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.