The range check in setup_res() checks the IO range against iomem_resource. That's just wrong. Move the check into a separate function and use ioport_resource for IO ranges. Signed-off-by: Thomas Gleixner --- arch/x86/pci/acpi.c | 51 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 18 deletions(-) Index: tip/arch/x86/pci/acpi.c =================================================================== --- tip.orig/arch/x86/pci/acpi.c +++ tip/arch/x86/pci/acpi.c @@ -240,12 +240,41 @@ static acpi_status count_resource(struct return AE_OK; } +static bool valid_resource_range(struct resource *r, struct device *dev) +{ + struct resource *ior; + u64 end; + + ior = (r->flags & IORESOURCE_IO) ? &ioport_resource : &iomem_resource; + + /* + * Exclude non-addressable range or non-addressable portion of + * range. We only check end because ior->start is always 0. + */ + end = r->end; + r->end = min(r->end, ior->end); + if (r->end <= r->start) { + dev_info(dev, "host bridge %s window [%#llx-%#llx] invalid range\n", + r->flags & IORESOURCE_IO ? "io" : "mem", + (unsigned long long)r->start, end); + return false; + } + + if (r->end == end) + return true; + + dev_info(dev, "host bridge %s window [%#llx-%#llx] truncated to [%#llx-%#llx]\n", + r->flags & IORESOURCE_IO ? "io" : "mem", + (unsigned long long)r->start, end, + (unsigned long long)r->start, (unsigned long long)r->end); + return true; +} + static acpi_status setup_resource(struct acpi_resource *acpi_res, void *data) { struct pci_root_info *info = data; u64 translation_offset = 0; struct resource r; - u64 orig_end; memset(&r, 0, sizeof(r)); if (!acpi_dev_resource_memory(acpi_res, &r)) { @@ -269,31 +298,17 @@ static acpi_status setup_resource(struct r.end += translation_offset; } - if (!is_valid_resource(&r)) + if (!is_valid_resource(&r) || + !valid_resource_range(&r, &info->bridge->dev)) return AE_OK; - /* Exclude non-addressable range or non-addressable portion of range */ - orig_end = r.end; - r.end = min(r.end, iomem_resource.end); - if (r.end <= r.start) { - dev_info(&info->bridge->dev, - "host bridge window [%#llx-%#llx] (ignored, not CPU addressable)\n", - (unsigned long long)r.start, orig_end); - return AE_OK; - } else if (orig_end != r.end) { - dev_info(&info->bridge->dev, - "host bridge window [%#llx-%#llx] ([%#llx-%#llx] ignored, not CPU addressable)\n", - (unsigned long long)r.start, orig_end, - (unsigned long long)r.end + 1, orig_end); - } - r.name = info->name; info->res[info->res_num] = r; info->res_offset[info->res_num] = translation_offset; info->res_num++; if (!pci_use_crs) dev_printk(KERN_DEBUG, &info->bridge->dev, - "host bridge window %pR (ignored)\n", &r); + "host bridge window %pR ignored\n", &r); return AE_OK; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/