[PATCH 0/3] alpha: fix floating-point exception state handling
Matt Turner <[email protected]> Mon, 03 Aug 2026 19:40:44 -0400
| Newsgroups | org.kernel.vger.linux-alpha,org.kernel.vger.linux-kernel,org.kernel.vger.linux-sh,org.kernel.vger.sparclinux,org.kernel.vger.stable,org.ozlabs.lists.linuxppc-dev |
|---|---|
| Message-ID | <[email protected]> |
Three fixes to floating-point exception handling on Alpha. The first two
are a pair and should be applied and backported together; each commit
message explains why taking one alone is worse than taking neither.
The first fixes ieee_swcr_to_fpcr() setting FPCR_DNOD unconditionally,
which disabled denormal operand traps for every process using the default
FPU settings. Instructions built with the software completion suffix
never reached the kernel emulator, and the hardware silently substituted
zero for denormal operands. This affects anything built with -mieee,
glibc included.
The second stops hardware-fabricated exception bits from reaching user
space. On EV6 and later the hardware writes exception status into the
FPCR before delivering a software completion trap, and those bits can be
wrong for the instruction that trapped. alpha_fp_emul() only wrote the
FPCR back when soft-fp raised something, so whenever it found the
instruction exact the fabricated bits stayed visible to fetestexcept().
The exception summary register is now passed down so the handler can tell
which exceptions the hardware attributed to the trapping instruction.
The third makes the emulation determine tininess after rounding, as the
hardware does. soft-fp had no notion of the distinction and always
determined it before rounding, so an operation that trapped for software
completion could report an underflow the same operation would not report
when it did not trap. The two paths disagreed on the same machine, which
IEEE 754 does not allow. This adds _FP_TININESS_AFTER_ROUNDING to the
shared soft-fp code, as glibc's copy already has, and sets it for Alpha
only. It defaults to zero, so powerpc, sh and sparc are unchanged.
Measured with the glibc testsuite on an UP1500 (EV67), with
CONFIG_MATHEMU=y. Without that option alpha_fp_emul() is not built at
all and roughly 830 math tests fail on their own, so it is a prerequisite
for any of this being reachable.
glibc make check subdirs=math
before 831 failures
after patch 1 48 failures
after patch 2 28 failures
after patch 3 (and glibc fixes) 3 failures
The three that remain are a GCC bug: a long double to float cast on Alpha
is lowered as quad to double to float, but C requires it to round once,
and the intermediate can land on a float halfway point. Two glibc fixes
are being posted separately to libc-alpha.
stdlib/tst-tininess passes, which confirms the hardware determines
tininess after rounding for the results it produces itself.
The shared soft-fp change was compile tested on sparc32, sparc64 and
ppc32 in addition to alpha. Only Alpha was tested at runtime; elsewhere
the new code is unreachable by default.
---
Matt Turner (3):
alpha: fix ieee_swcr_to_fpcr setting FPCR_DNOD unconditionally
alpha: don't leak hardware-fabricated FP exception bits to user space
alpha: determine tininess after rounding in the FP emulation
arch/alpha/include/asm/sfp-machine.h | 4 ++
arch/alpha/include/uapi/asm/fpu.h | 8 +++-
arch/alpha/kernel/traps.c | 6 +--
arch/alpha/math-emu/math.c | 88 +++++++++++++++++++++++++++++++-----
include/math-emu/op-common.h | 23 +++++++++-
include/math-emu/soft-fp.h | 8 ++++
6 files changed, 119 insertions(+), 18 deletions(-)
---
base-commit: 8cdeaa50eae8dad34885515f62559ee83e7e8dda
change-id: 20260803-alpha-fp-exceptions-5c77d9e057a3
Best regards,
--
Matt Turner <[email protected]>