From: Pranjal Shrivastava <praan@google.com>
To: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
kvm@vger.kernel.org
Cc: Bjorn Helgaas <bhelgaas@google.com>,
Logan Gunthorpe <logang@deltatee.com>,
Alex Williamson <alex@shazbot.org>,
Jason Gunthorpe <jgg@ziepe.ca>, Kevin Tian <kevin.tian@intel.com>,
Pranjal Shrivastava <praan@google.com>,
Ankit Agrawal <ankita@nvidia.com>, Matt Evans <mattev@meta.com>,
Vivek Kasireddy <vivek.kasireddy@intel.com>,
Leon Romanovsky <leon@kernel.org>,
Shivaji Kant <shivajikant@google.com>,
Samiullah Khawaja <skhawaja@google.com>,
Unnati Sachan <unnatisachan@google.com>
Subject: [RFC PATCH v2 4/5] vfio/pci: Add .mmap handler for page-backed DMABUFs
Date: Tue, 4 Aug 2026 18:50:49 +0000 [thread overview]
Message-ID: <20260804185050.2053672-5-praan@google.com> (raw)
In-Reply-To: <20260804185050.2053672-1-praan@google.com>
Implement mmap and a corresponding page fault handler for ZONE_DEVICE
backed DMABUFs. Set VM_MIXEDMAP for page-backed VMAs and introduce the
vfio_pci_vmf_insert_page() helper to insert struct page pointers into
the user PTEs.
Signed-off-by: Pranjal Shrivastava <praan@google.com>
---
drivers/vfio/pci/vfio_pci_core.c | 39 +++++++++++++++++++++++++++---
drivers/vfio/pci/vfio_pci_dmabuf.c | 22 +++++++++++++++--
include/linux/vfio_pci_core.h | 3 +++
3 files changed, 58 insertions(+), 6 deletions(-)
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 9ca99a5a61c3..f5c2912c3ffc 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -1790,6 +1790,34 @@ vm_fault_t vfio_pci_vmf_insert_pfn(struct vfio_pci_core_device *vdev,
}
EXPORT_SYMBOL_GPL(vfio_pci_vmf_insert_pfn);
+vm_fault_t vfio_pci_vmf_insert_page(struct vfio_pci_core_device *vdev,
+ struct vm_fault *vmf,
+ unsigned long pfn,
+ unsigned int order)
+{
+ struct vm_area_struct *vma = vmf->vma;
+ struct page *page;
+
+ lockdep_assert_held_read(&vdev->memory_lock);
+
+ if (vdev->pm_runtime_engaged || !__vfio_pci_memory_enabled(vdev))
+ return VM_FAULT_SIGBUS;
+
+ /* vmf_insert_page only supports 0-order pages */
+ if (order > 0)
+ return VM_FAULT_FALLBACK;
+
+ if (WARN_ON_ONCE(!pfn_valid(pfn)))
+ return VM_FAULT_SIGBUS;
+
+ page = pfn_to_page(pfn);
+
+ if (vma->vm_flags & VM_WRITE)
+ return vmf_insert_page_mkwrite(vmf, page, false);
+
+ return vmf_insert_page(vma, vmf->address, page);
+}
+
static vm_fault_t vfio_pci_mmap_huge_fault(struct vm_fault *vmf,
unsigned int order)
{
@@ -1877,11 +1905,14 @@ static vm_fault_t vfio_pci_mmap_huge_fault(struct vm_fault *vmf,
vmf->address,
order, &pfn);
- if (pres == 0)
- ret = vfio_pci_vmf_insert_pfn(vdev, vmf,
- pfn, order);
- else if (pres == -EAGAIN)
+ if (pres == 0) {
+ if (priv->zone_device_backed)
+ ret = vfio_pci_vmf_insert_page(vdev, vmf, pfn, order);
+ else
+ ret = vfio_pci_vmf_insert_pfn(vdev, vmf, pfn, order);
+ } else if (pres == -EAGAIN) {
ret = VM_FAULT_FALLBACK;
+ }
}
}
diff --git a/drivers/vfio/pci/vfio_pci_dmabuf.c b/drivers/vfio/pci/vfio_pci_dmabuf.c
index b936da3bcada..b582e856ba7a 100644
--- a/drivers/vfio/pci/vfio_pci_dmabuf.c
+++ b/drivers/vfio/pci/vfio_pci_dmabuf.c
@@ -4,6 +4,7 @@
#include <linux/dma-buf-mapping.h>
#include <linux/pci-p2pdma.h>
#include <linux/dma-resv.h>
+#include <linux/sched.h>
#include <uapi/linux/dma-buf.h>
#include "vfio_pci_priv.h"
@@ -53,8 +54,14 @@ static int vfio_pci_dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *
vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
/* See comments in vfio_pci_core_mmap() re VM_ALLOW_ANY_UNCACHED. */
- vm_flags_set(vma, VM_ALLOW_ANY_UNCACHED | VM_IO | VM_PFNMAP |
- VM_DONTEXPAND | VM_DONTDUMP);
+ if (priv->zone_device_backed) {
+ /* VM_MIXEDMAP is required for ZONE_DEVICE pages */
+ vm_flags_set(vma, VM_ALLOW_ANY_UNCACHED | VM_MIXEDMAP |
+ VM_DONTEXPAND | VM_DONTDUMP);
+ } else {
+ vm_flags_set(vma, VM_ALLOW_ANY_UNCACHED | VM_IO | VM_PFNMAP |
+ VM_DONTEXPAND | VM_DONTDUMP);
+ }
vma->vm_private_data = priv;
vfio_pci_set_vma_ops(vma);
@@ -521,6 +528,17 @@ static int vfio_pci_dma_buf_alloc_struct_pages(struct vfio_pci_core_device *vdev
if (ret) {
if (ret != -EEXIST)
return ret;
+ } else {
+ /* Initialise the refcount for the freshly allocated page. */
+ unsigned long pfn = pci_resource_start(pdev, bar_index) >> PAGE_SHIFT;
+ unsigned long npgs = pci_resource_len(pdev, bar_index) >> PAGE_SHIFT;
+
+ while (npgs--) {
+ set_page_count(pfn_to_page(pfn++), 1);
+ /* Yield the CPU periodically on large BARs to prevent soft lockups */
+ if (unlikely((npgs & 4095) == 0))
+ cond_resched();
+ }
}
vdev->p2p_struct_page_bars |= (1 << bar_index);
diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h
index c28f06bae302..778671194b24 100644
--- a/include/linux/vfio_pci_core.h
+++ b/include/linux/vfio_pci_core.h
@@ -187,6 +187,9 @@ ssize_t vfio_pci_core_write(struct vfio_device *core_vdev, const char __user *bu
vm_fault_t vfio_pci_vmf_insert_pfn(struct vfio_pci_core_device *vdev,
struct vm_fault *vmf, unsigned long pfn,
unsigned int order);
+vm_fault_t vfio_pci_vmf_insert_page(struct vfio_pci_core_device *vdev,
+ struct vm_fault *vmf, unsigned long pfn,
+ unsigned int order);
int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma);
void vfio_pci_core_request(struct vfio_device *core_vdev, unsigned int count);
int vfio_pci_core_match(struct vfio_device *core_vdev, char *buf);
--
2.55.0.571.g244d577d93-goog
next prev parent reply other threads:[~2026-08-04 18:51 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-04 18:50 [RFC PATCH v2 0/5] vfio/pci: Support ZONE_DEVICE-backed DMABUF Exports Pranjal Shrivastava
2026-08-04 18:50 ` [RFC PATCH v2 1/5] vfio: Add UAPI flag for ZONE_DEVICE-backed DMABUF exports Pranjal Shrivastava
2026-08-04 18:50 ` [RFC PATCH v2 2/5] vfio/pci: Implement ZONE_DEVICE registration for DMABUFs Pranjal Shrivastava
2026-08-04 18:50 ` [RFC PATCH v2 3/5] vfio/pci: Implement page-backed .map_dma_buf handler Pranjal Shrivastava
2026-08-04 18:50 ` Pranjal Shrivastava [this message]
2026-08-04 18:50 ` [RFC PATCH v2 5/5] vfio/pci: Add revocation fence for ZONE_DEVICE DMABUFs Pranjal Shrivastava
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=20260804185050.2053672-5-praan@google.com \
--to=praan@google.com \
--cc=alex@shazbot.org \
--cc=ankita@nvidia.com \
--cc=bhelgaas@google.com \
--cc=jgg@ziepe.ca \
--cc=kevin.tian@intel.com \
--cc=kvm@vger.kernel.org \
--cc=leon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=logang@deltatee.com \
--cc=mattev@meta.com \
--cc=shivajikant@google.com \
--cc=skhawaja@google.com \
--cc=unnatisachan@google.com \
--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.