Skip to content

Commit

Permalink
PCI: disable MEM decoding while updating 64-bit MEM BARs
Browse files Browse the repository at this point in the history
When we update 64-bit BARs, we have to perform two config writes.  Between
the writes, the half-written BAR value could match a MEM access intended
for another device.  This could result in corruption of this device (for
writes) or an unexpected response machine check (for reads).

To prevent this, disable MEM decoding while updating such BARs.  This uses
the same safety test as 253d2e5, which disables both MEM and IO while
sizing BARs, namely, we don't disable decoding for host bridge devices.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
  • Loading branch information
Bjorn Helgaas committed Jul 10, 2012
1 parent bbffe43 commit 9aac537
Showing 1 changed file with 18 additions and 0 deletions.
18 changes: 18 additions & 0 deletions drivers/pci/setup-res.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
void pci_update_resource(struct pci_dev *dev, int resno)
{
struct pci_bus_region region;
bool disable;
u16 cmd;
u32 new, check, mask;
int reg;
enum pci_bar_type type;
Expand Down Expand Up @@ -67,6 +69,18 @@ void pci_update_resource(struct pci_dev *dev, int resno)
new |= PCI_ROM_ADDRESS_ENABLE;
}

/*
* We can't update a 64-bit BAR atomically, so when possible,
* disable decoding so that a half-updated BAR won't conflict
* with another device.
*/
disable = (res->flags & IORESOURCE_MEM_64) && !dev->mmio_always_on;
if (disable) {
pci_read_config_word(dev, PCI_COMMAND, &cmd);
pci_write_config_word(dev, PCI_COMMAND,
cmd & ~PCI_COMMAND_MEMORY);
}

pci_write_config_dword(dev, reg, new);
pci_read_config_dword(dev, reg, &check);

Expand All @@ -84,6 +98,10 @@ void pci_update_resource(struct pci_dev *dev, int resno)
"(high %#08x != %#08x)\n", resno, new, check);
}
}

if (disable)
pci_write_config_word(dev, PCI_COMMAND, cmd);

res->flags &= ~IORESOURCE_UNSET;
dev_dbg(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx])\n",
resno, res, (unsigned long long)region.start,
Expand Down

0 comments on commit 9aac537

Please sign in to comment.