virtualization.lists.linux-foundation.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v7 0/4] virtio-gpu: Add userptr support for compute workloads
@ 2026-09-18  2:11 Honglei Huang
  2026-09-18  2:11 ` [PATCH v7 1/4] drm/virtio-gpu: Add VIRTIO_GPU_CAPSET_ROCM capability Honglei Huang
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Honglei Huang @ 2026-09-18  2:11 UTC (permalink / raw)
  To: Dmitry Osipenko, Akihiko Odaki, David Airlie, Gerd Hoffmann
  Cc: Gurchetan Singh, Chia-I Wu, Ray Huang, dri-devel, virtualization,
	linux-kernel, Honglei Huang

Hello,

This series adds virtio-gpu userptr support for ROCm native compute
contexts. The guest kernel pins an existing userspace mapping with
FOLL_LONGTERM and exposes it to the host as ordinary CREATE_BLOB
backing entries, avoiding a second shmem allocation and memcpy.

USE_USERPTR and USERPTR_RDONLY are guest-only DRM ioctl selectors.
They are not added to virtio_gpu.h; the device does not need a new
wire flag.

Patches overview:
1. Add VIRTIO_GPU_CAPSET_ROCM capability for compute workloads
2. Extend DRM UAPI with guest-only userptr flags and strip them
   from the CREATE_BLOB wire command
3. Implement core userptr functionality with page management
4. Wire blob ioctl creation to userptr objects

Tests:
- Full OPENCL CTS tests passed on ROCm 5.7.0 in V2000 platform.
- Near 70% percentage of OPENCL CTS tests passed on ROCm 7.0 W7900 platform.
- most HIP catch tests passed on ROCm 7.0 W7900 platform.
- Some AI applications enabled on ROCm 7.0 W7900 platform.
- latest ROCm 7.14 and ROCm 10 testing is ongoing.

V7 changes:
- Mask guest-only DRM flags out of CREATE_BLOB wire blob_flags
- Clear userptr->pages after pin failure to avoid double-free
- DMA-map userptr SG only when virtio_gpu_use_dma_api() is required
- Use DMA_TO_DEVICE for USERPTR_RDONLY
- Reject USERPTR unless blob_mem is VIRTGPU_BLOB_MEM_GUEST
- Note that CAPSET_ROCM uses ID 8 because ID 7 is taken by VIRCL

V6 changes:
- Rebase onto drm-misc-next
- Keep USE_USERPTR / USERPTR_RDONLY as guest-only DRM flags; drop the
  virtio wire-header patch (5 patches down to 4)
- Fix userptr lifetime, DMA mapping, memlock accounting, alignment
  checks, and PRIME SG export
- Updated corresponding cover letter and commit messages

V5 changes:
    - Add VIRTIO_GPU_BLOB_FLAG_USERPTR_RDONLY definition to patch 2
    - Dropped unused VIRTIO_GPU_F_RESOURCE_USERPTR feature bit in patch 2
    - Included VIRTIO_GPU_BLOB_FLAG_USERPTR_RDONLY in VIRTGPU_BLOB_FLAG_USE_MASK in patch 5
    - Add check for userptr feature in patch 5 before creating userptr blob resource
    - Updated corresponding cover letter and commit messages

V4 changes:
    - Renamed VIRTIO_GPU_CAPSET_HSAKMT to VIRTIO_GPU_CAPSET_ROCM
    - Remove userptr feature probing cause it can reuse the guest
      blob resource code path, reduce patch count from 6 to 5
    - Updated corresponding commit messages
    - Consolidated userptr feature detection in final patch
    - Update corresponding cover letter content

V3 changes:
    - Split into focused patches for easier review
    - Removed complex interval tree userptr management
    - Simplified resource creation without deduplication
    - Added VIRTGPU_PARAM_RESOURCE_USERPTR for feature detection
    - Improved UAPI documentation and error handling
    - Enhanced code quality with proper cleanup paths
    - Removed MMU notifier dependencies for simplicity
    - Fixed resource lifecycle management issues

V2: - Split add HSAKMT context and blob userptr resource to two patches.
    - Remove MMU notifier related patches, cause use not moveable user space
      memory with MMU notifier is not a good idea.
    - Remove HSAKMT context check when create context, let all the context
      support the userptr feature.
    - Remove MMU notifier related content in cover letter.
    - Add more comments  for patch 6 in cover letter.

Previous version:
https://lore.kernel.org/dri-devel/20260917102540.1312102-1-honghuan@amd.com/

Honglei Huang (4):
  drm/virtio-gpu: Add VIRTIO_GPU_CAPSET_ROCM capability
  drm/virtgpu api: add blob userptr resource
  drm/virtio: implement userptr support for zero-copy memory access
  drm/virtio: wire blob ioctl creation to userptr objects

 drivers/gpu/drm/virtio/Makefile          |   3 +-
 drivers/gpu/drm/virtio/virtgpu_drv.h     |  37 +++
 drivers/gpu/drm/virtio/virtgpu_ioctl.c   |  25 +-
 drivers/gpu/drm/virtio/virtgpu_object.c  |  10 +
 drivers/gpu/drm/virtio/virtgpu_userptr.c | 335 +++++++++++++++++++++++
 drivers/gpu/drm/virtio/virtgpu_vq.c      |   6 +-
 include/uapi/drm/virtgpu_drm.h           |   9 +
 include/uapi/linux/virtio_gpu.h          |   1 +
 8 files changed, 422 insertions(+), 4 deletions(-)
 create mode 100644 drivers/gpu/drm/virtio/virtgpu_userptr.c

base-commit: 766bfba0f3bae329f99b42dcabc3ef11fa368f0b
-- 
2.34.1

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v7 1/4] drm/virtio-gpu: Add VIRTIO_GPU_CAPSET_ROCM capability
  2026-09-18  2:11 [PATCH v7 0/4] virtio-gpu: Add userptr support for compute workloads Honglei Huang
@ 2026-09-18  2:11 ` Honglei Huang
  2026-09-18  2:16   ` sashiko-bot
  2026-09-18  2:11 ` [PATCH v7 2/4] drm/virtgpu api: add blob userptr resource Honglei Huang
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Honglei Huang @ 2026-09-18  2:11 UTC (permalink / raw)
  To: Dmitry Osipenko, Akihiko Odaki, David Airlie, Gerd Hoffmann
  Cc: Gurchetan Singh, Chia-I Wu, Ray Huang, dri-devel, virtualization,
	linux-kernel, Honglei Huang

