trap.c revision 1.111.4.4 1 /* $NetBSD: trap.c,v 1.111.4.4 2025/09/23 12:52:31 martin Exp $ */
2
3 /*-
4 * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matthew Fredette.
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 /* $OpenBSD: trap.c,v 1.30 2001/09/19 20:50:56 mickey Exp $ */
33
34 /*
35 * Copyright (c) 1998-2004 Michael Shalayeff
36 * All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 *
47 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
48 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
49 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
50 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
51 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
52 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
53 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
55 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
56 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
57 * THE POSSIBILITY OF SUCH DAMAGE.
58 */
59
60 #include <sys/cdefs.h>
61 __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.111.4.4 2025/09/23 12:52:31 martin Exp $");
62
63 /* #define INTRDEBUG */
64 /* #define TRAPDEBUG */
65 /* #define USERTRACE */
66
67 #include "opt_kgdb.h"
68 #include "opt_ptrace.h"
69
70 #include <sys/param.h>
71 #include <sys/systm.h>
72 #include <sys/kernel.h>
73 #include <sys/syscall.h>
74 #include <sys/syscallvar.h>
75 #include <sys/mutex.h>
76 #include <sys/ktrace.h>
77 #include <sys/proc.h>
78 #include <sys/signalvar.h>
79 #include <sys/acct.h>
80 #include <sys/signal.h>
81 #include <sys/device.h>
82 #include <sys/kauth.h>
83 #include <sys/kmem.h>
84 #include <sys/userret.h>
85
86 #include <net/netisr.h>
87
88 #ifdef KGDB
89 #include <sys/kgdb.h>
90 #endif
91
92 #include <uvm/uvm.h>
93
94 #include <machine/iomod.h>
95 #include <machine/cpufunc.h>
96 #include <machine/reg.h>
97 #include <machine/autoconf.h>
98
99 #include <machine/db_machdep.h>
100
101 #include <hppa/hppa/machdep.h>
102
103 #include <ddb/db_output.h>
104 #include <ddb/db_interface.h>
105
106 #ifdef PTRACE
107 void ss_clear_breakpoints(struct lwp *l);
108 int ss_put_value(struct lwp *, vaddr_t, u_int);
109 int ss_get_value(struct lwp *, vaddr_t, u_int *);
110
111 /* single-step breakpoint */
112 #define SSBREAKPOINT (HPPA_BREAK_KERNEL | (HPPA_BREAK_SS << 13))
113
114 #endif
115
116 #if defined(DEBUG) || defined(DIAGNOSTIC)
117 /*
118 * 0x6fc1000 is a stwm r1, d(sr0, sp), which is the last
119 * instruction in the function prologue that gcc -O0 uses.
120 * When we have this instruction we know the relationship
121 * between the stack pointer and the gcc -O0 frame pointer
122 * (in r3, loaded with the initial sp) for the body of a
123 * function.
124 *
125 * If the given instruction is a stwm r1, d(sr0, sp) where
126 * d > 0, we evaluate to d, else we evaluate to zero.
127 */
128 #define STWM_R1_D_SR0_SP(inst) \
129 (((inst) & 0xffffc001) == 0x6fc10000 ? (((inst) & 0x00003ff) >> 1) : 0)
130 #endif /* DEBUG || DIAGNOSTIC */
131
132 const char *trap_type[] = {
133 "invalid",
134 "HPMC",
135 "power failure",
136 "recovery counter",
137 "external interrupt",
138 "LPMC",
139 "ITLB miss fault",
140 "instruction protection",
141 "Illegal instruction",
142 "break instruction",
143 "privileged operation",
144 "privileged register",
145 "overflow",
146 "conditional",
147 "assist exception",
148 "DTLB miss",
149 "ITLB non-access miss",
150 "DTLB non-access miss",
151 "data protection/rights/alignment",
152 "data break",
153 "TLB dirty",
154 "page reference",
155 "assist emulation",
156 "higher-priv transfer",
157 "lower-priv transfer",
158 "taken branch",
159 "data access rights",
160 "data protection",
161 "unaligned data ref",
162 };
163 int trap_types = __arraycount(trap_type);
164
165 uint8_t fpopmap[] = {
166 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
167 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00,
171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174 };
175
176 void pmap_hptdump(void);
177 void syscall(struct trapframe *, int *);
178
179 #if defined(DEBUG)
180 struct trapframe *sanity_frame;
181 struct lwp *sanity_lwp;
182 const char *sanity_string;
183 void frame_sanity_check(const char *, int, int, struct trapframe *,
184 struct lwp *);
185 #endif
186
187
188 #ifdef USERTRACE
189 /*
190 * USERTRACE is a crude facility that traces the PC of a single user process.
191 * This tracing is normally activated by the dispatching of a certain syscall
192 * with certain arguments - see the activation code in syscall().
193 */
194 static void user_backtrace(struct trapframe *, struct lwp *, int);
195 static void user_backtrace_raw(u_int, u_int);
196
197 u_int rctr_next_iioq;
198 #endif
199
200 static inline void
201 userret(struct lwp *l, register_t pc, u_quad_t oticks)
202 {
203 struct proc *p = l->l_proc;
204
205 if (l->l_md.md_astpending) {
206 l->l_md.md_astpending = 0;
207 //curcpu()->ci_data.cpu_nast++;
208
209 if (curcpu()->ci_want_resched)
210 preempt();
211 }
212
213 mi_userret(l);
214
215 /*
216 * If profiling, charge recent system time to the trapped pc.
217 */
218 if (p->p_stflag & PST_PROFIL) {
219 extern int psratio;
220
221 addupc_task(l, pc, (int)(p->p_sticks - oticks) * psratio);
222 }
223 }
224
225 /*
226 * This handles some messy kernel debugger details.
227 * It dispatches into either kgdb or DDB, and knows
228 * about some special things to do, like skipping over
229 * break instructions and how to really set up for
230 * a single-step.
231 */
232 #if defined(KGDB) || defined(DDB)
233 static int
234 trap_kdebug(int type, int code, struct trapframe *frame)
235 {
236 int handled;
237 u_int tf_iioq_head_old;
238 u_int tf_iioq_tail_old;
239
240 for (;;) {
241
242 /* This trap has not been handled. */
243 handled = 0;
244
245 /* Remember the instruction offset queue. */
246 tf_iioq_head_old = frame->tf_iioq_head;
247 tf_iioq_tail_old = frame->tf_iioq_tail;
248
249 #ifdef KGDB
250 /* Let KGDB handle it (if connected) */
251 if (!handled)
252 handled = kgdb_trap(type, frame);
253 #endif
254 #ifdef DDB
255 /* Let DDB handle it. */
256 if (!handled)
257 handled = kdb_trap(type, code, frame);
258 #endif
259
260 /* If this trap wasn't handled, return now. */
261 if (!handled)
262 return(0);
263
264 /*
265 * If the instruction offset queue head changed, but the offset
266 * queue tail didn't, assume that the user wants to jump to the
267 * head offset, and adjust the tail accordingly. This should
268 * fix the kgdb `jump' command, and can help DDB users who `set'
269 * the offset head but forget the tail.
270 */
271 if (frame->tf_iioq_head != tf_iioq_head_old &&
272 frame->tf_iioq_tail == tf_iioq_tail_old)
273 frame->tf_iioq_tail = frame->tf_iioq_head + 4;
274
275 /*
276 * This is some single-stepping support. If we're trying to
277 * step through a nullified instruction, just advance by hand
278 * and trap again. Otherwise, load the recovery counter with
279 * zero.
280 */
281 if (frame->tf_ipsw & PSW_R) {
282 #ifdef TRAPDEBUG
283 printf("(single stepping at head 0x%x tail 0x%x)\n",
284 frame->tf_iioq_head, frame->tf_iioq_tail);
285 #endif
286 if (frame->tf_ipsw & PSW_N) {
287 #ifdef TRAPDEBUG
288 printf("(single stepping past nullified)\n");
289 #endif
290
291 /* Advance the program counter. */
292 frame->tf_iioq_head = frame->tf_iioq_tail;
293 frame->tf_iioq_tail = frame->tf_iioq_head + 4;
294
295 /* Clear flags. */
296 frame->tf_ipsw &= ~(PSW_N|PSW_X|PSW_Y|PSW_Z|PSW_B|PSW_T|PSW_H|PSW_L);
297
298 /* Simulate another trap. */
299 type = T_RECOVERY;
300 continue;
301 }
302 frame->tf_rctr = 0;
303 }
304
305 /* We handled this trap. */
306 return (1);
307 }
308 /* NOTREACHED */
309 }
310 #else /* !KGDB && !DDB */
311 #define trap_kdebug(t, c, f) (0)
312 #endif /* !KGDB && !DDB */
313
314 #if defined(DEBUG) || defined(USERTRACE)
315 /*
316 * These functions give a crude usermode backtrace. They really only work when
317 * code has been compiled without optimization, as they assume a certain func-
318 * tion prologue sets up a frame pointer and stores the return pointer and arg-
319 * uments in it.
320 */
321 static void
322 user_backtrace_raw(u_int pc, u_int fp)
323 {
324 int frame_number;
325 int arg_number;
326 uint32_t val;
327
328 for (frame_number = 0;
329 frame_number < 100 && pc > HPPA_PC_PRIV_MASK && fp;
330 frame_number++) {
331
332 printf("%3d: pc=%08x%s fp=0x%08x", frame_number,
333 pc & ~HPPA_PC_PRIV_MASK, USERMODE(pc) ? " " : "**", fp);
334 for (arg_number = 0; arg_number < 4; arg_number++) {
335 if (ufetch_32(HPPA_FRAME_CARG(arg_number, fp),
336 &val) == 0) {
337 printf(" arg%d=0x%08x", arg_number, val);
338 } else {
339 printf(" arg%d=<bad address>", arg_number);
340 }
341 }
342 printf("\n");
343 if (ufetch_int((((uint32_t *) fp) - 5), &pc) != 0) {
344 printf(" ufetch for pc failed\n");
345 break;
346 }
347 if (ufetch_int((((uint32_t *) fp) + 0), &fp) != 0) {
348 printf(" ufetch for fp failed\n");
349 break;
350 }
351 }
352 printf(" backtrace stopped with pc %08x fp 0x%08x\n", pc, fp);
353 }
354
355 static void
356 user_backtrace(struct trapframe *tf, struct lwp *l, int type)
357 {
358 struct proc *p = l->l_proc;
359 u_int pc, fp, inst;
360
361 /*
362 * Display any trap type that we have.
363 */
364 if (type >= 0)
365 printf("pid %d (%s) trap #%d\n",
366 p->p_pid, p->p_comm, type & ~T_USER);
367
368 /*
369 * Assuming that the frame pointer in r3 is valid,
370 * dump out a stack trace.
371 */
372 fp = tf->tf_r3;
373 printf("pid %d (%s) backtrace, starting with fp 0x%08x\n",
374 p->p_pid, p->p_comm, fp);
375 user_backtrace_raw(tf->tf_iioq_head, fp);
376
377 /*
378 * In case the frame pointer in r3 is not valid, assuming the stack
379 * pointer is valid and the faulting function is a non-leaf, if we can
380 * find its prologue we can recover its frame pointer.
381 */
382 pc = tf->tf_iioq_head;
383 fp = tf->tf_sp - HPPA_FRAME_SIZE;
384 printf("pid %d (%s) backtrace, starting with sp 0x%08x pc 0x%08x\n",
385 p->p_pid, p->p_comm, tf->tf_sp, pc);
386 for (pc &= ~HPPA_PC_PRIV_MASK; pc > 0; pc -= sizeof(inst)) {
387 if (ufetch_int((u_int *) pc, &inst) != 0) {
388 printf(" ufetch for inst at pc %08x failed\n", pc);
389 break;
390 }
391 /* Check for the prologue instruction that sets sp. */
392 if (STWM_R1_D_SR0_SP(inst)) {
393 fp = tf->tf_sp - STWM_R1_D_SR0_SP(inst);
394 printf(" sp from fp at pc %08x: %08x\n", pc, inst);
395 break;
396 }
397 }
398 user_backtrace_raw(tf->tf_iioq_head, fp);
399 }
400 #endif /* DEBUG || USERTRACE */
401
402 #ifdef DEBUG
403 /*
404 * This sanity-checks a trapframe. It is full of various assumptions about
405 * what a healthy CPU state should be, with some documented elsewhere, some not.
406 */
407 void
408 frame_sanity_check(const char *func, int line, int type, struct trapframe *tf,
409 struct lwp *l)
410 {
411 #if 0
412 extern int kernel_text;
413 extern int etext;
414 #endif
415 struct cpu_info *ci = curcpu();
416
417 #define SANITY(e) \
418 do { \
419 if (sanity_frame == NULL && !(e)) { \
420 sanity_frame = tf; \
421 sanity_lwp = l; \
422 sanity_string = #e; \
423 } \
424 } while (/* CONSTCOND */ 0)
425
426 KASSERT(l != NULL);
427 SANITY((tf->tf_ipsw & ci->ci_psw) == ci->ci_psw);
428 SANITY((ci->ci_psw & PSW_I) == 0 || tf->tf_eiem != 0);
429 if (tf->tf_iisq_head == HPPA_SID_KERNEL) {
430 vaddr_t minsp, maxsp, uv;
431
432 uv = uvm_lwp_getuarea(l);
433
434 /*
435 * If the trap happened in the gateway page, we take the easy
436 * way out and assume that the trapframe is okay.
437 */
438 if ((tf->tf_iioq_head & ~PAGE_MASK) == SYSCALLGATE)
439 goto out;
440
441 SANITY(!USERMODE(tf->tf_iioq_head));
442 SANITY(!USERMODE(tf->tf_iioq_tail));
443
444 /*
445 * Don't check the instruction queues or stack on interrupts
446 * as we could be be in the sti code (outside normal kernel
447 * text) or switching LWPs (curlwp and sp are not in sync)
448 */
449 if ((type & ~T_USER) == T_INTERRUPT)
450 goto out;
451 #if 0
452 SANITY(tf->tf_iioq_head >= (u_int) &kernel_text);
453 SANITY(tf->tf_iioq_head < (u_int) &etext);
454 SANITY(tf->tf_iioq_tail >= (u_int) &kernel_text);
455 SANITY(tf->tf_iioq_tail < (u_int) &etext);
456 #endif
457
458 maxsp = uv + USPACE + PAGE_SIZE;
459 minsp = uv + PAGE_SIZE;
460
461 SANITY(tf->tf_sp >= minsp && tf->tf_sp < maxsp);
462 } else {
463 struct pcb *pcb = lwp_getpcb(l);
464
465 SANITY(USERMODE(tf->tf_iioq_head));
466 SANITY(USERMODE(tf->tf_iioq_tail));
467 SANITY(tf->tf_cr30 == (u_int)pcb->pcb_fpregs);
468 }
469 #undef SANITY
470 out:
471 if (sanity_frame == tf) {
472 printf("insanity: '%s' at %s:%d type 0x%x tf %p lwp %p "
473 "sp 0x%x pc 0x%x\n",
474 sanity_string, func, line, type, sanity_frame, sanity_lwp,
475 tf->tf_sp, tf->tf_iioq_head);
476 (void) trap_kdebug(T_IBREAK, 0, tf);
477 sanity_frame = NULL;
478 sanity_lwp = NULL;
479 }
480 }
481 #endif /* DEBUG */
482
483
484 #define __PABITS(x, y) __BITS(31 - (x), 31 - (y))
485 #define __PABIT(x) __BIT(31 - (x))
486
487 #define LPA_MASK \
488 ( __PABITS(0, 5) | \
489 __PABITS(18, 25))
490 #define LPA \
491 (__SHIFTIN(1, __PABITS(0, 5)) | \
492 __SHIFTIN(0x4d, __PABITS(18, 25)))
493
494
495 #define PROBE_ENCS (0x46 | 0xc6 | 0x47 | 0xc7)
496 #define PROBE_PL __PABITS(11, 15)
497 #define PROBE_IMMED __PABIT(18)
498 #define PROBE_RW __PABIT(25)
499
500 #define PROBE_MASK \
501 (( __PABITS(0, 5) | \
502 __PABITS(18, 25) | \
503 __PABIT(26)) ^ \
504 (PROBE_IMMED | PROBE_RW))
505
506 #define PROBE \
507 ((__SHIFTIN(1, __PABITS(0, 5)) | \
508 __SHIFTIN(PROBE_ENCS, __PABITS(18, 25)) | \
509 __SHIFTIN(0, __PABIT(26))) ^ \
510 (PROBE_IMMED | PROBE_RW))
511
512 #define PLMASK __BITS(1, 0)
513
514
515 /* for hppa64 */
516 CTASSERT(sizeof(register_t) == sizeof(u_int));
517 size_t hppa_regmap[] = {
518 0, /* r0 is special case */
519 offsetof(struct trapframe, tf_r1 ) / sizeof(register_t),
520 offsetof(struct trapframe, tf_rp ) / sizeof(register_t),
521 offsetof(struct trapframe, tf_r3 ) / sizeof(register_t),
522 offsetof(struct trapframe, tf_r4 ) / sizeof(register_t),
523 offsetof(struct trapframe, tf_r5 ) / sizeof(register_t),
524 offsetof(struct trapframe, tf_r6 ) / sizeof(register_t),
525 offsetof(struct trapframe, tf_r7 ) / sizeof(register_t),
526 offsetof(struct trapframe, tf_r8 ) / sizeof(register_t),
527 offsetof(struct trapframe, tf_r9 ) / sizeof(register_t),
528 offsetof(struct trapframe, tf_r10 ) / sizeof(register_t),
529 offsetof(struct trapframe, tf_r11 ) / sizeof(register_t),
530 offsetof(struct trapframe, tf_r12 ) / sizeof(register_t),
531 offsetof(struct trapframe, tf_r13 ) / sizeof(register_t),
532 offsetof(struct trapframe, tf_r14 ) / sizeof(register_t),
533 offsetof(struct trapframe, tf_r15 ) / sizeof(register_t),
534 offsetof(struct trapframe, tf_r16 ) / sizeof(register_t),
535 offsetof(struct trapframe, tf_r17 ) / sizeof(register_t),
536 offsetof(struct trapframe, tf_r18 ) / sizeof(register_t),
537 offsetof(struct trapframe, tf_t4 ) / sizeof(register_t),
538 offsetof(struct trapframe, tf_t3 ) / sizeof(register_t),
539 offsetof(struct trapframe, tf_t2 ) / sizeof(register_t),
540 offsetof(struct trapframe, tf_t1 ) / sizeof(register_t),
541 offsetof(struct trapframe, tf_arg3) / sizeof(register_t),
542 offsetof(struct trapframe, tf_arg2) / sizeof(register_t),
543 offsetof(struct trapframe, tf_arg1) / sizeof(register_t),
544 offsetof(struct trapframe, tf_arg0) / sizeof(register_t),
545 offsetof(struct trapframe, tf_dp ) / sizeof(register_t),
546 offsetof(struct trapframe, tf_ret0) / sizeof(register_t),
547 offsetof(struct trapframe, tf_ret1) / sizeof(register_t),
548 offsetof(struct trapframe, tf_sp ) / sizeof(register_t),
549 offsetof(struct trapframe, tf_r31 ) / sizeof(register_t),
550 };
551
552
553 static inline register_t
554 tf_getregno(struct trapframe *tf, u_int regno)
555 {
556 register_t *tf_reg = (register_t *)tf;
557 if (regno == 0)
558 return 0;
559 else
560 return tf_reg[hppa_regmap[regno]];
561 }
562
563 static inline void
564 tf_setregno(struct trapframe *tf, u_int regno, register_t val)
565 {
566 register_t *tf_reg = (register_t *)tf;
567 if (regno == 0)
568 return;
569 else
570 tf_reg[hppa_regmap[regno]] = val;
571 }
572
573 void
574 trap(int type, struct trapframe *frame)
575 {
576 struct lwp *l;
577 struct proc *p;
578 struct pcb *pcb;
579 vaddr_t va;
580 struct vm_map *map;
581 struct vmspace *vm;
582 vm_prot_t vftype;
583 pa_space_t space;
584 ksiginfo_t ksi;
585 u_int opcode, onfault;
586 int ret;
587 const char *tts = "reserved";
588 int trapnum;
589 #ifdef DIAGNOSTIC
590 extern int emergency_stack_start, emergency_stack_end;
591 struct cpu_info *ci = curcpu();
592 int oldcpl = ci->ci_cpl;
593 #endif
594
595 trapnum = type & ~T_USER;
596 opcode = frame->tf_iir;
597
598 if (trapnum <= T_EXCEPTION || trapnum == T_HIGHERPL ||
599 trapnum == T_LOWERPL || trapnum == T_TAKENBR ||
600 trapnum == T_IDEBUG || trapnum == T_PERFMON) {
601 va = frame->tf_iioq_head;
602 space = frame->tf_iisq_head;
603 vftype = VM_PROT_EXECUTE;
604 } else {
605 va = frame->tf_ior;
606 space = frame->tf_isr;
607 vftype = inst_store(opcode) ? VM_PROT_WRITE : VM_PROT_READ;
608 }
609
610 KASSERT(curlwp != NULL);
611 l = curlwp;
612 p = l->l_proc;
613 if ((type & T_USER) != 0)
614 LWP_CACHE_CREDS(l, p);
615
616 #ifdef DIAGNOSTIC
617 /*
618 * If we are on the emergency stack, then we either got
619 * a fault on the kernel stack, or we're just handling
620 * a trap for the machine check handler (which also
621 * runs on the emergency stack).
622 *
623 * We *very crudely* differentiate between the two cases
624 * by checking the faulting instruction: if it is the
625 * function prologue instruction that stores the old
626 * frame pointer and updates the stack pointer, we assume
627 * that we faulted on the kernel stack.
628 *
629 * In this case, not completing that instruction will
630 * probably confuse backtraces in kgdb/ddb. Completing
631 * it would be difficult, because we already faulted on
632 * that part of the stack, so instead we fix up the
633 * frame as if the function called has just returned.
634 * This has peculiar knowledge about what values are in
635 * what registers during the "normal gcc -g" prologue.
636 */
637 if (&type >= &emergency_stack_start &&
638 &type < &emergency_stack_end &&
639 type != T_IBREAK && STWM_R1_D_SR0_SP(opcode)) {
640 /* Restore the caller's frame pointer. */
641 frame->tf_r3 = frame->tf_r1;
642 /* Restore the caller's instruction offsets. */
643 frame->tf_iioq_head = frame->tf_rp;
644 frame->tf_iioq_tail = frame->tf_iioq_head + 4;
645 goto dead_end;
646 }
647 #endif /* DIAGNOSTIC */
648
649 #ifdef DEBUG
650 frame_sanity_check(__func__, __LINE__, type, frame, l);
651 #endif /* DEBUG */
652
653 if (frame->tf_flags & TFF_LAST)
654 l->l_md.md_regs = frame;
655
656 if (trapnum <= trap_types)
657 tts = trap_type[trapnum];
658
659 #ifdef TRAPDEBUG
660 if (trapnum != T_INTERRUPT && trapnum != T_IBREAK)
661 printf("trap: %d, %s for %x:%lx at %x:%x, fp=%p, rp=%x\n",
662 type, tts, space, va, frame->tf_iisq_head,
663 frame->tf_iioq_head, frame, frame->tf_rp);
664 else if (trapnum == T_IBREAK)
665 printf("trap: break instruction %x:%x at %x:%x, fp=%p\n",
666 break5(opcode), break13(opcode),
667 frame->tf_iisq_head, frame->tf_iioq_head, frame);
668
669 {
670 extern int etext;
671 if (frame < (struct trapframe *)&etext) {
672 printf("trap: bogus frame ptr %p\n", frame);
673 goto dead_end;
674 }
675 }
676 #endif
677
678 pcb = lwp_getpcb(l);
679
680 /* If this is a trap, not an interrupt, reenable interrupts. */
681 if (trapnum != T_INTERRUPT) {
682 curcpu()->ci_data.cpu_ntrap++;
683 mtctl(frame->tf_eiem, CR_EIEM);
684 }
685
686 const bool user = (type & T_USER) != 0;
687 switch (type) {
688 case T_NONEXIST:
689 case T_NONEXIST|T_USER:
690 #if !defined(DDB) && !defined(KGDB)
691 /* we've got screwed up by the central scrutinizer */
692 panic ("trap: elvis has just left the building!");
693 break;
694 #else
695 goto dead_end;
696 #endif
697 case T_RECOVERY|T_USER:
698 #ifdef USERTRACE
699 for (;;) {
700 if (frame->tf_iioq_head != rctr_next_iioq)
701 printf("-%08x\nr %08x",
702 rctr_next_iioq - 4,
703 frame->tf_iioq_head);
704 rctr_next_iioq = frame->tf_iioq_head + 4;
705 if (frame->tf_ipsw & PSW_N) {
706 /* Advance the program counter. */
707 frame->tf_iioq_head = frame->tf_iioq_tail;
708 frame->tf_iioq_tail = frame->tf_iioq_head + 4;
709 /* Clear flags. */
710 frame->tf_ipsw &= ~(PSW_N|PSW_X|PSW_Y|PSW_Z|PSW_B|PSW_T|PSW_H|PSW_L);
711 /* Simulate another trap. */
712 continue;
713 }
714 break;
715 }
716 frame->tf_rctr = 0;
717 break;
718 #endif /* USERTRACE */
719 case T_RECOVERY:
720 #if !defined(DDB) && !defined(KGDB)
721 /* XXX will implement later */
722 printf ("trap: handicapped");
723 break;
724 #else
725 goto dead_end;
726 #endif
727
728 case T_EMULATION | T_USER:
729 hppa_fpu_emulate(frame, l, opcode);
730 break;
731
732 case T_DATALIGN:
733 onfault = pcb->pcb_onfault;
734 if (onfault) {
735 ret = EFAULT;
736 do_onfault:
737 frame->tf_iioq_head = onfault;
738 frame->tf_iioq_tail = frame->tf_iioq_head + 4;
739 frame->tf_ret0 = ret;
740 break;
741 }
742 /*FALLTHROUGH*/
743
744 #ifdef DIAGNOSTIC
745 /* these just can't happen ever */
746 case T_PRIV_OP:
747 case T_PRIV_REG:
748 /* these just can't make it to the trap() ever */
749 case T_HPMC:
750 case T_HPMC | T_USER:
751 case T_EMULATION:
752 case T_EXCEPTION:
753 #endif
754 case T_IBREAK:
755 case T_DBREAK:
756 dead_end:
757 if (type & T_USER) {
758 #ifdef DEBUG
759 user_backtrace(frame, l, type);
760 #endif
761 KSI_INIT_TRAP(&ksi);
762 ksi.ksi_signo = SIGILL;
763 ksi.ksi_code = ILL_ILLTRP;
764 ksi.ksi_trap = type;
765 ksi.ksi_addr = (void *)frame->tf_iioq_head;
766 trapsignal(l, &ksi);
767 break;
768 }
769 if (trap_kdebug(type, va, frame))
770 return;
771 else if (type == T_DATALIGN)
772 panic ("trap: %s at 0x%x", tts, (u_int) va);
773 else
774 panic ("trap: no debugger for \"%s\" (%d)", tts, type);
775 break;
776
777 case T_IBREAK | T_USER:
778 case T_DBREAK | T_USER:
779 KSI_INIT_TRAP(&ksi);
780 ksi.ksi_signo = SIGTRAP;
781 ksi.ksi_code = TRAP_BRKPT;
782 ksi.ksi_trap = trapnum;
783 ksi.ksi_addr = (void *)(frame->tf_iioq_head & ~HPPA_PC_PRIV_MASK);
784 #ifdef PTRACE
785 ss_clear_breakpoints(l);
786 if (opcode == SSBREAKPOINT)
787 ksi.ksi_code = TRAP_TRACE;
788 #endif
789 /* pass to user debugger */
790 trapsignal(l, &ksi);
791 break;
792
793 #ifdef PTRACE
794 case T_TAKENBR | T_USER:
795 ss_clear_breakpoints(l);
796
797 KSI_INIT_TRAP(&ksi);
798 ksi.ksi_signo = SIGTRAP;
799 ksi.ksi_code = TRAP_TRACE;
800 ksi.ksi_trap = trapnum;
801 ksi.ksi_addr = (void *)(frame->tf_iioq_head & ~HPPA_PC_PRIV_MASK);
802
803 /* pass to user debugger */
804 trapsignal(l, &ksi);
805 break;
806 #endif
807
808 case T_EXCEPTION | T_USER: { /* co-proc assist trap */
809 uint64_t *fpp;
810 uint32_t *pex, ex, inst;
811 int i;
812
813 hppa_fpu_flush(l);
814 fpp = (uint64_t *)pcb->pcb_fpregs;
815
816 /* skip the status register */
817 pex = (uint32_t *)&fpp[0];
818 pex++;
819
820 /* loop through the exception registers */
821 for (i = 1; i < 8 && !*pex; i++, pex++)
822 ;
823 KASSERT(i < 8);
824 ex = *pex;
825 *pex = 0;
826
827 /* reset the trap flag, as if there was none */
828 fpp[0] &= ~(((uint64_t)HPPA_FPU_T) << 32);
829
830 /* emulate the instruction */
831 inst = ((uint32_t)fpopmap[ex >> 26] << 26) | (ex & 0x03ffffff);
832 hppa_fpu_emulate(frame, l, inst);
833 }
834 break;
835
836 case T_OVERFLOW | T_USER:
837 KSI_INIT_TRAP(&ksi);
838 ksi.ksi_signo = SIGFPE;
839 ksi.ksi_code = SI_NOINFO;
840 ksi.ksi_trap = type;
841 ksi.ksi_addr = (void *)va;
842 trapsignal(l, &ksi);
843 break;
844
845 case T_CONDITION | T_USER:
846 KSI_INIT_TRAP(&ksi);
847 ksi.ksi_signo = SIGFPE;
848 ksi.ksi_code = FPE_INTDIV;
849 ksi.ksi_trap = type;
850 ksi.ksi_addr = (void *)va;
851 trapsignal(l, &ksi);
852 break;
853
854 case T_ILLEGAL | T_USER:
855 #ifdef DEBUG
856 user_backtrace(frame, l, type);
857 #endif
858 KSI_INIT_TRAP(&ksi);
859 ksi.ksi_signo = SIGILL;
860 ksi.ksi_code = ILL_ILLOPC;
861 ksi.ksi_trap = type;
862 ksi.ksi_addr = (void *)va;
863 trapsignal(l, &ksi);
864 break;
865
866 case T_PRIV_OP | T_USER:
867 #ifdef DEBUG
868 user_backtrace(frame, l, type);
869 #endif
870 KSI_INIT_TRAP(&ksi);
871 ksi.ksi_signo = SIGILL;
872 ksi.ksi_code = ILL_PRVOPC;
873 ksi.ksi_trap = type;
874 ksi.ksi_addr = (void *)va;
875 trapsignal(l, &ksi);
876 break;
877
878 case T_PRIV_REG | T_USER:
879 #ifdef DEBUG
880 user_backtrace(frame, l, type);
881 #endif
882 KSI_INIT_TRAP(&ksi);
883 ksi.ksi_signo = SIGILL;
884 ksi.ksi_code = ILL_PRVREG;
885 ksi.ksi_trap = type;
886 ksi.ksi_addr = (void *)va;
887 trapsignal(l, &ksi);
888 break;
889
890 /* these should never got here */
891 case T_HIGHERPL | T_USER:
892 case T_LOWERPL | T_USER:
893 KSI_INIT_TRAP(&ksi);
894 ksi.ksi_signo = SIGSEGV;
895 ksi.ksi_code = SEGV_ACCERR;
896 ksi.ksi_trap = type;
897 ksi.ksi_addr = (void *)va;
898 trapsignal(l, &ksi);
899 break;
900
901 case T_IPROT | T_USER:
902 case T_DPROT | T_USER:
903 KSI_INIT_TRAP(&ksi);
904 ksi.ksi_signo = SIGSEGV;
905 ksi.ksi_code = SEGV_ACCERR;
906 ksi.ksi_trap = type;
907 ksi.ksi_addr = (void *)va;
908 trapsignal(l, &ksi);
909 break;
910
911 case T_ITLBMISSNA: case T_USER | T_ITLBMISSNA:
912 case T_DTLBMISSNA: case T_USER | T_DTLBMISSNA:
913 vm = p->p_vmspace;
914
915 if (!vm) {
916 #ifdef TRAPDEBUG
917 printf("trap: no vm, p=%p\n", p);
918 #endif
919 goto dead_end;
920 }
921
922 /*
923 * it could be a kernel map for exec_map faults
924 */
925 if (!user && space == HPPA_SID_KERNEL)
926 map = kernel_map;
927 else {
928 map = &vm->vm_map;
929 }
930
931 va = trunc_page(va);
932
933 if ((opcode & LPA_MASK) == LPA) {
934 /* lpa failure case */
935 const u_int regno =
936 __SHIFTOUT(opcode, __PABITS(27, 31));
937 tf_setregno(frame, regno, 0);
938 frame->tf_ipsw |= PSW_N;
939 } else if ((opcode & PROBE_MASK) == PROBE) {
940 u_int pl;
941 if ((opcode & PROBE_IMMED) != 0) {
942 pl = __SHIFTOUT(opcode, PROBE_PL) & PLMASK;
943 } else {
944 const u_int plreg =
945 __SHIFTOUT(opcode, PROBE_PL);
946 pl = tf_getregno(frame, plreg) & PLMASK;
947 }
948
949 bool ok = true;
950 if ((user && space == HPPA_SID_KERNEL) ||
951 (frame->tf_iioq_head & HPPA_PC_PRIV_MASK) != pl ||
952 (user && va >= VM_MAXUSER_ADDRESS)) {
953 ok = false;
954 } else {
955 /* Never call uvm_fault in interrupt context. */
956 KASSERT(curcpu()->ci_intr_depth == 0);
957
958 const bool read =
959 __SHIFTOUT(opcode, PROBE_RW) == 0;
960 onfault = pcb->pcb_onfault;
961 pcb->pcb_onfault = 0;
962 ret = uvm_fault(map, va, read ?
963 VM_PROT_READ : VM_PROT_WRITE);
964 pcb->pcb_onfault = onfault;
965
966 if (ret)
967 ok = false;
968 }
969 if (!ok) {
970 const u_int regno =
971 __SHIFTOUT(opcode, __PABITS(27, 31));
972 tf_setregno(frame, regno, 0);
973 frame->tf_ipsw |= PSW_N;
974 }
975 }
976 break;
977
978 case T_DATACC: case T_USER | T_DATACC:
979 case T_ITLBMISS: case T_USER | T_ITLBMISS:
980 case T_DTLBMISS: case T_USER | T_DTLBMISS:
981 case T_TLB_DIRTY: case T_USER | T_TLB_DIRTY:
982 vm = p->p_vmspace;
983
984 if (!vm) {
985 #ifdef TRAPDEBUG
986 printf("trap: no vm, p=%p\n", p);
987 #endif
988 goto dead_end;
989 }
990
991 /*
992 * it could be a kernel map for exec_map faults
993 */
994 if (!(type & T_USER) && space == HPPA_SID_KERNEL)
995 map = kernel_map;
996 else {
997 map = &vm->vm_map;
998 }
999
1000 va = trunc_page(va);
1001
1002 if (map->pmap->pm_space != space) {
1003 #ifdef TRAPDEBUG
1004 printf("trap: space mismatch %d != %d\n",
1005 space, map->pmap->pm_space);
1006 #endif
1007 /* actually dump the user, crap the kernel */
1008 goto dead_end;
1009 }
1010
1011 /* Never call uvm_fault in interrupt context. */
1012 KASSERT(curcpu()->ci_intr_depth == 0);
1013
1014 onfault = pcb->pcb_onfault;
1015 pcb->pcb_onfault = 0;
1016 ret = uvm_fault(map, va, vftype);
1017 pcb->pcb_onfault = onfault;
1018
1019 #ifdef TRAPDEBUG
1020 printf("uvm_fault(%p, %x, %d)=%d\n",
1021 map, (u_int)va, vftype, ret);
1022 #endif
1023
1024 /*
1025 * If this was a stack access we keep track of the maximum
1026 * accessed stack size. Also, if uvm_fault gets a protection
1027 * failure it is due to accessing the stack region outside
1028 * the current limit and we need to reflect that as an access
1029 * error.
1030 */
1031 if (map != kernel_map && va >= (vaddr_t)vm->vm_minsaddr) {
1032 if (ret == 0)
1033 uvm_grow(l->l_proc, va);
1034 else if (ret == EACCES)
1035 ret = EFAULT;
1036 }
1037
1038 if (ret != 0) {
1039 if (type & T_USER) {
1040 #ifdef DEBUG
1041 user_backtrace(frame, l, type);
1042 #endif
1043 KSI_INIT_TRAP(&ksi);
1044 switch (ret) {
1045 case EACCES:
1046 ksi.ksi_signo = SIGSEGV;
1047 ksi.ksi_code = SEGV_ACCERR;
1048 break;
1049 case ENOMEM:
1050 ksi.ksi_signo = SIGKILL;
1051 printf("UVM: pid %d (%s), uid %d "
1052 "killed: out of swap\n",
1053 p->p_pid, p->p_comm,
1054 l->l_cred ?
1055 kauth_cred_geteuid(l->l_cred)
1056 : -1);
1057 break;
1058 case EINVAL:
1059 ksi.ksi_signo = SIGBUS;
1060 ksi.ksi_code = BUS_ADRERR;
1061 break;
1062 default:
1063 ksi.ksi_signo = SIGSEGV;
1064 ksi.ksi_code = SEGV_MAPERR;
1065 break;
1066 }
1067 ksi.ksi_trap = type;
1068 ksi.ksi_addr = (void *)va;
1069 trapsignal(l, &ksi);
1070 } else {
1071 if (onfault) {
1072 goto do_onfault;
1073 }
1074 panic("trap: uvm_fault(%p, %lx, %d): %d",
1075 map, va, vftype, ret);
1076 }
1077 }
1078 break;
1079
1080 case T_DATALIGN | T_USER:
1081 #ifdef DEBUG
1082 user_backtrace(frame, l, type);
1083 #endif
1084 KSI_INIT_TRAP(&ksi);
1085 ksi.ksi_signo = SIGBUS;
1086 ksi.ksi_code = BUS_ADRALN;
1087 ksi.ksi_trap = type;
1088 ksi.ksi_addr = (void *)va;
1089 trapsignal(l, &ksi);
1090 break;
1091
1092 case T_INTERRUPT:
1093 case T_INTERRUPT|T_USER:
1094 hppa_intr(frame);
1095 mtctl(frame->tf_eiem, CR_EIEM);
1096 break;
1097
1098 case T_LOWERPL:
1099 case T_DPROT:
1100 case T_IPROT:
1101 case T_OVERFLOW:
1102 case T_CONDITION:
1103 case T_ILLEGAL:
1104 case T_HIGHERPL:
1105 case T_TAKENBR:
1106 case T_POWERFAIL:
1107 case T_LPMC:
1108 case T_PAGEREF:
1109 case T_DATAPID: case T_DATAPID | T_USER:
1110 if (0 /* T-chip */) {
1111 break;
1112 }
1113 /* FALLTHROUGH to unimplemented */
1114 default:
1115 panic ("trap: unimplemented \'%s\' (%d)", tts, type);
1116 }
1117
1118 #ifdef DIAGNOSTIC
1119 if (ci->ci_cpl != oldcpl)
1120 printf("WARNING: SPL (%d) NOT LOWERED ON TRAP (%d) EXIT\n",
1121 ci->ci_cpl, trapnum);
1122 #endif
1123
1124 if (type & T_USER)
1125 userret(l, l->l_md.md_regs->tf_iioq_head, 0);
1126
1127 #ifdef DEBUG
1128 frame_sanity_check(__func__, __LINE__, type, frame, l);
1129 if (frame->tf_flags & TFF_LAST && (curlwp->l_flag & LW_IDLE) == 0)
1130 frame_sanity_check(__func__, __LINE__, type,
1131 curlwp->l_md.md_regs, curlwp);
1132 #endif /* DEBUG */
1133 }
1134
1135 void
1136 md_child_return(struct lwp *l)
1137 {
1138 /*
1139 * Return values in the frame set by cpu_lwp_fork().
1140 */
1141
1142 userret(l, l->l_md.md_regs->tf_iioq_head, 0);
1143 #ifdef DEBUG
1144 frame_sanity_check(__func__, __LINE__, 0, l->l_md.md_regs, l);
1145 #endif /* DEBUG */
1146 }
1147
1148 /*
1149 * Process the tail end of a posix_spawn() for the child.
1150 */
1151 void
1152 cpu_spawn_return(struct lwp *l)
1153 {
1154
1155 userret(l, l->l_md.md_regs->tf_iioq_head, 0);
1156 #ifdef DEBUG
1157 frame_sanity_check(__func__, __LINE__, 0, l->l_md.md_regs, l);
1158 #endif /* DEBUG */
1159 }
1160
1161 #ifdef PTRACE
1162
1163 #include <sys/ptrace.h>
1164
1165 int
1166 ss_get_value(struct lwp *l, vaddr_t addr, u_int *value)
1167 {
1168 struct uio uio;
1169 struct iovec iov;
1170
1171 iov.iov_base = (void *)value;
1172 iov.iov_len = sizeof(u_int);
1173 uio.uio_iov = &iov;
1174 uio.uio_iovcnt = 1;
1175 uio.uio_offset = (off_t)addr;
1176 uio.uio_resid = sizeof(u_int);
1177 uio.uio_rw = UIO_READ;
1178 UIO_SETUP_SYSSPACE(&uio);
1179
1180 return (process_domem(curlwp, l, &uio));
1181 }
1182
1183 int
1184 ss_put_value(struct lwp *l, vaddr_t addr, u_int value)
1185 {
1186 struct uio uio;
1187 struct iovec iov;
1188
1189 iov.iov_base = (void *)&value;
1190 iov.iov_len = sizeof(u_int);
1191 uio.uio_iov = &iov;
1192 uio.uio_iovcnt = 1;
1193 uio.uio_offset = (off_t)addr;
1194 uio.uio_resid = sizeof(u_int);
1195 uio.uio_rw = UIO_WRITE;
1196 UIO_SETUP_SYSSPACE(&uio);
1197
1198 return (process_domem(curlwp, l, &uio));
1199 }
1200
1201 void
1202 ss_clear_breakpoints(struct lwp *l)
1203 {
1204 /* Restore origional instructions. */
1205 if (l->l_md.md_bpva != 0) {
1206 ss_put_value(l, l->l_md.md_bpva, l->l_md.md_bpsave[0]);
1207 ss_put_value(l, l->l_md.md_bpva + 4, l->l_md.md_bpsave[1]);
1208 l->l_md.md_bpva = 0;
1209 }
1210 }
1211
1212
1213 int
1214 process_sstep(struct lwp *l, int sstep)
1215 {
1216 struct trapframe *tf = l->l_md.md_regs;
1217 int error;
1218
1219 ss_clear_breakpoints(l);
1220
1221 /* We're continuing... */
1222 if (sstep == 0) {
1223 tf->tf_ipsw &= ~PSW_T;
1224 return 0;
1225 }
1226
1227 /*
1228 * Don't touch the syscall gateway page. Instead, insert a
1229 * breakpoint where we're supposed to return.
1230 */
1231 if ((tf->tf_iioq_tail & ~PAGE_MASK) == SYSCALLGATE)
1232 l->l_md.md_bpva = tf->tf_r31 & ~HPPA_PC_PRIV_MASK;
1233 else
1234 l->l_md.md_bpva = tf->tf_iioq_tail & ~HPPA_PC_PRIV_MASK;
1235
1236 error = ss_get_value(l, l->l_md.md_bpva, &l->l_md.md_bpsave[0]);
1237 if (error)
1238 return error;
1239 error = ss_get_value(l, l->l_md.md_bpva + 4, &l->l_md.md_bpsave[1]);
1240 if (error)
1241 return error;
1242
1243 error = ss_put_value(l, l->l_md.md_bpva, SSBREAKPOINT);
1244 if (error)
1245 return error;
1246 error = ss_put_value(l, l->l_md.md_bpva + 4, SSBREAKPOINT);
1247 if (error)
1248 return error;
1249
1250 if ((tf->tf_iioq_tail & ~PAGE_MASK) == SYSCALLGATE)
1251 tf->tf_ipsw &= ~PSW_T;
1252 else
1253 tf->tf_ipsw |= PSW_T;
1254
1255 return 0;
1256 }
1257 #endif
1258
1259
1260 /*
1261 * call actual syscall routine
1262 * from the low-level syscall handler:
1263 * - all HPPA_FRAME_NARGS syscall's arguments supposed to be copied onto
1264 * our stack, this wins compared to copyin just needed amount anyway
1265 * - register args are copied onto stack too
1266 */
1267 void
1268 syscall(struct trapframe *frame, int *args)
1269 {
1270 struct lwp *l;
1271 struct proc *p;
1272 const struct sysent *callp;
1273 size_t nargs64;
1274 int nsys, code, error;
1275 int tmp;
1276 int rval[2];
1277 #ifdef DIAGNOSTIC
1278 struct cpu_info *ci = curcpu();
1279 int oldcpl = ci->ci_cpl;
1280 #endif
1281
1282 curcpu()->ci_data.cpu_nsyscall++;
1283
1284 #ifdef DEBUG
1285 frame_sanity_check(__func__, __LINE__, 0, frame, curlwp);
1286 #endif /* DEBUG */
1287
1288 if (!USERMODE(frame->tf_iioq_head))
1289 panic("syscall");
1290
1291 KASSERT(curlwp != NULL);
1292 l = curlwp;
1293 p = l->l_proc;
1294 l->l_md.md_regs = frame;
1295 nsys = p->p_emul->e_nsysent;
1296 callp = p->p_emul->e_sysent;
1297 code = frame->tf_t1;
1298 LWP_CACHE_CREDS(l, p);
1299
1300 /*
1301 * Restarting a system call is touchy on the HPPA, because syscall
1302 * arguments are passed in registers and the program counter of the
1303 * syscall "point" isn't easily divined.
1304 *
1305 * We handle the first problem by assuming that we will have to restart
1306 * this system call, so we stuff the first four words of the original
1307 * arguments back into the frame as arg0...arg3, which is where we
1308 * found them in the first place. Any further arguments are (still) on
1309 * the user's stack and the syscall code will fetch them from there
1310 * (again).
1311 *
1312 * The program counter problem is addressed below.
1313 */
1314 frame->tf_arg0 = args[0];
1315 frame->tf_arg1 = args[1];
1316 frame->tf_arg2 = args[2];
1317 frame->tf_arg3 = args[3];
1318
1319 /*
1320 * Some special handling for the syscall(2) and
1321 * __syscall(2) system calls.
1322 */
1323 switch (code) {
1324 case SYS_syscall:
1325 code = *args;
1326 args += 1;
1327 break;
1328 case SYS___syscall:
1329 if (callp != sysent)
1330 break;
1331 /*
1332 * NB: even though __syscall(2) takes a quad_t containing the
1333 * system call number, because our argument copying word-swaps
1334 * 64-bit arguments, the least significant word of that quad_t
1335 * is the first word in the argument array.
1336 */
1337 code = *args;
1338 args += 2;
1339 }
1340
1341 /*
1342 * Stacks growing from lower addresses to higher addresses are not
1343 * really such a good idea, because it makes it impossible to overlay a
1344 * struct on top of C stack arguments (the arguments appear in
1345 * reversed order).
1346 *
1347 * You can do the obvious thing (as locore.S does) and copy argument
1348 * words one by one, laying them out in the "right" order in the dest-
1349 * ination buffer, but this ends up word-swapping multi-word arguments
1350 * (like off_t).
1351 *
1352 * FIXME - this works only on native binaries and
1353 * will probably screw up any and all emulation.
1354 *
1355 */
1356
1357 if (code < 0 || code >= nsys)
1358 callp += p->p_emul->e_nosys; /* bad syscall # */
1359 else
1360 callp += code;
1361
1362 nargs64 = SYCALL_NARGS64(callp);
1363 if (nargs64 != 0) {
1364 size_t nargs = callp->sy_narg;
1365
1366 for (size_t i = 0; i < nargs + nargs64;) {
1367 if (SYCALL_ARG_64_P(callp, i)) {
1368 tmp = args[i];
1369 args[i] = args[i + 1];
1370 args[i + 1] = tmp;
1371 i += 2;
1372 } else
1373 i++;
1374 }
1375 }
1376
1377 #ifdef USERTRACE
1378 if (0) {
1379 user_backtrace(frame, l, -1);
1380 frame->tf_ipsw |= PSW_R;
1381 frame->tf_rctr = 0;
1382 printf("r %08x", frame->tf_iioq_head);
1383 rctr_next_iioq = frame->tf_iioq_head + 4;
1384 }
1385 #endif
1386
1387 error = sy_invoke(callp, l, args, rval, code);
1388
1389 switch (error) {
1390 case 0:
1391 l = curlwp; /* changes on exec() */
1392 frame = l->l_md.md_regs;
1393 frame->tf_ret0 = rval[0];
1394 frame->tf_ret1 = rval[1];
1395 frame->tf_t1 = 0;
1396 break;
1397 case ERESTART:
1398 /*
1399 * Now we have to wind back the instruction offset queue to the
1400 * point where the system call will be made again. This is
1401 * inherently tied to the SYSCALL macro.
1402 *
1403 * Currently, the part of the SYSCALL macro that we want to re-
1404 * run reads as:
1405 *
1406 * ldil L%SYSCALLGATE, r1
1407 * ble 4(srX, r1)
1408 * ldi __CONCAT(SYS_,x), t1
1409 * comb,<> %r0, %t1, __cerror
1410 *
1411 * And our offset queue head points to the comb instruction.
1412 * So we need to subtract twelve to reach the ldil.
1413 */
1414 frame->tf_iioq_head -= 12;
1415 frame->tf_iioq_tail = frame->tf_iioq_head + 4;
1416 break;
1417 case EJUSTRETURN:
1418 p = curproc;
1419 break;
1420 default:
1421 if (p->p_emul->e_errno)
1422 error = p->p_emul->e_errno[error];
1423 frame->tf_t1 = error;
1424 break;
1425 }
1426
1427 userret(l, frame->tf_iioq_head, 0);
1428
1429 #ifdef DIAGNOSTIC
1430 if (ci->ci_cpl != oldcpl) {
1431 printf("WARNING: SPL (0x%x) NOT LOWERED ON "
1432 "syscall(0x%x, 0x%x, 0x%x, 0x%x...) EXIT, PID %d\n",
1433 ci->ci_cpl, code, args[0], args[1], args[2], p->p_pid);
1434 ci->ci_cpl = oldcpl;
1435 }
1436 #endif
1437
1438 #ifdef DEBUG
1439 frame_sanity_check(__func__, __LINE__, 0, frame, l);
1440 #endif /* DEBUG */
1441 }
1442
1443 /*
1444 * Start a new LWP
1445 */
1446 void
1447 startlwp(void *arg)
1448 {
1449 ucontext_t *uc = arg;
1450 lwp_t *l = curlwp;
1451 int error __diagused;
1452
1453 error = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
1454 KASSERT(error == 0);
1455
1456 kmem_free(uc, sizeof(ucontext_t));
1457 userret(l, l->l_md.md_regs->tf_iioq_head, 0);
1458 }
1459