head 1.1; access; symbols netbsd-11:1.1.0.2; locks; strict; comment @ * @; 1.1 date 2026.07.09.02.05.45; author riastradh; state Exp; branches 1.1.2.1; next ; commitid Xe3vv8FEcLUo9VMG; 1.1.2.1 date 2026.07.09.02.05.45; author martin; state dead; branches; next 1.1.2.2; commitid UTsqisx2UKr5rhOG; 1.1.2.2 date 2026.07.19.15.57.28; author martin; state Exp; branches; next ; commitid UTsqisx2UKr5rhOG; desc @@ 1.1 log @Verify signal delivery preserves various FPU state. Should also test AVX512 but I'm not sure I have hardware handy to do this right now and qemu doesn't emulate it, as far as I know! TBD. (Plus: there's umpteen different cpuid feature bits to consider, annoyingly, and that means a lot of manual reading to sort through them.) PR kern/60426: Signal handler corrupts AVX (YMM) registers @ text @/* $NetBSD$ */ /*- * Copyright (c) 2026 The NetBSD Foundation, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef TESTS_KERNEL_ARCH_X86_64_SIG_FPU_H #define TESTS_KERNEL_ARCH_X86_64_SIG_FPU_H #include bool x87_supported(void); bool xmm_supported(void); bool ymm_supported(void); bool zmm_supported(void); void trash_x87(void); void trash_xmm(void); void trash_ymm(void); void trash_zmm(void); int test_x87(volatile bool *, const volatile bool *); int test_xmm(volatile bool *, const volatile bool *); int test_ymm(volatile bool *, const volatile bool *); int test_zmm(volatile bool *, const volatile bool *); #endif /* TESTS_KERNEL_ARCH_X86_64_SIG_FPU_H */ @ 1.1.2.1 log @file sig_fpu.h was added on branch netbsd-11 on 2026-07-19 15:57:28 +0000 @ text @d1 49 @ 1.1.2.2 log @Pull up following revision(s) (requested by riastradh in ticket #381): sys/arch/amd64/amd64/machdep.c: revision 1.380 sys/arch/amd64/include/mcontext.h: revision 1.25 sys/arch/amd64/amd64/netbsd32_machdep.c: revision 1.143 distrib/sets/lists/tests/mi: revision 1.1424 sys/arch/x86/include/specialreg.h: revision 1.222 sys/arch/x86/x86/identcpu.c: revision 1.140 sys/arch/i386/include/mcontext.h: revision 1.20 sys/arch/x86/x86/identcpu.c: revision 1.141 tests/kernel/t_signal_and_fpu.c: revision 1.1 tests/kernel/t_signal_and_fpu.c: revision 1.2 tests/kernel/t_signal_and_fpu.c: revision 1.3 sys/arch/x86/include/fpu.h: revision 1.24 sys/arch/x86/include/cpu_extended_state.h: revision 1.20 sys/arch/i386/i386/machdep.c: revision 1.852 distrib/sets/lists/debug/mi: revision 1.516 tests/kernel/Makefile: revision 1.98 tests/kernel/arch/x86/sig_fpu.c: revision 1.1 sys/arch/x86/x86/fpu.c: revision 1.95 tests/kernel/arch/x86/sig_fpu.h: revision 1.1 Verify signal delivery preserves various FPU state. Should also test AVX512 but I'm not sure I have hardware handy to do this right now and qemu doesn't emulate it, as far as I know! TBD. (Plus: there's umpteen different cpuid feature bits to consider, annoyingly, and that means a lot of manual reading to sort through them.) PR kern/60426: Signal handler corrupts AVX (YMM) registers x86: Save and restore all supported extended CPU state on signals. While here, disable Intel AMX, whose state size (>>8 KiB) exceeds MINSIGSTKSZ (8 KiB), until we are ready to safely update the ABI for sigaltstack(2). This isn't a regression: we've never had a release with Intel AMX support. Previously, on signal delivery, we would only save and restore at most what FXSAVE does, which is the x87 and SSE registers that always exist on amd64. To save and restore the upper halves of the YMM or ZMM registers (AVX/AVX2/AVX512), or the AVX512 registers ZMM16..ZMM31, or the enormous AMX state, we need to do more. And we need to do that even if the signal handler doesn't use AVX instructions, because an SSE instruction modifying xmmN (e.g., in a vectorized memcpy) will, as a side effect, zero the high half of ymmN. Fortunately, the x86 architecture has an extensible mechanism for saving and restoring extended CPU state, the XSAVE/XRSTOR instruction family, so we don't need to update this code for every extension -- just handling the generic XSAVE/XRSTOR mechanism will work for a while. When delivering a signal to a thread that has actually made use of these extended registers, we: 1. allocate a separate space on the user's stack for an XSAVE area of whatever size is necessary (as long as it fits in the sigaltstack, if one was provided), and 2. store a pointer to and the length of the separate XSAVE area in an architecturally unused section of the FXSAVE area of the mcontext_t, with the _UC_XSAVE bit set. This way existing applications that have SA_SIGINFO signal handlers and expect to find an FXSAVE area in the mcontext_t with x87 and SSE register content will continue to work, but if the thread has used any state beyond that like AVX registers requiring XSAVE/XRSTOR, on return from signal it can restore everything. Unfortunately, the _size_ that XSAVE needs is variable and might be expanded by architectural extensions, such as Intel AMX. So the minimum stack size to store it all might exceed MINSIGSTKSZ. The current MINSIGSTKSZ is plenty for AVX/AVX2/AVX-512. But before raising MINSIGSTKSZ to support larger XSAVE sizes by adding them to XCR0_FPU, we need to make sure that older binaries built with the old MINSIGSTKSZ continue to work -- of course, they won't be able to use (e.g.) Intel AMX state. To make sure we don't break the ABI accidentally, I've added some __CTASSERTs relating XSAVE_MAX_BYTES, the maximum supported XSAVE area size, and MINSIGSTKSZ, and a panic at boot if the CPU advertises an XSAVE size larger than XSAVE_MAX_BYTES, which would mean either: (a) the CPU's advertised size for various architecturally defined extended CPU state does not match the documentation, or (b) we have inadvertently bitten off more extended state CPU state than we can chew in XCR0_FPU and we have to adjust the ABI and add compatibility for userland programs. Fortunately for getcontext(2), all of the registers in question are caller-saves, so it doesn't need to store any extra state. PR kern/60426: Signal handler corrupts AVX (YMM) registers t_signal_and_fpu: Fix machine-independent double test. Copypasta error! Float and long double tests were fine. PR kern/60426: Signal handler corrupts AVX (YMM) registers x86: Redo boot-time XSAVE area size ABI check. Instead of checking each component's offset+size from size = CPUID[EAX=0x0d,ECX=i].EAX, offset = CPUID[EAX=0x0d,ECX=i].EBX, to make sure it fits in the XSAVE_MAX_BYTES implied by the MINSIGSTKSZ ABI parameter, just check the total _enabled_ XSAVE area size from CPUID[EAX=0x0d,ECX=0].EBX, which is what we use to allocate the XSAVE area in software anyway. The Intel documentation[1] is not very clear on exactly what CPUID[EAX=0x0d,ECX=i] reports for i >= 2, saying `valid bit in the XCR0 register' without distinguishing `supported' from `enabled' bits, and the AMD documentation I skimmed didn't have these leaves in any obvious place. But it seems CPUID[EAX=0xd,ECX=i].EAX/.EBX give the size and offset of the CPU's _supported_ XSAVE features, rather than only those for _enabled_ XSAVE features, so the original panic would have tripped on features we haven't enabled in XCR0_FPU. In any case, better to verify the parameter we use directly for allocating space. [1] Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1: Basic Architecture, Intel, Order Number: 253665-092US, June 2026, Sec. 21.3 `CPUID Leaves', Subsection `CPUID.0DH -- Processor Extended State', Subsubsection `CPUID.0DH.SUB-LEAVES - Sub-leaves', pp. 21-43 -- 21-44. https://web.archive.org/web/20260709150417/https://cdrdv2-public.intel.com/922477/253665-092-sdm-vol-1.pdf PR kern/60426: Signal handler corrupts AVX (YMM) registers @ text @a0 49 /* $NetBSD: sig_fpu.h,v 1.1 2026/07/09 02:05:45 riastradh Exp $ */ /*- * Copyright (c) 2026 The NetBSD Foundation, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef TESTS_KERNEL_ARCH_X86_64_SIG_FPU_H #define TESTS_KERNEL_ARCH_X86_64_SIG_FPU_H #include bool x87_supported(void); bool xmm_supported(void); bool ymm_supported(void); bool zmm_supported(void); void trash_x87(void); void trash_xmm(void); void trash_ymm(void); void trash_zmm(void); int test_x87(volatile bool *, const volatile bool *); int test_xmm(volatile bool *, const volatile bool *); int test_ymm(volatile bool *, const volatile bool *); int test_zmm(volatile bool *, const volatile bool *); #endif /* TESTS_KERNEL_ARCH_X86_64_SIG_FPU_H */ @