Commit e03e406c authored by Noa Osherovich's avatar Noa Osherovich Committed by Ben Hutchings

net/mlx5: Avoid passing dma address 0 to firmware

commit 6b276190 upstream.

Currently the firmware can't work with a page with dma address 0.
Passing such an address to the firmware will cause the give_pages
command to fail.

To avoid this, in case we get a 0 dma address of a page from the
dma engine, we avoid passing it to FW by remapping to get an address
other than 0.

Fixes: bf0bf77f ('mlx5: Support communicating arbitrary host...')
Signed-off-by: default avatarNoa Osherovich <noaos@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
parent d1f472da
...@@ -243,6 +243,7 @@ static void free_4k(struct mlx5_core_dev *dev, u64 addr) ...@@ -243,6 +243,7 @@ static void free_4k(struct mlx5_core_dev *dev, u64 addr)
static int alloc_system_page(struct mlx5_core_dev *dev, u16 func_id) static int alloc_system_page(struct mlx5_core_dev *dev, u16 func_id)
{ {
struct page *page; struct page *page;
u64 zero_addr = 1;
u64 addr; u64 addr;
int err; int err;
...@@ -251,27 +252,36 @@ static int alloc_system_page(struct mlx5_core_dev *dev, u16 func_id) ...@@ -251,27 +252,36 @@ static int alloc_system_page(struct mlx5_core_dev *dev, u16 func_id)
mlx5_core_warn(dev, "failed to allocate page\n"); mlx5_core_warn(dev, "failed to allocate page\n");
return -ENOMEM; return -ENOMEM;
} }
map:
addr = dma_map_page(&dev->pdev->dev, page, 0, addr = dma_map_page(&dev->pdev->dev, page, 0,
PAGE_SIZE, DMA_BIDIRECTIONAL); PAGE_SIZE, DMA_BIDIRECTIONAL);
if (dma_mapping_error(&dev->pdev->dev, addr)) { if (dma_mapping_error(&dev->pdev->dev, addr)) {
mlx5_core_warn(dev, "failed dma mapping page\n"); mlx5_core_warn(dev, "failed dma mapping page\n");
err = -ENOMEM; err = -ENOMEM;
goto out_alloc; goto err_mapping;
}
/* Firmware doesn't support page with physical address 0 */
if (addr == 0) {
zero_addr = addr;
goto map;
} }
err = insert_page(dev, addr, page, func_id); err = insert_page(dev, addr, page, func_id);
if (err) { if (err) {
mlx5_core_err(dev, "failed to track allocated page\n"); mlx5_core_err(dev, "failed to track allocated page\n");
goto out_mapping; dma_unmap_page(&dev->pdev->dev, addr, PAGE_SIZE,
DMA_BIDIRECTIONAL);
} }
return 0; err_mapping:
if (err)
out_mapping:
dma_unmap_page(&dev->pdev->dev, addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
out_alloc:
__free_page(page); __free_page(page);
if (zero_addr == 0)
dma_unmap_page(&dev->pdev->dev, zero_addr, PAGE_SIZE,
DMA_BIDIRECTIONAL);
return err; return err;
} }
static int give_pages(struct mlx5_core_dev *dev, u16 func_id, int npages, static int give_pages(struct mlx5_core_dev *dev, u16 func_id, int npages,
......
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