PCI: ECAM: Map config region with pci_remap_cfgspace()
authorLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Wed, 19 Apr 2017 16:48:56 +0000 (17:48 +0100)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 24 Apr 2017 18:53:14 +0000 (13:53 -0500)
The current ECAM kernel implementation uses ioremap() to map the ECAM
configuration space memory region; this is not safe in that on some
architectures the ioremap interface provides mappings that allow posted
write transactions. This, as highlighted in the PCIe specifications (4.0 -
Rev0.3, "Ordering Considerations for the Enhanced Configuration Address
Mechanism"), can create ordering issues for software because posted writes
transactions on the CPU host bus are non posted in the PCI express fabric.

Update the ioremap() interface to use pci_remap_cfgspace() whose mapping
attributes guarantee that non-posted writes transactions are issued for
memory writes within the ECAM memory mapped address region.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: Jayachandran C <jnair@caviumnetworks.com>
drivers/pci/ecam.c

index 2fee61bb6559408469c795554b87a320695fff24..c228a2eb7faa85ba8b0b0d57da23572c433df0e9 100644 (file)
@@ -84,12 +84,14 @@ struct pci_config_window *pci_ecam_create(struct device *dev,
                if (!cfg->winp)
                        goto err_exit_malloc;
                for (i = 0; i < bus_range; i++) {
-                       cfg->winp[i] = ioremap(cfgres->start + i * bsz, bsz);
+                       cfg->winp[i] =
+                               pci_remap_cfgspace(cfgres->start + i * bsz,
+                                                  bsz);
                        if (!cfg->winp[i])
                                goto err_exit_iomap;
                }
        } else {
-               cfg->win = ioremap(cfgres->start, bus_range * bsz);
+               cfg->win = pci_remap_cfgspace(cfgres->start, bus_range * bsz);
                if (!cfg->win)
                        goto err_exit_iomap;
        }