WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] x2APIC/VT-d: allocate iommu when create a

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x2APIC/VT-d: allocate iommu when create a drhd
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 05 Jul 2010 00:45:14 -0700
Delivery-date: Mon, 05 Jul 2010 00:45:51 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1278314950 -3600
# Node ID 64a80813978fbefea8f5cb2fe99620d2f8476424
# Parent  70ac5171a48fb26872d8f79fc866f3525a377b2f
x2APIC/VT-d: allocate iommu when create a drhd

A drhd is created when parse ACPI DMAR table, but drhd->iommu is not
allocated until iommu setup. But iommu is needed by x2APIC which will
enable interrupt remapping before iommu setup. This patch allocates
iommu when create drhd. And then drhd->ecap can be removed because
it's the same as iommu->ecap.

Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx>
---
 xen/drivers/passthrough/vtd/dmar.c     |   20 ++++++++++++++------
 xen/drivers/passthrough/vtd/dmar.h     |    1 -
 xen/drivers/passthrough/vtd/intremap.c |   11 ++++++++---
 xen/drivers/passthrough/vtd/iommu.c    |   16 ++++++----------
 xen/drivers/passthrough/vtd/vtd.h      |    3 +++
 5 files changed, 31 insertions(+), 20 deletions(-)

diff -r 70ac5171a48f -r 64a80813978f xen/drivers/passthrough/vtd/dmar.c
--- a/xen/drivers/passthrough/vtd/dmar.c        Mon Jul 05 08:28:08 2010 +0100
+++ b/xen/drivers/passthrough/vtd/dmar.c        Mon Jul 05 08:29:10 2010 +0100
@@ -32,6 +32,7 @@
 #include "dmar.h"
 #include "iommu.h"
 #include "extern.h"
+#include "vtd.h"
 
 #undef PREFIX
 #define PREFIX VTDPREFIX "ACPI DMAR:"
@@ -378,7 +379,6 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
     struct acpi_table_drhd * drhd = (struct acpi_table_drhd *)header;
     void *dev_scope_start, *dev_scope_end;
     struct acpi_drhd_unit *dmaru;
-    void *addr;
     int ret;
     static int include_all = 0;
 
@@ -397,8 +397,9 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
         dprintk(VTDPREFIX, "  dmaru->address = %"PRIx64"\n",
                 dmaru->address);
 
-    addr = map_to_nocache_virt(0, drhd->address);
-    dmaru->ecap = dmar_readq(addr, DMAR_ECAP_REG);
+    ret = iommu_alloc(dmaru);
+    if ( ret )
+        goto out;
 
     dev_scope_start = (void *)(drhd + 1);
     dev_scope_end = ((void *)drhd) + header->length;
@@ -420,7 +421,7 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
     }
 
     if ( ret )
-        xfree(dmaru);
+        goto out;
     else if ( force_iommu || dmaru->include_all )
         acpi_register_drhd_unit(dmaru);
     else
@@ -451,14 +452,15 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
 
         if ( invalid_cnt )
         {
-            xfree(dmaru);
-
             if ( iommu_workaround_bios_bug &&
                  invalid_cnt == dmaru->scope.devices_cnt )
             {
                 dprintk(XENLOG_WARNING VTDPREFIX,
                     "  Workaround BIOS bug: ignore the DRHD due to all "
                     "devices under its scope are not PCI discoverable!\n");
+
+                iommu_free(dmaru);
+                xfree(dmaru);
             }
             else
             {
@@ -474,6 +476,12 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
             acpi_register_drhd_unit(dmaru);
     }
 
+out:
+    if ( ret )
+    {
+        iommu_free(dmaru);
+        xfree(dmaru);
+    }
     return ret;
 }
 
