On Fri, 14 Jul 2023 at 18:26, Peter Maydell <peter.mayd...@linaro.org> wrote:
>
> In CPUSparcState we define the fprs field as uint64_t.  However we
> then refer to it in translate.c via a TCGv_i32 which we set up with
> tcg_global_mem_new_ptr().  This means that on a big-endian host when
> the guest does something to writo te the FPRS register this value
> ends up in the wrong half of the uint64_t, and the QEMU C code that
> refers to env->fprs sees the wrong value.  The effect of this is that
> guest code that enables the FPU crashes with spurious FPU Disabled
> exceptions.  In particular, this is why
>  tests/avocado/machine_sparc64_sun4u.py:Sun4uMachine.test_sparc64_sun4u
> times out on an s390 host.
>
> There are multiple ways we could fix this; since there are actually
> only three bits in the FPRS register and the code in translate.c
> would be a bit painful to convert to dealing with a TCGv_i64, change
> the type of the CPU state struct field to match what translate.c is
> expecting.

> diff --git a/target/sparc/machine.c b/target/sparc/machine.c
> index 44b9e7d75d6..5a8502804a4 100644
> --- a/target/sparc/machine.c
> +++ b/target/sparc/machine.c
> @@ -168,7 +168,8 @@ const VMStateDescription vmstate_sparc_cpu = {
>          VMSTATE_UINT64_ARRAY(env.bgregs, SPARCCPU, 8),
>          VMSTATE_UINT64_ARRAY(env.igregs, SPARCCPU, 8),
>          VMSTATE_UINT64_ARRAY(env.mgregs, SPARCCPU, 8),
> -        VMSTATE_UINT64(env.fprs, SPARCCPU),
> +        VMSTATE_UINT32(env.fprs, SPARCCPU),
> +        VMSTATE_UNUSED(4), /* was unused high half of uint64_t fprs */

Whoops, these two fields are the wrong way around. The on-the-wire
format for migration is always big-endian, so we need to put
the VMSTATE_UNUSED() placeholder before the VMSTATE_UINT32(),
not after it.

thanks
-- PMM

Reply via email to