X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/060df5ea7c632b1ac8cc8aac1fb59758165c2084..cc8bc92ae4a8e9f1a1ab61bf83d34ad8150b3405:/bsd/dev/i386/unix_signal.c?ds=inline diff --git a/bsd/dev/i386/unix_signal.c b/bsd/dev/i386/unix_signal.c index 06ed4172c..1c271607f 100644 --- a/bsd/dev/i386/unix_signal.c +++ b/bsd/dev/i386/unix_signal.c @@ -53,17 +53,18 @@ #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 *); -extern kern_return_t thread_getstatus(register thread_t act, int flavor, +extern kern_return_t thread_getstatus(thread_t act, int flavor, thread_state_t tstate, mach_msg_type_number_t *count); extern kern_return_t thread_setstatus(thread_t thread, int flavor, thread_state_t tstate, mach_msg_type_number_t count); @@ -100,11 +101,34 @@ struct sigframe32 { user32_addr_t uctx; /* struct ucontext32 */ }; +/* + * Declare table of structure flavors and sizes for 64-bit and 32-bit processes + * for the cases of extended states (plain FP, or AVX): + */ +typedef struct { + int flavor; natural_t state_count; size_t mcontext_size; +} xstate_info_t; +static const xstate_info_t thread_state64[] = { + [FP] = { x86_FLOAT_STATE64, x86_FLOAT_STATE64_COUNT, sizeof(struct mcontext64) }, + [AVX] = { x86_AVX_STATE64, x86_AVX_STATE64_COUNT, sizeof(struct mcontext_avx64) }, +#if !defined(RC_HIDE_XNU_J137) + [AVX512] = { x86_AVX512_STATE64, x86_AVX512_STATE64_COUNT, sizeof(struct mcontext_avx512_64) } +#endif +}; +static const xstate_info_t thread_state32[] = { + [FP] = { x86_FLOAT_STATE32, x86_FLOAT_STATE32_COUNT, sizeof(struct mcontext32) }, + [AVX] = { x86_AVX_STATE32, x86_AVX_STATE32_COUNT, sizeof(struct mcontext_avx32) }, +#if !defined(RC_HIDE_XNU_J137) + [AVX512] = { x86_AVX512_STATE32, x86_AVX512_STATE32_COUNT, sizeof(struct mcontext_avx512_32) } +#endif +}; + /* * NOTE: Source and target may *NOT* overlap! + * XXX: Unify with bsd/kern/kern_exit.c */ static void -siginfo_user_to_user32(user_siginfo_t *in, user32_siginfo_t *out) +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; @@ -120,7 +144,7 @@ siginfo_user_to_user32(user_siginfo_t *in, user32_siginfo_t *out) } static void -siginfo_user_to_user64(user_siginfo_t *in, user64_siginfo_t *out) +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; @@ -138,8 +162,12 @@ void sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused uint32_t code) { union { - struct mcontext_avx32 mctx_avx32; - struct mcontext_avx64 mctx_avx64; + struct mcontext_avx32 mctx_avx32; + struct mcontext_avx64 mctx_avx64; +#if !defined(RC_HIDE_XNU_J137) + struct mcontext_avx512_32 mctx_avx512_32; + struct mcontext_avx512_64 mctx_avx512_64; +#endif } mctx_store, *mctxp = &mctx_store; user_addr_t ua_sp; @@ -161,7 +189,7 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused uint struct uthread * ut; int stack_size = 0; int infostyle = UC_TRAD; - boolean_t sig_avx; + xstate_t sig_xstate; thread = current_thread(); ut = get_bsdthread_info(thread); @@ -182,7 +210,8 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused uint sinfo64.si_signo = sig; bzero(mctxp, sizeof(*mctxp)); - sig_avx = ml_fpu_avx_enabled(); + + sig_xstate = current_xstate(); if (proc_is64bit(p)) { x86_thread_state64_t *tstate64; @@ -194,14 +223,8 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused uint if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS) goto bad; - if (sig_avx) { - flavor = x86_AVX_STATE64; - state_count = x86_AVX_STATE64_COUNT; - } - else { - flavor = x86_FLOAT_STATE64; - state_count = x86_FLOAT_STATE64_COUNT; - } + flavor = thread_state64[sig_xstate].flavor; + state_count = thread_state64[sig_xstate].state_count; state = (void *)&mctxp->mctx_avx64.fs; if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS) goto bad; @@ -235,7 +258,7 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused uint ua_sp -= sizeof (user64_siginfo_t); ua_sip = ua_sp; - ua_sp -= sizeof (struct mcontext_avx64); + ua_sp -= thread_state64[sig_xstate].mcontext_size; ua_mctxp = ua_sp; /* @@ -264,13 +287,13 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused uint uctx64.uc_stack.ss_flags |= SS_ONSTACK; uctx64.uc_link = 0; - uctx64.uc_mcsize = sig_avx ? sizeof(struct mcontext_avx64) : sizeof(struct mcontext64); + uctx64.uc_mcsize = thread_state64[sig_xstate].mcontext_size; uctx64.uc_mcontext64 = ua_mctxp; if (copyout((caddr_t)&uctx64, ua_uctxp, sizeof (uctx64))) goto bad; - if (copyout((caddr_t)&mctxp->mctx_avx64, ua_mctxp, sizeof (struct mcontext_avx64))) + if (copyout((caddr_t)&mctx_store, ua_mctxp, thread_state64[sig_xstate].mcontext_size)) goto bad; sinfo64.pad[0] = tstate64->rsp; @@ -307,15 +330,8 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused uint if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS) goto bad; - if (sig_avx) { - flavor = x86_AVX_STATE32; - state_count = x86_AVX_STATE32_COUNT; - } - else { - flavor = x86_FLOAT_STATE32; - state_count = x86_FLOAT_STATE32_COUNT; - } - + flavor = thread_state32[sig_xstate].flavor; + state_count = thread_state32[sig_xstate].state_count; state = (void *)&mctxp->mctx_avx32.fs; if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS) goto bad; @@ -346,7 +362,7 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused uint ua_sp -= sizeof (user32_siginfo_t); ua_sip = ua_sp; - ua_sp -= sizeof (struct mcontext_avx32); + ua_sp -= thread_state32[sig_xstate].mcontext_size; ua_mctxp = ua_sp; ua_sp -= sizeof (struct sigframe32); @@ -392,14 +408,14 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused uint uctx32.uc_stack.ss_flags |= SS_ONSTACK; uctx32.uc_link = 0; - uctx32.uc_mcsize = sig_avx ? sizeof(struct mcontext_avx32) : sizeof(struct mcontext32); + uctx32.uc_mcsize = thread_state64[sig_xstate].mcontext_size; 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)&mctxp->mctx_avx32, ua_mctxp, sizeof (struct mcontext_avx32))) + if (copyout((caddr_t)&mctx_store, ua_mctxp, thread_state32[sig_xstate].mcontext_size)) goto bad; sinfo64.pad[0] = tstate32->esp; @@ -512,7 +528,8 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused uint * in the siginfo to the handler is supposed to only * contain the status, so we have to shift it out. */ - sinfo64.si_status = WEXITSTATUS(status_and_exitcode); + sinfo64.si_status = (WEXITSTATUS(status_and_exitcode) & 0x00FFFFFF) | (((uint32_t)(p->p_xhighbits) << 24) & 0xFF000000); + p->p_xhighbits = 0; break; } } @@ -521,7 +538,7 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused uint bzero((caddr_t)&sinfo64_user64, sizeof(sinfo64_user64)); - siginfo_user_to_user64(&sinfo64,&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)); @@ -560,7 +577,7 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused uint bzero((caddr_t)&sinfo32, sizeof(sinfo32)); - siginfo_user_to_user32(&sinfo64,&sinfo32); + siginfo_user_to_user32_x86(&sinfo64,&sinfo32); #if CONFIG_DTRACE bzero((caddr_t)&(ut->t_dtrace_siginfo), sizeof(ut->t_dtrace_siginfo)); @@ -610,6 +627,8 @@ sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused uint goto bad; ml_fp_setvalid(FALSE); + /* Tell the PAL layer about the signal */ + pal_set_signal_delivery( thread ); proc_lock(p); @@ -645,8 +664,12 @@ int sigreturn(struct proc *p, struct sigreturn_args *uap, __unused int *retval) { union { - struct mcontext_avx32 mctx_avx32; - struct mcontext_avx64 mctx_avx64; + struct mcontext_avx32 mctx_avx32; + struct mcontext_avx64 mctx_avx64; +#if !defined(RC_HIDE_XNU_J137) + struct mcontext_avx512_32 mctx_avx512_32; + struct mcontext_avx512_64 mctx_avx512_64; +#endif } mctx_store, *mctxp = &mctx_store; thread_t thread = current_thread(); @@ -660,8 +683,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; + int rval = EJUSTRETURN; + xstate_t sig_xstate; ut = (struct uthread *)get_bsdthread_info(thread); @@ -678,7 +701,8 @@ sigreturn(struct proc *p, struct sigreturn_args *uap, __unused int *retval) } bzero(mctxp, sizeof(*mctxp)); - sig_avx = ml_fpu_avx_enabled(); + + sig_xstate = current_xstate(); if (proc_is64bit(p)) { struct user_ucontext64 uctx64; @@ -686,7 +710,7 @@ sigreturn(struct proc *p, struct sigreturn_args *uap, __unused int *retval) if ((error = copyin(uap->uctx, (void *)&uctx64, sizeof (uctx64)))) return(error); - if ((error = copyin(uctx64.uc_mcontext64, (void *)&mctxp->mctx_avx64, sizeof (struct mcontext_avx64)))) + if ((error = copyin(uctx64.uc_mcontext64, (void *)mctxp, thread_state64[sig_xstate].mcontext_size))) return(error); onstack = uctx64.uc_onstack & 01; @@ -696,15 +720,8 @@ sigreturn(struct proc *p, struct sigreturn_args *uap, __unused int *retval) ts_count = x86_THREAD_STATE64_COUNT; ts = (void *)&mctxp->mctx_avx64.ss; - 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_flavor = thread_state64[sig_xstate].flavor; + fs_count = thread_state64[sig_xstate].state_count; fs = (void *)&mctxp->mctx_avx64.fs; } else { @@ -713,7 +730,7 @@ sigreturn(struct proc *p, struct sigreturn_args *uap, __unused int *retval) if ((error = copyin(uap->uctx, (void *)&uctx32, sizeof (uctx32)))) return(error); - if ((error = copyin(CAST_USER_ADDR_T(uctx32.uc_mcontext), (void *)&mctxp->mctx_avx32, sizeof (struct mcontext_avx32)))) + if ((error = copyin(CAST_USER_ADDR_T(uctx32.uc_mcontext), (void *)mctxp, thread_state32[sig_xstate].mcontext_size))) return(error); onstack = uctx32.uc_onstack & 01; @@ -723,15 +740,8 @@ sigreturn(struct proc *p, struct sigreturn_args *uap, __unused int *retval) ts_count = x86_THREAD_STATE32_COUNT; ts = (void *)&mctxp->mctx_avx32.ss; - 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_flavor = thread_state32[sig_xstate].flavor; + fs_count = thread_state32[sig_xstate].state_count; fs = (void *)&mctxp->mctx_avx32.fs; }