On 2/26/26 21:21, Matt Evans wrote:
A VFIO DMABUF can export a subset of a BAR to userspace by fd; add support for mmap() of this fd. This provides another route for a process to map BARs, except one where the process can only map a specific subset of a BAR represented by the exported DMABUF.
mmap() support enables userspace driver designs that safely delegate access to BAR sub-ranges to other client processes by sharing a DMABUF fd, without having to share the (omnipotent) VFIO device fd with them.
The mmap callback installs vm_ops callbacks for .fault and .huge_fault; they find a PFN by searching the DMABUF's physical ranges. That is, DMABUFs with multiple ranges are supported for mmap().
In general sounds like a good idea but this approach here doesn't looks good at all.
Especially how you call unmap_mapping_range() from your DMA-buf cleanup path looks extremely questionable.
...
+/*
- Similar to vfio_pci_core_mmap() for a regular VFIO device fd, but
- differs by pre-checks performed and ultimately the vm_ops installed.
- */
+static int vfio_pci_dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) +{
struct vfio_pci_dma_buf *priv = dmabuf->priv;u64 req_len, req_start;if (!vfio_pci_dma_buf_is_mappable(dmabuf))return -ENODEV;if ((vma->vm_flags & VM_SHARED) == 0)return -EINVAL;req_len = vma->vm_end - vma->vm_start;req_start = vma->vm_pgoff << PAGE_SHIFT;if (req_start + req_len > priv->size)return -EINVAL;vma->vm_private_data = priv;vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);/** See comments in vfio_pci_core_mmap() re VM_ALLOW_ANY_UNCACHED.** FIXME: get mapping attributes from dmabuf?*/vm_flags_set(vma, VM_ALLOW_ANY_UNCACHED | VM_IO | VM_PFNMAP |VM_DONTEXPAND | VM_DONTDUMP);vma->vm_ops = &vfio_pci_dma_buf_mmap_ops;return 0;
Let's start with this here, it just looks horrible over complicated.
When a DMA-buf just represents a linear piece of BAR which is map-able through the VFIO FD anyway then the right approach is to just re-direct the mapping to this VFIO FD.
Roughly something like this here should do it:
vma->vm_pgoff += offset_which_your_dma_buf_represents; vma_set_file(vma, core_dev->file); vfio_pci_core_mmap(core_dev, vma);
It can be that you want additional checks (e.g. if the DMA-buf is revoked) in which case you would need to override the vma->vm_ops, but then just do the access checks and call the vfio_pci_mmap_ops to get the actually page fault handling done.
unmap_mapping_range(priv->dmabuf->file->f_mapping,0, priv->size, 1);
When you need to use unmap_mapping_range() then you usually share the address space object between the file descriptor exporting the DMA-buf and the DMA-buf fd itself.
Otherwise functions like vfio_pci_zap_bars() doesn't work correctly any more and that usually creates a huge bunch of problems.
Regards, Christian.
On Fri, Feb 27, 2026 at 11:09:31AM +0100, Christian König wrote:
When a DMA-buf just represents a linear piece of BAR which is map-able through the VFIO FD anyway then the right approach is to just re-direct the mapping to this VFIO FD.
I actually would like to go the other way and have VFIO always have a DMABUF under the VMA's it mmaps because that will make it easy to finish the type1 emulation which requires finding dmabufs for the VMAs.
It can be that you want additional checks (e.g. if the DMA-buf is revoked) in which case you would need to override the vma->vm_ops, but then just do the access checks and call the vfio_pci_mmap_ops to get the actually page fault handling done.
It isn't that simple, the vm_ops won't have a way to get back to the dmabuf from the vma to find the per-fd revoke flag to check it.
unmap_mapping_range(priv->dmabuf->file->f_mapping,0, priv->size, 1);When you need to use unmap_mapping_range() then you usually share the address space object between the file descriptor exporting the DMA-buf and the DMA-buf fd itself.
Yeah, this becomes problematic. Right now there is a single address space per vfio-device and the invalidation is global.
Possibly for this use case you can keep that and do a global unmap and rely on fault to restore the mmaps that were not revoked.
Jason
linaro-mm-sig@lists.linaro.org