Thread (7 messages) flat view 7 messages, 2 authors, 3d ago

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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help