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

[Xen-changelog] [xen-3.4-testing] vt-d: don't treat IOAPIC RTE of dest_SMI type specially.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1254408997 -3600
# Node ID dd4213e75210fda21c5054e526ca1655eaa20d53
# Parent  065976816758044334a4f6326c1637e1f263c59f
vt-d: don't treat IOAPIC RTE of dest_SMI type specially.

We also need to create IRTE for it since we enable EIM and clear CFI,
or else, the IOAPIC RTE's interrupt message would be blocked by IR
unit.

In io_apic_read_remap_rte(), we now use
"apic_pin_2_ir_idx[apic][ioapic_pin]"
rather than "(remap_rte->index_15 << 15) | remap_rte->index_0_14" to
avoid the "interrupt remapping table out of bound error".

Signed-off-by: Dexuan Cui <dexuan.cui@xxxxxxxxx>
xen-unstable changeset:   20178:7c8a33ed6dec
xen-unstable date:        Mon Sep 07 13:52:17 2009 +0100
---
 xen/drivers/passthrough/vtd/intremap.c |   46 ++++-----------------------------
 1 files changed, 6 insertions(+), 40 deletions(-)

diff -r 065976816758 -r dd4213e75210 xen/drivers/passthrough/vtd/intremap.c
--- a/xen/drivers/passthrough/vtd/intremap.c    Thu Oct 01 15:56:06 2009 +0100
+++ b/xen/drivers/passthrough/vtd/intremap.c    Thu Oct 01 15:56:37 2009 +0100
@@ -32,7 +32,6 @@
 #include "extern.h"
 
 #ifdef __ia64__
-#define dest_SMI -1
 #define nr_ioapics              iosapic_get_nr_iosapics()
 #define nr_ioapic_registers(i)  iosapic_get_nr_pins(i)
 #else
@@ -91,11 +90,9 @@ u16 apicid_to_bdf(int apic_id)
 }
 
 static int remap_entry_to_ioapic_rte(
-    struct iommu *iommu, struct IO_xAPIC_route_entry *old_rte)
+    struct iommu *iommu, int index, struct IO_xAPIC_route_entry *old_rte)
 {
     struct iremap_entry *iremap_entry = NULL, *iremap_entries;
-    struct IO_APIC_route_remap_entry *remap_rte;
-    int index = 0;
     unsigned long flags;
     struct ir_ctrl *ir_ctrl = iommu_ir_ctrl(iommu);
 
@@ -105,9 +102,6 @@ static int remap_entry_to_ioapic_rte(
                 "remap_entry_to_ioapic_rte: ir_ctl is not ready\n");
         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 )
     {
@@ -230,6 +224,8 @@ unsigned int io_apic_read_remap_rte(
 unsigned int io_apic_read_remap_rte(
     unsigned int apic, unsigned int reg)
 {
+    unsigned int ioapic_pin = (reg - 0x10) / 2;
+    int index;
     struct IO_xAPIC_route_entry old_rte = { 0 };
     struct IO_APIC_route_remap_entry *remap_rte;
     int rte_upper = (reg & 1) ? 1 : 0;
@@ -237,7 +233,8 @@ unsigned int io_apic_read_remap_rte(
     struct ir_ctrl *ir_ctrl = iommu_ir_ctrl(iommu);
 
     if ( !iommu || !ir_ctrl || ir_ctrl->iremap_maddr == 0 ||
-         ir_ctrl->iremap_index == -1 )
+        (ir_ctrl->iremap_index == -1) ||
+        ( (index = apic_pin_2_ir_idx[apic][ioapic_pin]) < 0 ) )
     {
         *IO_APIC_BASE(apic) = reg;
         return *(IO_APIC_BASE(apic)+4);
@@ -254,13 +251,7 @@ unsigned int io_apic_read_remap_rte(
 
     remap_rte = (struct IO_APIC_route_remap_entry *) &old_rte;
 
-    if ( (remap_rte->format == 0) || (old_rte.delivery_mode == dest_SMI) )
-    {
-        *IO_APIC_BASE(apic) = rte_upper ? (reg + 1) : reg;
-        return *(IO_APIC_BASE(apic)+4);
-    }
-
-    if ( remap_entry_to_ioapic_rte(iommu, &old_rte) )
+    if ( remap_entry_to_ioapic_rte(iommu, index, &old_rte) )
     {
         *IO_APIC_BASE(apic) = rte_upper ? (reg + 1) : reg;
         return *(IO_APIC_BASE(apic)+4);
@@ -300,31 +291,6 @@ void io_apic_write_remap_rte(
     *(((u32 *)&old_rte) + 1) = *(IO_APIC_BASE(apic)+4);
 
     remap_rte = (struct IO_APIC_route_remap_entry *) &old_rte;
-
-    if ( old_rte.delivery_mode == dest_SMI )
-    {
-        /* Some BIOS does not zero out reserve fields in IOAPIC
-         * RTE's.  clear_IO_APIC() zeroes out all RTE's except for RTE
-         * with MSI delivery type.  This is a problem when the host
-         * OS converts SMI delivery type to some other type but leaving
-         * the reserved field uninitialized.  This can cause interrupt
-         * remapping table out of bound error if "format" field is 1
-         * and the "index" field has a value that that is larger than 
-         * the maximum index of interrupt remapping table.
-         */
-        if ( remap_rte->format == 1 )
-        {
-            remap_rte->format = 0;
-            *IO_APIC_BASE(apic) = reg;
-            *(IO_APIC_BASE(apic)+4) = *(((u32 *)&old_rte)+0);
-            *IO_APIC_BASE(apic) = reg + 1;
-            *(IO_APIC_BASE(apic)+4) = *(((u32 *)&old_rte)+1);
-        }
-
-        *IO_APIC_BASE(apic) = rte_upper ? (reg + 1) : reg;
-        *(IO_APIC_BASE(apic)+4) = value;
-        return;
-    }
 
     /* mask the interrupt while we change the intremap table */
     saved_mask = remap_rte->mask;

_______________________________________________
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®.