Skip to content

Commit 2aeaf66

Browse files
committed
cxl/mbox: Add variable output size validation for internal commands
cxl_internal_send_cmd() skips output size validation for variable output commands which is not ideal. Most of the time internal usages want to fail if the output size does not match what was requested. For other commands where the caller cannot predict the size there is usually a a header that conveys how much vaild data is in the payload. For those cases add @min_out as a parameter to specify what the minimum response payload needs to be for the caller to parse the rest of the payload. In this patch only Get Supported Logs has that behavior, but going forward records retrieval commands like Get Poison List and Get Event Records can use @min_out to retrieve a variable amount of records. Critically, this validation scheme skips the needs to interrogate the cxl_mem_commands array which in turn frees up the implementation to support internal command enabling without also enabling external / user commands. Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Ira Weiny <ira.weiny@intel.com> Link: https://lore.kernel.org/r/167030055918.4044561.10339573829837910505.stgit@dwillia2-xfh.jf.intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent 5331cdf commit 2aeaf66

2 files changed

Lines changed: 16 additions & 9 deletions

File tree

drivers/cxl/core/mbox.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -166,31 +166,34 @@ static const char *cxl_mem_opcode_to_name(u16 opcode)
166166
int cxl_internal_send_cmd(struct cxl_dev_state *cxlds,
167167
struct cxl_mbox_cmd *mbox_cmd)
168168
{
169-
const struct cxl_mem_command *cmd =
170-
cxl_mem_find_command(mbox_cmd->opcode);
171-
size_t out_size;
169+
size_t out_size, min_out;
172170
int rc;
173171

174172
if (mbox_cmd->size_in > cxlds->payload_size ||
175173
mbox_cmd->size_out > cxlds->payload_size)
176174
return -E2BIG;
177175

178176
out_size = mbox_cmd->size_out;
177+
min_out = mbox_cmd->min_out;
179178
rc = cxlds->mbox_send(cxlds, mbox_cmd);
180179
if (rc)
181180
return rc;
182181

183182
if (mbox_cmd->return_code != CXL_MBOX_CMD_RC_SUCCESS)
184183
return cxl_mbox_cmd_rc2errno(mbox_cmd);
185184

185+
if (!out_size)
186+
return 0;
187+
186188
/*
187-
* Variable sized commands can't be validated and so it's up to the
188-
* caller to do that if they wish.
189+
* Variable sized output needs to at least satisfy the caller's
190+
* minimum if not the fully requested size.
189191
*/
190-
if (cmd->info.size_out != CXL_VARIABLE_PAYLOAD) {
191-
if (mbox_cmd->size_out != out_size)
192-
return -EIO;
193-
}
192+
if (min_out == 0)
193+
min_out = out_size;
194+
195+
if (mbox_cmd->size_out < min_out)
196+
return -EIO;
194197
return 0;
195198
}
196199
EXPORT_SYMBOL_NS_GPL(cxl_internal_send_cmd, CXL);
@@ -635,6 +638,8 @@ static struct cxl_mbox_get_supported_logs *cxl_get_gsl(struct cxl_dev_state *cxl
635638
.opcode = CXL_MBOX_OP_GET_SUPPORTED_LOGS,
636639
.size_out = cxlds->payload_size,
637640
.payload_out = ret,
641+
/* At least the record number field must be valid */
642+
.min_out = 2,
638643
};
639644
rc = cxl_internal_send_cmd(cxlds, &mbox_cmd);
640645
if (rc < 0) {

drivers/cxl/cxlmem.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ static inline struct cxl_ep *cxl_ep_load(struct cxl_port *port,
101101
* outputs commands this is always expected to be deterministic. For
102102
* variable sized output commands, it tells the exact number of bytes
103103
* written.
104+
* @min_out: (input) internal command output payload size validation
104105
* @return_code: (output) Error code returned from hardware.
105106
*
106107
* This is the primary mechanism used to send commands to the hardware.
@@ -115,6 +116,7 @@ struct cxl_mbox_cmd {
115116
void *payload_out;
116117
size_t size_in;
117118
size_t size_out;
119+
size_t min_out;
118120
u16 return_code;
119121
};
120122

0 commit comments

Comments
 (0)