Skip to content

Commit 5331cdf

Browse files
committed
cxl/mbox: Enable cxl_mbox_send_cmd() users to validate output size
Internally cxl_mbox_send_cmd() converts all passed-in parameters to a 'struct cxl_mbox_cmd' instance and sends that to cxlds->mbox_send(). It then teases the possibilty that the caller can validate the output size. However, they cannot since the resulting output size is not conveyed to the called. Fix that by making the caller pass in a constructed 'struct cxl_mbox_cmd'. This prepares for a future patch to add output size validation on a per-command basis. Given the change in signature, also change the name to differentiate it from the user command submission path that performs more validation before generating the 'struct cxl_mbox_cmd' instance to execute. Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Ira Weiny <ira.weiny@intel.com> Link: https://lore.kernel.org/r/167030055370.4044561.17788093375112783036.stgit@dwillia2-xfh.jf.intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent f5ee4cc commit 5331cdf

4 files changed

Lines changed: 126 additions & 62 deletions

File tree

drivers/cxl/core/mbox.c

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,9 @@ static const char *cxl_mem_opcode_to_name(u16 opcode)
146146
}
147147

148148
/**
149-
* cxl_mbox_send_cmd() - Send a mailbox command to a device.
149+
* cxl_internal_send_cmd() - Kernel internal interface to send a mailbox command
150150
* @cxlds: The device data for the operation
151-
* @opcode: Opcode for the mailbox command.
152-
* @in: The input payload for the mailbox command.
153-
* @in_size: The length of the input payload
154-
* @out: Caller allocated buffer for the output.
155-
* @out_size: Expected size of output.
151+
* @mbox_cmd: initialized command to execute
156152
*
157153
* Context: Any context.
158154
* Return:
@@ -167,40 +163,37 @@ static const char *cxl_mem_opcode_to_name(u16 opcode)
167163
* error. While this distinction can be useful for commands from userspace, the
168164
* kernel will only be able to use results when both are successful.
169165
*/
170-
int cxl_mbox_send_cmd(struct cxl_dev_state *cxlds, u16 opcode, void *in,
171-
size_t in_size, void *out, size_t out_size)
166+
int cxl_internal_send_cmd(struct cxl_dev_state *cxlds,
167+
struct cxl_mbox_cmd *mbox_cmd)
172168
{
173-
const struct cxl_mem_command *cmd = cxl_mem_find_command(opcode);
174-
struct cxl_mbox_cmd mbox_cmd = {
175-
.opcode = opcode,
176-
.payload_in = in,
177-
.size_in = in_size,
178-
.size_out = out_size,
179-
.payload_out = out,
180-
};
169+
const struct cxl_mem_command *cmd =
170+
cxl_mem_find_command(mbox_cmd->opcode);
171+
size_t out_size;
181172
int rc;
182173

183-
if (in_size > cxlds->payload_size || out_size > cxlds->payload_size)
174+
if (mbox_cmd->size_in > cxlds->payload_size ||
175+
mbox_cmd->size_out > cxlds->payload_size)
184176
return -E2BIG;
185177

186-
rc = cxlds->mbox_send(cxlds, &mbox_cmd);
178+
out_size = mbox_cmd->size_out;
179+
rc = cxlds->mbox_send(cxlds, mbox_cmd);
187180
if (rc)
188181
return rc;
189182

190-
if (mbox_cmd.return_code != CXL_MBOX_CMD_RC_SUCCESS)
191-
return cxl_mbox_cmd_rc2errno(&mbox_cmd);
183+
if (mbox_cmd->return_code != CXL_MBOX_CMD_RC_SUCCESS)
184+
return cxl_mbox_cmd_rc2errno(mbox_cmd);
192185

193186
/*
194187
* Variable sized commands can't be validated and so it's up to the
195188
* caller to do that if they wish.
196189
*/
197190
if (cmd->info.size_out != CXL_VARIABLE_PAYLOAD) {
198-
if (mbox_cmd.size_out != out_size)
191+
if (mbox_cmd->size_out != out_size)
199192
return -EIO;
200193
}
201194
return 0;
202195
}
203-
EXPORT_SYMBOL_NS_GPL(cxl_mbox_send_cmd, CXL);
196+
EXPORT_SYMBOL_NS_GPL(cxl_internal_send_cmd, CXL);
204197

205198
static bool cxl_mem_raw_command_allowed(u16 opcode)
206199
{
@@ -567,15 +560,25 @@ static int cxl_xfer_log(struct cxl_dev_state *cxlds, uuid_t *uuid, u32 size, u8
567560

568561
while (remaining) {
569562
u32 xfer_size = min_t(u32, remaining, cxlds->payload_size);
570-
struct cxl_mbox_get_log log = {
563+
struct cxl_mbox_cmd mbox_cmd;
564+
struct cxl_mbox_get_log log;
565+
int rc;
566+
567+
log = (struct cxl_mbox_get_log) {
571568
.uuid = *uuid,
572569
.offset = cpu_to_le32(offset),
573-
.length = cpu_to_le32(xfer_size)
570+
.length = cpu_to_le32(xfer_size),
571+
};
572+
573+
mbox_cmd = (struct cxl_mbox_cmd) {
574+
.opcode = CXL_MBOX_OP_GET_LOG,
575+
.size_in = sizeof(log),
576+
.payload_in = &log,
577+
.size_out = xfer_size,
578+
.payload_out = out,
574579
};
575-
int rc;
576580

577-
rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_GET_LOG, &log, sizeof(log),
578-
out, xfer_size);
581+
rc = cxl_internal_send_cmd(cxlds, &mbox_cmd);
579582
if (rc < 0)
580583
return rc;
581584

@@ -621,19 +624,25 @@ static void cxl_walk_cel(struct cxl_dev_state *cxlds, size_t size, u8 *cel)
621624
static struct cxl_mbox_get_supported_logs *cxl_get_gsl(struct cxl_dev_state *cxlds)
622625
{
623626
struct cxl_mbox_get_supported_logs *ret;
627+
struct cxl_mbox_cmd mbox_cmd;
624628
int rc;
625629

626630
ret = kvmalloc(cxlds->payload_size, GFP_KERNEL);
627631
if (!ret)
628632
return ERR_PTR(-ENOMEM);
629633

630-
rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_GET_SUPPORTED_LOGS, NULL, 0, ret,
631-
cxlds->payload_size);
634+
mbox_cmd = (struct cxl_mbox_cmd) {
635+
.opcode = CXL_MBOX_OP_GET_SUPPORTED_LOGS,
636+
.size_out = cxlds->payload_size,
637+
.payload_out = ret,
638+
};
639+
rc = cxl_internal_send_cmd(cxlds, &mbox_cmd);
632640
if (rc < 0) {
633641
kvfree(ret);
634642
return ERR_PTR(rc);
635643
}
636644

645+
637646
return ret;
638647
}
639648

@@ -735,11 +744,15 @@ EXPORT_SYMBOL_NS_GPL(cxl_enumerate_cmds, CXL);
735744
static int cxl_mem_get_partition_info(struct cxl_dev_state *cxlds)
736745
{
737746
struct cxl_mbox_get_partition_info pi;
747+
struct cxl_mbox_cmd mbox_cmd;
738748
int rc;
739749

740-
rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_GET_PARTITION_INFO, NULL, 0,
741-
&pi, sizeof(pi));
742-
750+
mbox_cmd = (struct cxl_mbox_cmd) {
751+
.opcode = CXL_MBOX_OP_GET_PARTITION_INFO,
752+
.size_out = sizeof(pi),
753+
.payload_out = &pi,
754+
};
755+
rc = cxl_internal_send_cmd(cxlds, &mbox_cmd);
743756
if (rc)
744757
return rc;
745758

@@ -768,10 +781,15 @@ int cxl_dev_state_identify(struct cxl_dev_state *cxlds)
768781
{
769782
/* See CXL 2.0 Table 175 Identify Memory Device Output Payload */
770783
struct cxl_mbox_identify id;
784+
struct cxl_mbox_cmd mbox_cmd;
771785
int rc;
772786

773-
rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_IDENTIFY, NULL, 0, &id,
774-
sizeof(id));
787+
mbox_cmd = (struct cxl_mbox_cmd) {
788+
.opcode = CXL_MBOX_OP_IDENTIFY,
789+
.size_out = sizeof(id),
790+
.payload_out = &id,
791+
};
792+
rc = cxl_internal_send_cmd(cxlds, &mbox_cmd);
775793
if (rc < 0)
776794
return rc;
777795

drivers/cxl/cxlmem.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,8 @@ enum {
430430
CXL_PMEM_SEC_PASS_USER,
431431
};
432432

433-
int cxl_mbox_send_cmd(struct cxl_dev_state *cxlds, u16 opcode, void *in,
434-
size_t in_size, void *out, size_t out_size);
433+
int cxl_internal_send_cmd(struct cxl_dev_state *cxlds,
434+
struct cxl_mbox_cmd *cmd);
435435
int cxl_dev_state_identify(struct cxl_dev_state *cxlds);
436436
int cxl_await_media_ready(struct cxl_dev_state *cxlds);
437437
int cxl_enumerate_cmds(struct cxl_dev_state *cxlds);

drivers/cxl/pmem.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ static int cxl_pmem_get_config_data(struct cxl_dev_state *cxlds,
119119
unsigned int buf_len)
120120
{
121121
struct cxl_mbox_get_lsa get_lsa;
122+
struct cxl_mbox_cmd mbox_cmd;
122123
int rc;
123124

124125
if (sizeof(*cmd) > buf_len)
@@ -130,9 +131,15 @@ static int cxl_pmem_get_config_data(struct cxl_dev_state *cxlds,
130131
.offset = cpu_to_le32(cmd->in_offset),
131132
.length = cpu_to_le32(cmd->in_length),
132133
};
134+
mbox_cmd = (struct cxl_mbox_cmd) {
135+
.opcode = CXL_MBOX_OP_GET_LSA,
136+
.payload_in = &get_lsa,
137+
.size_in = sizeof(get_lsa),
138+
.size_out = cmd->in_length,
139+
.payload_out = cmd->out_buf,
140+
};
133141

134-
rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_GET_LSA, &get_lsa,
135-
sizeof(get_lsa), cmd->out_buf, cmd->in_length);
142+
rc = cxl_internal_send_cmd(cxlds, &mbox_cmd);
136143
cmd->status = 0;
137144

138145
return rc;
@@ -143,6 +150,7 @@ static int cxl_pmem_set_config_data(struct cxl_dev_state *cxlds,
143150
unsigned int buf_len)
144151
{
145152
struct cxl_mbox_set_lsa *set_lsa;
153+
struct cxl_mbox_cmd mbox_cmd;
146154
int rc;
147155

148156
if (sizeof(*cmd) > buf_len)
@@ -161,10 +169,13 @@ static int cxl_pmem_set_config_data(struct cxl_dev_state *cxlds,
161169
.offset = cpu_to_le32(cmd->in_offset),
162170
};
163171
memcpy(set_lsa->data, cmd->in_buf, cmd->in_length);
172+
mbox_cmd = (struct cxl_mbox_cmd) {
173+
.opcode = CXL_MBOX_OP_SET_LSA,
174+
.payload_in = set_lsa,
175+
.size_in = struct_size(set_lsa, data, cmd->in_length),
176+
};
164177

165-
rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_SET_LSA, set_lsa,
166-
struct_size(set_lsa, data, cmd->in_length),
167-
NULL, 0);
178+
rc = cxl_internal_send_cmd(cxlds, &mbox_cmd);
168179

169180
/*
170181
* Set "firmware" status (4-packed bytes at the end of the input

drivers/cxl/security.c

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,17 @@ static unsigned long cxl_pmem_get_security_flags(struct nvdimm *nvdimm,
1919
struct cxl_get_security_output {
2020
__le32 flags;
2121
} out;
22+
struct cxl_mbox_cmd mbox_cmd;
2223
u32 sec_out;
2324
int rc;
2425

25-
rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_GET_SECURITY_STATE, NULL, 0,
26-
&out, sizeof(out));
26+
mbox_cmd = (struct cxl_mbox_cmd) {
27+
.opcode = CXL_MBOX_OP_GET_SECURITY_STATE,
28+
.size_out = sizeof(out),
29+
.payload_out = &out,
30+
};
31+
32+
rc = cxl_internal_send_cmd(cxlds, &mbox_cmd);
2733
if (rc < 0)
2834
return 0;
2935

@@ -62,17 +68,23 @@ static int cxl_pmem_security_change_key(struct nvdimm *nvdimm,
6268
struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm);
6369
struct cxl_memdev *cxlmd = cxl_nvd->cxlmd;
6470
struct cxl_dev_state *cxlds = cxlmd->cxlds;
71+
struct cxl_mbox_cmd mbox_cmd;
6572
struct cxl_set_pass set_pass;
66-
int rc;
6773

68-
set_pass.type = ptype == NVDIMM_MASTER ?
69-
CXL_PMEM_SEC_PASS_MASTER : CXL_PMEM_SEC_PASS_USER;
74+
set_pass = (struct cxl_set_pass) {
75+
.type = ptype == NVDIMM_MASTER ? CXL_PMEM_SEC_PASS_MASTER :
76+
CXL_PMEM_SEC_PASS_USER,
77+
};
7078
memcpy(set_pass.old_pass, old_data->data, NVDIMM_PASSPHRASE_LEN);
7179
memcpy(set_pass.new_pass, new_data->data, NVDIMM_PASSPHRASE_LEN);
7280

73-
rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_SET_PASSPHRASE,
74-
&set_pass, sizeof(set_pass), NULL, 0);
75-
return rc;
81+
mbox_cmd = (struct cxl_mbox_cmd) {
82+
.opcode = CXL_MBOX_OP_SET_PASSPHRASE,
83+
.size_in = sizeof(set_pass),
84+
.payload_in = &set_pass,
85+
};
86+
87+
return cxl_internal_send_cmd(cxlds, &mbox_cmd);
7688
}
7789

7890
static int __cxl_pmem_security_disable(struct nvdimm *nvdimm,
@@ -83,15 +95,21 @@ static int __cxl_pmem_security_disable(struct nvdimm *nvdimm,
8395
struct cxl_memdev *cxlmd = cxl_nvd->cxlmd;
8496
struct cxl_dev_state *cxlds = cxlmd->cxlds;
8597
struct cxl_disable_pass dis_pass;
86-
int rc;
98+
struct cxl_mbox_cmd mbox_cmd;
8799

88-
dis_pass.type = ptype == NVDIMM_MASTER ?
89-
CXL_PMEM_SEC_PASS_MASTER : CXL_PMEM_SEC_PASS_USER;
100+
dis_pass = (struct cxl_disable_pass) {
101+
.type = ptype == NVDIMM_MASTER ? CXL_PMEM_SEC_PASS_MASTER :
102+
CXL_PMEM_SEC_PASS_USER,
103+
};
90104
memcpy(dis_pass.pass, key_data->data, NVDIMM_PASSPHRASE_LEN);
91105

92-
rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_DISABLE_PASSPHRASE,
93-
&dis_pass, sizeof(dis_pass), NULL, 0);
94-
return rc;
106+
mbox_cmd = (struct cxl_mbox_cmd) {
107+
.opcode = CXL_MBOX_OP_DISABLE_PASSPHRASE,
108+
.size_in = sizeof(dis_pass),
109+
.payload_in = &dis_pass,
110+
};
111+
112+
return cxl_internal_send_cmd(cxlds, &mbox_cmd);
95113
}
96114

97115
static int cxl_pmem_security_disable(struct nvdimm *nvdimm,
@@ -111,8 +129,11 @@ static int cxl_pmem_security_freeze(struct nvdimm *nvdimm)
111129
struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm);
112130
struct cxl_memdev *cxlmd = cxl_nvd->cxlmd;
113131
struct cxl_dev_state *cxlds = cxlmd->cxlds;
132+
struct cxl_mbox_cmd mbox_cmd = {
133+
.opcode = CXL_MBOX_OP_FREEZE_SECURITY,
134+
};
114135

115-
return cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_FREEZE_SECURITY, NULL, 0, NULL, 0);
136+
return cxl_internal_send_cmd(cxlds, &mbox_cmd);
116137
}
117138

118139
static int cxl_pmem_security_unlock(struct nvdimm *nvdimm,
@@ -122,11 +143,17 @@ static int cxl_pmem_security_unlock(struct nvdimm *nvdimm,
122143
struct cxl_memdev *cxlmd = cxl_nvd->cxlmd;
123144
struct cxl_dev_state *cxlds = cxlmd->cxlds;
124145
u8 pass[NVDIMM_PASSPHRASE_LEN];
146+
struct cxl_mbox_cmd mbox_cmd;
125147
int rc;
126148

127149
memcpy(pass, key_data->data, NVDIMM_PASSPHRASE_LEN);
128-
rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_UNLOCK,
129-
pass, NVDIMM_PASSPHRASE_LEN, NULL, 0);
150+
mbox_cmd = (struct cxl_mbox_cmd) {
151+
.opcode = CXL_MBOX_OP_UNLOCK,
152+
.size_in = NVDIMM_PASSPHRASE_LEN,
153+
.payload_in = pass,
154+
};
155+
156+
rc = cxl_internal_send_cmd(cxlds, &mbox_cmd);
130157
if (rc < 0)
131158
return rc;
132159

@@ -140,14 +167,22 @@ static int cxl_pmem_security_passphrase_erase(struct nvdimm *nvdimm,
140167
struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm);
141168
struct cxl_memdev *cxlmd = cxl_nvd->cxlmd;
142169
struct cxl_dev_state *cxlds = cxlmd->cxlds;
170+
struct cxl_mbox_cmd mbox_cmd;
143171
struct cxl_pass_erase erase;
144172
int rc;
145173

146-
erase.type = ptype == NVDIMM_MASTER ?
147-
CXL_PMEM_SEC_PASS_MASTER : CXL_PMEM_SEC_PASS_USER;
174+
erase = (struct cxl_pass_erase) {
175+
.type = ptype == NVDIMM_MASTER ? CXL_PMEM_SEC_PASS_MASTER :
176+
CXL_PMEM_SEC_PASS_USER,
177+
};
148178
memcpy(erase.pass, key->data, NVDIMM_PASSPHRASE_LEN);
149-
rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_PASSPHRASE_SECURE_ERASE,
150-
&erase, sizeof(erase), NULL, 0);
179+
mbox_cmd = (struct cxl_mbox_cmd) {
180+
.opcode = CXL_MBOX_OP_PASSPHRASE_SECURE_ERASE,
181+
.size_in = sizeof(erase),
182+
.payload_in = &erase,
183+
};
184+
185+
rc = cxl_internal_send_cmd(cxlds, &mbox_cmd);
151186
if (rc < 0)
152187
return rc;
153188

0 commit comments

Comments
 (0)