From: alison.schofield@intel.com
To: Ben Widawsky <ben.widawsky@intel.com>,
Dan Williams <dan.j.williams@intel.com>,
Ira Weiny <ira.weiny@intel.com>,
Vishal Verma <vishal.l.verma@intel.com>
Cc: Alison Schofield <alison.schofield@intel.com>, linux-cxl@vger.kernel.org
Subject: [PATCH v2 1/4] cxl/mbox: Move cxl_mem_command construction to helper funcs
Date: Fri, 25 Feb 2022 12:30:58 -0800 [thread overview]
Message-ID: <84c0ddda79331bbbc37a6237e980b53735c29c77.1645817416.git.alison.schofield@intel.com> (raw)
In-Reply-To: <cover.1645817416.git.alison.schofield@intel.com>
From: Alison Schofield <alison.schofield@intel.com>
Sanitizing and constructing a cxl_mem_command from a userspace
command is part of the validation process prior to submitting
the command to a CXL device. Move this work to helper functions:
cxl_to_mem_cmd(), cxl_to_mem_cmd_raw().
This declutters cxl_validate_cmd_from_user() in preparation for
adding new validation steps.
Signed-off-by: Alison Schofield <alison.schofield@intel.com>
---
drivers/cxl/core/mbox.c | 143 ++++++++++++++++++++++------------------
1 file changed, 79 insertions(+), 64 deletions(-)
diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
index be61a0d8016b..06fbe6d079ba 100644
--- a/drivers/cxl/core/mbox.c
+++ b/drivers/cxl/core/mbox.c
@@ -207,6 +207,75 @@ static bool cxl_mem_raw_command_allowed(u16 opcode)
return true;
}
+static int cxl_to_mem_cmd_raw(struct cxl_dev_state *cxlds,
+ const struct cxl_send_command *send_cmd,
+ struct cxl_mem_command *mem_cmd)
+{
+ if (send_cmd->raw.rsvd)
+ return -EINVAL;
+ /*
+ * Unlike supported commands, the output size of RAW commands
+ * gets passed along without further checking, so it must be
+ * validated here.
+ */
+ if (send_cmd->out.size > cxlds->payload_size)
+ return -EINVAL;
+
+ if (!cxl_mem_raw_command_allowed(send_cmd->raw.opcode))
+ return -EPERM;
+
+ dev_WARN_ONCE(cxlds->dev, true, "raw command path used\n");
+
+ mem_cmd->info.id = CXL_MEM_COMMAND_ID_RAW;
+ mem_cmd->info.flags = 0;
+ mem_cmd->info.size_in = send_cmd->in.size;
+ mem_cmd->info.size_out = send_cmd->out.size;
+ mem_cmd->opcode = send_cmd->raw.opcode;
+
+ return 0;
+}
+
+static int cxl_to_mem_cmd(struct cxl_dev_state *cxlds,
+ const struct cxl_send_command *send_cmd,
+ struct cxl_mem_command *mem_cmd)
+{
+ const struct cxl_command_info *info;
+ struct cxl_mem_command *c;
+
+ if (send_cmd->flags & ~CXL_MEM_COMMAND_FLAG_MASK)
+ return -EINVAL;
+
+ if (send_cmd->rsvd)
+ return -EINVAL;
+
+ if (send_cmd->in.rsvd || send_cmd->out.rsvd)
+ return -EINVAL;
+
+ /* Convert user's command into the internal representation */
+ c = &cxl_mem_commands[send_cmd->id];
+ info = &c->info;
+
+ /* Check that the command is enabled for hardware */
+ if (!test_bit(info->id, cxlds->enabled_cmds))
+ return -ENOTTY;
+
+ /* Check that the command is not claimed for exclusive kernel use */
+ if (test_bit(info->id, cxlds->exclusive_cmds))
+ return -EBUSY;
+
+ /* Check the input buffer is the expected size */
+ if (info->size_in >= 0 && info->size_in != send_cmd->in.size)
+ return -ENOMEM;
+
+ /* Check the output buffer is at least large enough */
+ if (info->size_out >= 0 && send_cmd->out.size < info->size_out)
+ return -ENOMEM;
+
+ memcpy(mem_cmd, c, sizeof(*c));
+ mem_cmd->info.size_in = send_cmd->in.size;
+ return 0;
+}
+
/**
* cxl_validate_cmd_from_user() - Check fields for CXL_MEM_SEND_COMMAND.
* @cxlds: The device data for the operation
@@ -230,8 +299,8 @@ static int cxl_validate_cmd_from_user(struct cxl_dev_state *cxlds,
const struct cxl_send_command *send_cmd,
struct cxl_mem_command *out_cmd)
{
- const struct cxl_command_info *info;
- struct cxl_mem_command *c;
+ struct cxl_mem_command mem_cmd;
+ int rc;
if (send_cmd->id == 0 || send_cmd->id >= CXL_MEM_COMMAND_ID_MAX)
return -ENOTTY;
@@ -244,70 +313,16 @@ static int cxl_validate_cmd_from_user(struct cxl_dev_state *cxlds,
if (send_cmd->in.size > cxlds->payload_size)
return -EINVAL;
- /*
- * Checks are bypassed for raw commands but a WARN/taint will occur
- * later in the callchain
- */
- if (send_cmd->id == CXL_MEM_COMMAND_ID_RAW) {
- const struct cxl_mem_command temp = {
- .info = {
- .id = CXL_MEM_COMMAND_ID_RAW,
- .flags = 0,
- .size_in = send_cmd->in.size,
- .size_out = send_cmd->out.size,
- },
- .opcode = send_cmd->raw.opcode
- };
+ /* Sanitize and construct a cxl_mem_command */
+ if (send_cmd->id == CXL_MEM_COMMAND_ID_RAW)
+ rc = cxl_to_mem_cmd_raw(cxlds, send_cmd, &mem_cmd);
+ else
+ rc = cxl_to_mem_cmd(cxlds, send_cmd, &mem_cmd);
- if (send_cmd->raw.rsvd)
- return -EINVAL;
+ if (rc)
+ return rc;
- /*
- * Unlike supported commands, the output size of RAW commands
- * gets passed along without further checking, so it must be
- * validated here.
- */
- if (send_cmd->out.size > cxlds->payload_size)
- return -EINVAL;
-
- if (!cxl_mem_raw_command_allowed(send_cmd->raw.opcode))
- return -EPERM;
-
- memcpy(out_cmd, &temp, sizeof(temp));
-
- return 0;
- }
-
- if (send_cmd->flags & ~CXL_MEM_COMMAND_FLAG_MASK)
- return -EINVAL;
-
- if (send_cmd->rsvd)
- return -EINVAL;
-
- if (send_cmd->in.rsvd || send_cmd->out.rsvd)
- return -EINVAL;
-
- /* Convert user's command into the internal representation */
- c = &cxl_mem_commands[send_cmd->id];
- info = &c->info;
-
- /* Check that the command is enabled for hardware */
- if (!test_bit(info->id, cxlds->enabled_cmds))
- return -ENOTTY;
-
- /* Check that the command is not claimed for exclusive kernel use */
- if (test_bit(info->id, cxlds->exclusive_cmds))
- return -EBUSY;
-
- /* Check the input buffer is the expected size */
- if (info->size_in >= 0 && info->size_in != send_cmd->in.size)
- return -ENOMEM;
-
- /* Check the output buffer is at least large enough */
- if (info->size_out >= 0 && send_cmd->out.size < info->size_out)
- return -ENOMEM;
-
- memcpy(out_cmd, c, sizeof(*c));
+ memcpy(out_cmd, &mem_cmd, sizeof(mem_cmd));
out_cmd->info.size_in = send_cmd->in.size;
/*
* XXX: out_cmd->info.size_out will be controlled by the driver, and the
--
2.31.1
next prev parent reply other threads:[~2022-02-25 20:27 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-25 20:30 [PATCH v2 0/4] Do not allow set-partition immediate mode alison.schofield
2022-02-25 20:30 ` alison.schofield [this message]
2022-02-25 21:31 ` [PATCH v2 1/4] cxl/mbox: Move cxl_mem_command construction to helper funcs Dan Williams
2022-02-25 20:30 ` [PATCH v2 2/4] cxl/mbox: Centralize the validation of user commands alison.schofield
2022-02-25 20:31 ` [PATCH v2 3/4] cxl/mbox: Block immediate mode in SET_PARTITION_INFO command alison.schofield
2022-02-25 20:31 ` [PATCH v2 4/4] cxl/pmem: Remove CXL SET_PARTITION_INFO from exclusive_cmds list alison.schofield
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=84c0ddda79331bbbc37a6237e980b53735c29c77.1645817416.git.alison.schofield@intel.com \
--to=alison.schofield@intel.com \
--cc=ben.widawsky@intel.com \
--cc=dan.j.williams@intel.com \
--cc=ira.weiny@intel.com \
--cc=linux-cxl@vger.kernel.org \
--cc=vishal.l.verma@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox