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
