Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

firmware: arm_scmi: Account for SHMEM memory overhead

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>

authored by

Cristian Marussi and committed by
Sudeep Holla
5c14f388 2cd7f3db

+18 -8
+5 -1
drivers/firmware/arm_scmi/common.h
··· 31 31 32 32 #define SCMI_MAX_RESPONSE_TIMEOUT (2 * MSEC_PER_SEC) 33 33 34 + #define SCMI_SHMEM_MAX_PAYLOAD_SIZE 104 35 + 34 36 enum scmi_error_codes { 35 37 SCMI_SUCCESS = 0, /* Success */ 36 38 SCMI_ERR_SUPPORT = -1, /* Not supported */ ··· 167 165 * channel 168 166 * @is_p2a: A flag to identify a channel as P2A (RX) 169 167 * @rx_timeout_ms: The configured RX timeout in milliseconds. 168 + * @max_msg_size: Maximum size of message payload. 170 169 * @handle: Pointer to SCMI entity handle 171 170 * @no_completion_irq: Flag to indicate that this channel has no completion 172 171 * interrupt mechanism for synchronous commands. ··· 180 177 struct device *dev; 181 178 bool is_p2a; 182 179 unsigned int rx_timeout_ms; 180 + unsigned int max_msg_size; 183 181 struct scmi_handle *handle; 184 182 bool no_completion_irq; 185 183 void *transport_info; ··· 228 224 * @max_msg: Maximum number of messages for a channel type (tx or rx) that can 229 225 * be pending simultaneously in the system. May be overridden by the 230 226 * get_max_msg op. 231 - * @max_msg_size: Maximum size of data per message that can be handled. 227 + * @max_msg_size: Maximum size of data payload per message that can be handled. 232 228 * @force_polling: Flag to force this whole transport to use SCMI core polling 233 229 * mechanism instead of completion interrupts even if available. 234 230 * @sync_cmds_completed_on_ret: Flag to indicate that the transport assures
+1
drivers/firmware/arm_scmi/driver.c
··· 2645 2645 2646 2646 cinfo->is_p2a = !tx; 2647 2647 cinfo->rx_timeout_ms = info->desc->max_rx_timeout_ms; 2648 + cinfo->max_msg_size = info->desc->max_msg_size; 2648 2649 2649 2650 /* Create a unique name for this transport device */ 2650 2651 snprintf(name, 32, "__scmi_transport_device_%s_%02X",
+7
drivers/firmware/arm_scmi/shmem.c
··· 16 16 17 17 #include "common.h" 18 18 19 + #define SCMI_SHMEM_LAYOUT_OVERHEAD 24 20 + 19 21 /* 20 22 * SCMI specification requires all parameters, message headers, return 21 23 * arguments or any protocol data to be expressed in little endian ··· 223 221 } 224 222 225 223 size = resource_size(res); 224 + if (cinfo->max_msg_size + SCMI_SHMEM_LAYOUT_OVERHEAD > size) { 225 + dev_err(dev, "misconfigured SCMI shared memory\n"); 226 + return IOMEM_ERR_PTR(-ENOSPC); 227 + } 228 + 226 229 addr = devm_ioremap(dev, res->start, size); 227 230 if (!addr) { 228 231 dev_err(dev, "failed to ioremap SCMI %s shared memory\n", desc);
+1 -1
drivers/firmware/arm_scmi/transports/mailbox.c
··· 371 371 .ops = &scmi_mailbox_ops, 372 372 .max_rx_timeout_ms = 30, /* We may increase this if required */ 373 373 .max_msg = 20, /* Limited by MBOX_TX_QUEUE_LEN */ 374 - .max_msg_size = 128, 374 + .max_msg_size = SCMI_SHMEM_MAX_PAYLOAD_SIZE, 375 375 }; 376 376 377 377 static const struct of_device_id scmi_of_match[] = {
+3 -5
drivers/firmware/arm_scmi/transports/optee.c
··· 17 17 18 18 #include "../common.h" 19 19 20 - #define SCMI_OPTEE_MAX_MSG_SIZE 128 21 - 22 20 enum scmi_optee_pta_cmd { 23 21 /* 24 22 * PTA_SCMI_CMD_CAPABILITIES - Get channel capabilities ··· 297 299 298 300 param[2].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; 299 301 param[2].u.memref.shm = channel->tee_shm; 300 - param[2].u.memref.size = SCMI_OPTEE_MAX_MSG_SIZE; 302 + param[2].u.memref.size = SCMI_SHMEM_MAX_PAYLOAD_SIZE; 301 303 302 304 ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param); 303 305 if (ret < 0 || arg.ret) { ··· 330 332 331 333 static int setup_dynamic_shmem(struct device *dev, struct scmi_optee_channel *channel) 332 334 { 333 - const size_t msg_size = SCMI_OPTEE_MAX_MSG_SIZE; 335 + const size_t msg_size = SCMI_SHMEM_MAX_PAYLOAD_SIZE; 334 336 void *shbuf; 335 337 336 338 channel->tee_shm = tee_shm_alloc_kernel_buf(scmi_optee_private->tee_ctx, msg_size); ··· 517 519 .ops = &scmi_optee_ops, 518 520 .max_rx_timeout_ms = 30, 519 521 .max_msg = 20, 520 - .max_msg_size = SCMI_OPTEE_MAX_MSG_SIZE, 522 + .max_msg_size = SCMI_SHMEM_MAX_PAYLOAD_SIZE, 521 523 .sync_cmds_completed_on_ret = true, 522 524 }; 523 525
+1 -1
drivers/firmware/arm_scmi/transports/smc.c
··· 282 282 .ops = &scmi_smc_ops, 283 283 .max_rx_timeout_ms = 30, 284 284 .max_msg = 20, 285 - .max_msg_size = 128, 285 + .max_msg_size = SCMI_SHMEM_MAX_PAYLOAD_SIZE, 286 286 /* 287 287 * Setting .sync_cmds_atomic_replies to true for SMC assumes that, 288 288 * once the SMC instruction has completed successfully, the issued