subr_syscall.c revision 1307
1154146Stakawata/*- 2154146Stakawata * Copyright (c) 1990 The Regents of the University of California. 3154146Stakawata * All rights reserved. 4154146Stakawata * 5154146Stakawata * This code is derived from software contributed to Berkeley by 6154146Stakawata * the University of Utah, and William Jolitz. 7154146Stakawata * 8154146Stakawata * Redistribution and use in source and binary forms, with or without 9154146Stakawata * modification, are permitted provided that the following conditions 10154146Stakawata * are met: 11154146Stakawata * 1. Redistributions of source code must retain the above copyright 12154146Stakawata * notice, this list of conditions and the following disclaimer. 13154146Stakawata * 2. Redistributions in binary form must reproduce the above copyright 14154146Stakawata * notice, this list of conditions and the following disclaimer in the 15154146Stakawata * documentation and/or other materials provided with the distribution. 16154146Stakawata * 3. All advertising materials mentioning features or use of this software 17154146Stakawata * must display the following acknowledgement: 18154146Stakawata * This product includes software developed by the University of 19154146Stakawata * California, Berkeley and its contributors. 20154146Stakawata * 4. Neither the name of the University nor the names of its contributors 21154146Stakawata * may be used to endorse or promote products derived from this software 22154146Stakawata * without specific prior written permission. 23154146Stakawata * 24154146Stakawata * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25154146Stakawata * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26154146Stakawata * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27154146Stakawata * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28154146Stakawata * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29154146Stakawata * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30227750Smiwi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31154146Stakawata * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32154146Stakawata * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33154146Stakawata * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34154146Stakawata * SUCH DAMAGE. 35154146Stakawata * 36154146Stakawata * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 37164524Sbrueffer * $Id: trap.c,v 1.19 1994/03/14 21:54:03 davidg Exp $ 38164524Sbrueffer */ 39164524Sbrueffer 40164524Sbrueffer/* 41227750Smiwi * 386 Trap and System call handleing 42227750Smiwi */ 43154146Stakawata 44164524Sbrueffer#include "isa.h" 45164524Sbrueffer#include "npx.h" 46164524Sbrueffer#include "ddb.h" 47164524Sbrueffer#include "machine/cpu.h" 48164524Sbrueffer#include "machine/psl.h" 49164524Sbrueffer#include "machine/reg.h" 50164524Sbrueffer#include "machine/eflags.h" 51164524Sbrueffer 52154146Stakawata#include "param.h" 53154146Stakawata#include "systm.h" 54154146Stakawata#include "proc.h" 55154238Stakawata#include "user.h" 56154238Stakawata#include "acct.h" 57154146Stakawata#include "kernel.h" 58154238Stakawata#ifdef KTRACE 59154146Stakawata#include "ktrace.h" 60154238Stakawata#endif 61154238Stakawata 62154238Stakawata#include "vm/vm_param.h" 63162871Sru#include "vm/pmap.h" 64154146Stakawata#include "vm/vm_map.h" 65154238Stakawata#include "vm/vm_user.h" 66154238Stakawata#include "vm/vm_page.h" 67154146Stakawata#include "sys/vmmeter.h" 68154146Stakawata 69154146Stakawata#include "machine/trap.h" 70154146Stakawata 71154146Stakawata#ifdef __GNUC__ 72154146Stakawata 73154146Stakawata/* 74154146Stakawata * The "r" contraint could be "rm" except for fatal bugs in gas. As usual, 75154146Stakawata * we omit the size from the mov instruction to avoid nonfatal bugs in gas. 76162871Sru */ 77162871Sru#define read_gs() ({ u_short gs; __asm("mov %%gs,%0" : "=r" (gs)); gs; }) 78162871Sru#define write_gs(newgs) __asm("mov %0,%%gs" : : "r" ((u_short) newgs)) 79154146Stakawata 80154146Stakawata#else /* not __GNUC__ */ 81154238Stakawata 82154146Stakawatau_short read_gs __P((void)); 83154146Stakawatavoid write_gs __P((/* promoted u_short */ int gs)); 84154146Stakawata 85154146Stakawata#endif /* __GNUC__ */ 86154146Stakawata 87154238Stakawataextern int grow(struct proc *,int); 88154146Stakawata 89162871Srustruct sysent sysent[]; 90154146Stakawataint nsysent; 91162871Sruextern unsigned cpl; 92154146Stakawataextern unsigned netmask, ttymask, biomask; 93162871Sru 94154146Stakawata#define MAX_TRAP_MSG 27 95162871Sruchar *trap_msg[] = { 96162871Sru "reserved addressing fault", /* 0 T_RESADFLT */ 97162871Sru "privileged instruction fault", /* 1 T_PRIVINFLT */ 98162871Sru "reserved operand fault", /* 2 T_RESOPFLT */ 99162871Sru "breakpoint instruction fault", /* 3 T_BPTFLT */ 100162871Sru "", /* 4 unused */ 101162871Sru "system call trap", /* 5 T_SYSCALL */ 102233648Seadler "arithmetic trap", /* 6 T_ARITHTRAP */ 103154146Stakawata "system forced exception", /* 7 T_ASTFLT */ 104154146Stakawata "segmentation (limit) fault", /* 8 T_SEGFLT */ 105154146Stakawata "protection fault", /* 9 T_PROTFLT */ 106154146Stakawata "trace trap", /* 10 T_TRCTRAP */ 107154146Stakawata "", /* 11 unused */ 108154146Stakawata "page fault", /* 12 T_PAGEFLT */ 109154146Stakawata "page table fault", /* 13 T_TABLEFLT */ 110154146Stakawata "alignment fault", /* 14 T_ALIGNFLT */ 111154146Stakawata "kernel stack pointer not valid", /* 15 T_KSPNOTVAL */ 112154146Stakawata "bus error", /* 16 T_BUSERR */ 113154223Stakawata "kernel debugger fault", /* 17 T_KDBTRAP */ 114154223Stakawata "integer divide fault", /* 18 T_DIVIDE */ 115154146Stakawata "non-maskable interrupt trap", /* 19 T_NMI */ 116154146Stakawata "overflow trap", /* 20 T_OFLOW */ 117162871Sru "FPU bounds check fault", /* 21 T_BOUND */ 118154148Stakawata "FPU device not available", /* 22 T_DNA */ 119162871Sru "double fault", /* 23 T_DOUBLEFLT */ 120162871Sru "FPU operand fetch fault", /* 24 T_FPOPFLT */ 121162871Sru "invalid TSS fault", /* 25 T_TSSFLT */ 122162871Sru "segment not present fault", /* 26 T_SEGNPFLT */ 123162871Sru "stack fault", /* 27 T_STKFLT */ 124162871Sru}; 125154148Stakawata 126154146Stakawata#define pde_v(v) (PTD[((v)>>PD_SHIFT)&1023].pd_v) 127154146Stakawata 128154146Stakawata/* 129154146Stakawata * trap(frame): 130154146Stakawata * Exception, fault, and trap interface to BSD kernel. This 131154146Stakawata * common code is called from assembly language IDT gate entry 132154146Stakawata * routines that prepare a suitable stack frame, and restore this 133154146Stakawata * frame after the exception has been processed. Note that the 134154146Stakawata * effect is as if the arguments were passed call by reference. 135162871Sru */ 136162871Sru 137154146Stakawata/*ARGSUSED*/ 138154146Stakawatavoid 139154146Stakawatatrap(frame) 140154146Stakawata struct trapframe frame; 141154146Stakawata{ 142 register int i; 143 register struct proc *p = curproc; 144 struct timeval syst; 145 int ucode, type, code, eva, fault_type; 146 147 frame.tf_eflags &= ~PSL_NT; /* clear nested trap XXX */ 148 type = frame.tf_trapno; 149#if NDDB > 0 150 if (curpcb && curpcb->pcb_onfault) { 151 if (frame.tf_trapno == T_BPTFLT 152 || frame.tf_trapno == T_TRCTRAP) 153 if (kdb_trap (type, 0, &frame)) 154 return; 155 } 156#endif 157 158 if (curpcb == 0 || curproc == 0) 159 goto skiptoswitch; 160 if (curpcb->pcb_onfault && frame.tf_trapno != T_PAGEFLT) { 161 extern int _udatasel; 162 163 if (read_gs() != (u_short) _udatasel) 164 /* 165 * Some user has corrupted %gs but we depend on it in 166 * copyout() etc. Fix it up and retry. 167 * 168 * (We don't preserve %fs or %gs, so users can change 169 * them to either _ucodesel, _udatasel or a not-present 170 * selector, possibly ORed with 0 to 3, making them 171 * volatile for other users. Not preserving them saves 172 * time and doesn't lose functionality or open security 173 * holes.) 174 */ 175 write_gs(_udatasel); 176 else 177copyfault: 178 frame.tf_eip = (int)curpcb->pcb_onfault; 179 return; 180 } 181 182 syst = p->p_stime; 183 if (ISPL(frame.tf_cs) == SEL_UPL) { 184 type |= T_USER; 185 p->p_regs = (int *)&frame; 186 } 187 188skiptoswitch: 189 ucode=0; 190 eva = rcr2(); 191 code = frame.tf_err; 192 193 if ((type & ~T_USER) == T_PAGEFLT) 194 goto pfault; 195 196 switch (type) { 197 case T_SEGNPFLT|T_USER: 198 case T_STKFLT|T_USER: 199 case T_PROTFLT|T_USER: /* protection fault */ 200 ucode = code + BUS_SEGM_FAULT ; 201 i = SIGBUS; 202 break; 203 204 case T_PRIVINFLT|T_USER: /* privileged instruction fault */ 205 case T_RESADFLT|T_USER: /* reserved addressing fault */ 206 case T_RESOPFLT|T_USER: /* reserved operand fault */ 207 case T_FPOPFLT|T_USER: /* coprocessor operand fault */ 208 ucode = type &~ T_USER; 209 i = SIGILL; 210 break; 211 212 case T_ASTFLT|T_USER: /* Allow process switch */ 213 astoff(); 214 cnt.v_soft++; 215 if ((p->p_flag & SOWEUPC) && p->p_stats->p_prof.pr_scale) { 216 addupc(frame.tf_eip, &p->p_stats->p_prof, 1); 217 p->p_flag &= ~SOWEUPC; 218 } 219 goto out; 220 221 case T_DNA|T_USER: 222#if NNPX > 0 223 /* if a transparent fault (due to context switch "late") */ 224 if (npxdna()) return; 225#endif /* NNPX > 0 */ 226#ifdef MATH_EMULATE 227 i = math_emulate(&frame); 228 if (i == 0) return; 229#else /* MATH_EMULTATE */ 230 panic("trap: math emulation necessary!"); 231#endif /* MATH_EMULTATE */ 232 ucode = FPE_FPU_NP_TRAP; 233 break; 234 235 case T_BOUND|T_USER: 236 ucode = FPE_SUBRNG_TRAP; 237 i = SIGFPE; 238 break; 239 240 case T_OFLOW|T_USER: 241 ucode = FPE_INTOVF_TRAP; 242 i = SIGFPE; 243 break; 244 245 case T_DIVIDE|T_USER: 246 ucode = FPE_INTDIV_TRAP; 247 i = SIGFPE; 248 break; 249 250 case T_ARITHTRAP|T_USER: 251 ucode = code; 252 i = SIGFPE; 253 break; 254 255 pfault: 256 case T_PAGEFLT: /* allow page faults in kernel mode */ 257 case T_PAGEFLT|T_USER: /* page fault */ 258 { 259 vm_offset_t va; 260 struct vmspace *vm; 261 vm_map_t map = 0; 262 int rv = 0, oldflags; 263 vm_prot_t ftype; 264 unsigned nss, v; 265 extern vm_map_t kernel_map; 266 267 va = trunc_page((vm_offset_t)eva); 268 269 /* 270 * Don't allow user-mode faults in kernel address space 271 */ 272 if ((type == (T_PAGEFLT|T_USER)) && (va >= KERNBASE)) { 273 goto nogo; 274 } 275 276 if ((p == 0) || (type == T_PAGEFLT && va >= KERNBASE)) { 277 vm = 0; 278 map = kernel_map; 279 } else { 280 vm = p->p_vmspace; 281 map = &vm->vm_map; 282 } 283 284 if (code & PGEX_W) 285 ftype = VM_PROT_READ | VM_PROT_WRITE; 286 else 287 ftype = VM_PROT_READ; 288 289 oldflags = p->p_flag; 290 if (map != kernel_map) { 291 vm_offset_t pa; 292 vm_offset_t v = (vm_offset_t) vtopte(va); 293 vm_page_t ptepg; 294 295 /* 296 * Keep swapout from messing with us during this 297 * critical time. 298 */ 299 p->p_flag |= SLOCK; 300 301 /* 302 * Grow the stack if necessary 303 */ 304 if ((caddr_t)va > vm->vm_maxsaddr 305 && (caddr_t)va < (caddr_t)USRSTACK) { 306 if (!grow(p, va)) { 307 rv = KERN_FAILURE; 308 p->p_flag &= ~SLOCK; 309 p->p_flag |= (oldflags & SLOCK); 310 goto nogo; 311 } 312 } 313 314 /* 315 * Check if page table is mapped, if not, 316 * fault it first 317 */ 318 319 /* Fault the pte only if needed: */ 320 *(volatile char *)v += 0; 321 322 ptepg = (vm_page_t) pmap_pte_vm_page(vm_map_pmap(map), v); 323 vm_page_hold(ptepg); 324 325 /* Fault in the user page: */ 326 rv = vm_fault(map, va, ftype, FALSE); 327 328 vm_page_unhold(ptepg); 329 330 /* 331 * page table pages don't need to be kept if they 332 * are not held 333 */ 334 if( ptepg->hold_count == 0 && ptepg->wire_count == 0) { 335 pmap_page_protect( VM_PAGE_TO_PHYS(ptepg), 336 VM_PROT_NONE); 337 if( ptepg->flags & PG_CLEAN) 338 vm_page_free(ptepg); 339 } 340 341 342 p->p_flag &= ~SLOCK; 343 p->p_flag |= (oldflags & SLOCK); 344 } else { 345 /* 346 * Since we know that kernel virtual address addresses 347 * always have pte pages mapped, we just have to fault 348 * the page. 349 */ 350 rv = vm_fault(map, va, ftype, FALSE); 351 } 352 353 if (rv == KERN_SUCCESS) { 354 if (type == T_PAGEFLT) 355 return; 356 goto out; 357 } 358nogo: 359 if (type == T_PAGEFLT) { 360 if (curpcb->pcb_onfault) 361 goto copyfault; 362 363 goto we_re_toast; 364 } 365 i = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV; 366 367 /* kludge to pass faulting virtual address to sendsig */ 368 ucode = type &~ T_USER; 369 frame.tf_err = eva; 370 371 break; 372 } 373 374#if NDDB == 0 375 case T_TRCTRAP: /* trace trap -- someone single stepping lcall's */ 376 frame.tf_eflags &= ~PSL_T; 377 378 /* Q: how do we turn it on again? */ 379 return; 380#endif 381 382 case T_BPTFLT|T_USER: /* bpt instruction fault */ 383 case T_TRCTRAP|T_USER: /* trace trap */ 384 frame.tf_eflags &= ~PSL_T; 385 i = SIGTRAP; 386 break; 387 388#if NISA > 0 389 case T_NMI: 390 case T_NMI|T_USER: 391#if NDDB > 0 392 /* NMI can be hooked up to a pushbutton for debugging */ 393 printf ("NMI ... going to debugger\n"); 394 if (kdb_trap (type, 0, &frame)) 395 return; 396#endif 397 /* machine/parity/power fail/"kitchen sink" faults */ 398 if (isa_nmi(code) == 0) return; 399 /* FALL THROUGH */ 400#endif 401 default: 402 we_re_toast: 403 404 fault_type = type & ~T_USER; 405 if (fault_type <= MAX_TRAP_MSG) 406 printf("\n\nFatal trap %d: %s while in %s mode\n", 407 fault_type, trap_msg[fault_type], 408 ISPL(frame.tf_cs) == SEL_UPL ? "user" : "kernel"); 409 if (fault_type == T_PAGEFLT) { 410 printf("fault virtual address = 0x%x\n", eva); 411 printf("fault code = %s %s, %s\n", 412 code & PGEX_U ? "user" : "supervisor", 413 code & PGEX_W ? "write" : "read", 414 code & PGEX_P ? "protection violation" : "page not present"); 415 } 416 printf("instruction pointer = 0x%x\n", frame.tf_eip); 417 printf("processor eflags = "); 418 if (frame.tf_eflags & EFL_TF) 419 printf("trace/trap, "); 420 if (frame.tf_eflags & EFL_IF) 421 printf("interrupt enabled, "); 422 if (frame.tf_eflags & EFL_NT) 423 printf("nested task, "); 424 if (frame.tf_eflags & EFL_RF) 425 printf("resume, "); 426 if (frame.tf_eflags & EFL_VM) 427 printf("vm86, "); 428 printf("IOPL = %d\n", (frame.tf_eflags & EFL_IOPL) >> 12); 429 printf("current process = "); 430 if (curproc) { 431 printf("%d (%s)\n", 432 curproc->p_pid, curproc->p_comm ? 433 curproc->p_comm : ""); 434 } else { 435 printf("Idle\n"); 436 } 437 printf("interrupt mask = "); 438 if ((cpl & netmask) == netmask) 439 printf("net "); 440 if ((cpl & ttymask) == ttymask) 441 printf("tty "); 442 if ((cpl & biomask) == biomask) 443 printf("bio "); 444 if (cpl == 0) 445 printf("none"); 446 printf("\n"); 447 448#ifdef KDB 449 if (kdb_trap(&psl)) 450 return; 451#endif 452#if NDDB > 0 453 if (kdb_trap (type, 0, &frame)) 454 return; 455#endif 456 if (fault_type <= MAX_TRAP_MSG) 457 panic(trap_msg[fault_type]); 458 else 459 panic("unknown/reserved trap"); 460 461 /* NOTREACHED */ 462 } 463 464 trapsignal(p, i, ucode); 465 if ((type & T_USER) == 0) 466 return; 467out: 468 while (i = CURSIG(p)) 469 psig(i); 470 p->p_pri = p->p_usrpri; 471 if (want_resched) { 472 int s; 473 /* 474 * Since we are curproc, clock will normally just change 475 * our priority without moving us from one queue to another 476 * (since the running process is not on a queue.) 477 * If that happened after we setrq ourselves but before we 478 * swtch()'ed, we might not be on the queue indicated by 479 * our priority. 480 */ 481 s = splclock(); 482 setrq(p); 483 p->p_stats->p_ru.ru_nivcsw++; 484 swtch(); 485 splx(s); 486 while (i = CURSIG(p)) 487 psig(i); 488 } 489 if (p->p_stats->p_prof.pr_scale) { 490 int ticks; 491 struct timeval *tv = &p->p_stime; 492 493 ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + 494 (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); 495 if (ticks) { 496#ifdef PROFTIMER 497 extern int profscale; 498 addupc(frame.tf_eip, &p->p_stats->p_prof, 499 ticks * profscale); 500#else 501 addupc(frame.tf_eip, &p->p_stats->p_prof, ticks); 502#endif 503 } 504 } 505 curpri = p->p_pri; 506} 507 508/* 509 * Compensate for 386 brain damage (missing URKR). 510 * This is a little simpler than the pagefault handler in trap() because 511 * it the page tables have already been faulted in and high addresses 512 * are thrown out early for other reasons. 513 */ 514int trapwrite(addr) 515 unsigned addr; 516{ 517 unsigned nss; 518 struct proc *p; 519 vm_offset_t va, v; 520 struct vmspace *vm; 521 int oldflags; 522 int rv; 523 524 va = trunc_page((vm_offset_t)addr); 525 /* 526 * XXX - MAX is END. Changed > to >= for temp. fix. 527 */ 528 if (va >= VM_MAXUSER_ADDRESS) 529 return (1); 530 531 p = curproc; 532 vm = p->p_vmspace; 533 534 oldflags = p->p_flag; 535 p->p_flag |= SLOCK; 536 537 if ((caddr_t)va >= vm->vm_maxsaddr 538 && (caddr_t)va < (caddr_t)USRSTACK) { 539 if (!grow(p, va)) { 540 p->p_flag &= ~SLOCK; 541 p->p_flag |= (oldflags & SLOCK); 542 return (1); 543 } 544 } 545 546 v = trunc_page(vtopte(va)); 547 548 /* 549 * wire the pte page 550 */ 551 if (va < USRSTACK) { 552 vm_map_pageable(&vm->vm_map, v, round_page(v+1), FALSE); 553 } 554 555 /* 556 * fault the data page 557 */ 558 rv = vm_fault(&vm->vm_map, va, VM_PROT_READ|VM_PROT_WRITE, FALSE); 559 560 /* 561 * unwire the pte page 562 */ 563 if (va < USRSTACK) { 564 vm_map_pageable(&vm->vm_map, v, round_page(v+1), TRUE); 565 } 566 567 p->p_flag &= ~SLOCK; 568 p->p_flag |= (oldflags & SLOCK); 569 570 if (rv != KERN_SUCCESS) 571 return 1; 572 573 return (0); 574} 575 576/* 577 * syscall(frame): 578 * System call request from POSIX system call gate interface to kernel. 579 * Like trap(), argument is call by reference. 580 */ 581/*ARGSUSED*/ 582void 583syscall(frame) 584 volatile struct trapframe frame; 585{ 586 register int *locr0 = ((int *)&frame); 587 register caddr_t params; 588 register int i; 589 register struct sysent *callp; 590 register struct proc *p = curproc; 591 struct timeval syst; 592 int error, opc; 593 int args[8], rval[2]; 594 int code; 595 596#ifdef lint 597 r0 = 0; r0 = r0; r1 = 0; r1 = r1; 598#endif 599 syst = p->p_stime; 600 if (ISPL(frame.tf_cs) != SEL_UPL) 601 panic("syscall"); 602 603 code = frame.tf_eax; 604 p->p_regs = (int *)&frame; 605 params = (caddr_t)frame.tf_esp + sizeof (int) ; 606 607 /* 608 * Reconstruct pc, assuming lcall $X,y is 7 bytes, as it is always. 609 */ 610 opc = frame.tf_eip - 7; 611 if (code == 0) { 612 code = fuword(params); 613 params += sizeof (int); 614 } 615 if (code < 0 || code >= nsysent) 616 callp = &sysent[0]; 617 else 618 callp = &sysent[code]; 619 620 if ((i = callp->sy_narg * sizeof (int)) && 621 (error = copyin(params, (caddr_t)args, (u_int)i))) { 622 frame.tf_eax = error; 623 frame.tf_eflags |= PSL_C; /* carry bit */ 624#ifdef KTRACE 625 if (KTRPOINT(p, KTR_SYSCALL)) 626 ktrsyscall(p->p_tracep, code, callp->sy_narg, args); 627#endif 628 goto done; 629 } 630#ifdef KTRACE 631 if (KTRPOINT(p, KTR_SYSCALL)) 632 ktrsyscall(p->p_tracep, code, callp->sy_narg, args); 633#endif 634 rval[0] = 0; 635 rval[1] = frame.tf_edx; 636/*pg("%d. s %d\n", p->p_pid, code);*/ 637 error = (*callp->sy_call)(p, args, rval); 638 if (error == ERESTART) 639 frame.tf_eip = opc; 640 else if (error != EJUSTRETURN) { 641 if (error) { 642/*pg("error %d", error);*/ 643 frame.tf_eax = error; 644 frame.tf_eflags |= PSL_C; /* carry bit */ 645 } else { 646 frame.tf_eax = rval[0]; 647 frame.tf_edx = rval[1]; 648 frame.tf_eflags &= ~PSL_C; /* carry bit */ 649 } 650 } 651 /* else if (error == EJUSTRETURN) */ 652 /* nothing to do */ 653done: 654 /* 655 * Reinitialize proc pointer `p' as it may be different 656 * if this is a child returning from fork syscall. 657 */ 658 p = curproc; 659 while (i = CURSIG(p)) 660 psig(i); 661 p->p_pri = p->p_usrpri; 662 if (want_resched) { 663 int s; 664 /* 665 * Since we are curproc, clock will normally just change 666 * our priority without moving us from one queue to another 667 * (since the running process is not on a queue.) 668 * If that happened after we setrq ourselves but before we 669 * swtch()'ed, we might not be on the queue indicated by 670 * our priority. 671 */ 672 s = splclock(); 673 setrq(p); 674 p->p_stats->p_ru.ru_nivcsw++; 675 swtch(); 676 splx(s); 677 while (i = CURSIG(p)) 678 psig(i); 679 } 680 if (p->p_stats->p_prof.pr_scale) { 681 int ticks; 682 struct timeval *tv = &p->p_stime; 683 684 ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + 685 (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); 686 if (ticks) { 687#ifdef PROFTIMER 688 extern int profscale; 689 addupc(frame.tf_eip, &p->p_stats->p_prof, 690 ticks * profscale); 691#else 692 addupc(frame.tf_eip, &p->p_stats->p_prof, ticks); 693#endif 694 } 695 } 696 curpri = p->p_pri; 697#ifdef KTRACE 698 if (KTRPOINT(p, KTR_SYSRET)) 699 ktrsysret(p->p_tracep, code, error, rval[0]); 700#endif 701#ifdef DIAGNOSTICx 702{ extern int _udatasel, _ucodesel; 703 if (frame.tf_ss != _udatasel) 704 printf("ss %x call %d\n", frame.tf_ss, code); 705 if ((frame.tf_cs&0xffff) != _ucodesel) 706 printf("cs %x call %d\n", frame.tf_cs, code); 707 if (frame.tf_eip > VM_MAXUSER_ADDRESS) { 708 printf("eip %x call %d\n", frame.tf_eip, code); 709 frame.tf_eip = 0; 710 } 711} 712#endif 713} 714