On Mon, Oct 13, 2025 at 06:26:11PM +0300, Leon Romanovsky wrote:
+static int vfio_pci_dma_buf_attach(struct dma_buf *dmabuf,
struct dma_buf_attachment *attachment)
+{
- struct vfio_pci_dma_buf *priv = dmabuf->priv;
- if (!attachment->peer2peer)
return -EOPNOTSUPP;
- if (priv->revoked)
return -ENODEV;
- switch (pci_p2pdma_map_type(priv->provider, attachment->dev)) {
- case PCI_P2PDMA_MAP_THRU_HOST_BRIDGE:
break;
- case PCI_P2PDMA_MAP_BUS_ADDR:
/*
* There is no need in IOVA at all for this flow.
* We rely on attachment->priv == NULL as a marker
* for this mode.
*/
return 0;
- default:
return -EINVAL;
- }
- attachment->priv = kzalloc(sizeof(struct dma_iova_state), GFP_KERNEL);
- if (!attachment->priv)
return -ENOMEM;
- dma_iova_try_alloc(attachment->dev, attachment->priv, 0, priv->size);
The lifetime of this isn't good..
- return 0;
+}
+static void vfio_pci_dma_buf_detach(struct dma_buf *dmabuf,
struct dma_buf_attachment *attachment)
+{
- kfree(attachment->priv);
+}
If the caller fails to call map then it leaks the iova.
+static struct sg_table * +vfio_pci_dma_buf_map(struct dma_buf_attachment *attachment,
enum dma_data_direction dir)
+{
[..]
+err_unmap_dma:
- if (!i || !state)
; /* Do nothing */
- else if (dma_use_iova(state))
dma_iova_destroy(attachment->dev, state, mapped_len, dir,
attrs);
If we hit this error path then it is freed..
+static void vfio_pci_dma_buf_unmap(struct dma_buf_attachment *attachment,
struct sg_table *sgt,
enum dma_data_direction dir)
+{
- struct vfio_pci_dma_buf *priv = attachment->dmabuf->priv;
- struct dma_iova_state *state = attachment->priv;
- unsigned long attrs = DMA_ATTR_MMIO;
- struct scatterlist *sgl;
- int i;
- if (!state)
; /* Do nothing */
- else if (dma_use_iova(state))
dma_iova_destroy(attachment->dev, state, priv->size, dir,
attrs);
It is freed here too, but we can call map multiple times. Every time a move_notify happens can trigger another call to map.
I think just call unlink in those two and put dma_iova_free in detach
Jason