From: Ekansh Gupta ekansh.gupta@oss.qualcomm.com
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 ekansh.gupta@oss.qualcomm.com --- 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