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] vtd: Fix ioapic interrupt remapping

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] vtd: Fix ioapic interrupt remapping
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 27 Aug 2008 11:23:19 -0700
Delivery-date: Wed, 27 Aug 2008 11:23:08 -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 1219752043 -3600
# Node ID 62b904dcf88c4549620741fcd16e9b33b53ea289
# Parent  21294d41c26e60a7bfe3759b6cb1acc8788c6045
vtd: Fix ioapic interrupt remapping

Besides io_apic_write(), io_apic_modify() also writes to io apic RTE.
This patch adds an intercept to remap interrupt in io_apic_modify().

In io_apic_read_remap_rte(), 'mask' value of RTE should not affect the
return value, so remove its checking.

Finally, remove panic() when index overflows. Instead, print error
messages and report back the failure to upper level.

Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx>
---
 xen/drivers/passthrough/vtd/intremap.c |   89 +++++++++++++++++++++------------
 xen/include/asm-x86/io_apic.h          |    4 +
 2 files changed, 62 insertions(+), 31 deletions(-)

diff -r 21294d41c26e -r 62b904dcf88c xen/drivers/passthrough/vtd/intremap.c
--- a/xen/drivers/passthrough/vtd/intremap.c    Tue Aug 26 10:14:32 2008 +0100
+++ b/xen/drivers/passthrough/vtd/intremap.c    Tue Aug 26 13:00:43 2008 +0100
@@ -43,7 +43,7 @@ u16 apicid_to_bdf(int apic_id)
     return 0;
 }
 
