summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/host/pci-hyperv.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
index 328c653d7503..58f7eeb79bb4 100644
--- a/drivers/pci/host/pci-hyperv.c
+++ b/drivers/pci/host/pci-hyperv.c
@@ -553,6 +553,8 @@ static void _hv_pcifront_read_config(struct hv_pci_dev *hpdev, int where,
spin_lock_irqsave(&hpdev->hbus->config_lock, flags);
/* Choose the function to be read. (See comment above) */
writel(hpdev->desc.win_slot.slot, hpdev->hbus->cfg_addr);
+ /* Make sure the function was chosen before we start reading. */
+ mb();
/* Read from that function's config space. */
switch (size) {
case 1:
@@ -565,6 +567,11 @@ static void _hv_pcifront_read_config(struct hv_pci_dev *hpdev, int where,
*val = readl(addr);
break;
}
+ /*
+ * Make sure the write was done before we release the spinlock
+ * allowing consecutive reads/writes.
+ */
+ mb();
spin_unlock_irqrestore(&hpdev->hbus->config_lock, flags);
} else {
dev_err(&hpdev->hbus->hdev->device,
@@ -592,6 +599,8 @@ static void _hv_pcifront_write_config(struct hv_pci_dev *hpdev, int where,
spin_lock_irqsave(&hpdev->hbus->config_lock, flags);
/* Choose the function to be written. (See comment above) */
writel(hpdev->desc.win_slot.slot, hpdev->hbus->cfg_addr);
+ /* Make sure the function was chosen before we start writing. */
+ wmb();
/* Write to that function's config space. */
switch (size) {
case 1:
@@ -604,6 +613,11 @@ static void _hv_pcifront_write_config(struct hv_pci_dev *hpdev, int where,
writel(val, addr);
break;
}
+ /*
+ * Make sure the write was done before we release the spinlock
+ * allowing consecutive reads/writes.
+ */
+ mb();
spin_unlock_irqrestore(&hpdev->hbus->config_lock, flags);
} else {
dev_err(&hpdev->hbus->hdev->device,