Add a new GPU capability set VIRTIO_GPU_CAPSET_ROCM to support
ROCm compute workloads in virtualized environments.

ROCm (Radeon Open Compute) is AMD's open-source software platform
for GPU compute and HPC workloads.

ID 7 is already used by VIRCL in the virgl/virtio-gpu stack, so
ROCm uses ID 8. A matching virtio-gpu specification change is in
progress to register this assignment.

Signed-off-by: Honglei Huang <honghuan@amd.com>
---
 include/uapi/linux/virtio_gpu.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h
index 4f530d9005..3d4dfadc9d 100644
--- a/include/uapi/linux/virtio_gpu.h
+++ b/include/uapi/linux/virtio_gpu.h
@@ -321,6 +321,7 @@ struct virtio_gpu_cmd_submit {
 #define VIRTIO_GPU_CAPSET_VENUS 4
 #define VIRTIO_GPU_CAPSET_CROSS_DOMAIN 5
 #define VIRTIO_GPU_CAPSET_DRM 6
+#define VIRTIO_GPU_CAPSET_ROCM 8
 
 /* VIRTIO_GPU_CMD_GET_CAPSET_INFO */
 struct virtio_gpu_get_capset_info {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v7 2/4] drm/virtgpu api: add blob userptr resource
  2026-09-18  2:11 [PATCH v7 0/4] virtio-gpu: Add userptr support for compute workloads Honglei Huang
  2026-09-18  2:11 ` [PATCH v7 1/4] drm/virtio-gpu: Add VIRTIO_GPU_CAPSET_ROCM capability Honglei Huang
@ 2026-09-18  2:11 ` Honglei Huang
  2026-09-18  2:19   ` sashiko-bot
  2026-09-18  2:11 ` [PATCH v7 3/4] drm/virtio: implement userptr support for zero-copy memory access Honglei Huang
  2026-09-18  2:11 ` [PATCH v7 4/4] drm/virtio: wire blob ioctl creation to userptr objects Honglei Huang
  3 siblings, 1 reply; 9+ messages in thread
From: Honglei Huang @ 2026-09-18  2:11 UTC (permalink / raw)
  To: Dmitry Osipenko, Akihiko Odaki, David Airlie, Gerd Hoffmann
  Cc: Gurchetan Singh, Chia-I Wu, Ray Huang, dri-devel, virtualization,
	linux-kernel, Honglei Huang

Add DRM ioctl flags and a userptr address field so userspace can
request a blob backed by an existing process mapping.

UAPI changes:
- Add guest-only VIRTGPU_BLOB_FLAG_USE_USERPTR and
  VIRTGPU_BLOB_FLAG_USERPTR_RDONLY flags
- Add a userptr field to drm_virtgpu_resource_create_blob

These flags select guest pin behavior in the ioctl. They are not
part of the virtio CREATE_BLOB wire ABI, so mask them out in
virtio_gpu_cmd_resource_create_blob().

Signed-off-by: Honglei Huang <honghuan@amd.com>
---
 drivers/gpu/drm/virtio/virtgpu_vq.c | 6 +++++-
 include/uapi/drm/virtgpu_drm.h      | 9 +++++++++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index c02c03c10d..6830673309 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -1494,7 +1494,11 @@ virtio_gpu_cmd_resource_create_blob(struct virtio_gpu_device *vgdev,
 	cmd_p->hdr.ctx_id = cpu_to_le32(params->ctx_id);
 	cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle);
 	cmd_p->blob_mem = cpu_to_le32(params->blob_mem);
-	cmd_p->blob_flags = cpu_to_le32(params->blob_flags);
+	/* Guest-only flags stay off the wire. */
+	cmd_p->blob_flags = cpu_to_le32(params->blob_flags &
+			(VIRTIO_GPU_BLOB_FLAG_USE_MAPPABLE |
+			 VIRTIO_GPU_BLOB_FLAG_USE_SHAREABLE |
+			 VIRTIO_GPU_BLOB_FLAG_USE_CROSS_DEVICE));
 	cmd_p->blob_id = cpu_to_le64(params->blob_id);
 	cmd_p->size = cpu_to_le64(params->size);
 	cmd_p->nr_entries = cpu_to_le32(nents);
diff --git a/include/uapi/drm/virtgpu_drm.h b/include/uapi/drm/virtgpu_drm.h
index 95587e12ae..62c4b8f19b 100644
--- a/include/uapi/drm/virtgpu_drm.h
+++ b/include/uapi/drm/virtgpu_drm.h
@@ -186,6 +186,9 @@ struct drm_virtgpu_resource_create_blob {
 #define VIRTGPU_BLOB_FLAG_USE_MAPPABLE     0x0001
 #define VIRTGPU_BLOB_FLAG_USE_SHAREABLE    0x0002
 #define VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE 0x0004
+/* Guest-only flags */
+#define VIRTGPU_BLOB_FLAG_USE_USERPTR      0x0008
+#define VIRTGPU_BLOB_FLAG_USERPTR_RDONLY   0x0010
 	/* zero is invalid blob_mem */
 	__u32 blob_mem;
 	__u32 blob_flags;
@@ -205,6 +208,12 @@ struct drm_virtgpu_resource_create_blob {
 #define DRM_VIRTGPU_BLOB_FLAG_HINT_DEFER_MAPPING        0x0001
 	__u32 blob_hints;
 	__u32 pad2;
+
+	/*
+	 * userptr: guest userspace memory address for VIRTGPU_BLOB_FLAG_USE_USERPTR.
+	 * Must be 0 if VIRTGPU_BLOB_FLAG_USE_USERPTR is not set.
+	 */
+	__u64 userptr;
 };
 
 #define VIRTGPU_CONTEXT_PARAM_CAPSET_ID       0x0001
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v7 3/4] drm/virtio: implement userptr support for zero-copy memory access
  2026-09-18  2:11 [PATCH v7 0/4] virtio-gpu: Add userptr support for compute workloads Honglei Huang
  2026-09-18  2:11 ` [PATCH v7 1/4] drm/virtio-gpu: Add VIRTIO_GPU_CAPSET_ROCM capability Honglei Huang
  2026-09-18  2:11 ` [PATCH v7 2/4] drm/virtgpu api: add blob userptr resource Honglei Huang
@ 2026-09-18  2:11 ` Honglei Huang
  2026-09-18  2:29   ` sashiko-bot
  2026-09-18  2:11 ` [PATCH v7 4/4] drm/virtio: wire blob ioctl creation to userptr objects Honglei Huang
  3 siblings, 1 reply; 9+ messages in thread
From: Honglei Huang @ 2026-09-18  2:11 UTC (permalink / raw)
  To: Dmitry Osipenko, Akihiko Odaki, David Airlie, Gerd Hoffmann
  Cc: Gurchetan Singh, Chia-I Wu, Ray Huang, dri-devel, virtualization,
	linux-kernel, Honglei Huang

Add userptr blob objects so the guest kernel can pin an existing
userspace mapping and advertise it as CREATE_BLOB backing entries.

- New virtio_gpu_object_userptr type for userptr resources
- Pin pages with pin_user_pages_fast() and FOLL_LONGTERM
- Charge FOLL_LONGTERM pins against RLIMIT_MEMLOCK
- DMA-map the scatterlist only when virtio_gpu_use_dma_api() is
  required; use DMA_TO_DEVICE for USERPTR_RDONLY
- Keep pages pinned until RESOURCE_UNREF is queued; drop them from
  cleanup_object() on the unref response or on create failure
- Clear userptr->pages on pin failure to avoid double-free on cleanup
- Reject unaligned or overflowing userptr ranges at create time
- Return a fresh SG table from PRIME export

Signed-off-by: Honglei Huang <honghuan@amd.com>
---
 drivers/gpu/drm/virtio/Makefile          |   3 +-
 drivers/gpu/drm/virtio/virtgpu_drv.h     |  37 +++
 drivers/gpu/drm/virtio/virtgpu_object.c  |  10 +
 drivers/gpu/drm/virtio/virtgpu_userptr.c | 335 +++++++++++++++++++++++
 4 files changed, 384 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/virtio/virtgpu_userptr.c

diff --git a/drivers/gpu/drm/virtio/Makefile b/drivers/gpu/drm/virtio/Makefile
index d2e1788a82..fe7332a621 100644
--- a/drivers/gpu/drm/virtio/Makefile
+++ b/drivers/gpu/drm/virtio/Makefile
@@ -6,6 +6,7 @@
 virtio-gpu-y := virtgpu_drv.o virtgpu_kms.o virtgpu_gem.o virtgpu_vram.o \
 	virtgpu_display.o virtgpu_vq.o \
 	virtgpu_fence.o virtgpu_object.o virtgpu_debugfs.o virtgpu_plane.o \
-	virtgpu_ioctl.o virtgpu_prime.o virtgpu_trace_points.o virtgpu_submit.o
+	virtgpu_ioctl.o virtgpu_prime.o virtgpu_trace_points.o virtgpu_submit.o \
+	virtgpu_userptr.o
 
 obj-$(CONFIG_DRM_VIRTIO_GPU) += virtio-gpu.o
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 9df4c71173..03791b72ca 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -105,6 +105,7 @@ struct virtio_gpu_object_params {
 	uint32_t blob_flags;
 	uint64_t blob_id;
 	uint32_t blob_hints;
+	uint64_t userptr;
 };
 
 struct virtio_gpu_object {
@@ -138,12 +139,42 @@ struct virtio_gpu_object_vram {
 	struct drm_mm_node vram_node;
 };
 
+struct virtio_gpu_object_userptr;
+
+struct virtio_gpu_object_userptr_ops {
+	int (*get_pages)(struct virtio_gpu_object_userptr *userptr);
+	void (*put_pages)(struct virtio_gpu_object_userptr *userptr);
+};
+
+struct virtio_gpu_object_userptr {
+	struct virtio_gpu_object base;
+	const struct virtio_gpu_object_userptr_ops *ops;
+	/* Protects pages and sgt. */
+	struct mutex lock;
+
+	uint64_t start;
+	uint32_t npages;
+	uint32_t bo_handle;
+	uint32_t flags;
+
+	struct virtio_gpu_device *vgdev;
+	struct drm_file *file;
+	struct page **pages;
+	struct sg_table *sgt;
+	bool dma_mapped;
+	enum dma_data_direction dma_dir;
+	struct mm_struct *mm;
+};
+
 #define to_virtio_gpu_shmem(virtio_gpu_object) \
 	container_of((virtio_gpu_object), struct virtio_gpu_object_shmem, base)
 
 #define to_virtio_gpu_vram(virtio_gpu_object) \
 	container_of((virtio_gpu_object), struct virtio_gpu_object_vram, base)
 
+#define to_virtio_gpu_userptr(virtio_gpu_object) \
+	container_of((virtio_gpu_object), struct virtio_gpu_object_userptr, base)
+
 struct virtio_gpu_object_array {
 	struct ww_acquire_ctx ticket;
 	struct list_head next;
@@ -562,4 +593,10 @@ void virtio_gpu_vram_map_deferred(struct virtio_gpu_object_vram *vram);
 int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
 				struct drm_file *file);
 
+/* virtgpu_userptr.c */
+int virtio_gpu_userptr_create(struct virtio_gpu_device *vgdev,
+			      struct drm_file *file,
+			      struct virtio_gpu_object_params *params,
+			      struct virtio_gpu_object **bo_ptr);
+bool virtio_gpu_is_userptr(struct virtio_gpu_object *bo);
 #endif
diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
index 49899485be..5c40f5a034 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -91,6 +91,16 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo)
 		drm_gem_free_mmap_offset(&vram->base.base.base);
 		drm_gem_object_release(&vram->base.base.base);
 		kfree(vram);
+	} else if (virtio_gpu_is_userptr(bo)) {
+		struct virtio_gpu_object_userptr *userptr =
+			to_virtio_gpu_userptr(bo);
+
+		mutex_lock(&userptr->lock);
+		userptr->ops->put_pages(userptr);
+		mutex_unlock(&userptr->lock);
+		mutex_destroy(&userptr->lock);
+		drm_gem_object_release(&userptr->base.base.base);
+		kfree(userptr);
 	} else {
 		drm_gem_object_release(&bo->base.base);
 		kfree(bo);
diff --git a/drivers/gpu/drm/virtio/virtgpu_userptr.c b/drivers/gpu/drm/virtio/virtgpu_userptr.c
new file mode 100644
index 0000000000..0097554897
--- /dev/null
+++ b/drivers/gpu/drm/virtio/virtgpu_userptr.c
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/dma-mapping.h>
+#include <linux/limits.h>
+#include <linux/mm.h>
+#include <linux/overflow.h>
+#include <linux/pid.h>
+#include <linux/sched/mm.h>
+#include <linux/sched/signal.h>
+#include <linux/vmalloc.h>
+
+#include "virtgpu_drv.h"
+#include <drm/drm_gem.h>
+#include <drm/drm_prime.h>
+
+static struct sg_table *
+virtio_gpu_userptr_get_sg_table(struct drm_gem_object *obj);
+
+static void virtio_gpu_userptr_free(struct drm_gem_object *obj)
+{
+	struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
+	struct virtio_gpu_device *vgdev = obj->dev->dev_private;
+
+	/*
+	 * Keep pages pinned until RESOURCE_UNREF completes. The response
+	 * callback calls virtio_gpu_cleanup_object(), which drops them.
+	 */
+	if (bo->created) {
+		virtio_gpu_remove_from_restore_list(bo);
+		virtio_gpu_cmd_unref_resource(vgdev, bo, false);
+		virtio_gpu_notify(vgdev);
+		return;
+	}
+
+	virtio_gpu_cleanup_object(bo);
+}
+
+static const struct drm_gem_object_funcs virtio_gpu_userptr_funcs = {
+	.open = virtio_gpu_gem_object_open,
+	.close = virtio_gpu_gem_object_close,
+	.free = virtio_gpu_userptr_free,
+	.export = virtgpu_gem_prime_export,
+	.get_sg_table = virtio_gpu_userptr_get_sg_table,
+};
+
+bool virtio_gpu_is_userptr(struct virtio_gpu_object *bo)
+{
+	return bo->base.base.funcs == &virtio_gpu_userptr_funcs;
+}
+
+static int
+virtio_gpu_userptr_get_pages(struct virtio_gpu_object_userptr *userptr)
+{
+	unsigned int flag = FOLL_LONGTERM;
+	unsigned int num_pages, pinned = 0;
+	int ret = 0;
+
+	if (userptr->pages)
+		return 0;
+
+	userptr->pages = kvmalloc_array(userptr->npages, sizeof(struct page *),
+					GFP_KERNEL);
+	if (!userptr->pages)
+		return -ENOMEM;
+
+	if (!(userptr->flags & VIRTGPU_BLOB_FLAG_USERPTR_RDONLY))
+		flag |= FOLL_WRITE;
+
+	do {
+		num_pages = userptr->npages - pinned;
+
+		ret = pin_user_pages_fast(userptr->start + pinned * PAGE_SIZE,
+					  num_pages, flag,
+					  userptr->pages + pinned);
+
+		if (ret < 0) {
+			if (pinned)
+				unpin_user_pages(userptr->pages, pinned);
+			kvfree(userptr->pages);
+			userptr->pages = NULL;
+			return ret;
+		}
+
+		pinned += ret;
+
+	} while (pinned < userptr->npages);
+
+	return 0;
+}
+
+static void
+virtio_gpu_userptr_unaccount(struct virtio_gpu_object_userptr *userptr)
+{
+	if (!userptr->mm)
+		return;
+
+	atomic64_sub(userptr->npages, &userptr->mm->pinned_vm);
+	mmdrop(userptr->mm);
+	userptr->mm = NULL;
+}
+
+static void
+virtio_gpu_userptr_put_pages(struct virtio_gpu_object_userptr *userptr)
+{
+	struct drm_device *dev = userptr->base.base.base.dev;
+
+	if (userptr->sgt) {
+		if (userptr->dma_mapped)
+			dma_unmap_sgtable(drm_dev_dma_dev(dev), userptr->sgt,
+					  userptr->dma_dir, 0);
+		userptr->dma_mapped = false;
+		sg_free_table(userptr->sgt);
+		kfree(userptr->sgt);
+		userptr->sgt = NULL;
+	}
+
+	if (userptr->pages) {
+		unpin_user_pages(userptr->pages, userptr->npages);
+		kvfree(userptr->pages);
+		userptr->pages = NULL;
+	}
+
+	virtio_gpu_userptr_unaccount(userptr);
+}
+
+static int
+virtio_gpu_userptr_get_entries(struct virtio_gpu_device *vgdev,
+			       struct virtio_gpu_object_userptr *userptr,
+			       struct virtio_gpu_mem_entry **ents,
+			       unsigned int *nents)
+{
+	bool use_dma_api = virtio_gpu_use_dma_api(vgdev->vdev);
+	struct scatterlist *sg;
+	unsigned int count;
+	int si;
+
+	count = use_dma_api ? userptr->sgt->nents : userptr->sgt->orig_nents;
+	if (!count)
+		return -EINVAL;
+
+	*ents = kvmalloc_array(count, sizeof(**ents), GFP_KERNEL);
+	if (!*ents)
+		return -ENOMEM;
+
+	if (use_dma_api) {
+		for_each_sgtable_dma_sg(userptr->sgt, sg, si) {
+			(*ents)[si].addr = cpu_to_le64(sg_dma_address(sg));
+			(*ents)[si].length = cpu_to_le32(sg_dma_len(sg));
+			(*ents)[si].padding = 0;
+		}
+	} else {
+		for_each_sgtable_sg(userptr->sgt, sg, si) {
+			(*ents)[si].addr = cpu_to_le64(sg_phys(sg));
+			(*ents)[si].length = cpu_to_le32(sg->length);
+			(*ents)[si].padding = 0;
+		}
+	}
+
+	*nents = count;
+	return 0;
+}
+
+static struct sg_table *
+virtio_gpu_userptr_get_sg_table(struct drm_gem_object *obj)
+{
+	struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
+	struct virtio_gpu_object_userptr *userptr = to_virtio_gpu_userptr(bo);
+	int ret;
+
+	mutex_lock(&userptr->lock);
+	if (!userptr->pages) {
+		ret = userptr->ops->get_pages(userptr);
+		if (ret) {
+			mutex_unlock(&userptr->lock);
+			return ERR_PTR(ret);
+		}
+	}
+	mutex_unlock(&userptr->lock);
+
+	/* PRIME takes ownership of the returned table. */
+	return drm_prime_pages_to_sg(obj->dev, userptr->pages, userptr->npages);
+}
+
+static int
+virtio_gpu_userptr_init(struct drm_device *dev, struct drm_file *file,
+			struct virtio_gpu_object_userptr *userptr,
+			struct virtio_gpu_object_params *params,
+			const struct virtio_gpu_object_userptr_ops *ops)
+{
+	struct drm_gem_object *obj;
+	int ret;
+
+	userptr->start = params->userptr;
+	userptr->npages = params->size >> PAGE_SHIFT;
+	userptr->flags = params->blob_flags;
+
+	mutex_init(&userptr->lock);
+	userptr->vgdev = dev->dev_private;
+	userptr->file = file;
+	userptr->ops = ops;
+
+	/*
+	 * Allocate the resource id before GEM init so a failure here can
+	 * unwind with a plain kfree and does not need a special id=0 guard
+	 * in the shared resource_id_put helper.
+	 */
+	ret = virtio_gpu_resource_id_get(userptr->vgdev,
+					 &userptr->base.hw_res_handle);
+	if (ret) {
+		mutex_destroy(&userptr->lock);
+		return ret;
+	}
+
+	obj = &userptr->base.base.base;
+	obj->funcs = &virtio_gpu_userptr_funcs;
+
+	drm_gem_private_object_init(dev, obj, params->size);
+	INIT_LIST_HEAD(&userptr->base.restore_node);
+
+	return 0;
+}
+
+static const struct virtio_gpu_object_userptr_ops virtio_gpu_userptr_ops = {
+	.get_pages = virtio_gpu_userptr_get_pages,
+	.put_pages = virtio_gpu_userptr_put_pages,
+};
+
+int virtio_gpu_userptr_create(struct virtio_gpu_device *vgdev,
+			      struct drm_file *file,
+			      struct virtio_gpu_object_params *params,
+			      struct virtio_gpu_object **bo_ptr)
+{
+	struct virtio_gpu_object_userptr *userptr;
+	struct virtio_gpu_mem_entry *ents = NULL;
+	struct sg_table *sgt;
+	struct mm_struct *mm;
+	unsigned long lock_limit;
+	unsigned long start;
+	unsigned long end;
+	s64 new_pinned;
+	unsigned int nents;
+	int ret;
+
+	*bo_ptr = NULL;
+
+	if (!params->size || !IS_ALIGNED(params->size, PAGE_SIZE) ||
+	    params->userptr != (unsigned long)params->userptr)
+		return -EINVAL;
+
+	start = params->userptr;
+	if (!IS_ALIGNED(start, PAGE_SIZE) ||
+	    check_add_overflow(start, (unsigned long)params->size, &end))
+		return -EINVAL;
+
+	if (!can_do_mlock())
+		return -EPERM;
+
+	if (params->size >> PAGE_SHIFT > INT_MAX)
+		return -E2BIG;
+
+	if (!access_ok((void __user *)start, params->size))
+		return -EFAULT;
+
+	userptr = kzalloc_obj(*userptr);
+	if (!userptr)
+		return -ENOMEM;
+
+	ret = virtio_gpu_userptr_init(vgdev->ddev, file, userptr, params,
+				      &virtio_gpu_userptr_ops);
+	if (ret) {
+		kfree(userptr);
+		return ret;
+	}
+
+	mm = current->mm;
+	mmgrab(mm);
+	lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
+	new_pinned = atomic64_add_return(userptr->npages, &mm->pinned_vm);
+	if (new_pinned < 0 ||
+	    (new_pinned > lock_limit && !capable(CAP_IPC_LOCK))) {
+		atomic64_sub(userptr->npages, &mm->pinned_vm);
+		mmdrop(mm);
+		ret = new_pinned < 0 ? -EOVERFLOW : -ENOMEM;
+		goto err_cleanup;
+	}
+	userptr->mm = mm;
+
+	mutex_lock(&userptr->lock);
+	ret = userptr->ops->get_pages(userptr);
+	mutex_unlock(&userptr->lock);
+	if (ret)
+		goto err_cleanup;
+
+	sgt = drm_prime_pages_to_sg(vgdev->ddev, userptr->pages,
+				    userptr->npages);
+	if (IS_ERR(sgt)) {
+		ret = PTR_ERR(sgt);
+		goto err_cleanup;
+	}
+
+	userptr->sgt = sgt;
+
+	/*
+	 * Match shmem blobs: only DMA-map when the virtio DMA API is in
+	 * use. Mapping unconditionally can create SWIOTLB bounce buffers
+	 * that get copied back over guest pages on unmap even though the
+	 * host was given sg_phys() addresses.
+	 */
+	if (virtio_gpu_use_dma_api(vgdev->vdev)) {
+		enum dma_data_direction dir =
+			(userptr->flags & VIRTGPU_BLOB_FLAG_USERPTR_RDONLY) ?
+			DMA_TO_DEVICE : DMA_BIDIRECTIONAL;
+
+		ret = dma_map_sgtable(drm_dev_dma_dev(vgdev->ddev), sgt,
+				      dir, 0);
+		if (ret)
+			goto err_cleanup;
+
+		userptr->dma_dir = dir;
+		userptr->dma_mapped = true;
+	}
+
+	ret = virtio_gpu_userptr_get_entries(vgdev, userptr, &ents, &nents);
+	if (ret)
+		goto err_cleanup;
+
+	virtio_gpu_cmd_resource_create_blob(vgdev, &userptr->base, params, ents,
+					    nents);
+
+	*bo_ptr = &userptr->base;
+	return 0;
+
+err_cleanup:
+	virtio_gpu_cleanup_object(&userptr->base);
+	return ret;
+}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v7 4/4] drm/virtio: wire blob ioctl creation to userptr objects
  2026-09-18  2:11 [PATCH v7 0/4] virtio-gpu: Add userptr support for compute workloads Honglei Huang
                   ` (2 preceding siblings ...)
  2026-09-18  2:11 ` [PATCH v7 3/4] drm/virtio: implement userptr support for zero-copy memory access Honglei Huang
