Commit 317e6bf6 authored by Jiang Liu's avatar Jiang Liu Committed by Greg Kroah-Hartman

x86/PCI/ACPI: Make all resources except [io 0xcf8-0xcff] available on PCI bus

commit 2c62e849 upstream.

An IO port or MMIO resource assigned to a PCI host bridge may be
consumed by the host bridge itself or available to its child
bus/devices. The ACPI specification defines a bit (Producer/Consumer)
to tell whether the resource is consumed by the host bridge itself,
but firmware hasn't used that bit consistently, so we can't rely on it.

Before commit 593669c2 ("x86/PCI/ACPI: Use common ACPI resource
interfaces to simplify implementation"), arch/x86/pci/acpi.c ignored
all IO port resources defined by acpi_resource_io and
acpi_resource_fixed_io to filter out IO ports consumed by the host
bridge itself.

Commit 593669c2 ("x86/PCI/ACPI: Use common ACPI resource interfaces
to simplify implementation") started accepting all IO port and MMIO
resources, which caused a regression that IO port resources consumed
by the host bridge itself became available to its child devices.

Then commit 63f1789e ("x86/PCI/ACPI: Ignore resources consumed by
host bridge itself") ignored resources consumed by the host bridge
itself by checking the IORESOURCE_WINDOW flag, which accidently removed
MMIO resources defined by acpi_resource_memory24, acpi_resource_memory32
and acpi_resource_fixed_memory32.

On x86 and IA64 platforms, all IO port and MMIO resources are assumed
to be available to child bus/devices except one special case:
    IO port [0xCF8-0xCFF] is consumed by the host bridge itself
    to access PCI configuration space.

So explicitly filter out PCI CFG IO ports[0xCF8-0xCFF]. This solution
will also ease the way to consolidate ACPI PCI host bridge common code
from x86, ia64 and ARM64.

Related ACPI table are archived at:
https://bugzilla.kernel.org/show_bug.cgi?id=94221

Related discussions at:
http://patchwork.ozlabs.org/patch/461633/
https://lkml.org/lkml/2015/3/29/304

Fixes: 63f1789e (Ignore resources consumed by host bridge itself)
Reported-by: default avatarBernhard Thaler <bernhard.thaler@wvnet.at>
Signed-off-by: default avatarJiang Liu <jiang.liu@linux.intel.com>
Reviewed-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 9b03ffb2
...@@ -325,6 +325,26 @@ static void release_pci_root_info(struct pci_host_bridge *bridge) ...@@ -325,6 +325,26 @@ static void release_pci_root_info(struct pci_host_bridge *bridge)
kfree(info); kfree(info);
} }
/*
* An IO port or MMIO resource assigned to a PCI host bridge may be
* consumed by the host bridge itself or available to its child
* bus/devices. The ACPI specification defines a bit (Producer/Consumer)
* to tell whether the resource is consumed by the host bridge itself,
* but firmware hasn't used that bit consistently, so we can't rely on it.
*
* On x86 and IA64 platforms, all IO port and MMIO resources are assumed
* to be available to child bus/devices except one special case:
* IO port [0xCF8-0xCFF] is consumed by the host bridge itself
* to access PCI configuration space.
*
* So explicitly filter out PCI CFG IO ports[0xCF8-0xCFF].
*/
static bool resource_is_pcicfg_ioport(struct resource *res)
{
return (res->flags & IORESOURCE_IO) &&
res->start == 0xCF8 && res->end == 0xCFF;
}
static void probe_pci_root_info(struct pci_root_info *info, static void probe_pci_root_info(struct pci_root_info *info,
struct acpi_device *device, struct acpi_device *device,
int busnum, int domain, int busnum, int domain,
...@@ -346,8 +366,8 @@ static void probe_pci_root_info(struct pci_root_info *info, ...@@ -346,8 +366,8 @@ static void probe_pci_root_info(struct pci_root_info *info,
"no IO and memory resources present in _CRS\n"); "no IO and memory resources present in _CRS\n");
else else
resource_list_for_each_entry_safe(entry, tmp, list) { resource_list_for_each_entry_safe(entry, tmp, list) {
if ((entry->res->flags & IORESOURCE_WINDOW) == 0 || if ((entry->res->flags & IORESOURCE_DISABLED) ||
(entry->res->flags & IORESOURCE_DISABLED)) resource_is_pcicfg_ioport(entry->res))
resource_list_destroy_entry(entry); resource_list_destroy_entry(entry);
else else
entry->res->name = info->name; entry->res->name = info->name;
......
...@@ -573,7 +573,7 @@ EXPORT_SYMBOL_GPL(acpi_dev_get_resources); ...@@ -573,7 +573,7 @@ EXPORT_SYMBOL_GPL(acpi_dev_get_resources);
* @ares: Input ACPI resource object. * @ares: Input ACPI resource object.
* @types: Valid resource types of IORESOURCE_XXX * @types: Valid resource types of IORESOURCE_XXX
* *
* This is a hepler function to support acpi_dev_get_resources(), which filters * This is a helper function to support acpi_dev_get_resources(), which filters
* ACPI resource objects according to resource types. * ACPI resource objects according to resource types.
*/ */
int acpi_dev_filter_resource_type(struct acpi_resource *ares, int acpi_dev_filter_resource_type(struct acpi_resource *ares,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment