Kernel Bug Tracker – Bug 14337
PCI host bridge driver accepts invalid apertures
Last modified: 2010-05-20 02:57:20 UTC
On x86, we currently ignore PCI host bridge _CRS by default, but booting with "pci=use_crs" on an HP DL360 G3, BIOS version P31 10/31/2003, ACPI reports these windows in a PCI host bridge _CRS:
pci_root PNP0A03:00: host bridge window: [io 0x0000-0x0cff]
pci_root PNP0A03:00: host bridge window: [io 0x0000-0x2cfe]
pci_root PNP0A03:00: host bridge window: [io 0x03b0-0x03bb]
pci_root PNP0A03:00: host bridge window: [io 0x03c0-0x03df]
pci_root PNP0A03:00: host bridge window: [mem 0xf5d00000-0xf6ffffff]
pci_root PNP0A03:00: host bridge window: [mem 0x000a0000-0x000bffff]
The bridge has this device behind it:
pci 0000:00:05.2: reg 10: [io 0x2c00-0x2cff]
This device BAR (0x2c00-0x2cff) doesn't fit in the bridge aperture (0x0-0x2cfe). This leads to the following allocation failure and causes PNP to mistakenly detect a conflict between a motherboard device and the BAR:
pci 0000:00:05.2: BAR 0: no parent found for device [io 0x2c00-0x2cff]
pci 0000:00:05.2: BAR 0: can't allocate [io 0x2c00-0x2cff]
pnp 00:01: resource [io 0x0092] overlaps 0000:00:05.2 BAR 0 [io 0x0000-0x00ff], disabling
pnp 00:01: resource [io 0x0010-0x001f] overlaps 0000:00:05.2 BAR 0 [io 0x0000-0x00ff], disabling
I think the host bridge aperture size reported by _CRS (0x2cff) is invalid. The low two bits of PCI I/O BARs are not part of the base address, so I/O decoders must be aligned on four-byte boundaries, and they must be a multiple of four bytes in size.
I installed Windows Server 2003 SP1 on this system. The attached Device Manager screenshot shows that Windows rounded the size up to a multiple of four.
This is pretty clearly a BIOS bug, but it would be straightforward to work around it in Linux.
Created attachment 23292 [details]
PCI resources from Windows device manager
Will you please add the boot option of "pci=earlydump" and attach the output of dmesg?
Please also attach the output of acpidump, lspci -vxxx.
Patch from Bjorn:
Here's part of the _CRS descriptor dump for the [io 0x0000-0x2cfe] window above:
 16-Bit WORD Address Space Resource
Resource Type : I/O Range
Address Minimum : 0000 (_MIN)
Address Maximum : 2CFF (_MAX)
Address Length : 2CFF (_LEN)
Windows computed the window as [io 0x0000-0x2cff] instead. I assumed this was because Windows was rounding the end to a sensible boundary. But I now think Windows is ignoring _LEN and simply using [_MIN to _MAX].
Created attachment 26162 [details]
Windows with a non-aligned IO window
Here's a Windows screenshot showing an I/O window where [_MIN to _MIN + _LEN - 1] would be [io 0x0d00-0xffff], but Windows is apparently using [_MIN to _MAX], or [io 0xd00-0xfffe].
Doing the same in Linux would make the code simpler and (I hope) closer to what Windows does.
bjorn's two patches on this subject:
applied to acpi test tree
Already pulled the x86/PCI patch into my tree and sent to Linus yesterday.
shipped in 2.6.34