[PATCH] nvme/ioctl: combine nvme_user_cmd and nvme_user_cmd64
Tokunori Ikegami
ikegami.t at gmail.com
Wed Mar 4 08:40:22 PST 2026
The functions almost duplicated but only changed result value size.
So combine the functions by adding a "bool is64bit" parameter.
Signed-off-by: Tokunori Ikegami <ikegami.t at gmail.com>
---
drivers/nvme/host/ioctl.c | 83 +++++++++++----------------------------
1 file changed, 23 insertions(+), 60 deletions(-)
diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
index 8844bbd39515..44340f5167f1 100644
--- a/drivers/nvme/host/ioctl.c
+++ b/drivers/nvme/host/ioctl.c
@@ -280,8 +280,10 @@ static bool nvme_validate_passthru_nsid(struct nvme_ctrl *ctrl,
static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
struct nvme_passthru_cmd __user *ucmd, unsigned int flags,
- bool open_for_write)
+ bool open_for_write, bool is64bit)
{
+ struct nvme_passthru_cmd64 __user *ucmd64 = (void __user *)ucmd;
+ unsigned int flags64 = is64bit ? flags : 0;
struct nvme_passthru_cmd cmd;
struct nvme_command c;
unsigned timeout = 0;
@@ -308,54 +310,7 @@ static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
c.common.cdw14 = cpu_to_le32(cmd.cdw14);
c.common.cdw15 = cpu_to_le32(cmd.cdw15);
- if (!nvme_cmd_allowed(ns, &c, 0, open_for_write))
- return -EACCES;
-
- if (cmd.timeout_ms)
- timeout = msecs_to_jiffies(cmd.timeout_ms);
-
- status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c,
- cmd.addr, cmd.data_len, nvme_to_user_ptr(cmd.metadata),
- cmd.metadata_len, &result, timeout, 0);
-
- if (status >= 0) {
- if (put_user(result, &ucmd->result))
- return -EFAULT;
- }
-
- return status;
-}
-
-static int nvme_user_cmd64(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
- struct nvme_passthru_cmd64 __user *ucmd, unsigned int flags,
- bool open_for_write)
-{
- struct nvme_passthru_cmd64 cmd;
- struct nvme_command c;
- unsigned timeout = 0;
- int status;
-
- 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;
-
- memset(&c, 0, sizeof(c));
- c.common.opcode = cmd.opcode;
- c.common.flags = cmd.flags;
- c.common.nsid = cpu_to_le32(cmd.nsid);
- c.common.cdw2[0] = cpu_to_le32(cmd.cdw2);
- c.common.cdw2[1] = cpu_to_le32(cmd.cdw3);
- c.common.cdw10 = cpu_to_le32(cmd.cdw10);
- c.common.cdw11 = cpu_to_le32(cmd.cdw11);
- c.common.cdw12 = cpu_to_le32(cmd.cdw12);
- c.common.cdw13 = cpu_to_le32(cmd.cdw13);
- c.common.cdw14 = cpu_to_le32(cmd.cdw14);
- c.common.cdw15 = cpu_to_le32(cmd.cdw15);
-
- if (!nvme_cmd_allowed(ns, &c, flags, open_for_write))
+ if (!nvme_cmd_allowed(ns, &c, flags64, open_for_write))
return -EACCES;
if (cmd.timeout_ms)
@@ -363,11 +318,16 @@ static int nvme_user_cmd64(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c,
cmd.addr, cmd.data_len, nvme_to_user_ptr(cmd.metadata),
- cmd.metadata_len, &cmd.result, timeout, flags);
+ cmd.metadata_len, &result, timeout, flags64);
if (status >= 0) {
- if (put_user(cmd.result, &ucmd->result))
- return -EFAULT;
+ if (is64bit) {
+ if (put_user(result, &ucmd64->result))
+ return -EFAULT;
+ } else {
+ if (put_user(result, &ucmd->result))
+ return -EFAULT;
+ }
}
return status;
@@ -552,9 +512,10 @@ static int nvme_ctrl_ioctl(struct nvme_ctrl *ctrl, unsigned int cmd,
{
switch (cmd) {
case NVME_IOCTL_ADMIN_CMD:
- return nvme_user_cmd(ctrl, NULL, argp, 0, open_for_write);
+ return nvme_user_cmd(ctrl, NULL, argp, 0, open_for_write,
+ false);
case NVME_IOCTL_ADMIN64_CMD:
- return nvme_user_cmd64(ctrl, NULL, argp, 0, open_for_write);
+ return nvme_user_cmd(ctrl, NULL, argp, 0, open_for_write, true);
default:
return sed_ioctl(ctrl->opal_dev, cmd, argp);
}
@@ -586,7 +547,8 @@ static int nvme_ns_ioctl(struct nvme_ns *ns, unsigned int cmd,
force_successful_syscall_return();
return ns->head->ns_id;
case NVME_IOCTL_IO_CMD:
- return nvme_user_cmd(ns->ctrl, ns, argp, flags, open_for_write);
+ return nvme_user_cmd(ns->ctrl, ns, argp, flags, open_for_write,
+ false);
/*
* struct nvme_user_io can have different padding on some 32-bit ABIs.
* Just accept the compat version as all fields that are used are the
@@ -601,8 +563,8 @@ static int nvme_ns_ioctl(struct nvme_ns *ns, unsigned int cmd,
flags |= NVME_IOCTL_VEC;
fallthrough;
case NVME_IOCTL_IO64_CMD:
- return nvme_user_cmd64(ns->ctrl, ns, argp, flags,
- open_for_write);
+ return nvme_user_cmd(ns->ctrl, ns, argp, flags, open_for_write,
+ true);
default:
return -ENOTTY;
}
@@ -836,7 +798,7 @@ static int nvme_dev_user_cmd(struct nvme_ctrl *ctrl, void __user *argp,
}
srcu_read_unlock(&ctrl->srcu, srcu_idx);
- ret = nvme_user_cmd(ctrl, ns, argp, 0, open_for_write);
+ ret = nvme_user_cmd(ctrl, ns, argp, 0, open_for_write, false);
nvme_put_ns(ns);
return ret;
@@ -854,9 +816,10 @@ long nvme_dev_ioctl(struct file *file, unsigned int cmd,
switch (cmd) {
case NVME_IOCTL_ADMIN_CMD:
- return nvme_user_cmd(ctrl, NULL, argp, 0, open_for_write);
+ return nvme_user_cmd(ctrl, NULL, argp, 0, open_for_write,
+ false);
case NVME_IOCTL_ADMIN64_CMD:
- return nvme_user_cmd64(ctrl, NULL, argp, 0, open_for_write);
+ return nvme_user_cmd(ctrl, NULL, argp, 0, open_for_write, true);
case NVME_IOCTL_IO_CMD:
return nvme_dev_user_cmd(ctrl, argp, open_for_write);
case NVME_IOCTL_RESET:
--
2.51.0
More information about the Linux-nvme
mailing list