diff mbox series

hw/arm_sysctl: fix extraxting 31th bit of val

Message ID 20241220103320.83385-1-abelova@astralinux.ru (mailing list archive)
State New
Headers show
Series hw/arm_sysctl: fix extraxting 31th bit of val | expand

Commit Message

Anastasia Belova Dec. 20, 2024, 10:33 a.m. UTC
1 << 31 is casted to uint64_t while bitwise and with val.
So this value may become 0xffffffff80000000 but only
31th "start" bit is required.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Signed-off-by: Anastasia Belova <abelova@astralinux.ru>
---
 hw/misc/arm_sysctl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Philippe Mathieu-Daudé Dec. 20, 2024, 10:44 a.m. UTC | #1
On 20/12/24 11:33, Anastasia Belova wrote:
> 1 << 31 is casted to uint64_t while bitwise and with val.
> So this value may become 0xffffffff80000000 but only
> 31th "start" bit is required.
> 
> Found by Linux Verification Center (linuxtesting.org) with SVACE.
> 
> Signed-off-by: Anastasia Belova <abelova@astralinux.ru>
> ---
>   hw/misc/arm_sysctl.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/misc/arm_sysctl.c b/hw/misc/arm_sysctl.c
> index 69e379fa10..ce8be44b6e 100644
> --- a/hw/misc/arm_sysctl.c
> +++ b/hw/misc/arm_sysctl.c
> @@ -520,7 +520,7 @@ static void arm_sysctl_write(void *opaque, hwaddr offset,
>            * as zero.
>            */
>           s->sys_cfgctrl = val & ~((3 << 18) | (1 << 31));
> -        if (val & (1 << 31)) {
> +        if (val & (1ULL << 31)) {

Alternatively clearer using the bitfield extract() API ...:

            if (extract64(val, 31, 1)) {

>               /* Start bit set -- actually do something */
>               unsigned int dcc = extract32(s->sys_cfgctrl, 26, 4);
>               unsigned int function = extract32(s->sys_cfgctrl, 20, 6);

... which we already use in this file   ^^^^^^^.
diff mbox series

Patch

diff --git a/hw/misc/arm_sysctl.c b/hw/misc/arm_sysctl.c
index 69e379fa10..ce8be44b6e 100644
--- a/hw/misc/arm_sysctl.c
+++ b/hw/misc/arm_sysctl.c
@@ -520,7 +520,7 @@  static void arm_sysctl_write(void *opaque, hwaddr offset,
          * as zero.
          */
         s->sys_cfgctrl = val & ~((3 << 18) | (1 << 31));
-        if (val & (1 << 31)) {
+        if (val & (1ULL << 31)) {
             /* Start bit set -- actually do something */
             unsigned int dcc = extract32(s->sys_cfgctrl, 26, 4);
             unsigned int function = extract32(s->sys_cfgctrl, 20, 6);