@ 2026-09-18  2:11 ` Honglei Huang
  2026-09-18  2:23   ` sashiko-bot
  3 siblings, 1 reply; 9+ messages in thread
From: Honglei Huang @ 2026-09-18  2:11 UTC (permalink / raw)
  To: Dmitry Osipenko, Akihiko Odaki, David Airlie, Gerd Hoffmann
  Cc: Gurchetan Singh, Chia-I Wu, Ray Huang, dri-devel, virtualization,
	linux-kernel, Honglei Huang

Integrate userptr into the blob resource creation ioctl.

- Include VIRTGPU_BLOB_FLAG_USE_USERPTR and
  VIRTGPU_BLOB_FLAG_USERPTR_RDONLY in VIRTGPU_BLOB_FLAG_USE_MASK
- Require userptr if and only if USE_USERPTR is set
- Reject USERPTR unless blob_mem is VIRTGPU_BLOB_MEM_GUEST
- Pass the userspace address into the internal create params
- Call virtio_gpu_userptr_create() for userptr blob requests

Signed-off-by: Honglei Huang <honghuan@amd.com>
---
 drivers/gpu/drm/virtio/virtgpu_ioctl.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 3d8e4ccdb7..6d38483f5f 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -36,7 +36,9 @@
 
 #define VIRTGPU_BLOB_FLAG_USE_MASK (VIRTGPU_BLOB_FLAG_USE_MAPPABLE | \
 				    VIRTGPU_BLOB_FLAG_USE_SHAREABLE | \
