Deleted Added
full compact
trap.c (114305) trap.c (115084)
1/* $FreeBSD: head/sys/ia64/ia64/trap.c 114305 2003-04-30 17:59:27Z jhb $ */
1/* $FreeBSD: head/sys/ia64/ia64/trap.c 115084 2003-05-16 21:26:42Z marcel $ */
2/* From: src/sys/alpha/alpha/trap.c,v 1.33 */
3/* $NetBSD: trap.c,v 1.31 1998/03/26 02:21:46 thorpej Exp $ */
4
5/*
6 * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
7 * All rights reserved.
8 *
9 * Author: Chris G. Demetriou

--- 31 unchanged lines hidden (view full) ---

41#include <sys/exec.h>
42#include <sys/lock.h>
43#include <sys/mutex.h>
44#include <sys/smp.h>
45#include <sys/vmmeter.h>
46#include <sys/sysent.h>
47#include <sys/syscall.h>
48#include <sys/pioctl.h>
2/* From: src/sys/alpha/alpha/trap.c,v 1.33 */
3/* $NetBSD: trap.c,v 1.31 1998/03/26 02:21:46 thorpej Exp $ */
4
5/*
6 * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
7 * All rights reserved.
8 *
9 * Author: Chris G. Demetriou

--- 31 unchanged lines hidden (view full) ---

41#include <sys/exec.h>
42#include <sys/lock.h>
43#include <sys/mutex.h>
44#include <sys/smp.h>
45#include <sys/vmmeter.h>
46#include <sys/sysent.h>
47#include <sys/syscall.h>
48#include <sys/pioctl.h>
49#include <sys/sysctl.h>
49#include <vm/vm.h>
50#include <vm/vm_kern.h>
51#include <vm/vm_page.h>
52#include <vm/vm_map.h>
53#include <vm/vm_extern.h>
54#include <vm/vm_param.h>
55#include <sys/user.h>
56#include <sys/ptrace.h>
57#include <machine/clock.h>
58#include <machine/cpu.h>
59#include <machine/md_var.h>
60#include <machine/reg.h>
61#include <machine/pal.h>
62#include <machine/fpu.h>
63#include <machine/efi.h>
50#include <vm/vm.h>
51#include <vm/vm_kern.h>
52#include <vm/vm_page.h>
53#include <vm/vm_map.h>
54#include <vm/vm_extern.h>
55#include <vm/vm_param.h>
56#include <sys/user.h>
57#include <sys/ptrace.h>
58#include <machine/clock.h>
59#include <machine/cpu.h>
60#include <machine/md_var.h>
61#include <machine/reg.h>
62#include <machine/pal.h>
63#include <machine/fpu.h>
64#include <machine/efi.h>
65#ifdef SMP
66#include <machine/smp.h>
67#endif
64
65#ifdef KTRACE
66#include <sys/uio.h>
67#include <sys/ktrace.h>
68#endif
69
70#ifdef DDB
71#include <ddb/ddb.h>
72#endif
73
68
69#ifdef KTRACE
70#include <sys/uio.h>
71#include <sys/ktrace.h>
72#endif
73
74#ifdef DDB
75#include <ddb/ddb.h>
76#endif
77
78static int print_usertrap = 0;
79SYSCTL_INT(_machdep, CPU_UNALIGNED_PRINT, print_usertrap,
80 CTLFLAG_RW, &print_usertrap, 0, "");
81
74extern int unaligned_fixup(struct trapframe *framep, struct thread *td);
82extern int unaligned_fixup(struct trapframe *framep, struct thread *td);
83
84static void break_syscall(struct trapframe *tf);
75static void ia32_syscall(struct trapframe *framep);
76
77/*
78 * EFI-Provided FPSWA interface (Floating Point SoftWare Assist
79 */
80
81/* The function entry address */
82extern FPSWA_INTERFACE *fpswa_interface;

--- 5 unchanged lines hidden (view full) ---

