ia64/xen-unstable

changeset 18638:61218a1763da

vt-d: Fix MSI-x interrupt remapping

MSI-x may have multiple vectors, however in current interrupt
remapping code, one device only has one entry in interrupt remapping
table.

This patch adds 'remap_index' in msi_desc structure to track its index
in interrupt remapping table.

Signed-off-by: Haitao Shan <haitao.shan@intel.com>
Signed-off-by: Weidong Han <weidong.han@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Oct 15 11:58:15 2008 +0100 (2008-10-15)
parents 8c3144b1ff63
children 3603e95245fa
files xen/arch/x86/msi.c xen/drivers/passthrough/vtd/intremap.c xen/include/asm-x86/msi.h
line diff
     1.1 --- a/xen/arch/x86/msi.c	Wed Oct 15 08:22:42 2008 +0100
     1.2 +++ b/xen/arch/x86/msi.c	Wed Oct 15 11:58:15 2008 +0100
     1.3 @@ -364,6 +364,7 @@ static struct msi_desc* alloc_msi_entry(
     1.4  
     1.5      INIT_LIST_HEAD(&entry->list);
     1.6      entry->dev = NULL;
     1.7 +    entry->remap_index = -1;
     1.8  
     1.9      return entry;
    1.10  }
     2.1 --- a/xen/drivers/passthrough/vtd/intremap.c	Wed Oct 15 08:22:42 2008 +0100
     2.2 +++ b/xen/drivers/passthrough/vtd/intremap.c	Wed Oct 15 11:58:15 2008 +0100
     2.3 @@ -328,7 +328,8 @@ static int remap_entry_to_msi_msg(
     2.4  }
     2.5  
     2.6  static int msi_msg_to_remap_entry(
     2.7 -    struct iommu *iommu, struct pci_dev *pdev, struct msi_msg *msg)
     2.8 +    struct iommu *iommu, struct pci_dev *pdev,
     2.9 +    struct msi_desc *msi_desc, struct msi_msg *msg)
    2.10  {
    2.11      struct iremap_entry *iremap_entry = NULL, *iremap_entries;
    2.12      struct iremap_entry new_ire;
    2.13 @@ -336,32 +337,18 @@ static int msi_msg_to_remap_entry(
    2.14      unsigned int index;
    2.15      unsigned long flags;
    2.16      struct ir_ctrl *ir_ctrl = iommu_ir_ctrl(iommu);
    2.17 -    int i = 0;
    2.18  
    2.19      remap_rte = (struct msi_msg_remap_entry *) msg;
    2.20      spin_lock_irqsave(&ir_ctrl->iremap_lock, flags);
    2.21  
    2.22 -    iremap_entries =
    2.23 -        (struct iremap_entry *)map_vtd_domain_page(ir_ctrl->iremap_maddr);
    2.24 -
    2.25 -    /* If the entry for a PCI device has been there, use the old entry,
    2.26 -     * Or, assign a new entry for it.
    2.27 -     */
    2.28 -    for ( i = 0; i <= ir_ctrl->iremap_index; i++ )
    2.29 +    if ( msi_desc->remap_index < 0 )
    2.30      {
    2.31 -        iremap_entry = &iremap_entries[i];
    2.32 -        if ( iremap_entry->hi.sid ==
    2.33 -             ((pdev->bus << 8) | pdev->devfn) )
    2.34 -           break;
    2.35 -    }
    2.36 -
    2.37 -    if ( i > ir_ctrl->iremap_index )
    2.38 -    {
    2.39 -    	ir_ctrl->iremap_index++;
    2.40 +        ir_ctrl->iremap_index++;
    2.41          index = ir_ctrl->iremap_index;
    2.42 +        msi_desc->remap_index = index;
    2.43      }
    2.44      else
    2.45 -        index = i;
    2.46 +        index = msi_desc->remap_index;
    2.47  
    2.48      if ( index > IREMAP_ENTRY_NR - 1 )
    2.49      {
    2.50 @@ -369,11 +356,13 @@ static int msi_msg_to_remap_entry(
    2.51                  "%s: intremap index (%d) is larger than"
    2.52                  " the maximum index (%ld)!\n",
    2.53                  __func__, index, IREMAP_ENTRY_NR - 1);
    2.54 -        unmap_vtd_domain_page(iremap_entries);
    2.55 +        msi_desc->remap_index = -1;
    2.56          spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
    2.57          return -EFAULT;
    2.58      }
    2.59  
    2.60 +    iremap_entries =
    2.61 +        (struct iremap_entry *)map_vtd_domain_page(ir_ctrl->iremap_maddr);
    2.62      iremap_entry = &iremap_entries[index];
    2.63      memcpy(&new_ire, iremap_entry, sizeof(struct iremap_entry));
    2.64  
    2.65 @@ -450,7 +439,7 @@ void msi_msg_write_remap_rte(
    2.66      if ( !iommu || !ir_ctrl || ir_ctrl->iremap_maddr == 0 )
    2.67          return;
    2.68  
    2.69 -    msi_msg_to_remap_entry(iommu, pdev, msg);
    2.70 +    msi_msg_to_remap_entry(iommu, pdev, msi_desc, msg);
    2.71  }
    2.72  #elif defined(__ia64__)
    2.73  void msi_msg_read_remap_rte(
     3.1 --- a/xen/include/asm-x86/msi.h	Wed Oct 15 08:22:42 2008 +0100
     3.2 +++ b/xen/include/asm-x86/msi.h	Wed Oct 15 11:58:15 2008 +0100
     3.3 @@ -90,10 +90,11 @@ struct msi_desc {
     3.4  
     3.5  	void __iomem *mask_base;
     3.6  	struct pci_dev *dev;
     3.7 -    int vector;
     3.8 +	int vector;
     3.9  
    3.10 -	/* Last set MSI message */
    3.11 -	struct msi_msg msg;
    3.12 +	struct msi_msg msg;		/* Last set MSI message */
    3.13 +
    3.14 +	int remap_index;		/* index in interrupt remapping table */
    3.15  };
    3.16  
    3.17  /*