Re: [PATCH 2/3] alpha: don't leak hardware-fabricated FP exception bits to user space
From: Magnus Lindholm <linmag7@gmail.com>
Date: 2026-08-05 09:34:09
Also in:
linux-alpha, linux-sh, lkml, sparclinux, stable
On Tue, Aug 4, 2026 at 1:40 AM Matt Turner [off-list ref] wrote:
On EV6 and later the hardware records exception status bits in the FPCR before delivering a software completion trap, and those bits can be wrong for the instruction that trapped. Converting a double that is exactly representable as a subnormal float sets FPCR_UNF even though the result is exact, and an underflow trap additionally sets FPCR_INE even when the emulated operation turns out to be exact. alpha_fp_emul() only wrote the FPCR when soft-fp raised an exception, so whenever it determined that the instruction was exact the fabricated bits stayed in the FPCR and were reported to user space by fetestexcept(). Pass the exception summary register down from do_entArith() so the handler can tell which exceptions the hardware attributed to the trapping instruction, and always write the FPCR. Clear the exceptions that the trap reported but that soft-fp did not raise. EXC_SUM reports only the underflow or overflow when the hardware also set INE, so treat INE as a candidate in that case, and treat a trap with no reported exception as a denormal operand trap, for which the hardware can fabricate INE and UNF as well. Bits that software has already confirmed in ieee_state belong to this or an earlier instruction and are never cleared. The imprecise path passes no summary. There the trap was taken somewhere in the trap shadow, so EXC_SUM is not attribution for the instruction being re-executed -- and only EV6, which traps precisely and so never takes that path, has fabricated bits to clear. For the same reason the clearing is guarded by implver(), matching swcr_update_status(). On an UP1500 (EV68) this takes the glibc math testsuite from 831 failures to 28, the remainder being unrelated to exception status. This belongs with the preceding fix to ieee_swcr_to_fpcr(), and should not be backported without it -- nor it without this. That fix stops FPCR_DNOD being set unconditionally, so denormal operand traps start firing again. Those traps very often find an exact result, which is precisely the case where the old code left the FPCR unwritten and the fabricated bits visible. Applied alone it would make spurious exception flags more common, not less. One case cannot be resolved here: an inexact instruction without the software completion suffix never traps, so its INE reaches the FPCR without being recorded anywhere else. Such a bit is indistinguishable from an INE the hardware fabricated for a trapping instruction, and is lost if an underflow or overflow trap with an exact result follows it. The FPCR is the only record of those instructions and it carries no attribution. The bug predates the git history, so there is no commit to reference in a Fixes tag. Cc: stable@vger.kernel.org # 5.15+ Signed-off-by: Matt Turner <mattst88@gmail.com> --- arch/alpha/kernel/traps.c | 6 ++-- arch/alpha/math-emu/math.c | 88 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 80 insertions(+), 14 deletions(-)
Hi, Passing EXC_SUM to the precise emulation path and always writing the corrected FPCR state back looks correct to me. I tested the complete series with CONFIG_MATHEMU=y on the same machine and using the same glibc build. The kernel boots normally, and the glibc math testsuite improves from 48 to 28 failing test programs, with no new failing tests. Tested on Alphaserver ES40. Reviewed-by: Magnus Lindholm linmag7@gmail.com Tested-by: Magnus Lindholm linmag7@gmail.com