From: Ekansh Gupta <[email protected]>

Implement DRM_IOCTL_QDA_REMOTE_MUNMAP (command 0x06), which unmaps
a previously mapped memory region from the DSP's virtual address space.
Two unmap modes mirror the two map modes:

QDA_MUNMAP_REQUEST_LEGACY (FASTRPC_RMID_INIT_MUNMAP)
  Legacy single-argument unmap: sends a fastrpc_munmap_req_msg
  containing the session ID, the DSP virtual address (vaddrout from
  the original map response), and the region size.

QDA_MUNMAP_REQUEST_ATTR (FASTRPC_RMID_INIT_MEM_UNMAP)
  Attribute-based unmap: sends a fastrpc_mem_unmap_req_msg which
  additionally carries the original DMA-BUF fd and virtual address,
  matching the fd-based MEM_MAP path.

DRM_QDA_REMOTE_MUNMAP is assigned command number 0x06, filling the
slot that was previously reserved for this purpose.

Assisted-by: Claude:claude-4-6-sonnet
Signed-off-by: Ekansh Gupta <[email protected]>
---
 drivers/accel/qda/qda_drv.c     |  1 +
 drivers/accel/qda/qda_fastrpc.c | 84 +++++++++++++++++++++++++++++++++++++++++
 drivers/accel/qda/qda_fastrpc.h | 34 +++++++++++++++++
 drivers/accel/qda/qda_ioctl.c   | 28 ++++++++++++++
 drivers/accel/qda/qda_ioctl.h   |  1 +
 include/uapi/drm/qda_accel.h    | 36 +++++++++++++++++-
 6 files changed, 183 insertions(+), 1 deletion(-)

diff --git a/drivers/accel/qda/qda_drv.c b/drivers/accel/qda/qda_drv.c
index 3640e4a41605..41cc207447b4 100644
--- a/drivers/accel/qda/qda_drv.c
+++ b/drivers/accel/qda/qda_drv.c
@@ -68,6 +68,7 @@ static const struct drm_ioctl_desc qda_ioctls[] = {
        DRM_IOCTL_DEF_DRV(QDA_GEM_MMAP_OFFSET, qda_ioctl_gem_mmap_offset, 0),
        DRM_IOCTL_DEF_DRV(QDA_REMOTE_SESSION_CREATE, qda_ioctl_init_create, 0),
        DRM_IOCTL_DEF_DRV(QDA_REMOTE_MAP, qda_ioctl_mmap, 0),
+       DRM_IOCTL_DEF_DRV(QDA_REMOTE_MUNMAP, qda_ioctl_munmap, 0),
        DRM_IOCTL_DEF_DRV(QDA_REMOTE_INVOKE, qda_ioctl_invoke, 0),
 };
 
diff --git a/drivers/accel/qda/qda_fastrpc.c b/drivers/accel/qda/qda_fastrpc.c
index cab3a560ceb5..0513beede428 100644
--- a/drivers/accel/qda/qda_fastrpc.c
+++ b/drivers/accel/qda/qda_fastrpc.c
@@ -887,6 +887,84 @@ static int fastrpc_prepare_args_mem_map_attr(struct 
fastrpc_invoke_context *ctx,
        return err;
 }
 
