On Fri, 21 Nov 2025 11:50:58 -0400 Jason Gunthorpe <[email protected]> wrote:
> This function is used to establish the "private interconnect" between the > VFIO DMABUF exporter and the iommufd DMABUF importer. This is intended to > be a temporary API until the core DMABUF interface is improved to natively > support a private interconnect and revocable negotiation. > > This function should only be called by iommufd when trying to map a > DMABUF. For now iommufd will only support VFIO DMABUFs. > > The following improvements are needed in the DMABUF API to generically > support more exporters with iommufd/kvm type importers that cannot use the > DMA API: > > 1) Revoke semantics. VFIO needs to be able to prevent access to the MMIO > during FLR, and so it will use dma_buf_move_notify() to prevent > access. iommmufd does not support fault handling so it cannot > implement the full move_notify. Instead if revoke is negotiated the > exporter promises not to use move_notify() unless the importer can > experiance failures. iommufd will unmap the dmabuf from the iommu page > tables while it is revoked. > > 2) Private interconnect negotiation. iommufd will only be able to map > a "private interconnect" that provides a phys_addr_t and a > struct p2pdma_provider * to describe the memory. It cannot use a DMA > mapped scatterlist since it is directly calling iommu_map(). > > 3) NULL device during dma_buf_dynamic_attach(). Since iommufd doesn't use > the DMA API it doesn't have a DMAable struct device to pass here. > > Reviewed-by: Nicolin Chen <[email protected]> > Reviewed-by: Kevin Tian <[email protected]> > Tested-by: Nicolin Chen <[email protected]> > Tested-by: Shuai Xue <[email protected]> > Signed-off-by: Jason Gunthorpe <[email protected]> > --- > drivers/vfio/pci/vfio_pci_dmabuf.c | 34 ++++++++++++++++++++++++++++++ > include/linux/vfio_pci_core.h | 4 ++++ > 2 files changed, 38 insertions(+) > > diff --git a/drivers/vfio/pci/vfio_pci_dmabuf.c > b/drivers/vfio/pci/vfio_pci_dmabuf.c > index 6698f540bdac87..d4d0f7d08c53e2 100644 > --- a/drivers/vfio/pci/vfio_pci_dmabuf.c > +++ b/drivers/vfio/pci/vfio_pci_dmabuf.c > @@ -82,6 +82,40 @@ static const struct dma_buf_ops vfio_pci_dmabuf_ops = { > .release = vfio_pci_dma_buf_release, > }; > > +/* > + * This is a temporary "private interconnect" between VFIO DMABUF and > iommufd. > + * It allows the two co-operating drivers to exchange the physical address of > + * the BAR. This is to be replaced with a formal DMABUF system for negotiated > + * interconnect types. > + * > + * If this function succeeds the following are true: > + * - There is one physical range and it is pointing to MMIO > + * - When move_notify is called it means revoke, not move, vfio_dma_buf_map > + * will fail if it is currently revoked > + */ > +int vfio_pci_dma_buf_iommufd_map(struct dma_buf_attachment *attachment, > + struct dma_buf_phys_vec *phys) > +{ > + struct vfio_pci_dma_buf *priv; > + > + dma_resv_assert_held(attachment->dmabuf->resv); > + > + if (attachment->dmabuf->ops != &vfio_pci_dmabuf_ops) > + return -EOPNOTSUPP; > + > + priv = attachment->dmabuf->priv; > + if (priv->revoked) > + return -ENODEV; > + > + /* More than one range to iommufd will require proper DMABUF support */ > + if (priv->nr_ranges != 1) > + return -EOPNOTSUPP; > + > + *phys = priv->phys_vec[0]; > + return 0; > +} > +EXPORT_SYMBOL_FOR_MODULES(vfio_pci_dma_buf_iommufd_map, "iommufd"); > + > int vfio_pci_core_fill_phys_vec(struct dma_buf_phys_vec *phys_vec, > struct vfio_region_dma_range *dma_ranges, > size_t nr_ranges, phys_addr_t start, > diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h > index c9466ba323fa9c..6a3074f2cf1cea 100644 > --- a/include/linux/vfio_pci_core.h > +++ b/include/linux/vfio_pci_core.h > @@ -28,6 +28,7 @@ struct vfio_pci_core_device; > struct vfio_pci_region; > struct p2pdma_provider; > struct dma_buf_phys_vec; > +struct dma_buf_attachment; > > struct vfio_pci_regops { > ssize_t (*rw)(struct vfio_pci_core_device *vdev, char __user *buf, > @@ -203,4 +204,7 @@ VFIO_IOREAD_DECLARATION(32) > VFIO_IOREAD_DECLARATION(64) > #endif > > +int vfio_pci_dma_buf_iommufd_map(struct dma_buf_attachment *attachment, > + struct dma_buf_phys_vec *phys); > + > #endif /* VFIO_PCI_CORE_H */ Acked-by: Alex Williamson <[email protected]>
