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] x86: vMSI: Fix msi irq affinity issue for

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86: vMSI: Fix msi irq affinity issue for hvm guest.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 19 Oct 2009 04:00:22 -0700
Delivery-date: Mon, 19 Oct 2009 04:00:45 -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 1255945846 -3600
# Node ID dcc5d5d954e942efd9a143ff3d5769e82178ecad
# Parent  24dd0e4261a8aa16d3622f100b8470082ed037e5
x86: vMSI: Fix msi irq affinity issue for hvm guest.

There is a race between guest setting new vector and doing EOI on old
vector.  Once guest sets new vector before its doing EOI on vector,
when guest does eoi, hypervisor may fail to find the related pirq, and
hypervisor may miss to EOI real vector and leads to system hang.  We
may need to add a timer for each pirq interrupt source to avoid host
hang, but this is another topic, and will be addressed later.

Signed-off-by: Xiantao Zhang <xiantao.zhang@xxxxxxxxx>
---
 xen/arch/x86/hvm/vmsi.c      |   10 ++++++++--
 xen/drivers/passthrough/io.c |   27 ++++++++++++++++++++++-----
 xen/include/xen/hvm/irq.h    |    4 +++-
 3 files changed, 33 insertions(+), 8 deletions(-)

diff -r 24dd0e4261a8 -r dcc5d5d954e9 xen/arch/x86/hvm/vmsi.c
--- a/xen/arch/x86/hvm/vmsi.c   Mon Oct 19 10:49:23 2009 +0100
+++ b/xen/arch/x86/hvm/vmsi.c   Mon Oct 19 10:50:46 2009 +0100
@@ -92,8 +92,11 @@ int vmsi_deliver(struct domain *d, int p
     case dest_LowestPrio:
     {
         target = vlapic_lowest_prio(d, NULL, 0, dest, dest_mode);
-        if ( target != NULL )
+        if ( target != NULL ) {
             vmsi_inj_irq(d, target, vector, trig_mode, delivery_mode);
+            hvm_irq_dpci->mirq[pirq].gmsi.old_gvec =
+                                    hvm_irq_dpci->mirq[pirq].gmsi.gvec;
+        }
         else
             HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "null round robin: "
                         "vector=%x delivery_mode=%x\n",
@@ -106,9 +109,12 @@ int vmsi_deliver(struct domain *d, int p
     {
         for_each_vcpu ( d, v )
             if ( vlapic_match_dest(vcpu_vlapic(v), NULL,
-                                   0, dest, dest_mode) )
+                                   0, dest, dest_mode) ) {
                 vmsi_inj_irq(d, vcpu_vlapic(v),
                              vector, trig_mode, delivery_mode);
+                hvm_irq_dpci->mirq[pirq].gmsi.old_gvec =
+                                    hvm_irq_dpci->mirq[pirq].gmsi.gvec;
+            }
         break;
     }
 
diff -r 24dd0e4261a8 -r dcc5d5d954e9 xen/drivers/passthrough/io.c
--- a/xen/drivers/passthrough/io.c      Mon Oct 19 10:49:23 2009 +0100
+++ b/xen/drivers/passthrough/io.c      Mon Oct 19 10:50:46 2009 +0100
@@ -164,7 +164,9 @@ int pt_irq_create_bind_vtd(
         {
             hvm_irq_dpci->mirq[pirq].flags = HVM_IRQ_DPCI_MACH_MSI |
                                              HVM_IRQ_DPCI_GUEST_MSI;
+            hvm_irq_dpci->mirq[pirq].gmsi.old_gvec = pt_irq_bind->u.msi.gvec;
             hvm_irq_dpci->mirq[pirq].gmsi.gvec = pt_irq_bind->u.msi.gvec;
+            hvm_irq_dpci->mirq[pirq].gmsi.old_gflags = 
pt_irq_bind->u.msi.gflags;
             hvm_irq_dpci->mirq[pirq].gmsi.gflags = pt_irq_bind->u.msi.gflags;
             /* bind after hvm_irq_dpci is setup to avoid race with irq 
handler*/
             rc = pirq_guest_bind(d->vcpu[0], pirq, 0);
@@ -178,6 +180,8 @@ int pt_irq_create_bind_vtd(
             {
                 hvm_irq_dpci->mirq[pirq].gmsi.gflags = 0;
                 hvm_irq_dpci->mirq[pirq].gmsi.gvec = 0;
+                hvm_irq_dpci->mirq[pirq].gmsi.old_gvec = 0;
+                hvm_irq_dpci->mirq[pirq].gmsi.old_gflags = 0;
                 hvm_irq_dpci->mirq[pirq].flags = 0;
                 clear_bit(pirq, hvm_irq_dpci->mapping);
                 spin_unlock(&d->event_lock);
@@ -195,8 +199,14 @@ int pt_irq_create_bind_vtd(
             }
  
             /* if pirq is already mapped as vmsi, update the guest data/addr */
-            hvm_irq_dpci->mirq[pirq].gmsi.gvec = pt_irq_bind->u.msi.gvec;
-            hvm_irq_dpci->mirq[pirq].gmsi.gflags = pt_irq_bind->u.msi.gflags;
+            if ( hvm_irq_dpci->mirq[pirq].gmsi.gvec != pt_irq_bind->u.msi.gvec 
) {
+                hvm_irq_dpci->mirq[pirq].gmsi.old_gvec =
+                                    hvm_irq_dpci->mirq[pirq].gmsi.gvec;
+                hvm_irq_dpci->mirq[pirq].gmsi.old_gflags =
+                                    hvm_irq_dpci->mirq[pirq].gmsi.gflags;
+                hvm_irq_dpci->mirq[pirq].gmsi.gvec = pt_irq_bind->u.msi.gvec;
+                hvm_irq_dpci->mirq[pirq].gmsi.gflags = 
pt_irq_bind->u.msi.gflags;
+            }
         }
         /* Caculate dest_vcpu_id for MSI-type pirq migration */
         dest = hvm_irq_dpci->mirq[pirq].gmsi.gflags & VMSI_DEST_ID_MASK;
@@ -424,14 +434,21 @@ void hvm_dpci_msi_eoi(struct domain *d, 
           pirq = find_next_bit(hvm_irq_dpci->mapping, d->nr_pirqs, pirq + 1) )
     {
         if ( (!(hvm_irq_dpci->mirq[pirq].flags & HVM_IRQ_DPCI_MACH_MSI)) ||
-                (hvm_irq_dpci->mirq[pirq].gmsi.gvec != vector) )
+                (hvm_irq_dpci->mirq[pirq].gmsi.gvec != vector &&
+                 hvm_irq_dpci->mirq[pirq].gmsi.old_gvec != vector) )
             continue;
 
-        dest = hvm_irq_dpci->mirq[pirq].gmsi.gflags & VMSI_DEST_ID_MASK;
-        dest_mode = !!(hvm_irq_dpci->mirq[pirq].gmsi.gflags & VMSI_DM_MASK);
+        if ( hvm_irq_dpci->mirq[pirq].gmsi.gvec == vector ) {
+            dest = hvm_irq_dpci->mirq[pirq].gmsi.gflags & VMSI_DEST_ID_MASK;
+            dest_mode = !!(hvm_irq_dpci->mirq[pirq].gmsi.gflags & 
VMSI_DM_MASK);
+        } else {
+            dest = hvm_irq_dpci->mirq[pirq].gmsi.old_gflags & 
VMSI_DEST_ID_MASK;
+            dest_mode = !!(hvm_irq_dpci->mirq[pirq].gmsi.old_gflags & 
VMSI_DM_MASK);
+        }
         if ( vlapic_match_dest(vcpu_vlapic(current), NULL, 0, dest, dest_mode) 
)
             break;
     }
+
     if ( pirq < d->nr_pirqs )
         __msi_pirq_eoi(d, pirq);
     spin_unlock(&d->event_lock);
diff -r 24dd0e4261a8 -r dcc5d5d954e9 xen/include/xen/hvm/irq.h
--- a/xen/include/xen/hvm/irq.h Mon Oct 19 10:49:23 2009 +0100
+++ b/xen/include/xen/hvm/irq.h Mon Oct 19 10:50:46 2009 +0100
@@ -58,8 +58,10 @@ struct dev_intx_gsi_link {
 #define GLFAGS_SHIFT_TRG_MODE       15
 
 struct hvm_gmsi_info {
-    uint32_t gvec;
+    uint16_t gvec;
+    uint16_t old_gvec;
     uint32_t gflags;
+    uint32_t old_gflags;
     int dest_vcpu_id; /* -1 :multi-dest, non-negative: dest_vcpu_id */
 };
 

_______________________________________________
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] x86: vMSI: Fix msi irq affinity issue for hvm guest., Xen patchbot-unstable <=