debuggers.hg

changeset 21958:39448a99227b

VMSI: This patch simulate the MSIx table read operation

Signed-off-by: Liu Yuan <yuan.b.liu@intel.com>
Signed-off-by: Eddie Dong <eddie.dong@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Aug 04 11:21:40 2010 +0100 (2010-08-04)
parents 4566d523b10a
children 581ebaa7e2da
files xen/arch/x86/hvm/vmsi.c
line diff
     1.1 --- a/xen/arch/x86/hvm/vmsi.c	Wed Aug 04 11:21:08 2010 +0100
     1.2 +++ b/xen/arch/x86/hvm/vmsi.c	Wed Aug 04 11:21:40 2010 +0100
     1.3 @@ -159,7 +159,10 @@ struct msixtbl_entry
     1.4      unsigned long gtable;       /* gpa of msix table */
     1.5      unsigned long table_len;
     1.6      unsigned long table_flags[MAX_MSIX_TABLE_ENTRIES / BITS_PER_LONG + 1];
     1.7 -
     1.8 +#define MAX_MSIX_ACC_ENTRIES 3
     1.9 +    struct { 
    1.10 +        uint32_t msi_ad[3];	/* Shadow of address low, high and data */
    1.11 +    } gentries[MAX_MSIX_ACC_ENTRIES];
    1.12      struct rcu_head rcu;
    1.13  };
    1.14  
    1.15 @@ -205,9 +208,10 @@ static int msixtbl_read(
    1.16      struct vcpu *v, unsigned long address,
    1.17      unsigned long len, unsigned long *pval)
    1.18  {
    1.19 -    unsigned long offset;
    1.20 +    unsigned long offset, val;
    1.21      struct msixtbl_entry *entry;
    1.22      void *virt;
    1.23 +    int nr_entry, index;
    1.24      int r = X86EMUL_UNHANDLEABLE;
    1.25  
    1.26      rcu_read_lock(&msixtbl_rcu_lock);
    1.27 @@ -215,18 +219,29 @@ static int msixtbl_read(
    1.28      if ( len != 4 )
    1.29          goto out;
    1.30  
    1.31 -    offset = address & (PCI_MSIX_ENTRY_SIZE - 1);
    1.32 -    if ( offset != PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET)
    1.33 -        goto out;
    1.34 -
    1.35      entry = msixtbl_find_entry(v, address);
    1.36      virt = msixtbl_addr_to_virt(entry, address);
    1.37      if ( !virt )
    1.38          goto out;
    1.39  
    1.40 -    *pval = readl(virt);
    1.41 +    nr_entry = (address - entry->gtable) / PCI_MSIX_ENTRY_SIZE;
    1.42 +    offset = address & (PCI_MSIX_ENTRY_SIZE - 1);
    1.43 +    if ( nr_entry >= MAX_MSIX_ACC_ENTRIES && 
    1.44 +         offset != PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET )
    1.45 +        goto out;
    1.46 +
    1.47 +    val = readl(virt);
    1.48 +    if ( offset != PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET )
    1.49 +    {
    1.50 +        index = offset / sizeof(uint32_t);
    1.51 +        *pval = entry->gentries[nr_entry].msi_ad[index];
    1.52 +    }
    1.53 +    else 
    1.54 +    {
    1.55 +        *pval = val;
    1.56 +    }
    1.57 +    
    1.58      r = X86EMUL_OKAY;
    1.59 -
    1.60  out:
    1.61      rcu_read_unlock(&msixtbl_rcu_lock);
    1.62      return r;
    1.63 @@ -238,7 +253,7 @@ static int msixtbl_write(struct vcpu *v,
    1.64      unsigned long offset;
    1.65      struct msixtbl_entry *entry;
    1.66      void *virt;
    1.67 -    int nr_entry;
    1.68 +    int nr_entry, index;
    1.69      int r = X86EMUL_UNHANDLEABLE;
    1.70  
    1.71      rcu_read_lock(&msixtbl_rcu_lock);
    1.72 @@ -252,6 +267,11 @@ static int msixtbl_write(struct vcpu *v,
    1.73      offset = address & (PCI_MSIX_ENTRY_SIZE - 1);
    1.74      if ( offset != PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET)
    1.75      {
    1.76 +        if ( nr_entry < MAX_MSIX_ACC_ENTRIES ) 
    1.77 +        {
    1.78 +            index = offset / sizeof(uint32_t);
    1.79 +            entry->gentries[nr_entry].msi_ad[index] = val;
    1.80 +        }
    1.81          set_bit(nr_entry, &entry->table_flags);
    1.82          goto out;
    1.83      }