pcmcia: do not autoadd root PCI bus resources

On the PCI root bus on the x86 architecture, the risk of hitting
some strange system devices is too high: If a driver isn't loaded,
the resources are not claimed; even if a driver is loaded, it
may not request all resources or even the wrong one. We can neither
trust the rest of the kernel nor ACPI/PNP and CRS parsing to get it
right.

Therefore, explicitly spell out what safeguards we provide, and add
a safeguard to only use resources which are set up exclusively for
the secondary PCI bus (non-subtractive mode): the risk of hitting
system devices is quite low, as they usually aren't connected to
the secondary PCI bus.

CC: Jesse Barnes <jbarnes@virtuousgeek.org>
CC: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
This commit is contained in:
Dominik Brodowski
2010-03-29 21:40:35 +02:00
parent b19a7275de
commit cf26e8dc41

View File

@@ -935,23 +935,42 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
return -ENODEV; return -ENODEV;
#if defined(CONFIG_X86) #if defined(CONFIG_X86)
/* If this is the root bus, the risk of hitting /* If this is the root bus, the risk of hitting some strange
* some strange system devices which aren't protected * system devices is too high: If a driver isn't loaded, the
* by either ACPI resource tables or properly requested * resources are not claimed; even if a driver is loaded, it
* resources is too big. Therefore, don't do auto-adding * may not request all resources or even the wrong one. We
* of resources at the moment. * can neither trust the rest of the kernel nor ACPI/PNP and
* CRS parsing to get it right. Therefore, use several
* safeguards:
*
* - Do not auto-add resources if the CardBus bridge is on
* the PCI root bus
*
* - Avoid any I/O ports < 0x100.
*
* - On PCI-PCI bridges, only use resources which are set up
* exclusively for the secondary PCI bus: the risk of hitting
* system devices is quite low, as they usually aren't
* connected to the secondary PCI bus.
*/ */
if (s->cb_dev->bus->number == 0) if (s->cb_dev->bus->number == 0)
return -EINVAL; return -EINVAL;
#endif
for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) {
res = s->cb_dev->bus->resource[i];
#else
pci_bus_for_each_resource(s->cb_dev->bus, res, i) { pci_bus_for_each_resource(s->cb_dev->bus, res, i) {
#endif
if (!res) if (!res)
continue; continue;
if (res->flags & IORESOURCE_IO) { if (res->flags & IORESOURCE_IO) {
/* safeguard against the root resource, where the
* risk of hitting any other device would be too
* high */
if (res == &ioport_resource) if (res == &ioport_resource)
continue; continue;
dev_printk(KERN_INFO, &s->cb_dev->dev, dev_printk(KERN_INFO, &s->cb_dev->dev,
"pcmcia: parent PCI bridge window: %pR\n", "pcmcia: parent PCI bridge window: %pR\n",
res); res);
@@ -961,8 +980,12 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
} }
if (res->flags & IORESOURCE_MEM) { if (res->flags & IORESOURCE_MEM) {
/* safeguard against the root resource, where the
* risk of hitting any other device would be too
* high */
if (res == &iomem_resource) if (res == &iomem_resource)
continue; continue;
dev_printk(KERN_INFO, &s->cb_dev->dev, dev_printk(KERN_INFO, &s->cb_dev->dev,
"pcmcia: parent PCI bridge window: %pR\n", "pcmcia: parent PCI bridge window: %pR\n",
res); res);