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] vt-d: use 32-bit Destination ID when Inte

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] vt-d: use 32-bit Destination ID when Interrupt Remapping with EIM is
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 07 Sep 2009 01:05:29 -0700
Delivery-date: Mon, 07 Sep 2009 01:06:29 -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 1252309563 -3600
# Node ID cb249398f3eff1560b2a4934b0da08ec6b355eba
# Parent  be45bf6fe25135cf704d9621faa1742cc7f74e7e
vt-d: use 32-bit Destination ID when Interrupt Remapping with EIM is
enabled

When x2APIC and Interrupt Remapping(IR) with EIM are enabled, we
should use 32-bit Destination ID for IOAPIC and MSI.

We implemented the IR support in xen by hooking the functions like
io_apic_write(),io_apic_modify(), write_msi_message(), and as a
result, in the hook functions in intremap.c, we can only see the 8-bit
dest id rather the 32-bit id, so we can't set IR table Entry that
requires a 32-bit dest id.

To solve the issue throughly, we need find every place in io_apic.c
and msi.c that could write ioapic RTE and and device's msi message and
explicitly handle the 32-bit dest id carefully (namely, when genapic
is x2apic, cpu_mask_to_apic could return a 32-bit value); and we have
to change the iommu_ops->{.update_ire_from_apic, .update_ire_from_msi}
interfaces. We may have to write an over-1000-LOC patch for this.

Instead, we could use a workround:
1) for ioapic, in the struct IO_APIC_route_entry, we could use a new
"dest32" to refer to the dest field;
2) for msi, in the struct msi_msg, we could add a new "u32 dest".
And in intremap.c, if x2apic_enabled, we use the new names to refer to
the dest fields.

We can improve this in future.

Signed-off-by: Dexuan Cui <dexuan.cui@xxxxxxxxx>
---
 xen/arch/x86/io_apic.c                 |   28 +++++++++++++++++-----------
 xen/arch/x86/msi.c                     |    2 ++
 xen/drivers/passthrough/vtd/intremap.c |   12 +++++++++---
 xen/include/asm-x86/io_apic.h          |    3 +++
 xen/include/asm-x86/msi.h              |    1 +
 5 files changed, 32 insertions(+), 14 deletions(-)

diff -r be45bf6fe251 -r cb249398f3ef xen/arch/x86/io_apic.c
--- a/xen/arch/x86/io_apic.c    Mon Sep 07 08:44:50 2009 +0100
+++ b/xen/arch/x86/io_apic.c    Mon Sep 07 08:46:03 2009 +0100
@@ -355,8 +355,8 @@ set_ioapic_affinity_irq_desc(struct irq_
     spin_lock_irqsave(&ioapic_lock, flags);
     dest = set_desc_affinity(desc, mask);
     if (dest != BAD_APICID) {
-        /* Only the high 8 bits are valid. */
-        dest = SET_APIC_LOGICAL_ID(dest);
+        if ( !x2apic_enabled )
+            dest = SET_APIC_LOGICAL_ID(dest);
         entry = irq_2_pin + irq;
         for (;;) {
             unsigned int data;
@@ -769,6 +769,9 @@ static struct hw_interrupt_type ioapic_e
 #define IOAPIC_AUTO    -1
 #define IOAPIC_EDGE    0
 #define IOAPIC_LEVEL   1
+
+#define SET_DEST(x, y, value) \
+    do { if ( x2apic_enabled ) x = value; else y = value; } while(0)
 
 static inline void ioapic_register_intr(int irq, unsigned long trigger)
 {
@@ -845,8 +848,8 @@ static void __init setup_IO_APIC_irqs(vo
                     disable_8259A_irq(irq);
             }
             cfg = irq_cfg(irq);
-            entry.dest.logical.logical_dest = 
-                cpu_mask_to_apicid(cfg->domain);
+            SET_DEST(entry.dest.dest32, entry.dest.logical.logical_dest,
+                cpu_mask_to_apicid(cfg->domain));
             spin_lock_irqsave(&ioapic_lock, flags);
             io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
             io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
@@ -880,7 +883,8 @@ static void __init setup_ExtINT_IRQ0_pin
      */
     entry.dest_mode = INT_DEST_MODE;
     entry.mask = 0;                                    /* unmask IRQ now */
-    entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
+    SET_DEST(entry.dest.dest32, entry.dest.logical.logical_dest,
+        cpu_mask_to_apicid(TARGET_CPUS));
     entry.delivery_mode = INT_DELIVERY_MODE;
     entry.polarity = 0;
     entry.trigger = 0;
@@ -1156,8 +1160,8 @@ void disable_IO_APIC(void)
         entry.dest_mode       = 0; /* Physical */
         entry.delivery_mode   = dest_ExtINT; /* ExtInt */
         entry.vector          = 0;
-        entry.dest.physical.physical_dest =
-            get_apic_id();
+        SET_DEST(entry.dest.dest32, entry.dest.physical.physical_dest,
+            get_apic_id());
 
         /*
          * Add it to the IO-APIC irq-routing table:
@@ -1667,7 +1671,8 @@ static inline void unlock_ExtINT_logic(v
 
     entry1.dest_mode = 0;                      /* physical delivery */
     entry1.mask = 0;                   /* unmask IRQ now */
-    entry1.dest.physical.physical_dest = hard_smp_processor_id();
+    SET_DEST(entry1.dest.dest32, entry1.dest.physical.physical_dest,
+        hard_smp_processor_id());
     entry1.delivery_mode = dest_ExtINT;
     entry1.polarity = entry0.polarity;
     entry1.trigger = 0;
@@ -2051,7 +2056,8 @@ int io_apic_set_pci_routing (int ioapic,
 
     entry.delivery_mode = INT_DELIVERY_MODE;
     entry.dest_mode = INT_DEST_MODE;
-    entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
+    SET_DEST(entry.dest.dest32, entry.dest.logical.logical_dest,
+        cpu_mask_to_apicid(TARGET_CPUS));
     entry.trigger = edge_level;
     entry.polarity = active_high_low;
     entry.mask  = 1;
@@ -2230,8 +2236,8 @@ int ioapic_guest_write(unsigned long phy
     /* Set the vector field to the real vector! */
     rte.vector = cfg->vector;
 
-    rte.dest.logical.logical_dest = 
-    cpu_mask_to_apicid(cfg->domain);
+    SET_DEST(rte.dest.dest32, rte.dest.logical.logical_dest,
+        cpu_mask_to_apicid(cfg->domain));
 
     io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&rte) + 0));
     io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&rte) + 1));
diff -r be45bf6fe251 -r cb249398f3ef xen/arch/x86/msi.c
--- a/xen/arch/x86/msi.c        Mon Sep 07 08:44:50 2009 +0100
+++ b/xen/arch/x86/msi.c        Mon Sep 07 08:46:03 2009 +0100
@@ -144,6 +144,7 @@ void msi_compose_msg(struct pci_dev *pde
              MSI_ADDR_REDIRECTION_CPU:
              MSI_ADDR_REDIRECTION_LOWPRI) |
             MSI_ADDR_DEST_ID(dest);
+        msg->dest32 = dest;
 
         msg->data =
             MSI_DATA_TRIGGER_EDGE |
@@ -283,6 +284,7 @@ void set_msi_affinity(unsigned int irq, 
     msg.data |= MSI_DATA_VECTOR(cfg->vector);
     msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
     msg.address_lo |= MSI_ADDR_DEST_ID(dest);
+    msg.dest32 = dest;
 
     write_msi_msg(msi_desc, &msg);
 }
diff -r be45bf6fe251 -r cb249398f3ef xen/drivers/passthrough/vtd/intremap.c
--- a/xen/drivers/passthrough/vtd/intremap.c    Mon Sep 07 08:44:50 2009 +0100
+++ b/xen/drivers/passthrough/vtd/intremap.c    Mon Sep 07 08:46:03 2009 +0100
@@ -225,7 +225,10 @@ static int ioapic_rte_to_remap_entry(str
     if ( rte_upper )
     {
 #if defined(__i386__) || defined(__x86_64__)
-        new_ire.lo.dst = (value >> 24) << 8;
+        if ( x2apic_enabled )
+            new_ire.lo.dst = value;
+        else
+            new_ire.lo.dst = (value >> 24) << 8;
 #else /* __ia64__ */
         new_ire.lo.dst = value >> 16;
 #endif
@@ -552,8 +555,11 @@ static int msi_msg_to_remap_entry(
     new_ire.lo.vector = (msg->data >> MSI_DATA_VECTOR_SHIFT) &
                         MSI_DATA_VECTOR_MASK;
     new_ire.lo.res_2 = 0;
-    new_ire.lo.dst = ((msg->address_lo >> MSI_ADDR_DEST_ID_SHIFT)
-                      & 0xff) << 8;
+    if ( x2apic_enabled )
+        new_ire.lo.dst = msg->dest32;
+    else
+        new_ire.lo.dst = ((msg->address_lo >> MSI_ADDR_DEST_ID_SHIFT)
+                          & 0xff) << 8;
 
     set_msi_source_id(pdev, &new_ire);
     new_ire.hi.res_1 = 0;
diff -r be45bf6fe251 -r cb249398f3ef xen/include/asm-x86/io_apic.h
--- a/xen/include/asm-x86/io_apic.h     Mon Sep 07 08:44:50 2009 +0100
+++ b/xen/include/asm-x86/io_apic.h     Mon Sep 07 08:46:03 2009 +0100
@@ -105,6 +105,9 @@ struct IO_APIC_route_entry {
                                        __reserved_1    : 24,
                                        logical_dest    :  8;
                        } logical;
+
+                       /* used when Interrupt Remapping with EIM is enabled */
+                       __u32 dest32;
        } dest;
 
 } __attribute__ ((packed));
diff -r be45bf6fe251 -r cb249398f3ef xen/include/asm-x86/msi.h
--- a/xen/include/asm-x86/msi.h Mon Sep 07 08:44:50 2009 +0100
+++ b/xen/include/asm-x86/msi.h Mon Sep 07 08:46:03 2009 +0100
@@ -65,6 +65,7 @@ struct msi_msg {
        u32     address_lo;     /* low 32 bits of msi message address */
        u32     address_hi;     /* high 32 bits of msi message address */
        u32     data;           /* 16 bits of msi message data */
+       u32     dest32;         /* used when Interrupt Remapping with EIM is 
enabled */
 };
 
 struct msi_desc;

_______________________________________________
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] vt-d: use 32-bit Destination ID when Interrupt Remapping with EIM is, Xen patchbot-unstable <=