X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/2d21ac55c334faf3a56e5634905ed6987fc787d4..316670eb35587141e969394ae8537d66b9211e80:/bsd/dev/i386/unix_signal.c?ds=sidebyside diff --git a/bsd/dev/i386/unix_signal.c b/bsd/dev/i386/unix_signal.c index 7a9291cae..4f31f83e5 100644 --- a/bsd/dev/i386/unix_signal.c +++ b/bsd/dev/i386/unix_signal.c @@ -48,16 +48,18 @@ #include #include /* for thread_abort_safely */ #include -#include #include #include +#include #include -#include +#include +#include #include + /* Forward: */ extern boolean_t machine_exception(int, mach_exception_code_t, mach_exception_subcode_t, int *, mach_exception_subcode_t *); @@ -90,23 +92,57 @@ extern kern_return_t thread_setstatus(thread_t thread, int flavor, * to the user specified pc, psl. */ struct sigframe32 { - int retaddr; - sig_t catcher; - int sigstyle; - int sig; - siginfo_t * sinfo; - struct ucontext * uctx; + int retaddr; + user32_addr_t catcher; /* sig_t */ + int sigstyle; + int sig; + user32_addr_t sinfo; /* siginfo32_t* */ + user32_addr_t uctx; /* struct ucontext32 */ }; +/* + * NOTE: Source and target may *NOT* overlap! + * XXX: Unify with bsd/kern/kern_exit.c + */ +static void +siginfo_user_to_user32_x86(user_siginfo_t *in, user32_siginfo_t *out) +{ + out->si_signo = in->si_signo; + out->si_errno = in->si_errno; + out->si_code = in->si_code; + out->si_pid = in->si_pid; + out->si_uid = in->si_uid; + out->si_status = in->si_status; + out->si_addr = CAST_DOWN_EXPLICIT(user32_addr_t,in->si_addr); + /* following cast works for sival_int because of padding */ + out->si_value.sival_ptr = CAST_DOWN_EXPLICIT(user32_addr_t,in->si_value.sival_ptr); + out->si_band = in->si_band; /* range reduction */ + out->__pad[0] = in->pad[0]; /* mcontext.ss.r1 */ +} +static void +siginfo_user_to_user64_x86(user_siginfo_t *in, user64_siginfo_t *out) +{ + out->si_signo = in->si_signo; + out->si_errno = in->si_errno; + out->si_code = in->si_code; + out->si_pid = in->si_pid; + out->si_uid = in->si_uid; + out->si_status = in->si_status; + out->si_addr = in->si_addr; + out->si_value.sival_ptr = in->si_value.sival_ptr; + out->si_band = in->si_band; /* range reduction */ + out->__pad[0] = in->pad[0]; /* mcontext.ss.r1 */ +} void -sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_long code) +sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused uint32_t code) { - union { - struct mcontext32 mctx32; - struct mcontext64 mctx64; - } mctx; + union { + struct mcontext_avx32 mctx_avx32; + struct mcontext_avx64 mctx_avx64; + } mctx_store, *mctxp = &mctx_store; + user_addr_t ua_sp; user_addr_t ua_fp; user_addr_t ua_cr2; @@ -117,6 +153,8 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_lo struct sigacts *ps = p->p_sigacts; int oonstack, flavor; + user_addr_t trampact; + int sigonstack; void * state; mach_msg_type_number_t state_count; @@ -124,7 +162,8 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_lo struct uthread * ut; int stack_size = 0; int infostyle = UC_TRAD; - + boolean_t sig_avx; + thread = current_thread(); ut = get_bsdthread_info(thread); @@ -132,15 +171,19 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_lo infostyle = UC_FLAVOR; oonstack = ut->uu_sigstk.ss_flags & SA_ONSTACK; + trampact = ps->ps_trampact[sig]; + sigonstack = (ps->ps_sigonstack & sigmask(sig)); /* * init siginfo */ proc_unlock(p); - bzero((caddr_t)&sinfo64, sizeof(user_siginfo_t)); + bzero((caddr_t)&sinfo64, sizeof(sinfo64)); sinfo64.si_signo = sig; - + + bzero(mctxp, sizeof(*mctxp)); + sig_avx = ml_fpu_avx_enabled(); if (proc_is64bit(p)) { x86_thread_state64_t *tstate64; @@ -148,27 +191,33 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_lo flavor = x86_THREAD_STATE64; state_count = x86_THREAD_STATE64_COUNT; - state = (void *)&mctx.mctx64.ss; + state = (void *)&mctxp->mctx_avx64.ss; if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS) goto bad; - flavor = x86_FLOAT_STATE64; - state_count = x86_FLOAT_STATE64_COUNT; - state = (void *)&mctx.mctx64.fs; + if (sig_avx) { + flavor = x86_AVX_STATE64; + state_count = x86_AVX_STATE64_COUNT; + } + else { + flavor = x86_FLOAT_STATE64; + state_count = x86_FLOAT_STATE64_COUNT; + } + state = (void *)&mctxp->mctx_avx64.fs; if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS) goto bad; flavor = x86_EXCEPTION_STATE64; state_count = x86_EXCEPTION_STATE64_COUNT; - state = (void *)&mctx.mctx64.es; + state = (void *)&mctxp->mctx_avx64.es; if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS) goto bad; - tstate64 = &mctx.mctx64.ss; + tstate64 = &mctxp->mctx_avx64.ss; /* figure out where our new stack lives */ if ((ut->uu_flag & UT_ALTSTACK) && !oonstack && - (ps->ps_sigonstack & sigmask(sig))) { + (sigonstack)) { ua_sp = ut->uu_sigstk.ss_sp; stack_size = ut->uu_sigstk.ss_size; ua_sp += stack_size; @@ -176,7 +225,7 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_lo } else { ua_sp = tstate64->rsp; } - ua_cr2 = mctx.mctx64.es.faultvaddr; + ua_cr2 = mctxp->mctx_avx64.es.faultvaddr; /* The x86_64 ABI defines a 128-byte red zone. */ ua_sp -= C_64_REDZONE_LEN; @@ -184,10 +233,10 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_lo ua_sp -= sizeof (struct user_ucontext64); ua_uctxp = ua_sp; // someone tramples the first word! - ua_sp -= sizeof (user_siginfo_t); + ua_sp -= sizeof (user64_siginfo_t); ua_sip = ua_sp; - ua_sp -= sizeof (struct mcontext64); + ua_sp -= sizeof (struct mcontext_avx64); ua_mctxp = ua_sp; /* @@ -216,19 +265,19 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_lo uctx64.uc_stack.ss_flags |= SS_ONSTACK; uctx64.uc_link = 0; - uctx64.uc_mcsize = sizeof(struct mcontext64); + uctx64.uc_mcsize = sig_avx ? sizeof(struct mcontext_avx64) : sizeof(struct mcontext64); uctx64.uc_mcontext64 = ua_mctxp; if (copyout((caddr_t)&uctx64, ua_uctxp, sizeof (uctx64))) goto bad; - if (copyout((caddr_t)&mctx.mctx64, ua_mctxp, sizeof (struct mcontext64))) + if (copyout((caddr_t)&mctxp->mctx_avx64, ua_mctxp, sizeof (struct mcontext_avx64))) goto bad; sinfo64.pad[0] = tstate64->rsp; sinfo64.si_addr = tstate64->rip; - tstate64->rip = ps->ps_trampact[sig]; + tstate64->rip = trampact; tstate64->rsp = ua_fp; tstate64->rflags = get_eflags_exportmask(); /* @@ -250,32 +299,39 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_lo } else { x86_thread_state32_t *tstate32; - struct ucontext uctx32; + struct user_ucontext32 uctx32; struct sigframe32 frame32; flavor = x86_THREAD_STATE32; state_count = x86_THREAD_STATE32_COUNT; - state = (void *)&mctx.mctx32.ss; + state = (void *)&mctxp->mctx_avx32.ss; if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS) goto bad; - flavor = x86_FLOAT_STATE32; - state_count = x86_FLOAT_STATE32_COUNT; - state = (void *)&mctx.mctx32.fs; + if (sig_avx) { + flavor = x86_AVX_STATE32; + state_count = x86_AVX_STATE32_COUNT; + } + else { + flavor = x86_FLOAT_STATE32; + state_count = x86_FLOAT_STATE32_COUNT; + } + + state = (void *)&mctxp->mctx_avx32.fs; if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS) goto bad; flavor = x86_EXCEPTION_STATE32; state_count = x86_EXCEPTION_STATE32_COUNT; - state = (void *)&mctx.mctx32.es; + state = (void *)&mctxp->mctx_avx32.es; if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS) goto bad; - tstate32 = &mctx.mctx32.ss; + tstate32 = &mctxp->mctx_avx32.ss; /* figure out where our new stack lives */ if ((ut->uu_flag & UT_ALTSTACK) && !oonstack && - (ps->ps_sigonstack & sigmask(sig))) { + (sigonstack)) { ua_sp = ut->uu_sigstk.ss_sp; stack_size = ut->uu_sigstk.ss_size; ua_sp += stack_size; @@ -283,15 +339,15 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_lo } else { ua_sp = tstate32->esp; } - ua_cr2 = mctx.mctx32.es.faultvaddr; + ua_cr2 = mctxp->mctx_avx32.es.faultvaddr; - ua_sp -= sizeof (struct ucontext); + ua_sp -= sizeof (struct user_ucontext32); ua_uctxp = ua_sp; // someone tramples the first word! - ua_sp -= sizeof (siginfo_t); + ua_sp -= sizeof (user32_siginfo_t); ua_sip = ua_sp; - ua_sp -= sizeof (struct mcontext32); + ua_sp -= sizeof (struct mcontext_avx32); ua_mctxp = ua_sp; ua_sp -= sizeof (struct sigframe32); @@ -316,9 +372,9 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_lo frame32.retaddr = -1; frame32.sigstyle = infostyle; frame32.sig = sig; - frame32.catcher = CAST_DOWN(sig_t, ua_catcher); - frame32.sinfo = CAST_DOWN(siginfo_t *, ua_sip); - frame32.uctx = CAST_DOWN(struct ucontext *, ua_uctxp); + frame32.catcher = CAST_DOWN_EXPLICIT(user32_addr_t, ua_catcher); + frame32.sinfo = CAST_DOWN_EXPLICIT(user32_addr_t, ua_sip); + frame32.uctx = CAST_DOWN_EXPLICIT(user32_addr_t, ua_uctxp); if (copyout((caddr_t)&frame32, ua_fp, sizeof (frame32))) goto bad; @@ -330,21 +386,21 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_lo uctx32.uc_onstack = oonstack; uctx32.uc_sigmask = mask; - uctx32.uc_stack.ss_sp = CAST_DOWN(char *, ua_fp); + uctx32.uc_stack.ss_sp = CAST_DOWN_EXPLICIT(user32_addr_t, ua_fp); uctx32.uc_stack.ss_size = stack_size; if (oonstack) uctx32.uc_stack.ss_flags |= SS_ONSTACK; uctx32.uc_link = 0; - uctx32.uc_mcsize = sizeof(struct mcontext32); + uctx32.uc_mcsize = sig_avx ? sizeof(struct mcontext_avx32) : sizeof(struct mcontext32); - uctx32.uc_mcontext = CAST_DOWN(_STRUCT_MCONTEXT32 *, ua_mctxp); + uctx32.uc_mcontext = CAST_DOWN_EXPLICIT(user32_addr_t, ua_mctxp); if (copyout((caddr_t)&uctx32, ua_uctxp, sizeof (uctx32))) goto bad; - if (copyout((caddr_t)&mctx.mctx32, ua_mctxp, sizeof (struct mcontext32))) + if (copyout((caddr_t)&mctxp->mctx_avx32, ua_mctxp, sizeof (struct mcontext_avx32))) goto bad; sinfo64.pad[0] = tstate32->esp; @@ -358,7 +414,6 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_lo sinfo64.si_code = ILL_ILLOPC; break; default: - printf("unknown SIGILL code %ld\n", (long) ut->uu_code); sinfo64.si_code = ILL_NOOP; } break; @@ -369,7 +424,13 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_lo #define FP_OE 3 /* overflow */ #define FP_UE 4 /* underflow */ #define FP_PE 5 /* precision */ - if (ut->uu_subcode & (1 << FP_ZE)) { + if (ut->uu_code == EXC_I386_DIV) { + sinfo64.si_code = FPE_INTDIV; + } + else if (ut->uu_code == EXC_I386_INTO) { + sinfo64.si_code = FPE_INTOVF; + } + else if (ut->uu_subcode & (1 << FP_ZE)) { sinfo64.si_code = FPE_FLTDIV; } else if (ut->uu_subcode & (1 << FP_OE)) { sinfo64.si_code = FPE_FLTOVF; @@ -380,8 +441,6 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_lo } else if (ut->uu_subcode & (1 << FP_IE)) { sinfo64.si_code = FPE_FLTINV; } else { - printf("unknown SIGFPE code %ld, subcode %lx\n", - (long) ut->uu_code, (long) ut->uu_subcode); sinfo64.si_code = FPE_NOOP; } break; @@ -409,7 +468,6 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_lo sinfo64.si_code = SEGV_MAPERR; break; default: - printf("unknown SIGSEGV code %ld\n", (long) ut->uu_code); sinfo64.si_code = FPE_NOOP; } break; @@ -460,41 +518,82 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_lo } } if (proc_is64bit(p)) { + user64_siginfo_t sinfo64_user64; + + bzero((caddr_t)&sinfo64_user64, sizeof(sinfo64_user64)); + + siginfo_user_to_user64_x86(&sinfo64,&sinfo64_user64); + +#if CONFIG_DTRACE + bzero((caddr_t)&(ut->t_dtrace_siginfo), sizeof(ut->t_dtrace_siginfo)); + + ut->t_dtrace_siginfo.si_signo = sinfo64.si_signo; + ut->t_dtrace_siginfo.si_code = sinfo64.si_code; + ut->t_dtrace_siginfo.si_pid = sinfo64.si_pid; + ut->t_dtrace_siginfo.si_uid = sinfo64.si_uid; + ut->t_dtrace_siginfo.si_status = sinfo64.si_status; + /* XXX truncates faulting address to void * on K32 */ + ut->t_dtrace_siginfo.si_addr = CAST_DOWN(void *, sinfo64.si_addr); + + /* Fire DTrace proc:::fault probe when signal is generated by hardware. */ + switch (sig) { + case SIGILL: case SIGBUS: case SIGSEGV: case SIGFPE: case SIGTRAP: + DTRACE_PROC2(fault, int, (int)(ut->uu_code), siginfo_t *, &(ut->t_dtrace_siginfo)); + break; + default: + break; + } /* XXX truncates catcher address to uintptr_t */ - DTRACE_PROC3(signal__handle, int, sig, siginfo_t *, &sinfo64, + DTRACE_PROC3(signal__handle, int, sig, siginfo_t *, &(ut->t_dtrace_siginfo), void (*)(void), CAST_DOWN(sig_t, ua_catcher)); +#endif /* CONFIG_DTRACE */ - if (copyout((caddr_t)&sinfo64, ua_sip, sizeof (sinfo64))) - goto bad; + if (copyout((caddr_t)&sinfo64_user64, ua_sip, sizeof (sinfo64_user64))) + goto bad; flavor = x86_THREAD_STATE64; state_count = x86_THREAD_STATE64_COUNT; - state = (void *)&mctx.mctx64.ss; + state = (void *)&mctxp->mctx_avx64.ss; } else { - x86_thread_state32_t *tstate32; - siginfo_t sinfo32; + x86_thread_state32_t *tstate32; + user32_siginfo_t sinfo32; + + bzero((caddr_t)&sinfo32, sizeof(sinfo32)); + + siginfo_user_to_user32_x86(&sinfo64,&sinfo32); + +#if CONFIG_DTRACE + bzero((caddr_t)&(ut->t_dtrace_siginfo), sizeof(ut->t_dtrace_siginfo)); - bzero((caddr_t)&sinfo32, sizeof(siginfo_t)); + ut->t_dtrace_siginfo.si_signo = sinfo32.si_signo; + ut->t_dtrace_siginfo.si_code = sinfo32.si_code; + ut->t_dtrace_siginfo.si_pid = sinfo32.si_pid; + ut->t_dtrace_siginfo.si_uid = sinfo32.si_uid; + ut->t_dtrace_siginfo.si_status = sinfo32.si_status; + ut->t_dtrace_siginfo.si_addr = CAST_DOWN(void *, sinfo32.si_addr); - sinfo32.si_signo = sinfo64.si_signo; - sinfo32.si_code = sinfo64.si_code; - sinfo32.si_pid = sinfo64.si_pid; - sinfo32.si_uid = sinfo64.si_uid; - sinfo32.si_status = sinfo64.si_status; - sinfo32.si_addr = CAST_DOWN(void *, sinfo64.si_addr); - sinfo32.__pad[0] = sinfo64.pad[0]; + /* Fire DTrace proc:::fault probe when signal is generated by hardware. */ + switch (sig) { + case SIGILL: case SIGBUS: case SIGSEGV: case SIGFPE: case SIGTRAP: + DTRACE_PROC2(fault, int, (int)(ut->uu_code), siginfo_t *, &(ut->t_dtrace_siginfo)); + break; + default: + break; + } - DTRACE_PROC3(signal__handle, int, sig, siginfo_t *, &sinfo32, + DTRACE_PROC3(signal__handle, int, sig, siginfo_t *, &(ut->t_dtrace_siginfo), void (*)(void), CAST_DOWN(sig_t, ua_catcher)); +#endif /* CONFIG_DTRACE */ - if (copyout((caddr_t)&sinfo32, ua_sip, sizeof (sinfo32))) - goto bad; + if (copyout((caddr_t)&sinfo32, ua_sip, sizeof (sinfo32))) + goto bad; - tstate32 = &mctx.mctx32.ss; - tstate32->eip = CAST_DOWN(unsigned int, ps->ps_trampact[sig]); - tstate32->esp = CAST_DOWN(unsigned int, ua_fp); - + tstate32 = &mctxp->mctx_avx32.ss; + + tstate32->eip = CAST_DOWN_EXPLICIT(user32_addr_t, trampact); + tstate32->esp = CAST_DOWN_EXPLICIT(user32_addr_t, ua_fp); + tstate32->eflags = get_eflags_exportmask(); tstate32->cs = USER_CS; @@ -512,11 +611,15 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_lo goto bad; ml_fp_setvalid(FALSE); + /* Tell the PAL layer about the signal */ + pal_set_signal_delivery( thread ); + proc_lock(p); return; bad: + proc_lock(p); SIGACTION(p, SIGILL) = SIG_DFL; sig = sigmask(SIGILL); @@ -544,10 +647,11 @@ bad: int sigreturn(struct proc *p, struct sigreturn_args *uap, __unused int *retval) { - union { - struct mcontext32 mctx32; - struct mcontext64 mctx64; - } mctx; + union { + struct mcontext_avx32 mctx_avx32; + struct mcontext_avx64 mctx_avx64; + } mctx_store, *mctxp = &mctx_store; + thread_t thread = current_thread(); struct uthread * ut; int error; @@ -559,6 +663,8 @@ sigreturn(struct proc *p, struct sigreturn_args *uap, __unused int *retval) mach_msg_type_number_t fs_count; unsigned int fs_flavor; void * fs; + int rval = EJUSTRETURN; + boolean_t sig_avx; ut = (struct uthread *)get_bsdthread_info(thread); @@ -574,33 +680,43 @@ sigreturn(struct proc *p, struct sigreturn_args *uap, __unused int *retval) return (0); } + bzero(mctxp, sizeof(*mctxp)); + sig_avx = ml_fpu_avx_enabled(); + if (proc_is64bit(p)) { struct user_ucontext64 uctx64; if ((error = copyin(uap->uctx, (void *)&uctx64, sizeof (uctx64)))) return(error); - if ((error = copyin(uctx64.uc_mcontext64, (void *)&mctx.mctx64, sizeof (struct mcontext64)))) + if ((error = copyin(uctx64.uc_mcontext64, (void *)&mctxp->mctx_avx64, sizeof (struct mcontext_avx64)))) return(error); onstack = uctx64.uc_onstack & 01; ut->uu_sigmask = uctx64.uc_sigmask & ~sigcantmask; - ts_flavor = x86_THREAD_STATE64; + ts_flavor = x86_THREAD_STATE64; ts_count = x86_THREAD_STATE64_COUNT; - ts = (void *)&mctx.mctx64.ss; + ts = (void *)&mctxp->mctx_avx64.ss; - fs_flavor = x86_FLOAT_STATE64; - fs_count = x86_FLOAT_STATE64_COUNT; - fs = (void *)&mctx.mctx64.fs; + if (sig_avx) { + fs_flavor = x86_AVX_STATE64; + fs_count = x86_AVX_STATE64_COUNT; + } + else { + fs_flavor = x86_FLOAT_STATE64; + fs_count = x86_FLOAT_STATE64_COUNT; + } + + fs = (void *)&mctxp->mctx_avx64.fs; } else { - struct ucontext uctx32; + struct user_ucontext32 uctx32; if ((error = copyin(uap->uctx, (void *)&uctx32, sizeof (uctx32)))) return(error); - if ((error = copyin(CAST_USER_ADDR_T(uctx32.uc_mcontext), (void *)&mctx.mctx32, sizeof (struct mcontext32)))) + if ((error = copyin(CAST_USER_ADDR_T(uctx32.uc_mcontext), (void *)&mctxp->mctx_avx32, sizeof (struct mcontext_avx32)))) return(error); onstack = uctx32.uc_onstack & 01; @@ -608,11 +724,18 @@ sigreturn(struct proc *p, struct sigreturn_args *uap, __unused int *retval) ts_flavor = x86_THREAD_STATE32; ts_count = x86_THREAD_STATE32_COUNT; - ts = (void *)&mctx.mctx32.ss; + ts = (void *)&mctxp->mctx_avx32.ss; - fs_flavor = x86_FLOAT_STATE32; - fs_count = x86_FLOAT_STATE32_COUNT; - fs = (void *)&mctx.mctx32.fs; + if (sig_avx) { + fs_flavor = x86_AVX_STATE32; + fs_count = x86_AVX_STATE32_COUNT; + } + else { + fs_flavor = x86_FLOAT_STATE32; + fs_count = x86_FLOAT_STATE32_COUNT; + } + + fs = (void *)&mctxp->mctx_avx32.fs; } if (onstack) @@ -622,20 +745,24 @@ sigreturn(struct proc *p, struct sigreturn_args *uap, __unused int *retval) if (ut->uu_siglist & ~ut->uu_sigmask) signal_setast(thread); - /* * thread_set_state() does all the needed checks for the passed in * content */ - if (thread_setstatus(thread, ts_flavor, ts, ts_count) != KERN_SUCCESS) - return(EINVAL); - + if (thread_setstatus(thread, ts_flavor, ts, ts_count) != KERN_SUCCESS) { + rval = EINVAL; + goto error_ret; + } + ml_fp_setvalid(TRUE); - if (thread_setstatus(thread, fs_flavor, fs, fs_count) != KERN_SUCCESS) - return(EINVAL); + if (thread_setstatus(thread, fs_flavor, fs, fs_count) != KERN_SUCCESS) { + rval = EINVAL; + goto error_ret; - return (EJUSTRETURN); + } +error_ret: + return rval; }