From 53fd3b1e90dd16017ca8e170659589744afea604 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Thu, 30 Jun 2011 09:18:27 -0400 Subject: [PATCH] --- yaml --- r: 254253 b: refs/heads/master c: 155a16f21923bc2f04161ac92acca986371ef27b h: refs/heads/master i: 254251: b324131976fa3a97e1c146a2ba023e3abc82e672 v: v3 --- [refs] | 2 +- trunk/arch/x86/pci/xen.c | 26 ++++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 943cd03fd775..14eaa530db4e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 32dd11942aeb47f91209a446d6b10063c5b69389 +refs/heads/master: 155a16f21923bc2f04161ac92acca986371ef27b diff --git a/trunk/arch/x86/pci/xen.c b/trunk/arch/x86/pci/xen.c index 8214724ce54d..fe008309ffec 100644 --- a/trunk/arch/x86/pci/xen.c +++ b/trunk/arch/x86/pci/xen.c @@ -333,6 +333,7 @@ static int xen_register_pirq(u32 gsi, int triggering) struct physdev_map_pirq map_irq; int shareable = 0; char *name; + bool gsi_override = false; if (!xen_pv_domain()) return -1; @@ -349,11 +350,32 @@ static int xen_register_pirq(u32 gsi, int triggering) if (pirq < 0) goto out; - irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name); + /* Before we bind the GSI to a Linux IRQ, check whether + * we need to override it with bus_irq (IRQ) value. Usually for + * IRQs below IRQ_LEGACY_IRQ this holds IRQ == GSI, as so: + * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level) + * but there are oddballs where the IRQ != GSI: + * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 20 low level) + * which ends up being: gsi_to_irq[9] == 20 + * (which is what acpi_gsi_to_irq ends up calling when starting the + * the ACPI interpreter and keels over since IRQ 9 has not been + * setup as we had setup IRQ 20 for it). + */ + if (gsi == acpi_sci_override_gsi) { + /* Check whether the GSI != IRQ */ + acpi_gsi_to_irq(gsi, &irq); + if (irq != gsi) + /* Bugger, we MUST have that IRQ. */ + gsi_override = true; + } + if (gsi_override) + irq = xen_bind_pirq_gsi_to_irq(irq, pirq, shareable, name); + else + irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name); if (irq < 0) goto out; - printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d\n", pirq, irq); + printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d (gsi=%d)\n", pirq, irq, gsi); map_irq.domid = DOMID_SELF; map_irq.type = MAP_PIRQ_TYPE_GSI;