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

[Xen-devel] [PATCH 3/5] AMD IOMMU: include IOMMU interrupt information in 'M' debug key output



Note that this also adds a few pieces missing from c/s
25903:5e4a00b4114c (relevant only when the PCI MSI mask bit is
supported by an IOMMU, which apparently isn't the case for existing
implementations).

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>

--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -263,7 +263,7 @@ static void write_msi_msg(struct msi_des
     }
 }
 
-static void set_msi_affinity(struct irq_desc *desc, const cpumask_t *mask)
+void set_msi_affinity(struct irq_desc *desc, const cpumask_t *mask)
 {
     struct msi_msg msg;
     unsigned int dest;
--- a/xen/drivers/passthrough/amd/iommu_detect.c
+++ b/xen/drivers/passthrough/amd/iommu_detect.c
@@ -39,7 +39,9 @@ static int __init get_iommu_msi_capabili
 
     AMD_IOMMU_DEBUG("Found MSI capability block at %#x\n", pos);
 
-    iommu->msi_cap = pos;
+    iommu->msi.msi_attrib.type = PCI_CAP_ID_MSI;
+    iommu->msi.msi_attrib.pos = pos;
+    iommu->msi.msi_attrib.is_64 = 1;
     return 0;
 }
 
--- a/xen/drivers/passthrough/amd/iommu_init.c
+++ b/xen/drivers/passthrough/amd/iommu_init.c
@@ -449,42 +449,10 @@ static void iommu_reset_log(struct amd_i
     ctrl_func(iommu, IOMMU_CONTROL_ENABLED);
 }
 
-static void iommu_msi_set_affinity(struct irq_desc *desc, const cpumask_t 
*mask)
-{
-    struct msi_msg msg;
-    unsigned int dest;
-    struct amd_iommu *iommu = desc->action->dev_id;
-    u16 seg = iommu->seg;
-    u8 bus = PCI_BUS(iommu->bdf);
-    u8 dev = PCI_SLOT(iommu->bdf);
-    u8 func = PCI_FUNC(iommu->bdf);
-
-    dest = set_desc_affinity(desc, mask);
-
-    if ( dest == BAD_APICID )
-    {
-        dprintk(XENLOG_ERR, "Set iommu interrupt affinity error!\n");
-        return;
-    }
-
-    msi_compose_msg(desc, &msg);
-    /* Is this override really needed? */
-    msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
-    msg.address_lo |= MSI_ADDR_DEST_ID(dest & 0xff);
-
-    pci_conf_write32(seg, bus, dev, func,
-        iommu->msi_cap + PCI_MSI_DATA_64, msg.data);
-    pci_conf_write32(seg, bus, dev, func,
-        iommu->msi_cap + PCI_MSI_ADDRESS_LO, msg.address_lo);
-    pci_conf_write32(seg, bus, dev, func,
-        iommu->msi_cap + PCI_MSI_ADDRESS_HI, msg.address_hi);
-    
-}
-
 static void amd_iommu_msi_enable(struct amd_iommu *iommu, int flag)
 {
     __msi_set_enable(iommu->seg, PCI_BUS(iommu->bdf), PCI_SLOT(iommu->bdf),
-                     PCI_FUNC(iommu->bdf), iommu->msi_cap, flag);
+                     PCI_FUNC(iommu->bdf), iommu->msi.msi_attrib.pos, flag);
 }
 
 static void iommu_msi_unmask(struct irq_desc *desc)
@@ -495,6 +463,7 @@ static void iommu_msi_unmask(struct irq_
     spin_lock_irqsave(&iommu->lock, flags);
     amd_iommu_msi_enable(iommu, IOMMU_CONTROL_ENABLED);
     spin_unlock_irqrestore(&iommu->lock, flags);
+    iommu->msi.msi_attrib.masked = 0;
 }
 
 static void iommu_msi_mask(struct irq_desc *desc)
@@ -507,6 +476,7 @@ static void iommu_msi_mask(struct irq_de
     spin_lock_irqsave(&iommu->lock, flags);
     amd_iommu_msi_enable(iommu, IOMMU_CONTROL_DISABLED);
     spin_unlock_irqrestore(&iommu->lock, flags);
+    iommu->msi.msi_attrib.masked = 1;
 }
 
 static unsigned int iommu_msi_startup(struct irq_desc *desc)
@@ -530,7 +500,7 @@ static hw_irq_controller iommu_msi_type 
     .disable = iommu_msi_mask,
     .ack = iommu_msi_mask,
     .end = iommu_msi_end,
-    .set_affinity = iommu_msi_set_affinity,
+    .set_affinity = set_msi_affinity,
 };
 
 static unsigned int iommu_maskable_msi_startup(struct irq_desc *desc)
@@ -561,7 +531,7 @@ static hw_irq_controller iommu_maskable_
     .disable = mask_msi_irq,
     .ack = iommu_maskable_msi_ack,
     .end = iommu_maskable_msi_end,
-    .set_affinity = iommu_msi_set_affinity,
+    .set_affinity = set_msi_affinity,
 };
 
 static void parse_event_log_entry(struct amd_iommu *iommu, u32 entry[])
