On Fri, May 30, 2025 at 09:36:39AM +0200, Herbert J. Skuhra wrote: > Hi, > > building lang/go (e.g. 1.24) and go ports (e.g. aerc, netbird) on main > (amd64) fails with: fatal: bad g in signal handler. > Arm64 seems to be OK.
I might have a guess. Try the following untested patch, you need to rebuild at least kernel, but ideally both kernel and userspace. Also it is amd64-only.
diff --git a/lib/libthr/thread/thr_create.c b/lib/libthr/thread/thr_create.c index 2ae7cf0cd7b2..84bbd36ed28d 100644 --- a/lib/libthr/thread/thr_create.c +++ b/lib/libthr/thread/thr_create.c @@ -160,7 +160,7 @@ _pthread_create(pthread_t * __restrict thread, param.tls_size = sizeof(struct tcb); param.child_tid = &new_thread->tid; param.parent_tid = &new_thread->tid; - param.flags = 0; + param.flags = THR_C_RUNTIME; if (new_thread->attr.flags & PTHREAD_SCOPE_SYSTEM) param.flags |= THR_SYSTEM_SCOPE; if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c index 4001f40554af..c763ff58680e 100644 --- a/sys/amd64/amd64/vm_machdep.c +++ b/sys/amd64/amd64/vm_machdep.c @@ -60,6 +60,7 @@ #include <sys/smp.h> #include <sys/sysctl.h> #include <sys/sysent.h> +#include <sys/thr.h> #include <sys/unistd.h> #include <sys/vnode.h> #include <sys/vmmeter.h> @@ -164,6 +165,7 @@ copy_thread(struct thread *td1, struct thread *td2) MPASS((pcb2->pcb_flags & (PCB_KERNFPU | PCB_KERNFPU_THR)) == 0); bcopy(get_pcb_user_save_td(td1), get_pcb_user_save_pcb(pcb2), cpu_max_ext_state_size); + clear_pcb_flags(pcb2, PCB_TLSBASE); } td2->td_frame = (struct trapframe *)td2->td_md.md_stack_base - 1; @@ -655,7 +657,7 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg, } int -cpu_set_user_tls(struct thread *td, void *tls_base) +cpu_set_user_tls(struct thread *td, void *tls_base, int thr_flags) { struct pcb *pcb; @@ -663,7 +665,8 @@ cpu_set_user_tls(struct thread *td, void *tls_base) return (EINVAL); pcb = td->td_pcb; - set_pcb_flags(pcb, PCB_FULL_IRET | PCB_TLSBASE); + set_pcb_flags(pcb, PCB_FULL_IRET | ((thr_flags & + THR_C_RUNTIME) != 0 ? PCB_TLSBASE : 0)); #ifdef COMPAT_FREEBSD32 if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) { pcb->pcb_gsbase = (register_t)tls_base; diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c index 0ab4cb5f7970..afd016ec9e75 100644 --- a/sys/kern/kern_thr.c +++ b/sys/kern/kern_thr.c @@ -169,7 +169,7 @@ thr_new_initthr(struct thread *td, void *thunk) if (error != 0) return (error); /* Setup user TLS address and TLS pointer register. */ - return (cpu_set_user_tls(td, param->tls_base)); + return (cpu_set_user_tls(td, param->tls_base, param->flags)); } int diff --git a/sys/sys/proc.h b/sys/sys/proc.h index eb0b66618a9d..fcacfec4442b 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1236,7 +1236,7 @@ int cpu_procctl(struct thread *td, int idtype, id_t id, int com, void cpu_set_syscall_retval(struct thread *, int); int cpu_set_upcall(struct thread *, void (*)(void *), void *, stack_t *); -int cpu_set_user_tls(struct thread *, void *tls_base); +int cpu_set_user_tls(struct thread *, void *tls_base, int flags); void cpu_thread_alloc(struct thread *); void cpu_thread_clean(struct thread *); void cpu_thread_exit(struct thread *); diff --git a/sys/sys/thr.h b/sys/sys/thr.h index 5e83ec208f07..54766668c929 100644 --- a/sys/sys/thr.h +++ b/sys/sys/thr.h @@ -43,6 +43,7 @@ typedef __size_t size_t; #define THR_SUSPENDED 0x0001 /* Create the system scope thread. */ #define THR_SYSTEM_SCOPE 0x0002 +#define THR_C_RUNTIME 0x0004 struct thr_param { void (*start_func)(void *); /* thread entry function. */