]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
firmware: arm_scmi: Account for SHMEM memory overhead
authorCristian Marussi <cristian.marussi@arm.com>
Mon, 28 Oct 2024 12:01:45 +0000 (12:01 +0000)
committerSudeep Holla <sudeep.holla@arm.com>
Mon, 28 Oct 2024 14:51:10 +0000 (14:51 +0000)
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>
drivers/firmware/arm_scmi/common.h
drivers/firmware/arm_scmi/driver.c
drivers/firmware/arm_scmi/shmem.c
drivers/firmware/arm_scmi/transports/mailbox.c
drivers/firmware/arm_scmi/transports/optee.c
drivers/firmware/arm_scmi/transports/smc.c

index 951254eda48231b827e1cfce077ff071a2f79b19..e2424e65066fd83b1d2378182f2262875b233ccb 100644 (file)
@@ -31,6 +31,8 @@
 
 #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 */
@@ -165,6 +167,7 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
  *      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.
@@ -177,6 +180,7 @@ struct scmi_chan_info {
        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;
@@ -224,7 +228,7 @@ struct scmi_transport_ops {
  * @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
index f8934d049d686fd9831c3dab571f40d7154a25fe..7d5f0da975c77205980b4cded0c1e85f70536b6c 100644 (file)
@@ -2645,6 +2645,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
 
        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",
index e9f30ab671a81a0953bb58ce8823bf7ba1de4eac..11c347bff766763c61100f884432c2e4669e5918 100644 (file)
@@ -16,6 +16,8 @@
 
 #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
@@ -221,6 +223,11 @@ static void __iomem *shmem_setup_iomap(struct scmi_chan_info *cinfo,
        }
 
        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);
index e7efa3376aae7ccd8daebcfd6054218d4bb12211..b66df29814566215770bfcaa3fa782dc730b9dc6 100644 (file)
@@ -371,7 +371,7 @@ static struct scmi_desc scmi_mailbox_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[] = {
index 663272879edfd54030709e428b269a0f3d553514..3949a877e17dd6bc9ab61b95af68404510032a2e 100644 (file)
@@ -17,8 +17,6 @@
 
 #include "../common.h"
 
-#define SCMI_OPTEE_MAX_MSG_SIZE                128
-
 enum scmi_optee_pta_cmd {
        /*
         * PTA_SCMI_CMD_CAPABILITIES - Get channel capabilities
@@ -299,7 +297,7 @@ static int invoke_process_msg_channel(struct scmi_optee_channel *channel, size_t
 
        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) {
@@ -332,7 +330,7 @@ static void scmi_optee_clear_channel(struct scmi_chan_info *cinfo)
 
 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);
@@ -519,7 +517,7 @@ static struct scmi_desc scmi_optee_desc = {
        .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,
 };
 
index 2f0e981e7599f0882522778068e3bdfa5f83520b..f632a62cfb3ec235b5225e616273faf5ce9878e1 100644 (file)
@@ -282,7 +282,7 @@ static struct scmi_desc scmi_smc_desc = {
        .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