summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/pci_link.c
diff options
context:
space:
mode:
authorJiang Liu <jiang.liu@linux.intel.com>2015-09-17 08:02:45 +0200
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-09-26 01:53:07 +0200
commit5ebc76035303016ec41bb752bec156ea9fde7c34 (patch)
tree50b32017fe7f9771a1fa2a97cba4ec64b34b046c /drivers/acpi/pci_link.c
parentLinux 4.3-rc2 (diff)
downloadlinux-5ebc76035303016ec41bb752bec156ea9fde7c34.tar.xz
linux-5ebc76035303016ec41bb752bec156ea9fde7c34.zip
ACPI, PCI, irq: Do not share PCI IRQ with ISA IRQ
Avoid IRQs occupied by ISA IRQs when allocating IRQs for PCI link devices, otherwise it may cause interrupt storm due to incompatible pin attributes. This issue was triggered on a KVM virtual machine, which 1) uses IRQ9 for SCI in high level mode. 2) defines an PCI interrupt link device (LNKS) with IRQ9 as the only possible irq. 3) has an PCI device referring to link device LNKS. So it causes interrupt storm when enabling the PCI device because PCI IRQ works in low level mode. Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/pci_link.c')
-rw-r--r--drivers/acpi/pci_link.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 3b4ea98e3ea0..246e50d22120 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -553,6 +553,13 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
irq = link->irq.possible[i];
}
}
+ if (acpi_irq_penalty[irq] >= PIRQ_PENALTY_ISA_ALWAYS) {
+ printk(KERN_ERR PREFIX "No IRQ available for %s [%s]. "
+ "Try pci=noacpi or acpi=off\n",
+ acpi_device_name(link->device),
+ acpi_device_bid(link->device));
+ return -ENODEV;
+ }
/* Attempt to enable the link device at this IRQ. */
if (acpi_pci_link_set(link, irq)) {
@@ -821,6 +828,12 @@ void acpi_penalize_isa_irq(int irq, int active)
}
}
+bool acpi_isa_irq_available(int irq)
+{
+ return irq >= 0 && (irq >= ARRAY_SIZE(acpi_irq_penalty) ||
+ acpi_irq_penalty[irq] < PIRQ_PENALTY_ISA_ALWAYS);
+}
+
/*
* Penalize IRQ used by ACPI SCI. If ACPI SCI pin attributes conflict with
* PCI IRQ attributes, mark ACPI SCI as ISA_ALWAYS so it won't be use for