Re: [PATCH v6 5/9] vfio/pci: Add a helper to create a DMABUF for a BAR-map VMA

From: Matt Evans

Date: Thu Sep 24 2026 - 08:58:51 EST


Hi Longfang,

On 22/09/2026 10:16, liulongfang wrote:
> On 2026/9/21 21:24, Matt Evans wrote:
>> Hi Longfang,
>>
>> On 15/09/2026 13:16, liulongfang wrote:
>>> On 2026/9/12 5:41, Matt Evans wrote:
>>>> [snip]
>>>> +
>>>> + /*
>>>> + * The DMABUF begins from the mmap()'s BAR offset, i.e. the
>>>> + * start of the VMA corresponds to byte 0 of the DMABUF and
>>>> + * byte (vma_pgoff << PAGE_SHIFT) of the BAR.
>>>> + *
>>>> + * vfio_pci_dma_buf_find_pfn() reverses this offset using
>>>> + * vma_pgoff_adjust, so that ultimately a fault's offset from
>>>> + * the start of the _VMA_ has a consistent usage whether the
>>>> + * VMA originates from an mmap() of the VFIO device here or a
>>>> + * direct DMABUF mmap(). Note vma_pgoff_adjust also includes
>>>> + * the encoded VFIO region index, which cancels out the index
>>>> + * encoded in vm_pgoff.
>>>> + */
>>>> + priv->vdev = vdev;
>>>> + priv->size = req_len;
>>>> + priv->nr_ranges = 1;
>>>> + priv->vma_pgoff_adjust = vma->vm_pgoff;
>>>> +
>>>> + priv->provider = pcim_p2pdma_provider(vdev->pdev, res_index);
>>>> + if (!priv->provider) {
>>>> + ret = -EINVAL;
>>>> + goto err_free_name;
>>>> + }
>>>> +
>>>> + priv->phys_vec[0].paddr = phys_start + ((u64)vma_pgoff << PAGE_SHIFT);
>>>> + priv->phys_vec[0].len = priv->size;
>>>> +
>>>> + ret = vfio_pci_dmabuf_export(vdev, priv, O_RDWR);
>>>> + if (ret)
>>>> + goto err_free_name;
>>>> +
>>>
>>> In the current patch, the PCIe device's BAR2 configuration space can be mapped as a DMABUF.
>>> However, on an OS with a 64K page size, if a VF device's BAR2 is smaller than 64K,
>>> a problem arises where the space is forced to page-align to 64K, it will causing the VM to
>>> access memory beyond the actual size of the VF device's BAR2 space.
>>>
>>> How does your solution handle these cases where the BAR2 space is smaller than the Host OS's page size?
>>
>> Even on a 4K host, there can be BARs < PAGE_SIZE so 64K (or 16K) hosts
>> aren't a new case. These small BARs cannot be mmap()ed and DMABUFs
>> cannot be exported from them. (vfio_pci_core_mmap() errors out when
>> !bar_mmap_supported[index]. And, a DMABUF needs to be an aligned
>> multiple of PAGE_SIZE, plus vfio_pci_core_fill_phys_vec() won't allow a
>> DMABUF to be created off the end of a BAR.)
>>
>> So, although this series allows a DMABUF to be mmap()ed, the preexisting
>> checks prevent a sub-page DMABUF from existing and so there is no new
>> route to mapping a sub-page BAR.
>>
>> What's the concern on BAR2 specifically, out of interest? This logic is
>> applied to all resources equally, and tests pci_resource_len(...) so
>> there shouldn't be a PF/VF distinction either.
>>
>
> However, the typical boundary check found in VFIO, such as:
>
> if (req_start + req_len > phys_len)
> return -EINVAL;
>
> seems to be missing here.

Isn't it covered by that statement in vfio_pci_core_mmap() just before
this function is called? This helper is intended to do as it's told by
a caller that has validated the range is correct (it doesn't duplicate
the checks already done by vfio_pci_core_mmap()).

Thanks,

Matt