NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/60539 (XSAVE changes break ucontext userspace API)



The following reply was made to PR kern/60539; it has been noted by GNATS.

From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
To: Robert Elz <kre%munnari.OZ.AU@localhost>
Cc: gnats-bugs%netbsd.org@localhost, lib-bug-people%netbsd.org@localhost, netbsd-bugs%netbsd.org@localhost
Subject: Re: kern/60539 (XSAVE changes break ucontext userspace API)
Date: Thu, 6 Aug 2026 14:41:22 +0000

 > Date: Thu, 06 Aug 2026 18:10:09 +0700
 > From: Robert Elz <kre%munnari.OZ.AU@localhost>
 > 
 >     Date:        Thu, 6 Aug 2026 02:47:23 +0000
 >     From:        Taylor R Campbell <riastradh%NetBSD.org@localhost>
 >     Message-ID:  <20260806024725.4385484D7C%mail.netbsd.org@localhost>
 > 
 >   | I think such applications are likely to be inherently problematic.  If
 >   | you're doing value substitution in an FPU trap handler, and some
 >   | AVX512 instruction operating on a 512-bit ZMM vector register traps,
 > 
 > And if you were doing software emulation of the AVX512 instructions,
 > wouldn't the trap handler need to be able to access the (emulated)
 > registers ?
 
 Yes, in that case you would absolutely need to know about the new
 XSAVE pointer in mcontext_t:
 
 static void
 handle_sigfpe(int signo, siginfo_t *si, void *ctx)
 {
 	ucontext_t *uc = ctx;
 	mcontext_t *mc = &uc->uc_mcontext;
 	struct xsave_header *xsh =
 	    (struct xsave_header *)mc->__fpregs.__xsaveptr;
 	size_t xslen = (size_t)mc->__fpregs.__xsavelen;
 
 	... if (xs->xsh_xstate_bv & XCR0_YMM_Hi128) ...
 }
 
 The hypothetical I was considering is a handler previously written for
 x87/SSE that, say, replaces all double-precision subnormal inputs and
 results by zero:
 
 static void
 handle_sigfpe(int signo, siginfo_t *si, void *ctx)
 {
 	ucontext_t *uc = ctx;
 	mcontext_t *mc = &uc->uc_mcontext;
 	struct fxsave *fx = (struct fxsave *)&mc->__fpregs.__fxsave;
 
 	for (i = 0; i < 16; i++) {
 		if (issubnormal(fx->fx_xmm[i].dbl[0]))
 			fx->fx_xmm[i].dbl[0] = 0;
 		if (issubnormal(fx->fx_xmm[i].dbl[1]))
 			fx->fx_xmm[i].dbl[1] = 0;
 	}
 	/* ditto x87 registers */
 }
 
 _Reading_ the FXSAVE state will continue to work, but in a process
 that uses AVX instructions -- at least, if the signal is delivered any
 time between the first AVX instruction and VZEROUPPER -- _writing_
 back changes to the FXSAVE state will be dropped.
 
 But also -- aside from the obvious problems this signal handler has
 like not catching any results that have already been written to memory
 and not making sense when the registers are used for anything other
 than a pair of doubles quantities -- this signal handler is unaware of
 the upper parts of the AVX/AVX512 registers ymmN/zmmN whose lower 128
 bits alias xmmN, so it will only convert the low 128 bits of each one.
 
 So I'm struggling to imagine a plausible scenario where the change
 disabling writeback of the ucontext_t FXSAVE area in the presence of
 AVX instructions will actually break something that isn't already
 profoundly broken.
 
 In other words, I think it wasn't necessary of me to expand the scope
 of the reported PR from `x86 mcontext.h API broke requiring you to
 insert a single & in existing programs' (so if we pull up the XSAVE
 changes to 9 and 10, the mcontext.h part should perhaps be under
 #ifdef _KERNEL) to `ABI change could have broken existing compiled
 programs' because the only ones it could have broken must have already
 been broken.
 



Home | Main Index | Thread Index | Old Index