[Vivid maybe pre-stable] Fix various issues when running as dom0
Andy Whitcroft
apw at canonical.com
Tue Feb 10 14:59:59 UTC 2015
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 at 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 at linux.intel.com>
> Tested-by: Sander Eikelenboom <linux at eikelenboom.it>
> Cc: Tony Luck <tony.luck at intel.com>
> Cc: xen-devel at lists.xenproject.org
> Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
> Cc: David Vrabel <david.vrabel at citrix.com>
> Cc: Rafael J. Wysocki <rjw at rjwysocki.net>
> Cc: Len Brown <len.brown at intel.com>
> Cc: Pavel Machek <pavel at ucw.cz>
> Cc: Bjorn Helgaas <bhelgaas at 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 at linutronix.de>
>
> (backported from commit b568b8601f05a591a7ff09d8ee1cedb5b2e815fe)
> Signed-off-by: Stefan Bader <stefan.bader at 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
More information about the kernel-team
mailing list