In vmxnet3_probe_device(), "adapter" is mapped to streaming DMA: adapter->adapter_pa = dma_map_single(..., adapter, ...);
Then "adapter" is accessed at many places in this function. Theses accesses may cause data inconsistency between CPU cache and hardware. To fix this problem, dma_map_single() is called after these accesses. Signed-off-by: Jia-Ju Bai <baiji...@tsinghua.edu.cn> --- drivers/net/vmxnet3/vmxnet3_drv.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index ca395f9679d0..96a4c28ba429 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -3445,14 +3445,6 @@ vmxnet3_probe_device(struct pci_dev *pdev, } spin_lock_init(&adapter->cmd_lock); - adapter->adapter_pa = dma_map_single(&adapter->pdev->dev, adapter, - sizeof(struct vmxnet3_adapter), - PCI_DMA_TODEVICE); - if (dma_mapping_error(&adapter->pdev->dev, adapter->adapter_pa)) { - dev_err(&pdev->dev, "Failed to map dma\n"); - err = -EFAULT; - goto err_set_mask; - } adapter->shared = dma_alloc_coherent( &adapter->pdev->dev, sizeof(struct Vmxnet3_DriverShared), @@ -3628,6 +3620,16 @@ vmxnet3_probe_device(struct pci_dev *pdev, } vmxnet3_check_link(adapter, false); + + adapter->adapter_pa = dma_map_single(&adapter->pdev->dev, adapter, + sizeof(struct vmxnet3_adapter), + PCI_DMA_TODEVICE); + if (dma_mapping_error(&adapter->pdev->dev, adapter->adapter_pa)) { + dev_err(&pdev->dev, "Failed to map dma\n"); + err = -EFAULT; + goto err_register; + } + return 0; err_register: @@ -3655,8 +3657,6 @@ vmxnet3_probe_device(struct pci_dev *pdev, sizeof(struct Vmxnet3_DriverShared), adapter->shared, adapter->shared_pa); err_alloc_shared: - dma_unmap_single(&adapter->pdev->dev, adapter->adapter_pa, - sizeof(struct vmxnet3_adapter), PCI_DMA_TODEVICE); err_set_mask: free_netdev(netdev); return err; -- 2.17.1