mirror of
https://github.com/torvalds/linux.git
synced 2024-12-04 18:13:04 +00:00
x86/PCI: truncate _CRS windows with _LEN > _MAX - _MIN + 1
Yanko's GA-MA78GM-S2H (BIOS F11) reports the following resource in a PCI host bridge _CRS: [07] 32-Bit DWORD Address Space Resource Min Relocatability : MinFixed Max Relocatability : MaxFixed Address Minimum : CFF00000 (_MIN) Address Maximum : FEBFFFFF (_MAX) Address Length : 3EE10000 (_LEN) This is invalid per spec (ACPI 4.0, 6.4.3.5) because it's a fixed size, fixed location descriptor, but _LEN != _MAX - _MIN + 1. Based on https://bugzilla.kernel.org/show_bug.cgi?id=15480#c15, I think Windows handles this by truncating the window so it fits between _MIN and _MAX. I also verified this by modifying the SeaBIOS DSDT and booting Windows 2008 R2 with qemu. This patch makes Linux truncate the window, too, which fixes: http://bugzilla.kernel.org/show_bug.cgi?id=15480 Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Tested-by: Yanko Kaneti <yaneti@declera.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
This commit is contained in:
parent
eb9fc8ef7c
commit
d558b483d5
@ -123,7 +123,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
|
||||
acpi_status status;
|
||||
unsigned long flags;
|
||||
struct resource *root, *conflict;
|
||||
u64 start, end;
|
||||
u64 start, end, max_len;
|
||||
|
||||
status = resource_to_addr(acpi_res, &addr);
|
||||
if (!ACPI_SUCCESS(status))
|
||||
@ -140,6 +140,17 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
|
||||
} else
|
||||
return AE_OK;
|
||||
|
||||
max_len = addr.maximum - addr.minimum + 1;
|
||||
if (addr.address_length > max_len) {
|
||||
dev_printk(KERN_DEBUG, &info->bridge->dev,
|
||||
"host bridge window length %#llx doesn't fit in "
|
||||
"%#llx-%#llx, trimming\n",
|
||||
(unsigned long long) addr.address_length,
|
||||
(unsigned long long) addr.minimum,
|
||||
(unsigned long long) addr.maximum);
|
||||
addr.address_length = max_len;
|
||||
}
|
||||
|
||||
start = addr.minimum + addr.translation_offset;
|
||||
end = start + addr.address_length - 1;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user