Home | History | Annotate | Line # | Download | only in amd64
      1 /*	$NetBSD: trap.c,v 1.130 2025/06/20 17:02:18 bouyer Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1998, 2000, 2017 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Charles M. Hannum, and by Maxime Villard.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /*
     33  * Copyright (c) 1990 The Regents of the University of California.
     34  * All rights reserved.
     35  *
     36  * This code is derived from software contributed to Berkeley by
     37  * the University of Utah, and William Jolitz.
     38  *
     39  * Redistribution and use in source and binary forms, with or without
     40  * modification, are permitted provided that the following conditions
     41  * are met:
     42  * 1. Redistributions of source code must retain the above copyright
     43  *    notice, this list of conditions and the following disclaimer.
     44  * 2. Redistributions in binary form must reproduce the above copyright
     45  *    notice, this list of conditions and the following disclaimer in the
     46  *    documentation and/or other materials provided with the distribution.
     47  * 3. Neither the name of the University nor the names of its contributors
     48  *    may be used to endorse or promote products derived from this software
     49  *    without specific prior written permission.
     50  *
     51  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     52  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     53  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     54  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     55  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     56  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     57  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     58  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     59  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     60  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     61  * SUCH DAMAGE.
     62  *
     63  *	@(#)trap.c	7.4 (Berkeley) 5/13/91
     64  */
     65 
     66 #include <sys/cdefs.h>
     67 __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.130 2025/06/20 17:02:18 bouyer Exp $");
     68 
     69 #include "opt_ddb.h"
     70 #include "opt_kgdb.h"
     71 #include "opt_xen.h"
     72 #include "opt_dtrace.h"
     73 
     74 #include <sys/param.h>
     75 #include <sys/systm.h>
     76 #include <sys/proc.h>
     77 #include <sys/acct.h>
     78 #include <sys/kauth.h>
     79 #include <sys/kernel.h>
     80 #include <sys/kmem.h>
     81 #include <sys/ras.h>
     82 #include <sys/signal.h>
     83 #include <sys/syscall.h>
     84 #include <sys/cpu.h>
     85 #include <sys/ucontext.h>
     86 #include <sys/module_hook.h>
     87 #include <sys/compat_stub.h>
     88 
     89 #include <uvm/uvm_extern.h>
     90 
     91 #include <machine/cpufunc.h>
     92 #include <x86/fpu.h>
     93 #include <x86/dbregs.h>
     94 #include <machine/psl.h>
     95 #include <machine/reg.h>
     96 #include <machine/trap.h>
     97 #include <machine/userret.h>
     98 #include <machine/db_machdep.h>
     99 
    100 #include <x86/nmi.h>
    101 
    102 #ifndef XENPV
    103 #include "isa.h"
    104 #endif
    105 
    106 #include <sys/kgdb.h>
    107 
    108 #ifdef KDTRACE_HOOKS
    109 #include <sys/dtrace_bsd.h>
    110 /*
    111  * This is a hook which is initialized by the dtrace module to handle traps
    112  * which might occur during DTrace probe execution.
    113  */
    114 dtrace_trap_func_t dtrace_trap_func = NULL;
    115 dtrace_doubletrap_func_t dtrace_doubletrap_func = NULL;
    116 #endif
    117 
    118 /*
    119  * Module hook for amd64_oosyscall
    120  */
    121 struct amd64_oosyscall_hook_t amd64_oosyscall_hook;
    122 
    123 void nmitrap(struct trapframe *);
    124 void doubletrap(struct trapframe *);
    125 void trap(struct trapframe *);
    126 
    127 const char * const trap_type[] = {
    128 	"privileged instruction fault",		/*  0 T_PRIVINFLT */
    129 	"breakpoint trap",			/*  1 T_BPTFLT */
    130 	"arithmetic trap",			/*  2 T_ARITHTRAP */
    131 	"asynchronous system trap",		/*  3 T_ASTFLT */
    132 	"protection fault",			/*  4 T_PROTFLT */
    133 	"trace trap",				/*  5 T_TRCTRAP */
    134 	"page fault",				/*  6 T_PAGEFLT */
    135 	"alignment fault",			/*  7 T_ALIGNFLT */
    136 	"integer divide fault",			/*  8 T_DIVIDE */
    137 	"non-maskable interrupt",		/*  9 T_NMI */
    138 	"overflow trap",			/* 10 T_OFLOW */
    139 	"bounds check fault",			/* 11 T_BOUND */
    140 	"FPU not available fault",		/* 12 T_DNA */
    141 	"double fault",				/* 13 T_DOUBLEFLT */
    142 	"FPU operand fetch fault",		/* 14 T_FPOPFLT */
    143 	"invalid TSS fault",			/* 15 T_TSSFLT */
    144 	"segment not present fault",		/* 16 T_SEGNPFLT */
    145 	"stack fault",				/* 17 T_STKFLT */
    146 	"machine check fault",			/* 18 T_MCA */
    147 	"SSE FP exception",			/* 19 T_XMM */
    148 	"reserved trap",			/* 20 T_RESERVED */
    149 };
    150 int trap_types = __arraycount(trap_type);
    151 
    152 #ifdef TRAP_SIGDEBUG
    153 static void sigdebug(const struct trapframe *, const ksiginfo_t *, int);
    154 #define SIGDEBUG(a, b, c) sigdebug(a, b, c)
    155 #else
    156 #define SIGDEBUG(a, b, c)
    157 #endif
    158 
    159 static void
    160 onfault_restore(struct trapframe *frame, void *onfault, int error)
    161 {
    162 	frame->tf_rip = (uintptr_t)onfault;
    163 	frame->tf_rax = error;
    164 }
    165 
    166 static void *
    167 onfault_handler(const struct pcb *pcb, const struct trapframe *tf)
    168 {
    169 	struct onfault_table {
    170 		uintptr_t start;
    171 		uintptr_t end;
    172 		void *handler;
    173 	};
    174 	extern const struct onfault_table onfault_table[];
    175 	const struct onfault_table *p;
    176 	uintptr_t pc;
    177 
    178 	if (pcb->pcb_onfault != NULL) {
    179 		return pcb->pcb_onfault;
    180 	}
    181 
    182 	pc = tf->tf_rip;
    183 	for (p = onfault_table; p->start; p++) {
    184 		if (p->start <= pc && pc < p->end) {
    185 			return p->handler;
    186 		}
    187 	}
    188 	return NULL;
    189 }
    190 
    191 static void
    192 trap_print(const struct trapframe *frame, const lwp_t *l)
    193 {
    194 	const int type = frame->tf_trapno;
    195 
    196 	if (frame->tf_trapno < trap_types) {
    197 		printf("fatal %s", trap_type[type]);
    198 	} else {
    199 		printf("unknown trap %d", type);
    200 	}
    201 	printf(" in %s mode\n", (type & T_USER) ? "user" : "supervisor");
    202 
    203 	printf("trap type %d code %#lx rip %#lx cs %#lx rflags %#lx cr2 %#lx "
    204 	    "ilevel %#x rsp %#lx\n",
    205 	    type, frame->tf_err, (u_long)frame->tf_rip, frame->tf_cs,
    206 	    frame->tf_rflags, rcr2(), curcpu()->ci_ilevel, frame->tf_rsp);
    207 
    208 	printf("curlwp %p pid %d.%d lowest kstack %p\n",
    209 	    l, l->l_proc->p_pid, l->l_lid, KSTACK_LOWEST_ADDR(l));
    210 }
    211 
    212 void
    213 nmitrap(struct trapframe *frame)
    214 {
    215 	const int type = T_NMI;
    216 
    217 	if (nmi_dispatch(frame))
    218 		return;
    219 	/* NMI can be hooked up to a pushbutton for debugging */
    220 	if (kgdb_trap(type, frame))
    221 		return;
    222 	if (kdb_trap(type, 0, frame))
    223 		return;
    224 	/* machine/parity/power fail/"kitchen sink" faults */
    225 
    226 	x86_nmi();
    227 }
    228 
    229 void
    230 doubletrap(struct trapframe *frame)
    231 {
    232 	const int type = T_DOUBLEFLT;
    233 	struct lwp *l = curlwp;
    234 
    235 	trap_print(frame, l);
    236 
    237 	if (kdb_trap(type, 0, frame))
    238 		return;
    239 	if (kgdb_trap(type, frame))
    240 		return;
    241 
    242 	panic("double fault");
    243 }
    244 
    245 /*
    246  * trap(frame): exception, fault, and trap interface to BSD kernel.
    247  *
    248  * This common code is called from assembly language IDT gate entry routines
    249  * that prepare a suitable stack frame, and restore this frame after the
    250  * exception has been processed. Note that the effect is as if the arguments
    251  * were passed call by reference.
    252  *
    253  * Note that the fpu traps (07 T_DNA, 10 T_ARITHTRAP and 13 T_XMM)
    254  * jump directly into the code in x86/fpu.c so they get processed
    255  * without interrupts being enabled.
    256  */
    257 void
    258 trap(struct trapframe *frame)
    259 {
    260 	struct lwp *l = curlwp;
    261 	struct proc *p;
    262 	struct pcb *pcb;
    263 	extern char kcopy_fault[];
    264 	ksiginfo_t ksi;
    265 	void *onfault;
    266 	int type, error;
    267 	uint64_t cr2;
    268 	bool pfail;
    269 
    270 	if (__predict_true(l != NULL)) {
    271 		pcb = lwp_getpcb(l);
    272 		p = l->l_proc;
    273 	} else {
    274 		/*
    275 		 * This can happen eg on break points in early on boot.
    276 		 */
    277 		pcb = NULL;
    278 		p = NULL;
    279 	}
    280 	type = frame->tf_trapno;
    281 
    282 	if (!KERNELMODE(frame->tf_cs)) {
    283 		type |= T_USER;
    284 		l->l_md.md_regs = frame;
    285 	}
    286 
    287 #ifdef KDTRACE_HOOKS
    288 	/*
    289 	 * A trap can occur while DTrace executes a probe. Before
    290 	 * executing the probe, DTrace blocks re-scheduling and sets
    291 	 * a flag in its per-cpu flags to indicate that it doesn't
    292 	 * want to fault. On returning from the probe, the no-fault
    293 	 * flag is cleared and finally re-scheduling is enabled.
    294 	 *
    295 	 * If the DTrace kernel module has registered a trap handler,
    296 	 * call it and if it returns non-zero, assume that it has
    297 	 * handled the trap and modified the trap frame so that this
    298 	 * function can return normally.
    299 	 */
    300 	if ((type == T_PROTFLT || type == T_PAGEFLT) &&
    301 	    dtrace_trap_func != NULL) {
    302 		if ((*dtrace_trap_func)(frame, type)) {
    303 			return;
    304 		}
    305 	}
    306 #endif
    307 
    308 	switch (type) {
    309 
    310 	default:
    311 	we_re_toast:
    312 		trap_print(frame, l);
    313 
    314 		if (kdb_trap(type, 0, frame))
    315 			return;
    316 		if (kgdb_trap(type, frame))
    317 			return;
    318 		/*
    319 		 * If this is a breakpoint, don't panic if we're not connected.
    320 		 */
    321 		if (type == T_BPTFLT && kgdb_disconnected()) {
    322 			printf("kgdb: ignored %s\n", trap_type[type]);
    323 			return;
    324 		}
    325 		panic("trap");
    326 		/*NOTREACHED*/
    327 
    328 	case T_PROTFLT:
    329 	case T_SEGNPFLT:
    330 	case T_ALIGNFLT:
    331 	case T_STKFLT:
    332 	case T_TSSFLT:
    333 		if (p == NULL)
    334 			goto we_re_toast;
    335 
    336 		/* Check for copyin/copyout fault. */
    337 		onfault = onfault_handler(pcb, frame);
    338 		if (onfault != NULL) {
    339 			onfault_restore(frame, onfault, EFAULT);
    340 			return;
    341 		}
    342 
    343 		goto we_re_toast;
    344 
    345 	case T_PROTFLT|T_USER:		/* protection fault */
    346 	{	int hook_ret;
    347 
    348 		MODULE_HOOK_CALL(amd64_oosyscall_hook, (p, frame),
    349 			ENOSYS, hook_ret);
    350 		if (hook_ret == 0) {
    351 			/* Do the syscall */
    352 			p->p_md.md_syscall(frame);
    353 			goto out;
    354 		}
    355 	}
    356 		/* FALLTHROUGH */
    357 	case T_TSSFLT|T_USER:
    358 	case T_SEGNPFLT|T_USER:
    359 	case T_STKFLT|T_USER:
    360 	case T_ALIGNFLT|T_USER:
    361 		KSI_INIT_TRAP(&ksi);
    362 		ksi.ksi_trap = type & ~T_USER;
    363 		ksi.ksi_addr = (void *)frame->tf_rip;
    364 		switch (type) {
    365 		case T_SEGNPFLT|T_USER:
    366 		case T_STKFLT|T_USER:
    367 			ksi.ksi_signo = SIGBUS;
    368 			ksi.ksi_code = BUS_ADRERR;
    369 			break;
    370 		case T_TSSFLT|T_USER:
    371 			ksi.ksi_signo = SIGBUS;
    372 			ksi.ksi_code = BUS_OBJERR;
    373 			break;
    374 		case T_ALIGNFLT|T_USER:
    375 			ksi.ksi_signo = SIGBUS;
    376 			ksi.ksi_code = BUS_ADRALN;
    377 			break;
    378 		case T_PROTFLT|T_USER:
    379 			ksi.ksi_signo = SIGSEGV;
    380 			ksi.ksi_code = SEGV_ACCERR;
    381 			break;
    382 		default:
    383 			KASSERT(0);
    384 			break;
    385 		}
    386 		goto trapsignal;
    387 
    388 	case T_PRIVINFLT|T_USER:	/* privileged instruction fault */
    389 	case T_FPOPFLT|T_USER:		/* coprocessor operand fault */
    390 		KSI_INIT_TRAP(&ksi);
    391 		ksi.ksi_signo = SIGILL;
    392 		ksi.ksi_trap = type & ~T_USER;
    393 		ksi.ksi_addr = (void *) frame->tf_rip;
    394 		switch (type) {
    395 		case T_PRIVINFLT|T_USER:
    396 			ksi.ksi_code = ILL_PRVOPC;
    397 			break;
    398 		case T_FPOPFLT|T_USER:
    399 			ksi.ksi_code = ILL_COPROC;
    400 			break;
    401 		default:
    402 			KASSERT(0);
    403 			break;
    404 		}
    405 		goto trapsignal;
    406 
    407 	case T_ASTFLT|T_USER:
    408 		/* Allow process switch. */
    409 		//curcpu()->ci_data.cpu_nast++;
    410 		if (l->l_pflag & LP_OWEUPC) {
    411 			l->l_pflag &= ~LP_OWEUPC;
    412 			ADDUPROF(l);
    413 		}
    414 		goto out;
    415 
    416 	case T_BOUND|T_USER:
    417 	case T_OFLOW|T_USER:
    418 	case T_DIVIDE|T_USER:
    419 		KSI_INIT_TRAP(&ksi);
    420 		ksi.ksi_signo = SIGFPE;
    421 		ksi.ksi_trap = type & ~T_USER;
    422 		ksi.ksi_addr = (void *)frame->tf_rip;
    423 		switch (type) {
    424 		case T_BOUND|T_USER:
    425 			ksi.ksi_code = FPE_FLTSUB;
    426 			break;
    427 		case T_OFLOW|T_USER:
    428 			ksi.ksi_code = FPE_INTOVF;
    429 			break;
    430 		case T_DIVIDE|T_USER:
    431 			ksi.ksi_code = FPE_INTDIV;
    432 			break;
    433 		default:
    434 			KASSERT(0);
    435 			break;
    436 		}
    437 		goto trapsignal;
    438 
    439 	case T_PAGEFLT:
    440 		/* Allow page faults in kernel mode. */
    441 		if (__predict_false(l == NULL))
    442 			goto we_re_toast;
    443 
    444 		onfault = pcb->pcb_onfault;
    445 
    446 		if (cpu_intr_p() || (l->l_pflag & LP_INTR) != 0) {
    447 			goto we_re_toast;
    448 		}
    449 
    450 		cr2 = rcr2();
    451 
    452 		if (frame->tf_err & PGEX_I) {
    453 			/* SMEP might have brought us here */
    454 			if (cr2 < VM_MAXUSER_ADDRESS) {
    455 				printf("prevented execution of %p (SMEP)\n",
    456 				    (void *)cr2);
    457 				goto we_re_toast;
    458 			}
    459 		}
    460 
    461 		if ((frame->tf_err & PGEX_P) &&
    462 		    cr2 < VM_MAXUSER_ADDRESS) {
    463 			/* SMAP might have brought us here */
    464 			if (onfault_handler(pcb, frame) == NULL) {
    465 				printf("prevented access to %p (SMAP)\n",
    466 				    (void *)cr2);
    467 				goto we_re_toast;
    468 			}
    469 		}
    470 
    471 		goto pagefltcommon;
    472 
    473 	case T_PAGEFLT|T_USER: {
    474 		register vaddr_t va;
    475 		register struct vmspace *vm;
    476 		register struct vm_map *map;
    477 		vm_prot_t ftype;
    478 		extern struct vm_map *kernel_map;
    479 
    480 		cr2 = rcr2();
    481 		if (p->p_emul->e_usertrap != NULL &&
    482 		    (*p->p_emul->e_usertrap)(l, cr2, frame) != 0)
    483 			return;
    484 pagefltcommon:
    485 		vm = p->p_vmspace;
    486 		if (__predict_false(vm == NULL)) {
    487 			goto we_re_toast;
    488 		}
    489 		pcb->pcb_cr2 = cr2;
    490 		va = trunc_page((vaddr_t)cr2);
    491 		/*
    492 		 * It is only a kernel address space fault iff:
    493 		 *	1. (type & T_USER) == 0  and
    494 		 *	2. pcb_onfault not set or
    495 		 *	3. pcb_onfault set but supervisor space fault
    496 		 * The last can occur during an exec() copyin where the
    497 		 * argument space is lazy-allocated.
    498 		 */
    499 		if (type == T_PAGEFLT && va >= VM_MIN_KERNEL_ADDRESS)
    500 			map = kernel_map;
    501 		else
    502 			map = &vm->vm_map;
    503 		if (frame->tf_err & PGEX_W)
    504 			ftype = VM_PROT_WRITE;
    505 		else if (frame->tf_err & PGEX_I)
    506 			ftype = VM_PROT_EXECUTE;
    507 		else
    508 			ftype = VM_PROT_READ;
    509 
    510 #ifdef DIAGNOSTIC
    511 		if (map == kernel_map && va == 0) {
    512 			printf("trap: bad kernel access at %lx\n", va);
    513 			goto we_re_toast;
    514 		}
    515 #endif
    516 #ifdef XENPV
    517 		/* Check to see if interrupts are enabled (ie; no events are masked) */
    518 		KASSERT(x86_read_psl() == 0);
    519 #endif
    520 		/* Fault the original page in. */
    521 		onfault = pcb->pcb_onfault;
    522 		pcb->pcb_onfault = NULL;
    523 		error = uvm_fault(map, va, ftype);
    524 		pcb->pcb_onfault = onfault;
    525 		if (error == 0) {
    526 			if (map != kernel_map && (void *)va >= vm->vm_maxsaddr)
    527 				uvm_grow(p, va);
    528 
    529 			pfail = false;
    530 			while (type == T_PAGEFLT) {
    531 				/*
    532 				 * we need to switch pmap now if we're in
    533 				 * the middle of copyin/out.
    534 				 *
    535 				 * but we don't need to do so for kcopy as
    536 				 * it never touch userspace.
    537  				 */
    538 				kpreempt_disable();
    539 				if (curcpu()->ci_want_pmapload) {
    540 					onfault = onfault_handler(pcb, frame);
    541 					if (onfault != kcopy_fault) {
    542 						pmap_load();
    543 					}
    544 				}
    545 				/*
    546 				 * We need to keep the pmap loaded and
    547 				 * so avoid being preempted until back
    548 				 * into the copy functions.  Disable
    549 				 * interrupts at the hardware level before
    550 				 * re-enabling preemption.  Interrupts
    551 				 * will be re-enabled by 'iret' when
    552 				 * returning back out of the trap stub.
    553 				 * They'll only be re-enabled when the
    554 				 * program counter is once again in
    555 				 * the copy functions, and so visible
    556 				 * to cpu_kpreempt_exit().
    557 				 */
    558 				x86_disable_intr();
    559 				l->l_nopreempt--;
    560 				if (l->l_nopreempt > 0 || !l->l_dopreempt ||
    561 				    pfail) {
    562 					return;
    563 				}
    564 				x86_enable_intr();
    565 				/*
    566 				 * If preemption fails for some reason,
    567 				 * don't retry it.  The conditions won't
    568 				 * change under our nose.
    569 				 */
    570 				pfail = kpreempt(0);
    571 			}
    572 			goto out;
    573 		}
    574 
    575 		if (type == T_PAGEFLT) {
    576 			onfault = onfault_handler(pcb, frame);
    577 			if (onfault != NULL) {
    578 				onfault_restore(frame, onfault, error);
    579 				return;
    580 			}
    581 
    582 			printf("uvm_fault(%p, 0x%lx, %d) -> %x\n",
    583 			    map, va, ftype, error);
    584 			goto we_re_toast;
    585 		}
    586 
    587 		KSI_INIT_TRAP(&ksi);
    588 		ksi.ksi_trap = type & ~T_USER;
    589 		ksi.ksi_addr = (void *)cr2;
    590 		switch (error) {
    591 		case EINVAL:
    592 			ksi.ksi_signo = SIGBUS;
    593 			ksi.ksi_code = BUS_ADRERR;
    594 			break;
    595 		case EACCES:
    596 			ksi.ksi_signo = SIGSEGV;
    597 			ksi.ksi_code = SEGV_ACCERR;
    598 			error = EFAULT;
    599 			break;
    600 		case ENOMEM:
    601 			ksi.ksi_signo = SIGKILL;
    602 			printf("UVM: pid %d.%d (%s), uid %d killed: "
    603 			    "out of swap\n", p->p_pid, l->l_lid, p->p_comm,
    604 			    l->l_cred ?  kauth_cred_geteuid(l->l_cred) : -1);
    605 			break;
    606 		default:
    607 			ksi.ksi_signo = SIGSEGV;
    608 			ksi.ksi_code = SEGV_MAPERR;
    609 			break;
    610 		}
    611 
    612 		SIGDEBUG(frame, &ksi, error);
    613  		(*p->p_emul->e_trapsignal)(l, &ksi);
    614 		break;
    615 	}
    616 
    617 	case T_TRCTRAP:
    618 		/*
    619 		 * Ignore debug register trace traps due to
    620 		 * accesses in the user's address space, which
    621 		 * can happen under several conditions such as
    622 		 * if a user sets a watchpoint on a buffer and
    623 		 * then passes that buffer to a system call.
    624 		 * We still want to get TRCTRAPS for addresses
    625 		 * in kernel space because that is useful when
    626 		 * debugging the kernel.
    627 		 */
    628 		if (x86_dbregs_user_trap())
    629 			break;
    630 
    631 		goto we_re_toast;
    632 
    633 	case T_BPTFLT|T_USER:		/* bpt instruction fault */
    634 	case T_TRCTRAP|T_USER:		/* trace trap */
    635 		/*
    636 		 * Don't go single-stepping into a RAS.
    637 		 */
    638 		if (p->p_raslist == NULL ||
    639 		    (ras_lookup(p, (void *)frame->tf_rip) == (void *)-1)) {
    640 			KSI_INIT_TRAP(&ksi);
    641 			ksi.ksi_signo = SIGTRAP;
    642 			ksi.ksi_trap = type & ~T_USER;
    643 			if (x86_dbregs_user_trap()) {
    644 				x86_dbregs_store_dr6(l);
    645 				ksi.ksi_code = TRAP_DBREG;
    646 			} else if (type == (T_BPTFLT|T_USER))
    647 				ksi.ksi_code = TRAP_BRKPT;
    648 			else
    649 				ksi.ksi_code = TRAP_TRACE;
    650 			(*p->p_emul->e_trapsignal)(l, &ksi);
    651 		}
    652 		break;
    653 	}
    654 
    655 	if ((type & T_USER) == 0)
    656 		return;
    657 out:
    658 	userret(l);
    659 	return;
    660 trapsignal:
    661 	SIGDEBUG(frame, &ksi, 0);
    662 	(*p->p_emul->e_trapsignal)(l, &ksi);
    663 	userret(l);
    664 }
    665 
    666 /*
    667  * startlwp: start of a new LWP.
    668  */
    669 void
    670 startlwp(void *arg)
    671 {
    672 	ucontext_t *uc = arg;
    673 	lwp_t *l = curlwp;
    674 	int error __diagused;
    675 
    676 	error = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
    677 	KASSERT(error == 0);
    678 
    679 	kmem_free(uc, sizeof(ucontext_t));
    680 	userret(l);
    681 }
    682 
    683 #ifdef TRAP_SIGDEBUG
    684 static void
    685 frame_dump(const struct trapframe *tf, struct pcb *pcb)
    686 {
    687 
    688 	printf("trapframe %p\n", tf);
    689 	printf("rip %#018lx  rsp %#018lx  rfl %#018lx\n",
    690 	    tf->tf_rip, tf->tf_rsp, tf->tf_rflags);
    691 	printf("rdi %#018lx  rsi %#018lx  rdx %#018lx\n",
    692 	    tf->tf_rdi, tf->tf_rsi, tf->tf_rdx);
    693 	printf("rcx %#018lx  r8  %#018lx  r9  %#018lx\n",
    694 	    tf->tf_rcx, tf->tf_r8, tf->tf_r9);
    695 	printf("r10 %#018lx  r11 %#018lx  r12 %#018lx\n",
    696 	    tf->tf_r10, tf->tf_r11, tf->tf_r12);
    697 	printf("r13 %#018lx  r14 %#018lx  r15 %#018lx\n",
    698 	    tf->tf_r13, tf->tf_r14, tf->tf_r15);
    699 	printf("rbp %#018lx  rbx %#018lx  rax %#018lx\n",
    700 	    tf->tf_rbp, tf->tf_rbx, tf->tf_rax);
    701 	printf("cs %#04lx  ds %#04lx  es %#04lx  "
    702 	    "fs %#04lx  gs %#04lx  ss %#04lx\n",
    703 	    tf->tf_cs & 0xffff, tf->tf_ds & 0xffff, tf->tf_es & 0xffff,
    704 	    tf->tf_fs & 0xffff, tf->tf_gs & 0xffff, tf->tf_ss & 0xffff);
    705 	printf("fsbase %#018lx gsbase %#018lx\n", pcb->pcb_fs, pcb->pcb_gs);
    706 	printf("\n");
    707 	hexdump(printf, "Stack dump", tf, 256);
    708 }
    709 
    710 static void
    711 sigdebug(const struct trapframe *tf, const ksiginfo_t *ksi, int e)
    712 {
    713 	struct lwp *l = curlwp;
    714 	struct proc *p = l->l_proc;
    715 
    716 	printf("pid %d.%d (%s): signal %d code=%d (trap %#lx) "
    717 	    "@rip %#lx addr %#lx error=%d\n",
    718 	    p->p_pid, l->l_lid, p->p_comm, ksi->ksi_signo, ksi->ksi_code,
    719 	    tf->tf_trapno, tf->tf_rip, rcr2(), e);
    720 	frame_dump(tf, lwp_getpcb(l));
    721 }
    722 #endif
    723