@@ -775,9 +745,11 @@ static void iommu_interrupt_handler(int 
     tasklet_schedule(&amd_iommu_irq_tasklet);
 }
 
-static int __init set_iommu_interrupt_handler(struct amd_iommu *iommu)
+static bool_t __init set_iommu_interrupt_handler(struct amd_iommu *iommu)
 {
     int irq, ret;
+    struct irq_desc *desc;
+    unsigned long flags;
     u16 control;
 
     irq = create_irq(NUMA_NO_NODE);
@@ -786,23 +758,38 @@ static int __init set_iommu_interrupt_ha
         dprintk(XENLOG_ERR, "IOMMU: no irqs\n");
         return 0;
     }
-    
+
+    desc = irq_to_desc(irq);
+    spin_lock_irqsave(&pcidevs_lock, flags);
+    iommu->msi.dev = pci_get_pdev(iommu->seg, PCI_BUS(iommu->bdf),
+                                  PCI_DEVFN2(iommu->bdf));
+    spin_unlock_irqrestore(&pcidevs_lock, flags);
+    if ( !iommu->msi.dev )
+    {
+        AMD_IOMMU_DEBUG("IOMMU: no pdev for %04x:%02x:%02x.%u\n",
+                        iommu->seg, PCI_BUS(iommu->bdf),
+                        PCI_SLOT(iommu->bdf), PCI_FUNC(iommu->bdf));
+        return 0;
+    }
+    desc->msi_desc = &iommu->msi;
     control = pci_conf_read16(iommu->seg, PCI_BUS(iommu->bdf),
                               PCI_SLOT(iommu->bdf), PCI_FUNC(iommu->bdf),
-                              iommu->msi_cap + PCI_MSI_FLAGS);
-    irq_desc[irq].handler = control & PCI_MSI_FLAGS_MASKBIT ?
-                            &iommu_maskable_msi_type : &iommu_msi_type;
+                              iommu->msi.msi_attrib.pos + PCI_MSI_FLAGS);
+    iommu->msi.msi_attrib.maskbit = !!(control & PCI_MSI_FLAGS_MASKBIT);
+    desc->handler = control & PCI_MSI_FLAGS_MASKBIT ?
+                    &iommu_maskable_msi_type : &iommu_msi_type;
     ret = request_irq(irq, iommu_interrupt_handler, 0, "amd_iommu", iommu);
     if ( ret )
     {
-        irq_desc[irq].handler = &no_irq_type;
+        desc->handler = &no_irq_type;
         destroy_irq(irq);
         AMD_IOMMU_DEBUG("can't request irq\n");
         return 0;
     }
 
-    iommu->irq = irq;
-    return irq;
+    iommu->msi.irq = irq;
+
+    return 1;
 }
 
 static void enable_iommu(struct amd_iommu *iommu)
@@ -825,7 +812,7 @@ static void enable_iommu(struct amd_iomm
     if ( iommu_has_feature(iommu, IOMMU_EXT_FEATURE_PPRSUP_SHIFT) )
         register_iommu_ppr_log_in_mmio_space(iommu);
 
-    iommu_msi_set_affinity(irq_to_desc(iommu->irq), &cpu_online_map);
+    set_msi_affinity(irq_to_desc(iommu->msi.irq), &cpu_online_map);
     amd_iommu_msi_enable(iommu, IOMMU_CONTROL_ENABLED);
 
     set_iommu_ht_flags(iommu);
@@ -947,7 +934,7 @@ static int __init amd_iommu_init_one(str
         if ( allocate_ppr_log(iommu) == NULL )
             goto error_out;
 
-    if ( set_iommu_interrupt_handler(iommu) == 0 )
+    if ( !set_iommu_interrupt_handler(iommu) )
         goto error_out;
 
     /* To make sure that device_table.buffer has been successfully allocated */
--- a/xen/include/asm-x86/amd-iommu.h
+++ b/xen/include/asm-x86/amd-iommu.h
@@ -25,6 +25,7 @@
 #include <xen/list.h>
 #include <xen/spinlock.h>
 #include <xen/tasklet.h>
+#include <asm/msi.h>
 #include <asm/hvm/svm/amd-iommu-defs.h>
 
 #define iommu_found()           (!list_empty(&amd_iommu_head))
@@ -82,8 +83,9 @@ struct amd_iommu {
 
     u16 seg;
     u16 bdf;
+    struct msi_desc msi;
+
     u16 cap_offset;
-    u8 msi_cap;
     iommu_cap_t cap;
 
     u8 ht_flags;
@@ -103,7 +105,6 @@ struct amd_iommu {
     uint64_t exclusion_limit;
 
     int enabled;
-    int irq;
 };
 
 struct ivrs_mappings {
--- a/xen/include/asm-x86/msi.h
+++ b/xen/include/asm-x86/msi.h
@@ -214,5 +214,6 @@ void mask_msi_irq(struct irq_desc *);
 void unmask_msi_irq(struct irq_desc *);
 void ack_nonmaskable_msi_irq(struct irq_desc *);
 void end_nonmaskable_msi_irq(struct irq_desc *, u8 vector);
+void set_msi_affinity(struct irq_desc *, const cpumask_t *);
 
 #endif /* __ASM_MSI_H */


Attachment: AMD-IOMMU-MSI-dump.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

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