* [PATCH] x86/build/64: Prevent native builds from generating SSE/AVX code
@ 2026-10-25 17:43 Antoni Kuczyński
2026-10-25 17:55 ` Antoni Kuczyński
2026-10-25 19:44 ` Nathan Chancellor
0 siblings, 2 replies; 5+ messages in thread
From: Antoni Kuczyński @ 2026-10-25 17:43 UTC (permalink / raw)
To: antoni.kucz, x86, linux-kernel
With CONFIG_X86_NATIVE_CPU=y, GCC is invoked with -march=native after
the -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -mno-sse4a flags
that keep FP/SIMD code out of the kernel. The GCC driver expands
-march=native into an explicit list of ISA options for the build host
(e.g. "-march=ivybridge ... -msse4.2 -mavx ..."), and because these come
later on the command line they override the earlier -mno-* flags.
As a result, on any build host with AVX the compiler is free to use
SSE/AVX registers throughout the kernel, for instance to zero or copy
structures. A trivial reproducer:
struct s { long a, b, c, d; };
void f(struct s *p) { struct s z = {0}; *p = z; }
$ gcc -mno-sse -mno-sse2 -mno-avx -march=native -Os -c t.c
vpxor %xmm0,%xmm0,%xmm0
vmovdqu %ymm0,(%rdi)
On an Ivy Bridge machine (i5-3317U, GCC 14.2) a v7.3 kernel built this
way resets immediately after the bootloader hands over control. Booting
the same image in QEMU with "-d int,cpu_reset -no-reboot" shows:
v=06 (#UD) IP=0010:000000000125e47b
v=0d (#GP) -> v=08 (#DF) -> Triple fault
__pi_startup_64_load_idt+0xb:
c5 f9 ef c0 vpxor %xmm0,%xmm0,%xmm0
The startup code executes an AVX instruction before CR4.OSXSAVE/XCR0
are set up and before an IDT is installed, so the #UD escalates to a
triple fault. Even past early boot, compiler-generated SIMD code would
silently clobber user space FPU state, since the kernel does not save
it on kernel entry outside of kernel_fpu_begin()/kernel_fpu_end().
Re-apply the -mno-* flags after -march=native, the same way EGPR use
is already suppressed for native builds.
Fixes: ea1dcca1de12 ("x86/kbuild/64: Add the CONFIG_X86_NATIVE_CPU option to locally optimize the kernel with '-march=native'")
Cc: stable@vger.kernel.org
Signed-off-by: Antoni Kuczyński <antoni.kucz@gmail.com>
---
Notes:
Tested: v7.3 + this patch, CONFIG_X86_NATIVE_CPU=y, GCC 14.2.0 (Debian),
boots on i5-3317U. arch/x86/boot/startup/gdt_idt.o contains no xmm/ymm
instructions after the change (previously 2).
arch/x86/Makefile | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index b7e08519b8c1..2c0575fd7bbc 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -161,6 +161,9 @@ else
ifdef CONFIG_X86_NATIVE_CPU
KBUILD_CFLAGS += -march=native
+ # -march=native expands to explicit -msse/-mavx/... flags that
+ # override the earlier -mno-* ones; disable FP/SIMD code again.
+ KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -mno-sse4a
# Prevent the compiler from generating EGPR use. The kernel is
# not yet prepared for general in-kernel use.
KBUILD_CFLAGS += $(call cc-option,-mno-apx-features=egpr)
--
2.47.3
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] x86/build/64: Prevent native builds from generating SSE/AVX code 2026-10-25 17:43 [PATCH] x86/build/64: Prevent native builds from generating SSE/AVX code Antoni Kuczyński @ 2026-10-25 17:55 ` Antoni Kuczyński 2026-10-25 19:44 ` Nathan Chancellor 1 sibling, 0 replies; 5+ messages in thread From: Antoni Kuczyński @ 2026-10-25 17:55 UTC (permalink / raw) To: antoni.kucz, x86, linux-kernel Cc: Nathan Chancellor, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, H. Peter Anvin Adding Nathan, who reviewed the related EGPR fix for native builds (commit 63edf5a009ae), and the x86 maintainers explicitly - sorry, the Cc list got dropped when sending. Patch: https://lore.kernel.org/all/20261025174336.8857-1-antoni.kucz@gmail.com/ Thanks, Antoni ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] x86/build/64: Prevent native builds from generating SSE/AVX code 2026-10-25 17:43 [PATCH] x86/build/64: Prevent native builds from generating SSE/AVX code Antoni Kuczyński 2026-10-25 17:55 ` Antoni Kuczyński @ 2026-10-25 19:44 ` Nathan Chancellor 2026-10-25 20:07 ` Antoni Kuczyński 1 sibling, 1 reply; 5+ messages in thread From: Nathan Chancellor @ 2026-10-25 19:44 UTC (permalink / raw) To: Antoni Kuczyński; +Cc: x86, linux-kernel Hi Antoni, On Sun, Oct 25, 2026 at 06:43:35PM +0100, Antoni Kuczyński wrote: > With CONFIG_X86_NATIVE_CPU=y, GCC is invoked with -march=native after > the -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -mno-sse4a flags > that keep FP/SIMD code out of the kernel. The GCC driver expands > -march=native into an explicit list of ISA options for the build host > (e.g. "-march=ivybridge ... -msse4.2 -mavx ..."), and because these come > later on the command line they override the earlier -mno-* flags. > > As a result, on any build host with AVX the compiler is free to use > SSE/AVX registers throughout the kernel, for instance to zero or copy > structures. A trivial reproducer: > > struct s { long a, b, c, d; }; > void f(struct s *p) { struct s z = {0}; *p = z; } > > $ gcc -mno-sse -mno-sse2 -mno-avx -march=native -Os -c t.c > vpxor %xmm0,%xmm0,%xmm0 > vmovdqu %ymm0,(%rdi) > > On an Ivy Bridge machine (i5-3317U, GCC 14.2) a v7.3 kernel built this > way resets immediately after the bootloader hands over control. Booting > the same image in QEMU with "-d int,cpu_reset -no-reboot" shows: > > v=06 (#UD) IP=0010:000000000125e47b > v=0d (#GP) -> v=08 (#DF) -> Triple fault > > __pi_startup_64_load_idt+0xb: > c5 f9 ef c0 vpxor %xmm0,%xmm0,%xmm0 > > The startup code executes an AVX instruction before CR4.OSXSAVE/XCR0 > are set up and before an IDT is installed, so the #UD escalates to a > triple fault. Even past early boot, compiler-generated SIMD code would > silently clobber user space FPU state, since the kernel does not save > it on kernel entry outside of kernel_fpu_begin()/kernel_fpu_end(). > > Re-apply the -mno-* flags after -march=native, the same way EGPR use > is already suppressed for native builds. > > Fixes: ea1dcca1de12 ("x86/kbuild/64: Add the CONFIG_X86_NATIVE_CPU option to locally optimize the kernel with '-march=native'") This option has been in the kernel for quite some time and I am sure people are using it. I wonder why this has not come up sooner. Just unlucky timing or configuration? > Cc: stable@vger.kernel.org > Signed-off-by: Antoni Kuczyński <antoni.kucz@gmail.com> > --- > > Notes: > Tested: v7.3 + this patch, CONFIG_X86_NATIVE_CPU=y, GCC 14.2.0 (Debian), > boots on i5-3317U. arch/x86/boot/startup/gdt_idt.o contains no xmm/ymm > instructions after the change (previously 2). > > arch/x86/Makefile | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/arch/x86/Makefile b/arch/x86/Makefile > index b7e08519b8c1..2c0575fd7bbc 100644 > --- a/arch/x86/Makefile > +++ b/arch/x86/Makefile > @@ -161,6 +161,9 @@ else > > ifdef CONFIG_X86_NATIVE_CPU > KBUILD_CFLAGS += -march=native > + # -march=native expands to explicit -msse/-mavx/... flags that > + # override the earlier -mno-* ones; disable FP/SIMD code again. > + KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -mno-sse4a Maintaining two copies of these flags (and having them appear in the command line twice) seems objectively worse than just adding an extra 'ifdef CONFIG_X86_64' and moving the block up so that this happens in the naturally expected order? diff --git a/arch/x86/Makefile b/arch/x86/Makefile index b7e08519b8c1..c18f660f6dc8 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -66,6 +66,21 @@ export REALMODE_CFLAGS # e.g.: obj-y += foo_$(BITS).o export BITS +ifdef CONFIG_X86_64 +ifdef CONFIG_X86_NATIVE_CPU +KBUILD_CFLAGS += -march=native +# Prevent the compiler from generating EGPR use. The kernel is +# not yet prepared for general in-kernel use. +KBUILD_CFLAGS += $(call cc-option,-mno-apx-features=egpr) + +# generate_rust_target.rs handles Rust APX gating. +KBUILD_RUSTFLAGS += -Ctarget-cpu=native +else +KBUILD_CFLAGS += -march=x86-64 -mtune=generic +KBUILD_RUSTFLAGS += -Ctarget-cpu=x86-64 -Ztune-cpu=generic +endif +endif + # # Prevent GCC from generating any FP code by mistake. # @@ -73,6 +88,8 @@ export BITS # # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53383 # +# and after -march=native. +# KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -mno-sse4a KBUILD_RUSTFLAGS += --target=$(objtree)/scripts/target.json KBUILD_RUSTFLAGS += -Ctarget-feature=-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2 @@ -159,19 +176,6 @@ else # Use -mskip-rax-setup if supported. KBUILD_CFLAGS += -mskip-rax-setup -ifdef CONFIG_X86_NATIVE_CPU - KBUILD_CFLAGS += -march=native - # Prevent the compiler from generating EGPR use. The kernel is - # not yet prepared for general in-kernel use. - KBUILD_CFLAGS += $(call cc-option,-mno-apx-features=egpr) - - # generate_rust_target.rs handles Rust APX gating. - KBUILD_RUSTFLAGS += -Ctarget-cpu=native -else - KBUILD_CFLAGS += -march=x86-64 -mtune=generic - KBUILD_RUSTFLAGS += -Ctarget-cpu=x86-64 -Ztune-cpu=generic -endif - KBUILD_CFLAGS += -mno-red-zone KBUILD_CFLAGS += -mcmodel=kernel KBUILD_RUSTFLAGS += -Cno-redzone=y -- Cheers, Nathan ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] x86/build/64: Prevent native builds from generating SSE/AVX code 2026-10-25 19:44 ` Nathan Chancellor @ 2026-10-25 20:07 ` Antoni Kuczyński 2026-10-25 20:20 ` Nathan Chancellor 0 siblings, 1 reply; 5+ messages in thread From: Antoni Kuczyński @ 2026-10-25 20:07 UTC (permalink / raw) To: nathan Cc: x86, linux-kernel, Antoni Kuczyński, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, H. Peter Anvin Hi Nathan, On Sun, Oct 25, 2026 at 12:44:11PM -0700, Nathan Chancellor wrote: > This option has been in the kernel for quite some time and I am sure > people are using it. I wonder why this has not come up sooner. Just > unlucky timing or configuration? Configuration, on my side, sorry for the noise. Following up on your question I found that "gcc" in my PATH was the icecc (icecream 1.4.0) wrapper. To be able to distribute the compilation, icecc replaces -march=native with an explicit list of options for the local CPU: /usr/bin/gcc -mno-sse -mno-avx -Os -march=ivybridge -mmmx -mpopcnt -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mavx ... so the expanded -msse/-mavx come after the kernel's -mno-* flags and win. Plain GCC 14.2 does not have this problem: the reproducer from the changelog built with /usr/bin/gcc-14 emits no SIMD instructions, as explicit -mno-* options take precedence over what -march=native enables. So the changelog's explanation and the Fixes:/stable tags are wrong, please drop this patch. I will report the issue to icecream instead. > Maintaining two copies of these flags (and having them appear in the > command line twice) seems objectively worse than just adding an extra > 'ifdef CONFIG_X86_64' and moving the block up so that this happens in > the naturally expected order? Agreed, and FWIW your diff on top of current master also fixes the icecc build here: -march=native now comes before the -mno-* flags and arch/x86/boot/startup/gdt_idt.o contains no SIMD instructions. If you think that ordering is worth having on its own merits, I am happy to send it as a cleanup without Fixes:/stable, but I understand if it is not worth the churn for an icecc-only problem. Thanks for the review, Antoni ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] x86/build/64: Prevent native builds from generating SSE/AVX code 2026-10-25 20:07 ` Antoni Kuczyński @ 2026-10-25 20:20 ` Nathan Chancellor 0 siblings, 0 replies; 5+ messages in thread From: Nathan Chancellor @ 2026-10-25 20:20 UTC (permalink / raw) To: Antoni Kuczyński Cc: x86, linux-kernel, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, H. Peter Anvin On Sun, Oct 25, 2026 at 09:07:35PM +0100, Antoni Kuczyński wrote: > On Sun, Oct 25, 2026 at 12:44:11PM -0700, Nathan Chancellor wrote: > > This option has been in the kernel for quite some time and I am sure > > people are using it. I wonder why this has not come up sooner. Just > > unlucky timing or configuration? > > Configuration, on my side, sorry for the noise. Following up on your > question I found that "gcc" in my PATH was the icecc (icecream 1.4.0) > wrapper. To be able to distribute the compilation, icecc replaces > -march=native with an explicit list of options for the local CPU: > > /usr/bin/gcc -mno-sse -mno-avx -Os -march=ivybridge -mmmx -mpopcnt > -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mavx ... > > so the expanded -msse/-mavx come after the kernel's -mno-* flags and > win. Plain GCC 14.2 does not have this problem: the reproducer from > the changelog built with /usr/bin/gcc-14 emits no SIMD instructions, > as explicit -mno-* options take precedence over what -march=native > enables. > > So the changelog's explanation and the Fixes:/stable tags are wrong, > please drop this patch. I will report the issue to icecream instead. Ah yeah, that makes a lot more sense. I guess the easiest solution is probably something like this patch internally where the expanded value of '-march=native' is moved to the front of the GCC command so that any overrides can happen naturally. > > Maintaining two copies of these flags (and having them appear in the > > command line twice) seems objectively worse than just adding an extra > > 'ifdef CONFIG_X86_64' and moving the block up so that this happens in > > the naturally expected order? > > Agreed, and FWIW your diff on top of current master also fixes the > icecc build here: -march=native now comes before the -mno-* flags and > arch/x86/boot/startup/gdt_idt.o contains no SIMD instructions. If you > think that ordering is worth having on its own merits, I am happy to > send it as a cleanup without Fixes:/stable, but I understand if it is > not worth the churn for an icecc-only problem. I guess that is up to the x86 maintainers. I would personally be fine with it since the workaround is basically an extra ifdef and comment, which I do not see an substantial maintenance burden, but they might feel otherwise. -- Cheers, Nathan ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-10-25 20:21 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-10-25 17:43 [PATCH] x86/build/64: Prevent native builds from generating SSE/AVX code Antoni Kuczyński 2026-10-25 17:55 ` Antoni Kuczyński 2026-10-25 19:44 ` Nathan Chancellor 2026-10-25 20:07 ` Antoni Kuczyński 2026-10-25 20:20 ` Nathan Chancellor
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®