Module Name: src Committed By: christos Date: Thu Dec 7 16:22:22 UTC 2017
Modified Files: src/sys/arch/amd64/amd64: netbsd32_machdep.c Log Message: Keep fs/gs the same for the signal context; otherwise calling things like __lwp_getprivate_fast() from a signal handler (that uses %gs) die. Merge context building code. To generate a diff of this commit: cvs rdiff -u -r1.113 -r1.114 src/sys/arch/amd64/amd64/netbsd32_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/amd64/amd64/netbsd32_machdep.c diff -u src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.113 src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.114 --- src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.113 Sat Dec 2 10:36:24 2017 +++ src/sys/arch/amd64/amd64/netbsd32_machdep.c Thu Dec 7 11:22:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_machdep.c,v 1.113 2017/12/02 15:36:24 maxv Exp $ */ +/* $NetBSD: netbsd32_machdep.c,v 1.114 2017/12/07 16:22:22 christos Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -36,7 +36,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.113 2017/12/02 15:36:24 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.114 2017/12/07 16:22:22 christos Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -164,6 +164,43 @@ netbsd32_setregs(struct lwp *l, struct e tf->tf_ss = LSEL(LUDATA32_SEL, SEL_UPL); } +static void +netbsd32_buildcontext(struct lwp *l, struct trapframe *tf, void *fp, + sig_t catcher, int onstack) +{ + /* + * Build context to run handler in. + */ + tf->tf_ds = GSEL(GUDATA32_SEL, SEL_UPL); + tf->tf_es = GSEL(GUDATA32_SEL, SEL_UPL); +#if 0 + tf->tf_fs = GSEL(GUDATA32_SEL, SEL_UPL); + tf->tf_gs = GSEL(GUDATA32_SEL, SEL_UPL); +#endif + + /* Ensure FP state is sane. */ + fpu_save_area_reset(l); + + tf->tf_rip = (uint64_t)catcher; + tf->tf_cs = GSEL(GUCODE32_SEL, SEL_UPL); + tf->tf_rflags &= ~PSL_CLEARSIG; + tf->tf_rsp = (uint64_t)fp; + tf->tf_ss = GSEL(GUDATA32_SEL, SEL_UPL); + + /* Remember that we're now on the signal stack. */ + if (onstack) + l->l_sigstk.ss_flags |= SS_ONSTACK; + if ((vaddr_t)catcher >= VM_MAXUSER_ADDRESS32) { + /* + * process has given an invalid address for the + * handler. Stop it, but do not do it before so + * we can return the right info to userland (or in core dump) + */ + sigexit(l, SIGILL); + /* NOTREACHED */ + } +} + #ifdef COMPAT_16 static void netbsd32_sendsig_sigcontext(const ksiginfo_t *ksi, const sigset_t *mask) @@ -249,35 +286,7 @@ netbsd32_sendsig_sigcontext(const ksigin /* NOTREACHED */ } - /* - * Build context to run handler in. - */ - tf->tf_ds = GSEL(GUDATA32_SEL, SEL_UPL); - tf->tf_es = GSEL(GUDATA32_SEL, SEL_UPL); - tf->tf_fs = GSEL(GUDATA32_SEL, SEL_UPL); - tf->tf_gs = GSEL(GUDATA32_SEL, SEL_UPL); - - /* Ensure FP state is sane. */ - fpu_save_area_reset(l); - - tf->tf_rip = (uint64_t)catcher; - tf->tf_cs = GSEL(GUCODE32_SEL, SEL_UPL); - tf->tf_rflags &= ~PSL_CLEARSIG; - tf->tf_rsp = (uint64_t)fp; - tf->tf_ss = GSEL(GUDATA32_SEL, SEL_UPL); - - /* Remember that we're now on the signal stack. */ - if (onstack) - l->l_sigstk.ss_flags |= SS_ONSTACK; - if ((vaddr_t)catcher >= VM_MAXUSER_ADDRESS32) { - /* - * process has given an invalid address for the - * handler. Stop it, but do not do it before so - * we can return the right info to userland (or in core dump) - */ - sigexit(l, SIGILL); - /* NOTREACHED */ - } + netbsd32_buildcontext(l, tf, fp, catcher, onstack); } #endif @@ -346,35 +355,7 @@ netbsd32_sendsig_siginfo(const ksiginfo_ /* NOTREACHED */ } - /* - * Build context to run handler in. - */ - tf->tf_ds = GSEL(GUDATA32_SEL, SEL_UPL); - tf->tf_es = GSEL(GUDATA32_SEL, SEL_UPL); - tf->tf_fs = GSEL(GUDATA32_SEL, SEL_UPL); - tf->tf_gs = GSEL(GUDATA32_SEL, SEL_UPL); - - tf->tf_rip = (uint64_t)catcher; - tf->tf_cs = GSEL(GUCODE32_SEL, SEL_UPL); - tf->tf_rflags &= ~PSL_CLEARSIG; - tf->tf_rsp = (uint64_t)fp; - tf->tf_ss = GSEL(GUDATA32_SEL, SEL_UPL); - - /* Ensure FP state is sane. */ - fpu_save_area_reset(l); - - /* Remember that we're now on the signal stack. */ - if (onstack) - l->l_sigstk.ss_flags |= SS_ONSTACK; - if ((vaddr_t)catcher >= VM_MAXUSER_ADDRESS32) { - /* - * process has given an invalid address for the - * handler. Stop it, but do not do it before so - * we can return the right info to userland (or in core dump) - */ - sigexit(l, SIGILL); - /* NOTREACHED */ - } + netbsd32_buildcontext(l, tf, fp, catcher, onstack); } void