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.

Reviewed-by: Kent Russell <kent.russell@amd.com>
Signed-off-by: David Francis <David.Francis@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 4f18c56630383c14bfc6b2d65f88f2f895d2121a)
Cc: stable@vger.kernel.org
This commit is contained in:
David Francis 2026-08-05 09:51:35 -04:00 committed by Alex Deucher
parent 04de4007d3
commit c883d0a132
4 changed files with 4 additions and 4 deletions

View File

@ -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 =

View File

@ -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 =

View File

@ -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 =

View File

@ -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 =