[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <5d850276-a872-45fb-9df2-2b72479787be@moroto.mountain>
Date: Mon, 25 Mar 2024 17:25:00 +0300
From: Dan Carpenter <dan.carpenter@...aro.org>
To: Su Hui <suhui@...china.com>
Cc: arnaud.pouliquen@...s.st.com, lgirdwood@...il.com, broonie@...nel.org,
perex@...ex.cz, tiwai@...e.com, nathan@...nel.org,
ndesaulniers@...gle.com, morbo@...gle.com, justinstitt@...gle.com,
alsa-devel@...a-project.org, linux-sound@...r.kernel.org,
linux-kernel@...r.kernel.org, llvm@...ts.linux.dev,
kernel-janitors@...r.kernel.org
Subject: Re: [PATCH] ASoC: sti: uniperif: fix the undefined bitwise shift
behavior problem
On Mon, Mar 25, 2024 at 11:40:33AM +0800, Su Hui wrote:
> Clang static checker(scan-build):
> sound/soc/sti/uniperif_player.c:1115:12: warning:
> The result of the left shift is undefined because the right operand is
> negative [core.UndefinedBinaryOperatorResult]
>
> When UNIPERIF_CONFIG_BACK_STALL_REQ_SHIFT(ip) equals to -1, the result of
> SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(ip) is undefined.
>
> Here are some results of using different compilers.
> 1UL >> -1 1UL << -1
> gcc 10.2.1 0x2 0
> gcc 11.4.0 0 0x8000000000000000
> clang 14.0.0 0x64b8a45d72a0 0x64b8a45d72a0
> clang 17.0.0 0x556c43b0f2a0 0x556c43b0f2a0
>
> Add some macros to ensure that when right opreand is negative or other
> invalid values, the results of bitwise shift is zero.
>
> Fixes: e1ecace6a685 ("ASoC: sti: Add uniperipheral header file")
> Signed-off-by: Su Hui <suhui@...china.com>
> ---
> sound/soc/sti/uniperif.h | 17 ++++++++++++++---
> 1 file changed, 14 insertions(+), 3 deletions(-)
>
> diff --git a/sound/soc/sti/uniperif.h b/sound/soc/sti/uniperif.h
> index 2a5de328501c..1cbff01fbff0 100644
> --- a/sound/soc/sti/uniperif.h
> +++ b/sound/soc/sti/uniperif.h
> @@ -12,17 +12,28 @@
>
> #include <sound/dmaengine_pcm.h>
>
> +#define SR_SHIFT(a, b) ({unsigned long __a = (a); \
> + unsigned int __b = (b); \
> + __b < BITS_PER_LONG ? \
> + __a >> __b : 0; })
The code definitely looks buggy, but how do you know your solution is
correct without testing it?
I don't like this solution at all. This is basically a really
complicated way of writing "if (b != -1)". Instead of checking for -1,
the better solution is to just stop passing -1. If you review that
file, every time it uses "-1" that's either dead code or a bug...
sound/soc/sti/uniperif.h
132 #define UNIPERIF_ITS_UNDERFLOW_REC_DONE_SHIFT(ip) \
133 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 12)
^^^^
This is dead code
134 #define UNIPERIF_ITS_UNDERFLOW_REC_DONE_MASK(ip) \
135 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
because the version is checked here.
136 0 : (BIT(UNIPERIF_ITS_UNDERFLOW_REC_DONE_SHIFT(ip))))
Just delete UNIPERIF_ITS_UNDERFLOW_REC_DONE_SHIFT() and use 12 directly.
[ snip ]
988 #define UNIPERIF_BIT_CONTROL_OFFSET(ip) \
989 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 0x004c)
^^^
Negative offsets seem like a bug.
990 #define GET_UNIPERIF_BIT_CONTROL(ip) \
991 readl_relaxed(ip->base + UNIPERIF_BIT_CONTROL_OFFSET(ip))
regards,
dan carpenter
Powered by blists - more mailing lists