WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 4/4] x86: split MSI IRQ chip

To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 4/4] x86: split MSI IRQ chip
From: "Jan Beulich" <JBeulich@xxxxxxxx>
Date: Tue, 20 Sep 2011 16:44:31 +0100
Delivery-date: Tue, 20 Sep 2011 08:47:57 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
With the .end() accessor having become optional and noting that
several of the accessors' behavior really depends on the result of
msi_maskable_irq(), the splits the MSI IRQ chip type into two - one
for the maskable ones, and the other for the (MSI only) non-maskable
ones.

At once the implementation of those methods gets moved from io_apic.c
to msi.c.

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

--- a/xen/arch/x86/hpet.c
+++ b/xen/arch/x86/hpet.c
@@ -312,7 +312,7 @@ static void __hpet_setup_msi_irq(struct 
 {
     struct msi_msg msg;
 
-    msi_compose_msg(desc->irq, &msg);
+    msi_compose_msg(desc, &msg);
     hpet_msi_write(desc->action->dev_id, &msg);
 }
 
--- a/xen/arch/x86/hvm/vmsi.c
+++ b/xen/arch/x86/hvm/vmsi.c
@@ -382,7 +382,7 @@ int msixtbl_pt_register(struct domain *d
         return r;
     }
 
-    if ( irq_desc->handler != &pci_msi_type )
+    if ( !irq_desc->msi_desc )
         goto out;
 
     msi_desc = irq_desc->msi_desc;
@@ -426,7 +426,7 @@ void msixtbl_pt_unregister(struct domain
     if ( !irq_desc )
         return;
 
-    if ( irq_desc->handler != &pci_msi_type )
+    if ( !irq_desc->msi_desc )
         goto out;
 
     msi_desc = irq_desc->msi_desc;
--- a/xen/arch/x86/io_apic.c
+++ b/xen/arch/x86/io_apic.c
@@ -1882,44 +1882,6 @@ static hw_irq_controller ioapic_level_ty
     .set_affinity      = set_ioapic_affinity_irq,
 };
 
-static unsigned int startup_msi_irq(struct irq_desc *desc)
-{
-    unmask_msi_irq(desc);
-    return 0;
-}
-
-static void ack_msi_irq(struct irq_desc *desc)
-{
-    irq_complete_move(desc);
-    move_native_irq(desc);
-
-    if ( msi_maskable_irq(desc->msi_desc) )
-        ack_APIC_irq(); /* ACKTYPE_NONE */
-}
-
-static void end_msi_irq(struct irq_desc *desc, u8 vector)
-{
-    if ( !msi_maskable_irq(desc->msi_desc) )
-        ack_APIC_irq(); /* ACKTYPE_EOI */
-}
-
-#define shutdown_msi_irq mask_msi_irq
-
-/*
- * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
- * which implement the MSI or MSI-X Capability Structure.
- */
-hw_irq_controller pci_msi_type = {
-    .typename   = "PCI-MSI",
-    .startup    = startup_msi_irq,
-    .shutdown   = shutdown_msi_irq,
-    .enable        = unmask_msi_irq,
-    .disable    = mask_msi_irq,
-    .ack        = ack_msi_irq,
-    .end        = end_msi_irq,
-    .set_affinity   = set_msi_affinity,
-};
-
 static inline void init_IO_APIC_traps(void)
 {
     int irq;
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -1303,7 +1303,7 @@ static int pirq_acktype(struct domain *d
      * MSIs are treated as edge-triggered interrupts, except
      * when there is no proper way to mask them.
      */
-    if ( desc->handler == &pci_msi_type )
+    if ( desc->msi_desc )
         return msi_maskable_irq(desc->msi_desc) ? ACKTYPE_NONE : ACKTYPE_EOI;
 
     /*
@@ -1722,7 +1722,7 @@ int map_domain_pirq(
         if ( desc->handler != &no_irq_type )
             dprintk(XENLOG_G_ERR, "dom%d: irq %d in use\n",
                     d->domain_id, irq);
-        desc->handler = &pci_msi_type;
+        setup_msi_handler(desc, msi_desc);
 
         if ( opt_irq_vector_map == OPT_IRQ_VECTOR_MAP_PERDEV
              && !desc->chip_data->used_vectors )
@@ -1738,7 +1738,7 @@ int map_domain_pirq(
         }
 
         set_domain_irq_pirq(d, irq, info);
-        setup_msi_irq(msi_desc, irq);
+        setup_msi_irq(desc);
         spin_unlock_irqrestore(&desc->lock, flags);
     }
     else
@@ -1806,6 +1806,12 @@ int unmap_domain_pirq(struct domain *d, 
             radix_tree_int_to_ptr(-pirq));
     }
 
+    if ( msi_desc )
+    {
+        desc->handler = &no_irq_type;
+        desc->msi_desc = NULL;
+    }
+
     spin_unlock_irqrestore(&desc->lock, flags);
     if (msi_desc)
         msi_free_irq(msi_desc);
@@ -1818,9 +1824,6 @@ int unmap_domain_pirq(struct domain *d, 
         dprintk(XENLOG_G_ERR, "dom%d: could not deny access to irq %d\n",
                 d->domain_id, pirq);
 
-    if ( desc->handler == &pci_msi_type )
-        desc->handler = &no_irq_type;
-
  done:
     return ret;
 }
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -120,11 +120,11 @@ static void msix_put_fixmap(struct pci_d
 /*
  * MSI message composition
  */
-void msi_compose_msg(int irq, struct msi_msg *msg)
+void msi_compose_msg(struct irq_desc *desc, struct msi_msg *msg)
 {
     unsigned dest;
     cpumask_t domain;
-    struct irq_cfg *cfg = irq_cfg(irq);
+    struct irq_cfg *cfg = desc->chip_data;
     int vector = cfg->vector;
     domain = cfg->cpu_mask;
 
@@ -205,19 +205,6 @@ static void read_msi_msg(struct msi_desc
         iommu_read_msi_from_ire(entry, msg);
 }
 
-static int set_irq_msi(struct msi_desc *entry)
-{
-    if ( entry->irq >= nr_irqs )
-    {
-        dprintk(XENLOG_ERR, "Trying to install msi data for irq %d\n",
-                entry->irq);
-        return -EINVAL;
-    }
-
-    irq_desc[entry->irq].msi_desc = entry;
-    return 0;
-}
-
 static void write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
 {
     entry->msg = *msg;
@@ -266,7 +253,7 @@ static void write_msi_msg(struct msi_des
     }
 }
 
-void set_msi_affinity(struct irq_desc *desc, const cpumask_t *mask)
+static void set_msi_affinity(struct irq_desc *desc, const cpumask_t *mask)
 {
     struct msi_msg msg;
     unsigned int dest;
@@ -387,16 +374,65 @@ static int msi_get_mask_bit(const struct
     return -1;
 }
 
-void mask_msi_irq(struct irq_desc *desc)
+static void mask_msi_irq(struct irq_desc *desc)
 {
     msi_set_mask_bit(desc, 1);
 }
 
-void unmask_msi_irq(struct irq_desc *desc)
+static void unmask_msi_irq(struct irq_desc *desc)
 {
     msi_set_mask_bit(desc, 0);
 }
 
+static unsigned int startup_msi_irq(struct irq_desc *desc)
+{
+    unmask_msi_irq(desc);
+    return 0;
+}
+
+static void ack_nonmaskable_msi_irq(struct irq_desc *desc)
+{
+    irq_complete_move(desc);
+    move_native_irq(desc);
+}
+
+static void ack_maskable_msi_irq(struct irq_desc *desc)
+{
+    ack_nonmaskable_msi_irq(desc);
+    ack_APIC_irq(); /* ACKTYPE_NONE */
+}
+
+static void end_nonmaskable_msi_irq(struct irq_desc *desc, u8 vector)
+{
+    ack_APIC_irq(); /* ACKTYPE_EOI */
+}
+
+/*
+ * IRQ chip for MSI PCI/PCI-X/PCI-Express devices,
+ * which implement the MSI or MSI-X capability structure.
+ */
+static hw_irq_controller pci_msi_maskable = {
+    .typename     = "PCI-MSI/-X",
+    .startup      = startup_msi_irq,
+    .shutdown     = mask_msi_irq,
+    .enable       = unmask_msi_irq,
+    .disable      = mask_msi_irq,
+    .ack          = ack_maskable_msi_irq,
+    .set_affinity = set_msi_affinity
+};
+
+/* As above, but without having masking capability. */
+static hw_irq_controller pci_msi_nonmaskable = {
+    .typename     = "PCI-MSI",
+    .startup      = irq_startup_none,
+    .shutdown     = irq_shutdown_none,
+    .enable       = irq_enable_none,
+    .disable      = irq_disable_none,
+    .ack          = ack_nonmaskable_msi_irq,
+    .end          = end_nonmaskable_msi_irq,
+    .set_affinity = set_msi_affinity
+};
+
 static struct msi_desc* alloc_msi_entry(void)
 {
     struct msi_desc *entry;
@@ -412,15 +448,19 @@ static struct msi_desc* alloc_msi_entry(
     return entry;
 }
 
-int setup_msi_irq(struct msi_desc *msidesc, int irq)
+void setup_msi_handler(struct irq_desc *desc, struct msi_desc *msidesc)
 {
-    struct msi_msg msg;
+    desc->msi_desc = msidesc;
+    desc->handler = msi_maskable_irq(msidesc) ? &pci_msi_maskable
+                                              : &pci_msi_nonmaskable;
+}
 
-    msi_compose_msg(irq, &msg);
-    set_irq_msi(msidesc);
-    write_msi_msg(irq_desc[irq].msi_desc, &msg);
+void setup_msi_irq(struct irq_desc *desc)
+{
+    struct msi_msg msg;
 
-    return 0;
+    msi_compose_msg(desc, &msg);
+    write_msi_msg(desc->msi_desc, &msg);
 }
 
 int msi_free_irq(struct msi_desc *entry)
@@ -1018,19 +1058,20 @@ static void dump_msi(unsigned char key)
     {
         struct irq_desc *desc = irq_to_desc(irq);
         const struct msi_desc *entry;
-        u32 addr, data;
+        u32 addr, data, dest32;
+        int mask;
+        struct msi_attrib attr;
         unsigned long flags;
         char type;
 
         spin_lock_irqsave(&desc->lock, flags);
 
         entry = desc->msi_desc;
-        type = desc->handler == &pci_msi_type && entry;
-
-        spin_unlock_irqrestore(&desc->lock, flags);
-
-        if ( !type )
+        if ( !entry )
+        {
+            spin_unlock_irqrestore(&desc->lock, flags);
             continue;
+        }
 
         switch ( entry->msi_attrib.type )
         {
@@ -1041,6 +1082,11 @@ static void dump_msi(unsigned char key)
 
         data = entry->msg.data;
         addr = entry->msg.address_lo;
+        dest32 = entry->msg.dest32;
+        attr = entry->msi_attrib;
+        mask = msi_get_mask_bit(entry);
+
+        spin_unlock_irqrestore(&desc->lock, flags);
 
         printk(" MSI%c %4u vec=%02x%7s%6s%3sassert%5s%7s"
                " dest=%08x mask=%d/%d/%d\n",
@@ -1051,9 +1097,7 @@ static void dump_msi(unsigned char key)
                data & MSI_DATA_LEVEL_ASSERT ? "" : "de",
                addr & MSI_ADDR_DESTMODE_LOGIC ? "log" : "phys",
                addr & MSI_ADDR_REDIRECTION_LOWPRI ? "lowest" : "cpu",
-               entry->msg.dest32,
-               entry->msi_attrib.maskbit, entry->msi_attrib.masked,
-               msi_get_mask_bit(entry));
+               dest32, attr.maskbit, attr.masked, mask);
     }
 }
 
--- a/xen/include/asm-x86/msi.h
+++ b/xen/include/asm-x86/msi.h
@@ -73,15 +73,14 @@ struct msi_msg {
        u32     dest32;         /* used when Interrupt Remapping with EIM is 
enabled */
 };
 
+struct irq_desc;
 struct msi_desc;
 /* Helper functions */
-extern void mask_msi_irq(struct irq_desc *);
-extern void unmask_msi_irq(struct irq_desc *);
-extern void set_msi_affinity(struct irq_desc *, const cpumask_t *);
 extern int pci_enable_msi(struct msi_info *msi, struct msi_desc **desc);
 extern void pci_disable_msi(struct msi_desc *desc);
 extern void pci_cleanup_msi(struct pci_dev *pdev);
-extern int setup_msi_irq(struct msi_desc *desc, int irq);
+extern void setup_msi_handler(struct irq_desc *, struct msi_desc *);
+extern void setup_msi_irq(struct irq_desc *);
 extern void teardown_msi_irq(int irq);
 extern int msi_free_vector(struct msi_desc *entry);
 extern int pci_restore_msi_state(struct pci_dev *pdev);
@@ -89,14 +88,14 @@ extern int pci_restore_msi_state(struct 
 extern unsigned int pci_msix_get_table_len(struct pci_dev *pdev);
 
 struct msi_desc {
-       struct {
+       struct msi_attrib {
                __u8    type    : 5;    /* {0: unused, 5h:MSI, 11h:MSI-X} */
                __u8    maskbit : 1;    /* mask-pending bit supported ?   */
                __u8    masked  : 1;
                __u8    is_64   : 1;    /* Address size: 0=32bit 1=64bit  */
                __u8    pos;            /* Location of the msi capability */
                __u16   entry_nr;       /* specific enabled entry         */
-       }msi_attrib;
+       } msi_attrib;
 
        struct list_head list;
 
@@ -122,8 +121,6 @@ int msi_free_irq(struct msi_desc *entry)
  */
 #define NR_HP_RESERVED_VECTORS         20
 
-extern const struct hw_interrupt_type pci_msi_type;
-
 #define PCI_MSIX_ENTRY_SIZE                    16
 #define  PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET      0
 #define  PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET      4
@@ -221,5 +218,6 @@ struct msg_address {
        __u32   hi_address;
 } __attribute__ ((packed));
 
-void msi_compose_msg(int irq, struct msi_msg *);
+void msi_compose_msg(struct irq_desc *, struct msi_msg *);
+
 #endif /* __ASM_MSI_H */


Attachment: x86-msi-type-split.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH 4/4] x86: split MSI IRQ chip, Jan Beulich <=