-static void remap_entry_to_ioapic_rte(
+static int remap_entry_to_ioapic_rte(
     struct iommu *iommu, struct IO_APIC_route_entry *old_rte)
 {
     struct iremap_entry *iremap_entry = NULL, *iremap_entries;
@@ -56,15 +56,19 @@ static void remap_entry_to_ioapic_rte(
     {
         dprintk(XENLOG_ERR VTDPREFIX,
                 "remap_entry_to_ioapic_rte: ir_ctl is not ready\n");
-        return;
+        return -EFAULT;
     }
 
     remap_rte = (struct IO_APIC_route_remap_entry *) old_rte;
     index = (remap_rte->index_15 << 15) | remap_rte->index_0_14;
 
     if ( index > ir_ctrl->iremap_index )
-        panic("%s: index (%d) is larger than remap table entry size (%d)!\n",
-              __func__, index, ir_ctrl->iremap_index);
+    {
+        dprintk(XENLOG_ERR VTDPREFIX,
+                "%s: index (%d) is larger than remap table entry size (%d)!\n",
+                __func__, index, ir_ctrl->iremap_index);
+        return -EFAULT;
+    }
 
     spin_lock_irqsave(&ir_ctrl->iremap_lock, flags);
 
@@ -82,9 +86,10 @@ static void remap_entry_to_ioapic_rte(
 
     unmap_vtd_domain_page(iremap_entries);
     spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
-}
-
-static void ioapic_rte_to_remap_entry(struct iommu *iommu,
+    return 0;
+}
+
+static int ioapic_rte_to_remap_entry(struct iommu *iommu,
     int apic_id, struct IO_APIC_route_entry *old_rte,
     unsigned int rte_upper, unsigned int value)
 {
@@ -108,7 +113,14 @@ static void ioapic_rte_to_remap_entry(st
         index = (remap_rte->index_15 << 15) | remap_rte->index_0_14;
 
     if ( index > IREMAP_ENTRY_NR - 1 )
-        panic("ioapic_rte_to_remap_entry: intremap index is more than 256!\n");
+    {
+        dprintk(XENLOG_ERR VTDPREFIX,
+                "%s: intremap index (%d) is larger than"
+                " the maximum index (%ld)!\n",
+                __func__, index, IREMAP_ENTRY_NR - 1);
+        spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
+        return -EFAULT;
+    }
 
     iremap_entries =
         (struct iremap_entry *)map_vtd_domain_page(ir_ctrl->iremap_maddr);
@@ -159,7 +171,7 @@ static void ioapic_rte_to_remap_entry(st
 
     unmap_vtd_domain_page(iremap_entries);
     spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
-    return;
+    return 0;
 }
 
 unsigned int io_apic_read_remap_rte(
@@ -189,23 +201,22 @@ unsigned int io_apic_read_remap_rte(
 
     remap_rte = (struct IO_APIC_route_remap_entry *) &old_rte;
 
-    if ( remap_rte->mask || (remap_rte->format == 0) )
-    {
-        *IO_APIC_BASE(apic) = reg;
+    if ( remap_rte->format == 0 )
+    {
+        *IO_APIC_BASE(apic) = rte_upper ? (reg + 1) : reg;
         return *(IO_APIC_BASE(apic)+4);
     }
 
-    remap_entry_to_ioapic_rte(iommu, &old_rte);
+    if ( remap_entry_to_ioapic_rte(iommu, &old_rte) )
+    {
+        *IO_APIC_BASE(apic) = rte_upper ? (reg + 1) : reg;
+        return *(IO_APIC_BASE(apic)+4);
+    }
+
     if ( rte_upper )
-    {
-        *IO_APIC_BASE(apic) = reg + 1;
         return (*(((u32 *)&old_rte) + 1));
-    }
     else
-    {
-        *IO_APIC_BASE(apic) = reg;
         return (*(((u32 *)&old_rte) + 0));
-    }
 }
 
 void io_apic_write_remap_rte(
@@ -243,8 +254,13 @@ void io_apic_write_remap_rte(
     *(IO_APIC_BASE(apic)+4) = *(((int *)&old_rte)+0);
     remap_rte->mask = saved_mask;
 
-    ioapic_rte_to_remap_entry(iommu, mp_ioapics[apic].mpc_apicid,
-                              &old_rte, rte_upper, value);
+    if ( ioapic_rte_to_remap_entry(iommu, mp_ioapics[apic].mpc_apicid,
+                                   &old_rte, rte_upper, value) )
+    {
+        *IO_APIC_BASE(apic) = rte_upper ? (reg + 1) : reg;
+        *(IO_APIC_BASE(apic)+4) = value;
+        return;
+    }
 
     /* write new entry to ioapic */
     *IO_APIC_BASE(apic) = reg;
@@ -253,7 +269,7 @@ void io_apic_write_remap_rte(
     *(IO_APIC_BASE(apic)+4) = *(((u32 *)&old_rte)+1);
 }
 
-static void remap_entry_to_msi_msg(
+static int remap_entry_to_msi_msg(
     struct iommu *iommu, struct msi_msg *msg)
 {
     struct iremap_entry *iremap_entry = NULL, *iremap_entries;
@@ -266,7 +282,7 @@ static void remap_entry_to_msi_msg(
     {
         dprintk(XENLOG_ERR VTDPREFIX,
                 "remap_entry_to_msi_msg: ir_ctl == NULL");
-        return;
+        return -EFAULT;
     }
 
     remap_rte = (struct msi_msg_remap_entry *) msg;
@@ -274,8 +290,12 @@ static void remap_entry_to_msi_msg(
              remap_rte->address_lo.index_0_14;
 
     if ( index > ir_ctrl->iremap_index )
-        panic("%s: index (%d) is larger than remap table entry size (%d)\n",
-              __func__, index, ir_ctrl->iremap_index);
+    {
+        dprintk(XENLOG_ERR VTDPREFIX,
+                "%s: index (%d) is larger than remap table entry size (%d)\n",
+                __func__, index, ir_ctrl->iremap_index);
+        return -EFAULT;
+    }
 
     spin_lock_irqsave(&ir_ctrl->iremap_lock, flags);
 
@@ -304,9 +324,10 @@ static void remap_entry_to_msi_msg(
 
     unmap_vtd_domain_page(iremap_entries);
     spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
-}
-
-static void msi_msg_to_remap_entry(
+    return 0;
+}
+
+static int msi_msg_to_remap_entry(
     struct iommu *iommu, struct pci_dev *pdev, struct msi_msg *msg)
 {
     struct iremap_entry *iremap_entry = NULL, *iremap_entries;
@@ -343,7 +364,15 @@ static void msi_msg_to_remap_entry(
         index = i;
 
     if ( index > IREMAP_ENTRY_NR - 1 )
-        panic("msi_msg_to_remap_entry: intremap index is more than 256!\n");
+    {
+        dprintk(XENLOG_ERR VTDPREFIX,
+                "%s: intremap index (%d) is larger than"
+                " the maximum index (%ld)!\n",
+                __func__, index, IREMAP_ENTRY_NR - 1);
+        unmap_vtd_domain_page(iremap_entries);
+        spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
+        return -EFAULT;
+    }
 
     iremap_entry = &iremap_entries[index];
     memcpy(&new_ire, iremap_entry, sizeof(struct iremap_entry));
@@ -385,7 +414,7 @@ static void msi_msg_to_remap_entry(
 
     unmap_vtd_domain_page(iremap_entries);
     spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
-    return;
+    return 0;
 }
 
 void msi_msg_read_remap_rte(
diff -r 21294d41c26e -r 62b904dcf88c xen/include/asm-x86/io_apic.h
--- a/xen/include/asm-x86/io_apic.h     Tue Aug 26 10:14:32 2008 +0100
+++ b/xen/include/asm-x86/io_apic.h     Tue Aug 26 13:00:43 2008 +0100
@@ -125,7 +125,7 @@ extern int mpc_default_type;
 
 static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
 {
-       if (vtd_enabled)
+       if (iommu_enabled)
                return io_apic_read_remap_rte(apic, reg);
        *IO_APIC_BASE(apic) = reg;
        return *(IO_APIC_BASE(apic)+4);
@@ -152,6 +152,8 @@ extern int sis_apic_bug;
 #endif
 static inline void io_apic_modify(unsigned int apic, unsigned int reg, 
unsigned int value)
 {
+       if (iommu_enabled)
+               return iommu_update_ire_from_apic(apic, reg, value);
        if (sis_apic_bug)
                *IO_APIC_BASE(apic) = reg;
        *(IO_APIC_BASE(apic)+4) = value;

_______________________________________________
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] vtd: Fix ioapic interrupt remapping, Xen patchbot-unstable <=