dmaengine: sun6i: bound burst selection before shifting

Message ID 20261021-submit-sun6i-dma-burst-limit-v1-v1-1-41a7a476ef66@gmail.com (mailing list archive)
State New
Headers
Series dmaengine: sun6i: bound burst selection before shifting |

Commit Message

James Hilliard Oct. 21, 2026, 9:06 p.m. UTC
find_burst_size() tests BIT(maxburst) before reducing the client's maximum
to a supported burst length. DesignWare UARTs request a maximum burst of
one quarter of their FIFO size, so a 256-byte FIFO supplies 64. Shifting
an unsigned long by 64 is undefined even on a 64-bit CPU. The fallback
loop can repeat the same invalid shift.

Limit the search to the highest burst represented in the controller's
nonzero capability mask before either shift. Larger client limits still
select the largest supported burst, while smaller limits retain the
existing power-of-two selection and the zero/default case is unchanged.

Fixes: 7178c3586ab4 ("dmaengine: sun6i: Choose appropriate burst length under maxburst")
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
 drivers/dma/sun6i-dma.c | 3 +++
 1 file changed, 3 insertions(+)


---
base-commit: 93f51579e7df248780214094418f205253383cc5
change-id: 20261021-submit-sun6i-dma-burst-limit-v1-47e32971471e

Best regards,
--  
James Hilliard <james.hilliard1@gmail.com>
  

Comments

Frank Li Oct. 22, 2026, 4:26 p.m. UTC | #1
On Wed, Oct 21, 2026 at 03:06:33PM -0600, James Hilliard wrote:
> find_burst_size() tests BIT(maxburst) before reducing the client's maximum
> to a supported burst length. DesignWare UARTs request a maximum burst of
> one quarter of their FIFO size, so a 256-byte FIFO supplies 64. Shifting
> an unsigned long by 64 is undefined even on a 64-bit CPU. The fallback
> loop can repeat the same invalid shift.
>
> Limit the search to the highest burst represented in the controller's
> nonzero capability mask before either shift. Larger client limits still
> select the largest supported burst, while smaller limits retain the
> existing power-of-two selection and the zero/default case is unchanged.
>
> Fixes: 7178c3586ab4 ("dmaengine: sun6i: Choose appropriate burst length under maxburst")
> Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/dma/sun6i-dma.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index 7704b016aed8..a8b12262b3c3 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -590,6 +590,9 @@ static u32 find_burst_size(const u32 burst_lengths, u32 maxburst)
>  	if (!maxburst)
>  		return 1;
>
> +	/* maxburst is a transfer limit, not necessarily a valid bit index. */
> +	maxburst = min_t(u32, maxburst, fls(burst_lengths) - 1);
> +
>  	if (BIT(maxburst) & burst_lengths)
>  		return maxburst;
>
>
> ---
> base-commit: 93f51579e7df248780214094418f205253383cc5
> change-id: 20261021-submit-sun6i-dma-burst-limit-v1-47e32971471e
>
> Best regards,
> --
> James Hilliard <james.hilliard1@gmail.com>
>
  

Patch

diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 7704b016aed8..a8b12262b3c3 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -590,6 +590,9 @@  static u32 find_burst_size(const u32 burst_lengths, u32 maxburst)
 	if (!maxburst)
 		return 1;
 
+	/* maxburst is a transfer limit, not necessarily a valid bit index. */
+	maxburst = min_t(u32, maxburst, fls(burst_lengths) - 1);
+
 	if (BIT(maxburst) & burst_lengths)
 		return maxburst;