Re: [PATCH 6.18 regression fix] dma-mapping: Fix DMA_BIT_MASK() macro being broken

From: Nathan Chancellor

Date: Sun Dec 07 2025 - 22:25:49 EST


On Sun, Dec 07, 2025 at 07:47:56PM +0100, Hans de Goede wrote:
> After commit a50f7456f853 ("dma-mapping: Allow use of DMA_BIT_MASK(64) in
> global scope"), the DMA_BIT_MASK() macro is broken when passed non trivial
> statements for the value of 'n'. This is caused by the new version missing
> parenthesis around 'n' when evaluating 'n'.
>
> One example of this breakage is the IPU6 driver now crashing due to
> it getting DMA-addresses with address bit 32 set even though it has
> tried to set a 32 bit DMA mask.
>
> The IPU6 CSI2 engine has a DMA mask of either 31 or 32 bits depending
> on if it is in secure mode or not and it sets this masks like this:
>
> mmu_info->aperture_end =
> (dma_addr_t)DMA_BIT_MASK(isp->secure_mode ?
> IPU6_MMU_ADDR_BITS :
> IPU6_MMU_ADDR_BITS_NON_SECURE);
>
> So the 'n' argument here is "isp->secure_mode ? IPU6_MMU_ADDR_BITS :
> IPU6_MMU_ADDR_BITS_NON_SECURE" which gets expanded into:
>
> isp->secure_mode ? IPU6_MMU_ADDR_BITS : IPU6_MMU_ADDR_BITS_NON_SECURE - 1
>
> With the -1 only being applied in the non secure case, causing
> the secure mode mask to be one 1 bit too large.
>
> Fixes: a50f7456f853 ("dma-mapping: Allow use of DMA_BIT_MASK(64) in global scope")
> Cc: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx>
> Cc: James Clark <james.clark@xxxxxxxxxx>
> Cc: Nathan Chancellor <nathan@xxxxxxxxxx>
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Hans de Goede <johannes.goede@xxxxxxxxxxxxxxxx>

Yeah, the parentheses definitely should have been kept.

Reviewed-by: Nathan Chancellor <nathan@xxxxxxxxxx>

> ---
> include/linux/dma-mapping.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
> index 2ceda49c609f..aa36a0d1d9df 100644
> --- a/include/linux/dma-mapping.h
> +++ b/include/linux/dma-mapping.h
> @@ -90,7 +90,7 @@
> */
> #define DMA_MAPPING_ERROR (~(dma_addr_t)0)
>
> -#define DMA_BIT_MASK(n) GENMASK_ULL(n - 1, 0)
> +#define DMA_BIT_MASK(n) GENMASK_ULL((n) - 1, 0)
>
> struct dma_iova_state {
> dma_addr_t addr;
> --
> 2.52.0
>