wire up support for passthru that takes an array of buffers (using iovec). Enable it for NVME_IOCTL_IO64_CMD; same ioctl code to be used with following differences - 1. NVME_IOVEC to be set as cmd.flags 2. cmd.addr, base addr of user iovec array 3. cmd.data_len, count of iovec array elements Signed-off-by: Kanchan Joshi <joshi.k@xxxxxxxxxxx> --- drivers/nvme/host/ioctl.c | 9 ++++++--- include/uapi/linux/nvme_ioctl.h | 4 ++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c index 22314962842d..3a896443e110 100644 --- a/drivers/nvme/host/ioctl.c +++ b/drivers/nvme/host/ioctl.c @@ -65,6 +65,7 @@ static int nvme_submit_user_cmd(struct request_queue *q, struct bio *bio = NULL; void *meta = NULL; int ret; + u8 cmd_flags = cmd->common.flags; req = nvme_alloc_request(q, cmd, 0); if (IS_ERR(req)) @@ -75,7 +76,11 @@ static int nvme_submit_user_cmd(struct request_queue *q, nvme_req(req)->flags |= NVME_REQ_USERCMD; if (ubuffer && bufflen) { - ret = blk_rq_map_user(q, req, NULL, ubuffer, bufflen, + if (!(cmd_flags & NVME_IOVEC)) + ret = blk_rq_map_user(q, req, NULL, ubuffer, bufflen, + GFP_KERNEL); + else + ret = blk_rq_map_user_vec(q, req, NULL, ubuffer, bufflen, GFP_KERNEL); if (ret) goto out; @@ -246,8 +251,6 @@ static int nvme_user_cmd64(struct nvme_ctrl *ctrl, struct nvme_ns *ns, return -EACCES; if (copy_from_user(&cmd, ucmd, sizeof(cmd))) return -EFAULT; - if (cmd.flags) - return -EINVAL; if (!nvme_validate_passthru_nsid(ctrl, ns, cmd.nsid)) return -EINVAL; diff --git a/include/uapi/linux/nvme_ioctl.h b/include/uapi/linux/nvme_ioctl.h index d99b5a772698..d4999e3930f8 100644 --- a/include/uapi/linux/nvme_ioctl.h +++ b/include/uapi/linux/nvme_ioctl.h @@ -9,6 +9,10 @@ #include <linux/types.h> +enum nvme_ioc_flags { + NVME_IOVEC = 1 << 0 /* vectored io */ +}; + struct nvme_user_io { __u8 opcode; __u8 flags; -- 2.25.1