hppa lazy FPU switching and QEMU bugs
Thor Lancelot Simon <[email protected]> Mon, 3 Aug 2026 22:57:54 -0400
| Newsgroups | gmane.os.netbsd.devel.crypto |
|---|---|
| Message-ID | <[email protected]> |
On Mon, Aug 03, 2026 at 03:59:18PM -0400, Thor Lancelot Simon wrote:
>
> This host manages QEMU guests running the exact same version of NetBSD
> on 14 other emulated architectures. Only hppa blows up like this. I
> suppose some day someone will figure out why.
Actually the problem is not ML-KEM at all nor OpenSSL. It's a bug in QEMU,
an information leak that can swap processes' FP registers!
An analysis generated using Claude:
1. PA-RISC has no integer multiply instruction. GCC emits xmpyu, which
executes in the FPU - verified in generated assembly, and it's true
even for 32-bit unsigned int:
mul32: stws %r26,-16(%sp) ; fldws -16(%sp),%fr22R
xmpyu %fr22R,%fr22L,%fr22
2. NetBSD/hppa uses lazy FPU switching. cpu_switchto (locore.S ~950)
clears the CCR enable bits when switching to an LWP that isn't the
current FP owner, and waits for assist-emulation trap 22 to swap FP state.
3. QEMU defines EXCP_ASSIST_EMU in target/hppa/cpu.h:85 and never raises
it, and never reads CR_CCR in translate.c.
4. So the swap never happens and every LWP shares the physical FP register
file.
I have a few different reproducers. One is a fixed-input X25519 derivation in
the parent, versus a forked child doing nothing but z = z * 6364136223846793005ULL + 1:
idle 1200 derivations 0 wrong
contended 1200 derivations 271 wrong (22.6%)
Working on a simple way to detect this QEMU bug in our kernel and avoid
lazy FPU switching. I won't commit any Claude-generated code, due to our
current policies, so it may take me a little while to ensure I understand
what it proposes and reimplement by hand.
Thor