Re: [PATCH v6 10/31] vfio/pci: Refuse ioeventfds and dma-buf exports over excluded ranges
From: Alex Williamson
Date: Fri Nov 06 2026 - 15:53:51 EST
On Fri, 16 Oct 2026 21:48:17 +0530
<mhonap@xxxxxxxxxx> wrote:
> From: Manish Honap <mhonap@xxxxxxxxxx>
>
> vfio_pci_bar_rw() keeps the excluded ranges of a BAR off the device, but
> two other paths reach BAR MMIO without it.
>
> An ioeventfd writes the BAR directly when it fires, through
> vfio_pci_core_iowriteN(). Refuse an ioeventfd whose range overlaps a
> write-excluded range, as one over the MSI-X table is already refused.
>
> A dma-buf export of a BAR range lets an importer map it for DMA, which
> reaches a range that the BAR keeps off mmap. Refuse an export whose
> ranges overlap an mmap-excluded range, so the dma-buf follows the same
> rule as mmap.
>
> Suggested-by: Alex Williamson <alex@xxxxxxxxxxx>
> Assisted-by: LLM
> Signed-off-by: Manish Honap <mhonap@xxxxxxxxxx>
> ---
> drivers/vfio/pci/vfio_pci_core.c | 4 ++--
> drivers/vfio/pci/vfio_pci_dmabuf.c | 14 ++++++++++++++
> drivers/vfio/pci/vfio_pci_priv.h | 3 +++
> drivers/vfio/pci/vfio_pci_rdwr.c | 9 +++++++++
> 4 files changed, 28 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> index f099a294af34..211fff6045e2 100644
> --- a/drivers/vfio/pci/vfio_pci_core.c
> +++ b/drivers/vfio/pci/vfio_pci_core.c
> @@ -1107,8 +1107,8 @@ static void vfio_pci_free_excluded_ranges(struct vfio_pci_core_device *vdev)
> }
>
> /* True when [start, start + len) on @bar overlaps a range with any of @flags. */
> -static bool vfio_pci_bar_range_excluded(struct vfio_pci_core_device *vdev,
> - int bar, u64 start, u64 len, u32 flags)
> +bool vfio_pci_bar_range_excluded(struct vfio_pci_core_device *vdev, int bar,
> + u64 start, u64 len, u32 flags)
> {
> struct vfio_pci_excluded_range *range;
>
> diff --git a/drivers/vfio/pci/vfio_pci_dmabuf.c b/drivers/vfio/pci/vfio_pci_dmabuf.c
> index c16f460c01d6..8606c15ab2fe 100644
> --- a/drivers/vfio/pci/vfio_pci_dmabuf.c
> +++ b/drivers/vfio/pci/vfio_pci_dmabuf.c
> @@ -260,6 +260,20 @@ int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,
> if (ret)
> goto err_free_ranges;
>
> + /*
> + * A DMA mapping built from the dma-buf would reach a range that the
> + * BAR keeps off mmap, so refuse such a range here as mmap does.
> + */
> + for (u32 i = 0; i < get_dma_buf.nr_ranges; i++) {
> + if (vfio_pci_bar_range_excluded(vdev, get_dma_buf.region_index,
> + dma_ranges[i].offset,
> + dma_ranges[i].length,
> + VFIO_PCI_EXCLUDE_MMAP)) {
> + ret = -EINVAL;
> + goto err_free_ranges;
> + }
> + }
This should be rolled into validate_dmabuf_input().
> +
> priv = kzalloc_obj(*priv);
> if (!priv) {
> ret = -ENOMEM;
> diff --git a/drivers/vfio/pci/vfio_pci_priv.h b/drivers/vfio/pci/vfio_pci_priv.h
> index 53544e0cbedf..09a68c99b43c 100644
> --- a/drivers/vfio/pci/vfio_pci_priv.h
> +++ b/drivers/vfio/pci/vfio_pci_priv.h
> @@ -52,6 +52,9 @@ struct vfio_pci_excluded_range {
> u32 flags;
> };
>
> +bool vfio_pci_bar_range_excluded(struct vfio_pci_core_device *vdev, int bar,
> + u64 start, u64 len, u32 flags);
> +
> #ifdef CONFIG_VFIO_PCI_VGA
> ssize_t vfio_pci_vga_rw(struct vfio_pci_core_device *vdev, char __user *buf,
> size_t count, loff_t *ppos, bool iswrite);
> diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c b/drivers/vfio/pci/vfio_pci_rdwr.c
> index 93823c6391f6..ef098f0b1401 100644
> --- a/drivers/vfio/pci/vfio_pci_rdwr.c
> +++ b/drivers/vfio/pci/vfio_pci_rdwr.c
> @@ -476,6 +476,15 @@ int vfio_pci_ioeventfd(struct vfio_pci_core_device *vdev, loff_t offset,
> pos >= vdev->msix_offset + vdev->msix_size))
> return -EINVAL;
>
> + /*
> + * The ioeventfd fire path writes the BAR directly, without the
> + * excluded-range filter of vfio_pci_bar_rw(), so refuse a write-excluded
> + * range here.
> + */
> + if (vfio_pci_bar_range_excluded(vdev, bar, pos, count,
> + VFIO_PCI_EXCLUDE_WRITE))
> + return -EINVAL;
> +
The code immediately above this is still performing the open coded
exclusion based on the MSI-X range, which is now incorporated into the
generic range exclusion. It should be removed. Thanks,
Alex