-				    VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE)
+				    VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE | \
+				    VIRTGPU_BLOB_FLAG_USE_USERPTR | \
+				    VIRTGPU_BLOB_FLAG_USERPTR_RDONLY)
 
 /* Must be called with &virtio_gpu_fpriv.struct_mutex held. */
 static void virtio_gpu_create_context_locked(struct virtio_gpu_device *vgdev,
@@ -458,6 +460,17 @@ static int verify_blob(struct virtio_gpu_device *vgdev,
 			return -EINVAL;
 	}
 
+	if (rc_blob->blob_flags & VIRTGPU_BLOB_FLAG_USE_USERPTR) {
+		if (!rc_blob->userptr)
+			return -EINVAL;
+	} else {
+		if (rc_blob->userptr)
+			return -EINVAL;
+
+		if (rc_blob->blob_flags & VIRTGPU_BLOB_FLAG_USERPTR_RDONLY)
+			return -EINVAL;
+	}
+
 	switch (rc_blob->blob_mem) {
 	case VIRTGPU_BLOB_MEM_GUEST:
 		*guest_blob = true;
@@ -472,6 +485,11 @@ static int verify_blob(struct virtio_gpu_device *vgdev,
 		return -EINVAL;
 	}
 
+	/* Userptr is only defined for pure guest backing. */
+	if ((rc_blob->blob_flags & VIRTGPU_BLOB_FLAG_USE_USERPTR) &&
+	    rc_blob->blob_mem != VIRTGPU_BLOB_MEM_GUEST)
+		return -EINVAL;
+
 	if (*host3d_blob) {
 		if (!vgdev->has_virgl_3d)
 			return -EINVAL;
@@ -495,6 +513,7 @@ static int verify_blob(struct virtio_gpu_device *vgdev,
 	params->blob = true;
 	params->blob_flags = rc_blob->blob_flags;
 	params->blob_hints = rc_blob->blob_hints;
+	params->userptr = rc_blob->userptr;
 
 	if (vgdev->has_blob_alignment &&
 	    !IS_ALIGNED(params->size, vgdev->blob_alignment))
@@ -538,8 +557,10 @@ static int virtio_gpu_resource_create_blob_ioctl(struct drm_device *dev,
 				      vfpriv->ctx_id, NULL, NULL);
 	}
 
-	if (guest_blob)
+	if (guest_blob && !params.userptr)
 		ret = virtio_gpu_object_create(vgdev, &params, &bo, NULL);
+	else if (guest_blob && params.userptr)
+		ret = virtio_gpu_userptr_create(vgdev, file, &params, &bo);
 	else if (!guest_blob && host3d_blob)
 		ret = virtio_gpu_vram_create(vgdev, &params, &bo);
 	else
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v7 1/4] drm/virtio-gpu: Add VIRTIO_GPU_CAPSET_ROCM capability
  2026-09-18  2:11 ` [PATCH v7 1/4] drm/virtio-gpu: Add VIRTIO_GPU_CAPSET_ROCM capability Honglei Huang
@ 2026-09-18  2:16   ` sashiko-bot
  0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-09-18  2:16 UTC (permalink / raw)
  To: Honglei Huang
  Cc: virtualization, dri-devel, Michael S. Tsirkin, Eugenio Perez

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] virtio: speculative UAPI capability set ID assignment
--

commit 45781e0bfdae22c4f82ae57badc273b48904b478
Author: Honglei Huang <honghuan@amd.com>

drm/virtio-gpu: Add VIRTIO_GPU_CAPSET_ROCM capability

This commit adds a new GPU capability set VIRTIO_GPU_CAPSET_ROCM to support
ROCm compute workloads in virtualized environments using ID 8. The commit
message notes that a matching virtio-gpu specification change is currently
in progress.

> diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h
> index 4f530d90058c7..3d4dfadc9d789 100644
> --- a/include/uapi/linux/virtio_gpu.h
> +++ b/include/uapi/linux/virtio_gpu.h
> @@ -321,6 +321,7 @@ struct virtio_gpu_cmd_submit {
>  #define VIRTIO_GPU_CAPSET_VENUS 4
>  #define VIRTIO_GPU_CAPSET_CROSS_DOMAIN 5
>  #define VIRTIO_GPU_CAPSET_DRM 6
> +#define VIRTIO_GPU_CAPSET_ROCM 8

[Severity: Medium]
Is it safe to speculatively assign a UAPI capability set ID while the virtio
specification change is still in progress?

If the virtio technical committee assigns ID 8 to a different capability set
or assigns a different ID to ROCm, the Linux kernel UAPI will permanently
diverge from the official OASIS standard, which could break interoperability
with spec-compliant hypervisors.

Should this UAPI addition wait until the specification assignment is formally
accepted?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260918021154.1432154-1-honghuan@amd.com?part=1

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v7 2/4] drm/virtgpu api: add blob userptr resource
  2026-09-18  2:11 ` [PATCH v7 2/4] drm/virtgpu api: add blob userptr resource Honglei Huang
@ 2026-09-18  2:19   ` sashiko-bot
  0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-09-18  2:19 UTC (permalink / raw)
  To: Honglei Huang
  Cc: Eugenio Perez, virtualization, Michael S. Tsirkin, dri-devel

> Add DRM ioctl flags and a userptr address field so userspace can
> request a blob backed by an existing process mapping.
> 
> UAPI changes:
> - Add guest-only VIRTGPU_BLOB_FLAG_USE_USERPTR and
>   VIRTGPU_BLOB_FLAG_USERPTR_RDONLY flags
> - Add a userptr field to drm_virtgpu_resource_create_blob
> 
> These flags select guest pin behavior in the ioctl. They are not
> part of the virtio CREATE_BLOB wire ABI, so mask them out in
> virtio_gpu_cmd_resource_create_blob().
> 
> Signed-off-by: Honglei Huang <honghuan@amd.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260918021154.1432154-1-honghuan@amd.com?part=2


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v7 4/4] drm/virtio: wire blob ioctl creation to userptr objects
  2026-09-18  2:11 ` [PATCH v7 4/4] drm/virtio: wire blob ioctl creation to userptr objects Honglei Huang
@ 2026-09-18  2:23   ` sashiko-bot
  0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-09-18  2:23 UTC (permalink / raw)
  To: Honglei Huang
  Cc: dri-devel, Michael S. Tsirkin, virtualization, Eugenio Perez

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Critical] drm/virtio: PRIME export of RDONLY userptr allows writable DMA mapping
--

