Mon Apr 17 06:48:07 2023 UTC ()
Trailing whitespace


(skrll)
diff -r1.39 -r1.40 src/sys/arch/powerpc/booke/trap.c

cvs diff -r1.39 -r1.40 src/sys/arch/powerpc/booke/trap.c (switch to unified diff)

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