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