commit 5d368a790c7066062061e9164c64d6e00b653f96
Author: Honglei Huang <honghuan@amd.com>
Subject: drm/virtio: wire blob ioctl creation to userptr objects

This commit integrates userptr support into the virtio GPU blob resource
creation ioctl. It adds userptr flags to the allowed mask, handles userptr
verification, and calls virtio_gpu_userptr_create() when requested.

> diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
> index 3d8e4ccdb7c1f..6d38483f5fd61 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
> @@ -36,7 +36,9 @@
>  
>  #define VIRTGPU_BLOB_FLAG_USE_MASK (VIRTGPU_BLOB_FLAG_USE_MAPPABLE | \
>  				    VIRTGPU_BLOB_FLAG_USE_SHAREABLE | \
> -				    VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE)
> +				    VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE | \
> +				    VIRTGPU_BLOB_FLAG_USE_USERPTR | \
> +				    VIRTGPU_BLOB_FLAG_USERPTR_RDONLY)

[Severity: Critical]
By exposing VIRTGPU_BLOB_FLAG_USERPTR_RDONLY to userspace, does this allow an
unprivileged local user to bypass write protection on read-only pages via
PRIME export?

Looking at virtio_gpu_userptr_funcs in
drivers/gpu/drm/virtio/virtgpu_userptr.c, .export is exposed for userptr
objects:

