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)
/* ==================== initialization and cleanup routines ============ */
static int
vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter, bool *dma64)
vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter)
{
int err;
unsigned long mmio_start, mmio_len;
......@@ -2687,30 +2687,12 @@ vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter, bool *dma64)
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,
vmxnet3_driver_name);
if (err) {
dev_err(&pdev->dev,
"Failed to request region for adapter: error %d\n", err);
goto err_set_mask;
goto err_enable_device;
}
pci_set_master(pdev);
......@@ -2738,7 +2720,7 @@ vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter, bool *dma64)
iounmap(adapter->hw_addr0);
err_ioremap:
pci_release_selected_regions(pdev, (1 << 2) - 1);
err_set_mask:
err_enable_device:
pci_disable_device(pdev);
return err;
}
......@@ -3246,7 +3228,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
#endif
};
int err;
bool dma64 = false; /* stupid gcc */
bool dma64;
u32 ver;
struct net_device *netdev;
struct vmxnet3_adapter *adapter;
......@@ -3292,6 +3274,24 @@ vmxnet3_probe_device(struct pci_dev *pdev,
adapter->rx_ring_size = VMXNET3_DEF_RX_RING_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);
adapter->adapter_pa = dma_map_single(&adapter->pdev->dev, adapter,
sizeof(struct vmxnet3_adapter),
......@@ -3299,7 +3299,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
if (dma_mapping_error(&adapter->pdev->dev, adapter->adapter_pa)) {
dev_err(&pdev->dev, "Failed to map dma\n");
err = -EFAULT;
goto err_dma_map;
goto err_set_mask;
}
adapter->shared = dma_alloc_coherent(
&adapter->pdev->dev,
......@@ -3350,7 +3350,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
}
#endif /* VMXNET3_RSS */
err = vmxnet3_alloc_pci_resources(adapter, &dma64);
err = vmxnet3_alloc_pci_resources(adapter);
if (err < 0)
goto err_alloc_pci;
......@@ -3492,7 +3492,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
err_alloc_shared:
dma_unmap_single(&adapter->pdev->dev, adapter->adapter_pa,
sizeof(struct vmxnet3_adapter), PCI_DMA_TODEVICE);
err_dma_map:
err_set_mask:
free_netdev(netdev);
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