[PATCH v2] drm/msm/a6xx+: Don't let IB_SIZE overflow
Antonino Maniscalco
antomani103 at gmail.com
Fri Mar 14 22:53:57 UTC 2025
On 3/14/25 10:56 PM, Rob Clark wrote:
> On Fri, Mar 14, 2025 at 2:35 PM Antonino Maniscalco
> <antomani103 at gmail.com> wrote:
>>
>> On 3/14/25 10:08 PM, Rob Clark wrote:
>>> On Fri, Mar 14, 2025 at 1:07 PM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
>>>>
>>>> On 3/15/2025 12:04 AM, Rob Clark wrote:
>>>>> From: Rob Clark <robdclark at chromium.org>
>>>>>
>>>>> IB_SIZE is only b0..b19. Starting with a6xx gen3, additional fields
>>>>> were added above the IB_SIZE. Accidentially setting them can cause
>>>>> badness. Fix this by properly defining the CP_INDIRECT_BUFFER packet
>>>>> and using the generated builder macro to ensure unintended bits are not
>>>>> set.
>>
>> I wonder if we should be returning -EINVAL from the ioctl when a size
>> larger than max is submitted. I say this because we do a 0 check when
>> submitting which this bug allows to bypass therefore putting a 0 sized
>> CP_INDIRECT_BUFFER pkt in the ring.
>> Fw is inconsistent as to how this is treated (should be a NOP but will
>> sometimes hang) and that is very confusing.
>
> tbh, I'm not sure I remember why we check for zero.. at least sqe fw
> explicitly handles this case on newer devices. Maybe it made older
> devices grumpy?
>
The problem occurs when a CP_INDIRECT_BUFFER with size 0 is encountered,
say in BV, when BV is disabled.
But yeah I don't feel strongly about this just wanted to point out that
a check is being bypassed and it does lead to some kind of UB (not sure
what this does across devices).
> But I wanted to avoid hard-coding (potentially) device specific limits
> in the frontend. And decided that userspace is allowed to shoot it's
> own foot if it really wants to.
>
> BR,
> -R
>
>>>>>
>>>>> v2: add missing type attribute for IB_BASE
>>>>>
>>>>> Reported-by: Connor Abbott <cwabbott0 at gmail.com>
>>>>> Fixes: a83366ef19ea ("drm/msm/a6xx: add A640/A650 to gpulist")
>>>>> Signed-off-by: Rob Clark <robdclark at chromium.org>
>>>>> ---
>>>>> Backport notes, prior to commit ae22a94997b8 ("drm/msm: import A2xx-A4xx
>>>>> XML display registers database"), just open code, ie:
>>>>>
>>>>> OUT_RING(ring, submit->cmd[i].size & 0xfffff);
>>>>>
>>>>> Prior to commit af66706accdf ("drm/msm/a6xx: Add skeleton A7xx
>>>>> support"), a7xx_submit() did not exist so that hunk can be dropped.
>>>>>
>>>>> drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 8 ++++----
>>>>> drivers/gpu/drm/msm/registers/adreno/adreno_pm4.xml | 7 +++++++
>>>>> 2 files changed, 11 insertions(+), 4 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>>>>> index d3978cfa3f20..ea52b7d0b212 100644
>>>>> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>>>>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>>>>> @@ -245,10 +245,10 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
>>>>> break;
>>>>> fallthrough;
>>>>> case MSM_SUBMIT_CMD_BUF:
>>>>> - OUT_PKT7(ring, CP_INDIRECT_BUFFER_PFE, 3);
>>>>> + OUT_PKT7(ring, CP_INDIRECT_BUFFER, 3);
>>>>> OUT_RING(ring, lower_32_bits(submit->cmd[i].iova));
>>>>> OUT_RING(ring, upper_32_bits(submit->cmd[i].iova));
>>>>> - OUT_RING(ring, submit->cmd[i].size);
>>>>> + OUT_RING(ring, A5XX_CP_INDIRECT_BUFFER_3_IB_SIZE(submit->cmd[i].size));
>>>>> ibs++;
>>>>> break;
>>>>> }
>>>>> @@ -382,10 +382,10 @@ static void a7xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
>>>>> break;
>>>>> fallthrough;
>>>>> case MSM_SUBMIT_CMD_BUF:
>>>>> - OUT_PKT7(ring, CP_INDIRECT_BUFFER_PFE, 3);
>>>>> + OUT_PKT7(ring, CP_INDIRECT_BUFFER, 3);
>>>>> OUT_RING(ring, lower_32_bits(submit->cmd[i].iova));
>>>>> OUT_RING(ring, upper_32_bits(submit->cmd[i].iova));
>>>>> - OUT_RING(ring, submit->cmd[i].size);
>>>>> + OUT_RING(ring, A5XX_CP_INDIRECT_BUFFER_3_IB_SIZE(submit->cmd[i].size));
>>>>> ibs++;
>>>>> break;
>>>>> }
>>>>> diff --git a/drivers/gpu/drm/msm/registers/adreno/adreno_pm4.xml b/drivers/gpu/drm/msm/registers/adreno/adreno_pm4.xml
>>>>> index 55a35182858c..a71bc6f16cbf 100644
>>>>> --- a/drivers/gpu/drm/msm/registers/adreno/adreno_pm4.xml
>>>>> +++ b/drivers/gpu/drm/msm/registers/adreno/adreno_pm4.xml
>>>>> @@ -2259,5 +2259,12 @@ opcode: CP_LOAD_STATE4 (30) (4 dwords)
>>>>> </reg32>
>>>>> </domain>
>>>>>
>>>>> +<domain name="CP_INDIRECT_BUFFER" width="32" varset="chip" prefix="chip" variants="A5XX-">
>>>>> + <reg64 offset="0" name="IB_BASE" type="address"/>
>>>>> + <reg32 offset="3" name="3">
>>>>
>>>> Why is the offset 3 here? It looks to me that it doesn't match the code
>>>> above.
>>>
>>> oh, bad copy/pasta.. it should be 2 (dword offset)
>>>
>>> BR,
>>> -R
>>>
>>>> -Akhil.
>>>>
>>>>> + <bitfield name="IB_SIZE" low="0" high="19"/>
>>>>> + </reg32>
>>>>> +</domain>
>>>>> +
>>>>> </database>
>>>>>
>>>>
>>
>> Best regards,
>> --
>> Antonino Maniscalco <antomani103 at gmail.com>
Best regards,
--
Antonino Maniscalco <antomani103 at gmail.com>
More information about the Freedreno
mailing list