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

[Xen-changelog] [xen-unstable] VMSI: This patch simulate the MSIx table read operation



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1280917300 -3600
# Node ID 39448a99227b61abb463c91e7e7c93763ddb3dce
# Parent  4566d523b10a1016643f4823a6c2de2068973627
VMSI: This patch simulate the MSIx table read operation

Signed-off-by: Liu Yuan <yuan.b.liu@xxxxxxxxx>
Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx>
---
 xen/arch/x86/hvm/vmsi.c |   38 +++++++++++++++++++++++++++++---------
 1 files changed, 29 insertions(+), 9 deletions(-)

diff -r 4566d523b10a -r 39448a99227b xen/arch/x86/hvm/vmsi.c
--- a/xen/arch/x86/hvm/vmsi.c   Wed Aug 04 11:21:08 2010 +0100
+++ b/xen/arch/x86/hvm/vmsi.c   Wed Aug 04 11:21:40 2010 +0100
@@ -159,7 +159,10 @@ struct msixtbl_entry
     unsigned long gtable;       /* gpa of msix table */
     unsigned long table_len;
     unsigned long table_flags[MAX_MSIX_TABLE_ENTRIES / BITS_PER_LONG + 1];
-
+#define MAX_MSIX_ACC_ENTRIES 3
+    struct { 
+        uint32_t msi_ad[3];    /* Shadow of address low, high and data */
+    } gentries[MAX_MSIX_ACC_ENTRIES];
     struct rcu_head rcu;
 };
 
@@ -205,18 +208,15 @@ static int msixtbl_read(
     struct vcpu *v, unsigned long address,
     unsigned long len, unsigned long *pval)
 {
-    unsigned long offset;
+    unsigned long offset, val;
     struct msixtbl_entry *entry;
     void *virt;
+    int nr_entry, index;
     int r = X86EMUL_UNHANDLEABLE;
 
     rcu_read_lock(&msixtbl_rcu_lock);
 
     if ( len != 4 )
-        goto out;
-
-    offset = address & (PCI_MSIX_ENTRY_SIZE - 1);
-    if ( offset != PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET)
         goto out;
 
     entry = msixtbl_find_entry(v, address);
@@ -224,9 +224,24 @@ static int msixtbl_read(
     if ( !virt )
         goto out;
 
-    *pval = readl(virt);
+    nr_entry = (address - entry->gtable) / PCI_MSIX_ENTRY_SIZE;
+    offset = address & (PCI_MSIX_ENTRY_SIZE - 1);
+    if ( nr_entry >= MAX_MSIX_ACC_ENTRIES && 
+         offset != PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET )
+        goto out;
+
+    val = readl(virt);
+    if ( offset != PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET )
+    {
+        index = offset / sizeof(uint32_t);
+        *pval = entry->gentries[nr_entry].msi_ad[index];
+    }
+    else 
+    {
+        *pval = val;
+    }
+    
     r = X86EMUL_OKAY;
-
 out:
     rcu_read_unlock(&msixtbl_rcu_lock);
     return r;
@@ -238,7 +253,7 @@ static int msixtbl_write(struct vcpu *v,
     unsigned long offset;
     struct msixtbl_entry *entry;
     void *virt;
-    int nr_entry;
+    int nr_entry, index;
     int r = X86EMUL_UNHANDLEABLE;
 
     rcu_read_lock(&msixtbl_rcu_lock);
@@ -252,6 +267,11 @@ static int msixtbl_write(struct vcpu *v,
     offset = address & (PCI_MSIX_ENTRY_SIZE - 1);
     if ( offset != PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET)
     {
+        if ( nr_entry < MAX_MSIX_ACC_ENTRIES ) 
+        {
+            index = offset / sizeof(uint32_t);
+            entry->gentries[nr_entry].msi_ad[index] = val;
+        }
         set_bit(nr_entry, &entry->table_flags);
         goto out;
     }

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