[PATCH v2 11/22] firmware: ti_sci: Use rx_message as message receive buffer

Padhi, Beleswar b-padhi at ti.com
Wed Sep 30 13:17:56 PDT 2026


On 10/1/2026 12:22 AM, Andrew Davis wrote:
> On 9/30/26 11:05 AM, Beleswar Padhi wrote:
>> From: Andrew Davis <afd at ti.com>
>>
>> Previously we allocated a message buffer big enough for the largest
>> message we could receive for every message we could have concurrently
>> in flight. Now have the rx_message buffer during the whole xfer process
>
> s/Now have/Now that we have
>
>> we can use that as our message receive buffer. This removes an extra 
>> copy
>> and the amount of memory we need to pre-allocate.
>>
>> Note: rx_buf now points to the caller's on-stack response buffer. If
>> the system firmware replies after ti_sci_do_xfer() has timed out, the
>> rx callback can race with the caller returning and write into a stale
>> stack frame. A reply that arrives after the timeout means the system
>
> To add, the RX callback checks that the message is still expected
> and returns safely if not. After a timeout the ti_sci_do_xfer()
> function marks the message as no longer expected, before the stack
> frame goes out of scope. The only way this can be an issue is if
> the RX callback happens exactly after the timeout and is able
> to get past the check before we set it, and then also not finish
> the memcpy until after we return from setting that expected check.
>
> We could probably still solve that with some additional locking, but
> in practice this exact sequence is never going to happen. And the only
> time a message timeouts is when the TI-SCI firmware has crashed, so
> your system is already borked.


Yup :D,  LLMs are good in hypothesising a scenario where the patch
could fail, but bottom line being this: "And the only  time a message
timeouts is when the TI-SCI firmware has crashed, so  your system is
already borked." , we're good. I had added this explanation in the
commit message to satisfy sashiko comments.

Thanks,
Beleswar

>
> Andrew
>
>> firmware is not responding within its specified bounds, after which the
>> system cannot be expected to operate correctly anyway, so this is not
>> handled.
>>
>> Signed-off-by: Andrew Davis <afd at ti.com>
>> Co-developed-by: Beleswar Padhi <b-padhi at ti.com>
>> Signed-off-by: Beleswar Padhi <b-padhi at ti.com>
>> ---
>> v2: Changelog:
>> 1. None to this patch.
>>
>> Link to v1:
>> https://lore.kernel.org/all/20260929201746.4078803-12-b-padhi@ti.com/
>>
>>   drivers/firmware/ti_sci.c | 21 +++++----------------
>>   1 file changed, 5 insertions(+), 16 deletions(-)
>>
>> diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
>> index 6ed67160c6a7f..fef7028d40e39 100644
>> --- a/drivers/firmware/ti_sci.c
>> +++ b/drivers/firmware/ti_sci.c
>> @@ -45,14 +45,12 @@ static DEFINE_MUTEX(ti_sci_list_mutex);
>>    * @tx_message:    Transmit message
>>    * @rx_buf:    Pointer to store received message
>>    * @rx_len:    Receive message length
>> - * @xfer_buf:    Preallocated buffer to store receive message
>>    * @done:    completion event
>>    */
>>   struct ti_sci_xfer {
>>       struct ti_msgmgr_message tx_message;
>>       void *rx_buf;
>>       u8 rx_len;
>> -    u8 *xfer_buf;
>>       struct completion done;
>>   };
>>   @@ -287,7 +285,7 @@ static void ti_sci_rx_callback(struct 
>> mbox_client *cl, void *m)
>>         ti_sci_dump_header_dbg(dev, hdr);
>>       /* Take a copy to the rx buffer.. */
>> -    memcpy(xfer->xfer_buf, mbox_msg->buf, xfer->rx_len);
>> +    memcpy(xfer->rx_buf, mbox_msg->buf, xfer->rx_len);
>>       complete(&xfer->done);
>>   }
>>   @@ -522,12 +520,10 @@ static inline int ti_sci_do_xfer(const struct 
>> ti_sci_handle *handle,
>>        * state, then ensure that the response is an ACK
>>        */
>>       if (response_expected && ret == 0) {
>> -        if (!ti_sci_is_response_ack(xfer->xfer_buf)) {
>> +        if (!ti_sci_is_response_ack(xfer->rx_buf)) {
>>               dev_warn(dev, "Message response not acknowledged 
>> (caller: %pS)\n",
>>                    caller);
>>               ret = -ENODEV;
>> -        } else {
>> -            memcpy(xfer->rx_buf, xfer->xfer_buf, xfer->rx_len);
>>           }
>>       }
>>   @@ -3326,7 +3322,6 @@ static int ti_sci_probe(struct 
>> platform_device *pdev)
>>   {
>>       struct device *dev = &pdev->dev;
>>       const struct ti_sci_desc *desc;
>> -    struct ti_sci_xfer *xfer;
>>       struct ti_sci_info *info = NULL;
>>       struct ti_sci_xfers_info *minfo;
>>       struct mbox_client *cl;
>> @@ -3380,15 +3375,9 @@ static int ti_sci_probe(struct platform_device 
>> *pdev)
>>       if (!minfo->xfer_alloc_table)
>>           return -ENOMEM;
>>   -    /* Pre-initialize the buffer pointer to pre-allocated buffers */
>> -    for (i = 0, xfer = minfo->xfer_block; i < desc->max_msgs; i++, 
>> xfer++) {
>> -        xfer->xfer_buf = devm_kzalloc(dev, desc->max_msg_size,
>> -                          GFP_KERNEL);
>> -        if (!xfer->xfer_buf)
>> -            return -ENOMEM;
>> -
>> -        init_completion(&xfer->done);
>> -    }
>> +    /* Initialize the xfer completions */
>> +    for (i = 0; i < desc->max_msgs; i++)
>> +        init_completion(&minfo->xfer_block[i].done);
>>         ret = ti_sci_debugfs_create(pdev, info);
>>       if (ret)
>



More information about the linux-arm-kernel mailing list