alpha: fix FEN fault handling
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 7 Jan 2023 00:59:29 +0000 (00:59 +0000)
committerMatt Turner <mattst88@gmail.com>
Sat, 25 Feb 2023 04:14:22 +0000 (23:14 -0500)
commitd3c51b701b1d3e618c7b158fb976aa648b1ac4ab
treec01aa0701c3eac7a5b4c85fd217dc879863e3e66
parent4da2bd306bffb46109819647b28e8cabae39c941
alpha: fix FEN fault handling

Type 3 instruction fault (FPU insn with FPU disabled) is handled
by quietly enabling FPU and returning.  Which is fine, except that
we need to do that both for fault in userland and in the kernel;
the latter *can* legitimately happen - all it takes is this:

.global _start
_start:
call_pal 0xae
lda $0, 0
ldq $0, 0($0)

- call_pal CLRFEN to clear "FPU enabled" flag and arrange for
a signal delivery (SIGSEGV in this case).

Fixed by moving the handling of type 3 into the common part of
do_entIF(), before we check for kernel vs. user mode.

Incidentally, check for kernel mode is unidiomatic; the normal
way to do that is !user_mode(regs).  The difference is that
the open-coded variant treats any of bits 63..3 of regs->ps being
set as "it's user mode" while the normal approach is to check just
the bit 3.  PS is a 4-bit register and regs->ps always will have
bits 63..4 clear, so the open-code variant here is actually equivalent
to !user_mode(regs).  Harder to follow, though...

Reproducer above will crash any box where CLRFEN is not ignored by
PAL (== any actual hardware, AFAICS; PAL used in qemu doesn't
bother implementing that crap).

Cc: stable@vger.kernel.org # all way back...
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Matt Turner <mattst88@gmail.com>
arch/alpha/kernel/traps.c