Transports using shared memory have to consider the overhead due to the
layout area when determining the area effectively available for messages.
Till now, such definitions were ambiguos across the SCMI stack and the
overhead layout area was not considered at all.
Add proper checks in the shmem layer to validate the provided max_msg_size
against the effectively available memory area, less the layout.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Message-Id: <
20241028120151.
1301177-2-cristian.marussi@arm.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
#define SCMI_MAX_RESPONSE_TIMEOUT (2 * MSEC_PER_SEC)
+#define SCMI_SHMEM_MAX_PAYLOAD_SIZE 104
+
enum scmi_error_codes {
SCMI_SUCCESS = 0, /* Success */
SCMI_ERR_SUPPORT = -1, /* Not supported */
* channel
* @is_p2a: A flag to identify a channel as P2A (RX)
* @rx_timeout_ms: The configured RX timeout in milliseconds.
+ * @max_msg_size: Maximum size of message payload.
* @handle: Pointer to SCMI entity handle
* @no_completion_irq: Flag to indicate that this channel has no completion
* interrupt mechanism for synchronous commands.
struct device *dev;
bool is_p2a;
unsigned int rx_timeout_ms;
+ unsigned int max_msg_size;
struct scmi_handle *handle;
bool no_completion_irq;
void *transport_info;
* @max_msg: Maximum number of messages for a channel type (tx or rx) that can
* be pending simultaneously in the system. May be overridden by the
* get_max_msg op.
- * @max_msg_size: Maximum size of data per message that can be handled.
+ * @max_msg_size: Maximum size of data payload per message that can be handled.
* @force_polling: Flag to force this whole transport to use SCMI core polling
* mechanism instead of completion interrupts even if available.
* @sync_cmds_completed_on_ret: Flag to indicate that the transport assures
cinfo->is_p2a = !tx;
cinfo->rx_timeout_ms = info->desc->max_rx_timeout_ms;
+ cinfo->max_msg_size = info->desc->max_msg_size;
/* Create a unique name for this transport device */
snprintf(name, 32, "__scmi_transport_device_%s_%02X",
#include "common.h"
+#define SCMI_SHMEM_LAYOUT_OVERHEAD 24
+
/*
* SCMI specification requires all parameters, message headers, return
* arguments or any protocol data to be expressed in little endian
}
size = resource_size(res);
+ if (cinfo->max_msg_size + SCMI_SHMEM_LAYOUT_OVERHEAD > size) {
+ dev_err(dev, "misconfigured SCMI shared memory\n");
+ return IOMEM_ERR_PTR(-ENOSPC);
+ }
+
addr = devm_ioremap(dev, res->start, size);
if (!addr) {
dev_err(dev, "failed to ioremap SCMI %s shared memory\n", desc);
.ops = &scmi_mailbox_ops,
.max_rx_timeout_ms = 30, /* We may increase this if required */
.max_msg = 20, /* Limited by MBOX_TX_QUEUE_LEN */
- .max_msg_size = 128,
+ .max_msg_size = SCMI_SHMEM_MAX_PAYLOAD_SIZE,
};
static const struct of_device_id scmi_of_match[] = {
#include "../common.h"
-#define SCMI_OPTEE_MAX_MSG_SIZE 128
-
enum scmi_optee_pta_cmd {
/*
* PTA_SCMI_CMD_CAPABILITIES - Get channel capabilities
param[2].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
param[2].u.memref.shm = channel->tee_shm;
- param[2].u.memref.size = SCMI_OPTEE_MAX_MSG_SIZE;
+ param[2].u.memref.size = SCMI_SHMEM_MAX_PAYLOAD_SIZE;
ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param);
if (ret < 0 || arg.ret) {
static int setup_dynamic_shmem(struct device *dev, struct scmi_optee_channel *channel)
{
- const size_t msg_size = SCMI_OPTEE_MAX_MSG_SIZE;
+ const size_t msg_size = SCMI_SHMEM_MAX_PAYLOAD_SIZE;
void *shbuf;
channel->tee_shm = tee_shm_alloc_kernel_buf(scmi_optee_private->tee_ctx, msg_size);
.ops = &scmi_optee_ops,
.max_rx_timeout_ms = 30,
.max_msg = 20,
- .max_msg_size = SCMI_OPTEE_MAX_MSG_SIZE,
+ .max_msg_size = SCMI_SHMEM_MAX_PAYLOAD_SIZE,
.sync_cmds_completed_on_ret = true,
};
.ops = &scmi_smc_ops,
.max_rx_timeout_ms = 30,
.max_msg = 20,
- .max_msg_size = 128,
+ .max_msg_size = SCMI_SHMEM_MAX_PAYLOAD_SIZE,
/*
* Setting .sync_cmds_atomic_replies to true for SMC assumes that,
* once the SMC instruction has completed successfully, the issued