drivers/gpu/drm/virtio/virtgpu_userptr.c:
static const struct drm_gem_object_funcs virtio_gpu_userptr_funcs = {
	.open = virtio_gpu_gem_object_open,
	.close = virtio_gpu_gem_object_close,
	.free = virtio_gpu_userptr_free,
	.export = virtgpu_gem_prime_export,
	.get_sg_table = virtio_gpu_userptr_get_sg_table,
};

And in virtio_gpu_userptr_get_pages() within the same file, it only pins with
FOLL_WRITE if read-only is not set:

drivers/gpu/drm/virtio/virtgpu_userptr.c:virtio_gpu_userptr_get_pages()
	if (!(userptr->flags & VIRTGPU_BLOB_FLAG_USERPTR_RDONLY))
		flag |= FOLL_WRITE;

If a user maps a read-only file into memory, creates a virtgpu blob resource
using VIRTGPU_BLOB_FLAG_USE_USERPTR and VIRTGPU_BLOB_FLAG_USERPTR_RDONLY, and
then exports it via DRM_IOCTL_PRIME_HANDLE_TO_FD while requesting DRM_RDWR,
does this allow the user to import this dma-buf into another device and
perform DMA writes to it?

This appears to circumvent the read-only pinning constraints when the resulting
sg_table is shared via PRIME and modified by an unaware importer, potentially
leading to arbitrary code execution or local privilege escalation.

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260918021154.1432154-1-honghuan@amd.com?part=4

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v7 3/4] drm/virtio: implement userptr support for zero-copy memory access
  2026-09-18  2:11 ` [PATCH v7 3/4] drm/virtio: implement userptr support for zero-copy memory access Honglei Huang
@ 2026-09-18  2:29   ` sashiko-bot
  0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-09-18  2:29 UTC (permalink / raw)
  To: Honglei Huang
  Cc: virtualization, Michael S. Tsirkin, dri-devel, Eugenio Perez

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Critical] mm: silent data loss due to missing dirty tracking on unpin
- [Critical] virtgpu: privilege escalation via read-write PRIME export of read-only userptrs
- [High] virtgpu: missing DMA sync for userptr objects causes stale reads
--

