habana has special code to check pci_p2pdma_distance() and rejects any importer that cannot do P2P DMA to its MMIO.
Convert this directly to a SGT_P2P match which does the same check inside the matching logic.
Someday this should be converted to use dma_buf_phys_vec_to_sgt() which does the P2P checking correctly, for both direct and IOMMU based cases, instead of this hack.
Remove the now empty attach function.
Signed-off-by: Jason Gunthorpe jgg@nvidia.com --- drivers/accel/habanalabs/common/memory.c | 54 +++++++++++------------- 1 file changed, 24 insertions(+), 30 deletions(-)
diff --git a/drivers/accel/habanalabs/common/memory.c b/drivers/accel/habanalabs/common/memory.c index 633db4bff46fc4..58dbc3c7f0877a 100644 --- a/drivers/accel/habanalabs/common/memory.c +++ b/drivers/accel/habanalabs/common/memory.c @@ -9,10 +9,10 @@ #include "habanalabs.h" #include "../include/hw_ip/mmu/mmu_general.h"
+#include <linux/dma-buf-mapping.h> #include <linux/uaccess.h> #include <linux/slab.h> #include <linux/vmalloc.h> -#include <linux/pci-p2pdma.h>
MODULE_IMPORT_NS("DMA_BUF");
@@ -1704,23 +1704,6 @@ static struct sg_table *alloc_sgt_from_device_pages(struct hl_device *hdev, u64 return ERR_PTR(rc); }
-static int hl_dmabuf_attach(struct dma_buf *dmabuf, - struct dma_buf_attachment *attachment) -{ - struct hl_dmabuf_priv *hl_dmabuf; - struct hl_device *hdev; - int rc; - - hl_dmabuf = dmabuf->priv; - hdev = hl_dmabuf->ctx->hdev; - - rc = pci_p2pdma_distance(hdev->pdev, attachment->dev, true); - - if (rc < 0) - attachment->peer2peer = false; - return 0; -} - static struct sg_table *hl_map_dmabuf(struct dma_buf_attachment *attachment, enum dma_data_direction dir) { @@ -1734,11 +1717,6 @@ static struct sg_table *hl_map_dmabuf(struct dma_buf_attachment *attachment, hl_dmabuf = dma_buf->priv; hdev = hl_dmabuf->ctx->hdev;
- if (!attachment->peer2peer) { - dev_dbg(hdev->dev, "Failed to map dmabuf because p2p is disabled\n"); - return ERR_PTR(-EPERM); - } - exported_size = hl_dmabuf->dmabuf->size; offset = hl_dmabuf->offset; phys_pg_pack = hl_dmabuf->phys_pg_pack; @@ -1753,8 +1731,10 @@ static struct sg_table *hl_map_dmabuf(struct dma_buf_attachment *attachment, page_size = hl_dmabuf->dmabuf->size; }
- sgt = alloc_sgt_from_device_pages(hdev, pages, npages, page_size, exported_size, offset, - attachment->dev, dir); + sgt = alloc_sgt_from_device_pages(hdev, pages, npages, page_size, + exported_size, offset, + dma_buf_sgt_dma_device(attachment), + dir); if (IS_ERR(sgt)) dev_err(hdev->dev, "failed (%ld) to initialize sgt for dmabuf\n", PTR_ERR(sgt));
@@ -1776,9 +1756,9 @@ static void hl_unmap_dmabuf(struct dma_buf_attachment *attachment, * a sync of the memory to the CPU's cache, as it never resided inside that cache. */ for_each_sgtable_dma_sg(sgt, sg, i) - dma_unmap_resource(attachment->dev, sg_dma_address(sg), - sg_dma_len(sg), dir, - DMA_ATTR_SKIP_CPU_SYNC); + dma_unmap_resource(dma_buf_sgt_dma_device(attachment), + sg_dma_address(sg), sg_dma_len(sg), dir, + DMA_ATTR_SKIP_CPU_SYNC);
/* Need to restore orig_nents because sg_free_table use that field */ sgt->orig_nents = sgt->nents; @@ -1848,11 +1828,25 @@ static void hl_release_dmabuf(struct dma_buf *dmabuf) kfree(hl_dmabuf); }
-static const struct dma_buf_ops habanalabs_dmabuf_ops = { - .attach = hl_dmabuf_attach, +static const struct dma_buf_mapping_sgt_exp_ops hl_dma_buf_sgt_ops = { .map_dma_buf = hl_map_dmabuf, .unmap_dma_buf = hl_unmap_dmabuf, +}; + +static int hl_match_mapping(struct dma_buf_match_args *args) +{ + struct hl_dmabuf_priv *hl_dmabuf = args->dmabuf->priv; + struct dma_buf_mapping_match sgt_match[] = { + DMA_BUF_EMAPPING_SGT_P2P(&hl_dma_buf_sgt_ops, + hl_dmabuf->ctx->hdev->pdev), + }; + + return dma_buf_match_mapping(args, sgt_match, ARRAY_SIZE(sgt_match)); +} + +static const struct dma_buf_ops habanalabs_dmabuf_ops = { .release = hl_release_dmabuf, + .match_mapping = hl_match_mapping, };
static int export_dmabuf(struct hl_ctx *ctx,