Words are stored in big endian in the guest memory for armeb.
Commit 7f4f0d9ea870 ("linux-user/arm: Implement __kernel_cmpxchg with
host atomics") switched to use qatomic_cmpxchg() to swap a word with the
memory content, but missed to endianess-swap the oldval and newval
values when emulating an armeb CPU.
The bug can be verified with qemu >= v7.2 on any little-endian host,
when starting the armeb binary of the upx program, which just hangs
without this patch.
Signed-off-by: Helge Deller <deller@gmx.de>
Cc: Richard Henderson <richard.henderson@linaro.org>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-stable@nongnu.org
Reported-by: "Markus F.X.J. Oberhumer" <markus@oberhumer.com>
Reported-by: John Reiser <jreiser@BitWagon.com>
Closes: https://github.com/upx/upx/issues/687
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
index a992423257..ff0bff7c63 100644
--- a/linux-user/arm/cpu_loop.c
+++ b/linux-user/arm/cpu_loop.c
@@ -117,8 +117,8 @@ static void arm_kernel_cmpxchg32_helper(CPUARMState *env)
{
uint32_t oldval, newval, val, addr, cpsr, *host_addr;
- oldval = env->regs[0];
- newval = env->regs[1];
+ oldval = tswap32(env->regs[0]);
+ newval = tswap32(env->regs[1]);
addr = env->regs[2];
mmap_lock();
On 27/7/23 23:19, Helge Deller wrote:
> Words are stored in big endian in the guest memory for armeb.
>
> Commit 7f4f0d9ea870 ("linux-user/arm: Implement __kernel_cmpxchg with
> host atomics") switched to use qatomic_cmpxchg() to swap a word with the
> memory content, but missed to endianess-swap the oldval and newval
> values when emulating an armeb CPU.
>
> The bug can be verified with qemu >= v7.2 on any little-endian host,
> when starting the armeb binary of the upx program, which just hangs
> without this patch.
>
> Signed-off-by: Helge Deller <deller@gmx.de>
> Cc: Richard Henderson <richard.henderson@linaro.org>
> Cc: Peter Maydell <peter.maydell@linaro.org>
> Cc: qemu-stable@nongnu.org
> Reported-by: "Markus F.X.J. Oberhumer" <markus@oberhumer.com>
> Reported-by: John Reiser <jreiser@BitWagon.com>
> Closes: https://github.com/upx/upx/issues/687
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
31.07.2023 12:26, Philippe Mathieu-Daudé wrote: > On 27/7/23 23:19, Helge Deller wrote: >> Words are stored in big endian in the guest memory for armeb. .. > Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> There was a v3 of this patch already, fwiw. /mjt
On 7/27/23 14:19, Helge Deller wrote:
> Words are stored in big endian in the guest memory for armeb.
>
> Commit 7f4f0d9ea870 ("linux-user/arm: Implement __kernel_cmpxchg with
> host atomics") switched to use qatomic_cmpxchg() to swap a word with the
> memory content, but missed to endianess-swap the oldval and newval
> values when emulating an armeb CPU.
>
> The bug can be verified with qemu >= v7.2 on any little-endian host,
> when starting the armeb binary of the upx program, which just hangs
> without this patch.
>
> Signed-off-by: Helge Deller <deller@gmx.de>
> Cc: Richard Henderson <richard.henderson@linaro.org>
> Cc: Peter Maydell <peter.maydell@linaro.org>
> Cc: qemu-stable@nongnu.org
> Reported-by: "Markus F.X.J. Oberhumer" <markus@oberhumer.com>
> Reported-by: John Reiser <jreiser@BitWagon.com>
> Closes: https://github.com/upx/upx/issues/687
>
> diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
> index a992423257..ff0bff7c63 100644
> --- a/linux-user/arm/cpu_loop.c
> +++ b/linux-user/arm/cpu_loop.c
> @@ -117,8 +117,8 @@ static void arm_kernel_cmpxchg32_helper(CPUARMState *env)
> {
> uint32_t oldval, newval, val, addr, cpsr, *host_addr;
>
> - oldval = env->regs[0];
> - newval = env->regs[1];
> + oldval = tswap32(env->regs[0]);
> + newval = tswap32(env->regs[1]);
> addr = env->regs[2];
There's a similar bug with arm_kernel_cmpxchg64_helper just below, but
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
as far as this goes.
r~
© 2016 - 2025 Red Hat, Inc.