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

[Xen-changelog] [xen-unstable] AMD IOMMU: handle MSI for phantom functions


  • To: xen-changelog@xxxxxxxxxxxxxxxxxxx
  • From: Xen patchbot-unstable <patchbot@xxxxxxx>
  • Date: Thu, 14 Feb 2013 19:44:12 +0000
  • Delivery-date: Thu, 14 Feb 2013 19:44:21 +0000
  • List-id: "Change log for Mercurial \(receive only\)" <xen-changelog.lists.xen.org>

# HG changeset patch
# User Jan Beulich <jbeulich@xxxxxxxx>
# Date 1360831377 -3600
# Node ID 788f4551580d476e13ea907e373e58806a32179e
# Parent  e68f14b9e73925e9d404e517ba510f73fe472e4e
AMD IOMMU: handle MSI for phantom functions

With ordinary requests allowed to come from phantom functions, the
remapping tables ought to be set up to also allow for MSI triggers to
come from other than the "real" device too.

It is not clear to me whether the alias-ID handling also needs
adjustment for this to work properly, or whether firmware can be
expected to properly express this through a device alias range
descriptor (or multiple device alias ones).

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---


diff -r e68f14b9e739 -r 788f4551580d xen/drivers/passthrough/amd/iommu_intr.c
--- a/xen/drivers/passthrough/amd/iommu_intr.c  Thu Feb 14 09:40:52 2013 +0100
+++ b/xen/drivers/passthrough/amd/iommu_intr.c  Thu Feb 14 09:42:57 2013 +0100
@@ -286,7 +286,7 @@ void amd_iommu_ioapic_update_ire(
 
 static void update_intremap_entry_from_msi_msg(
     struct amd_iommu *iommu, u16 bdf,
-    struct msi_desc *msi_desc, struct msi_msg *msg)
+    int *remap_index, const struct msi_msg *msg)
 {
     unsigned long flags;
     u32* entry;
@@ -302,7 +302,7 @@ static void update_intremap_entry_from_m
     {
         lock = get_intremap_lock(iommu->seg, req_id);
         spin_lock_irqsave(lock, flags);
-        free_intremap_entry(iommu->seg, req_id, msi_desc->remap_index);
+        free_intremap_entry(iommu->seg, req_id, *remap_index);
         spin_unlock_irqrestore(lock, flags);
 
         if ( ( req_id != alias_id ) &&
@@ -310,7 +310,7 @@ static void update_intremap_entry_from_m
         {
             lock = get_intremap_lock(iommu->seg, alias_id);
             spin_lock_irqsave(lock, flags);
-            free_intremap_entry(iommu->seg, alias_id, msi_desc->remap_index);
+            free_intremap_entry(iommu->seg, alias_id, *remap_index);
             spin_unlock_irqrestore(lock, flags);
         }
         goto done;
@@ -324,7 +324,10 @@ static void update_intremap_entry_from_m
     vector = (msg->data >> MSI_DATA_VECTOR_SHIFT) & MSI_DATA_VECTOR_MASK;
     dest = (msg->address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff;
     offset = get_intremap_offset(vector, delivery_mode);
-    msi_desc->remap_index = offset;
+    if ( *remap_index < 0)
+        *remap_index = offset;
+    else
+        BUG_ON(*remap_index != offset);
 
     entry = (u32*)get_intremap_entry(iommu->seg, req_id, offset);
     update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest);
@@ -379,12 +382,30 @@ void amd_iommu_msi_msg_update_ire(
     }
 
     if ( msi_desc->remap_index >= 0 )
-        update_intremap_entry_from_msi_msg(iommu, bdf, msi_desc, NULL);
+    {
+        do {
+            update_intremap_entry_from_msi_msg(iommu, bdf,
+                                               &msi_desc->remap_index, NULL);
+            if ( !pdev || !pdev->phantom_stride )
+                break;
+            bdf += pdev->phantom_stride;
+        } while ( PCI_SLOT(bdf) == PCI_SLOT(pdev->devfn) );
+
+        msi_desc->remap_index = -1;
+        if ( pdev )
+            bdf = PCI_BDF2(pdev->bus, pdev->devfn);
+    }
 
     if ( !msg )
         return;
 
-    update_intremap_entry_from_msi_msg(iommu, bdf, msi_desc, msg);
+    do {
+        update_intremap_entry_from_msi_msg(iommu, bdf, &msi_desc->remap_index,
+                                           msg);
+        if ( !pdev || !pdev->phantom_stride )
+            break;
+        bdf += pdev->phantom_stride;
+    } while ( PCI_SLOT(bdf) == PCI_SLOT(pdev->devfn) );
 }
 
 void amd_iommu_read_msi_from_ire(

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
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®.