88} FPSWA_BUNDLE;
89
90/*
91 * The fp state descriptor... tell FPSWA where the "true" copy is.
92 * We save some registers in the trapframe, so we have to point some of
93 * these there. The rest of the registers are "live"
94 */
95typedef struct {
85static void ia32_syscall(struct trapframe *framep);
86
87/*
88 * EFI-Provided FPSWA interface (Floating Point SoftWare Assist
89 */
90
91/* The function entry address */
92extern FPSWA_INTERFACE *fpswa_interface;

--- 5 unchanged lines hidden (view full) ---

98} FPSWA_BUNDLE;
99
100/*
101 * The fp state descriptor... tell FPSWA where the "true" copy is.
102 * We save some registers in the trapframe, so we have to point some of
103 * these there. The rest of the registers are "live"
104 */
105typedef struct {
96 u_int64_t bitmask_low64; /* f63 - f2 */
97 u_int64_t bitmask_high64; /* f127 - f64 */
98 struct ia64_fpreg *fp_low_preserved; /* f2 - f5 */
99 struct ia64_fpreg *fp_low_volatile; /* f6 - f15 */
100 struct ia64_fpreg *fp_high_preserved; /* f16 - f31 */
101 struct ia64_fpreg *fp_high_volatile; /* f32 - f127 */
106 u_int64_t bitmask_low64; /* f63 - f2 */
107 u_int64_t bitmask_high64; /* f127 - f64 */
108 struct _ia64_fpreg *fp_low_preserved; /* f2 - f5 */
109 struct _ia64_fpreg *fp_low_volatile; /* f6 - f15 */
110 struct _ia64_fpreg *fp_high_preserved; /* f16 - f31 */
111 struct _ia64_fpreg *fp_high_volatile; /* f32 - f127 */
102} FP_STATE;
103
104#ifdef WITNESS
105extern char *syscallnames[];
106#endif
107
108static const char *ia64_vector_names[] = {
109 "VHPT Translation", /* 0 */

--- 156 unchanged lines hidden (view full) ---

266};
267
268static void printisr(u_int64_t isr)
269{
270 printbits(isr, isr_bits, sizeof(isr_bits)/sizeof(isr_bits[0]));
271}
272
273static void
112} FP_STATE;
113
114#ifdef WITNESS
115extern char *syscallnames[];
116#endif
117
118static const char *ia64_vector_names[] = {
119 "VHPT Translation", /* 0 */

--- 156 unchanged lines hidden (view full) ---

276};
277
278static void printisr(u_int64_t isr)
279{
280 printbits(isr, isr_bits, sizeof(isr_bits)/sizeof(isr_bits[0]));
281}
282
283static void
274printtrap(int vector, int imm, struct trapframe *framep, int isfatal, int user)
284printtrap(int vector, struct trapframe *framep, int isfatal, int user)
275{
276 printf("\n");
277 printf("%s %s trap (cpu %d):\n", isfatal? "fatal" : "handled",
278 user ? "user" : "kernel", PCPU_GET(cpuid));
279 printf("\n");
280 printf(" trap vector = 0x%x (%s)\n",
281 vector, ia64_vector_names[vector]);
285{
286 printf("\n");
287 printf("%s %s trap (cpu %d):\n", isfatal? "fatal" : "handled",
288 user ? "user" : "kernel", PCPU_GET(cpuid));
289 printf("\n");
290 printf(" trap vector = 0x%x (%s)\n",
291 vector, ia64_vector_names[vector]);
282 printf(" cr.iip = 0x%lx\n", framep->tf_cr_iip);
283 printf(" cr.ipsr = 0x%lx (", framep->tf_cr_ipsr);
284 printpsr(framep->tf_cr_ipsr);
292 printf(" cr.iip = 0x%lx\n", framep->tf_special.iip);
293 printf(" cr.ipsr = 0x%lx (", framep->tf_special.psr);
294 printpsr(framep->tf_special.psr);
285 printf(")\n");
295 printf(")\n");
286 printf(" cr.isr = 0x%lx (", framep->tf_cr_isr);
287 printisr(framep->tf_cr_isr);
296 printf(" cr.isr = 0x%lx (", framep->tf_special.isr);
297 printisr(framep->tf_special.isr);
288 printf(")\n");
298 printf(")\n");
289 printf(" cr.ifa = 0x%lx\n", framep->tf_cr_ifa);
290 printf(" cr.iim = 0x%x\n", imm);
291 if (framep->tf_cr_ipsr & IA64_PSR_IS) {
299 printf(" cr.ifa = 0x%lx\n", framep->tf_special.ifa);
300 if (framep->tf_special.psr & IA64_PSR_IS) {
292 printf(" ar.cflg = 0x%lx\n", ia64_get_cflg());
293 printf(" ar.csd = 0x%lx\n", ia64_get_csd());
294 printf(" ar.ssd = 0x%lx\n", ia64_get_ssd());
295 }
296 printf(" curthread = %p\n", curthread);
297 if (curthread != NULL)
298 printf(" pid = %d, comm = %s\n",
299 curthread->td_proc->p_pid, curthread->td_proc->p_comm);
300 printf("\n");
301}
302
303/*
301 printf(" ar.cflg = 0x%lx\n", ia64_get_cflg());
302 printf(" ar.csd = 0x%lx\n", ia64_get_csd());
303 printf(" ar.ssd = 0x%lx\n", ia64_get_ssd());
304 }
305 printf(" curthread = %p\n", curthread);
306 if (curthread != NULL)
307 printf(" pid = %d, comm = %s\n",
308 curthread->td_proc->p_pid, curthread->td_proc->p_comm);
309 printf("\n");
310}
311
312/*
313 *
314 */
315int
316do_ast(struct trapframe *tf)
317{
318
319 disable_intr();
320 while (curthread->td_flags & (TDF_ASTPENDING|TDF_NEEDRESCHED)) {
321 enable_intr();
322 ast(tf);
323 disable_intr();
324 }
325 /*
326 * Keep interrupts disabled. We return r10 as a favor to the EPC
327 * syscall code so that it can quicky determine if the syscall
328 * needs to be restarted or not.
329 */
330 return (tf->tf_scratch.gr10);
331}
332
333/*
304 * Trap is called from exception.s to handle most types of processor traps.
334 * Trap is called from exception.s to handle most types of processor traps.
305 * System calls are broken out for efficiency and ASTs are broken out
306 * to make the code a bit cleaner and more representative of the
307 * architecture.
308 */
309/*ARGSUSED*/
310void
335 */
336/*ARGSUSED*/
337void
311trap(int vector, int imm, struct trapframe *framep)
338trap(int vector, struct trapframe *framep)
312{
339{
313 struct thread *td;
314 struct proc *p;
340 struct proc *p;
315 int i;
341 struct thread *td;
316 u_int64_t ucode;
342 u_int64_t ucode;
343 int i, user;
317 u_int sticks;
344 u_int sticks;
318 int user;
319
345
320 cnt.v_trap++;
346 user = ((framep->tf_special.psr & IA64_PSR_CPL) == IA64_PSR_CPL_USER);
347
348 /* Short-circuit break instruction based system calls. */
349 if (vector == IA64_VEC_BREAK && user &&
350 framep->tf_special.ifa == 0x100000) {
351 break_syscall(framep);
352 return;
353 }
354
355 /* Sanitize the FP state in case the user has trashed it. */
356 ia64_set_fpsr(IA64_FPSR_DEFAULT);
357
358 atomic_add_int(&cnt.v_trap, 1);
359
321 td = curthread;
322 p = td->td_proc;
323 ucode = 0;
324
360 td = curthread;
361 p = td->td_proc;
362 ucode = 0;
363
325 /*
326 * Make sure we have a sane floating-point state in case the
327 * user has trashed it.
328 */
329 ia64_set_fpsr(IA64_FPSR_DEFAULT);
330
331 user = ((framep->tf_cr_ipsr & IA64_PSR_CPL) == IA64_PSR_CPL_USER);
332 if (user) {
333 sticks = td->td_sticks;
334 td->td_frame = framep;
335 if (td->td_ucred != p->p_ucred)
336 cred_update_thread(td);
337 } else {
338 sticks = 0; /* XXX bogus -Wuninitialized warning */
339 KASSERT(cold || td->td_ucred != NULL,
340 ("kernel trap doesn't have ucred"));
341 }
342
343 switch (vector) {
364 if (user) {
365 sticks = td->td_sticks;
366 td->td_frame = framep;
367 if (td->td_ucred != p->p_ucred)
368 cred_update_thread(td);
369 } else {
370 sticks = 0; /* XXX bogus -Wuninitialized warning */
371 KASSERT(cold || td->td_ucred != NULL,
372 ("kernel trap doesn't have ucred"));
373 }
374
375 switch (vector) {
344 case IA64_VEC_UNALIGNED_REFERENCE:
376
377 case IA64_VEC_UNALIGNED_REFERENCE: {
345 /*
346 * If user-land, do whatever fixups, printing, and
347 * signalling is appropriate (based on system-wide
348 * and per-process unaligned-access-handling flags).
349 */
350 if (user) {
378 /*
379 * If user-land, do whatever fixups, printing, and
380 * signalling is appropriate (based on system-wide
381 * and per-process unaligned-access-handling flags).
382 */
383 if (user) {
351 mtx_lock(&Giant);
352 i = unaligned_fixup(framep, td);
384 i = unaligned_fixup(framep, td);
353 mtx_unlock(&Giant);
354 if (i == 0)
355 goto out;
385 if (i == 0)
386 goto out;
356 ucode = framep->tf_cr_ifa; /* VA */
387 ucode = framep->tf_special.ifa; /* VA */
357 break;
358 }
359
360 /*
361 * Unaligned access from kernel mode is always an error,
362 * EVEN IF A COPY FAULT HANDLER IS SET!
363 *
364 * It's an error if a copy fault handler is set because
365 * the various routines which do user-initiated copies
366 * do so in a bcopy-like manner. In other words, the
367 * kernel never assumes that pointers provided by the
368 * user are properly aligned, and so if the kernel
369 * does cause an unaligned access it's a kernel bug.
370 */
371 goto dopanic;
388 break;
389 }
390
391 /*
392 * Unaligned access from kernel mode is always an error,
393 * EVEN IF A COPY FAULT HANDLER IS SET!
394 *
395 * It's an error if a copy fault handler is set because
396 * the various routines which do user-initiated copies
397 * do so in a bcopy-like manner. In other words, the
398 * kernel never assumes that pointers provided by the
399 * user are properly aligned, and so if the kernel
400 * does cause an unaligned access it's a kernel bug.
401 */
402 goto dopanic;
403 }
372
404
373 case IA64_VEC_FLOATING_POINT_FAULT:
374 {
405 case IA64_VEC_FLOATING_POINT_FAULT: {
375 FP_STATE fp_state;
376 FPSWA_RET fpswa_ret;
377 FPSWA_BUNDLE bundle;
378
379 /* Always fatal in kernel. Should never happen. */
380 if (!user)
381 goto dopanic;
382 if (fpswa_interface == NULL) {
383 i = SIGFPE;
384 ucode = 0;
385 break;
386 }
387 mtx_lock(&Giant);
406 FP_STATE fp_state;
407 FPSWA_RET fpswa_ret;
408 FPSWA_BUNDLE bundle;
409
410 /* Always fatal in kernel. Should never happen. */
411 if (!user)
412 goto dopanic;
413 if (fpswa_interface == NULL) {
414 i = SIGFPE;
415 ucode = 0;
416 break;
417 }
418 mtx_lock(&Giant);
388 i = copyin((const void *)(framep->tf_cr_iip), &bundle, 16);
419 i = copyin((void *)(framep->tf_special.iip), &bundle, 16);
389 mtx_unlock(&Giant);
390 if (i) {
391 i = SIGBUS; /* EFAULT, basically */
392 ucode = /*a0*/ 0; /* exception summary */
393 break;
394 }
395 /* f6-f15 are saved in exception_save */
396 fp_state.bitmask_low64 = 0xffc0; /* bits 6 - 15 */
397 fp_state.bitmask_high64 = 0x0;
398 fp_state.fp_low_preserved = NULL;
420 mtx_unlock(&Giant);
421 if (i) {
422 i = SIGBUS; /* EFAULT, basically */
423 ucode = /*a0*/ 0; /* exception summary */
424 break;
425 }
426 /* f6-f15 are saved in exception_save */
427 fp_state.bitmask_low64 = 0xffc0; /* bits 6 - 15 */
428 fp_state.bitmask_high64 = 0x0;
429 fp_state.fp_low_preserved = NULL;
399 fp_state.fp_low_volatile = framep->tf_f;
430 fp_state.fp_low_volatile = &framep->tf_scratch_fp.fr6;
400 fp_state.fp_high_preserved = NULL;
401 fp_state.fp_high_volatile = NULL;
402 /* The docs are unclear. Is Fpswa reentrant? */
403 fpswa_ret = fpswa_interface->Fpswa(1, &bundle,
431 fp_state.fp_high_preserved = NULL;
432 fp_state.fp_high_volatile = NULL;
433 /* The docs are unclear. Is Fpswa reentrant? */
434 fpswa_ret = fpswa_interface->Fpswa(1, &bundle,
404 &framep->tf_cr_ipsr, &framep->tf_ar_fpsr,
405 &framep->tf_cr_isr, &framep->tf_pr,
406 &framep->tf_cr_ifs, &fp_state);
435 &framep->tf_special.psr, &framep->tf_special.fpsr,
436 &framep->tf_special.isr, &framep->tf_special.pr,
437 &framep->tf_special.cfm, &fp_state);
407 if (fpswa_ret.status == 0) {
408 /* fixed. update ipsr and iip to next insn */
409 int ei;
410
438 if (fpswa_ret.status == 0) {
439 /* fixed. update ipsr and iip to next insn */
440 int ei;
441
411 ei = (framep->tf_cr_isr >> 41) & 0x03;
442 ei = (framep->tf_special.isr >> 41) & 0x03;
412 if (ei == 0) { /* no template for this case */
443 if (ei == 0) { /* no template for this case */
413 framep->tf_cr_ipsr &= ~IA64_ISR_EI;
414 framep->tf_cr_ipsr |= IA64_ISR_EI_1;
444 framep->tf_special.psr &= ~IA64_ISR_EI;
445 framep->tf_special.psr |= IA64_ISR_EI_1;
415 } else if (ei == 1) { /* MFI or MFB */
446 } else if (ei == 1) { /* MFI or MFB */
416 framep->tf_cr_ipsr &= ~IA64_ISR_EI;
417 framep->tf_cr_ipsr |= IA64_ISR_EI_2;
447 framep->tf_special.psr &= ~IA64_ISR_EI;
448 framep->tf_special.psr |= IA64_ISR_EI_2;
418 } else if (ei == 2) { /* MMF */
449 } else if (ei == 2) { /* MMF */
419 framep->tf_cr_ipsr &= ~IA64_ISR_EI;
420 framep->tf_cr_iip += 0x10;
450 framep->tf_special.psr &= ~IA64_ISR_EI;
451 framep->tf_special.iip += 0x10;
421 }
422 goto out;
423 } else if (fpswa_ret.status == -1) {
424 printf("FATAL: FPSWA err1 %lx, err2 %lx, err3 %lx\n",
425 fpswa_ret.err1, fpswa_ret.err2, fpswa_ret.err3);
426 panic("fpswa fatal error on fp fault");
427 } else if (fpswa_ret.status > 0) {
428#if 0

--- 12 unchanged lines hidden (view full) ---

441 i = SIGFPE;
442 ucode = /*a0*/ 0; /* exception summary */
443 break;
444 } else {
445 panic("bad fpswa return code %lx", fpswa_ret.status);
446 }
447 }
448
452 }
453 goto out;
454 } else if (fpswa_ret.status == -1) {
455 printf("FATAL: FPSWA err1 %lx, err2 %lx, err3 %lx\n",
456 fpswa_ret.err1, fpswa_ret.err2, fpswa_ret.err3);
457 panic("fpswa fatal error on fp fault");
458 } else if (fpswa_ret.status > 0) {
459#if 0

--- 12 unchanged lines hidden (view full) ---

472 i = SIGFPE;
473 ucode = /*a0*/ 0; /* exception summary */
474 break;
475 } else {
476 panic("bad fpswa return code %lx", fpswa_ret.status);
477 }
478 }
479
449 case IA64_VEC_FLOATING_POINT_TRAP:
450 {
480 case IA64_VEC_FLOATING_POINT_TRAP: {
451 FP_STATE fp_state;
452 FPSWA_RET fpswa_ret;
453 FPSWA_BUNDLE bundle;
454
455 /* Always fatal in kernel. Should never happen. */
456 if (!user)
457 goto dopanic;
458 if (fpswa_interface == NULL) {
459 i = SIGFPE;
460 ucode = 0;
461 break;
462 }
463 mtx_lock(&Giant);
481 FP_STATE fp_state;
482 FPSWA_RET fpswa_ret;
483 FPSWA_BUNDLE bundle;
484
485 /* Always fatal in kernel. Should never happen. */
486 if (!user)
487 goto dopanic;
488 if (fpswa_interface == NULL) {
489 i = SIGFPE;
490 ucode = 0;
491 break;
492 }
493 mtx_lock(&Giant);
464 i = copyin((const void *)(framep->tf_cr_iip), &bundle, 16);
494 i = copyin((void *)(framep->tf_special.iip), &bundle, 16);
465 mtx_unlock(&Giant);
466 if (i) {
467 i = SIGBUS; /* EFAULT, basically */
468 ucode = /*a0*/ 0; /* exception summary */
469 break;
470 }
471 /* f6-f15 are saved in exception_save */
472 fp_state.bitmask_low64 = 0xffc0; /* bits 6 - 15 */
473 fp_state.bitmask_high64 = 0x0;
474 fp_state.fp_low_preserved = NULL;
495 mtx_unlock(&Giant);
496 if (i) {
497 i = SIGBUS; /* EFAULT, basically */
498 ucode = /*a0*/ 0; /* exception summary */
499 break;
500 }
501 /* f6-f15 are saved in exception_save */
502 fp_state.bitmask_low64 = 0xffc0; /* bits 6 - 15 */
503 fp_state.bitmask_high64 = 0x0;
504 fp_state.fp_low_preserved = NULL;
475 fp_state.fp_low_volatile = framep->tf_f;
505 fp_state.fp_low_volatile = &framep->tf_scratch_fp.fr6;
476 fp_state.fp_high_preserved = NULL;
477 fp_state.fp_high_volatile = NULL;
478 /* The docs are unclear. Is Fpswa reentrant? */
479 fpswa_ret = fpswa_interface->Fpswa(0, &bundle,
506 fp_state.fp_high_preserved = NULL;
507 fp_state.fp_high_volatile = NULL;
508 /* The docs are unclear. Is Fpswa reentrant? */
509 fpswa_ret = fpswa_interface->Fpswa(0, &bundle,
480 &framep->tf_cr_ipsr, &framep->tf_ar_fpsr,
481 &framep->tf_cr_isr, &framep->tf_pr,
482 &framep->tf_cr_ifs, &fp_state);
510 &framep->tf_special.psr, &framep->tf_special.fpsr,
511 &framep->tf_special.isr, &framep->tf_special.pr,
512 &framep->tf_special.cfm, &fp_state);
483 if (fpswa_ret.status == 0) {
484 /* fixed */
485 /*
486 * should we increment iip like the fault case?
487 * or has fpswa done something like normalizing a
488 * register so that we should just rerun it?
489 */
490 goto out;

--- 5 unchanged lines hidden (view full) ---

496 i = SIGFPE;
497 ucode = /*a0*/ 0; /* exception summary */
498 break;
499 } else {
500 panic("bad fpswa return code %lx", fpswa_ret.status);
501 }
502 }
503
513 if (fpswa_ret.status == 0) {
514 /* fixed */
515 /*
516 * should we increment iip like the fault case?
517 * or has fpswa done something like normalizing a
518 * register so that we should just rerun it?
519 */
520 goto out;

--- 5 unchanged lines hidden (view full) ---

526 i = SIGFPE;
527 ucode = /*a0*/ 0; /* exception summary */
528 break;
529 } else {
530 panic("bad fpswa return code %lx", fpswa_ret.status);
531 }
532 }
533
504 case IA64_VEC_DISABLED_FP:
534 case IA64_VEC_DISABLED_FP: { /* High FP registers are disabled. */
535 struct pcpu *pcpu;
536 struct pcb *pcb;
537 struct thread *thr;
538
539 /* Always fatal in kernel. Should never happen. */
540 if (!user)
541 goto dopanic;
542
543 pcb = td->td_pcb;
544 pcpu = pcb->pcb_fpcpu;
545
546#if 0
547 printf("XXX: td %p: highfp on cpu %p\n", td, pcpu);
548#endif
549
505 /*
550 /*
506 * on exit from the kernel, if thread == fpcurthread,
507 * FP is enabled.
551 * The pcpu variable holds the address of the per-CPU
552 * structure of the CPU currently holding this threads
553 * high FP registers (or NULL if no CPU holds these
554 * registers). We have to interrupt that CPU and wait
555 * for it to have saved the registers.
508 */
556 */
509 if (PCPU_GET(fpcurthread) == td) {
510 printf("trap: fp disabled for fpcurthread == %p", td);
511 goto dopanic;
557 if (pcpu != NULL) {
558 thr = pcpu->pc_fpcurthread;
559 KASSERT(thr == td, ("High FP state out of sync"));
560
561 if (pcpu == pcpup) {
562 /*
563 * Short-circuit handling the trap when this
564 * CPU already holds the high FP registers for
565 * this thread. We really shouldn't get the
566 * trap in the first place, but since it's
567 * only a performance issue and not a
568 * correctness issue, we emit a message for
569 * now, enable the high FP registers and
570 * return.
571 */
572 printf("XXX: bogusly disabled high FP regs\n");
573 framep->tf_special.psr &= ~IA64_PSR_DFH;
574 goto out;
575 }
576#ifdef SMP
577 /*
578 * Interrupt the other CPU so that it saves the high
579 * FP registers of this thread. Note that this can
580 * only happen for the SMP case.
581 */
582 ipi_send(pcpu->pc_lid, IPI_HIGH_FP);
583#endif
584#ifdef DIAGNOSTICS
585 } else {
586 KASSERT(PCPU_GET(fpcurthread) != td,
587 ("High FP state out of sync"));
588#endif
512 }
589 }
513
514 ia64_fpstate_switch(td);
590
591 thr = PCPU_GET(fpcurthread);
592
593#if 0
594 printf("XXX: cpu %p: highfp belongs to td %p\n", pcpup, thr);
595#endif
596
597 /*
598 * The thr variable holds the thread that owns the high FP
599 * registers currently on this CPU. Free this CPU so that
600 * we can load the current threads high FP registers.
601 */
602 if (thr != NULL) {
603 KASSERT(thr != td, ("High FP state out of sync"));
604 pcb = thr->td_pcb;
605 KASSERT(pcb->pcb_fpcpu == pcpup,
606 ("High FP state out of sync"));
607 ia64_highfp_save(thr);
608 }
609
610 /*
611 * Wait for the other CPU to have saved out high FP
612 * registers (if applicable).
613 */
614 while (pcpu && pcpu->pc_fpcurthread == td);
615
616 ia64_highfp_load(td);
617 framep->tf_special.psr &= ~IA64_PSR_DFH;
515 goto out;
516 break;
618 goto out;
619 break;
620 }
517
518 case IA64_VEC_PAGE_NOT_PRESENT:
519 case IA64_VEC_INST_ACCESS_RIGHTS:
621
622 case IA64_VEC_PAGE_NOT_PRESENT:
623 case IA64_VEC_INST_ACCESS_RIGHTS:
520 case IA64_VEC_DATA_ACCESS_RIGHTS:
521 {
624 case IA64_VEC_DATA_ACCESS_RIGHTS: {
522 vm_offset_t va;
523 struct vmspace *vm;
524 vm_map_t map;
525 vm_prot_t ftype;
526 int rv;
527
528 rv = 0;
625 vm_offset_t va;
626 struct vmspace *vm;
627 vm_map_t map;
628 vm_prot_t ftype;
629 int rv;
630
631 rv = 0;
529 va = framep->tf_cr_ifa;
632 va = framep->tf_special.ifa;
530
531 /*
532 * If it was caused by fuswintr or suswintr, just punt. Note
533 * that we check the faulting address against the address
534 * accessed by [fs]uswintr, in case another fault happens when
535 * they are running.
536 */
537 if (!user && td != NULL && td->td_pcb->pcb_accessaddr == va &&
538 td->td_pcb->pcb_onfault == (unsigned long)fswintrberr) {
633
634 /*
635 * If it was caused by fuswintr or suswintr, just punt. Note
636 * that we check the faulting address against the address
637 * accessed by [fs]uswintr, in case another fault happens when
638 * they are running.
639 */
640 if (!user && td != NULL && td->td_pcb->pcb_accessaddr == va &&
641 td->td_pcb->pcb_onfault == (unsigned long)fswintrberr) {
539 framep->tf_cr_iip = td->td_pcb->pcb_onfault;
540 framep->tf_cr_ipsr &= ~IA64_PSR_RI;
642 framep->tf_special.iip = td->td_pcb->pcb_onfault;
643 framep->tf_special.psr &= ~IA64_PSR_RI;
541 td->td_pcb->pcb_onfault = 0;
542 goto out;
543 }
544
545 va = trunc_page((vm_offset_t)va);
546
547 if (va >= VM_MIN_KERNEL_ADDRESS) {
548 /*

--- 5 unchanged lines hidden (view full) ---

554 map = kernel_map;
555 } else {
556 vm = (p != NULL) ? p->p_vmspace : NULL;
557 if (vm == NULL)
558 goto no_fault_in;
559 map = &vm->vm_map;
560 }
561
644 td->td_pcb->pcb_onfault = 0;
645 goto out;
646 }
647
648 va = trunc_page((vm_offset_t)va);
649
650 if (va >= VM_MIN_KERNEL_ADDRESS) {
651 /*

--- 5 unchanged lines hidden (view full) ---

657 map = kernel_map;
658 } else {
659 vm = (p != NULL) ? p->p_vmspace : NULL;
660 if (vm == NULL)
661 goto no_fault_in;
662 map = &vm->vm_map;
663 }
664
562 if (framep->tf_cr_isr & IA64_ISR_X)
665 if (framep->tf_special.isr & IA64_ISR_X)
563 ftype = VM_PROT_EXECUTE;
666 ftype = VM_PROT_EXECUTE;
564 else if (framep->tf_cr_isr & IA64_ISR_W)
667 else if (framep->tf_special.isr & IA64_ISR_W)
565 ftype = VM_PROT_WRITE;
566 else
567 ftype = VM_PROT_READ;
568
569 if (map != kernel_map) {
570 /*
571 * Keep swapout from messing with us during this
572 * critical time.

--- 19 unchanged lines hidden (view full) ---

592
593 if (rv == KERN_SUCCESS)
594 goto out;
595
596 no_fault_in:
597 if (!user) {
598 /* Check for copyin/copyout fault. */
599 if (td != NULL && td->td_pcb->pcb_onfault != 0) {
668 ftype = VM_PROT_WRITE;
669 else
670 ftype = VM_PROT_READ;
671
672 if (map != kernel_map) {
673 /*
674 * Keep swapout from messing with us during this
675 * critical time.

--- 19 unchanged lines hidden (view full) ---

695
696 if (rv == KERN_SUCCESS)
697 goto out;
698
699 no_fault_in:
700 if (!user) {
701 /* Check for copyin/copyout fault. */
702 if (td != NULL && td->td_pcb->pcb_onfault != 0) {
600 framep->tf_cr_iip = td->td_pcb->pcb_onfault;
601 framep->tf_cr_ipsr &= ~IA64_PSR_RI;
703 framep->tf_special.iip =
704 td->td_pcb->pcb_onfault;
705 framep->tf_special.psr &= ~IA64_PSR_RI;
602 td->td_pcb->pcb_onfault = 0;
603 goto out;
604 }
605 goto dopanic;
606 }
607 ucode = va;
608 i = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV;
609 break;
610 }
611
706 td->td_pcb->pcb_onfault = 0;
707 goto out;
708 }
709 goto dopanic;
710 }
711 ucode = va;
712 i = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV;
713 break;
714 }
715
612 case IA64_VEC_SINGLE_STEP_TRAP:
613 case IA64_VEC_DEBUG:
614 case IA64_VEC_TAKEN_BRANCH_TRAP:
615 case IA64_VEC_BREAK:
716 case IA64_VEC_BREAK:
717 case IA64_VEC_DEBUG:
718 case IA64_VEC_SINGLE_STEP_TRAP:
719 case IA64_VEC_TAKEN_BRANCH_TRAP: {
616 /*
617 * These are always fatal in kernel, and should never happen.
618 */
619 if (!user) {
620#ifdef DDB
621 /*
622 * ...unless, of course, DDB is configured.
623 */

--- 4 unchanged lines hidden (view full) ---

628 * If we get here, DDB did _not_ handle the
629 * trap, and we need to PANIC!
630 */
631#endif
632 goto dopanic;
633 }
634 i = SIGTRAP;
635 break;
720 /*
721 * These are always fatal in kernel, and should never happen.
722 */
723 if (!user) {
724#ifdef DDB
725 /*
726 * ...unless, of course, DDB is configured.
727 */

--- 4 unchanged lines hidden (view full) ---

732 * If we get here, DDB did _not_ handle the
733 * trap, and we need to PANIC!
734 */
735#endif
736 goto dopanic;
737 }
738 i = SIGTRAP;
739 break;
740 }
636
741
637 case IA64_VEC_GENERAL_EXCEPTION:
742 case IA64_VEC_GENERAL_EXCEPTION: {
638 if (user) {
639 ucode = vector;
640 i = SIGILL;
641 break;
642 }
643 goto dopanic;
743 if (user) {
744 ucode = vector;
745 i = SIGILL;
746 break;
747 }
748 goto dopanic;
749 }
644
645 case IA64_VEC_UNSUPP_DATA_REFERENCE:
750
751 case IA64_VEC_UNSUPP_DATA_REFERENCE:
646 case IA64_VEC_LOWER_PRIVILEGE_TRANSFER:
752 case IA64_VEC_LOWER_PRIVILEGE_TRANSFER: {
647 if (user) {
648 ucode = vector;
649 i = SIGBUS;
650 break;
651 }
652 goto dopanic;
753 if (user) {
754 ucode = vector;
755 i = SIGBUS;
756 break;
757 }
758 goto dopanic;
759 }
653
760
654 case IA64_VEC_IA32_EXCEPTION:
655 {
656 u_int64_t isr = framep->tf_cr_isr;
761 case IA64_VEC_IA32_EXCEPTION: {
762 u_int64_t isr = framep->tf_special.isr;
657
658 switch ((isr >> 16) & 0xffff) {
659 case IA32_EXCEPTION_DIVIDE:
660 ucode = FPE_INTDIV;
661 i = SIGFPE;
662 break;
663
664 case IA32_EXCEPTION_DEBUG:

--- 24 unchanged lines hidden (view full) ---

689 break;
690
691 case IA32_EXCEPTION_FPERROR:
692 ucode = 0; /* XXX */
693 i = SIGFPE;
694 break;
695
696 case IA32_EXCEPTION_ALIGNMENT_CHECK:
763
764 switch ((isr >> 16) & 0xffff) {
765 case IA32_EXCEPTION_DIVIDE:
766 ucode = FPE_INTDIV;
767 i = SIGFPE;
768 break;
769
770 case IA32_EXCEPTION_DEBUG:

--- 24 unchanged lines hidden (view full) ---

795 break;
796
797 case IA32_EXCEPTION_FPERROR:
798 ucode = 0; /* XXX */
799 i = SIGFPE;
800 break;
801
802 case IA32_EXCEPTION_ALIGNMENT_CHECK:
697 ucode = framep->tf_cr_ifa; /* VA */
803 ucode = framep->tf_special.ifa; /* VA */
698 i = SIGBUS;
699 break;
700
701 case IA32_EXCEPTION_STREAMING_SIMD:
702 ucode = 0; /* XXX */
703 i = SIGFPE;
704 break;
705
706 default:
707 goto dopanic;
708 }
709 break;
710 }
711
804 i = SIGBUS;
805 break;
806
807 case IA32_EXCEPTION_STREAMING_SIMD:
808 ucode = 0; /* XXX */
809 i = SIGFPE;
810 break;
811
812 default:
813 goto dopanic;
814 }
815 break;
816 }
817
712 case IA64_VEC_IA32_INTERRUPT:
818 case IA64_VEC_IA32_INTERRUPT: {
713 /*
714 * INT n instruction - probably a syscall.
715 */
819 /*
820 * INT n instruction - probably a syscall.
821 */
716 if (((framep->tf_cr_isr >> 16) & 0xffff) == 0x80) {
822 if (((framep->tf_special.isr >> 16) & 0xffff) == 0x80) {
717 ia32_syscall(framep);
718 goto out;
719 } else {
823 ia32_syscall(framep);
824 goto out;
825 } else {
720 ucode = (framep->tf_cr_isr >> 16) & 0xffff;
826 ucode = (framep->tf_special.isr >> 16) & 0xffff;
721 i = SIGILL;
722 break;
723 }
827 i = SIGILL;
828 break;
829 }
830 }
724
831
725 case IA64_VEC_IA32_INTERCEPT:
832 case IA64_VEC_IA32_INTERCEPT: {
726 /*
727 * Maybe need to emulate ia32 instruction.
728 */
729 goto dopanic;
833 /*
834 * Maybe need to emulate ia32 instruction.
835 */
836 goto dopanic;
837 }
730
731 default:
732 goto dopanic;
733 }
734
838
839 default:
840 goto dopanic;
841 }
842
735#ifdef DEBUG
736 printtrap(vector, imm, framep, 1, user);
737#endif
843 if (print_usertrap)
844 printtrap(vector, framep, 1, user);
845
738 trapsignal(td, i, ucode);
846 trapsignal(td, i, ucode);
847
739out:
740 if (user) {
741 userret(td, framep, sticks);
742 mtx_assert(&Giant, MA_NOTOWNED);
743#ifdef DIAGNOSTIC
744 cred_free_thread(td);
745#endif
848out:
849 if (user) {
850 userret(td, framep, sticks);
851 mtx_assert(&Giant, MA_NOTOWNED);
852#ifdef DIAGNOSTIC
853 cred_free_thread(td);
854#endif
855 do_ast(framep);
746 }
747 return;
748
749dopanic:
856 }
857 return;
858
859dopanic:
750 printtrap(vector, imm, framep, 1, user);
751
752 /* XXX dump registers */
753
860 printtrap(vector, framep, 1, user);
754#ifdef DDB
755 kdb_trap(vector, framep);
756#endif
861#ifdef DDB
862 kdb_trap(vector, framep);
863#endif
757
758 panic("trap");
759}
760
864 panic("trap");
865}
866
867
761/*
868/*
869 * Handle break instruction based system calls.
870 */
871void
872break_syscall(struct trapframe *tf)
873{
874 uint64_t *bsp, *tfp;
875 uint64_t iip, psr;
876 int error, nargs;
877
878 /* Save address of break instruction. */
879 iip = tf->tf_special.iip;
880 psr = tf->tf_special.psr;
881
882 /* Advance to the next instruction. */
883 tf->tf_special.psr += IA64_PSR_RI_1;
884 if ((tf->tf_special.psr & IA64_PSR_RI) > IA64_PSR_RI_2) {
885 tf->tf_special.iip += 16;
886 tf->tf_special.psr &= ~IA64_PSR_RI;
887 }
888
889 /*
890 * Copy the arguments on the register stack into the trapframe
891 * to avoid having interleaved NaT collections.
892 */
893 tfp = &tf->tf_scratch.gr16;
894 nargs = tf->tf_special.cfm & 0x7f;
895 bsp = (uint64_t*)(curthread->td_kstack + tf->tf_special.ndirty);
896 bsp -= (((uintptr_t)bsp & 0x1ff) < (nargs << 3)) ? (nargs + 1): nargs;
897 while (nargs--) {
898 *tfp++ = *bsp++;
899 if (((uintptr_t)bsp & 0x1ff) == 0x1f8)
900 bsp++;
901 }
902 error = syscall(tf);
903 if (error == ERESTART) {
904 tf->tf_special.iip = iip;
905 tf->tf_special.psr = psr;
906 }
907
908 do_ast(tf);
909}
910
911/*
762 * Process a system call.
763 *
912 * Process a system call.
913 *
764 * System calls are strange beasts. They are passed the syscall number
765 * in r15, and the arguments in the registers (as normal). They return
766 * an error flag in r10 (if r10 != 0 on return, the syscall had an error),
767 * and the return value (if any) in r8 and r9.
768 *
769 * The assembly stub takes care of moving the call number into a register
770 * we can get to, and moves all of the argument registers into a stack
771 * buffer. On return, it restores r8-r10 from the frame before
772 * returning to the user process.
914 * See syscall.s for details as to how we get here. In order to support
915 * the ERESTART case, we return the error to our caller. They deal with
916 * the hairy details.
773 */
917 */
774void
775syscall(int code, u_int64_t *args, struct trapframe *framep)
918int
919syscall(struct trapframe *tf)
776{
777 struct sysent *callp;
920{
921 struct sysent *callp;
778 struct thread *td;
779 struct proc *p;
922 struct proc *p;
780 int error = 0;
781 u_int64_t oldip, oldri;
923 struct thread *td;
924 u_int64_t *args;
925 int code, error;
782 u_int sticks;
783
926 u_int sticks;
927
784 cnt.v_syscall++;
928 code = tf->tf_scratch.gr15;
929 args = &tf->tf_scratch.gr16;
930
931 atomic_add_int(&cnt.v_syscall, 1);
932
785 td = curthread;
786 p = td->td_proc;
787
933 td = curthread;
934 p = td->td_proc;
935
788 td->td_frame = framep;
936 td->td_frame = tf;
789 sticks = td->td_sticks;
790 if (td->td_ucred != p->p_ucred)
791 cred_update_thread(td);
937 sticks = td->td_sticks;
938 if (td->td_ucred != p->p_ucred)
939 cred_update_thread(td);
792
793 /*
794 * Skip past the break instruction. Remember old address in case
795 * we have to restart.
796 */
797 oldip = framep->tf_cr_iip;
798 oldri = framep->tf_cr_ipsr & IA64_PSR_RI;
799 framep->tf_cr_ipsr += IA64_PSR_RI_1;
800 if ((framep->tf_cr_ipsr & IA64_PSR_RI) > IA64_PSR_RI_2) {
801 framep->tf_cr_ipsr &= ~IA64_PSR_RI;
802 framep->tf_cr_iip += 16;
803 }
804
805 if (p->p_flag & P_THREADED)
806 thread_user_enter(p, td);
940 if (p->p_flag & P_THREADED)
941 thread_user_enter(p, td);
807#ifdef DIAGNOSTIC
808 ia64_fpstate_check(td);
809#endif
810
811 if (p->p_sysent->sv_prepsyscall) {
942
943 if (p->p_sysent->sv_prepsyscall) {
812 /* (*p->p_sysent->sv_prepsyscall)(framep, args, &code, &params); */
944 /* (*p->p_sysent->sv_prepsyscall)(tf, args, &code, &params); */
813 panic("prepsyscall");
814 } else {
815 /*
816 * syscall() and __syscall() are handled the same on
817 * the ia64, as everything is 64-bit aligned, anyway.
818 */
819 if (code == SYS_syscall || code == SYS___syscall) {
820 /*

--- 16 unchanged lines hidden (view full) ---

837 * Try to run the syscall without Giant if the syscall is MP safe.
838 */
839 if ((callp->sy_narg & SYF_MPSAFE) == 0)
840 mtx_lock(&Giant);
841#ifdef KTRACE
842 if (KTRPOINT(td, KTR_SYSCALL))
843 ktrsyscall(code, (callp->sy_narg & SYF_ARGMASK), args);
844#endif
945 panic("prepsyscall");
946 } else {
947 /*
948 * syscall() and __syscall() are handled the same on
949 * the ia64, as everything is 64-bit aligned, anyway.
950 */
951 if (code == SYS_syscall || code == SYS___syscall) {
952 /*

--- 16 unchanged lines hidden (view full) ---

969 * Try to run the syscall without Giant if the syscall is MP safe.
970 */
971 if ((callp->sy_narg & SYF_MPSAFE) == 0)
972 mtx_lock(&Giant);
973#ifdef KTRACE
974 if (KTRPOINT(td, KTR_SYSCALL))
975 ktrsyscall(code, (callp->sy_narg & SYF_ARGMASK), args);
976#endif
845 if (error == 0) {
846 td->td_retval[0] = 0;
847 td->td_retval[1] = 0;
848
977
849 STOPEVENT(p, S_SCE, (callp->sy_narg & SYF_ARGMASK));
978 td->td_retval[0] = 0;
979 td->td_retval[1] = 0;
980 tf->tf_scratch.gr10 = EJUSTRETURN;
850
981
851 error = (*callp->sy_call)(td, args);
852 }
982 STOPEVENT(p, S_SCE, (callp->sy_narg & SYF_ARGMASK));
853
983
984 error = (*callp->sy_call)(td, args);
854
985
855 switch (error) {
856 case 0:
857 framep->tf_r[FRAME_R8] = td->td_retval[0];
858 framep->tf_r[FRAME_R9] = td->td_retval[1];
859 framep->tf_r[FRAME_R10] = 0;
860 break;
861 case ERESTART:
862 framep->tf_cr_iip = oldip;
863 framep->tf_cr_ipsr =
864 (framep->tf_cr_ipsr & ~IA64_PSR_RI) | oldri;
865 break;
866 case EJUSTRETURN:
867 break;
868 default:
869 if (p->p_sysent->sv_errsize) {
870 if (error >= p->p_sysent->sv_errsize)
871 error = -1; /* XXX */
872 else
986 if (error != EJUSTRETURN) {
987 /*
988 * Save the "raw" error code in r10. We use this to handle
989 * syscall restarts (see do_ast()).
990 */
991 tf->tf_scratch.gr10 = error;
992 if (error == 0) {
993 tf->tf_scratch.gr8 = td->td_retval[0];
994 tf->tf_scratch.gr9 = td->td_retval[1];
995 } else if (error != ERESTART) {
996 if (error < p->p_sysent->sv_errsize)
873 error = p->p_sysent->sv_errtbl[error];
997 error = p->p_sysent->sv_errtbl[error];
998 /*
999 * Translated error codes are returned in r8. User
1000 * processes use the translated error code.
1001 */
1002 tf->tf_scratch.gr8 = error;
874 }
1003 }
875 framep->tf_r[FRAME_R8] = error;
876 framep->tf_r[FRAME_R10] = 1;
877 break;
878 }
879
880 /*
881 * Release Giant if we had to get it.
882 */
883 if ((callp->sy_narg & SYF_MPSAFE) == 0)
884 mtx_unlock(&Giant);
885
1004 }
1005
1006 /*
1007 * Release Giant if we had to get it.
1008 */
1009 if ((callp->sy_narg & SYF_MPSAFE) == 0)
1010 mtx_unlock(&Giant);
1011
886 userret(td, framep, sticks);
1012 userret(td, tf, sticks);
887
888#ifdef KTRACE
889 if (KTRPOINT(td, KTR_SYSRET))
890 ktrsysret(code, error, td->td_retval[0]);
891#endif
1013
1014#ifdef KTRACE
1015 if (KTRPOINT(td, KTR_SYSRET))
1016 ktrsysret(code, error, td->td_retval[0]);
1017#endif
1018
892 /*
893 * This works because errno is findable through the
894 * register set. If we ever support an emulation where this
895 * is not the case, this code will need to be revisited.
896 */
897 STOPEVENT(p, S_SCX, code);
898
899#ifdef DIAGNOSTIC
900 cred_free_thread(td);
901#endif
1019 /*
1020 * This works because errno is findable through the
1021 * register set. If we ever support an emulation where this
1022 * is not the case, this code will need to be revisited.
1023 */
1024 STOPEVENT(p, S_SCX, code);
1025
1026#ifdef DIAGNOSTIC
1027 cred_free_thread(td);
1028#endif
1029
902 WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
903 (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
904 mtx_assert(&sched_lock, MA_NOTOWNED);
905 mtx_assert(&Giant, MA_NOTOWNED);
1030 WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
1031 (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
1032 mtx_assert(&sched_lock, MA_NOTOWNED);
1033 mtx_assert(&Giant, MA_NOTOWNED);
1034
1035 return (error);
906}
907
908#include <i386/include/psl.h>
909
910static void
911ia32_syscall(struct trapframe *framep)
912{
913 caddr_t params;

--- 14 unchanged lines hidden (view full) ---

928 * occassional inaccuracy in the count.
929 */
930 cnt.v_syscall++;
931
932 sticks = td->td_sticks;
933 td->td_frame = framep;
934 if (td->td_ucred != p->p_ucred)
935 cred_update_thread(td);
1036}
1037
1038#include <i386/include/psl.h>
1039
1040static void
1041ia32_syscall(struct trapframe *framep)
1042{
1043 caddr_t params;

--- 14 unchanged lines hidden (view full) ---

1058 * occassional inaccuracy in the count.
1059 */
1060 cnt.v_syscall++;
1061
1062 sticks = td->td_sticks;
1063 td->td_frame = framep;
1064 if (td->td_ucred != p->p_ucred)
1065 cred_update_thread(td);
936 params = (caddr_t)(framep->tf_r[FRAME_SP] & ((1L<<32)-1))
937 + sizeof(u_int32_t);
938 code = framep->tf_r[FRAME_R8]; /* eax */
1066 params = (caddr_t)(framep->tf_special.sp & ((1L<<32)-1))
1067 + sizeof(u_int32_t);
1068 code = framep->tf_scratch.gr8; /* eax */
939 orig_eflags = ia64_get_eflag();
940
941 if (p->p_sysent->sv_prepsyscall) {
942 /*
943 * The prep code is MP aware.
944 */
945 (*p->p_sysent->sv_prepsyscall)(framep, args, &code, &params);
946 } else {

--- 49 unchanged lines hidden (view full) ---

996 * Try to run the syscall without Giant if the syscall
997 * is MP safe.
998 */
999 if ((callp->sy_narg & SYF_MPSAFE) == 0)
1000 mtx_lock(&Giant);
1001
1002 if (error == 0) {
1003 td->td_retval[0] = 0;
1069 orig_eflags = ia64_get_eflag();
1070
1071 if (p->p_sysent->sv_prepsyscall) {
1072 /*
1073 * The prep code is MP aware.
1074 */
1075 (*p->p_sysent->sv_prepsyscall)(framep, args, &code, &params);
1076 } else {

--- 49 unchanged lines hidden (view full) ---

1126 * Try to run the syscall without Giant if the syscall
1127 * is MP safe.
1128 */
1129 if ((callp->sy_narg & SYF_MPSAFE) == 0)
1130 mtx_lock(&Giant);
1131
1132 if (error == 0) {
1133 td->td_retval[0] = 0;
1004 td->td_retval[1] = framep->tf_r[FRAME_R10]; /* edx */
1134 td->td_retval[1] = framep->tf_scratch.gr10; /* edx */
1005
1006 STOPEVENT(p, S_SCE, narg);
1007
1008 error = (*callp->sy_call)(td, args64);
1009 }
1010
1011 switch (error) {
1012 case 0:
1135
1136 STOPEVENT(p, S_SCE, narg);
1137
1138 error = (*callp->sy_call)(td, args64);
1139 }
1140
1141 switch (error) {
1142 case 0:
1013 framep->tf_r[FRAME_R8] = td->td_retval[0]; /* eax */
1014 framep->tf_r[FRAME_R10] = td->td_retval[1]; /* edx */
1143 framep->tf_scratch.gr8 = td->td_retval[0]; /* eax */
1144 framep->tf_scratch.gr10 = td->td_retval[1]; /* edx */
1015 ia64_set_eflag(ia64_get_eflag() & ~PSL_C);
1016 break;
1017
1018 case ERESTART:
1019 /*
1020 * Reconstruct pc, assuming lcall $X,y is 7 bytes,
1021 * int 0x80 is 2 bytes. XXX Assume int 0x80.
1022 */
1145 ia64_set_eflag(ia64_get_eflag() & ~PSL_C);
1146 break;
1147
1148 case ERESTART:
1149 /*
1150 * Reconstruct pc, assuming lcall $X,y is 7 bytes,
1151 * int 0x80 is 2 bytes. XXX Assume int 0x80.
1152 */
1023 framep->tf_cr_iip -= 2;
1153 framep->tf_special.iip -= 2;
1024 break;
1025
1026 case EJUSTRETURN:
1027 break;
1028
1029 default:
1030 if (p->p_sysent->sv_errsize) {
1031 if (error >= p->p_sysent->sv_errsize)
1032 error = -1; /* XXX */
1033 else
1034 error = p->p_sysent->sv_errtbl[error];
1035 }
1154 break;
1155
1156 case EJUSTRETURN:
1157 break;
1158
1159 default:
1160 if (p->p_sysent->sv_errsize) {
1161 if (error >= p->p_sysent->sv_errsize)
1162 error = -1; /* XXX */
1163 else
1164 error = p->p_sysent->sv_errtbl[error];
1165 }
1036 framep->tf_r[FRAME_R8] = error;
1166 framep->tf_scratch.gr8 = error;
1037 ia64_set_eflag(ia64_get_eflag() | PSL_C);
1038 break;
1039 }
1040
1041 /*
1042 * Traced syscall.
1043 */
1044 if ((orig_eflags & PSL_T) && !(orig_eflags & PSL_VM)) {

--- 35 unchanged lines hidden ---
1167 ia64_set_eflag(ia64_get_eflag() | PSL_C);
1168 break;
1169 }
1170
1171 /*
1172 * Traced syscall.
1173 */
1174 if ((orig_eflags & PSL_T) && !(orig_eflags & PSL_VM)) {

--- 35 unchanged lines hidden ---