[PATCHv2] firmware: zynqmp: add handling of the NULL return payload pointer in xilinx_pm_request.
Michal Simek
michal.simek at xilinx.com
Thu Oct 14 11:47:10 CEST 2021
On 10/14/21 10:54, Adrian Fiergolski wrote:
> On 14.10.2021 at 09:22, Michal Simek wrote:
>>
>> First of all subject is quite long. Please make it shorter and remove
>> dot at the end.
>>
>>
>> On 10/13/21 18:21, Adrian Fiergolski wrote:
>>> When a caller is not interested in the returned message, the
>>> ret_payload pointer is set to NULL in the u-boot-sources.
>>> In this case, under EL3, the memory from address 0x0 would be
>>> overwritten by xilinx_pm_request with the returned IPI message,
>>> damaging the original data under this address. The patch, in case
>>> ret_payload is NULL, assigns the pointer to the array
>>> holding the IPI message being sent.
>>
>> There is any limit around 80 chars on the line that's why please use it.
>>
>>>
>>> Signed-off-by: Adrian Fiergolski <adrian.fiergolski at fastree3d.com>
>>> ---
>>> drivers/firmware/firmware-zynqmp.c | 20 ++++++++++++++------
>>> 1 file changed, 14 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/firmware/firmware-zynqmp.c
>>> b/drivers/firmware/firmware-zynqmp.c
>>> index d4dc856baf..7517a84f0e 100644
>>> --- a/drivers/firmware/firmware-zynqmp.c
>>> +++ b/drivers/firmware/firmware-zynqmp.c
>>> @@ -154,16 +154,24 @@ U_BOOT_DRIVER(zynqmp_power) = {
>>> int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32
>>> arg1, u32 arg2,
>>> u32 arg3, u32 *ret_payload)
>>> {
>>> +#if defined(CONFIG_ZYNQMP_IPI)
>>> + /*
>>> + * Use fixed payload and arg size as the EL2 call. The firmware
>>> + * is capable to handle PMUFW_PAYLOAD_ARG_CNT bytes but the
>>> + * firmware API is limited by the SMC call size
>>> + */
>>> + u32 regs[] = {api_id, arg0, arg1, arg2, arg3};
>>> +
>>> + /*
>>> + * Use regs array in case ret_payload is NULL
>>> + */
>>> + if (ret_payload == NULL)
>>> + ret_payload = regs;
>>> +#endif
>>> debug("%s at EL%d, API ID: 0x%0x\n", __func__, current_el(),
>>> api_id);
>>> if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
>>> #if defined(CONFIG_ZYNQMP_IPI)
>>> - /*
>>> - * Use fixed payload and arg size as the EL2 call. The firmware
>>> - * is capable to handle PMUFW_PAYLOAD_ARG_CNT bytes but the
>>> - * firmware API is limited by the SMC call size
>>> - */
>>> - u32 regs[] = {api_id, arg0, arg1, arg2, arg3};
>>>
>>
>> Based on your description the only code affected by this is here and
>> there is no reason to move it out of there.
>> It should be enough just to define ret_payload here as:
>>
>> /* Use regs array in case ret_payload is NULL */
>> if (!ret_payload)
>> ret_payload = regs;
>>
>>
>> Or is there any other reason why you have moved code from here?
>> In else part regs are defined as pt_regs that's why that regs won't be
>> used anyway. And reg_payload is checked already.
>
> I moved the code, because otherwise, the life scope of regs would be
> limited to the first branch of the 'if' statement. As a consequence,
> outside 'if', reg_payload would point to the already invalid location of
> the regs variable in the return statement. Do you agree?
Ok. I see it was purely for handling
return (ret_payload) ? ret_payload[0] : 0;
Just simply call return within CONFIG_ZYNQMP_IPI code and that should be
it.
It really doesn't look good that you have
#if defined(CONFIG_ZYNQMP_IPI)
...
#endif
..
if
#if defined(CONFIG_ZYNQMP_IPI)
...
#else
...
#endif
else
...
>
> I also realised, that in the return statement, if ret_payload was NULL,
> a success status (0) was returned. Is it intended? After all, even e.g.
> a setter call to pmu-firmware (not interested in the returned payload),
> could fail. The returned value would be misleading then.
That's a little bit different story. If ipi_req fails it should be error
out. But if doesn't fail and user doesn't care about return value you
should return just 0/success.
Definitely adding handling for ipi_req() failure is good to do.
Thanks,
Michal
More information about the U-Boot
mailing list