commit 419406d5baa93528ec030b7b95cc7d5ada190751
Author: Honglei Huang <honghuan@amd.com>

drm/virtio: implement userptr support for zero-copy memory access

This commit implements userptr support for virtio-gpu by adding a new
virtio_gpu_object_userptr type. It pins user pages via pin_user_pages_fast()
and maps them via the DMA API when required.

> diff --git a/drivers/gpu/drm/virtio/virtgpu_userptr.c b/drivers/gpu/drm/virtio/virtgpu_userptr.c
> new file mode 100644
> index 0000000000000..009755489774c
> --- /dev/null
> +++ b/drivers/gpu/drm/virtio/virtgpu_userptr.c
> @@ -0,0 +1,335 @@
[ ... ]
> +static const struct drm_gem_object_funcs virtio_gpu_userptr_funcs = {
> +	.open = virtio_gpu_gem_object_open,
> +	.close = virtio_gpu_gem_object_close,
> +	.free = virtio_gpu_userptr_free,
> +	.export = virtgpu_gem_prime_export,
> +	.get_sg_table = virtio_gpu_userptr_get_sg_table,
> +};

[Severity: Critical]
Is it safe to expose these objects to the PRIME export subsystem without
verifying their read-only status?

If a userptr object is created with VIRTGPU_BLOB_FLAG_USERPTR_RDONLY to pin
read-only memory, userspace could potentially export it via PRIME with
O_RDWR permissions and import it into another device that performs DMA writes.
Could this allow hardware to bypass CPU page table protections and overwrite
read-only system memory or files?

