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

[Xen-devel] RE: [PATCH] Simulates the MSIx table read operation



VMSI: This patch simulates the MSIx table read operation

 

Signed-off-by: Liu Yuan <yuan.b.liu@xxxxxxxxx>

Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx>

 

diff -r 114f860872fb xen/arch/x86/hvm/vmsi.c

--- a/xen/arch/x86/hvm/vmsi.c

+++ b/xen/arch/x86/hvm/vmsi.c

@@ -158,7 +158,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,6 +208,7 @@ static int msixtbl_read(

     unsigned long offset;

     struct msixtbl_entry *entry;

     void *virt;

+    int nr_entry, index;

     int r = X86EMUL_UNHANDLEABLE;

 

     rcu_read_lock();

@@ -212,14 +216,22 @@ static int msixtbl_read(

     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);

     virt = msixtbl_addr_to_virt(entry, address);

     if ( !virt )

         goto out;

+

+    offset = address & (PCI_MSIX_ENTRY_SIZE - 1);

+    entry = msixtbl_find_entry(v, address);

+    if ( offset != PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET){

+        nr_entry = (address - entry->gtable) / PCI_MSIX_ENTRY_SIZE;

+        index = offset / sizeof(uint32_t);

+        if (nr_entry < MAX_MSIX_ACC_ENTRIES) {

+            *pval = entry->gentries[nr_entry].msi_ad[index];

+            readl(virt); /* Linux kernel needs this to flush the write */

+            r = X86EMUL_OKAY;

+        }

+        goto out;

+    }

 

     *pval = readl(virt);

     r = X86EMUL_OKAY;

@@ -235,7 +247,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();

@@ -249,6 +261,10 @@ 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-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.