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

[PATCH 1/2] Xen: Use a dedicated irq_info structure pointer



Use a dedicated irq_info structure pointer to avoid conflicts
with other parts of the kernel code

Signed-off-by: Sergey Temerkhanov <s.temerkhanov@xxxxxxxxx>
---
 drivers/xen/events/events_base.c | 62 +++++++++++++++-----------------
 include/linux/irq.h              | 15 ++++++++
 kernel/irq/chip.c                | 14 ++++++++
 3 files changed, 57 insertions(+), 34 deletions(-)

diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 8d49b91d92cd..bcc3af399016 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -151,12 +151,6 @@ int get_evtchn_to_irq(unsigned evtchn)
        return evtchn_to_irq[EVTCHN_ROW(evtchn)][EVTCHN_COL(evtchn)];
 }
 
-/* Get info for IRQ */
-struct irq_info *info_for_irq(unsigned irq)
-{
-       return irq_get_handler_data(irq);
-}
-
 /* Constructors for packed IRQ information. */
 static int xen_irq_info_common_setup(struct irq_info *info,
                                     unsigned irq,
@@ -185,7 +179,7 @@ static int xen_irq_info_common_setup(struct irq_info *info,
 static int xen_irq_info_evtchn_setup(unsigned irq,
                                     unsigned evtchn)
 {
-       struct irq_info *info = info_for_irq(irq);
+       struct irq_info *info = xen_get_irq_info(irq);
 
        return xen_irq_info_common_setup(info, irq, IRQT_EVTCHN, evtchn, 0);
 }
@@ -195,7 +189,7 @@ static int xen_irq_info_ipi_setup(unsigned cpu,
                                  unsigned evtchn,
                                  enum ipi_vector ipi)
 {
-       struct irq_info *info = info_for_irq(irq);
+       struct irq_info *info = xen_get_irq_info(irq);
 
        info->u.ipi = ipi;
 
@@ -209,7 +203,7 @@ static int xen_irq_info_virq_setup(unsigned cpu,
                                   unsigned evtchn,
                                   unsigned virq)
 {
-       struct irq_info *info = info_for_irq(irq);
+       struct irq_info *info = xen_get_irq_info(irq);
 
        info->u.virq = virq;
 
@@ -225,7 +219,7 @@ static int xen_irq_info_pirq_setup(unsigned irq,
                                   uint16_t domid,
                                   unsigned char flags)
 {
-       struct irq_info *info = info_for_irq(irq);
+       struct irq_info *info = xen_get_irq_info(irq);
 
        info->u.pirq.pirq = pirq;
        info->u.pirq.gsi = gsi;
@@ -249,7 +243,7 @@ unsigned int evtchn_from_irq(unsigned irq)
        if (unlikely(WARN(irq >= nr_irqs, "Invalid irq %d!\n", irq)))
                return 0;
 
-       return info_for_irq(irq)->evtchn;
+       return xen_get_irq_info(irq)->evtchn;
 }
 
 unsigned irq_from_evtchn(unsigned int evtchn)
@@ -265,7 +259,7 @@ int irq_from_virq(unsigned int cpu, unsigned int virq)
 
 static enum ipi_vector ipi_from_irq(unsigned irq)
 {
-       struct irq_info *info = info_for_irq(irq);
+       struct irq_info *info = xen_get_irq_info(irq);
 
        BUG_ON(info == NULL);
        BUG_ON(info->type != IRQT_IPI);
@@ -275,7 +269,7 @@ static enum ipi_vector ipi_from_irq(unsigned irq)
 
 static unsigned virq_from_irq(unsigned irq)
 {
-       struct irq_info *info = info_for_irq(irq);
+       struct irq_info *info = xen_get_irq_info(irq);
 
        BUG_ON(info == NULL);
        BUG_ON(info->type != IRQT_VIRQ);
@@ -285,7 +279,7 @@ static unsigned virq_from_irq(unsigned irq)
 
 static unsigned pirq_from_irq(unsigned irq)
 {
-       struct irq_info *info = info_for_irq(irq);
+       struct irq_info *info = xen_get_irq_info(irq);
 
        BUG_ON(info == NULL);
        BUG_ON(info->type != IRQT_PIRQ);
@@ -295,12 +289,12 @@ static unsigned pirq_from_irq(unsigned irq)
 
 static enum xen_irq_type type_from_irq(unsigned irq)
 {
-       return info_for_irq(irq)->type;
+       return xen_get_irq_info(irq)->type;
 }
 
 unsigned cpu_from_irq(unsigned irq)
 {
-       return info_for_irq(irq)->cpu;
+       return xen_get_irq_info(irq)->cpu;
 }
 
 unsigned int cpu_from_evtchn(unsigned int evtchn)
@@ -323,7 +317,7 @@ static bool pirq_check_eoi_map(unsigned irq)
 
 static bool pirq_needs_eoi_flag(unsigned irq)
 {
-       struct irq_info *info = info_for_irq(irq);
+       struct irq_info *info = xen_get_irq_info(irq);
        BUG_ON(info->type != IRQT_PIRQ);
 
        return info->u.pirq.flags & PIRQ_NEEDS_EOI;
@@ -332,7 +326,7 @@ static bool pirq_needs_eoi_flag(unsigned irq)
 static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
 {
        int irq = get_evtchn_to_irq(chn);
-       struct irq_info *info = info_for_irq(irq);
+       struct irq_info *info = xen_get_irq_info(irq);
 
        BUG_ON(irq == -1);
 #ifdef CONFIG_SMP
@@ -375,7 +369,7 @@ static void xen_irq_init(unsigned irq)
        info->type = IRQT_UNBOUND;
        info->refcnt = -1;
 
-       irq_set_handler_data(irq, info);
+       xen_set_irq_info(irq, info);
 
        list_add_tail(&info->list, &xen_irq_list_head);
 }
@@ -424,14 +418,14 @@ static int __must_check xen_allocate_irq_gsi(unsigned gsi)
 
 static void xen_free_irq(unsigned irq)
 {
-       struct irq_info *info = irq_get_handler_data(irq);
+       struct irq_info *info = xen_get_irq_info(irq);
 
        if (WARN_ON(!info))
                return;
 
        list_del(&info->list);
 
-       irq_set_handler_data(irq, NULL);
+       xen_set_irq_info(irq, NULL);
 
        WARN_ON(info->refcnt > 0);
 
@@ -456,7 +450,7 @@ static void xen_evtchn_close(unsigned int port)
 static void pirq_query_unmask(int irq)
 {
        struct physdev_irq_status_query irq_status;
-       struct irq_info *info = info_for_irq(irq);
+       struct irq_info *info = xen_get_irq_info(irq);
 
        BUG_ON(info->type != IRQT_PIRQ);
 
@@ -506,7 +500,7 @@ static void mask_ack_pirq(struct irq_data *data)
 static unsigned int __startup_pirq(unsigned int irq)
 {
        struct evtchn_bind_pirq bind_pirq;
-       struct irq_info *info = info_for_irq(irq);
+       struct irq_info *info = xen_get_irq_info(irq);
        int evtchn = evtchn_from_irq(irq);
        int rc;
 
@@ -559,7 +553,7 @@ static unsigned int startup_pirq(struct irq_data *data)
 static void shutdown_pirq(struct irq_data *data)
 {
        unsigned int irq = data->irq;
-       struct irq_info *info = info_for_irq(irq);
+       struct irq_info *info = xen_get_irq_info(irq);
        unsigned evtchn = evtchn_from_irq(irq);
 
        BUG_ON(info->type != IRQT_PIRQ);
@@ -601,7 +595,7 @@ EXPORT_SYMBOL_GPL(xen_irq_from_gsi);
 static void __unbind_from_irq(unsigned int irq)
 {
        int evtchn = evtchn_from_irq(irq);
-       struct irq_info *info = irq_get_handler_data(irq);
+       struct irq_info *info = xen_get_irq_info(irq);
 
        if (info->refcnt > 0) {
                info->refcnt--;
@@ -763,7 +757,7 @@ int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct 
msi_desc *msidesc,
 int xen_destroy_irq(int irq)
 {
        struct physdev_unmap_pirq unmap_irq;
-       struct irq_info *info = info_for_irq(irq);
+       struct irq_info *info = xen_get_irq_info(irq);
        int rc = -ENOENT;
 
        mutex_lock(&irq_mapping_update_lock);
@@ -855,7 +849,7 @@ int bind_evtchn_to_irq(unsigned int evtchn)
                /* New interdomain events are bound to VCPU 0. */
                bind_evtchn_to_cpu(evtchn, 0);
        } else {
-               struct irq_info *info = info_for_irq(irq);
+               struct irq_info *info = xen_get_irq_info(irq);
                WARN_ON(info == NULL || info->type != IRQT_EVTCHN);
        }
 
@@ -898,7 +892,7 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int 
cpu)
                }
                bind_evtchn_to_cpu(evtchn, cpu);
        } else {
-               struct irq_info *info = info_for_irq(irq);
+               struct irq_info *info = xen_get_irq_info(irq);
                WARN_ON(info == NULL || info->type != IRQT_IPI);
        }
 
@@ -1001,7 +995,7 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu, 
bool percpu)
 
                bind_evtchn_to_cpu(evtchn, cpu);
        } else {
-               struct irq_info *info = info_for_irq(irq);
+               struct irq_info *info = xen_get_irq_info(irq);
                WARN_ON(info == NULL || info->type != IRQT_VIRQ);
        }
 
@@ -1105,7 +1099,7 @@ int bind_ipi_to_irqhandler(enum ipi_vector ipi,
 
 void unbind_from_irqhandler(unsigned int irq, void *dev_id)
 {
-       struct irq_info *info = irq_get_handler_data(irq);
+       struct irq_info *info = xen_get_irq_info(irq);
 
        if (WARN_ON(!info))
                return;
@@ -1139,7 +1133,7 @@ int evtchn_make_refcounted(unsigned int evtchn)
        if (irq == -1)
                return -ENOENT;
 
-       info = irq_get_handler_data(irq);
+       info = xen_get_irq_info(irq);
 
        if (!info)
                return -ENOENT;
@@ -1167,7 +1161,7 @@ int evtchn_get(unsigned int evtchn)
        if (irq == -1)
                goto done;
 
-       info = irq_get_handler_data(irq);
+       info = xen_get_irq_info(irq);
 
        if (!info)
                goto done;
@@ -1263,7 +1257,7 @@ EXPORT_SYMBOL_GPL(xen_hvm_evtchn_do_upcall);
 /* Rebind a new event channel to an existing irq. */
 void rebind_evtchn_irq(int evtchn, int irq)
 {
-       struct irq_info *info = info_for_irq(irq);
+       struct irq_info *info = xen_get_irq_info(irq);
 
        if (WARN_ON(!info))
                return;
@@ -1551,7 +1545,7 @@ void xen_poll_irq(int irq)
 /* Check whether the IRQ line is shared with other guests. */
 int xen_test_irq_shared(int irq)
 {
-       struct irq_info *info = info_for_irq(irq);
+       struct irq_info *info = xen_get_irq_info(irq);
        struct physdev_irq_status_query irq_status;
 
        if (WARN_ON(!info))
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 6ecaf056ab63..e094d31916e2 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -123,6 +123,7 @@ enum {
 
 struct msi_desc;
 struct irq_domain;
+struct irq_info;
 
 /**
  * struct irq_common_data - per irq data shared by all irqchips
@@ -153,6 +154,9 @@ struct irq_common_data {
 #ifdef CONFIG_GENERIC_IRQ_IPI
        unsigned int            ipi_offset;
 #endif
+#ifdef CONFIG_XEN
+       struct irq_info     *xen_irq_info;
+#endif
 };
 
 /**
@@ -849,6 +853,17 @@ struct cpumask 
*irq_data_get_effective_affinity_mask(struct irq_data *d)
 }
 #endif
 
+#ifdef CONFIG_XEN
+static inline struct irq_info *xen_get_irq_info(unsigned int irq)
+{
+       struct irq_data *d = irq_get_irq_data(irq);
+
+       return d ? d->common->xen_irq_info : NULL;
+}
+
+extern int xen_set_irq_info(unsigned int irq, struct irq_info *data);
+#endif
+
 unsigned int arch_dynirq_lower_bound(unsigned int from);
 
 int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 09d914e486a2..58d1cf60a4f8 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -163,6 +163,20 @@ struct irq_data *irq_get_irq_data(unsigned int irq)
 }
 EXPORT_SYMBOL_GPL(irq_get_irq_data);
 
+#ifdef CONFIG_XEN
+int xen_set_irq_info(unsigned int irq, struct irq_info *data)
+{
+       unsigned long flags;
+       struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
+
+       if (!desc)
+               return -EINVAL;
+       desc->irq_common_data.xen_irq_info = data;
+       irq_put_desc_unlock(desc, flags);
+       return 0;
+}
+#endif
+
 static void irq_state_clr_disabled(struct irq_desc *desc)
 {
        irqd_clear(&desc->irq_data, IRQD_IRQ_DISABLED);
-- 
2.26.2




 


Rackspace

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