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-3.4-testing] AMD IOMMU: Use global interrupt remapp

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-3.4-testing] AMD IOMMU: Use global interrupt remapping table by default
From: "Xen patchbot-3.4-testing" <patchbot-3.4-testing@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 09 Nov 2009 00:25:22 -0800
Delivery-date: Mon, 09 Nov 2009 00:26:27 -0800
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 1257753932 0
# Node ID 7b58e660e8b3d6789ca905242e71f97225826eeb
# Parent  14cfa4efcce554b5beaf8af65f0c8f538a22b333
AMD IOMMU: Use global interrupt remapping table by default

Using a global interrupt remapping table shared by all devices has
better compatibility with certain old BIOSes. Per-device interrupt
remapping table can still be enabled by using a new parameter
"amd-iommu-perdev-intremap".

Signed-off-by: Wei Wang <wei.wang2@xxxxxxx>
xen-unstable changeset:   20380:a2c17e320c47
xen-unstable date:        Wed Oct 28 17:08:26 2009 +0000
---
 xen/drivers/passthrough/amd/iommu_acpi.c      |   18 ++++++++++---
 xen/drivers/passthrough/amd/iommu_init.c      |    3 +-
 xen/drivers/passthrough/amd/iommu_intr.c      |   36 ++++++++++++++++++--------
 xen/drivers/passthrough/iommu.c               |    5 +++
 xen/include/asm-x86/hvm/svm/amd-iommu-proto.h |    1 
 5 files changed, 48 insertions(+), 15 deletions(-)

diff -r 14cfa4efcce5 -r 7b58e660e8b3 xen/drivers/passthrough/amd/iommu_acpi.c
--- a/xen/drivers/passthrough/amd/iommu_acpi.c  Thu Nov 05 11:59:20 2009 +0000
+++ b/xen/drivers/passthrough/amd/iommu_acpi.c  Mon Nov 09 08:05:32 2009 +0000
@@ -29,6 +29,7 @@ extern struct ivrs_mappings *ivrs_mappin
 extern struct ivrs_mappings *ivrs_mappings;
 extern unsigned short last_bdf;
 extern int ioapic_bdf[MAX_IO_APICS];
+extern void *shared_intremap_table;
 
 static void add_ivrs_mapping_entry(
     u16 bdf, u16 alias_id, u8 flags, struct amd_iommu *iommu)
@@ -66,10 +67,19 @@ static void add_ivrs_mapping_entry(
     ivrs_mappings[bdf].dte_ext_int_pass = ext_int_pass;
     ivrs_mappings[bdf].dte_init_pass = init_pass;
 
-    /* allocate per-device interrupt remapping table */
-    if ( ivrs_mappings[alias_id].intremap_table == NULL )
-        ivrs_mappings[alias_id].intremap_table =
-            amd_iommu_alloc_intremap_table();
+    if (ivrs_mappings[alias_id].intremap_table == NULL )
+    {
+         /* allocate per-device interrupt remapping table */
+         if ( amd_iommu_perdev_intremap )
+             ivrs_mappings[alias_id].intremap_table =
+                amd_iommu_alloc_intremap_table();
+         else
+         {
+             if ( shared_intremap_table == NULL  )
+                 shared_intremap_table = amd_iommu_alloc_intremap_table();
+             ivrs_mappings[alias_id].intremap_table = shared_intremap_table;
+         }
+    }
     /* assgin iommu hardware */
     ivrs_mappings[bdf].iommu = iommu;
 }
diff -r 14cfa4efcce5 -r 7b58e660e8b3 xen/drivers/passthrough/amd/iommu_init.c
--- a/xen/drivers/passthrough/amd/iommu_init.c  Thu Nov 05 11:59:20 2009 +0000
+++ b/xen/drivers/passthrough/amd/iommu_init.c  Mon Nov 09 08:05:32 2009 +0000
@@ -698,7 +698,8 @@ static int __init init_ivrs_mapping(void
         ivrs_mappings[bdf].dte_ext_int_pass = IOMMU_CONTROL_DISABLED;
         ivrs_mappings[bdf].dte_init_pass = IOMMU_CONTROL_DISABLED;
 
-        spin_lock_init(&ivrs_mappings[bdf].intremap_lock);
+        if ( amd_iommu_perdev_intremap )
+            spin_lock_init(&ivrs_mappings[bdf].intremap_lock);
     }
     return 0;
 }
