Commit 779fd38b authored by hpreg@vmware.com's avatar hpreg@vmware.com Committed by Greg Kroah-Hartman

vmxnet3: set the DMA mask before the first DMA map operation

[ Upstream commit 61aeecea ]

The DMA mask must be set before, not after, the first DMA map operation, or
the first DMA map operation could in theory fail on some systems.

Fixes: b0eb57cb ("VMXNET3: Add support for virtual IOMMU")
Signed-off-by: default avatarRegis Duchesne <hpreg@vmware.com>
Acked-by: default avatarRonak Doshi <doshir@vmware.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 74a4c09d
...@@ -2675,7 +2675,7 @@ vmxnet3_set_mac_addr(struct net_device *netdev, void *p) ...@@ -2675,7 +2675,7 @@ vmxnet3_set_mac_addr(struct net_device *netdev, void *p)
/* ==================== initialization and cleanup routines ============ */ /* ==================== initialization and cleanup routines ============ */
static int static int
vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter, bool *dma64) vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter)
{ {
int err; int err;
unsigned long mmio_start, mmio_len; unsigned long mmio_start, mmio_len;
...@@ -2687,30 +2687,12 @@ vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter, bool *dma64) ...@@ -2687,30 +2687,12 @@ vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter, bool *dma64)
return err; return err;
} }
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) == 0) {
if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) {
dev_err(&pdev->dev,
"pci_set_consistent_dma_mask failed\n");
err = -EIO;
goto err_set_mask;
}
*dma64 = true;
} else {
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
dev_err(&pdev->dev,
"pci_set_dma_mask failed\n");
err = -EIO;
goto err_set_mask;
}
*dma64 = false;
}
err = pci_request_selected_regions(pdev, (1 << 2) - 1, err = pci_request_selected_regions(pdev, (1 << 2) - 1,
vmxnet3_driver_name); vmxnet3_driver_name);
if (err) { if (err) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"Failed to request region for adapter: error %d\n", err); "Failed to request region for adapter: error %d\n", err);
goto err_set_mask; goto err_enable_device;
} }
pci_set_master(pdev); pci_set_master(pdev);
...@@ -2738,7 +2720,7 @@ vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter, bool *dma64) ...@@ -2738,7 +2720,7 @@ vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter, bool *dma64)
iounmap(adapter->hw_addr0); iounmap(adapter->hw_addr0);
err_ioremap: err_ioremap:
pci_release_selected_regions(pdev, (1 << 2) - 1); pci_release_selected_regions(pdev, (1 << 2) - 1);
err_set_mask: err_enable_device:
pci_disable_device(pdev); pci_disable_device(pdev);
return err; return err;
} }
...@@ -3246,7 +3228,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, ...@@ -3246,7 +3228,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
#endif #endif
}; };
int err; int err;
bool dma64 = false; /* stupid gcc */ bool dma64;
u32 ver; u32 ver;
struct net_device *netdev; struct net_device *netdev;
struct vmxnet3_adapter *adapter; struct vmxnet3_adapter *adapter;
...@@ -3292,6 +3274,24 @@ vmxnet3_probe_device(struct pci_dev *pdev, ...@@ -3292,6 +3274,24 @@ vmxnet3_probe_device(struct pci_dev *pdev,
adapter->rx_ring_size = VMXNET3_DEF_RX_RING_SIZE; adapter->rx_ring_size = VMXNET3_DEF_RX_RING_SIZE;
adapter->rx_ring2_size = VMXNET3_DEF_RX_RING2_SIZE; adapter->rx_ring2_size = VMXNET3_DEF_RX_RING2_SIZE;
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) == 0) {
if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) {
dev_err(&pdev->dev,
"pci_set_consistent_dma_mask failed\n");
err = -EIO;
goto err_set_mask;
}
dma64 = true;
} else {
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
dev_err(&pdev->dev,
"pci_set_dma_mask failed\n");
err = -EIO;
goto err_set_mask;
}
dma64 = false;
}
spin_lock_init(&adapter->cmd_lock); spin_lock_init(&adapter->cmd_lock);
adapter->adapter_pa = dma_map_single(&adapter->pdev->dev, adapter, adapter->adapter_pa = dma_map_single(&adapter->pdev->dev, adapter,
sizeof(struct vmxnet3_adapter), sizeof(struct vmxnet3_adapter),
...@@ -3299,7 +3299,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, ...@@ -3299,7 +3299,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
if (dma_mapping_error(&adapter->pdev->dev, adapter->adapter_pa)) { if (dma_mapping_error(&adapter->pdev->dev, adapter->adapter_pa)) {
dev_err(&pdev->dev, "Failed to map dma\n"); dev_err(&pdev->dev, "Failed to map dma\n");
err = -EFAULT; err = -EFAULT;
goto err_dma_map; goto err_set_mask;
} }
adapter->shared = dma_alloc_coherent( adapter->shared = dma_alloc_coherent(
&adapter->pdev->dev, &adapter->pdev->dev,
...@@ -3350,7 +3350,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, ...@@ -3350,7 +3350,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
} }
#endif /* VMXNET3_RSS */ #endif /* VMXNET3_RSS */
err = vmxnet3_alloc_pci_resources(adapter, &dma64); err = vmxnet3_alloc_pci_resources(adapter);
if (err < 0) if (err < 0)
goto err_alloc_pci; goto err_alloc_pci;
...@@ -3492,7 +3492,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, ...@@ -3492,7 +3492,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
err_alloc_shared: err_alloc_shared:
dma_unmap_single(&adapter->pdev->dev, adapter->adapter_pa, dma_unmap_single(&adapter->pdev->dev, adapter->adapter_pa,
sizeof(struct vmxnet3_adapter), PCI_DMA_TODEVICE); sizeof(struct vmxnet3_adapter), PCI_DMA_TODEVICE);
err_dma_map: err_set_mask:
free_netdev(netdev); free_netdev(netdev);
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment