mbox.c (5331cdf44dc389ac56f7ba5c24ca52d13eaad8d7) mbox.c (2aeaf663b85e436dc6287692b7561ffbf0aa4381)
1// SPDX-License-Identifier: GPL-2.0-only
2/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
3#include <linux/io-64-nonatomic-lo-hi.h>
4#include <linux/security.h>
5#include <linux/debugfs.h>
6#include <linux/mutex.h>
7#include <cxlmem.h>
8#include <cxl.h>

--- 152 unchanged lines hidden (view full) ---

161 *
162 * Mailbox commands may execute successfully yet the device itself reported an
163 * error. While this distinction can be useful for commands from userspace, the
164 * kernel will only be able to use results when both are successful.
165 */
166int cxl_internal_send_cmd(struct cxl_dev_state *cxlds,
167 struct cxl_mbox_cmd *mbox_cmd)
168{
1// SPDX-License-Identifier: GPL-2.0-only
2/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
3#include <linux/io-64-nonatomic-lo-hi.h>
4#include <linux/security.h>
5#include <linux/debugfs.h>
6#include <linux/mutex.h>
7#include <cxlmem.h>
8#include <cxl.h>

--- 152 unchanged lines hidden (view full) ---

161 *
162 * Mailbox commands may execute successfully yet the device itself reported an
163 * error. While this distinction can be useful for commands from userspace, the
164 * kernel will only be able to use results when both are successful.
165 */
166int cxl_internal_send_cmd(struct cxl_dev_state *cxlds,
167 struct cxl_mbox_cmd *mbox_cmd)
168{
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;
172 int rc;
173
174 if (mbox_cmd->size_in > cxlds->payload_size ||
175 mbox_cmd->size_out > cxlds->payload_size)
176 return -E2BIG;
177
178 out_size = mbox_cmd->size_out;
170 int rc;
171
172 if (mbox_cmd->size_in > cxlds->payload_size ||
173 mbox_cmd->size_out > cxlds->payload_size)
174 return -E2BIG;
175
176 out_size = mbox_cmd->size_out;
177 min_out = mbox_cmd->min_out;
179 rc = cxlds->mbox_send(cxlds, mbox_cmd);
180 if (rc)
181 return rc;
182
183 if (mbox_cmd->return_code != CXL_MBOX_CMD_RC_SUCCESS)
184 return cxl_mbox_cmd_rc2errno(mbox_cmd);
185
178 rc = cxlds->mbox_send(cxlds, mbox_cmd);
179 if (rc)
180 return rc;
181
182 if (mbox_cmd->return_code != CXL_MBOX_CMD_RC_SUCCESS)
183 return cxl_mbox_cmd_rc2errno(mbox_cmd);
184
185 if (!out_size)
186 return 0;
187
186 /*
188 /*
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.
189 */
191 */
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;
194 return 0;
195}
196EXPORT_SYMBOL_NS_GPL(cxl_internal_send_cmd, CXL);
197
198static bool cxl_mem_raw_command_allowed(u16 opcode)
199{
200 int i;
201

--- 428 unchanged lines hidden (view full) ---

630 ret = kvmalloc(cxlds->payload_size, GFP_KERNEL);
631 if (!ret)
632 return ERR_PTR(-ENOMEM);
633
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,
197 return 0;
198}
199EXPORT_SYMBOL_NS_GPL(cxl_internal_send_cmd, CXL);
200
201static bool cxl_mem_raw_command_allowed(u16 opcode)
202{
203 int i;
204

--- 428 unchanged lines hidden (view full) ---

633 ret = kvmalloc(cxlds->payload_size, GFP_KERNEL);
634 if (!ret)
635 return ERR_PTR(-ENOMEM);
636
637 mbox_cmd = (struct cxl_mbox_cmd) {
638 .opcode = CXL_MBOX_OP_GET_SUPPORTED_LOGS,
639 .size_out = cxlds->payload_size,
640 .payload_out = ret,
641 /* At least the record number field must be valid */
642 .min_out = 2,
638 };
639 rc = cxl_internal_send_cmd(cxlds, &mbox_cmd);
640 if (rc < 0) {
641 kvfree(ret);
642 return ERR_PTR(rc);
643 }
644
645

--- 251 unchanged lines hidden ---
643 };
644 rc = cxl_internal_send_cmd(cxlds, &mbox_cmd);
645 if (rc < 0) {
646 kvfree(ret);
647 return ERR_PTR(rc);
648 }
649
650

--- 251 unchanged lines hidden ---