diff -r 70ac5171a48f -r 64a80813978f xen/drivers/passthrough/vtd/dmar.h
--- a/xen/drivers/passthrough/vtd/dmar.h        Mon Jul 05 08:28:08 2010 +0100
+++ b/xen/drivers/passthrough/vtd/dmar.h        Mon Jul 05 08:29:10 2010 +0100
@@ -50,7 +50,6 @@ struct acpi_drhd_unit {
     struct dmar_scope scope;            /* must be first member of struct */
     struct list_head list;
     u64    address;                     /* register base address of the unit */
-    u64    ecap;
     u8     include_all:1;
     struct iommu *iommu;
     struct list_head ioapic_list;
diff -r 70ac5171a48f -r 64a80813978f xen/drivers/passthrough/vtd/intremap.c
--- a/xen/drivers/passthrough/vtd/intremap.c    Mon Jul 05 08:28:08 2010 +0100
+++ b/xen/drivers/passthrough/vtd/intremap.c    Mon Jul 05 08:29:10 2010 +0100
@@ -137,15 +137,20 @@ int iommu_supports_eim(void)
     /* We MUST have a DRHD unit for each IOAPIC. */
     for ( apic = 0; apic < nr_ioapics; apic++ )
         if ( !ioapic_to_drhd(IO_APIC_ID(apic)) )
+    {
+            dprintk(XENLOG_WARNING VTDPREFIX,
+                    "There is not a DRHD for IOAPIC 0x%x (id: 0x%x)!\n",
+                    apic, IO_APIC_ID(apic));
             return 0;
+    }
 
     if ( list_empty(&acpi_drhd_units) )
         return 0;
 
     for_each_drhd_unit ( drhd )
-        if ( !ecap_queued_inval(drhd->ecap) ||
-             !ecap_intr_remap(drhd->ecap) ||
-             !ecap_eim(drhd->ecap) )
+        if ( !ecap_queued_inval(drhd->iommu->ecap) ||
+             !ecap_intr_remap(drhd->iommu->ecap) ||
+             !ecap_eim(drhd->iommu->ecap) )
             return 0;
 
     return 1;
diff -r 70ac5171a48f -r 64a80813978f xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c       Mon Jul 05 08:28:08 2010 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.c       Mon Jul 05 08:29:10 2010 +0100
@@ -144,14 +144,17 @@ struct iommu_flush *iommu_get_flush(stru
     return iommu ? &iommu->intel->flush : NULL;
 }
 
-static unsigned int clflush_size;
 static int iommus_incoherent;
 static void __iommu_flush_cache(void *addr, unsigned int size)
 {
     int i;
+    static unsigned int clflush_size = 0;
 
     if ( !iommus_incoherent )
         return;
+
+    if ( clflush_size == 0 )
+        clflush_size = get_cache_line_size();
 
     for ( i = 0; i < size; i += clflush_size )
         cacheline_flush((char *)addr + i);
@@ -1037,7 +1040,7 @@ static int iommu_set_interrupt(struct io
     return irq;
 }
 
-static int __init iommu_alloc(struct acpi_drhd_unit *drhd)
+int __init iommu_alloc(struct acpi_drhd_unit *drhd)
 {
     struct iommu *iommu;
     unsigned long sagaw, nr_dom;
@@ -1131,7 +1134,7 @@ static int __init iommu_alloc(struct acp
     return 0;
 }
 
-static void __init iommu_free(struct acpi_drhd_unit *drhd)
+void __init iommu_free(struct acpi_drhd_unit *drhd)
 {
     struct iommu *iommu = drhd->iommu;
 
@@ -1943,8 +1946,6 @@ int __init intel_vtd_setup(void)
 
     platform_quirks();
 
-    clflush_size = get_cache_line_size();
-
     irq_to_iommu = xmalloc_array(struct iommu*, nr_irqs);
     BUG_ON(!irq_to_iommu);
     memset(irq_to_iommu, 0, nr_irqs * sizeof(struct iommu*));
@@ -1958,9 +1959,6 @@ int __init intel_vtd_setup(void)
      */
     for_each_drhd_unit ( drhd )
     {
-        if ( iommu_alloc(drhd) != 0 )
-            goto error;
-
         iommu = drhd->iommu;
 
         if ( iommu_snoop && !ecap_snp_ctl(iommu->ecap) )
@@ -2000,8 +1998,6 @@ int __init intel_vtd_setup(void)
     return 0;
 
  error:
-    for_each_drhd_unit ( drhd )
-        iommu_free(drhd);
     iommu_enabled = 0;
     iommu_snoop = 0;
     iommu_passthrough = 0;
diff -r 70ac5171a48f -r 64a80813978f xen/drivers/passthrough/vtd/vtd.h
--- a/xen/drivers/passthrough/vtd/vtd.h Mon Jul 05 08:28:08 2010 +0100
+++ b/xen/drivers/passthrough/vtd/vtd.h Mon Jul 05 08:29:10 2010 +0100
@@ -108,4 +108,7 @@ void iommu_flush_cache_entry(void *addr,
 void iommu_flush_cache_entry(void *addr, unsigned int size);
 void iommu_flush_cache_page(void *addr, unsigned long npages);
 
+int iommu_alloc(struct acpi_drhd_unit *drhd);
+void iommu_free(struct acpi_drhd_unit *drhd);
+
 #endif // _VTD_H_

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x2APIC/VT-d: allocate iommu when create a drhd, Xen patchbot-unstable <=