[ ... ]
> +static void
> +virtio_gpu_userptr_put_pages(struct virtio_gpu_object_userptr *userptr)
> +{
[ ... ]
> +	if (userptr->pages) {
> +		unpin_user_pages(userptr->pages, userptr->npages);
> +		kvfree(userptr->pages);
> +		userptr->pages = NULL;
> +	}

[Severity: Critical]
Are we missing dirty tracking when releasing these pages back to the OS?

If a userptr object is created without the read-only flag, pinned with
FOLL_WRITE, written to by the device, and then destroyed, we call
unpin_user_pages() here without explicitly marking the pages as dirty. If the
pages are file-backed or swapped, could the kernel memory management subsystem
silently discard the data written by the host or device?

[ ... ]
> +int virtio_gpu_userptr_create(struct virtio_gpu_device *vgdev,
> +			      struct drm_file *file,
> +			      struct virtio_gpu_object_params *params,
> +			      struct virtio_gpu_object **bo_ptr)
> +{
[ ... ]
> +	/*
> +	 * Match shmem blobs: only DMA-map when the virtio DMA API is in
> +	 * use. Mapping unconditionally can create SWIOTLB bounce buffers
> +	 * that get copied back over guest pages on unmap even though the
> +	 * host was given sg_phys() addresses.
> +	 */
> +	if (virtio_gpu_use_dma_api(vgdev->vdev)) {
> +		enum dma_data_direction dir =
> +			(userptr->flags & VIRTGPU_BLOB_FLAG_USERPTR_RDONLY) ?
> +			DMA_TO_DEVICE : DMA_BIDIRECTIONAL;
> +
> +		ret = dma_map_sgtable(drm_dev_dma_dev(vgdev->ddev), sgt,
> +				      dir, 0);

[Severity: High]
How does this DMA-mapped memory get synchronized to avoid stale reads?

When mapping with DMA_BIDIRECTIONAL and the guest modifies the userptr memory,
the host might read stale data from bounce buffers unless a DMA sync occurs. 
However, in virtio_gpu_cmd_transfer_to_host_3d() and 2d transfers, the sync
check looks like this:

	if (virtio_gpu_is_shmem(bo) && use_dma_api)
		dma_sync_sgtable_for_device(vgdev->vdev->dev.parent,
					    bo->base.sgt, DMA_TO_DEVICE);

Since virtio_gpu_is_shmem() evaluates to false for userptr objects, they
appear to be excluded from this synchronization. Will this skip cause the
host to read stale data during transfers?

> +		if (ret)
> +			goto err_cleanup;
> +
> +		userptr->dma_dir = dir;
> +		userptr->dma_mapped = true;
> +	}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260918021154.1432154-1-honghuan@amd.com?part=3

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-09-18  2:29 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-18  2:11 [PATCH v7 0/4] virtio-gpu: Add userptr support for compute workloads Honglei Huang
2026-09-18  2:11 ` [PATCH v7 1/4] drm/virtio-gpu: Add VIRTIO_GPU_CAPSET_ROCM capability Honglei Huang
2026-09-18  2:16   ` sashiko-bot
2026-09-18  2:11 ` [PATCH v7 2/4] drm/virtgpu api: add blob userptr resource Honglei Huang
2026-09-18  2:19   ` sashiko-bot
2026-09-18  2:11 ` [PATCH v7 3/4] drm/virtio: implement userptr support for zero-copy memory access Honglei Huang
2026-09-18  2:29   ` sashiko-bot
2026-09-18  2:11 ` [PATCH v7 4/4] drm/virtio: wire blob ioctl creation to userptr objects Honglei Huang
2026-09-18  2:23   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).