[PATCH] sh4: ensure FPSCR.PR==0 when executing FRCHG [BZ #27543]
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Tue Jan 7 15:10:35 GMT 2025
On 03/01/25 16:23, mirabilos wrote:
> 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>
> ---
> sysdeps/unix/sysv/linux/sh/sh4/getcontext.S | 6 ++++++
> sysdeps/unix/sysv/linux/sh/sh4/setcontext.S | 2 ++
> sysdeps/unix/sysv/linux/sh/sh4/swapcontext.S | 2 ++
> 3 files changed, 10 insertions(+)
The patch does not apply from patchwork, but I could apply it manually.
Besides it, LGTM although I don't have a working hardware to actually
test it (and qemu-sh4-static shows a failure, setjmp/tst-setjmp-fp).
> From b9015c5a51bfbf3b7dc59f52620a8d5ca307c54b Mon Sep 17 00:00:00 2001
> From: mirabilos <tg@debian.org>
> Date: Fri, 3 Jan 2025 18:53:21 +0000
> Subject: [PATCH] sh4: ensure FPSCR.PR==0 when executing FRCHG [BZ #27543]
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
> To: libc-alpha@sourceware.org
> Cc: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>,
> John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
>
> 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>
> ---
> sysdeps/unix/sysv/linux/sh/sh4/getcontext.S | 6 ++++++
> sysdeps/unix/sysv/linux/sh/sh4/setcontext.S | 2 ++
> sysdeps/unix/sysv/linux/sh/sh4/swapcontext.S | 2 ++
> 3 files changed, 10 insertions(+)
>
> diff --git a/sysdeps/unix/sysv/linux/sh/sh4/getcontext.S b/sysdeps/unix/sysv/linux/sh/sh4/getcontext.S
> index 4470e5730b..329a790cd6 100644
> --- a/sysdeps/unix/sysv/linux/sh/sh4/getcontext.S
> +++ b/sysdeps/unix/sysv/linux/sh/sh4/getcontext.S
> @@ -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). */
> diff --git a/sysdeps/unix/sysv/linux/sh/sh4/setcontext.S b/sysdeps/unix/sysv/linux/sh/sh4/setcontext.S
> index a6d1de960c..60aff78256 100644
> --- a/sysdeps/unix/sysv/linux/sh/sh4/setcontext.S
> +++ b/sysdeps/unix/sysv/linux/sh/sh4/setcontext.S
> @@ -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
> diff --git a/sysdeps/unix/sysv/linux/sh/sh4/swapcontext.S b/sysdeps/unix/sysv/linux/sh/sh4/swapcontext.S
> index a299e05b41..6cf88f2b68 100644
> --- a/sysdeps/unix/sysv/linux/sh/sh4/swapcontext.S
> +++ b/sysdeps/unix/sysv/linux/sh/sh4/swapcontext.S
> @@ -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
> --
> 2.30.2
More information about the Libc-alpha
mailing list