Commit 61aeecea authored by hpreg@vmware.com's avatar hpreg@vmware.com Committed by David S. Miller

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

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>
parent 849a742c
...@@ -2688,7 +2688,7 @@ vmxnet3_set_mac_addr(struct net_device *netdev, void *p) ...@@ -2688,7 +2688,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;
...@@ -2700,30 +2700,12 @@ vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter, bool *dma64) ...@@ -2700,30 +2700,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);
...@@ -2751,7 +2733,7 @@ vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter, bool *dma64) ...@@ -2751,7 +2733,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;
} }
...@@ -3254,7 +3236,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, ...@@ -3254,7 +3236,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;
...@@ -3300,6 +3282,24 @@ vmxnet3_probe_device(struct pci_dev *pdev, ...@@ -3300,6 +3282,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),
...@@ -3307,7 +3307,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, ...@@ -3307,7 +3307,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,
...@@ -3358,7 +3358,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, ...@@ -3358,7 +3358,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;
...@@ -3504,7 +3504,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, ...@@ -3504,7 +3504,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;
} }
......
...@@ -69,10 +69,12 @@ ...@@ -69,10 +69,12 @@
/* /*
* Version numbers * Version numbers
*/ */
#define VMXNET3_DRIVER_VERSION_STRING "1.4.14.0-k" #define VMXNET3_DRIVER_VERSION_STRING "1.4.15.0-k"
/* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ /* Each byte of this 32-bit integer encodes a version number in
#define VMXNET3_DRIVER_VERSION_NUM 0x01040e00 * VMXNET3_DRIVER_VERSION_STRING.
*/
#define VMXNET3_DRIVER_VERSION_NUM 0x01040f00
#if defined(CONFIG_PCI_MSI) #if defined(CONFIG_PCI_MSI)
/* RSS only makes sense if MSI-X is supported. */ /* RSS only makes sense if MSI-X is supported. */
......
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