[PATCH linux dev-5.4] soc: aspeed: xdma: Fix command buffer overrun

Eddie James eajames at linux.ibm.com
Thu Apr 2 03:28:03 AEDT 2020


On 4/1/20 3:40 AM, Joel Stanley wrote:
> On Tue, 31 Mar 2020 at 21:56, Eddie James <eajames at linux.ibm.com> wrote:
>> In the case of an operation requiring two commands, it was possible to
>> copy the second command into the user's memory space, which also
>> prevents the command from completing since the first doesn't trigger an
>> interrupt. Test for this special case and prevent it.
>>
>> Signed-off-by: Eddie James <eajames at linux.ibm.com>
>> ---
>>   drivers/soc/aspeed/aspeed-xdma.c | 7 +++++++
>>   1 file changed, 7 insertions(+)
>>
>> diff --git a/drivers/soc/aspeed/aspeed-xdma.c b/drivers/soc/aspeed/aspeed-xdma.c
>> index 5d97919d38cf..d0a56a5a81ae 100644
>> --- a/drivers/soc/aspeed/aspeed-xdma.c
>> +++ b/drivers/soc/aspeed/aspeed-xdma.c
>> @@ -436,6 +436,13 @@ static void aspeed_xdma_start(struct aspeed_xdma *ctx,
>>
>>          mutex_lock(&ctx->start_lock);
>>
>> +       if ((rc == 2) && (ctx->cmd_idx == (XDMA_NUM_CMDS - 1))) {
> I don't understand what's going on here, so I'm going to explain what
> I read and you can correct me.


Sorry, it was rushed... I have found a cleaner way to do this anyway and 
will send a v2.


>
> rc in this case is the command number? so this operation is attempting
> to queue up the second of our "two commands" you mention in the commit
> message?


rc is the number of commands to send. It can only be 1 or 2. They're 
always queued together because they're processed in one go by the engine.


>
> We're saying if the second command is the last cmd_idx, we reset the
> write pointer back to zero.
>
> We don't reset the pointer back to zero anywhere else in the driver.
> Why do we special case this case?


We do in the reset actually. But we do it here because we have one slot 
left for a single command in the buffer/queue of commands. But since we 
have to send two, we'd better reset to 0 and put both there, instead of 
copying beyond our buffer space...


Thanks,

Eddie


>
>> +               aspeed_xdma_writel(ctx, ctx->chip->regs.bmc_cmdq_readp,
>> +                                  XDMA_BMC_CMDQ_READP_RESET);
>> +               aspeed_xdma_writel(ctx, ctx->chip->regs.bmc_cmdq_writep, 0);
>> +               ctx->cmd_idx = 0;
>> +       }
>> +
>>          memcpy(&ctx->cmdq[ctx->cmd_idx], cmds,
>>                 rc * sizeof(struct aspeed_xdma_cmd));
>>          ctx->cmd_idx = (ctx->cmd_idx + rc) % XDMA_NUM_CMDS;
>> --
>> 2.24.0
>>


More information about the openbmc mailing list