qemu/target/sparc
Peter Maydell 246ff44295 linux-user/sparc: Correct sparc64_get/set_context() FPU handling
The handling of the FPU state in sparc64_get_context() and
sparc64_set_context() is not the same as what the kernel actually
does: we unconditionally read and write the FP registers and the
FSR, GSR and FPRS, but the kernel logic is more complicated:
 * in get_context the kernel has code for saving FPU registers,
   but it is hidden inside an "if (fenab) condition and the
   fenab flag is always set to 0 (inside an "#if 1" which has
   been in the kernel for over 15 years). So the effect is that
   the FPU state part is always written as zeroes.
 * in set_context the kernel looks at the fenab field in the
   structure from the guest, and only restores the state if
   it is set; it also looks at the structure's FPRS to see
   whether either the upper or lower or both halves of the
   register file have valid data.

Bring our implementations into line with the kernel:
 * in get_context:
    - clear the entire target_ucontext at the top of the
      function (as the kernel does)
    - then don't write the FPU state, so those fields remain zero
    - this fixes Coverity issue CID 1432305 by deleting the code
      it was complaining about
 * in set_context:
    - check the fenab and the fpsr to decide which parts of
      the FPU data to restore, if any
    - instead of setting the FPU registers by doing two
      32-bit loads and filling in the .upper and .lower parts
      of the CPU_Double union separately, just do a 64-bit
      load of the whole register at once. This fixes Coverity
      issue CID 1432303 because we now access the dregs[] part
      of the mcfpu_fregs union rather than the sregs[] part
      (which is not large enough to actually cover the whole of
      the data, so we were accessing off the end of sregs[])

We change both functions in a single commit to avoid potentially
breaking bisection.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20201106152738.26026-2-peter.maydell@linaro.org>
[lv: fix FPRS_DU loop s/31/32/]
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
2020-12-18 11:23:29 +01:00
..
asi.h Clean up ill-advised or unusual header guards 2019-05-13 08:58:55 +02:00
cc_helper.c sparc tcg cpus: Fix Lesser GPL version number 2020-11-15 16:46:00 +01:00
cpu-param.h tcg: Split out target/arch/cpu-param.h 2019-06-10 07:03:34 -07:00
cpu-qom.h qom: Remove module_obj_name parameter from OBJECT_DECLARE* macros 2020-09-18 14:12:32 -04:00
cpu.c sparc: Check dev->realized at sparc_set_nwindows() 2020-12-15 10:02:07 -05:00
cpu.h linux-user/sparc: Correct sparc64_get/set_context() FPU handling 2020-12-18 11:23:29 +01:00
fop_helper.c sparc tcg cpus: Fix Lesser GPL version number 2020-11-15 16:46:00 +01:00
gdbstub.c sparc tcg cpus: Fix Lesser GPL version number 2020-11-15 16:46:00 +01:00
helper.c sparc tcg cpus: Fix Lesser GPL version number 2020-11-15 16:46:00 +01:00
helper.h target-sparc: implement UA2005 GL register 2017-01-18 22:03:44 +01:00
int32_helper.c sparc tcg cpus: Fix Lesser GPL version number 2020-11-15 16:46:00 +01:00
int64_helper.c sparc tcg cpus: Fix Lesser GPL version number 2020-11-15 16:46:00 +01:00
ldst_helper.c sparc tcg cpus: Fix Lesser GPL version number 2020-11-15 16:46:00 +01:00
machine.c Include hw/boards.h a bit less 2019-08-16 13:31:53 +02:00
meson.build meson: target 2020-08-21 06:30:35 -04:00
mmu_helper.c sparc tcg cpus: Fix Lesser GPL version number 2020-11-15 16:46:00 +01:00
monitor.c hmp: Pass monitor to mon_get_cpu_env() 2020-11-13 12:45:51 +00:00
trace-events trace-events: Shorten file names in comments 2019-03-22 16:18:07 +00:00
trace.h trace: switch position of headers to what Meson requires 2020-08-21 06:18:24 -04:00
translate.c sparc tcg cpus: Fix Lesser GPL version number 2020-11-15 16:46:00 +01:00
vis_helper.c sparc tcg cpus: Fix Lesser GPL version number 2020-11-15 16:46:00 +01:00
win_helper.c sparc tcg cpus: Fix Lesser GPL version number 2020-11-15 16:46:00 +01:00