AMD General

Reviewed-by: Kent Russell <[email protected]>



> -----Original Message-----
> From: amd-gfx <[email protected]> On Behalf Of David
> Francis
> Sent: August 5, 2026 10:02 AM
> To: [email protected]
> Cc: Deucher, Alexander <[email protected]>; Francis, David
> <[email protected]>
> Subject: [PATCH] drm/amdkfd: Avoid integer underflow with ffs in EOP ring size
> calc
>
> The low 6 bits of cp_hqd_eop_control store the base-2 logarithm
> of the EOP ring size. This was calculated as
>
> ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1
>
> But ffs can in theory return 1 or 0, so this could underflow
> (although in practice the ring buffer size cannot be less than 4096).
>
> Change this to
>
> ffs(q->eop_ring_buffer_size / sizeof(unsigned int) / 4)
>
> using properties of logarithms.
>
> Signed-off-by: David Francis <[email protected]>
> ---
>  drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c   | 2 +-
>  drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c   | 2 +-
>  drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c   | 2 +-
>  drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c | 2 +-
>  4 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
> b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
> index e034da638c07..4f8a8a1a6186 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
> @@ -204,7 +204,7 @@ static void update_mqd(struct mqd_manager *mm, void
> *mqd,
>        * is safe, giving a maximum field value of 0xA.
>        */
>       m->cp_hqd_eop_control = q->eop_ring_buffer_size ? min(0xA,
> -             ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1) : 
> 0;
> +             ffs(q->eop_ring_buffer_size / sizeof(unsigned int) / 4)) : 0;
>       m->cp_hqd_eop_base_addr_lo =
>                       lower_32_bits(q->eop_ring_buffer_address >> 8);
>       m->cp_hqd_eop_base_addr_hi =
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
> b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
> index 350fcbbba4b2..bf015dc5b868 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
> @@ -242,7 +242,7 @@ static void update_mqd(struct mqd_manager *mm, void
> *mqd,
>        * is safe, giving a maximum field value of 0xA.
>        */
>       m->cp_hqd_eop_control = q->eop_ring_buffer_size ? min(0xA,
> -             ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1) : 
> 0;
> +             ffs(q->eop_ring_buffer_size / sizeof(unsigned int) / 4)) : 0;
>       m->cp_hqd_eop_base_addr_lo =
>                       lower_32_bits(q->eop_ring_buffer_address >> 8);
>       m->cp_hqd_eop_base_addr_hi =
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c
> b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c
> index 7c387fa90076..3942d6675268 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c
> @@ -217,7 +217,7 @@ static void update_mqd(struct mqd_manager *mm, void
> *mqd,
>        * is safe, giving a maximum field value of 0xA.
>        */
>       m->cp_hqd_eop_control = q->eop_ring_buffer_size ? min(0xA,
> -             ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1) : 
> 0;
> +             ffs(q->eop_ring_buffer_size / sizeof(unsigned int) / 4)) : 0;
>       m->cp_hqd_eop_base_addr_lo =
>                       lower_32_bits(q->eop_ring_buffer_address >> 8);
>       m->cp_hqd_eop_base_addr_hi =
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c
> b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c
> index 431a940f91f3..08da097f780a 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c
> @@ -295,7 +295,7 @@ static void update_mqd(struct mqd_manager *mm, void
> *mqd,
>        * is safe, giving a maximum field value of 0xA.
>        */
>       m->cp_hqd_eop_control = q->eop_ring_buffer_size ? min(0xA,
> -             ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1) : 
> 0;
> +             ffs(q->eop_ring_buffer_size / sizeof(unsigned int) / 4)) : 0;
>       m->cp_hqd_eop_base_addr_lo =
>                       lower_32_bits(q->eop_ring_buffer_address >> 8);
>       m->cp_hqd_eop_base_addr_hi =
> --
> 2.34.1

Reply via email to