]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/virtio: Add a helper to map and note the dma addrs and lengths
authorVivek Kasireddy <vivek.kasireddy@intel.com>
Tue, 26 Nov 2024 03:13:43 +0000 (19:13 -0800)
committerDmitry Osipenko <dmitry.osipenko@collabora.com>
Tue, 26 Nov 2024 09:52:45 +0000 (12:52 +0300)
This helper would be used when first initializing the object as
part of import and also when updating the plane where we need to
ensure that the imported object's backing is valid.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Cc: Rob Clark <robdclark@gmail.com>
Cc: Gurchetan Singh <gurchetansingh@chromium.org>
Cc: Chia-I Wu <olvaffe@gmail.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241126031643.3490496-3-vivek.kasireddy@intel.com
drivers/gpu/drm/virtio/virtgpu_drv.h
drivers/gpu/drm/virtio/virtgpu_prime.c

index 77892fa01ef0859998f3f83421f5bbd0e1b3aa76..8328107edf780b8c89c6ab29377f34dd5924cf2e 100644 (file)
@@ -89,6 +89,7 @@ struct virtio_gpu_object_params {
 
 struct virtio_gpu_object {
        struct drm_gem_shmem_object base;
+       struct sg_table *sgt;
        uint32_t hw_res_handle;
        bool dumb;
        bool created;
@@ -477,6 +478,10 @@ struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev,
 struct drm_gem_object *virtgpu_gem_prime_import_sg_table(
        struct drm_device *dev, struct dma_buf_attachment *attach,
        struct sg_table *sgt);
+int virtgpu_dma_buf_import_sgt(struct virtio_gpu_mem_entry **ents,
+                              unsigned int *nents,
+                              struct virtio_gpu_object *bo,
+                              struct dma_buf_attachment *attach);
 
 /* virtgpu_debugfs.c */
 void virtio_gpu_debugfs_init(struct drm_minor *minor);
index 44425f20d91aa67999059f9f92b4a2f88e303d37..8e63aa67270af756549327e914881466fdb13f42 100644 (file)
@@ -27,6 +27,8 @@
 
 #include "virtgpu_drv.h"
 
+MODULE_IMPORT_NS(DMA_BUF);
+
 static int virtgpu_virtio_get_uuid(struct dma_buf *buf,
                                   uuid_t *uuid)
 {
@@ -142,6 +144,46 @@ struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj,
        return buf;
 }
 
+int virtgpu_dma_buf_import_sgt(struct virtio_gpu_mem_entry **ents,
+                              unsigned int *nents,
+                              struct virtio_gpu_object *bo,
+                              struct dma_buf_attachment *attach)
+{
+       struct scatterlist *sl;
+       struct sg_table *sgt;
+       long i, ret;
+
+       dma_resv_assert_held(attach->dmabuf->resv);
+
+       ret = dma_resv_wait_timeout(attach->dmabuf->resv,
+                                   DMA_RESV_USAGE_KERNEL,
+                                   false, MAX_SCHEDULE_TIMEOUT);
+       if (ret <= 0)
+               return ret < 0 ? ret : -ETIMEDOUT;
+
+       sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
+       if (IS_ERR(sgt))
+               return PTR_ERR(sgt);
+
+       *ents = kvmalloc_array(sgt->nents,
+                              sizeof(struct virtio_gpu_mem_entry),
+                              GFP_KERNEL);
+       if (!(*ents)) {
+               dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
+               return -ENOMEM;
+       }
+
+       *nents = sgt->nents;
+       for_each_sgtable_dma_sg(sgt, sl, i) {
+               (*ents)[i].addr = cpu_to_le64(sg_dma_address(sl));
+               (*ents)[i].length = cpu_to_le32(sg_dma_len(sl));
+               (*ents)[i].padding = 0;
+       }
+
+       bo->sgt = sgt;
+       return 0;
+}
+
 struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev,
                                                struct dma_buf *buf)
 {