The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/i386/exec_machdep.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-4-Clause
    3  *
    4  * Copyright (c) 2018 The FreeBSD Foundation
    5  * Copyright (c) 1992 Terrence R. Lambert.
    6  * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
    7  * All rights reserved.
    8  *
    9  * This code is derived from software contributed to Berkeley by
   10  * William Jolitz.
   11  *
   12  * Portions of this software were developed by A. Joseph Koshy under
   13  * sponsorship from the FreeBSD Foundation and Google, Inc.
   14  *
   15  * Redistribution and use in source and binary forms, with or without
   16  * modification, are permitted provided that the following conditions
   17  * are met:
   18  * 1. Redistributions of source code must retain the above copyright
   19  *    notice, this list of conditions and the following disclaimer.
   20  * 2. Redistributions in binary form must reproduce the above copyright
   21  *    notice, this list of conditions and the following disclaimer in the
   22  *    documentation and/or other materials provided with the distribution.
   23  * 3. All advertising materials mentioning features or use of this software
   24  *    must display the following acknowledgement:
   25  *      This product includes software developed by the University of
   26  *      California, Berkeley and its contributors.
   27  * 4. Neither the name of the University nor the names of its contributors
   28  *    may be used to endorse or promote products derived from this software
   29  *    without specific prior written permission.
   30  *
   31  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   32  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   33  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   34  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   35  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   39  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   40  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   41  * SUCH DAMAGE.
   42  *
   43  *      from: @(#)machdep.c     7.4 (Berkeley) 6/3/91
   44  */
   45 
   46 #include <sys/cdefs.h>
   47 __FBSDID("$FreeBSD$");
   48 
   49 #include "opt_cpu.h"
   50 #include "opt_ddb.h"
   51 #include "opt_kstack_pages.h"
   52 
   53 #include <sys/param.h>
   54 #include <sys/proc.h>
   55 #include <sys/systm.h>
   56 #include <sys/exec.h>
   57 #include <sys/imgact.h>
   58 #include <sys/kdb.h>
   59 #include <sys/kernel.h>
   60 #include <sys/ktr.h>
   61 #include <sys/linker.h>
   62 #include <sys/lock.h>
   63 #include <sys/malloc.h>
   64 #include <sys/mutex.h>
   65 #include <sys/pcpu.h>
   66 #include <sys/ptrace.h>
   67 #include <sys/reg.h>
   68 #include <sys/rwlock.h>
   69 #include <sys/signalvar.h>
   70 #include <sys/syscallsubr.h>
   71 #include <sys/sysctl.h>
   72 #include <sys/sysent.h>
   73 #include <sys/sysproto.h>
   74 #include <sys/ucontext.h>
   75 #include <sys/vmmeter.h>
   76 
   77 #include <vm/vm.h>
   78 #include <vm/vm_param.h>
   79 #include <vm/vm_extern.h>
   80 #include <vm/vm_kern.h>
   81 #include <vm/vm_page.h>
   82 #include <vm/vm_map.h>
   83 #include <vm/vm_object.h>
   84 
   85 #ifdef DDB
   86 #ifndef KDB
   87 #error KDB must be enabled in order for DDB to work!
   88 #endif
   89 #include <ddb/ddb.h>
   90 #include <ddb/db_sym.h>
   91 #endif
   92 
   93 #include <machine/cpu.h>
   94 #include <machine/cputypes.h>
   95 #include <machine/md_var.h>
   96 #include <machine/pcb.h>
   97 #include <machine/pcb_ext.h>
   98 #include <machine/proc.h>
   99 #include <machine/sigframe.h>
  100 #include <machine/specialreg.h>
  101 #include <machine/sysarch.h>
  102 #include <machine/trap.h>
  103 
  104 static void fpstate_drop(struct thread *td);
  105 static void get_fpcontext(struct thread *td, mcontext_t *mcp,
  106     char *xfpusave, size_t xfpusave_len);
  107 static int  set_fpcontext(struct thread *td, mcontext_t *mcp,
  108     char *xfpustate, size_t xfpustate_len);
  109 #ifdef COMPAT_43
  110 static void osendsig(sig_t catcher, ksiginfo_t *, sigset_t *mask);
  111 #endif
  112 #ifdef COMPAT_FREEBSD4
  113 static void freebsd4_sendsig(sig_t catcher, ksiginfo_t *, sigset_t *mask);
  114 #endif
  115 
  116 extern struct sysentvec elf32_freebsd_sysvec;
  117 
  118 _Static_assert(sizeof(mcontext_t) == 640, "mcontext_t size incorrect");
  119 _Static_assert(sizeof(ucontext_t) == 704, "ucontext_t size incorrect");
  120 _Static_assert(sizeof(siginfo_t) == 64, "siginfo_t size incorrect");
  121 
  122 /*
  123  * Send an interrupt to process.
  124  *
  125  * Stack is set up to allow sigcode stored at top to call routine,
  126  * followed by call to sigreturn routine below.  After sigreturn
  127  * resets the signal mask, the stack, and the frame pointer, it
  128  * returns to the user specified pc, psl.
  129  */
  130 #ifdef COMPAT_43
  131 static void
  132 osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
  133 {
  134         struct osigframe sf, *fp;
  135         struct proc *p;
  136         struct thread *td;
  137         struct sigacts *psp;
  138         struct trapframe *regs;
  139         int sig;
  140         int oonstack;
  141 
  142         td = curthread;
  143         p = td->td_proc;
  144         PROC_LOCK_ASSERT(p, MA_OWNED);
  145         sig = ksi->ksi_signo;
  146         psp = p->p_sigacts;
  147         mtx_assert(&psp->ps_mtx, MA_OWNED);
  148         regs = td->td_frame;
  149         oonstack = sigonstack(regs->tf_esp);
  150 
  151         /* Allocate space for the signal handler context. */
  152         if ((td->td_pflags & TDP_ALTSTACK) && !oonstack &&
  153             SIGISMEMBER(psp->ps_sigonstack, sig)) {
  154                 fp = (struct osigframe *)((uintptr_t)td->td_sigstk.ss_sp +
  155                     td->td_sigstk.ss_size - sizeof(struct osigframe));
  156 #if defined(COMPAT_43)
  157                 td->td_sigstk.ss_flags |= SS_ONSTACK;
  158 #endif
  159         } else
  160                 fp = (struct osigframe *)regs->tf_esp - 1;
  161 
  162         /* Build the argument list for the signal handler. */
  163         sf.sf_signum = sig;
  164         sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc;
  165         bzero(&sf.sf_siginfo, sizeof(sf.sf_siginfo));
  166         if (SIGISMEMBER(psp->ps_siginfo, sig)) {
  167                 /* Signal handler installed with SA_SIGINFO. */
  168                 sf.sf_arg2 = (register_t)&fp->sf_siginfo;
  169                 sf.sf_siginfo.si_signo = sig;
  170                 sf.sf_siginfo.si_code = ksi->ksi_code;
  171                 sf.sf_ahu.sf_action = (__osiginfohandler_t *)catcher;
  172                 sf.sf_addr = 0;
  173         } else {
  174                 /* Old FreeBSD-style arguments. */
  175                 sf.sf_arg2 = ksi->ksi_code;
  176                 sf.sf_addr = (register_t)ksi->ksi_addr;
  177                 sf.sf_ahu.sf_handler = catcher;
  178         }
  179         mtx_unlock(&psp->ps_mtx);
  180         PROC_UNLOCK(p);
  181 
  182         /* Save most if not all of trap frame. */
  183         sf.sf_siginfo.si_sc.sc_eax = regs->tf_eax;
  184         sf.sf_siginfo.si_sc.sc_ebx = regs->tf_ebx;
  185         sf.sf_siginfo.si_sc.sc_ecx = regs->tf_ecx;
  186         sf.sf_siginfo.si_sc.sc_edx = regs->tf_edx;
  187         sf.sf_siginfo.si_sc.sc_esi = regs->tf_esi;
  188         sf.sf_siginfo.si_sc.sc_edi = regs->tf_edi;
  189         sf.sf_siginfo.si_sc.sc_cs = regs->tf_cs;
  190         sf.sf_siginfo.si_sc.sc_ds = regs->tf_ds;
  191         sf.sf_siginfo.si_sc.sc_ss = regs->tf_ss;
  192         sf.sf_siginfo.si_sc.sc_es = regs->tf_es;
  193         sf.sf_siginfo.si_sc.sc_fs = regs->tf_fs;
  194         sf.sf_siginfo.si_sc.sc_gs = rgs();
  195         sf.sf_siginfo.si_sc.sc_isp = regs->tf_isp;
  196 
  197         /* Build the signal context to be used by osigreturn(). */
  198         sf.sf_siginfo.si_sc.sc_onstack = (oonstack) ? 1 : 0;
  199         SIG2OSIG(*mask, sf.sf_siginfo.si_sc.sc_mask);
  200         sf.sf_siginfo.si_sc.sc_sp = regs->tf_esp;
  201         sf.sf_siginfo.si_sc.sc_fp = regs->tf_ebp;
  202         sf.sf_siginfo.si_sc.sc_pc = regs->tf_eip;
  203         sf.sf_siginfo.si_sc.sc_ps = regs->tf_eflags;
  204         sf.sf_siginfo.si_sc.sc_trapno = regs->tf_trapno;
  205         sf.sf_siginfo.si_sc.sc_err = regs->tf_err;
  206 
  207         /*
  208          * If we're a vm86 process, we want to save the segment registers.
  209          * We also change eflags to be our emulated eflags, not the actual
  210          * eflags.
  211          */
  212         if (regs->tf_eflags & PSL_VM) {
  213                 /* XXX confusing names: `tf' isn't a trapframe; `regs' is. */
  214                 struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
  215                 struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86;
  216 
  217                 sf.sf_siginfo.si_sc.sc_gs = tf->tf_vm86_gs;
  218                 sf.sf_siginfo.si_sc.sc_fs = tf->tf_vm86_fs;
  219                 sf.sf_siginfo.si_sc.sc_es = tf->tf_vm86_es;
  220                 sf.sf_siginfo.si_sc.sc_ds = tf->tf_vm86_ds;
  221 
  222                 if (vm86->vm86_has_vme == 0)
  223                         sf.sf_siginfo.si_sc.sc_ps =
  224                             (tf->tf_eflags & ~(PSL_VIF | PSL_VIP)) |
  225                             (vm86->vm86_eflags & (PSL_VIF | PSL_VIP));
  226 
  227                 /* See sendsig() for comments. */
  228                 tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP);
  229         }
  230 
  231         /*
  232          * Copy the sigframe out to the user's stack.
  233          */
  234         if (copyout(&sf, fp, sizeof(*fp)) != 0) {
  235                 PROC_LOCK(p);
  236                 sigexit(td, SIGILL);
  237         }
  238 
  239         regs->tf_esp = (int)fp;
  240         if (PROC_HAS_SHP(p)) {
  241                 regs->tf_eip = PROC_SIGCODE(p) + szsigcode -
  242                     szosigcode;
  243         } else {
  244                 /* a.out sysentvec does not use shared page */
  245                 regs->tf_eip = PROC_PS_STRINGS(p) - szosigcode;
  246         }
  247         regs->tf_eflags &= ~(PSL_T | PSL_D);
  248         regs->tf_cs = _ucodesel;
  249         regs->tf_ds = _udatasel;
  250         regs->tf_es = _udatasel;
  251         regs->tf_fs = _udatasel;
  252         load_gs(_udatasel);
  253         regs->tf_ss = _udatasel;
  254         PROC_LOCK(p);
  255         mtx_lock(&psp->ps_mtx);
  256 }
  257 #endif /* COMPAT_43 */
  258 
  259 #ifdef COMPAT_FREEBSD4
  260 static void
  261 freebsd4_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
  262 {
  263         struct freebsd4_sigframe sf, *sfp;
  264         struct proc *p;
  265         struct thread *td;
  266         struct sigacts *psp;
  267         struct trapframe *regs;
  268         int sig;
  269         int oonstack;
  270 
  271         td = curthread;
  272         p = td->td_proc;
  273         PROC_LOCK_ASSERT(p, MA_OWNED);
  274         sig = ksi->ksi_signo;
  275         psp = p->p_sigacts;
  276         mtx_assert(&psp->ps_mtx, MA_OWNED);
  277         regs = td->td_frame;
  278         oonstack = sigonstack(regs->tf_esp);
  279 
  280         /* Save user context. */
  281         bzero(&sf, sizeof(sf));
  282         sf.sf_uc.uc_sigmask = *mask;
  283         sf.sf_uc.uc_stack = td->td_sigstk;
  284         sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
  285             ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
  286         sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
  287         sf.sf_uc.uc_mcontext.mc_gs = rgs();
  288         bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(*regs));
  289         bzero(sf.sf_uc.uc_mcontext.mc_fpregs,
  290             sizeof(sf.sf_uc.uc_mcontext.mc_fpregs));
  291         bzero(sf.sf_uc.uc_mcontext.__spare__,
  292             sizeof(sf.sf_uc.uc_mcontext.__spare__));
  293         bzero(sf.sf_uc.__spare__, sizeof(sf.sf_uc.__spare__));
  294 
  295         /* Allocate space for the signal handler context. */
  296         if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
  297             SIGISMEMBER(psp->ps_sigonstack, sig)) {
  298                 sfp = (struct freebsd4_sigframe *)((uintptr_t)td->td_sigstk.ss_sp +
  299                     td->td_sigstk.ss_size - sizeof(struct freebsd4_sigframe));
  300 #if defined(COMPAT_43)
  301                 td->td_sigstk.ss_flags |= SS_ONSTACK;
  302 #endif
  303         } else
  304                 sfp = (struct freebsd4_sigframe *)regs->tf_esp - 1;
  305 
  306         /* Build the argument list for the signal handler. */
  307         sf.sf_signum = sig;
  308         sf.sf_ucontext = (register_t)&sfp->sf_uc;
  309         bzero(&sf.sf_si, sizeof(sf.sf_si));
  310         if (SIGISMEMBER(psp->ps_siginfo, sig)) {
  311                 /* Signal handler installed with SA_SIGINFO. */
  312                 sf.sf_siginfo = (register_t)&sfp->sf_si;
  313                 sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
  314 
  315                 /* Fill in POSIX parts */
  316                 sf.sf_si.si_signo = sig;
  317                 sf.sf_si.si_code = ksi->ksi_code;
  318                 sf.sf_si.si_addr = ksi->ksi_addr;
  319         } else {
  320                 /* Old FreeBSD-style arguments. */
  321                 sf.sf_siginfo = ksi->ksi_code;
  322                 sf.sf_addr = (register_t)ksi->ksi_addr;
  323                 sf.sf_ahu.sf_handler = catcher;
  324         }
  325         mtx_unlock(&psp->ps_mtx);
  326         PROC_UNLOCK(p);
  327 
  328         /*
  329          * If we're a vm86 process, we want to save the segment registers.
  330          * We also change eflags to be our emulated eflags, not the actual
  331          * eflags.
  332          */
  333         if (regs->tf_eflags & PSL_VM) {
  334                 struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
  335                 struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86;
  336 
  337                 sf.sf_uc.uc_mcontext.mc_gs = tf->tf_vm86_gs;
  338                 sf.sf_uc.uc_mcontext.mc_fs = tf->tf_vm86_fs;
  339                 sf.sf_uc.uc_mcontext.mc_es = tf->tf_vm86_es;
  340                 sf.sf_uc.uc_mcontext.mc_ds = tf->tf_vm86_ds;
  341 
  342                 if (vm86->vm86_has_vme == 0)
  343                         sf.sf_uc.uc_mcontext.mc_eflags =
  344                             (tf->tf_eflags & ~(PSL_VIF | PSL_VIP)) |
  345                             (vm86->vm86_eflags & (PSL_VIF | PSL_VIP));
  346 
  347                 /*
  348                  * Clear PSL_NT to inhibit T_TSSFLT faults on return from
  349                  * syscalls made by the signal handler.  This just avoids
  350                  * wasting time for our lazy fixup of such faults.  PSL_NT
  351                  * does nothing in vm86 mode, but vm86 programs can set it
  352                  * almost legitimately in probes for old cpu types.
  353                  */
  354                 tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP);
  355         }
  356 
  357         /*
  358          * Copy the sigframe out to the user's stack.
  359          */
  360         if (copyout(&sf, sfp, sizeof(*sfp)) != 0) {
  361                 PROC_LOCK(p);
  362                 sigexit(td, SIGILL);
  363         }
  364 
  365         regs->tf_esp = (int)sfp;
  366         regs->tf_eip = PROC_SIGCODE(p) + szsigcode -
  367             szfreebsd4_sigcode;
  368         regs->tf_eflags &= ~(PSL_T | PSL_D);
  369         regs->tf_cs = _ucodesel;
  370         regs->tf_ds = _udatasel;
  371         regs->tf_es = _udatasel;
  372         regs->tf_fs = _udatasel;
  373         regs->tf_ss = _udatasel;
  374         PROC_LOCK(p);
  375         mtx_lock(&psp->ps_mtx);
  376 }
  377 #endif  /* COMPAT_FREEBSD4 */
  378 
  379 void
  380 sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
  381 {
  382         struct sigframe sf, *sfp;
  383         struct proc *p;
  384         struct thread *td;
  385         struct sigacts *psp;
  386         char *sp;
  387         struct trapframe *regs;
  388         struct segment_descriptor *sdp;
  389         char *xfpusave;
  390         size_t xfpusave_len;
  391         int sig;
  392         int oonstack;
  393 
  394         td = curthread;
  395         p = td->td_proc;
  396         PROC_LOCK_ASSERT(p, MA_OWNED);
  397         sig = ksi->ksi_signo;
  398         psp = p->p_sigacts;
  399         mtx_assert(&psp->ps_mtx, MA_OWNED);
  400 #ifdef COMPAT_FREEBSD4
  401         if (SIGISMEMBER(psp->ps_freebsd4, sig)) {
  402                 freebsd4_sendsig(catcher, ksi, mask);
  403                 return;
  404         }
  405 #endif
  406 #ifdef COMPAT_43
  407         if (SIGISMEMBER(psp->ps_osigset, sig)) {
  408                 osendsig(catcher, ksi, mask);
  409                 return;
  410         }
  411 #endif
  412         regs = td->td_frame;
  413         oonstack = sigonstack(regs->tf_esp);
  414 
  415         if (cpu_max_ext_state_size > sizeof(union savefpu) && use_xsave) {
  416                 xfpusave_len = cpu_max_ext_state_size - sizeof(union savefpu);
  417                 xfpusave = __builtin_alloca(xfpusave_len);
  418         } else {
  419                 xfpusave_len = 0;
  420                 xfpusave = NULL;
  421         }
  422 
  423         /* Save user context. */
  424         bzero(&sf, sizeof(sf));
  425         sf.sf_uc.uc_sigmask = *mask;
  426         sf.sf_uc.uc_stack = td->td_sigstk;
  427         sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
  428             ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
  429         sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
  430         sf.sf_uc.uc_mcontext.mc_gs = rgs();
  431         bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(*regs));
  432         sf.sf_uc.uc_mcontext.mc_len = sizeof(sf.sf_uc.uc_mcontext); /* magic */
  433         get_fpcontext(td, &sf.sf_uc.uc_mcontext, xfpusave, xfpusave_len);
  434         fpstate_drop(td);
  435         /*
  436          * Unconditionally fill the fsbase and gsbase into the mcontext.
  437          */
  438         sdp = &td->td_pcb->pcb_fsd;
  439         sf.sf_uc.uc_mcontext.mc_fsbase = sdp->sd_hibase << 24 |
  440             sdp->sd_lobase;
  441         sdp = &td->td_pcb->pcb_gsd;
  442         sf.sf_uc.uc_mcontext.mc_gsbase = sdp->sd_hibase << 24 |
  443             sdp->sd_lobase;
  444         bzero(sf.sf_uc.uc_mcontext.mc_spare2,
  445             sizeof(sf.sf_uc.uc_mcontext.mc_spare2));
  446 
  447         /* Allocate space for the signal handler context. */
  448         if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
  449             SIGISMEMBER(psp->ps_sigonstack, sig)) {
  450                 sp = (char *)td->td_sigstk.ss_sp + td->td_sigstk.ss_size;
  451 #if defined(COMPAT_43)
  452                 td->td_sigstk.ss_flags |= SS_ONSTACK;
  453 #endif
  454         } else
  455                 sp = (char *)regs->tf_esp - 128;
  456         if (xfpusave != NULL) {
  457                 sp -= xfpusave_len;
  458                 sp = (char *)((unsigned int)sp & ~0x3F);
  459                 sf.sf_uc.uc_mcontext.mc_xfpustate = (register_t)sp;
  460         }
  461         sp -= sizeof(struct sigframe);
  462 
  463         /* Align to 16 bytes. */
  464         sfp = (struct sigframe *)((unsigned int)sp & ~0xF);
  465 
  466         /* Build the argument list for the signal handler. */
  467         sf.sf_signum = sig;
  468         sf.sf_ucontext = (register_t)&sfp->sf_uc;
  469         bzero(&sf.sf_si, sizeof(sf.sf_si));
  470         if (SIGISMEMBER(psp->ps_siginfo, sig)) {
  471                 /* Signal handler installed with SA_SIGINFO. */
  472                 sf.sf_siginfo = (register_t)&sfp->sf_si;
  473                 sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
  474 
  475                 /* Fill in POSIX parts */
  476                 sf.sf_si = ksi->ksi_info;
  477                 sf.sf_si.si_signo = sig; /* maybe a translated signal */
  478         } else {
  479                 /* Old FreeBSD-style arguments. */
  480                 sf.sf_siginfo = ksi->ksi_code;
  481                 sf.sf_addr = (register_t)ksi->ksi_addr;
  482                 sf.sf_ahu.sf_handler = catcher;
  483         }
  484         mtx_unlock(&psp->ps_mtx);
  485         PROC_UNLOCK(p);
  486 
  487         /*
  488          * If we're a vm86 process, we want to save the segment registers.
  489          * We also change eflags to be our emulated eflags, not the actual
  490          * eflags.
  491          */
  492         if (regs->tf_eflags & PSL_VM) {
  493                 struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
  494                 struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86;
  495 
  496                 sf.sf_uc.uc_mcontext.mc_gs = tf->tf_vm86_gs;
  497                 sf.sf_uc.uc_mcontext.mc_fs = tf->tf_vm86_fs;
  498                 sf.sf_uc.uc_mcontext.mc_es = tf->tf_vm86_es;
  499                 sf.sf_uc.uc_mcontext.mc_ds = tf->tf_vm86_ds;
  500 
  501                 if (vm86->vm86_has_vme == 0)
  502                         sf.sf_uc.uc_mcontext.mc_eflags =
  503                             (tf->tf_eflags & ~(PSL_VIF | PSL_VIP)) |
  504                             (vm86->vm86_eflags & (PSL_VIF | PSL_VIP));
  505 
  506                 /*
  507                  * Clear PSL_NT to inhibit T_TSSFLT faults on return from
  508                  * syscalls made by the signal handler.  This just avoids
  509                  * wasting time for our lazy fixup of such faults.  PSL_NT
  510                  * does nothing in vm86 mode, but vm86 programs can set it
  511                  * almost legitimately in probes for old cpu types.
  512                  */
  513                 tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP);
  514         }
  515 
  516         /*
  517          * Copy the sigframe out to the user's stack.
  518          */
  519         if (copyout(&sf, sfp, sizeof(*sfp)) != 0 ||
  520             (xfpusave != NULL && copyout(xfpusave,
  521             (void *)sf.sf_uc.uc_mcontext.mc_xfpustate, xfpusave_len)
  522             != 0)) {
  523                 PROC_LOCK(p);
  524                 sigexit(td, SIGILL);
  525         }
  526 
  527         regs->tf_esp = (int)sfp;
  528         regs->tf_eip = PROC_SIGCODE(p);
  529         if (regs->tf_eip == 0)
  530                 regs->tf_eip = PROC_PS_STRINGS(p) - szsigcode;
  531         regs->tf_eflags &= ~(PSL_T | PSL_D);
  532         regs->tf_cs = _ucodesel;
  533         regs->tf_ds = _udatasel;
  534         regs->tf_es = _udatasel;
  535         regs->tf_fs = _udatasel;
  536         regs->tf_ss = _udatasel;
  537         PROC_LOCK(p);
  538         mtx_lock(&psp->ps_mtx);
  539 }
  540 
  541 /*
  542  * System call to cleanup state after a signal has been taken.  Reset
  543  * signal mask and stack state from context left by sendsig (above).
  544  * Return to previous pc and psl as specified by context left by
  545  * sendsig. Check carefully to make sure that the user has not
  546  * modified the state to gain improper privileges.
  547  */
  548 #ifdef COMPAT_43
  549 int
  550 osigreturn(struct thread *td, struct osigreturn_args *uap)
  551 {
  552         struct osigcontext sc;
  553         struct trapframe *regs;
  554         struct osigcontext *scp;
  555         int eflags, error;
  556         ksiginfo_t ksi;
  557 
  558         regs = td->td_frame;
  559         error = copyin(uap->sigcntxp, &sc, sizeof(sc));
  560         if (error != 0)
  561                 return (error);
  562         scp = &sc;
  563         eflags = scp->sc_ps;
  564         if (eflags & PSL_VM) {
  565                 struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
  566                 struct vm86_kernel *vm86;
  567 
  568                 /*
  569                  * if pcb_ext == 0 or vm86_inited == 0, the user hasn't
  570                  * set up the vm86 area, and we can't enter vm86 mode.
  571                  */
  572                 if (td->td_pcb->pcb_ext == 0)
  573                         return (EINVAL);
  574                 vm86 = &td->td_pcb->pcb_ext->ext_vm86;
  575                 if (vm86->vm86_inited == 0)
  576                         return (EINVAL);
  577 
  578                 /* Go back to user mode if both flags are set. */
  579                 if ((eflags & PSL_VIP) && (eflags & PSL_VIF)) {
  580                         ksiginfo_init_trap(&ksi);
  581                         ksi.ksi_signo = SIGBUS;
  582                         ksi.ksi_code = BUS_OBJERR;
  583                         ksi.ksi_addr = (void *)regs->tf_eip;
  584                         trapsignal(td, &ksi);
  585                 }
  586 
  587                 if (vm86->vm86_has_vme) {
  588                         eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
  589                             (eflags & VME_USERCHANGE) | PSL_VM;
  590                 } else {
  591                         vm86->vm86_eflags = eflags;     /* save VIF, VIP */
  592                         eflags = (tf->tf_eflags & ~VM_USERCHANGE) |
  593                             (eflags & VM_USERCHANGE) | PSL_VM;
  594                 }
  595                 tf->tf_vm86_ds = scp->sc_ds;
  596                 tf->tf_vm86_es = scp->sc_es;
  597                 tf->tf_vm86_fs = scp->sc_fs;
  598                 tf->tf_vm86_gs = scp->sc_gs;
  599                 tf->tf_ds = _udatasel;
  600                 tf->tf_es = _udatasel;
  601                 tf->tf_fs = _udatasel;
  602         } else {
  603                 /*
  604                  * Don't allow users to change privileged or reserved flags.
  605                  */
  606                 if (!EFL_SECURE(eflags, regs->tf_eflags)) {
  607                         return (EINVAL);
  608                 }
  609 
  610                 /*
  611                  * Don't allow users to load a valid privileged %cs.  Let the
  612                  * hardware check for invalid selectors, excess privilege in
  613                  * other selectors, invalid %eip's and invalid %esp's.
  614                  */
  615                 if (!CS_SECURE(scp->sc_cs)) {
  616                         ksiginfo_init_trap(&ksi);
  617                         ksi.ksi_signo = SIGBUS;
  618                         ksi.ksi_code = BUS_OBJERR;
  619                         ksi.ksi_trapno = T_PROTFLT;
  620                         ksi.ksi_addr = (void *)regs->tf_eip;
  621                         trapsignal(td, &ksi);
  622                         return (EINVAL);
  623                 }
  624                 regs->tf_ds = scp->sc_ds;
  625                 regs->tf_es = scp->sc_es;
  626                 regs->tf_fs = scp->sc_fs;
  627         }
  628 
  629         /* Restore remaining registers. */
  630         regs->tf_eax = scp->sc_eax;
  631         regs->tf_ebx = scp->sc_ebx;
  632         regs->tf_ecx = scp->sc_ecx;
  633         regs->tf_edx = scp->sc_edx;
  634         regs->tf_esi = scp->sc_esi;
  635         regs->tf_edi = scp->sc_edi;
  636         regs->tf_cs = scp->sc_cs;
  637         regs->tf_ss = scp->sc_ss;
  638         regs->tf_isp = scp->sc_isp;
  639         regs->tf_ebp = scp->sc_fp;
  640         regs->tf_esp = scp->sc_sp;
  641         regs->tf_eip = scp->sc_pc;
  642         regs->tf_eflags = eflags;
  643         regs->tf_trapno = T_RESERVED;
  644 
  645 #if defined(COMPAT_43)
  646         if (scp->sc_onstack & 1)
  647                 td->td_sigstk.ss_flags |= SS_ONSTACK;
  648         else
  649                 td->td_sigstk.ss_flags &= ~SS_ONSTACK;
  650 #endif
  651         kern_sigprocmask(td, SIG_SETMASK, (sigset_t *)&scp->sc_mask, NULL,
  652             SIGPROCMASK_OLD);
  653         return (EJUSTRETURN);
  654 }
  655 #endif /* COMPAT_43 */
  656 
  657 #ifdef COMPAT_FREEBSD4
  658 int
  659 freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap)
  660 {
  661         struct freebsd4_ucontext uc;
  662         struct trapframe *regs;
  663         struct freebsd4_ucontext *ucp;
  664         int cs, eflags, error;
  665         ksiginfo_t ksi;
  666 
  667         error = copyin(uap->sigcntxp, &uc, sizeof(uc));
  668         if (error != 0)
  669                 return (error);
  670         ucp = &uc;
  671         regs = td->td_frame;
  672         eflags = ucp->uc_mcontext.mc_eflags;
  673         if (eflags & PSL_VM) {
  674                 struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
  675                 struct vm86_kernel *vm86;
  676 
  677                 /*
  678                  * if pcb_ext == 0 or vm86_inited == 0, the user hasn't
  679                  * set up the vm86 area, and we can't enter vm86 mode.
  680                  */
  681                 if (td->td_pcb->pcb_ext == 0)
  682                         return (EINVAL);
  683                 vm86 = &td->td_pcb->pcb_ext->ext_vm86;
  684                 if (vm86->vm86_inited == 0)
  685                         return (EINVAL);
  686 
  687                 /* Go back to user mode if both flags are set. */
  688                 if ((eflags & PSL_VIP) && (eflags & PSL_VIF)) {
  689                         ksiginfo_init_trap(&ksi);
  690                         ksi.ksi_signo = SIGBUS;
  691                         ksi.ksi_code = BUS_OBJERR;
  692                         ksi.ksi_addr = (void *)regs->tf_eip;
  693                         trapsignal(td, &ksi);
  694                 }
  695                 if (vm86->vm86_has_vme) {
  696                         eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
  697                             (eflags & VME_USERCHANGE) | PSL_VM;
  698                 } else {
  699                         vm86->vm86_eflags = eflags;     /* save VIF, VIP */
  700                         eflags = (tf->tf_eflags & ~VM_USERCHANGE) |
  701                             (eflags & VM_USERCHANGE) | PSL_VM;
  702                 }
  703                 bcopy(&ucp->uc_mcontext.mc_fs, tf, sizeof(struct trapframe));
  704                 tf->tf_eflags = eflags;
  705                 tf->tf_vm86_ds = tf->tf_ds;
  706                 tf->tf_vm86_es = tf->tf_es;
  707                 tf->tf_vm86_fs = tf->tf_fs;
  708                 tf->tf_vm86_gs = ucp->uc_mcontext.mc_gs;
  709                 tf->tf_ds = _udatasel;
  710                 tf->tf_es = _udatasel;
  711                 tf->tf_fs = _udatasel;
  712         } else {
  713                 /*
  714                  * Don't allow users to change privileged or reserved flags.
  715                  */
  716                 if (!EFL_SECURE(eflags, regs->tf_eflags)) {
  717                         uprintf(
  718                             "pid %d (%s): freebsd4_sigreturn eflags = 0x%x\n",
  719                             td->td_proc->p_pid, td->td_name, eflags);
  720                         return (EINVAL);
  721                 }
  722 
  723                 /*
  724                  * Don't allow users to load a valid privileged %cs.  Let the
  725                  * hardware check for invalid selectors, excess privilege in
  726                  * other selectors, invalid %eip's and invalid %esp's.
  727                  */
  728                 cs = ucp->uc_mcontext.mc_cs;
  729                 if (!CS_SECURE(cs)) {
  730                         uprintf("pid %d (%s): freebsd4_sigreturn cs = 0x%x\n",
  731                             td->td_proc->p_pid, td->td_name, cs);
  732                         ksiginfo_init_trap(&ksi);
  733                         ksi.ksi_signo = SIGBUS;
  734                         ksi.ksi_code = BUS_OBJERR;
  735                         ksi.ksi_trapno = T_PROTFLT;
  736                         ksi.ksi_addr = (void *)regs->tf_eip;
  737                         trapsignal(td, &ksi);
  738                         return (EINVAL);
  739                 }
  740 
  741                 bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs));
  742         }
  743         regs->tf_trapno = T_RESERVED;
  744 
  745 #if defined(COMPAT_43)
  746         if (ucp->uc_mcontext.mc_onstack & 1)
  747                 td->td_sigstk.ss_flags |= SS_ONSTACK;
  748         else
  749                 td->td_sigstk.ss_flags &= ~SS_ONSTACK;
  750 #endif
  751         kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0);
  752         return (EJUSTRETURN);
  753 }
  754 #endif  /* COMPAT_FREEBSD4 */
  755 
  756 int
  757 sys_sigreturn(struct thread *td, struct sigreturn_args *uap)
  758 {
  759         ucontext_t uc;
  760         struct proc *p;
  761         struct trapframe *regs;
  762         ucontext_t *ucp;
  763         char *xfpustate;
  764         size_t xfpustate_len;
  765         int cs, eflags, error, ret;
  766         ksiginfo_t ksi;
  767 
  768         p = td->td_proc;
  769 
  770         error = copyin(uap->sigcntxp, &uc, sizeof(uc));
  771         if (error != 0)
  772                 return (error);
  773         ucp = &uc;
  774         if ((ucp->uc_mcontext.mc_flags & ~_MC_FLAG_MASK) != 0) {
  775                 uprintf("pid %d (%s): sigreturn mc_flags %x\n", p->p_pid,
  776                     td->td_name, ucp->uc_mcontext.mc_flags);
  777                 return (EINVAL);
  778         }
  779         regs = td->td_frame;
  780         eflags = ucp->uc_mcontext.mc_eflags;
  781         if (eflags & PSL_VM) {
  782                 struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
  783                 struct vm86_kernel *vm86;
  784 
  785                 /*
  786                  * if pcb_ext == 0 or vm86_inited == 0, the user hasn't
  787                  * set up the vm86 area, and we can't enter vm86 mode.
  788                  */
  789                 if (td->td_pcb->pcb_ext == 0)
  790                         return (EINVAL);
  791                 vm86 = &td->td_pcb->pcb_ext->ext_vm86;
  792                 if (vm86->vm86_inited == 0)
  793                         return (EINVAL);
  794 
  795                 /* Go back to user mode if both flags are set. */
  796                 if ((eflags & PSL_VIP) && (eflags & PSL_VIF)) {
  797                         ksiginfo_init_trap(&ksi);
  798                         ksi.ksi_signo = SIGBUS;
  799                         ksi.ksi_code = BUS_OBJERR;
  800                         ksi.ksi_addr = (void *)regs->tf_eip;
  801                         trapsignal(td, &ksi);
  802                 }
  803 
  804                 if (vm86->vm86_has_vme) {
  805                         eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
  806                             (eflags & VME_USERCHANGE) | PSL_VM;
  807                 } else {
  808                         vm86->vm86_eflags = eflags;     /* save VIF, VIP */
  809                         eflags = (tf->tf_eflags & ~VM_USERCHANGE) |
  810                             (eflags & VM_USERCHANGE) | PSL_VM;
  811                 }
  812                 bcopy(&ucp->uc_mcontext.mc_fs, tf, sizeof(struct trapframe));
  813                 tf->tf_eflags = eflags;
  814                 tf->tf_vm86_ds = tf->tf_ds;
  815                 tf->tf_vm86_es = tf->tf_es;
  816                 tf->tf_vm86_fs = tf->tf_fs;
  817                 tf->tf_vm86_gs = ucp->uc_mcontext.mc_gs;
  818                 tf->tf_ds = _udatasel;
  819                 tf->tf_es = _udatasel;
  820                 tf->tf_fs = _udatasel;
  821         } else {
  822                 /*
  823                  * Don't allow users to change privileged or reserved flags.
  824                  */
  825                 if (!EFL_SECURE(eflags, regs->tf_eflags)) {
  826                         uprintf("pid %d (%s): sigreturn eflags = 0x%x\n",
  827                             td->td_proc->p_pid, td->td_name, eflags);
  828                         return (EINVAL);
  829                 }
  830 
  831                 /*
  832                  * Don't allow users to load a valid privileged %cs.  Let the
  833                  * hardware check for invalid selectors, excess privilege in
  834                  * other selectors, invalid %eip's and invalid %esp's.
  835                  */
  836                 cs = ucp->uc_mcontext.mc_cs;
  837                 if (!CS_SECURE(cs)) {
  838                         uprintf("pid %d (%s): sigreturn cs = 0x%x\n",
  839                             td->td_proc->p_pid, td->td_name, cs);
  840                         ksiginfo_init_trap(&ksi);
  841                         ksi.ksi_signo = SIGBUS;
  842                         ksi.ksi_code = BUS_OBJERR;
  843                         ksi.ksi_trapno = T_PROTFLT;
  844                         ksi.ksi_addr = (void *)regs->tf_eip;
  845                         trapsignal(td, &ksi);
  846                         return (EINVAL);
  847                 }
  848 
  849                 if ((uc.uc_mcontext.mc_flags & _MC_HASFPXSTATE) != 0) {
  850                         xfpustate_len = uc.uc_mcontext.mc_xfpustate_len;
  851                         if (xfpustate_len > cpu_max_ext_state_size -
  852                             sizeof(union savefpu)) {
  853                                 uprintf(
  854                             "pid %d (%s): sigreturn xfpusave_len = 0x%zx\n",
  855                                     p->p_pid, td->td_name, xfpustate_len);
  856                                 return (EINVAL);
  857                         }
  858                         xfpustate = __builtin_alloca(xfpustate_len);
  859                         error = copyin(
  860                             (const void *)uc.uc_mcontext.mc_xfpustate,
  861                             xfpustate, xfpustate_len);
  862                         if (error != 0) {
  863                                 uprintf(
  864         "pid %d (%s): sigreturn copying xfpustate failed\n",
  865                                     p->p_pid, td->td_name);
  866                                 return (error);
  867                         }
  868                 } else {
  869                         xfpustate = NULL;
  870                         xfpustate_len = 0;
  871                 }
  872                 ret = set_fpcontext(td, &ucp->uc_mcontext, xfpustate,
  873                     xfpustate_len);
  874                 if (ret != 0)
  875                         return (ret);
  876                 bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs));
  877         }
  878         regs->tf_trapno = T_RESERVED;
  879 
  880 #if defined(COMPAT_43)
  881         if (ucp->uc_mcontext.mc_onstack & 1)
  882                 td->td_sigstk.ss_flags |= SS_ONSTACK;
  883         else
  884                 td->td_sigstk.ss_flags &= ~SS_ONSTACK;
  885 #endif
  886 
  887         kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0);
  888         return (EJUSTRETURN);
  889 }
  890 
  891 /*
  892  * Reset the hardware debug registers if they were in use.
  893  * They won't have any meaning for the newly exec'd process.
  894  */
  895 void
  896 x86_clear_dbregs(struct pcb *pcb)
  897 {
  898         if ((pcb->pcb_flags & PCB_DBREGS) == 0)
  899                 return;
  900 
  901         pcb->pcb_dr0 = 0;
  902         pcb->pcb_dr1 = 0;
  903         pcb->pcb_dr2 = 0;
  904         pcb->pcb_dr3 = 0;
  905         pcb->pcb_dr6 = 0;
  906         pcb->pcb_dr7 = 0;
  907 
  908         if (pcb == curpcb) {
  909                 /*
  910                  * Clear the debug registers on the running CPU,
  911                  * otherwise they will end up affecting the next
  912                  * process we switch to.
  913                  */
  914                 reset_dbregs();
  915         }
  916         pcb->pcb_flags &= ~PCB_DBREGS;
  917 }
  918 
  919 #ifdef COMPAT_43
  920 static void
  921 setup_priv_lcall_gate(struct proc *p)
  922 {
  923         struct i386_ldt_args uap;
  924         union descriptor desc;
  925         u_int lcall_addr;
  926 
  927         bzero(&uap, sizeof(uap));
  928         uap.start = 0;
  929         uap.num = 1;
  930         lcall_addr = p->p_sysent->sv_psstrings - sz_lcall_tramp;
  931         bzero(&desc, sizeof(desc));
  932         desc.sd.sd_type = SDT_MEMERA;
  933         desc.sd.sd_dpl = SEL_UPL;
  934         desc.sd.sd_p = 1;
  935         desc.sd.sd_def32 = 1;
  936         desc.sd.sd_gran = 1;
  937         desc.sd.sd_lolimit = 0xffff;
  938         desc.sd.sd_hilimit = 0xf;
  939         desc.sd.sd_lobase = lcall_addr;
  940         desc.sd.sd_hibase = lcall_addr >> 24;
  941         i386_set_ldt(curthread, &uap, &desc);
  942 }
  943 #endif
  944 
  945 /*
  946  * Reset registers to default values on exec.
  947  */
  948 void
  949 exec_setregs(struct thread *td, struct image_params *imgp, uintptr_t stack)
  950 {
  951         struct trapframe *regs;
  952         struct pcb *pcb;
  953         register_t saved_eflags;
  954 
  955         regs = td->td_frame;
  956         pcb = td->td_pcb;
  957 
  958         /* Reset pc->pcb_gs and %gs before possibly invalidating it. */
  959         pcb->pcb_gs = _udatasel;
  960         load_gs(_udatasel);
  961 
  962         mtx_lock_spin(&dt_lock);
  963         if (td->td_proc->p_md.md_ldt != NULL)
  964                 user_ldt_free(td);
  965         else
  966                 mtx_unlock_spin(&dt_lock);
  967 
  968 #ifdef COMPAT_43
  969         if (td->td_proc->p_sysent->sv_psstrings !=
  970             elf32_freebsd_sysvec.sv_psstrings)
  971                 setup_priv_lcall_gate(td->td_proc);
  972 #endif
  973 
  974         /*
  975          * Reset the fs and gs bases.  The values from the old address
  976          * space do not make sense for the new program.  In particular,
  977          * gsbase might be the TLS base for the old program but the new
  978          * program has no TLS now.
  979          */
  980         set_fsbase(td, 0);
  981         set_gsbase(td, 0);
  982 
  983         /* Make sure edx is 0x0 on entry. Linux binaries depend on it. */
  984         saved_eflags = regs->tf_eflags & PSL_T;
  985         bzero((char *)regs, sizeof(struct trapframe));
  986         regs->tf_eip = imgp->entry_addr;
  987         regs->tf_esp = stack;
  988         regs->tf_eflags = PSL_USER | saved_eflags;
  989         regs->tf_ss = _udatasel;
  990         regs->tf_ds = _udatasel;
  991         regs->tf_es = _udatasel;
  992         regs->tf_fs = _udatasel;
  993         regs->tf_cs = _ucodesel;
  994 
  995         /* PS_STRINGS value for BSD/OS binaries.  It is 0 for non-BSD/OS. */
  996         regs->tf_ebx = (register_t)imgp->ps_strings;
  997 
  998         x86_clear_dbregs(pcb);
  999 
 1000         pcb->pcb_initial_npxcw = __INITIAL_NPXCW__;
 1001 
 1002         /*
 1003          * Drop the FP state if we hold it, so that the process gets a
 1004          * clean FP state if it uses the FPU again.
 1005          */
 1006         fpstate_drop(td);
 1007 }
 1008 
 1009 int
 1010 fill_regs(struct thread *td, struct reg *regs)
 1011 {
 1012         struct pcb *pcb;
 1013         struct trapframe *tp;
 1014 
 1015         tp = td->td_frame;
 1016         pcb = td->td_pcb;
 1017         regs->r_gs = pcb->pcb_gs;
 1018         return (fill_frame_regs(tp, regs));
 1019 }
 1020 
 1021 int
 1022 fill_frame_regs(struct trapframe *tp, struct reg *regs)
 1023 {
 1024 
 1025         regs->r_fs = tp->tf_fs;
 1026         regs->r_es = tp->tf_es;
 1027         regs->r_ds = tp->tf_ds;
 1028         regs->r_edi = tp->tf_edi;
 1029         regs->r_esi = tp->tf_esi;
 1030         regs->r_ebp = tp->tf_ebp;
 1031         regs->r_ebx = tp->tf_ebx;
 1032         regs->r_edx = tp->tf_edx;
 1033         regs->r_ecx = tp->tf_ecx;
 1034         regs->r_eax = tp->tf_eax;
 1035         regs->r_eip = tp->tf_eip;
 1036         regs->r_cs = tp->tf_cs;
 1037         regs->r_eflags = tp->tf_eflags;
 1038         regs->r_esp = tp->tf_esp;
 1039         regs->r_ss = tp->tf_ss;
 1040         regs->r_err = 0;
 1041         regs->r_trapno = 0;
 1042         return (0);
 1043 }
 1044 
 1045 int
 1046 set_regs(struct thread *td, struct reg *regs)
 1047 {
 1048         struct pcb *pcb;
 1049         struct trapframe *tp;
 1050 
 1051         tp = td->td_frame;
 1052         if (!EFL_SECURE(regs->r_eflags, tp->tf_eflags) ||
 1053             !CS_SECURE(regs->r_cs))
 1054                 return (EINVAL);
 1055         pcb = td->td_pcb;
 1056         tp->tf_fs = regs->r_fs;
 1057         tp->tf_es = regs->r_es;
 1058         tp->tf_ds = regs->r_ds;
 1059         tp->tf_edi = regs->r_edi;
 1060         tp->tf_esi = regs->r_esi;
 1061         tp->tf_ebp = regs->r_ebp;
 1062         tp->tf_ebx = regs->r_ebx;
 1063         tp->tf_edx = regs->r_edx;
 1064         tp->tf_ecx = regs->r_ecx;
 1065         tp->tf_eax = regs->r_eax;
 1066         tp->tf_eip = regs->r_eip;
 1067         tp->tf_cs = regs->r_cs;
 1068         tp->tf_eflags = regs->r_eflags;
 1069         tp->tf_esp = regs->r_esp;
 1070         tp->tf_ss = regs->r_ss;
 1071         pcb->pcb_gs = regs->r_gs;
 1072         return (0);
 1073 }
 1074 
 1075 int
 1076 fill_fpregs(struct thread *td, struct fpreg *fpregs)
 1077 {
 1078 
 1079         KASSERT(td == curthread || TD_IS_SUSPENDED(td) ||
 1080             P_SHOULDSTOP(td->td_proc),
 1081             ("not suspended thread %p", td));
 1082         npxgetregs(td);
 1083         if (cpu_fxsr)
 1084                 npx_fill_fpregs_xmm(&get_pcb_user_save_td(td)->sv_xmm,
 1085                     (struct save87 *)fpregs);
 1086         else
 1087                 bcopy(&get_pcb_user_save_td(td)->sv_87, fpregs,
 1088                     sizeof(*fpregs));
 1089         return (0);
 1090 }
 1091 
 1092 int
 1093 set_fpregs(struct thread *td, struct fpreg *fpregs)
 1094 {
 1095 
 1096         critical_enter();
 1097         if (cpu_fxsr)
 1098                 npx_set_fpregs_xmm((struct save87 *)fpregs,
 1099                     &get_pcb_user_save_td(td)->sv_xmm);
 1100         else
 1101                 bcopy(fpregs, &get_pcb_user_save_td(td)->sv_87,
 1102                     sizeof(*fpregs));
 1103         npxuserinited(td);
 1104         critical_exit();
 1105         return (0);
 1106 }
 1107 
 1108 /*
 1109  * Get machine context.
 1110  */
 1111 int
 1112 get_mcontext(struct thread *td, mcontext_t *mcp, int flags)
 1113 {
 1114         struct trapframe *tp;
 1115         struct segment_descriptor *sdp;
 1116 
 1117         tp = td->td_frame;
 1118 
 1119         PROC_LOCK(curthread->td_proc);
 1120         mcp->mc_onstack = sigonstack(tp->tf_esp);
 1121         PROC_UNLOCK(curthread->td_proc);
 1122         mcp->mc_gs = td->td_pcb->pcb_gs;
 1123         mcp->mc_fs = tp->tf_fs;
 1124         mcp->mc_es = tp->tf_es;
 1125         mcp->mc_ds = tp->tf_ds;
 1126         mcp->mc_edi = tp->tf_edi;
 1127         mcp->mc_esi = tp->tf_esi;
 1128         mcp->mc_ebp = tp->tf_ebp;
 1129         mcp->mc_isp = tp->tf_isp;
 1130         mcp->mc_eflags = tp->tf_eflags;
 1131         if (flags & GET_MC_CLEAR_RET) {
 1132                 mcp->mc_eax = 0;
 1133                 mcp->mc_edx = 0;
 1134                 mcp->mc_eflags &= ~PSL_C;
 1135         } else {
 1136                 mcp->mc_eax = tp->tf_eax;
 1137                 mcp->mc_edx = tp->tf_edx;
 1138         }
 1139         mcp->mc_ebx = tp->tf_ebx;
 1140         mcp->mc_ecx = tp->tf_ecx;
 1141         mcp->mc_eip = tp->tf_eip;
 1142         mcp->mc_cs = tp->tf_cs;
 1143         mcp->mc_esp = tp->tf_esp;
 1144         mcp->mc_ss = tp->tf_ss;
 1145         mcp->mc_len = sizeof(*mcp);
 1146         get_fpcontext(td, mcp, NULL, 0);
 1147         sdp = &td->td_pcb->pcb_fsd;
 1148         mcp->mc_fsbase = sdp->sd_hibase << 24 | sdp->sd_lobase;
 1149         sdp = &td->td_pcb->pcb_gsd;
 1150         mcp->mc_gsbase = sdp->sd_hibase << 24 | sdp->sd_lobase;
 1151         mcp->mc_flags = 0;
 1152         mcp->mc_xfpustate = 0;
 1153         mcp->mc_xfpustate_len = 0;
 1154         bzero(mcp->mc_spare2, sizeof(mcp->mc_spare2));
 1155         return (0);
 1156 }
 1157 
 1158 /*
 1159  * Set machine context.
 1160  *
 1161  * However, we don't set any but the user modifiable flags, and we won't
 1162  * touch the cs selector.
 1163  */
 1164 int
 1165 set_mcontext(struct thread *td, mcontext_t *mcp)
 1166 {
 1167         struct trapframe *tp;
 1168         char *xfpustate;
 1169         int eflags, ret;
 1170 
 1171         tp = td->td_frame;
 1172         if (mcp->mc_len != sizeof(*mcp) ||
 1173             (mcp->mc_flags & ~_MC_FLAG_MASK) != 0)
 1174                 return (EINVAL);
 1175         eflags = (mcp->mc_eflags & PSL_USERCHANGE) |
 1176             (tp->tf_eflags & ~PSL_USERCHANGE);
 1177         if (mcp->mc_flags & _MC_HASFPXSTATE) {
 1178                 if (mcp->mc_xfpustate_len > cpu_max_ext_state_size -
 1179                     sizeof(union savefpu))
 1180                         return (EINVAL);
 1181                 xfpustate = __builtin_alloca(mcp->mc_xfpustate_len);
 1182                 ret = copyin((void *)mcp->mc_xfpustate, xfpustate,
 1183                     mcp->mc_xfpustate_len);
 1184                 if (ret != 0)
 1185                         return (ret);
 1186         } else
 1187                 xfpustate = NULL;
 1188         ret = set_fpcontext(td, mcp, xfpustate, mcp->mc_xfpustate_len);
 1189         if (ret != 0)
 1190                 return (ret);
 1191         tp->tf_fs = mcp->mc_fs;
 1192         tp->tf_es = mcp->mc_es;
 1193         tp->tf_ds = mcp->mc_ds;
 1194         tp->tf_edi = mcp->mc_edi;
 1195         tp->tf_esi = mcp->mc_esi;
 1196         tp->tf_ebp = mcp->mc_ebp;
 1197         tp->tf_ebx = mcp->mc_ebx;
 1198         tp->tf_edx = mcp->mc_edx;
 1199         tp->tf_ecx = mcp->mc_ecx;
 1200         tp->tf_eax = mcp->mc_eax;
 1201         tp->tf_eip = mcp->mc_eip;
 1202         tp->tf_eflags = eflags;
 1203         tp->tf_esp = mcp->mc_esp;
 1204         tp->tf_ss = mcp->mc_ss;
 1205         td->td_pcb->pcb_gs = mcp->mc_gs;
 1206         return (0);
 1207 }
 1208 
 1209 static void
 1210 get_fpcontext(struct thread *td, mcontext_t *mcp, char *xfpusave,
 1211     size_t xfpusave_len)
 1212 {
 1213         size_t max_len, len;
 1214 
 1215         mcp->mc_ownedfp = npxgetregs(td);
 1216         bcopy(get_pcb_user_save_td(td), &mcp->mc_fpstate[0],
 1217             sizeof(mcp->mc_fpstate));
 1218         mcp->mc_fpformat = npxformat();
 1219         if (!use_xsave || xfpusave_len == 0)
 1220                 return;
 1221         max_len = cpu_max_ext_state_size - sizeof(union savefpu);
 1222         len = xfpusave_len;
 1223         if (len > max_len) {
 1224                 len = max_len;
 1225                 bzero(xfpusave + max_len, len - max_len);
 1226         }
 1227         mcp->mc_flags |= _MC_HASFPXSTATE;
 1228         mcp->mc_xfpustate_len = len;
 1229         bcopy(get_pcb_user_save_td(td) + 1, xfpusave, len);
 1230 }
 1231 
 1232 static int
 1233 set_fpcontext(struct thread *td, mcontext_t *mcp, char *xfpustate,
 1234     size_t xfpustate_len)
 1235 {
 1236         int error;
 1237 
 1238         if (mcp->mc_fpformat == _MC_FPFMT_NODEV)
 1239                 return (0);
 1240         else if (mcp->mc_fpformat != _MC_FPFMT_387 &&
 1241             mcp->mc_fpformat != _MC_FPFMT_XMM)
 1242                 return (EINVAL);
 1243         else if (mcp->mc_ownedfp == _MC_FPOWNED_NONE) {
 1244                 /* We don't care what state is left in the FPU or PCB. */
 1245                 fpstate_drop(td);
 1246                 error = 0;
 1247         } else if (mcp->mc_ownedfp == _MC_FPOWNED_FPU ||
 1248             mcp->mc_ownedfp == _MC_FPOWNED_PCB) {
 1249                 error = npxsetregs(td, (union savefpu *)&mcp->mc_fpstate,
 1250                     xfpustate, xfpustate_len);
 1251         } else
 1252                 return (EINVAL);
 1253         return (error);
 1254 }
 1255 
 1256 static void
 1257 fpstate_drop(struct thread *td)
 1258 {
 1259 
 1260         KASSERT(PCB_USER_FPU(td->td_pcb), ("fpstate_drop: kernel-owned fpu"));
 1261         critical_enter();
 1262         if (PCPU_GET(fpcurthread) == td)
 1263                 npxdrop();
 1264         /*
 1265          * XXX force a full drop of the npx.  The above only drops it if we
 1266          * owned it.  npxgetregs() has the same bug in the !cpu_fxsr case.
 1267          *
 1268          * XXX I don't much like npxgetregs()'s semantics of doing a full
 1269          * drop.  Dropping only to the pcb matches fnsave's behaviour.
 1270          * We only need to drop to !PCB_INITDONE in sendsig().  But
 1271          * sendsig() is the only caller of npxgetregs()... perhaps we just
 1272          * have too many layers.
 1273          */
 1274         curthread->td_pcb->pcb_flags &= ~(PCB_NPXINITDONE |
 1275             PCB_NPXUSERINITDONE);
 1276         critical_exit();
 1277 }
 1278 
 1279 int
 1280 fill_dbregs(struct thread *td, struct dbreg *dbregs)
 1281 {
 1282         struct pcb *pcb;
 1283 
 1284         if (td == NULL) {
 1285                 dbregs->dr[0] = rdr0();
 1286                 dbregs->dr[1] = rdr1();
 1287                 dbregs->dr[2] = rdr2();
 1288                 dbregs->dr[3] = rdr3();
 1289                 dbregs->dr[6] = rdr6();
 1290                 dbregs->dr[7] = rdr7();
 1291         } else {
 1292                 pcb = td->td_pcb;
 1293                 dbregs->dr[0] = pcb->pcb_dr0;
 1294                 dbregs->dr[1] = pcb->pcb_dr1;
 1295                 dbregs->dr[2] = pcb->pcb_dr2;
 1296                 dbregs->dr[3] = pcb->pcb_dr3;
 1297                 dbregs->dr[6] = pcb->pcb_dr6;
 1298                 dbregs->dr[7] = pcb->pcb_dr7;
 1299         }
 1300         dbregs->dr[4] = 0;
 1301         dbregs->dr[5] = 0;
 1302         return (0);
 1303 }
 1304 
 1305 int
 1306 set_dbregs(struct thread *td, struct dbreg *dbregs)
 1307 {
 1308         struct pcb *pcb;
 1309         int i;
 1310 
 1311         if (td == NULL) {
 1312                 load_dr0(dbregs->dr[0]);
 1313                 load_dr1(dbregs->dr[1]);
 1314                 load_dr2(dbregs->dr[2]);
 1315                 load_dr3(dbregs->dr[3]);
 1316                 load_dr6(dbregs->dr[6]);
 1317                 load_dr7(dbregs->dr[7]);
 1318         } else {
 1319                 /*
 1320                  * Don't let an illegal value for dr7 get set.  Specifically,
 1321                  * check for undefined settings.  Setting these bit patterns
 1322                  * result in undefined behaviour and can lead to an unexpected
 1323                  * TRCTRAP.
 1324                  */
 1325                 for (i = 0; i < 4; i++) {
 1326                         if (DBREG_DR7_ACCESS(dbregs->dr[7], i) == 0x02)
 1327                                 return (EINVAL);
 1328                         if (DBREG_DR7_LEN(dbregs->dr[7], i) == 0x02)
 1329                                 return (EINVAL);
 1330                 }
 1331 
 1332                 pcb = td->td_pcb;
 1333 
 1334                 /*
 1335                  * Don't let a process set a breakpoint that is not within the
 1336                  * process's address space.  If a process could do this, it
 1337                  * could halt the system by setting a breakpoint in the kernel
 1338                  * (if ddb was enabled).  Thus, we need to check to make sure
 1339                  * that no breakpoints are being enabled for addresses outside
 1340                  * process's address space.
 1341                  *
 1342                  * XXX - what about when the watched area of the user's
 1343                  * address space is written into from within the kernel
 1344                  * ... wouldn't that still cause a breakpoint to be generated
 1345                  * from within kernel mode?
 1346                  */
 1347 
 1348                 if (DBREG_DR7_ENABLED(dbregs->dr[7], 0)) {
 1349                         /* dr0 is enabled */
 1350                         if (dbregs->dr[0] >= VM_MAXUSER_ADDRESS)
 1351                                 return (EINVAL);
 1352                 }
 1353 
 1354                 if (DBREG_DR7_ENABLED(dbregs->dr[7], 1)) {
 1355                         /* dr1 is enabled */
 1356                         if (dbregs->dr[1] >= VM_MAXUSER_ADDRESS)
 1357                                 return (EINVAL);
 1358                 }
 1359 
 1360                 if (DBREG_DR7_ENABLED(dbregs->dr[7], 2)) {
 1361                         /* dr2 is enabled */
 1362                         if (dbregs->dr[2] >= VM_MAXUSER_ADDRESS)
 1363                                 return (EINVAL);
 1364                 }
 1365 
 1366                 if (DBREG_DR7_ENABLED(dbregs->dr[7], 3)) {
 1367                         /* dr3 is enabled */
 1368                         if (dbregs->dr[3] >= VM_MAXUSER_ADDRESS)
 1369                                 return (EINVAL);
 1370                 }
 1371 
 1372                 pcb->pcb_dr0 = dbregs->dr[0];
 1373                 pcb->pcb_dr1 = dbregs->dr[1];
 1374                 pcb->pcb_dr2 = dbregs->dr[2];
 1375                 pcb->pcb_dr3 = dbregs->dr[3];
 1376                 pcb->pcb_dr6 = dbregs->dr[6];
 1377                 pcb->pcb_dr7 = dbregs->dr[7];
 1378 
 1379                 pcb->pcb_flags |= PCB_DBREGS;
 1380         }
 1381 
 1382         return (0);
 1383 }
 1384 
 1385 /*
 1386  * Return > 0 if a hardware breakpoint has been hit, and the
 1387  * breakpoint was in user space.  Return 0, otherwise.
 1388  */
 1389 int
 1390 user_dbreg_trap(register_t dr6)
 1391 {
 1392         u_int32_t dr7;
 1393         u_int32_t bp;       /* breakpoint bits extracted from dr6 */
 1394         int nbp;            /* number of breakpoints that triggered */
 1395         caddr_t addr[4];    /* breakpoint addresses */
 1396         int i;
 1397 
 1398         bp = dr6 & DBREG_DR6_BMASK;
 1399         if (bp == 0) {
 1400                 /*
 1401                  * None of the breakpoint bits are set meaning this
 1402                  * trap was not caused by any of the debug registers
 1403                  */
 1404                 return (0);
 1405         }
 1406 
 1407         dr7 = rdr7();
 1408         if ((dr7 & 0x000000ff) == 0) {
 1409                 /*
 1410                  * all GE and LE bits in the dr7 register are zero,
 1411                  * thus the trap couldn't have been caused by the
 1412                  * hardware debug registers
 1413                  */
 1414                 return (0);
 1415         }
 1416 
 1417         nbp = 0;
 1418 
 1419         /*
 1420          * at least one of the breakpoints were hit, check to see
 1421          * which ones and if any of them are user space addresses
 1422          */
 1423 
 1424         if (bp & 0x01) {
 1425                 addr[nbp++] = (caddr_t)rdr0();
 1426         }
 1427         if (bp & 0x02) {
 1428                 addr[nbp++] = (caddr_t)rdr1();
 1429         }
 1430         if (bp & 0x04) {
 1431                 addr[nbp++] = (caddr_t)rdr2();
 1432         }
 1433         if (bp & 0x08) {
 1434                 addr[nbp++] = (caddr_t)rdr3();
 1435         }
 1436 
 1437         for (i = 0; i < nbp; i++) {
 1438                 if (addr[i] < (caddr_t)VM_MAXUSER_ADDRESS) {
 1439                         /*
 1440                          * addr[i] is in user space
 1441                          */
 1442                         return (nbp);
 1443                 }
 1444         }
 1445 
 1446         /*
 1447          * None of the breakpoints are in user space.
 1448          */
 1449         return (0);
 1450 }

Cache object: 5215cbbfd818b488bdcee4486e66f41e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.