From: Alex Williamson <alex@shazbot.org>
To: Matt Evans <mattev@meta.com>
Cc: "Leon Romanovsky" <leon@kernel.org>,
"Jason Gunthorpe" <jgg@nvidia.com>,
"Alex Mastro" <amastro@fb.com>,
"Christian König" <christian.koenig@amd.com>,
"Bjorn Helgaas" <bhelgaas@google.com>,
"Logan Gunthorpe" <logang@deltatee.com>,
"Mahmoud Adam" <mngyadam@amazon.de>,
"David Matlack" <dmatlack@google.com>,
"Björn Töpel" <bjorn@kernel.org>,
"Sumit Semwal" <sumit.semwal@linaro.org>,
"Kevin Tian" <kevin.tian@intel.com>,
"Ankit Agrawal" <ankita@nvidia.com>,
"Pranjal Shrivastava" <praan@google.com>,
"Alistair Popple" <apopple@nvidia.com>,
"Vivek Kasireddy" <vivek.kasireddy@intel.com>,
linux-kernel@vger.kernel.org, linux-media@vger.kernel.org,
dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org,
kvm@vger.kernel.org, linux-pci@vger.kernel.org, alex@shazbot.org
Subject: Re: [PATCH v2 9/9] vfio/pci: Add mmap() attributes to DMABUF feature
Date: Thu, 28 May 2026 17:14:32 -0600 [thread overview]
Message-ID: <20260528171432.771a1a30@shazbot.org> (raw)
In-Reply-To: <20260527102319.100128-10-mattev@meta.com>
On Wed, 27 May 2026 03:23:12 -0700
Matt Evans <mattev@meta.com> wrote:
> A new VFIO feature, VFIO_DEVICE_FEATURE_DMA_BUF_MEMATTR, is added to
> set (and get) CPU-facing memory type attributes for a DMABUF exported
> from vfio-pci. These are used for subsequent mmap()s of the buffer.
>
> There are two attributes supported:
> - The default, VFIO_DEVICE_FEATURE_DMA_BUF_MEMATTR_UC
> - VFIO_DEVICE_FEATURE_DMA_BUF_MEMATTR_WC, which results in WC
> PTEs for the DMABUF's BAR region.
>
> Signed-off-by: Matt Evans <mattev@meta.com>
> ---
> drivers/vfio/pci/vfio_pci_core.c | 2 +
> drivers/vfio/pci/vfio_pci_dmabuf.c | 70 +++++++++++++++++++++++++++++-
> drivers/vfio/pci/vfio_pci_priv.h | 12 +++++
> include/uapi/linux/vfio.h | 27 ++++++++++++
> 4 files changed, 110 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> index 5184b3cac160..e256a925e7ce 100644
> --- a/drivers/vfio/pci/vfio_pci_core.c
> +++ b/drivers/vfio/pci/vfio_pci_core.c
> @@ -1590,6 +1590,8 @@ int vfio_pci_core_ioctl_feature(struct vfio_device *device, u32 flags,
> return vfio_pci_core_feature_token(vdev, flags, arg, argsz);
> case VFIO_DEVICE_FEATURE_DMA_BUF:
> return vfio_pci_core_feature_dma_buf(vdev, flags, arg, argsz);
> + case VFIO_DEVICE_FEATURE_DMA_BUF_MEMATTR:
> + return vfio_pci_core_feature_dma_buf_memattr(vdev, flags, arg, argsz);
> default:
> return -ENOTTY;
> }
> diff --git a/drivers/vfio/pci/vfio_pci_dmabuf.c b/drivers/vfio/pci/vfio_pci_dmabuf.c
> index 3fa14760898f..db8b95ddbe18 100644
> --- a/drivers/vfio/pci/vfio_pci_dmabuf.c
> +++ b/drivers/vfio/pci/vfio_pci_dmabuf.c
> @@ -42,7 +42,10 @@ static int vfio_pci_dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *
> * contained within the DMABUF size before calling this.
> */
>
> - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
> + if (READ_ONCE(priv->memattr) == VFIO_DEVICE_FEATURE_DMA_BUF_MEMATTR_WC)
> + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
> + else
> + 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. */
> @@ -464,6 +467,7 @@ int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,
> priv->vdev = vdev;
> priv->nr_ranges = get_dma_buf.nr_ranges;
> priv->size = length;
> + priv->memattr = VFIO_DEVICE_FEATURE_DMA_BUF_MEMATTR_NC;
> ret = vdev->pci_ops->get_dmabuf_phys(vdev, &priv->provider,
> get_dma_buf.region_index,
> priv->phys_vec, dma_ranges,
> @@ -731,4 +735,68 @@ int vfio_pci_dma_buf_revoke(struct vfio_pci_core_device *vdev, int dmabuf_fd)
>
> return ret;
> }
> +
> +int vfio_pci_core_feature_dma_buf_memattr(
> + struct vfio_pci_core_device *vdev, u32 flags,
> + struct vfio_device_feature_dma_buf_memattr __user *arg,
> + size_t argsz)
> +{
> + struct vfio_device_feature_dma_buf_memattr db_attr;
> + struct vfio_pci_dma_buf *priv;
> + struct dma_buf *dmabuf;
> + int ret;
> +
> + if (!vdev->pci_ops || !vdev->pci_ops->get_dmabuf_phys)
> + return -EOPNOTSUPP;
> +
> + ret = vfio_check_feature(flags, argsz,
> + VFIO_DEVICE_FEATURE_GET |
> + VFIO_DEVICE_FEATURE_SET,
> + sizeof(db_attr));
I don't see why this needs to support GET. Are we solving a userspace
problem that doesn't exist?
> + if (ret != 1)
> + return ret;
> +
> + if (copy_from_user(&db_attr, arg, sizeof(db_attr)))
> + return -EFAULT;
> +
> + dmabuf = dma_buf_get(db_attr.dmabuf_fd);
> + if (IS_ERR(dmabuf))
> + return PTR_ERR(dmabuf);
> +
> + /* Verify DMABUF: see comments in vfio_pci_dma_buf_revoke() */
> + priv = dmabuf->priv;
> + if (dmabuf->ops != &vfio_pci_dmabuf_ops || priv->vdev != vdev) {
> + ret = -ENODEV;
> + goto out_put_buf;
> + }
> +
> + ret = 0;
> + scoped_guard(rwsem_write, &vdev->memory_lock) {
Why? This doesn't serialize against mmap. Just use a WRITE_ONCE() to
match the READ_ONCE() on mmap?
> + uint32_t old_attr = priv->memattr;
> +
> + if (flags & VFIO_DEVICE_FEATURE_SET) {
> + switch(db_attr.memattr) {
> + case VFIO_DEVICE_FEATURE_DMA_BUF_MEMATTR_NC:
> + case VFIO_DEVICE_FEATURE_DMA_BUF_MEMATTR_WC:
> + priv->memattr = db_attr.memattr;
> + break;
> +
> + default:
> + ret = -ENOTSUPP;
-EINVAL
> + }
> + }
> + db_attr.memattr = old_attr;
> + }
> +
> + if (!ret && (flags & VFIO_DEVICE_FEATURE_GET)) {
> + if (copy_to_user(arg, &db_attr, sizeof(db_attr)))
> + ret = -EFAULT;
> + }
> +
> + out_put_buf:
> + dma_buf_put(dmabuf);
> +
> + return ret;
> +
> +}
> #endif /* CONFIG_VFIO_PCI_DMABUF */
> diff --git a/drivers/vfio/pci/vfio_pci_priv.h b/drivers/vfio/pci/vfio_pci_priv.h
> index a1e0f4fcb1dc..8067be45beb0 100644
> --- a/drivers/vfio/pci/vfio_pci_priv.h
> +++ b/drivers/vfio/pci/vfio_pci_priv.h
> @@ -41,6 +41,7 @@ struct vfio_pci_dma_buf {
> struct kref kref;
> struct completion comp;
> unsigned long vma_pgoff_adjust;
> + u32 memattr;
> enum vfio_pci_dma_buf_status status;
> };
>
> @@ -154,6 +155,10 @@ void vfio_pci_dma_buf_move(struct vfio_pci_core_device *vdev, bool revoked);
> int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,
> struct vfio_device_feature_dma_buf __user *arg,
> size_t argsz);
> +int vfio_pci_core_feature_dma_buf_memattr(
> + struct vfio_pci_core_device *vdev, u32 flags,
> + struct vfio_device_feature_dma_buf_memattr __user *arg,
> + size_t argsz);
> int vfio_pci_dma_buf_revoke(struct vfio_pci_core_device *vdev, int dmabuf_fd);
> #else
> static inline int
> @@ -163,6 +168,13 @@ vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,
> {
> return -ENOTTY;
> }
> +static inline int vfio_pci_core_feature_dma_buf_memattr(
> + struct vfio_pci_core_device *vdev, u32 flags,
> + struct vfio_device_feature_dma_buf_memattr __user *arg,
> + size_t argsz)
> +{
> + return -ENODEV;
-ENOTTY
Thanks,
Alex
> +}
> static inline int vfio_pci_dma_buf_revoke(struct vfio_pci_core_device *vdev,
> int dmabuf_fd)
> {
> diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
> index 02366e9f8e16..9b0b68f8a1ef 100644
> --- a/include/uapi/linux/vfio.h
> +++ b/include/uapi/linux/vfio.h
> @@ -1564,6 +1564,33 @@ struct vfio_device_feature_dma_buf {
> */
> #define VFIO_DEVICE_FEATURE_MIG_PRECOPY_INFOv2 12
>
> +/**
> + * Given a dma_buf fd previously created by
> + * VFIO_DEVICE_FEATURE_DMA_BUF, GET or SET the memory attribute that
> + * will be used by future mmap()s of that fd. SETting a new attribute
> + * does not affect existing VMAs.
> + *
> + * The default, if no previous SET has been performed, is NC.
> + *
> + * Return: 0 on success, -1 and errno is set on failure:
> + *
> + * ENOTSUPP: The given memattr is not supported.
> + * EBADF, EINVAL: dmabuf_fd is not a DMABUF fd.
> + * ENODEV: The dmabuf_fd does not match this VFIO device.
> + */
> +#define VFIO_DEVICE_FEATURE_DMA_BUF_MEMATTR 13
> +
> +/* Valid memory attributes for the memattr field */
> +enum vfio_device_dma_buf_memattr {
> + VFIO_DEVICE_FEATURE_DMA_BUF_MEMATTR_NC = 0, /* pgprot_noncached */
> + VFIO_DEVICE_FEATURE_DMA_BUF_MEMATTR_WC = 1, /* pgprot_writecombine */
> +};
> +
> +struct vfio_device_feature_dma_buf_memattr {
> + __s32 dmabuf_fd;
> + __u32 memattr;
> +};
> +
> /* -------- API for Type1 VFIO IOMMU -------- */
>
> /**
next prev parent reply other threads:[~2026-05-28 23:16 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-27 10:23 [PATCH v2 0/9] vfio/pci: Add mmap() for DMABUFs Matt Evans
2026-05-27 10:23 ` [PATCH v2 1/9] PCI/P2PDMA: Add CONFIG_PCI_P2PDMA_CORE Matt Evans
2026-05-27 16:07 ` Logan Gunthorpe
2026-05-27 17:13 ` Matt Evans
2026-05-27 21:09 ` Alex Williamson
2026-05-29 23:05 ` Jason Gunthorpe
2026-06-09 22:45 ` Bjorn Helgaas
2026-06-10 15:27 ` Pranjal Shrivastava
2026-06-10 16:00 ` Matt Evans
2026-05-27 10:23 ` [PATCH v2 2/9] vfio/pci: Add a helper to look up PFNs for DMABUFs Matt Evans
2026-05-27 22:38 ` Alex Williamson
2026-06-02 16:37 ` Matt Evans
2026-05-27 10:23 ` [PATCH v2 3/9] vfio/pci: Add a helper to create a DMABUF for a BAR-map VMA Matt Evans
2026-05-27 22:59 ` Alex Williamson
2026-06-02 16:39 ` Matt Evans
2026-05-27 10:23 ` [PATCH v2 4/9] vfio/pci: Convert BAR mmap() to use a DMABUF Matt Evans
2026-05-28 23:15 ` Alex Williamson
2026-06-02 18:01 ` Matt Evans
2026-05-27 10:23 ` [PATCH v2 5/9] vfio/pci: Provide a user-facing name for BAR mappings Matt Evans
2026-05-27 10:23 ` [PATCH v2 6/9] vfio/pci: Clean up BAR zap and revocation Matt Evans
2026-05-28 23:15 ` Alex Williamson
2026-05-27 10:23 ` [PATCH v2 7/9] vfio/pci: Support mmap() of a VFIO DMABUF Matt Evans
2026-05-28 23:15 ` Alex Williamson
2026-06-02 17:35 ` Matt Evans
2026-06-02 19:03 ` Alex Williamson
2026-05-27 10:23 ` [PATCH v2 8/9] vfio/pci: Permanently revoke a DMABUF on request Matt Evans
2026-05-28 23:14 ` Alex Williamson
2026-06-02 17:02 ` Matt Evans
2026-05-27 10:23 ` [PATCH v2 9/9] vfio/pci: Add mmap() attributes to DMABUF feature Matt Evans
2026-05-28 23:14 ` Alex Williamson [this message]
2026-06-02 16:50 ` Matt Evans
2026-06-02 19:14 ` Alex Williamson
2026-06-03 14:22 ` Matt Evans
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260528171432.771a1a30@shazbot.org \
--to=alex@shazbot.org \
--cc=amastro@fb.com \
--cc=ankita@nvidia.com \
--cc=apopple@nvidia.com \
--cc=bhelgaas@google.com \
--cc=bjorn@kernel.org \
--cc=christian.koenig@amd.com \
--cc=dmatlack@google.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=jgg@nvidia.com \
--cc=kevin.tian@intel.com \
--cc=kvm@vger.kernel.org \
--cc=leon@kernel.org \
--cc=linaro-mm-sig@lists.linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=logang@deltatee.com \
--cc=mattev@meta.com \
--cc=mngyadam@amazon.de \
--cc=praan@google.com \
--cc=sumit.semwal@linaro.org \
--cc=vivek.kasireddy@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.