Message ID | 1423575637-6170-1-git-send-email-stefan.bader@canonical.com |
---|---|
State | New |
Headers | show |
On Tue, Feb 10, 2015 at 02:40:37PM +0100, Stefan Bader wrote: > I was discussing this backport upstream and it should come back > via stable sooner or later. So whether we want to pick it up before > or not I would leave up to you. > > Right now this causes some kind of weird side-effects as Sander > had problems with the power button getting recognized (which I would > rather understand) and I am having all attached USB devices failing > to get initialized (which is rather odd). Nevertheless all those things > are gone when acpi is getting its interrupt back. > > -Stefan > > --- > > From 8b5b328b62248d95743ca9af7aa71c06dd808dfe Mon Sep 17 00:00:00 2001 > From: Jiang Liu <jiang.liu@linux.intel.com> > Date: Tue, 20 Jan 2015 10:21:05 +0800 > Subject: [PATCH] x86/xen: Treat SCI interrupt as normal GSI interrupt > > Currently Xen Domain0 has special treatment for ACPI SCI interrupt, > that is initialize irq for ACPI SCI at early stage in a special way as: > xen_init_IRQ() > ->pci_xen_initial_domain() > ->xen_setup_acpi_sci() > Allocate and initialize irq for ACPI SCI > > Function xen_setup_acpi_sci() calls acpi_gsi_to_irq() to get an irq > number for ACPI SCI. But unfortunately acpi_gsi_to_irq() depends on > IOAPIC irqdomains through following path > acpi_gsi_to_irq() > ->mp_map_gsi_to_irq() > ->mp_map_pin_to_irq() > ->check IOAPIC irqdomain > > For PV domains, it uses Xen event based interrupt manangement and > doesn't make uses of native IOAPIC, so no irqdomains created for IOAPIC. > This causes Xen domain0 fail to install interrupt handler for ACPI SCI > and all ACPI events will be lost. Please refer to: > https://lkml.org/lkml/2014/12/19/178 > > So the fix is to get rid of special treatment for ACPI SCI, just treat > ACPI SCI as normal GSI interrupt as: > acpi_gsi_to_irq() > ->acpi_register_gsi() > ->acpi_register_gsi_xen() > ->xen_register_gsi() > > With above change, there's no need for xen_setup_acpi_sci() anymore. > The above change also works with bare metal kernel too. > > Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com> > Tested-by: Sander Eikelenboom <linux@eikelenboom.it> > Cc: Tony Luck <tony.luck@intel.com> > Cc: xen-devel@lists.xenproject.org > Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> > Cc: David Vrabel <david.vrabel@citrix.com> > Cc: Rafael J. Wysocki <rjw@rjwysocki.net> > Cc: Len Brown <len.brown@intel.com> > Cc: Pavel Machek <pavel@ucw.cz> > Cc: Bjorn Helgaas <bhelgaas@google.com> > Link: http://lkml.kernel.org/r/1421720467-7709-2-git-send-email-jiang.liu@linux.intel.com > Signed-off-by: Thomas Gleixner <tglx@linutronix.de> > > (backported from commit b568b8601f05a591a7ff09d8ee1cedb5b2e815fe) > Signed-off-by: Stefan Bader <stefan.bader@canonical.com> > --- > arch/x86/kernel/acpi/boot.c | 23 +++++++++++----------- > arch/x86/pci/xen.c | 47 --------------------------------------------- > 2 files changed, 12 insertions(+), 58 deletions(-) > > diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c > index a142e77..460f498 100644 > --- a/arch/x86/kernel/acpi/boot.c > +++ b/arch/x86/kernel/acpi/boot.c > @@ -604,18 +604,19 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) > > int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp) > { > - int irq; > - > - if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { > - *irqp = gsi; > - } else { > - irq = mp_map_gsi_to_irq(gsi, > - IOAPIC_MAP_ALLOC | IOAPIC_MAP_CHECK); > - if (irq < 0) > - return -1; > - *irqp = irq; > + int rc, irq, trigger, polarity; > + > + rc = acpi_get_override_irq(gsi, &trigger, &polarity); > + if (rc == 0) { > + trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; > + polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; > + irq = acpi_register_gsi(NULL, gsi, trigger, polarity); > + if (irq >= 0) { > + *irqp = irq; > + return 0; > + } > } > - return 0; > + return -1; > } > EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); > > diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c > index 093f5f4..6b3cf7c 100644 > --- a/arch/x86/pci/xen.c > +++ b/arch/x86/pci/xen.c > @@ -452,52 +452,6 @@ int __init pci_xen_hvm_init(void) > } > > #ifdef CONFIG_XEN_DOM0 > -static __init void xen_setup_acpi_sci(void) > -{ > - int rc; > - int trigger, polarity; > - int gsi = acpi_sci_override_gsi; > - int irq = -1; > - int gsi_override = -1; > - > - if (!gsi) > - return; > - > - rc = acpi_get_override_irq(gsi, &trigger, &polarity); > - if (rc) { > - printk(KERN_WARNING "xen: acpi_get_override_irq failed for acpi" > - " sci, rc=%d\n", rc); > - return; > - } > - trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; > - polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; > - > - printk(KERN_INFO "xen: sci override: global_irq=%d trigger=%d " > - "polarity=%d\n", gsi, trigger, polarity); > - > - /* 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 (acpi_gsi_to_irq(gsi, &irq) == 0) { > - /* Use the provided value if it's valid. */ > - if (irq >= 0) > - gsi_override = irq; > - } > - > - gsi = xen_register_gsi(gsi, gsi_override, trigger, polarity); > - printk(KERN_INFO "xen: acpi sci %d\n", gsi); > - > - return; > -} > - > int __init pci_xen_initial_domain(void) > { > int irq; > @@ -509,7 +463,6 @@ int __init pci_xen_initial_domain(void) > x86_msi.msi_mask_irq = xen_nop_msi_mask_irq; > x86_msi.msix_mask_irq = xen_nop_msix_mask_irq; > #endif > - xen_setup_acpi_sci(); > __acpi_register_gsi = acpi_register_gsi_xen; > /* Pre-allocate legacy irqs */ > for (irq = 0; irq < nr_legacy_irqs(); irq++) { As this is applied in mainline in v3.19 I assume this is master-next material: git describe --contains b568b8601f05a591a7ff09d8ee1cedb5b2e815fe v3.19-rc6~1^2~14 -apw
Applied to vivid master-next. -apw
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index a142e77..460f498 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -604,18 +604,19 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp) { - int irq; - - if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { - *irqp = gsi; - } else { - irq = mp_map_gsi_to_irq(gsi, - IOAPIC_MAP_ALLOC | IOAPIC_MAP_CHECK); - if (irq < 0) - return -1; - *irqp = irq; + int rc, irq, trigger, polarity; + + rc = acpi_get_override_irq(gsi, &trigger, &polarity); + if (rc == 0) { + trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; + polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; + irq = acpi_register_gsi(NULL, gsi, trigger, polarity); + if (irq >= 0) { + *irqp = irq; + return 0; + } } - return 0; + return -1; } EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 093f5f4..6b3cf7c 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -452,52 +452,6 @@ int __init pci_xen_hvm_init(void) } #ifdef CONFIG_XEN_DOM0 -static __init void xen_setup_acpi_sci(void) -{ - int rc; - int trigger, polarity; - int gsi = acpi_sci_override_gsi; - int irq = -1; - int gsi_override = -1; - - if (!gsi) - return; - - rc = acpi_get_override_irq(gsi, &trigger, &polarity); - if (rc) { - printk(KERN_WARNING "xen: acpi_get_override_irq failed for acpi" - " sci, rc=%d\n", rc); - return; - } - trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; - polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; - - printk(KERN_INFO "xen: sci override: global_irq=%d trigger=%d " - "polarity=%d\n", gsi, trigger, polarity); - - /* 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 (acpi_gsi_to_irq(gsi, &irq) == 0) { - /* Use the provided value if it's valid. */ - if (irq >= 0) - gsi_override = irq; - } - - gsi = xen_register_gsi(gsi, gsi_override, trigger, polarity); - printk(KERN_INFO "xen: acpi sci %d\n", gsi); - - return; -} - int __init pci_xen_initial_domain(void) { int irq; @@ -509,7 +463,6 @@ int __init pci_xen_initial_domain(void) x86_msi.msi_mask_irq = xen_nop_msi_mask_irq; x86_msi.msix_mask_irq = xen_nop_msix_mask_irq; #endif - xen_setup_acpi_sci(); __acpi_register_gsi = acpi_register_gsi_xen; /* Pre-allocate legacy irqs */ for (irq = 0; irq < nr_legacy_irqs(); irq++) {