diff -r 14cfa4efcce5 -r 7b58e660e8b3 xen/drivers/passthrough/amd/iommu_intr.c
--- a/xen/drivers/passthrough/amd/iommu_intr.c  Thu Nov 05 11:59:20 2009 +0000
+++ b/xen/drivers/passthrough/amd/iommu_intr.c  Mon Nov 09 08:05:32 2009 +0000
@@ -27,6 +27,15 @@ extern struct ivrs_mappings *ivrs_mappin
 extern struct ivrs_mappings *ivrs_mappings;
 extern unsigned short ivrs_bdf_entries;
 extern int amd_iommu_enabled;
+void *shared_intremap_table;
+static DEFINE_SPINLOCK(shared_intremap_lock);
+
+static spinlock_t* get_intremap_lock(int req_id)
+{
+    return (amd_iommu_perdev_intremap ?
+           &ivrs_mappings[req_id].intremap_lock:
+           &shared_intremap_lock);
+}
 
 static int get_intremap_requestor_id(int bdf)
 {
@@ -102,8 +111,10 @@ static void update_intremap_entry_from_i
     u8 delivery_mode, dest, vector, dest_mode;
     struct IO_APIC_route_entry *rte = ioapic_rte;
     int req_id;
+    spinlock_t *lock;
 
     req_id = get_intremap_requestor_id(bdf);
+    lock = get_intremap_lock(req_id);
 
     /* only remap interrupt vector when lower 32 bits in ioapic ire changed */
     if ( likely(!rte_upper) )
@@ -113,10 +124,10 @@ static void update_intremap_entry_from_i
         dest_mode = rte->dest_mode;
         dest = rte->dest.logical.logical_dest;
 
-        spin_lock_irqsave(&ivrs_mappings[req_id].intremap_lock, flags);
+        spin_lock_irqsave(lock, flags);
         entry = (u32*)get_intremap_entry(req_id, vector, delivery_mode);
         update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest);
-        spin_unlock_irqrestore(&ivrs_mappings[req_id].intremap_lock, flags);
+        spin_unlock_irqrestore(lock, flags);
 
        if ( iommu->enabled )
         {
@@ -137,6 +148,7 @@ int __init amd_iommu_setup_ioapic_remapp
     u8 delivery_mode, dest, vector, dest_mode;
     u16 bdf, req_id;
     struct amd_iommu *iommu;
+    spinlock_t *lock;
 
     /* Read ioapic entries and update interrupt remapping table accordingly */
     for ( apic = 0; apic < nr_ioapics; apic++ )
@@ -160,15 +172,17 @@ int __init amd_iommu_setup_ioapic_remapp
             }
 
             req_id = get_intremap_requestor_id(bdf);
+            lock = get_intremap_lock(req_id);
+
             delivery_mode = rte.delivery_mode;
             vector = rte.vector;
             dest_mode = rte.dest_mode;
             dest = rte.dest.logical.logical_dest;
 
