xen: events: add xen_allocate_irq_{dynamic, gsi} and xen_free_irq
This is neater than open-coded calls to irq_alloc_desc_at and
irq_free_desc.
No intended behavioural change.
Note that we previously were not checking the return value of
irq_alloc_desc_at which would be failing for GSI<NR_IRQS_LEGACY
because the core architecture code has already allocated those for
us. Hence the additional check against NR_IRQS_LEGACY in
xen_allocate_irq_gsi.
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 1ae7757..81a53eb 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -387,7 +387,7 @@
return ret;
}
-static int find_unbound_irq(void)
+static int xen_allocate_irq_dynamic(void)
{
struct irq_data *data;
int irq, res;
@@ -436,6 +436,30 @@
return irq < get_nr_hw_irqs();
}
+static int xen_allocate_irq_gsi(unsigned gsi)
+{
+ int irq;
+
+ if (!identity_mapped_irq(gsi) &&
+ (xen_initial_domain() || !xen_pv_domain()))
+ return xen_allocate_irq_dynamic();
+
+ /* Legacy IRQ descriptors are already allocated by the arch. */
+ if (gsi < NR_IRQS_LEGACY)
+ return gsi;
+
+ irq = irq_alloc_desc_at(gsi, -1);
+ if (irq < 0)
+ panic("Unable to allocate to IRQ%d (%d)\n", gsi, irq);
+
+ return irq;
+}
+
+static void xen_free_irq(unsigned irq)
+{
+ irq_free_desc(irq);
+}
+
static void pirq_unmask_notify(int irq)
{
struct physdev_eoi eoi = { .irq = pirq_from_irq(irq) };
@@ -621,14 +645,7 @@
goto out; /* XXX need refcount? */
}
- /* If we are a PV guest, we don't have GSIs (no ACPI passed). Therefore
- * we are using the !xen_initial_domain() to drop in the function.*/
- if (identity_mapped_irq(gsi) || (!xen_initial_domain() &&
- xen_pv_domain())) {
- irq = gsi;
- irq_alloc_desc_at(irq, -1);
- } else
- irq = find_unbound_irq();
+ irq = xen_allocate_irq_gsi(gsi);
set_irq_chip_and_handler_name(irq, &xen_pirq_chip,
handle_level_irq, name);
@@ -641,7 +658,7 @@
* this in the priv domain. */
if (xen_initial_domain() &&
HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op)) {
- irq_free_desc(irq);
+ xen_free_irq(irq);
irq = -ENOSPC;
goto out;
}
@@ -682,7 +699,7 @@
spin_lock(&irq_mapping_update_lock);
if (alloc & XEN_ALLOC_IRQ) {
- *irq = find_unbound_irq();
+ *irq = xen_allocate_irq_dynamic();
if (*irq == -1)
goto out;
}
@@ -732,7 +749,7 @@
spin_lock(&irq_mapping_update_lock);
- irq = find_unbound_irq();
+ irq = xen_allocate_irq_dynamic();
if (irq == -1)
goto out;
@@ -741,7 +758,7 @@
if (rc) {
printk(KERN_WARNING "xen map irq failed %d\n", rc);
- irq_free_desc(irq);
+ xen_free_irq(irq);
irq = -1;
goto out;
@@ -783,7 +800,7 @@
}
irq_info[irq] = mk_unbound_info();
- irq_free_desc(irq);
+ xen_free_irq(irq);
out:
spin_unlock(&irq_mapping_update_lock);
@@ -814,7 +831,7 @@
irq = evtchn_to_irq[evtchn];
if (irq == -1) {
- irq = find_unbound_irq();
+ irq = xen_allocate_irq_dynamic();
set_irq_chip_and_handler_name(irq, &xen_dynamic_chip,
handle_fasteoi_irq, "event");
@@ -839,7 +856,7 @@
irq = per_cpu(ipi_to_irq, cpu)[ipi];
if (irq == -1) {
- irq = find_unbound_irq();
+ irq = xen_allocate_irq_dynamic();
if (irq < 0)
goto out;
@@ -875,7 +892,7 @@
irq = per_cpu(virq_to_irq, cpu)[virq];
if (irq == -1) {
- irq = find_unbound_irq();
+ irq = xen_allocate_irq_dynamic();
set_irq_chip_and_handler_name(irq, &xen_percpu_chip,
handle_percpu_irq, "virq");
@@ -934,7 +951,7 @@
if (irq_info[irq].type != IRQT_UNBOUND) {
irq_info[irq] = mk_unbound_info();
- irq_free_desc(irq);
+ xen_free_irq(irq);
}
spin_unlock(&irq_mapping_update_lock);