1 1.41 andvar /* $NetBSD: trap.c,v 1.41 2024/09/08 10:16:04 andvar Exp $ */ 2 1.2 matt /*- 3 1.2 matt * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. 4 1.2 matt * All rights reserved. 5 1.2 matt * 6 1.2 matt * This code is derived from software contributed to The NetBSD Foundation 7 1.2 matt * by Raytheon BBN Technologies Corp and Defense Advanced Research Projects 8 1.2 matt * Agency and which was developed by Matt Thomas of 3am Software Foundry. 9 1.2 matt * 10 1.2 matt * This material is based upon work supported by the Defense Advanced Research 11 1.2 matt * Projects Agency and Space and Naval Warfare Systems Center, Pacific, under 12 1.2 matt * Contract No. N66001-09-C-2073. 13 1.2 matt * Approved for Public Release, Distribution Unlimited 14 1.2 matt * 15 1.2 matt * Redistribution and use in source and binary forms, with or without 16 1.2 matt * modification, are permitted provided that the following conditions 17 1.2 matt * are met: 18 1.2 matt * 1. Redistributions of source code must retain the above copyright 19 1.2 matt * notice, this list of conditions and the following disclaimer. 20 1.2 matt * 2. Redistributions in binary form must reproduce the above copyright 21 1.2 matt * notice, this list of conditions and the following disclaimer in the 22 1.2 matt * documentation and/or other materials provided with the distribution. 23 1.2 matt * 24 1.2 matt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 25 1.2 matt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 26 1.2 matt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 27 1.2 matt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 28 1.2 matt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 1.2 matt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 1.2 matt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 1.2 matt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 32 1.2 matt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 1.2 matt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 1.2 matt * POSSIBILITY OF SUCH DAMAGE. 35 1.2 matt */ 36 1.2 matt 37 1.2 matt #include <sys/cdefs.h> 38 1.41 andvar __KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.41 2024/09/08 10:16:04 andvar Exp $"); 39 1.2 matt 40 1.28 rin #ifdef _KERNEL_OPT 41 1.29 rin #include "opt_altivec.h" 42 1.28 rin #include "opt_ddb.h" 43 1.28 rin #endif 44 1.2 matt 45 1.2 matt #include <sys/param.h> 46 1.36 rin #include <sys/cpu.h> 47 1.36 rin #include <sys/kauth.h> 48 1.2 matt #include <sys/lwp.h> 49 1.2 matt #include <sys/proc.h> 50 1.37 rin #include <sys/ptrace.h> 51 1.2 matt #include <sys/ras.h> 52 1.36 rin #include <sys/siginfo.h> 53 1.36 rin #include <sys/systm.h> 54 1.36 rin 55 1.36 rin #include <ddb/ddb.h> 56 1.2 matt 57 1.2 matt #include <uvm/uvm_extern.h> 58 1.2 matt 59 1.36 rin #include <powerpc/altivec.h> /* use same interface for SPE */ 60 1.36 rin #include <powerpc/instr.h> 61 1.2 matt #include <powerpc/pcb.h> 62 1.2 matt #include <powerpc/psl.h> 63 1.2 matt #include <powerpc/spr.h> 64 1.36 rin #include <powerpc/trap.h> 65 1.36 rin #include <powerpc/userret.h> 66 1.2 matt 67 1.18 matt #include <powerpc/fpu/fpu_extern.h> 68 1.18 matt 69 1.36 rin #include <powerpc/booke/cpuvar.h> 70 1.36 rin #include <powerpc/booke/pte.h> 71 1.36 rin #include <powerpc/booke/spr.h> 72 1.2 matt #include <powerpc/booke/trap.h> 73 1.2 matt 74 1.2 matt void trap(enum ppc_booke_exceptions, struct trapframe *); 75 1.2 matt 76 1.2 matt static const char trap_names[][8] = { 77 1.2 matt [T_CRITIAL_INPUT] = "CRIT", 78 1.2 matt [T_EXTERNAL_INPUT] = "EXT", 79 1.2 matt [T_DECREMENTER] = "DECR", 80 1.2 matt [T_FIXED_INTERVAL] = "FIT", 81 1.2 matt [T_WATCHDOG] = "WDOG", 82 1.2 matt [T_SYSTEM_CALL] = "SC", 83 1.2 matt [T_MACHINE_CHECK] = "MCHK", 84 1.2 matt [T_DSI] = "DSI", 85 1.2 matt [T_ISI] = "ISI", 86 1.2 matt [T_ALIGNMENT] = "ALN", 87 1.2 matt [T_PROGRAM] = "PGM", 88 1.2 matt [T_FP_UNAVAILABLE] = "FP", 89 1.2 matt [T_AP_UNAVAILABLE] = "AP", 90 1.2 matt [T_DATA_TLB_ERROR] = "DTLB", 91 1.2 matt [T_INSTRUCTION_TLB_ERROR] = "ITLB", 92 1.2 matt [T_DEBUG] = "DEBUG", 93 1.2 matt [T_SPE_UNAVAILABLE] = "SPE", 94 1.2 matt [T_EMBEDDED_FP_DATA] = "FPDATA", 95 1.2 matt [T_EMBEDDED_FP_ROUND] = "FPROUND", 96 1.2 matt [T_EMBEDDED_PERF_MONITOR] = "PERFMON", 97 1.2 matt [T_AST] = "AST", 98 1.2 matt }; 99 1.2 matt 100 1.2 matt static inline bool 101 1.2 matt usertrap_p(struct trapframe *tf) 102 1.2 matt { 103 1.2 matt return (tf->tf_srr1 & PSL_PR) != 0; 104 1.2 matt } 105 1.2 matt 106 1.2 matt static int 107 1.2 matt mchk_exception(struct trapframe *tf, ksiginfo_t *ksi) 108 1.2 matt { 109 1.2 matt const bool usertrap = usertrap_p(tf); 110 1.2 matt const vaddr_t faultva = tf->tf_mcar; 111 1.2 matt struct cpu_info * const ci = curcpu(); 112 1.2 matt int rv = EFAULT; 113 1.2 matt 114 1.32 rin if (usertrap) { 115 1.2 matt ci->ci_ev_umchk.ev_count++; 116 1.2 matt KSI_INIT_TRAP(ksi); 117 1.32 rin ksi->ksi_signo = SIGBUS; 118 1.32 rin ksi->ksi_trap = EXC_MCHK; 119 1.2 matt ksi->ksi_addr = (void *)faultva; 120 1.32 rin ksi->ksi_code = BUS_OBJERR; 121 1.2 matt } 122 1.2 matt 123 1.2 matt return rv; 124 1.2 matt } 125 1.2 matt 126 1.2 matt static inline vm_prot_t 127 1.2 matt get_faulttype(const struct trapframe * const tf) 128 1.2 matt { 129 1.2 matt return VM_PROT_READ | (tf->tf_esr & ESR_ST ? VM_PROT_WRITE : 0); 130 1.2 matt } 131 1.2 matt 132 1.2 matt static inline struct vm_map * 133 1.2 matt get_faultmap(const struct trapframe * const tf, register_t psl_mask) 134 1.2 matt { 135 1.2 matt return (tf->tf_srr1 & psl_mask) 136 1.2 matt ? &curlwp->l_proc->p_vmspace->vm_map 137 1.2 matt : kernel_map; 138 1.2 matt } 139 1.2 matt 140 1.2 matt /* 141 1.17 matt * We could use pmap_pte_lookup but this slightly faster since we already 142 1.2 matt * the segtab pointers in cpu_info. 143 1.2 matt */ 144 1.2 matt static inline pt_entry_t * 145 1.2 matt trap_pte_lookup(struct trapframe *tf, vaddr_t va, register_t psl_mask) 146 1.2 matt { 147 1.38 skrll pmap_segtab_t ** const stbs = &curcpu()->ci_pmap_kern_segtab; 148 1.38 skrll pmap_segtab_t * const stb = stbs[(tf->tf_srr1 / psl_mask) & 1]; 149 1.38 skrll if (__predict_false(stb == NULL)) 150 1.2 matt return NULL; 151 1.39 skrll 152 1.39 skrll pmap_ptpage_t * const ppg = stb->seg_ppg[va >> SEGSHIFT]; 153 1.39 skrll if (__predict_false(ppg == NULL)) 154 1.2 matt return NULL; 155 1.39 skrll const size_t pte_idx = (va >> PGSHIFT) & (NPTEPG - 1); 156 1.39 skrll 157 1.39 skrll return ppg->ppg_ptes + pte_idx; 158 1.2 matt } 159 1.2 matt 160 1.2 matt static int 161 1.2 matt pagefault(struct vm_map *map, vaddr_t va, vm_prot_t ftype, bool usertrap) 162 1.2 matt { 163 1.2 matt struct lwp * const l = curlwp; 164 1.2 matt int rv; 165 1.2 matt 166 1.2 matt // printf("%s(%p,%#lx,%u,%u)\n", __func__, map, va, ftype, usertrap); 167 1.2 matt 168 1.2 matt if (usertrap) { 169 1.2 matt rv = uvm_fault(map, trunc_page(va), ftype); 170 1.2 matt if (rv == 0) 171 1.2 matt uvm_grow(l->l_proc, trunc_page(va)); 172 1.2 matt } else { 173 1.2 matt if (cpu_intr_p()) 174 1.2 matt return EFAULT; 175 1.2 matt 176 1.2 matt struct pcb * const pcb = lwp_getpcb(l); 177 1.2 matt struct faultbuf * const fb = pcb->pcb_onfault; 178 1.2 matt pcb->pcb_onfault = NULL; 179 1.2 matt rv = uvm_fault(map, trunc_page(va), ftype); 180 1.2 matt pcb->pcb_onfault = fb; 181 1.2 matt if (map != kernel_map) { 182 1.2 matt if (rv == 0) 183 1.2 matt uvm_grow(l->l_proc, trunc_page(va)); 184 1.2 matt } 185 1.2 matt } 186 1.2 matt return rv; 187 1.2 matt } 188 1.2 matt 189 1.32 rin static void 190 1.32 rin vm_signal(int error, int trap, vaddr_t addr, ksiginfo_t *ksi) 191 1.32 rin { 192 1.32 rin 193 1.32 rin KSI_INIT_TRAP(ksi); 194 1.32 rin switch (error) { 195 1.32 rin case EINVAL: 196 1.32 rin ksi->ksi_signo = SIGBUS; 197 1.32 rin ksi->ksi_code = BUS_ADRERR; 198 1.32 rin break; 199 1.32 rin case EACCES: 200 1.32 rin ksi->ksi_signo = SIGSEGV; 201 1.32 rin ksi->ksi_code = SEGV_ACCERR; 202 1.32 rin break; 203 1.32 rin default: 204 1.32 rin ksi->ksi_signo = SIGSEGV; 205 1.32 rin ksi->ksi_code = SEGV_MAPERR; 206 1.32 rin break; 207 1.32 rin } 208 1.32 rin ksi->ksi_trap = trap; 209 1.32 rin ksi->ksi_addr = (void *)addr; 210 1.32 rin } 211 1.32 rin 212 1.2 matt static int 213 1.2 matt dsi_exception(struct trapframe *tf, ksiginfo_t *ksi) 214 1.2 matt { 215 1.2 matt const vaddr_t faultva = tf->tf_dear; 216 1.2 matt const vm_prot_t ftype = get_faulttype(tf); 217 1.2 matt struct vm_map * const faultmap = get_faultmap(tf, PSL_DS); 218 1.2 matt const bool usertrap = usertrap_p(tf); 219 1.2 matt 220 1.2 matt kpreempt_disable(); 221 1.2 matt struct cpu_info * const ci = curcpu(); 222 1.2 matt 223 1.2 matt if (usertrap) 224 1.2 matt ci->ci_ev_udsi.ev_count++; 225 1.2 matt else 226 1.2 matt ci->ci_ev_kdsi.ev_count++; 227 1.2 matt 228 1.2 matt /* 229 1.2 matt * If we had a TLB entry (which we must have had to get this exception), 230 1.2 matt * we certainly have a PTE. 231 1.2 matt */ 232 1.2 matt pt_entry_t * const ptep = trap_pte_lookup(tf, trunc_page(faultva), 233 1.2 matt PSL_DS); 234 1.2 matt KASSERT(ptep != NULL); 235 1.2 matt pt_entry_t pte = *ptep; 236 1.2 matt 237 1.2 matt if ((ftype & VM_PROT_WRITE) 238 1.2 matt && ((pte & (PTE_xW|PTE_UNMODIFIED)) == (PTE_xW|PTE_UNMODIFIED))) { 239 1.2 matt const paddr_t pa = pte_to_paddr(pte); 240 1.2 matt struct vm_page * const pg = PHYS_TO_VM_PAGE(pa); 241 1.2 matt KASSERT(pg); 242 1.11 matt struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg); 243 1.2 matt 244 1.11 matt if (!VM_PAGEMD_MODIFIED_P(mdpg)) { 245 1.11 matt pmap_page_set_attributes(mdpg, VM_PAGEMD_MODIFIED); 246 1.2 matt } 247 1.2 matt pte &= ~PTE_UNMODIFIED; 248 1.2 matt *ptep = pte; 249 1.2 matt pmap_tlb_update_addr(faultmap->pmap, trunc_page(faultva), 250 1.2 matt pte, 0); 251 1.2 matt kpreempt_enable(); 252 1.2 matt return 0; 253 1.2 matt } 254 1.2 matt kpreempt_enable(); 255 1.2 matt 256 1.2 matt int rv = pagefault(faultmap, faultva, ftype, usertrap); 257 1.2 matt 258 1.2 matt if (__predict_false(rv != 0 && usertrap)) { 259 1.2 matt ci->ci_ev_udsi_fatal.ev_count++; 260 1.32 rin vm_signal(rv, EXC_DSI, faultva, ksi); 261 1.2 matt } 262 1.2 matt return rv; 263 1.2 matt } 264 1.2 matt 265 1.2 matt static int 266 1.2 matt isi_exception(struct trapframe *tf, ksiginfo_t *ksi) 267 1.2 matt { 268 1.2 matt const vaddr_t faultva = trunc_page(tf->tf_srr0); 269 1.2 matt struct vm_map * const faultmap = get_faultmap(tf, PSL_IS); 270 1.2 matt const bool usertrap = usertrap_p(tf); 271 1.2 matt 272 1.2 matt kpreempt_disable(); 273 1.2 matt struct cpu_info * const ci = curcpu(); 274 1.2 matt 275 1.2 matt if (usertrap) 276 1.2 matt ci->ci_ev_isi.ev_count++; 277 1.2 matt else 278 1.2 matt ci->ci_ev_kisi.ev_count++; 279 1.2 matt 280 1.2 matt /* 281 1.2 matt * If we had a TLB entry (which we must have had to get this exception), 282 1.2 matt * we certainly have a PTE. 283 1.2 matt */ 284 1.2 matt pt_entry_t * const ptep = trap_pte_lookup(tf, trunc_page(faultva), 285 1.2 matt PSL_IS); 286 1.2 matt if (ptep == NULL) 287 1.20 matt dump_trapframe(tf, NULL); 288 1.2 matt KASSERT(ptep != NULL); 289 1.2 matt pt_entry_t pte = *ptep; 290 1.2 matt 291 1.8 matt UVMHIST_FUNC(__func__); UVMHIST_CALLED(pmapexechist); 292 1.8 matt 293 1.2 matt if ((pte & PTE_UNSYNCED) == PTE_UNSYNCED) { 294 1.2 matt const paddr_t pa = pte_to_paddr(pte); 295 1.2 matt struct vm_page * const pg = PHYS_TO_VM_PAGE(pa); 296 1.2 matt KASSERT(pg); 297 1.11 matt struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg); 298 1.2 matt 299 1.35 rin #ifdef UVMHIST 300 1.35 rin if (VM_PAGEMD_EXECPAGE_P(mdpg)) 301 1.35 rin UVMHIST_LOG(pmapexechist, 302 1.35 rin "srr0=%#x pg=%p (pa %#"PRIxPADDR"): " 303 1.40 skrll "no syncicache (already execpage)", 304 1.35 rin tf->tf_srr0, (uintptr_t)pg, pa, 0); 305 1.35 rin else 306 1.35 rin UVMHIST_LOG(pmapexechist, 307 1.35 rin "srr0=%#x pg=%p (pa %#"PRIxPADDR"): " 308 1.35 rin "performed syncicache (now execpage)", 309 1.35 rin tf->tf_srr0, (uintptr_t)pg, pa, 0); 310 1.35 rin #endif 311 1.8 matt 312 1.11 matt if (!VM_PAGEMD_EXECPAGE_P(mdpg)) { 313 1.2 matt ci->ci_softc->cpu_ev_exec_trap_sync.ev_count++; 314 1.2 matt dcache_wb_page(pa); 315 1.2 matt icache_inv_page(pa); 316 1.11 matt pmap_page_set_attributes(mdpg, VM_PAGEMD_EXECPAGE); 317 1.2 matt } 318 1.2 matt pte &= ~PTE_UNSYNCED; 319 1.2 matt pte |= PTE_xX; 320 1.2 matt *ptep = pte; 321 1.8 matt 322 1.2 matt pmap_tlb_update_addr(faultmap->pmap, trunc_page(faultva), 323 1.2 matt pte, 0); 324 1.2 matt kpreempt_enable(); 325 1.8 matt UVMHIST_LOG(pmapexechist, "<- 0", 0,0,0,0); 326 1.8 matt return 0; 327 1.2 matt } 328 1.2 matt kpreempt_enable(); 329 1.2 matt 330 1.2 matt int rv = pagefault(faultmap, faultva, VM_PROT_READ|VM_PROT_EXECUTE, 331 1.2 matt usertrap); 332 1.2 matt 333 1.2 matt if (__predict_false(rv != 0 && usertrap)) { 334 1.2 matt ci->ci_ev_isi_fatal.ev_count++; 335 1.32 rin vm_signal(rv, EXC_ISI, tf->tf_srr0, ksi); 336 1.2 matt } 337 1.8 matt UVMHIST_LOG(pmapexechist, "<- %d", rv, 0,0,0); 338 1.2 matt return rv; 339 1.2 matt } 340 1.2 matt 341 1.2 matt static int 342 1.2 matt dtlb_exception(struct trapframe *tf, ksiginfo_t *ksi) 343 1.2 matt { 344 1.2 matt const vaddr_t faultva = tf->tf_dear; 345 1.2 matt const vm_prot_t ftype = get_faulttype(tf); 346 1.2 matt struct vm_map * const faultmap = get_faultmap(tf, PSL_DS); 347 1.2 matt struct cpu_info * const ci = curcpu(); 348 1.2 matt const bool usertrap = usertrap_p(tf); 349 1.2 matt 350 1.2 matt #if 0 351 1.2 matt /* 352 1.2 matt * This is what pte_load in trap_subr.S does for us. 353 1.2 matt */ 354 1.2 matt const pt_entry_t * const ptep = 355 1.2 matt trap_pte_lookup(tf, trunc_page(faultva), PSL_DS); 356 1.2 matt if (ptep != NULL && !usertrap && pte_valid_p(*ptep)) { 357 1.2 matt tlb_update_addr(trunc_page(faultva), KERNEL_PID, *ptep, true); 358 1.2 matt ci->ci_ev_tlbmiss_soft.ev_count++; 359 1.2 matt return 0; 360 1.2 matt } 361 1.2 matt #endif 362 1.2 matt 363 1.2 matt ci->ci_ev_dtlbmiss_hard.ev_count++; 364 1.2 matt 365 1.2 matt // printf("pagefault(%p,%#lx,%u,%u)", faultmap, faultva, ftype, usertrap); 366 1.2 matt int rv = pagefault(faultmap, faultva, ftype, usertrap); 367 1.2 matt // printf(": %d\n", rv); 368 1.2 matt 369 1.2 matt if (__predict_false(rv != 0 && usertrap)) { 370 1.2 matt ci->ci_ev_udsi_fatal.ev_count++; 371 1.32 rin vm_signal(rv, EXC_DSI, faultva, ksi); 372 1.2 matt } 373 1.2 matt return rv; 374 1.2 matt } 375 1.2 matt 376 1.2 matt static int 377 1.2 matt itlb_exception(struct trapframe *tf, ksiginfo_t *ksi) 378 1.2 matt { 379 1.2 matt struct vm_map * const faultmap = get_faultmap(tf, PSL_IS); 380 1.2 matt const vaddr_t faultva = tf->tf_srr0; 381 1.2 matt struct cpu_info * const ci = curcpu(); 382 1.2 matt const bool usertrap = usertrap_p(tf); 383 1.2 matt 384 1.2 matt ci->ci_ev_itlbmiss_hard.ev_count++; 385 1.2 matt 386 1.2 matt int rv = pagefault(faultmap, faultva, VM_PROT_READ|VM_PROT_EXECUTE, 387 1.2 matt usertrap); 388 1.2 matt 389 1.2 matt if (__predict_false(rv != 0 && usertrap)) { 390 1.2 matt ci->ci_ev_isi_fatal.ev_count++; 391 1.32 rin vm_signal(rv, EXC_ISI, tf->tf_srr0, ksi); 392 1.2 matt } 393 1.2 matt return rv; 394 1.2 matt } 395 1.2 matt 396 1.2 matt static int 397 1.2 matt spe_exception(struct trapframe *tf, ksiginfo_t *ksi) 398 1.2 matt { 399 1.2 matt struct cpu_info * const ci = curcpu(); 400 1.2 matt 401 1.2 matt if (!usertrap_p(tf)) 402 1.2 matt return EPERM; 403 1.2 matt 404 1.2 matt ci->ci_ev_vec.ev_count++; 405 1.2 matt 406 1.2 matt #ifdef PPC_HAVE_SPE 407 1.6 matt vec_load(); 408 1.2 matt return 0; 409 1.2 matt #else 410 1.2 matt KSI_INIT_TRAP(ksi); 411 1.2 matt ksi->ksi_signo = SIGILL; 412 1.2 matt ksi->ksi_trap = EXC_PGM; 413 1.2 matt ksi->ksi_code = ILL_ILLOPC; 414 1.2 matt ksi->ksi_addr = (void *)tf->tf_srr0; 415 1.2 matt return EPERM; 416 1.2 matt #endif 417 1.2 matt } 418 1.2 matt 419 1.2 matt static bool 420 1.2 matt emulate_opcode(struct trapframe *tf, ksiginfo_t *ksi) 421 1.2 matt { 422 1.2 matt uint32_t opcode; 423 1.2 matt if (copyin((void *)tf->tf_srr0, &opcode, sizeof(opcode)) != 0) 424 1.2 matt return false; 425 1.2 matt 426 1.2 matt if (opcode == OPC_LWSYNC) 427 1.2 matt return true; 428 1.2 matt 429 1.2 matt if (OPC_MFSPR_P(opcode, SPR_PVR)) { 430 1.2 matt __asm ("mfpvr %0" : "=r"(tf->tf_fixreg[OPC_MFSPR_REG(opcode)])); 431 1.2 matt return true; 432 1.2 matt } 433 1.2 matt 434 1.18 matt if (OPC_MFSPR_P(opcode, SPR_PIR)) { 435 1.25 matt __asm ("mfspr %0, %1" 436 1.25 matt : "=r"(tf->tf_fixreg[OPC_MFSPR_REG(opcode)]) 437 1.26 joerg : "n"(SPR_PIR)); 438 1.18 matt return true; 439 1.18 matt } 440 1.18 matt 441 1.18 matt if (OPC_MFSPR_P(opcode, SPR_SVR)) { 442 1.18 matt __asm ("mfspr %0,%1" 443 1.18 matt : "=r"(tf->tf_fixreg[OPC_MFSPR_REG(opcode)]) 444 1.18 matt : "n"(SPR_SVR)); 445 1.18 matt return true; 446 1.18 matt } 447 1.18 matt 448 1.34 rin return emulate_mxmsr(curlwp, tf, opcode); 449 1.2 matt } 450 1.2 matt 451 1.2 matt static int 452 1.2 matt pgm_exception(struct trapframe *tf, ksiginfo_t *ksi) 453 1.2 matt { 454 1.2 matt struct cpu_info * const ci = curcpu(); 455 1.2 matt int rv = EPERM; 456 1.2 matt 457 1.2 matt if (!usertrap_p(tf)) 458 1.2 matt return rv; 459 1.2 matt 460 1.8 matt UVMHIST_FUNC(__func__); UVMHIST_CALLED(pmapexechist); 461 1.8 matt 462 1.40 skrll UVMHIST_LOG(pmapexechist, " srr0/1=%#x/%#x esr=%#x pte=%#x", 463 1.8 matt tf->tf_srr0, tf->tf_srr1, tf->tf_esr, 464 1.8 matt *trap_pte_lookup(tf, trunc_page(tf->tf_srr0), PSL_IS)); 465 1.8 matt 466 1.2 matt ci->ci_ev_pgm.ev_count++; 467 1.2 matt 468 1.37 rin KSI_INIT_TRAP(ksi); 469 1.37 rin 470 1.2 matt if (tf->tf_esr & ESR_PTR) { 471 1.37 rin struct lwp * const l = curlwp; 472 1.37 rin struct proc * const p = curlwp->l_proc; 473 1.37 rin vaddr_t va = (vaddr_t)tf->tf_srr0; 474 1.37 rin int error; 475 1.37 rin 476 1.37 rin /* 477 1.37 rin * Restore original instruction and clear BP. 478 1.37 rin */ 479 1.37 rin if (p->p_md.md_ss_addr[0] == va || 480 1.37 rin p->p_md.md_ss_addr[1] == va) { 481 1.37 rin error = ppc_sstep(l, 0); 482 1.37 rin if (error != 0) { 483 1.37 rin vm_signal(error, EXC_PGM /* XXX */, va, ksi); 484 1.37 rin return error; 485 1.37 rin } 486 1.37 rin ksi->ksi_code = TRAP_TRACE; 487 1.37 rin } else 488 1.37 rin ksi->ksi_code = TRAP_BRKPT; 489 1.37 rin 490 1.37 rin if (p->p_raslist != NULL && 491 1.37 rin ras_lookup(p, (void *)va) != (void *)-1) { 492 1.37 rin tf->tf_srr0 += (ksi->ksi_code == TRAP_TRACE) ? 0 : 4; 493 1.2 matt return 0; 494 1.2 matt } 495 1.5 matt } 496 1.5 matt 497 1.5 matt if (tf->tf_esr & (ESR_PIL|ESR_PPR)) { 498 1.2 matt if (emulate_opcode(tf, ksi)) { 499 1.2 matt tf->tf_srr0 += 4; 500 1.2 matt return 0; 501 1.2 matt } 502 1.2 matt } 503 1.2 matt 504 1.18 matt if (tf->tf_esr & ESR_PIL) { 505 1.33 rin struct lwp * const l = curlwp; 506 1.33 rin struct pcb * const pcb = lwp_getpcb(l); 507 1.33 rin 508 1.33 rin if (__predict_false(!fpu_used_p(l))) { 509 1.18 matt memset(&pcb->pcb_fpu, 0, sizeof(pcb->pcb_fpu)); 510 1.33 rin fpu_mark_used(l); 511 1.18 matt } 512 1.18 matt if (fpu_emulate(tf, &pcb->pcb_fpu, ksi)) { 513 1.18 matt if (ksi->ksi_signo == 0) { 514 1.18 matt ci->ci_ev_fpu.ev_count++; 515 1.18 matt return 0; 516 1.18 matt } 517 1.18 matt return EFAULT; 518 1.18 matt } 519 1.18 matt } 520 1.18 matt 521 1.2 matt ksi->ksi_signo = SIGILL; 522 1.2 matt ksi->ksi_trap = EXC_PGM; 523 1.4 matt if (tf->tf_esr & ESR_PIL) { 524 1.2 matt ksi->ksi_code = ILL_ILLOPC; 525 1.4 matt } else if (tf->tf_esr & ESR_PPR) { 526 1.2 matt ksi->ksi_code = ILL_PRVOPC; 527 1.4 matt } else if (tf->tf_esr & ESR_PTR) { 528 1.4 matt ksi->ksi_signo = SIGTRAP; 529 1.4 matt } else { 530 1.2 matt ksi->ksi_code = 0; 531 1.4 matt } 532 1.2 matt ksi->ksi_addr = (void *)tf->tf_srr0; 533 1.2 matt return rv; 534 1.2 matt } 535 1.2 matt 536 1.37 rin #if 0 537 1.2 matt static int 538 1.5 matt debug_exception(struct trapframe *tf, ksiginfo_t *ksi) 539 1.5 matt { 540 1.5 matt struct cpu_info * const ci = curcpu(); 541 1.5 matt int rv = EPERM; 542 1.5 matt 543 1.5 matt if (!usertrap_p(tf)) 544 1.5 matt return rv; 545 1.5 matt 546 1.5 matt ci->ci_ev_debug.ev_count++; 547 1.5 matt 548 1.5 matt /* 549 1.5 matt * Ack the interrupt. 550 1.5 matt */ 551 1.5 matt mtspr(SPR_DBSR, tf->tf_esr); 552 1.25 matt KASSERT(tf->tf_esr & (DBSR_IAC1|DBSR_IAC2|DBSR_BRT)); 553 1.5 matt KASSERT((tf->tf_srr1 & PSL_SE) == 0); 554 1.5 matt 555 1.5 matt /* 556 1.5 matt * Disable debug events 557 1.5 matt */ 558 1.5 matt mtspr(SPR_DBCR1, 0); 559 1.5 matt mtspr(SPR_DBCR0, 0); 560 1.5 matt 561 1.5 matt /* 562 1.5 matt * Tell the debugger ... 563 1.5 matt */ 564 1.5 matt KSI_INIT_TRAP(ksi); 565 1.5 matt ksi->ksi_signo = SIGTRAP; 566 1.5 matt ksi->ksi_trap = EXC_TRC; 567 1.5 matt ksi->ksi_addr = (void *)tf->tf_srr0; 568 1.5 matt ksi->ksi_code = TRAP_TRACE; 569 1.5 matt return rv; 570 1.5 matt } 571 1.37 rin #endif 572 1.5 matt 573 1.5 matt static int 574 1.2 matt ali_exception(struct trapframe *tf, ksiginfo_t *ksi) 575 1.2 matt { 576 1.2 matt struct cpu_info * const ci = curcpu(); 577 1.2 matt int rv = EFAULT; 578 1.2 matt 579 1.2 matt ci->ci_ev_ali.ev_count++; 580 1.2 matt 581 1.2 matt if (rv != 0 && usertrap_p(tf)) { 582 1.2 matt ci->ci_ev_ali_fatal.ev_count++; 583 1.2 matt KSI_INIT_TRAP(ksi); 584 1.2 matt ksi->ksi_signo = SIGILL; 585 1.2 matt ksi->ksi_trap = EXC_PGM; 586 1.2 matt if (tf->tf_esr & ESR_PIL) 587 1.2 matt ksi->ksi_code = ILL_ILLOPC; 588 1.2 matt else if (tf->tf_esr & ESR_PPR) 589 1.2 matt ksi->ksi_code = ILL_PRVOPC; 590 1.2 matt else if (tf->tf_esr & ESR_PTR) 591 1.2 matt ksi->ksi_code = ILL_ILLTRP; 592 1.2 matt else 593 1.2 matt ksi->ksi_code = 0; 594 1.2 matt ksi->ksi_addr = (void *)tf->tf_srr0; 595 1.2 matt } 596 1.2 matt return rv; 597 1.2 matt } 598 1.2 matt 599 1.2 matt static int 600 1.2 matt embedded_fp_data_exception(struct trapframe *tf, ksiginfo_t *ksi) 601 1.2 matt { 602 1.2 matt struct cpu_info * const ci = curcpu(); 603 1.2 matt int rv = EFAULT; 604 1.2 matt 605 1.2 matt ci->ci_ev_fpu.ev_count++; 606 1.2 matt 607 1.2 matt if (rv != 0 && usertrap_p(tf)) { 608 1.2 matt KSI_INIT_TRAP(ksi); 609 1.2 matt #ifdef PPC_HAVE_SPE 610 1.2 matt ksi->ksi_signo = SIGFPE; 611 1.2 matt ksi->ksi_trap = tf->tf_exc; 612 1.2 matt ksi->ksi_code = vec_siginfo_code(tf); 613 1.2 matt #else 614 1.2 matt ksi->ksi_signo = SIGILL; 615 1.2 matt ksi->ksi_trap = EXC_PGM; 616 1.2 matt ksi->ksi_code = ILL_ILLOPC; 617 1.2 matt #endif 618 1.2 matt ksi->ksi_addr = (void *)tf->tf_srr0; 619 1.2 matt } 620 1.2 matt return rv; 621 1.2 matt } 622 1.2 matt 623 1.2 matt static int 624 1.2 matt embedded_fp_round_exception(struct trapframe *tf, ksiginfo_t *ksi) 625 1.2 matt { 626 1.2 matt struct cpu_info * const ci = curcpu(); 627 1.2 matt int rv = EDOM; 628 1.2 matt 629 1.2 matt ci->ci_ev_fpu.ev_count++; 630 1.2 matt 631 1.2 matt if (rv != 0 && usertrap_p(tf)) { 632 1.2 matt KSI_INIT_TRAP(ksi); 633 1.2 matt #ifdef PPC_HAVE_SPE 634 1.2 matt ksi->ksi_signo = SIGFPE; 635 1.2 matt ksi->ksi_trap = tf->tf_exc; 636 1.2 matt ksi->ksi_code = vec_siginfo_code(tf); 637 1.2 matt #else 638 1.2 matt ksi->ksi_signo = SIGILL; 639 1.2 matt ksi->ksi_trap = EXC_PGM; 640 1.2 matt ksi->ksi_code = ILL_ILLOPC; 641 1.2 matt #endif 642 1.2 matt ksi->ksi_addr = (void *)tf->tf_srr0; 643 1.2 matt } 644 1.2 matt return rv; 645 1.2 matt } 646 1.2 matt 647 1.19 matt void 648 1.20 matt dump_trapframe(const struct trapframe *tf, void (*pr)(const char *, ...)) 649 1.2 matt { 650 1.20 matt if (pr == NULL) 651 1.20 matt pr = printf; 652 1.20 matt (*pr)("trapframe %p (exc=%x srr0/1=%#lx/%#lx esr/dear=%#x/%#lx)\n", 653 1.2 matt tf, tf->tf_exc, tf->tf_srr0, tf->tf_srr1, tf->tf_esr, tf->tf_dear); 654 1.20 matt (*pr)("lr =%08lx ctr=%08lx cr =%08x xer=%08x\n", 655 1.2 matt tf->tf_lr, tf->tf_ctr, tf->tf_cr, tf->tf_xer); 656 1.2 matt for (u_int r = 0; r < 32; r += 4) { 657 1.20 matt (*pr)("r%02u=%08lx r%02u=%08lx r%02u=%08lx r%02u=%08lx\n", 658 1.2 matt r+0, tf->tf_fixreg[r+0], r+1, tf->tf_fixreg[r+1], 659 1.2 matt r+2, tf->tf_fixreg[r+2], r+3, tf->tf_fixreg[r+3]); 660 1.2 matt } 661 1.2 matt } 662 1.20 matt 663 1.41 andvar #ifdef DDB 664 1.2 matt static bool 665 1.2 matt ddb_exception(struct trapframe *tf) 666 1.2 matt { 667 1.2 matt #if 0 668 1.2 matt const register_t ddb_trapfunc = (uintptr_t) cpu_Debugger; 669 1.2 matt if ((tf->tf_esr & ESR_PTR) == 0) 670 1.2 matt return false; 671 1.2 matt if (ddb_trapfunc <= tf->tf_srr0 && tf->tf_srr0 <= ddb_trapfunc+16) { 672 1.2 matt register_t srr0 = tf->tf_srr0; 673 1.2 matt if (kdb_trap(tf->tf_exc, tf)) { 674 1.2 matt if (srr0 == tf->tf_srr0) 675 1.2 matt tf->tf_srr0 += 4; 676 1.2 matt return true; 677 1.2 matt } 678 1.2 matt } 679 1.2 matt return false; 680 1.2 matt #else 681 1.5 matt #if 0 682 1.2 matt struct cpu_info * const ci = curcpu(); 683 1.2 matt struct cpu_softc * const cpu = ci->ci_softc; 684 1.2 matt printf("CPL stack:"); 685 1.2 matt if (ci->ci_idepth >= 0) { 686 1.2 matt for (u_int i = 0; i <= ci->ci_idepth; i++) { 687 1.2 matt printf(" [%u]=%u", i, cpu->cpu_pcpls[i]); 688 1.2 matt } 689 1.2 matt } 690 1.2 matt printf(" %u\n", ci->ci_cpl); 691 1.20 matt dump_trapframe(tf, NULL); 692 1.5 matt #endif 693 1.2 matt if (kdb_trap(tf->tf_exc, tf)) { 694 1.2 matt tf->tf_srr0 += 4; 695 1.2 matt return true; 696 1.2 matt } 697 1.2 matt return false; 698 1.2 matt #endif 699 1.2 matt } 700 1.41 andvar #endif /* DDB */ 701 1.2 matt 702 1.2 matt static bool 703 1.2 matt onfaulted(struct trapframe *tf, register_t rv) 704 1.2 matt { 705 1.2 matt struct lwp * const l = curlwp; 706 1.2 matt struct pcb * const pcb = lwp_getpcb(l); 707 1.2 matt struct faultbuf * const fb = pcb->pcb_onfault; 708 1.2 matt if (fb == NULL) 709 1.2 matt return false; 710 1.2 matt tf->tf_srr0 = fb->fb_pc; 711 1.2 matt tf->tf_srr1 = fb->fb_msr; 712 1.2 matt tf->tf_cr = fb->fb_cr; 713 1.2 matt tf->tf_fixreg[1] = fb->fb_sp; 714 1.2 matt tf->tf_fixreg[2] = fb->fb_r2; 715 1.2 matt tf->tf_fixreg[3] = rv; 716 1.30 rin memcpy(&tf->tf_fixreg[13], fb->fb_fixreg, sizeof(fb->fb_fixreg)); 717 1.2 matt return true; 718 1.2 matt } 719 1.2 matt 720 1.2 matt void 721 1.2 matt trap(enum ppc_booke_exceptions trap_code, struct trapframe *tf) 722 1.2 matt { 723 1.2 matt const bool usertrap = usertrap_p(tf); 724 1.2 matt struct cpu_info * const ci = curcpu(); 725 1.2 matt struct lwp * const l = curlwp; 726 1.2 matt struct proc * const p = l->l_proc; 727 1.2 matt ksiginfo_t ksi; 728 1.2 matt int rv = EACCES; 729 1.2 matt 730 1.2 matt ci->ci_ev_traps.ev_count++; 731 1.2 matt ci->ci_data.cpu_ntrap++; 732 1.2 matt 733 1.2 matt KASSERTMSG(!usertrap || tf == trapframe(l), 734 1.13 jym "trap: tf=%p is invalid: trapframe(%p)=%p", tf, l, trapframe(l)); 735 1.2 matt 736 1.2 matt #if 0 737 1.2 matt if (trap_code != T_PROGRAM || usertrap) 738 1.2 matt printf("trap(enter): %s (tf=%p, esr/dear=%#x/%#lx, srr0/1=%#lx/%#lx, lr=%#lx)\n", 739 1.2 matt trap_names[trap_code], tf, tf->tf_esr, tf->tf_dear, 740 1.2 matt tf->tf_srr0, tf->tf_srr1, tf->tf_lr); 741 1.2 matt #endif 742 1.2 matt #if 0 743 1.2 matt if ((register_t)tf >= (register_t)l->l_addr + USPACE 744 1.2 matt || (register_t)tf < (register_t)l->l_addr + PAGE_SIZE) { 745 1.2 matt printf("%s(entry): pid %d.%d (%s): invalid tf addr %p\n", 746 1.2 matt __func__, p->p_pid, l->l_lid, p->p_comm, tf); 747 1.20 matt dump_trapframe(tf, NULL); 748 1.41 andvar console_debugger(); 749 1.2 matt } 750 1.2 matt #endif 751 1.2 matt #if 0 752 1.2 matt if ((mfmsr() & PSL_CE) == 0) { 753 1.2 matt printf("%s(entry): pid %d.%d (%s): %s: PSL_CE (%#lx) not set\n", 754 1.2 matt __func__, p->p_pid, l->l_lid, p->p_comm, 755 1.2 matt trap_names[trap_code], mfmsr()); 756 1.20 matt dump_trapframe(tf, NULL); 757 1.2 matt } 758 1.2 matt #endif 759 1.2 matt 760 1.15 matt if ((VM_MAX_ADDRESS & 0x80000000) == 0 761 1.15 matt && usertrap && (tf->tf_fixreg[1] & 0x80000000)) { 762 1.27 flxd printf("%s(entry): pid %d.%d (%s): %s invalid sp %#lx " 763 1.27 flxd "(sprg1=%#jx)\n", __func__, p->p_pid, l->l_lid, p->p_comm, 764 1.27 flxd trap_names[trap_code], tf->tf_fixreg[1], 765 1.27 flxd (uintmax_t)mfspr(SPR_SPRG1)); 766 1.20 matt dump_trapframe(tf, NULL); 767 1.41 andvar console_debugger(); 768 1.2 matt } 769 1.2 matt 770 1.2 matt if (usertrap && (tf->tf_srr1 & (PSL_DS|PSL_IS)) != (PSL_DS|PSL_IS)) { 771 1.2 matt printf("%s(entry): pid %d.%d (%s): %s invalid PSL %#lx\n", 772 1.2 matt __func__, p->p_pid, l->l_lid, p->p_comm, 773 1.2 matt trap_names[trap_code], tf->tf_srr1); 774 1.20 matt dump_trapframe(tf, NULL); 775 1.41 andvar console_debugger(); 776 1.2 matt } 777 1.2 matt 778 1.2 matt switch (trap_code) { 779 1.2 matt case T_CRITIAL_INPUT: 780 1.2 matt case T_EXTERNAL_INPUT: 781 1.37 rin case T_DEBUG: 782 1.2 matt case T_DECREMENTER: 783 1.2 matt case T_FIXED_INTERVAL: 784 1.2 matt case T_WATCHDOG: 785 1.2 matt case T_SYSTEM_CALL: 786 1.2 matt default: 787 1.2 matt panic("trap: unexcepted trap code %d! (tf=%p, srr0/1=%#lx/%#lx)", 788 1.2 matt trap_code, tf, tf->tf_srr0, tf->tf_srr1); 789 1.2 matt case T_MACHINE_CHECK: 790 1.2 matt rv = mchk_exception(tf, &ksi); 791 1.2 matt break; 792 1.2 matt case T_DSI: 793 1.2 matt rv = dsi_exception(tf, &ksi); 794 1.2 matt break; 795 1.2 matt case T_ISI: 796 1.2 matt rv = isi_exception(tf, &ksi); 797 1.2 matt break; 798 1.2 matt case T_ALIGNMENT: 799 1.2 matt rv = ali_exception(tf, &ksi); 800 1.2 matt break; 801 1.2 matt case T_SPE_UNAVAILABLE: 802 1.2 matt rv = spe_exception(tf, &ksi); 803 1.2 matt break; 804 1.2 matt case T_PROGRAM: 805 1.2 matt #ifdef DDB 806 1.2 matt if (!usertrap && ddb_exception(tf)) 807 1.2 matt return; 808 1.2 matt #endif 809 1.2 matt rv = pgm_exception(tf, &ksi); 810 1.2 matt break; 811 1.2 matt case T_FP_UNAVAILABLE: 812 1.2 matt case T_AP_UNAVAILABLE: 813 1.2 matt panic("trap: unexcepted trap code %d! (tf=%p, srr0/1=%#lx/%#lx)", 814 1.2 matt trap_code, tf, tf->tf_srr0, tf->tf_srr1); 815 1.2 matt case T_DATA_TLB_ERROR: 816 1.2 matt rv = dtlb_exception(tf, &ksi); 817 1.2 matt break; 818 1.2 matt case T_INSTRUCTION_TLB_ERROR: 819 1.2 matt rv = itlb_exception(tf, &ksi); 820 1.2 matt break; 821 1.37 rin #if 0 822 1.2 matt case T_DEBUG: 823 1.5 matt #ifdef DDB 824 1.5 matt if (!usertrap && ddb_exception(tf)) 825 1.5 matt return; 826 1.5 matt #endif 827 1.5 matt rv = debug_exception(tf, &ksi); 828 1.5 matt break; 829 1.37 rin #endif 830 1.2 matt case T_EMBEDDED_FP_DATA: 831 1.2 matt rv = embedded_fp_data_exception(tf, &ksi); 832 1.2 matt break; 833 1.2 matt case T_EMBEDDED_FP_ROUND: 834 1.2 matt rv = embedded_fp_round_exception(tf, &ksi); 835 1.2 matt break; 836 1.2 matt case T_EMBEDDED_PERF_MONITOR: 837 1.41 andvar #ifdef DDB 838 1.2 matt //db_stack_trace_print(tf->tf_fixreg[1], true, 40, "", printf); 839 1.41 andvar #endif 840 1.20 matt dump_trapframe(tf, NULL); 841 1.2 matt rv = EPERM; 842 1.2 matt break; 843 1.2 matt case T_AST: 844 1.2 matt KASSERT(usertrap); 845 1.12 matt cpu_ast(l, ci); 846 1.15 matt if ((VM_MAX_ADDRESS & 0x80000000) == 0 847 1.15 matt && (tf->tf_fixreg[1] & 0x80000000)) { 848 1.2 matt printf("%s(ast-exit): pid %d.%d (%s): invalid sp %#lx\n", 849 1.2 matt __func__, p->p_pid, l->l_lid, p->p_comm, 850 1.2 matt tf->tf_fixreg[1]); 851 1.20 matt dump_trapframe(tf, NULL); 852 1.41 andvar console_debugger(); 853 1.2 matt } 854 1.2 matt if ((tf->tf_srr1 & (PSL_DS|PSL_IS)) != (PSL_DS|PSL_IS)) { 855 1.2 matt printf("%s(entry): pid %d.%d (%s): %s invalid PSL %#lx\n", 856 1.2 matt __func__, p->p_pid, l->l_lid, p->p_comm, 857 1.2 matt trap_names[trap_code], tf->tf_srr1); 858 1.20 matt dump_trapframe(tf, NULL); 859 1.41 andvar console_debugger(); 860 1.2 matt } 861 1.2 matt #if 0 862 1.2 matt if ((mfmsr() & PSL_CE) == 0) { 863 1.2 matt printf("%s(exit): pid %d.%d (%s): %s: PSL_CE (%#lx) not set\n", 864 1.2 matt __func__, p->p_pid, l->l_lid, p->p_comm, 865 1.2 matt trap_names[trap_code], mfmsr()); 866 1.20 matt dump_trapframe(tf, NULL); 867 1.2 matt } 868 1.2 matt #endif 869 1.2 matt userret(l, tf); 870 1.2 matt return; 871 1.2 matt } 872 1.2 matt if (!usertrap) { 873 1.2 matt if (rv != 0) { 874 1.2 matt if (!onfaulted(tf, rv)) { 875 1.41 andvar #ifdef DDB 876 1.2 matt db_stack_trace_print(tf->tf_fixreg[1], true, 40, "", printf); 877 1.41 andvar #endif 878 1.20 matt dump_trapframe(tf, NULL); 879 1.2 matt panic("%s: pid %d.%d (%s): %s exception in kernel mode" 880 1.2 matt " (tf=%p, dear=%#lx, esr=%#x," 881 1.2 matt " srr0/1=%#lx/%#lx)", 882 1.2 matt __func__, p->p_pid, l->l_lid, p->p_comm, 883 1.2 matt trap_names[trap_code], tf, tf->tf_dear, 884 1.2 matt tf->tf_esr, tf->tf_srr0, tf->tf_srr1); 885 1.2 matt } 886 1.2 matt } 887 1.2 matt #if 0 888 1.2 matt if (tf->tf_fixreg[1] >= (register_t)l->l_addr + USPACE 889 1.2 matt || tf->tf_fixreg[1] < (register_t)l->l_addr + PAGE_SIZE) { 890 1.2 matt printf("%s(exit): pid %d.%d (%s): invalid kern sp %#lx\n", 891 1.2 matt __func__, p->p_pid, l->l_lid, p->p_comm, 892 1.2 matt tf->tf_fixreg[1]); 893 1.20 matt dump_trapframe(tf, NULL); 894 1.2 matt Debugger(); 895 1.2 matt } 896 1.2 matt #endif 897 1.2 matt #if 0 898 1.2 matt if ((mfmsr() & PSL_CE) == 0) { 899 1.2 matt printf("%s(exit): pid %d.%d (%s): %s: PSL_CE (%#lx) not set\n", 900 1.2 matt __func__, p->p_pid, l->l_lid, p->p_comm, 901 1.2 matt trap_names[trap_code], mfmsr()); 902 1.2 matt mtmsr(mfmsr()|PSL_CE); 903 1.20 matt dump_trapframe(tf, NULL); 904 1.2 matt } 905 1.2 matt #endif 906 1.2 matt } else { 907 1.2 matt if (rv == ENOMEM) { 908 1.2 matt printf("UVM: pid %d.%d (%s), uid %d killed: " 909 1.2 matt "out of swap\n", 910 1.2 matt p->p_pid, l->l_lid, p->p_comm, 911 1.2 matt l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1); 912 1.2 matt ksi.ksi_signo = SIGKILL; 913 1.32 rin ksi.ksi_code = 0; 914 1.2 matt } 915 1.2 matt if (rv != 0) { 916 1.21 matt /* 917 1.21 matt * Only print a fatal trap if the signal will be 918 1.21 matt * uncaught. 919 1.21 matt */ 920 1.21 matt if (cpu_printfataltraps 921 1.22 matt && (p->p_slflag & PSL_TRACED) == 0 922 1.21 matt && !sigismember(&p->p_sigctx.ps_sigcatch, 923 1.21 matt ksi.ksi_signo)) { 924 1.2 matt printf("%s: pid %d.%d (%s):" 925 1.2 matt " %s exception in user mode\n", 926 1.2 matt __func__, p->p_pid, l->l_lid, p->p_comm, 927 1.2 matt trap_names[trap_code]); 928 1.2 matt if (cpu_printfataltraps > 1) 929 1.20 matt dump_trapframe(tf, NULL); 930 1.2 matt } 931 1.2 matt (*p->p_emul->e_trapsignal)(l, &ksi); 932 1.2 matt } 933 1.2 matt #ifdef DEBUG 934 1.2 matt if ((tf->tf_srr1 & (PSL_DS|PSL_IS)) != (PSL_DS|PSL_IS)) { 935 1.2 matt printf("%s(exit): pid %d.%d (%s): %s invalid PSL %#lx\n", 936 1.2 matt __func__, p->p_pid, l->l_lid, p->p_comm, 937 1.2 matt trap_names[trap_code], tf->tf_srr1); 938 1.20 matt dump_trapframe(tf, NULL); 939 1.41 andvar console_debugger(); 940 1.2 matt } 941 1.2 matt #endif 942 1.2 matt #if 0 943 1.2 matt if ((mfmsr() & PSL_CE) == 0) { 944 1.2 matt printf("%s(exit): pid %d.%d (%s): %s: PSL_CE (%#lx) not set\n", 945 1.2 matt __func__, p->p_pid, l->l_lid, p->p_comm, 946 1.2 matt trap_names[trap_code], mfmsr()); 947 1.20 matt dump_trapframe(tf, NULL); 948 1.2 matt } 949 1.2 matt #endif 950 1.2 matt userret(l, tf); 951 1.2 matt } 952 1.2 matt } 953