From 996df950f71e905e1d2fea2f50813d72ccfd5275 Mon Sep 17 00:00:00 2001 From: Luca Toniolo Date: Thu, 2 Apr 2026 07:53:53 -0400 Subject: [PATCH] pwmgen: prevent GCC from emitting SSE in base-thread function make_pulses() is exported with uses_fp=0 for the base-thread, but GCC optimizes struct zeroing into SSE instructions (pxor/movups on XMM registers). Since RTAI skips FPU/SSE save/restore for non-FP threads, this silently corrupts XMM state of whatever Linux process was running, causing heap corruption, segfaults, and hard crashes. Add __attribute__((target("general-regs-only"))) to make_pulses() to force GCC to use only general-purpose registers. Confirmed via objdump that the compiled function contains zero SSE instructions after this change. Tested on RTAI 5.4.280 with the etch-servo parport config which previously crashed reliably. See: https://github.com/LinuxCNC/linuxcnc/issues/3895 --- src/hal/components/pwmgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hal/components/pwmgen.c b/src/hal/components/pwmgen.c index 3f4d0a720d9..c024e3ef421 100644 --- a/src/hal/components/pwmgen.c +++ b/src/hal/components/pwmgen.c @@ -135,7 +135,7 @@ static long periodns; /* makepulses function period in nanosec */ ************************************************************************/ static int export_pwmgen(int num, pwmgen_t * addr, int output_type); -static void make_pulses(void *arg, long period); +static void __attribute__((target("general-regs-only"))) make_pulses(void *arg, long period); static void update(void *arg, long period); /*********************************************************************** @@ -231,7 +231,7 @@ void rtapi_app_exit(void) added and subtracted. */ -static void make_pulses(void *arg, long period) +static void __attribute__((target("general-regs-only"))) make_pulses(void *arg, long period) { pwmgen_t *pwmgen; int n;