-            spin_lock_irqsave(&ivrs_mappings[req_id].intremap_lock, flags);
+            spin_lock_irqsave(lock, flags);
             entry = (u32*)get_intremap_entry(req_id, vector, delivery_mode);
             update_intremap_entry(entry, vector, delivery_mode, dest_mode, 
dest);
-            spin_unlock_irqrestore(&ivrs_mappings[req_id].intremap_lock, 
flags);
+            spin_unlock_irqrestore(lock, flags);
 
             if ( iommu->enabled )
             {
@@ -235,13 +249,14 @@ static void update_intremap_entry_from_m
     unsigned long flags;
     u32* entry;
     u16 bdf, req_id, alias_id;
-
     u8 delivery_mode, dest, vector, dest_mode;
+    spinlock_t *lock;
 
     bdf = (pdev->bus << 8) | pdev->devfn;
     req_id = get_dma_requestor_id(bdf);
-
-    spin_lock_irqsave(&ivrs_mappings[req_id].intremap_lock, flags);
+    lock = get_intremap_lock(req_id);
+
+    spin_lock_irqsave(lock, flags);
     dest_mode = (msg->address_lo >> MSI_ADDR_DESTMODE_SHIFT) & 0x1;
     delivery_mode = (msg->data >> MSI_DATA_DELIVERY_MODE_SHIFT) & 0x1;
     vector = (msg->data >> MSI_DATA_VECTOR_SHIFT) & MSI_DATA_VECTOR_MASK;
@@ -249,7 +264,7 @@ static void update_intremap_entry_from_m
 
     entry = (u32*)get_intremap_entry(req_id, vector, delivery_mode);
     update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest);
-    spin_unlock_irqrestore(&ivrs_mappings[req_id].intremap_lock, flags);
+    spin_unlock_irqrestore(lock, flags);
 
     /*
      * In some special cases, a pci-e device(e.g SATA controller in IDE mode)
@@ -258,14 +273,15 @@ static void update_intremap_entry_from_m
      * devices.
      */
     alias_id = get_intremap_requestor_id(bdf);
+    lock = get_intremap_lock(alias_id);
     if ( ( bdf != alias_id ) &&
         ivrs_mappings[alias_id].intremap_table != NULL )
     {
-        spin_lock_irqsave(&ivrs_mappings[alias_id].intremap_lock, flags);
+        spin_lock_irqsave(lock, flags);
         entry = (u32*)get_intremap_entry(alias_id, vector, delivery_mode);
         update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest);
         invalidate_interrupt_table(iommu, alias_id);
-        spin_unlock_irqrestore(&ivrs_mappings[alias_id].intremap_lock, flags);
+        spin_unlock_irqrestore(lock, flags);
     }
 
     if ( iommu->enabled )
diff -r 14cfa4efcce5 -r 7b58e660e8b3 xen/drivers/passthrough/iommu.c
--- a/xen/drivers/passthrough/iommu.c   Thu Nov 05 11:59:20 2009 +0000
+++ b/xen/drivers/passthrough/iommu.c   Mon Nov 09 08:05:32 2009 +0000
@@ -47,6 +47,7 @@ int iommu_qinval = 0;
 int iommu_qinval = 0;
 int iommu_intremap = 0;
 int amd_iommu_debug = 0;
+int amd_iommu_perdev_intremap = 0;
 
 static void __init parse_iommu_param(char *s)
 {
@@ -55,6 +56,8 @@ static void __init parse_iommu_param(cha
     iommu_snoop = 1;
     iommu_qinval = 1;
     iommu_intremap = 1;
+    amd_iommu_debug = 0;
+    amd_iommu_perdev_intremap = 0;
 
     do {
         ss = strchr(s, ',');
@@ -80,6 +83,8 @@ static void __init parse_iommu_param(cha
             iommu_intremap = 0;
         else if ( !strcmp(s, "amd-iommu-debug") )
             amd_iommu_debug = 1;
+        else if ( !strcmp(s, "amd-iommu-perdev-intremap") )
+            amd_iommu_perdev_intremap = 1;
 
         s = ss + 1;
     } while ( ss );
diff -r 14cfa4efcce5 -r 7b58e660e8b3 
xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
--- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h     Thu Nov 05 11:59:20 
2009 +0000
+++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h     Mon Nov 09 08:05:32 
2009 +0000
@@ -33,6 +33,7 @@
 #define PAGE_ALIGN(addr)    (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
 
 extern int amd_iommu_debug;
+extern int amd_iommu_perdev_intremap;
 
 #define AMD_IOMMU_DEBUG(fmt, args...) \
     do  \

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-3.4-testing] AMD IOMMU: Use global interrupt remapping table by default, Xen patchbot-3.4-testing <=