]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ASoC: fsl_sai: Fix 32 slots TDM broken by integer shift UB in xMR write
authorChancel Liu <chancel.liu@nxp.com>
Mon, 1 Jun 2026 08:33:27 +0000 (17:33 +0900)
committerMark Brown <broonie@kernel.org>
Thu, 4 Jun 2026 10:16:58 +0000 (11:16 +0100)
When configuring 32 slots TDM (channels == slots == 32), the xMR
(Mask Register) write used:
~0UL - ((1 << min(channels, slots)) - 1)

The literal "1" is a signed 32-bit int. Shifting it by 32 positions is
undefined behaviour which may set this register to 0xFFFFFFFF, masking
all 32 slots.

Use GENMASK_U32() macro instead. For 32 slots this produces a zero mask:
~GENMASK_U32(31, 0) = ~0xFFFFFFFF = 0x00000000
Behaviour for fewer than 32 slots is unchanged.

Fixes: 770f58d7d2c5 ("ASoC: fsl_sai: Support multiple data channel enable bits")
Cc: stable@vger.kernel.org
Signed-off-by: Chancel Liu <chancel.liu@nxp.com>
Reviewed-by: Shengjiu Wang <shengjiu.wang@gmail.com>
Link: https://patch.msgid.link/20260601083327.1535185-1-chancel.liu@oss.nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/fsl/fsl_sai.c

index e364552c1f47e43247eb078212e519e1d81095ba..78e953cd3e9fdad01e686c59552aa85e89ac1d2a 100644 (file)
@@ -793,7 +793,7 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
                                   FSL_SAI_CR4_FSD_MSTR, FSL_SAI_CR4_FSD_MSTR);
 
        regmap_write(sai->regmap, FSL_SAI_xMR(tx),
-                    ~0UL - ((1 << min(channels, slots)) - 1));
+                    ~GENMASK_U32(min(channels, slots) - 1, 0));
 
        return 0;
 }