+static int fastrpc_prepare_args_munmap(struct fastrpc_invoke_context *ctx, 
char __user *argp)
+{
+       struct drm_qda_fastrpc_invoke_args *args;
+       struct fastrpc_munmap_req_msg *req_msg;
+       struct drm_qda_mem_unmap uargs;
+       void *req;
+       int err;
+
+       memcpy(&uargs, argp, sizeof(uargs));
+
+       args = kzalloc_obj(*args);
+       if (!args)
+               return -ENOMEM;
+
+       req = kzalloc_obj(*req_msg);
+       if (!req) {
+               err = -ENOMEM;
+               goto err_free_args;
+       }
+       req_msg = (struct fastrpc_munmap_req_msg *)req;
+
+       req_msg->remote_session_id = ctx->remote_session_id;
+       req_msg->size  = uargs.size;
+       req_msg->vaddr = uargs.vaddrout;
+
+       setup_single_arg(args, req_msg, sizeof(*req_msg));
+       ctx->sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MUNMAP, 1, 0);
+       ctx->args = args;
+       ctx->req = req;
+       ctx->handle = FASTRPC_INIT_HANDLE;
+
+       return 0;
+
+err_free_args:
+       kfree(args);
+       return err;
+}
+
+static int fastrpc_prepare_args_mem_unmap_attr(struct fastrpc_invoke_context 
*ctx,
+                                              char __user *argp)
+{
+       struct drm_qda_fastrpc_invoke_args *args;
+       struct fastrpc_mem_unmap_req_msg *req_msg;
+       struct drm_qda_mem_unmap uargs;
+       void *req;
+       int err;
+
+       memcpy(&uargs, argp, sizeof(uargs));
+
+       args = kzalloc_obj(*args);
+       if (!args)
+               return -ENOMEM;
+
+       req = kzalloc_obj(*req_msg);
+       if (!req) {
+               err = -ENOMEM;
+               goto err_free_args;
+       }
+       req_msg = (struct fastrpc_mem_unmap_req_msg *)req;
+
+       req_msg->remote_session_id = ctx->remote_session_id;
+       req_msg->fd      = uargs.fd;            /* DMA-BUF fd forwarded to DSP 
*/
+       req_msg->vaddrin = uargs.vaddr;
+       req_msg->len     = uargs.size;
+
+       setup_single_arg(args, req_msg, sizeof(*req_msg));
+       ctx->sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MEM_UNMAP, 1, 0);
+       ctx->args = args;
+       ctx->req = req;
+       ctx->handle = FASTRPC_INIT_HANDLE;
+
+       return 0;
+
+err_free_args:
+       kfree(args);
+       return err;
+}
+
 static int fastrpc_prepare_args_invoke(struct fastrpc_invoke_context *ctx, 
char __user *argp)
 {
        struct drm_qda_invoke_args invoke_args;
@@ -945,6 +1023,12 @@ int qda_fastrpc_prepare_args(struct 
fastrpc_invoke_context *ctx, char __user *ar
        case FASTRPC_RMID_INIT_MEM_MAP:
                err = fastrpc_prepare_args_mem_map_attr(ctx, argp);
                break;
+       case FASTRPC_RMID_INIT_MUNMAP:
+               err = fastrpc_prepare_args_munmap(ctx, argp);
+               break;
+       case FASTRPC_RMID_INIT_MEM_UNMAP:
+               err = fastrpc_prepare_args_mem_unmap_attr(ctx, argp);
+               break;
        case FASTRPC_RMID_INVOKE_DYNAMIC:
                err = fastrpc_prepare_args_invoke(ctx, argp);
                break;
diff --git a/drivers/accel/qda/qda_fastrpc.h b/drivers/accel/qda/qda_fastrpc.h
index 71812eaf9a54..030e9b954f7a 100644
--- a/drivers/accel/qda/qda_fastrpc.h
+++ b/drivers/accel/qda/qda_fastrpc.h
@@ -275,9 +275,11 @@ struct fastrpc_invoke_context {
 /* Remote Method ID table - identifies initialization and control operations */
 #define FASTRPC_RMID_INIT_RELEASE      1       /* Release DSP process */
 #define FASTRPC_RMID_INIT_MMAP         4       /* Map memory region to DSP */
+#define FASTRPC_RMID_INIT_MUNMAP       5       /* Unmap DSP memory region */
 #define FASTRPC_RMID_INIT_CREATE       6       /* Create DSP process */
 #define FASTRPC_RMID_INIT_CREATE_ATTR  7       /* Create DSP process with 
attributes */
 #define FASTRPC_RMID_INIT_MEM_MAP      10      /* Map DMA buffer with 
attributes to DSP */
+#define FASTRPC_RMID_INIT_MEM_UNMAP    11      /* Unmap DMA buffer from DSP */
 #define FASTRPC_RMID_INVOKE_DYNAMIC    0xFFFFFFFF      /* Dynamic method 
invocation */
 
 /* Common handle for initialization operations */
@@ -345,6 +347,38 @@ struct fastrpc_map_rsp_msg {
        u64 vaddrout;
 };
 
+/**
+ * struct fastrpc_mem_unmap_req_msg - Memory unmap request message with 
attributes
+ *
+ * This message structure is sent to the DSP to request unmapping
+ * of a previously mapped memory region (ATTR request).
+ */
+struct fastrpc_mem_unmap_req_msg {
+       /** @remote_session_id: Client identifier for the session */
+       s32 remote_session_id;
+       /** @fd: DMA-BUF file descriptor of the buffer to unmap */
+       s32 fd;
+       /** @vaddrin: DSP virtual address of the mapped region to unmap */
+       u64 vaddrin;
+       /** @len: Size of the region to unmap in bytes */
+       u64 len;
+};
+
+/**
+ * struct fastrpc_munmap_req_msg - Legacy memory unmap request message
+ *
+ * This message structure is sent to the DSP to request unmapping
+ * of a previously mapped memory region.
+ */
+struct fastrpc_munmap_req_msg {
+       /** @remote_session_id: Client identifier for the session */
+       s32 remote_session_id;
+       /** @vaddr: DSP virtual address of the mapped region to unmap */
+       u64 vaddr;
+       /** @size: Size of the region to unmap in bytes */
+       u64 size;
+};
+
 void qda_fastrpc_context_free(struct kref *ref);
 struct fastrpc_invoke_context *qda_fastrpc_context_alloc(void);
 int qda_fastrpc_prepare_args(struct fastrpc_invoke_context *ctx, char __user 
*argp);
diff --git a/drivers/accel/qda/qda_ioctl.c b/drivers/accel/qda/qda_ioctl.c
index 283eb7535c45..aeba6190182e 100644
--- a/drivers/accel/qda/qda_ioctl.c
+++ b/drivers/accel/qda/qda_ioctl.c
@@ -254,6 +254,34 @@ int qda_ioctl_mmap(struct drm_device *dev, void *data, 
struct drm_file *file_pri
        }
 }
 
+/**
+ * qda_ioctl_munmap() - Unmap memory from DSP address space
+ * @dev: DRM device structure
+ * @data: User-space data (struct drm_qda_mem_unmap)
+ * @file_priv: DRM file private data
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int qda_ioctl_munmap(struct drm_device *dev, void *data, struct drm_file 
*file_priv)
+{
+       struct drm_qda_mem_unmap *unmap_req;
+
+       if (!data)
+               return -EINVAL;
+
+       unmap_req = (struct drm_qda_mem_unmap *)data;
+
+       switch (unmap_req->request) {
+       case QDA_MUNMAP_REQUEST_LEGACY:
+               return fastrpc_invoke(FASTRPC_RMID_INIT_MUNMAP, dev, data, 
file_priv);
+       case QDA_MUNMAP_REQUEST_ATTR:
+               return fastrpc_invoke(FASTRPC_RMID_INIT_MEM_UNMAP, dev, data, 
file_priv);
+       default:
+               drm_err(dev, "Invalid munmap request type: %u\n", 
unmap_req->request);
+               return -EINVAL;
+       }
+}
+
 /**
  * qda_ioctl_invoke() - Perform a dynamic FastRPC method invocation
  * @dev: DRM device structure
diff --git a/drivers/accel/qda/qda_ioctl.h b/drivers/accel/qda/qda_ioctl.h
index 457ceccede08..e14a39050d09 100644
--- a/drivers/accel/qda/qda_ioctl.h
+++ b/drivers/accel/qda/qda_ioctl.h
@@ -14,5 +14,6 @@ int qda_ioctl_gem_create(struct drm_device *dev, void *data, 
struct drm_file *fi
 int qda_ioctl_gem_mmap_offset(struct drm_device *dev, void *data, struct 
drm_file *file_priv);
 int qda_ioctl_invoke(struct drm_device *dev, void *data, struct drm_file 
*file_priv);
 int qda_ioctl_mmap(struct drm_device *dev, void *data, struct drm_file 
*file_priv);
+int qda_ioctl_munmap(struct drm_device *dev, void *data, struct drm_file 
*file_priv);
 
 #endif /* __QDA_IOCTL_H__ */
diff --git a/include/uapi/drm/qda_accel.h b/include/uapi/drm/qda_accel.h
index 173f59abd361..e3b5c9a963bf 100644
--- a/include/uapi/drm/qda_accel.h
+++ b/include/uapi/drm/qda_accel.h
@@ -21,9 +21,10 @@ extern "C" {
 #define DRM_QDA_QUERY          0x00
 #define DRM_QDA_GEM_CREATE             0x01
 #define DRM_QDA_GEM_MMAP_OFFSET        0x02
-/* Command number 0x03 reserved for INIT_ATTACH; 0x06 reserved for MUNMAP */
+/* Command number 0x03 reserved for INIT_ATTACH */
 #define DRM_QDA_REMOTE_SESSION_CREATE          0x04
 #define DRM_QDA_REMOTE_MAP                     0x05
+#define DRM_QDA_REMOTE_MUNMAP                  0x06
 #define DRM_QDA_REMOTE_INVOKE                  0x07
 
 /*
@@ -44,6 +45,8 @@ extern "C" {
                 struct drm_qda_init_create)
 #define DRM_IOCTL_QDA_REMOTE_MAP       DRM_IOWR(DRM_COMMAND_BASE + 
DRM_QDA_REMOTE_MAP, \
                                          struct drm_qda_mem_map)
+#define DRM_IOCTL_QDA_REMOTE_MUNMAP    DRM_IOWR(DRM_COMMAND_BASE + 
DRM_QDA_REMOTE_MUNMAP, \
+                                         struct drm_qda_mem_unmap)
 #define DRM_IOCTL_QDA_REMOTE_INVOKE    DRM_IOWR(DRM_COMMAND_BASE + 
DRM_QDA_REMOTE_INVOKE, \
                                          struct drm_qda_invoke_args)
 
@@ -51,6 +54,10 @@ extern "C" {
 #define QDA_MAP_REQUEST_LEGACY    1  /* Legacy MMAP operation */
 #define QDA_MAP_REQUEST_ATTR      2  /* Handle-based MEM_MAP operation with 
attributes */
 
+/* Request type definitions for qda_mem_unmap */
+#define QDA_MUNMAP_REQUEST_LEGACY    1  /* Legacy MUNMAP operation */
+#define QDA_MUNMAP_REQUEST_ATTR      2  /* Handle-based MEM_UNMAP operation */
+
 /**
  * struct drm_qda_query - Device information query structure
  * @dsp_name: Name of DSP (e.g., "adsp", "cdsp", "cdsp1", "gdsp0", "gdsp1")
@@ -188,6 +195,33 @@ struct drm_qda_mem_map {
        __u64 vaddrout;
 };
 
+/**
+ * struct drm_qda_mem_unmap - Memory unmapping request structure
+ * @request: Request type (QDA_MUNMAP_REQUEST_LEGACY or 
QDA_MUNMAP_REQUEST_ATTR)
+ * @fd: DMA-BUF file descriptor (used for ATTR request)
+ * @vaddr: Virtual address (used for ATTR request)
+ * @vaddrout: DSP virtual address (used for LEGACY request)
+ * @size: Size of the memory region to unmap in bytes
+ *
+ * This structure is used to request unmapping of a previously mapped
+ * memory region from the DSP's virtual address space.
+ *
+ * For QDA_MUNMAP_REQUEST_LEGACY (value 1):
+ *   - Uses fields: vaddrout, size
+ *   - Legacy MUNMAP operation for backward compatibility
+ *
+ * For QDA_MUNMAP_REQUEST_ATTR (value 2):
+ *   - Uses fields: fd, vaddr, size
+ *   - Handle-based MEM_UNMAP operation
+ */
+struct drm_qda_mem_unmap {
+       __u32 request;
+       __s32 fd;
+       __u64 vaddr;
+       __u64 vaddrout;
+       __u64 size;
+};
+
 #if defined(__cplusplus)
 }
 #endif

-- 
2.34.1


Reply via email to