subr_syscall.c revision 200
167754Smsmith/*- 267754Smsmith * Copyright (c) 1990 The Regents of the University of California. 367754Smsmith * All rights reserved. 470243Smsmith * 567754Smsmith * This code is derived from software contributed to Berkeley by 667754Smsmith * the University of Utah, and William Jolitz. 767754Smsmith * 867754Smsmith * Redistribution and use in source and binary forms, with or without 967754Smsmith * modification, are permitted provided that the following conditions 1067754Smsmith * are met: 1167754Smsmith * 1. Redistributions of source code must retain the above copyright 12193267Sjkim * notice, this list of conditions and the following disclaimer. 1370243Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1467754Smsmith * notice, this list of conditions and the following disclaimer in the 1567754Smsmith * documentation and/or other materials provided with the distribution. 1667754Smsmith * 3. All advertising materials mentioning features or use of this software 1767754Smsmith * must display the following acknowledgement: 1867754Smsmith * This product includes software developed by the University of 1967754Smsmith * California, Berkeley and its contributors. 2067754Smsmith * 4. Neither the name of the University nor the names of its contributors 2167754Smsmith * may be used to endorse or promote products derived from this software 2267754Smsmith * without specific prior written permission. 2367754Smsmith * 2467754Smsmith * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2567754Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2667754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2767754Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2867754Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2967754Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3067754Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3167754Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3267754Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3367754Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3467754Smsmith * SUCH DAMAGE. 3567754Smsmith * 3667754Smsmith * @(#)trap.c 7.4 (Berkeley) 5/13/91 3767754Smsmith * 3867754Smsmith * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE 3967754Smsmith * -------------------- ----- ---------------------- 4067754Smsmith * CURRENT PATCH LEVEL: 1 00137 4167754Smsmith * -------------------- ----- ---------------------- 4267754Smsmith * 4367754Smsmith * 08 Apr 93 Bruce Evans Several VM system fixes 4467754Smsmith * Paul Kranenburg Add counter for vmstat 4567754Smsmith */ 4667754Smsmithstatic char rcsid[] = "$Header: /a/cvs/386BSD/src/sys/i386/i386/trap.c,v 1.1.1.1 1993/06/12 14:58:05 rgrimes Exp $"; 4767754Smsmith 4867754Smsmith/* 4967754Smsmith * 386 Trap and System call handleing 5067754Smsmith */ 5167754Smsmith 5267754Smsmith#include "machine/cpu.h" 5367754Smsmith#include "machine/psl.h" 5467754Smsmith#include "machine/reg.h" 5567754Smsmith 5667754Smsmith#include "param.h" 5767754Smsmith#include "systm.h" 5867754Smsmith#include "proc.h" 5967754Smsmith#include "user.h" 6067754Smsmith#include "acct.h" 6167754Smsmith#include "kernel.h" 6267754Smsmith#ifdef KTRACE 6367754Smsmith#include "ktrace.h" 6467754Smsmith#endif 6567754Smsmith 6667754Smsmith#include "vm/vm_param.h" 6767754Smsmith#include "vm/pmap.h" 6867754Smsmith#include "vm/vm_map.h" 6967754Smsmith#include "sys/vmmeter.h" 7067754Smsmith 7167754Smsmith#include "machine/trap.h" 7267754Smsmith 7367754Smsmith#ifdef __GNUC__ 7467754Smsmith 7567754Smsmith/* 7667754Smsmith * The "r" contraint could be "rm" except for fatal bugs in gas. As usual, 7767754Smsmith * we omit the size from the mov instruction to avoid nonfatal bugs in gas. 7867754Smsmith */ 7967754Smsmith#define read_gs() ({ u_short gs; __asm("mov %%gs,%0" : "=r" (gs)); gs; }) 8067754Smsmith#define write_gs(gs) __asm("mov %0,%%gs" : : "r" ((u_short) gs)) 8167754Smsmith 8267754Smsmith#else /* not __GNUC__ */ 8367754Smsmith 8467754Smsmithu_short read_gs __P((void)); 8567754Smsmithvoid write_gs __P((/* promoted u_short */ int gs)); 8667754Smsmith 8767754Smsmith#endif /* __GNUC__ */ 8867754Smsmith 8967754Smsmithstruct sysent sysent[]; 9067754Smsmithint nsysent; 9167754Smsmithint dostacklimits; 9267754Smsmithunsigned rcr2(); 9367754Smsmithextern short cpl; 9467754Smsmith 9567754Smsmith 9667754Smsmith/* 9767754Smsmith * trap(frame): 9867754Smsmith * Exception, fault, and trap interface to BSD kernel. This 9967754Smsmith * common code is called from assembly language IDT gate entry 10067754Smsmith * routines that prepare a suitable stack frame, and restore this 10167754Smsmith * frame after the exception has been processed. Note that the 10267754Smsmith * effect is as if the arguments were passed call by reference. 10367754Smsmith */ 10467754Smsmith 10567754Smsmith/*ARGSUSED*/ 10667754Smsmithtrap(frame) 10767754Smsmith struct trapframe frame; 10867754Smsmith{ 10967754Smsmith register int i; 11067754Smsmith register struct proc *p = curproc; 11167754Smsmith struct timeval syst; 11267754Smsmith int ucode, type, code, eva; 11367754Smsmith 11467754Smsmith frame.tf_eflags &= ~PSL_NT; /* clear nested trap XXX */ 11567754Smsmith type = frame.tf_trapno; 11667754Smsmith#include "ddb.h" 11767754Smsmith#if NDDB > 0 11867754Smsmith if (curpcb && curpcb->pcb_onfault) { 11967754Smsmith if (frame.tf_trapno == T_BPTFLT 12067754Smsmith || frame.tf_trapno == T_TRCTRAP) 121193267Sjkim if (kdb_trap (type, 0, &frame)) 122193267Sjkim return; 123193267Sjkim } 124193267Sjkim#endif 125193251Sjkim 126193251Sjkim/*pg("trap type %d code = %x eip = %x cs = %x eva = %x esp %x", 12767754Smsmith frame.tf_trapno, frame.tf_err, frame.tf_eip, 128193267Sjkim frame.tf_cs, rcr2(), frame.tf_esp);*/ 129193267Sjkimif(curpcb == 0 || curproc == 0) goto we_re_toast; 130193267Sjkim if (curpcb->pcb_onfault && frame.tf_trapno != T_PAGEFLT) { 131193267Sjkim extern int _udatasel; 132193267Sjkim 13377424Smsmith if (read_gs() != (u_short) _udatasel) 134193267Sjkim /* 135193267Sjkim * Some user has corrupted %gs but we depend on it in 136193267Sjkim * copyout() etc. Fix it up and retry. 137193267Sjkim * 138193267Sjkim * (We don't preserve %fs or %gs, so users can change 139193267Sjkim * them to either _ucodesel, _udatasel or a not-present 140193267Sjkim * selector, possibly ORed with 0 to 3, making them 141193267Sjkim * volatile for other users. Not preserving them saves 142193267Sjkim * time and doesn't lose functionality or open security 143193267Sjkim * holes.) 144193267Sjkim */ 145193267Sjkim write_gs(_udatasel); 146193267Sjkim else 147193267Sjkimcopyfault: 148193267Sjkim frame.tf_eip = (int)curpcb->pcb_onfault; 149193267Sjkim return; 150151937Sjkim } 15167754Smsmith 15267754Smsmith syst = p->p_stime; 15367754Smsmith if (ISPL(frame.tf_cs) == SEL_UPL) { 154167802Sjkim type |= T_USER; 155167802Sjkim p->p_regs = (int *)&frame; 156167802Sjkim curpcb->pcb_flags |= FM_TRAP; /* used by sendsig */ 157167802Sjkim } 158167802Sjkim 159167802Sjkim ucode=0; 16067754Smsmith eva = rcr2(); 16167754Smsmith code = frame.tf_err; 16267754Smsmith switch (type) { 16367754Smsmith 16467754Smsmith default: 16567754Smsmith we_re_toast: 16667754Smsmith#ifdef KDB 16767754Smsmith if (kdb_trap(&psl)) 168100966Siwasaki return; 169100966Siwasaki#endif 170100966Siwasaki#if NDDB > 0 171100966Siwasaki if (kdb_trap (type, 0, &frame)) 17267754Smsmith return; 17367754Smsmith#endif 17467754Smsmith 17567754Smsmith printf("trap type %d code = %x eip = %x cs = %x eflags = %x ", 17680062Smsmith frame.tf_trapno, frame.tf_err, frame.tf_eip, 17780062Smsmith frame.tf_cs, frame.tf_eflags); 17880062Smsmith eva = rcr2(); 17980062Smsmith printf("cr2 %x cpl %x\n", eva, cpl); 18067754Smsmith /* type &= ~T_USER; */ /* XXX what the hell is this */ 18167754Smsmith panic("trap"); 18267754Smsmith /*NOTREACHED*/ 18367754Smsmith 18467754Smsmith case T_SEGNPFLT|T_USER: 18567754Smsmith case T_STKFLT|T_USER: 18667754Smsmith case T_PROTFLT|T_USER: /* protection fault */ 18767754Smsmith ucode = code + BUS_SEGM_FAULT ; 18880062Smsmith i = SIGBUS; 18967754Smsmith break; 19067754Smsmith 191193267Sjkim case T_PRIVINFLT|T_USER: /* privileged instruction fault */ 192193267Sjkim case T_RESADFLT|T_USER: /* reserved addressing fault */ 193193267Sjkim case T_RESOPFLT|T_USER: /* reserved operand fault */ 194193267Sjkim case T_FPOPFLT|T_USER: /* coprocessor operand fault */ 19580062Smsmith ucode = type &~ T_USER; 19667754Smsmith i = SIGILL; 19780062Smsmith break; 19867754Smsmith 19987031Smsmith case T_ASTFLT|T_USER: /* Allow process switch */ 20087031Smsmith astoff(); 20187031Smsmith cnt.v_soft++; 20267754Smsmith if ((p->p_flag & SOWEUPC) && p->p_stats->p_prof.pr_scale) { 20387031Smsmith addupc(frame.tf_eip, &p->p_stats->p_prof, 1); 20467754Smsmith p->p_flag &= ~SOWEUPC; 205151937Sjkim } 20677424Smsmith goto out; 20777424Smsmith 20877424Smsmith case T_DNA|T_USER: 20977424Smsmith#ifdef NPX 21077424Smsmith /* if a transparent fault (due to context switch "late") */ 21177424Smsmith if (npxdna()) return; 21277424Smsmith#endif 21377424Smsmith i = math_emulate(&frame); 21477424Smsmith if (i == 0) return; 21577424Smsmith ucode = FPE_FPU_NP_TRAP; 21677424Smsmith break; 21777424Smsmith 21877424Smsmith case T_BOUND|T_USER: 21977424Smsmith ucode = FPE_SUBRNG_TRAP; 22077424Smsmith i = SIGFPE; 22167754Smsmith break; 22267754Smsmith 22367754Smsmith case T_OFLOW|T_USER: 224167802Sjkim ucode = FPE_INTOVF_TRAP; 225167802Sjkim i = SIGFPE; 226167802Sjkim break; 227167802Sjkim 22867754Smsmith case T_DIVIDE|T_USER: 229193267Sjkim ucode = FPE_INTDIV_TRAP; 23067754Smsmith i = SIGFPE; 23167754Smsmith break; 23267754Smsmith 23380062Smsmith case T_ARITHTRAP|T_USER: 23467754Smsmith ucode = code; 23567754Smsmith i = SIGFPE; 23667754Smsmith break; 237167802Sjkim 238193267Sjkim case T_PAGEFLT: /* allow page faults in kernel mode */ 23967754Smsmith#if 0 24067754Smsmith /* XXX - check only applies to 386's and 486's with WP off */ 24167754Smsmith if (code & PGEX_P) goto we_re_toast; 24267754Smsmith#endif 243167802Sjkim 244193267Sjkim /* fall into */ 245167802Sjkim case T_PAGEFLT|T_USER: /* page fault */ 24667754Smsmith { 24778986Smsmith register vm_offset_t va; 248167802Sjkim register struct vmspace *vm = p->p_vmspace; 249193267Sjkim register vm_map_t map; 250167802Sjkim int rv; 25167754Smsmith vm_prot_t ftype; 252193267Sjkim extern vm_map_t kernel_map; 253193267Sjkim unsigned nss,v; 254193267Sjkim 255193267Sjkim va = trunc_page((vm_offset_t)eva); 25678986Smsmith /* 257193267Sjkim * Avoid even looking at pde_v(va) for high va's. va's 258193267Sjkim * above VM_MAX_KERNEL_ADDRESS don't correspond to normal 259193267Sjkim * PDE's (half of them correspond to APDEpde and half to 260193267Sjkim * an unmapped kernel PDE). va's betweeen 0xFEC00000 and 261193267Sjkim * VM_MAX_KERNEL_ADDRESS correspond to unmapped kernel PDE's 26267754Smsmith * (XXX - why are only 3 initialized when 6 are required to 26367754Smsmith * reach VM_MAX_KERNEL_ADDRESS?). Faulting in an unmapped 26467754Smsmith * kernel page table would give inconsistent PTD's. 26567754Smsmith * 26667754Smsmith * XXX - faulting in unmapped page tables wastes a page if 26767754Smsmith * va turns out to be invalid. 26867754Smsmith * 26967754Smsmith * XXX - should "kernel address space" cover the kernel page 27077424Smsmith * tables? Might have same problem with PDEpde as with 27167754Smsmith * APDEpde (or there may be no problem with APDEpde). 272114237Snjl */ 27367754Smsmith if (va > 0xFEBFF000) { 27467754Smsmith rv = KERN_FAILURE; /* becomes SIGBUS */ 27567754Smsmith goto nogo; 276114237Snjl } 27777424Smsmith /* 27867754Smsmith * It is only a kernel address space fault iff: 27967754Smsmith * 1. (type & T_USER) == 0 and 28067754Smsmith * 2. pcb_onfault not set or 28167754Smsmith * 3. pcb_onfault set but supervisor space fault 28267754Smsmith * The last can occur during an exec() copyin where the 28367754Smsmith * argument space is lazy-allocated. 28467754Smsmith */ 28567754Smsmith if (type == T_PAGEFLT && va >= KERNBASE) 28667754Smsmith map = kernel_map; 28767754Smsmith else 28867754Smsmith map = &vm->vm_map; 28967754Smsmith if (code & PGEX_W) 29067754Smsmith ftype = VM_PROT_READ | VM_PROT_WRITE; 29167754Smsmith else 29267754Smsmith ftype = VM_PROT_READ; 29387031Smsmith 29487031Smsmith#ifdef DEBUG 29587031Smsmith if (map == kernel_map && va == 0) { 29687031Smsmith printf("trap: bad kernel access at %x\n", va); 29787031Smsmith goto we_re_toast; 29867754Smsmith } 29987031Smsmith#endif 30087031Smsmith 30187031Smsmith /* 30287031Smsmith * XXX: rude hack to make stack limits "work" 30387031Smsmith */ 30487031Smsmith nss = 0; 30587031Smsmith if ((caddr_t)va >= vm->vm_maxsaddr && map != kernel_map 30687031Smsmith && dostacklimits) { 30787031Smsmith nss = clrnd(btoc((unsigned)vm->vm_maxsaddr 30887031Smsmith + MAXSSIZ - (unsigned)va)); 30987031Smsmith if (nss > btoc(p->p_rlimit[RLIMIT_STACK].rlim_cur)) { 310151937Sjkim/*pg("trap rlimit %d, maxsaddr %x va %x ", nss, vm->vm_maxsaddr, va);*/ 311151937Sjkim rv = KERN_FAILURE; 312151937Sjkim goto nogo; 313151937Sjkim } 314151937Sjkim } 315151937Sjkim 31687031Smsmith /* check if page table is mapped, if not, fault it first */ 317151937Sjkim#define pde_v(v) (PTD[((v)>>PD_SHIFT)&1023].pd_v) 31867754Smsmith if (!pde_v(va)) { 31967754Smsmith v = trunc_page(vtopte(va)); 32067754Smsmith rv = vm_fault(map, v, ftype, FALSE); 32167754Smsmith if (rv != KERN_SUCCESS) goto nogo; 32267754Smsmith /* check if page table fault, increment wiring */ 32367754Smsmith vm_map_pageable(map, v, round_page(v+1), FALSE); 32467754Smsmith } else v=0; 32567754Smsmith rv = vm_fault(map, va, ftype, FALSE); 32667754Smsmith if (rv == KERN_SUCCESS) { 32767754Smsmith /* 32867754Smsmith * XXX: continuation of rude stack hack 32999679Siwasaki */ 33099679Siwasaki if (nss > vm->vm_ssize) 33199679Siwasaki vm->vm_ssize = nss; 33299679Siwasaki va = trunc_page(vtopte(va)); 33399679Siwasaki /* for page table, increment wiring 33499679Siwasaki as long as not a page table fault as well */ 33599679Siwasaki if (!v && type != T_PAGEFLT) 33699679Siwasaki vm_map_pageable(map, va, round_page(va+1), FALSE); 33767754Smsmith if (type == T_PAGEFLT) 338117521Snjl return; 339117521Snjl goto out; 34067754Smsmith } 34167754Smsmithnogo: 342193267Sjkim if (type == T_PAGEFLT) { 343193267Sjkim if (curpcb->pcb_onfault) 344193267Sjkim goto copyfault; 345193267Sjkim printf("vm_fault(%x, %x, %x, 0) -> %x\n", 34667754Smsmith map, va, ftype, rv); 34767754Smsmith printf(" type %x, code %x\n", 34867754Smsmith type, code); 34967754Smsmith goto we_re_toast; 35067754Smsmith } 35167754Smsmith i = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV; 35267754Smsmith break; 35367754Smsmith } 35467754Smsmith 35567754Smsmith#if NDDB == 0 35667754Smsmith case T_TRCTRAP: /* trace trap -- someone single stepping lcall's */ 35767754Smsmith frame.tf_eflags &= ~PSL_T; 35867754Smsmith 35967754Smsmith /* Q: how do we turn it on again? */ 36067754Smsmith return; 36167754Smsmith#endif 36267754Smsmith 36367754Smsmith case T_BPTFLT|T_USER: /* bpt instruction fault */ 364193267Sjkim case T_TRCTRAP|T_USER: /* trace trap */ 36567754Smsmith frame.tf_eflags &= ~PSL_T; 36667754Smsmith i = SIGTRAP; 367193267Sjkim break; 368193267Sjkim 369193267Sjkim#include "isa.h" 370193267Sjkim#if NISA > 0 371193267Sjkim case T_NMI: 37267754Smsmith case T_NMI|T_USER: 37367754Smsmith#if NDDB > 0 37477424Smsmith /* NMI can be hooked up to a pushbutton for debugging */ 37567754Smsmith printf ("NMI ... going to debugger\n"); 37667754Smsmith if (kdb_trap (type, 0, &frame)) 37767754Smsmith return; 37867754Smsmith#endif 37967754Smsmith /* machine/parity/power fail/"kitchen sink" faults */ 38077424Smsmith if(isa_nmi(code) == 0) return; 38167754Smsmith else goto we_re_toast; 38267754Smsmith#endif 38367754Smsmith } 38467754Smsmith 38567754Smsmith trapsignal(p, i, ucode); 38677424Smsmith if ((type & T_USER) == 0) 38767754Smsmith return; 38867754Smsmithout: 38967754Smsmith while (i = CURSIG(p)) 39067754Smsmith psig(i); 39167754Smsmith p->p_pri = p->p_usrpri; 39267754Smsmith if (want_resched) { 39377424Smsmith /* 39467754Smsmith * Since we are curproc, clock will normally just change 39567754Smsmith * our priority without moving us from one queue to another 39667754Smsmith * (since the running process is not on a queue.) 39767754Smsmith * If that happened after we setrq ourselves but before we 39877424Smsmith * swtch()'ed, we might not be on the queue indicated by 39977424Smsmith * our priority. 40077424Smsmith */ 40167754Smsmith (void) splclock(); 40267754Smsmith setrq(p); 40367754Smsmith p->p_stats->p_ru.ru_nivcsw++; 40467754Smsmith swtch(); 40567754Smsmith (void) splnone(); 40677424Smsmith while (i = CURSIG(p)) 40777424Smsmith psig(i); 40867754Smsmith } 40967754Smsmith if (p->p_stats->p_prof.pr_scale) { 41067754Smsmith int ticks; 411117521Snjl struct timeval *tv = &p->p_stime; 41267754Smsmith 41367754Smsmith ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + 414129684Snjl (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); 41567754Smsmith if (ticks) { 41667754Smsmith#ifdef PROFTIMER 41767754Smsmith extern int profscale; 418193267Sjkim addupc(frame.tf_eip, &p->p_stats->p_prof, 419193267Sjkim ticks * profscale); 420193267Sjkim#else 421193267Sjkim addupc(frame.tf_eip, &p->p_stats->p_prof, ticks); 422193267Sjkim#endif 423193267Sjkim } 424138287Smarks } 425138287Smarks curpri = p->p_pri; 426138287Smarks curpcb->pcb_flags &= ~FM_TRAP; /* used by sendsig */ 427138287Smarks} 428138287Smarks 429138287Smarks/* 430138287Smarks * Compensate for 386 brain damage (missing URKR). 431138287Smarks * This is a little simpler than the pagefault handler in trap() because 43267754Smsmith * it the page tables have already been faulted in and high addresses 433107325Siwasaki * are thrown out early for other reasons. 43491116Smsmith */ 43567754Smsmithint trapwrite(addr) 43667754Smsmith unsigned addr; 43767754Smsmith{ 43891116Smsmith unsigned nss; 43967754Smsmith struct proc *p; 44067754Smsmith vm_offset_t va; 44167754Smsmith struct vmspace *vm; 442117521Snjl 44384491Smsmith va = trunc_page((vm_offset_t)addr); 44467754Smsmith /* 44567754Smsmith * XXX - MAX is END. Changed > to >= for temp. fix. 44667754Smsmith */ 447117521Snjl if (va >= VM_MAXUSER_ADDRESS) 44884491Smsmith return (1); 44967754Smsmith /* 45067754Smsmith * XXX: rude stack hack adapted from trap(). 45167754Smsmith */ 452117521Snjl nss = 0; 45367754Smsmith p = curproc; 45467754Smsmith vm = p->p_vmspace; 45567754Smsmith if ((caddr_t)va >= vm->vm_maxsaddr && dostacklimits) { 456117521Snjl nss = clrnd(btoc((unsigned)vm->vm_maxsaddr + MAXSSIZ 45767754Smsmith - (unsigned)va)); 45867754Smsmith if (nss > btoc(p->p_rlimit[RLIMIT_STACK].rlim_cur)) 459193267Sjkim return (1); 460193267Sjkim } 461193267Sjkim 462193267Sjkim if (vm_fault(&vm->vm_map, va, VM_PROT_READ | VM_PROT_WRITE, FALSE) 463117521Snjl != KERN_SUCCESS) 464129684Snjl return (1); 465129684Snjl 466129684Snjl /* 467129684Snjl * XXX: continuation of rude stack hack 468129684Snjl */ 469129684Snjl if (nss > vm->vm_ssize) 470117521Snjl vm->vm_ssize = nss; 471117521Snjl 472117521Snjl return (0); 473117521Snjl} 474117521Snjl 475117521Snjl/* 476117521Snjl * syscall(frame): 477117521Snjl * System call request from POSIX system call gate interface to kernel. 478117521Snjl * Like trap(), argument is call by reference. 479117521Snjl */ 480117521Snjl/*ARGSUSED*/ 481117521Snjlsyscall(frame) 482117521Snjl volatile struct syscframe frame; 483117521Snjl{ 484117521Snjl register int *locr0 = ((int *)&frame); 485117521Snjl register caddr_t params; 486117521Snjl register int i; 487117521Snjl register struct sysent *callp; 488117521Snjl register struct proc *p = curproc; 489117521Snjl struct timeval syst; 490117521Snjl int error, opc; 491117521Snjl int args[8], rval[2]; 492117521Snjl int code; 493117521Snjl 494117521Snjl#ifdef lint 495193267Sjkim r0 = 0; r0 = r0; r1 = 0; r1 = r1; 496193267Sjkim#endif 497193267Sjkim syst = p->p_stime; 498193267Sjkim if (ISPL(frame.sf_cs) != SEL_UPL) 499193267Sjkim panic("syscall"); 500193267Sjkim 501193267Sjkim code = frame.sf_eax; 502193267Sjkim curpcb->pcb_flags &= ~FM_TRAP; /* used by sendsig */ 503193267Sjkim p->p_regs = (int *)&frame; 504193267Sjkim params = (caddr_t)frame.sf_esp + sizeof (int) ; 505193267Sjkim 506193267Sjkim /* 507193267Sjkim * Reconstruct pc, assuming lcall $X,y is 7 bytes, as it is always. 508117521Snjl */ 509117521Snjl opc = frame.sf_eip - 7; 510117521Snjl callp = (code >= nsysent) ? &sysent[63] : &sysent[code]; 511117521Snjl if (callp == sysent) { 512151937Sjkim i = fuword(params); 513117521Snjl params += sizeof (int); 514117521Snjl callp = (code >= nsysent) ? &sysent[63] : &sysent[code]; 515117521Snjl } 516117521Snjl 517117521Snjl if ((i = callp->sy_narg * sizeof (int)) && 518117521Snjl (error = copyin(params, (caddr_t)args, (u_int)i))) { 51967754Smsmith frame.sf_eax = error; 52067754Smsmith frame.sf_eflags |= PSL_C; /* carry bit */ 52167754Smsmith#ifdef KTRACE 522114237Snjl if (KTRPOINT(p, KTR_SYSCALL)) 523114237Snjl ktrsyscall(p->p_tracep, code, callp->sy_narg, &args); 524114237Snjl#endif 525114237Snjl goto done; 526114237Snjl } 527167802Sjkim#ifdef KTRACE 528167802Sjkim if (KTRPOINT(p, KTR_SYSCALL)) 529167802Sjkim ktrsyscall(p->p_tracep, code, callp->sy_narg, &args); 530167802Sjkim#endif 531167802Sjkim rval[0] = 0; 532167802Sjkim rval[1] = frame.sf_edx; 533114237Snjl/*pg("%d. s %d\n", p->p_pid, code);*/ 53467754Smsmith error = (*callp->sy_call)(p, args, rval); 53567754Smsmith if (error == ERESTART) 53667754Smsmith frame.sf_eip = opc; 53767754Smsmith else if (error != EJUSTRETURN) { 53867754Smsmith if (error) { 53967754Smsmith/*pg("error %d", error);*/ 54067754Smsmith frame.sf_eax = error; 54167754Smsmith frame.sf_eflags |= PSL_C; /* carry bit */ 54267754Smsmith } else { 54367754Smsmith frame.sf_eax = rval[0]; 54467754Smsmith frame.sf_edx = rval[1]; 545114237Snjl frame.sf_eflags &= ~PSL_C; /* carry bit */ 546167802Sjkim } 547167802Sjkim } 548167802Sjkim /* else if (error == EJUSTRETURN) */ 549167802Sjkim /* nothing to do */ 550114237Snjldone: 551114237Snjl /* 55267754Smsmith * Reinitialize proc pointer `p' as it may be different 55367754Smsmith * if this is a child returning from fork syscall. 55467754Smsmith */ 55567754Smsmith p = curproc; 55667754Smsmith while (i = CURSIG(p)) 55767754Smsmith psig(i); 55867754Smsmith p->p_pri = p->p_usrpri; 55967754Smsmith if (want_resched) { 56067754Smsmith /* 561114237Snjl * Since we are curproc, clock will normally just change 562114237Snjl * our priority without moving us from one queue to another 563114237Snjl * (since the running process is not on a queue.) 564114237Snjl * If that happened after we setrq ourselves but before we 56567754Smsmith * swtch()'ed, we might not be on the queue indicated by 566193267Sjkim * our priority. 56767754Smsmith */ 56867754Smsmith (void) splclock(); 56967754Smsmith setrq(p); 57067754Smsmith p->p_stats->p_ru.ru_nivcsw++; 571193267Sjkim swtch(); 572193267Sjkim (void) splnone(); 573193267Sjkim while (i = CURSIG(p)) 574193267Sjkim psig(i); 575193267Sjkim } 576193267Sjkim if (p->p_stats->p_prof.pr_scale) { 577193267Sjkim int ticks; 578193267Sjkim struct timeval *tv = &p->p_stime; 579193267Sjkim 580193267Sjkim ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + 581193267Sjkim (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); 582193267Sjkim if (ticks) { 583193267Sjkim#ifdef PROFTIMER 584193267Sjkim extern int profscale; 585193267Sjkim addupc(frame.sf_eip, &p->p_stats->p_prof, 58699679Siwasaki ticks * profscale); 587167802Sjkim#else 58899679Siwasaki addupc(frame.sf_eip, &p->p_stats->p_prof, ticks); 58999679Siwasaki#endif 590193267Sjkim } 59199679Siwasaki } 592167802Sjkim curpri = p->p_pri; 59399679Siwasaki#ifdef KTRACE 59499679Siwasaki if (KTRPOINT(p, KTR_SYSRET)) 59599679Siwasaki ktrsysret(p->p_tracep, code, error, rval[0]); 59699679Siwasaki#endif 59799679Siwasaki#ifdef DIAGNOSTICx 59899679Siwasaki{ extern int _udatasel, _ucodesel; 59987031Smsmith if (frame.sf_ss != _udatasel) 60067754Smsmith printf("ss %x call %d\n", frame.sf_ss, code); 60187031Smsmith if ((frame.sf_cs&0xffff) != _ucodesel) 60299679Siwasaki printf("cs %x call %d\n", frame.sf_cs, code); 60387031Smsmith if (frame.sf_eip > VM_MAXUSER_ADDRESS) { 60487031Smsmith printf("eip %x call %d\n", frame.sf_eip, code); 60571867Smsmith frame.sf_eip = 0; 60699679Siwasaki } 60771867Smsmith} 60871867Smsmith#endif 609114237Snjl} 610114237Snjl