]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
sh4: ensure FPSCR.PR==0 when executing FRCHG [BZ #27543]
authormirabilos <tg@debian.org>
Mon, 13 Jan 2025 14:24:37 +0000 (11:24 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Mon, 13 Jan 2025 14:25:23 +0000 (11:25 -0300)
If the bit is not 0, the operations FRCHG and FSCHG are
undefined and cause a trap; qemu now checks for this as
well, so we set it to 0 temporarily and restore the old
value in getcontext afterwards (setcontext/swapcontext
already do so).

From the discussion in the bugreport, this can probably
be optimised in one place but none of the people involved
are SH4 assembly experts, this patch is field-tested, and
it’s not a code path run often. The other question, what
happens if a signal occurs while the bit is temporarily 0,
is also still unsolved, but to fix that a kernel change is
most likely needed; this patch changes a certain trap on
many CPUs for a hard-to-get trap in a signal handler if a
signal is delivered during the few instructions the PR bit
is temporarily set to 0, so it’s not a regression for most
users.

See BZ and https://bugs.launchpad.net/qemu/+bug/1796520 for
related discussion, references and review comments.

Signed-off-by: mirabilos <tg@debian.org>
Reviewed-by: Oleg Endo <olegendo@gcc.gnu.org>
Tested-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
sysdeps/unix/sysv/linux/sh/sh4/getcontext.S
sysdeps/unix/sysv/linux/sh/sh4/setcontext.S
sysdeps/unix/sysv/linux/sh/sh4/swapcontext.S

index 4470e5730b2bca2efbf18ef8da7847f62ba5a34f..329a790cd6f91cef0296fbd6ccaec035fc202738 100644 (file)
@@ -67,6 +67,8 @@ ENTRY(__getcontext)
        add     #(oFPUL+4-124),r0
        sts.l   fpul, @-r0
        sts.l   fpscr, @-r0
+       mov     #0, r6
+       lds     r6, fpscr
        frchg
        fmov.s  fr15, @-r0
        fmov.s  fr14, @-r0
@@ -101,6 +103,10 @@ ENTRY(__getcontext)
        fmov.s  fr2, @-r0
        fmov.s  fr1, @-r0
        fmov.s  fr0, @-r0
+       mov     r4, r0
+       add     #124, r0
+       add     #(oFPSCR-124), r0
+       lds.l   @r0+, fpscr
 #endif /* __SH_FPU_ANY__ */
 
        /* sigprocmask (SIG_BLOCK, NULL, &uc->uc_sigmask).  */
index a6d1de960ce43a6cf31074694685b5cdfff9e47a..60aff782564774ef2bd709b33021101da5e52cf0 100644 (file)
@@ -50,6 +50,8 @@ ENTRY(__setcontext)
 
 .Lsetcontext_restore:
 #ifdef __SH_FPU_ANY__
+       mov     #0, r9
+       lds     r9, fpscr
        mov     r8, r0
        add     #(oFR0),r0
        fmov.s  @r0+, fr0
index a299e05b41451e0c400edae070c4dacb3e61b7f0..6cf88f2b6807eec782c92b8b22e3a41f0cf3526b 100644 (file)
@@ -67,6 +67,8 @@ ENTRY(__swapcontext)
        add     #(oFPUL+4-124),r0
        sts.l   fpul, @-r0
        sts.l   fpscr, @-r0
+       mov     #0, r9
+       lds     r9, fpscr
        frchg
        fmov.s  fr15, @-r0
        fmov.s  fr14, @-r0