[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |