Deleted Added
full compact
subr_syscall.c (1431) subr_syscall.c (1549)
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * the University of Utah, and William Jolitz.
7 *
8 * Redistribution and use in source and binary forms, with or without

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

36 * from: @(#)trap.c 7.4 (Berkeley) 5/13/91
37 * $Id: trap.c,v 1.22 1994/04/07 10:51:00 davidg Exp $
38 */
39
40/*
41 * 386 Trap and System call handleing
42 */
43
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * the University of Utah, and William Jolitz.
7 *
8 * Redistribution and use in source and binary forms, with or without

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

36 * from: @(#)trap.c 7.4 (Berkeley) 5/13/91
37 * $Id: trap.c,v 1.22 1994/04/07 10:51:00 davidg Exp $
38 */
39
40/*
41 * 386 Trap and System call handleing
42 */
43
44#include "isa.h"
45#include "npx.h"
46#include "ddb.h"
47#include "machine/cpu.h"
48#include "machine/psl.h"
49#include "machine/reg.h"
50#include "machine/eflags.h"
44#include <sys/param.h>
45#include <sys/systm.h>
51
46
52#include "param.h"
53#include "systm.h"
54#include "proc.h"
55#include "user.h"
56#include "acct.h"
57#include "kernel.h"
47#include <sys/proc.h>
48#include <sys/user.h>
49#include <sys/acct.h>
50#include <sys/kernel.h>
51#include <sys/syscall.h>
58#ifdef KTRACE
52#ifdef KTRACE
59#include "ktrace.h"
53#include <sys/ktrace.h>
60#endif
61
54#endif
55
62#include "vm/vm_param.h"
63#include "vm/pmap.h"
64#include "vm/vm_map.h"
65#include "vm/vm_user.h"
66#include "vm/vm_page.h"
67#include "sys/vmmeter.h"
56#include <vm/vm_param.h>
57#include <vm/pmap.h>
58#include <vm/vm_map.h>
59#include <vm/vm_page.h>
68
60
69#include "machine/trap.h"
61#include <machine/cpu.h>
62#include <machine/psl.h>
63#include <machine/reg.h>
64#include <machine/eflags.h>
70
65
66#include <machine/trap.h>
67
68#include "isa.h"
69#include "npx.h"
70#include "ddb.h"
71
71#ifdef __GNUC__
72
73/*
74 * The "r" contraint could be "rm" except for fatal bugs in gas. As usual,
75 * we omit the size from the mov instruction to avoid nonfatal bugs in gas.
76 */
77#define read_gs() ({ u_short gs; __asm("mov %%gs,%0" : "=r" (gs)); gs; })
78#define write_gs(newgs) __asm("mov %0,%%gs" : : "r" ((u_short) newgs))
79
80#else /* not __GNUC__ */
81
82u_short read_gs __P((void));
83void write_gs __P((/* promoted u_short */ int gs));
84
85#endif /* __GNUC__ */
86
72#ifdef __GNUC__
73
74/*
75 * The "r" contraint could be "rm" except for fatal bugs in gas. As usual,
76 * we omit the size from the mov instruction to avoid nonfatal bugs in gas.
77 */
78#define read_gs() ({ u_short gs; __asm("mov %%gs,%0" : "=r" (gs)); gs; })
79#define write_gs(newgs) __asm("mov %0,%%gs" : : "r" ((u_short) newgs))
80
81#else /* not __GNUC__ */
82
83u_short read_gs __P((void));
84void write_gs __P((/* promoted u_short */ int gs));
85
86#endif /* __GNUC__ */
87
87extern int grow(struct proc *,int);
88extern int grow(struct proc *,u_int);
88
89struct sysent sysent[];
90int nsysent;
91
92#define MAX_TRAP_MSG 27
93char *trap_msg[] = {
94 "reserved addressing fault", /* 0 T_RESADFLT */
95 "privileged instruction fault", /* 1 T_PRIVINFLT */

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

134
135/*ARGSUSED*/
136void
137trap(frame)
138 struct trapframe frame;
139{
140 register int i;
141 register struct proc *p = curproc;
89
90struct sysent sysent[];
91int nsysent;
92
93#define MAX_TRAP_MSG 27
94char *trap_msg[] = {
95 "reserved addressing fault", /* 0 T_RESADFLT */
96 "privileged instruction fault", /* 1 T_PRIVINFLT */

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

135
136/*ARGSUSED*/
137void
138trap(frame)
139 struct trapframe frame;
140{
141 register int i;
142 register struct proc *p = curproc;
142 struct timeval syst;
143 u_quad_t sticks = 0;
143 int ucode, type, code, eva, fault_type;
144
145 frame.tf_eflags &= ~PSL_NT; /* clear nested trap XXX */
146 type = frame.tf_trapno;
147#if NDDB > 0
148 if (curpcb && curpcb->pcb_onfault) {
149 if (frame.tf_trapno == T_BPTFLT
150 || frame.tf_trapno == T_TRCTRAP)

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

172 */
173 write_gs(_udatasel);
174 else
175copyfault:
176 frame.tf_eip = (int)curpcb->pcb_onfault;
177 return;
178 }
179
144 int ucode, type, code, eva, fault_type;
145
146 frame.tf_eflags &= ~PSL_NT; /* clear nested trap XXX */
147 type = frame.tf_trapno;
148#if NDDB > 0
149 if (curpcb && curpcb->pcb_onfault) {
150 if (frame.tf_trapno == T_BPTFLT
151 || frame.tf_trapno == T_TRCTRAP)

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

173 */
174 write_gs(_udatasel);
175 else
176copyfault:
177 frame.tf_eip = (int)curpcb->pcb_onfault;
178 return;
179 }
180
180 syst = p->p_stime;
181 if (ISPL(frame.tf_cs) == SEL_UPL) {
182 type |= T_USER;
181 if (ISPL(frame.tf_cs) == SEL_UPL) {
182 type |= T_USER;
183 p->p_regs = (int *)&frame;
183 p->p_md.md_regs = (int *)&frame;
184 sticks = p->p_sticks;
184 }
185
186skiptoswitch:
187 ucode=0;
188 eva = rcr2();
189 code = frame.tf_err;
190
191 if ((type & ~T_USER) == T_PAGEFLT)

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

205 case T_FPOPFLT|T_USER: /* coprocessor operand fault */
206 ucode = type &~ T_USER;
207 i = SIGILL;
208 break;
209
210 case T_ASTFLT|T_USER: /* Allow process switch */
211 astoff();
212 cnt.v_soft++;
185 }
186
187skiptoswitch:
188 ucode=0;
189 eva = rcr2();
190 code = frame.tf_err;
191
192 if ((type & ~T_USER) == T_PAGEFLT)

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

206 case T_FPOPFLT|T_USER: /* coprocessor operand fault */
207 ucode = type &~ T_USER;
208 i = SIGILL;
209 break;
210
211 case T_ASTFLT|T_USER: /* Allow process switch */
212 astoff();
213 cnt.v_soft++;
213 if ((p->p_flag & SOWEUPC) && p->p_stats->p_prof.pr_scale) {
214 if ((p->p_flag & P_OWEUPC) && p->p_stats->p_prof.pr_scale) {
214 addupc(frame.tf_eip, &p->p_stats->p_prof, 1);
215 addupc(frame.tf_eip, &p->p_stats->p_prof, 1);
215 p->p_flag &= ~SOWEUPC;
216 p->p_flag &= ~P_OWEUPC;
216 }
217 goto out;
218
219 case T_DNA|T_USER:
220#if NNPX > 0
221 /* if a transparent fault (due to context switch "late") */
222 if (npxdna()) return;
223#endif /* NNPX > 0 */

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

279 map = &vm->vm_map;
280 }
281
282 if (code & PGEX_W)
283 ftype = VM_PROT_READ | VM_PROT_WRITE;
284 else
285 ftype = VM_PROT_READ;
286
217 }
218 goto out;
219
220 case T_DNA|T_USER:
221#if NNPX > 0
222 /* if a transparent fault (due to context switch "late") */
223 if (npxdna()) return;
224#endif /* NNPX > 0 */

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

280 map = &vm->vm_map;
281 }
282
283 if (code & PGEX_W)
284 ftype = VM_PROT_READ | VM_PROT_WRITE;
285 else
286 ftype = VM_PROT_READ;
287
287 oldflags = p->p_flag;
288 if (map != kernel_map) {
289 vm_offset_t pa;
290 vm_offset_t v = (vm_offset_t) vtopte(va);
291 vm_page_t ptepg;
292
293 /*
294 * Keep swapout from messing with us during this
295 * critical time.
296 */
288 if (map != kernel_map) {
289 vm_offset_t pa;
290 vm_offset_t v = (vm_offset_t) vtopte(va);
291 vm_page_t ptepg;
292
293 /*
294 * Keep swapout from messing with us during this
295 * critical time.
296 */
297 p->p_flag |= SLOCK;
297 ++p->p_lock;
298
299 /*
300 * Grow the stack if necessary
301 */
302 if ((caddr_t)va > vm->vm_maxsaddr
303 && (caddr_t)va < (caddr_t)USRSTACK) {
304 if (!grow(p, va)) {
305 rv = KERN_FAILURE;
298
299 /*
300 * Grow the stack if necessary
301 */
302 if ((caddr_t)va > vm->vm_maxsaddr
303 && (caddr_t)va < (caddr_t)USRSTACK) {
304 if (!grow(p, va)) {
305 rv = KERN_FAILURE;
306 p->p_flag &= ~SLOCK;
307 p->p_flag |= (oldflags & SLOCK);
306 --p->p_lock;
308 goto nogo;
309 }
310 }
311
312 /*
313 * Check if page table is mapped, if not,
314 * fault it first
315 */

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

327
328 /*
329 * page table pages don't need to be kept if they
330 * are not held
331 */
332 if( ptepg->hold_count == 0 && ptepg->wire_count == 0) {
333 pmap_page_protect( VM_PAGE_TO_PHYS(ptepg),
334 VM_PROT_NONE);
307 goto nogo;
308 }
309 }
310
311 /*
312 * Check if page table is mapped, if not,
313 * fault it first
314 */

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

326
327 /*
328 * page table pages don't need to be kept if they
329 * are not held
330 */
331 if( ptepg->hold_count == 0 && ptepg->wire_count == 0) {
332 pmap_page_protect( VM_PAGE_TO_PHYS(ptepg),
333 VM_PROT_NONE);
335 if( ptepg->flags & PG_CLEAN)
336 vm_page_free(ptepg);
334 vm_page_free(ptepg);
337 }
338
335 }
336
339
340 p->p_flag &= ~SLOCK;
341 p->p_flag |= (oldflags & SLOCK);
337 --p->p_lock;
342 } else {
343 /*
344 * Since we know that kernel virtual address addresses
345 * always have pte pages mapped, we just have to fault
346 * the page.
347 */
348 rv = vm_fault(map, va, ftype, FALSE);
349 }

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

477 if ((fault_type == T_PAGEFLT) || (fault_type == T_PROTFLT))
478 uprintf(", fault VA = 0x%x", eva);
479 uprintf("\n");
480 }
481#endif
482
483out:
484 while (i = CURSIG(p))
338 } else {
339 /*
340 * Since we know that kernel virtual address addresses
341 * always have pte pages mapped, we just have to fault
342 * the page.
343 */
344 rv = vm_fault(map, va, ftype, FALSE);
345 }

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

473 if ((fault_type == T_PAGEFLT) || (fault_type == T_PROTFLT))
474 uprintf(", fault VA = 0x%x", eva);
475 uprintf("\n");
476 }
477#endif
478
479out:
480 while (i = CURSIG(p))
485 psig(i);
486 p->p_pri = p->p_usrpri;
481 postsig(i);
482 p->p_priority = p->p_usrpri;
487 if (want_resched) {
488 int s;
489 /*
490 * Since we are curproc, clock will normally just change
491 * our priority without moving us from one queue to another
492 * (since the running process is not on a queue.)
483 if (want_resched) {
484 int s;
485 /*
486 * Since we are curproc, clock will normally just change
487 * our priority without moving us from one queue to another
488 * (since the running process is not on a queue.)
493 * If that happened after we setrq ourselves but before we
494 * swtch()'ed, we might not be on the queue indicated by
489 * If that happened after we setrunqueue ourselves but before we
490 * mi_switch()'ed, we might not be on the queue indicated by
495 * our priority.
496 */
497 s = splclock();
491 * our priority.
492 */
493 s = splclock();
498 setrq(p);
494 setrunqueue(p);
499 p->p_stats->p_ru.ru_nivcsw++;
495 p->p_stats->p_ru.ru_nivcsw++;
500 swtch();
496 mi_switch();
501 splx(s);
502 while (i = CURSIG(p))
497 splx(s);
498 while (i = CURSIG(p))
503 psig(i);
499 postsig(i);
504 }
505 if (p->p_stats->p_prof.pr_scale) {
500 }
501 if (p->p_stats->p_prof.pr_scale) {
506 int ticks;
507 struct timeval *tv = &p->p_stime;
502 u_quad_t ticks = p->p_sticks - sticks;
508
503
509 ticks = ((tv->tv_sec - syst.tv_sec) * 1000 +
510 (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000);
511 if (ticks) {
512#ifdef PROFTIMER
513 extern int profscale;
514 addupc(frame.tf_eip, &p->p_stats->p_prof,
515 ticks * profscale);
516#else
517 addupc(frame.tf_eip, &p->p_stats->p_prof, ticks);
518#endif
519 }
520 }
504 if (ticks) {
505#ifdef PROFTIMER
506 extern int profscale;
507 addupc(frame.tf_eip, &p->p_stats->p_prof,
508 ticks * profscale);
509#else
510 addupc(frame.tf_eip, &p->p_stats->p_prof, ticks);
511#endif
512 }
513 }
521 curpri = p->p_pri;
514 curpriority = p->p_priority;
522}
523
524/*
525 * Compensate for 386 brain damage (missing URKR).
526 * This is a little simpler than the pagefault handler in trap() because
527 * it the page tables have already been faulted in and high addresses
528 * are thrown out early for other reasons.
529 */

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

541 * XXX - MAX is END. Changed > to >= for temp. fix.
542 */
543 if (va >= VM_MAXUSER_ADDRESS)
544 return (1);
545
546 p = curproc;
547 vm = p->p_vmspace;
548
515}
516
517/*
518 * Compensate for 386 brain damage (missing URKR).
519 * This is a little simpler than the pagefault handler in trap() because
520 * it the page tables have already been faulted in and high addresses
521 * are thrown out early for other reasons.
522 */

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

534 * XXX - MAX is END. Changed > to >= for temp. fix.
535 */
536 if (va >= VM_MAXUSER_ADDRESS)
537 return (1);
538
539 p = curproc;
540 vm = p->p_vmspace;
541
549 oldflags = p->p_flag;
550 p->p_flag |= SLOCK;
542 ++p->p_lock;
551
552 if ((caddr_t)va >= vm->vm_maxsaddr
553 && (caddr_t)va < (caddr_t)USRSTACK) {
554 if (!grow(p, va)) {
543
544 if ((caddr_t)va >= vm->vm_maxsaddr
545 && (caddr_t)va < (caddr_t)USRSTACK) {
546 if (!grow(p, va)) {
555 p->p_flag &= ~SLOCK;
556 p->p_flag |= (oldflags & SLOCK);
547 --p->p_lock;
557 return (1);
558 }
559 }
560
561 v = trunc_page(vtopte(va));
562
563 /*
564 * wire the pte page

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

574
575 /*
576 * unwire the pte page
577 */
578 if (va < USRSTACK) {
579 vm_map_pageable(&vm->vm_map, v, round_page(v+1), TRUE);
580 }
581
548 return (1);
549 }
550 }
551
552 v = trunc_page(vtopte(va));
553
554 /*
555 * wire the pte page

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

565
566 /*
567 * unwire the pte page
568 */
569 if (va < USRSTACK) {
570 vm_map_pageable(&vm->vm_map, v, round_page(v+1), TRUE);
571 }
572
582 p->p_flag &= ~SLOCK;
583 p->p_flag |= (oldflags & SLOCK);
573 --p->p_lock;
584
585 if (rv != KERN_SUCCESS)
586 return 1;
587
588 return (0);
589}
590
591/*

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

598syscall(frame)
599 volatile struct trapframe frame;
600{
601 register int *locr0 = ((int *)&frame);
602 register caddr_t params;
603 register int i;
604 register struct sysent *callp;
605 register struct proc *p = curproc;
574
575 if (rv != KERN_SUCCESS)
576 return 1;
577
578 return (0);
579}
580
581/*

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

588syscall(frame)
589 volatile struct trapframe frame;
590{
591 register int *locr0 = ((int *)&frame);
592 register caddr_t params;
593 register int i;
594 register struct sysent *callp;
595 register struct proc *p = curproc;
606 struct timeval syst;
596 u_quad_t sticks;
607 int error, opc;
608 int args[8], rval[2];
597 int error, opc;
598 int args[8], rval[2];
609 int code;
599 u_int code;
610
611#ifdef lint
612 r0 = 0; r0 = r0; r1 = 0; r1 = r1;
613#endif
600
601#ifdef lint
602 r0 = 0; r0 = r0; r1 = 0; r1 = r1;
603#endif
614 syst = p->p_stime;
604 sticks = p->p_sticks;
615 if (ISPL(frame.tf_cs) != SEL_UPL)
616 panic("syscall");
617
618 code = frame.tf_eax;
605 if (ISPL(frame.tf_cs) != SEL_UPL)
606 panic("syscall");
607
608 code = frame.tf_eax;
619 p->p_regs = (int *)&frame;
609 p->p_md.md_regs = (int *)&frame;
620 params = (caddr_t)frame.tf_esp + sizeof (int) ;
621
622 /*
623 * Reconstruct pc, assuming lcall $X,y is 7 bytes, as it is always.
624 */
625 opc = frame.tf_eip - 7;
610 params = (caddr_t)frame.tf_esp + sizeof (int) ;
611
612 /*
613 * Reconstruct pc, assuming lcall $X,y is 7 bytes, as it is always.
614 */
615 opc = frame.tf_eip - 7;
626 if (code == 0) {
616 /*
617 * Need to check if this is a 32 bit or 64 bit syscall.
618 */
619 if (code == SYS_syscall) {
620 /*
621 * Code is first argument, followed by actual args.
622 */
627 code = fuword(params);
628 params += sizeof (int);
623 code = fuword(params);
624 params += sizeof (int);
625 } else if (code == SYS___syscall) {
626 /*
627 * Like syscall, but code is a quad, so as to maintain
628 * quad alignment for the rest of the arguments.
629 */
630 code = fuword(params + _QUAD_LOWWORD * sizeof(int));
631 params += sizeof(quad_t);
629 }
632 }
630 if (code < 0 || code >= nsysent)
633
634 if (code >= nsysent)
631 callp = &sysent[0];
632 else
633 callp = &sysent[code];
634
635 if ((i = callp->sy_narg * sizeof (int)) &&
636 (error = copyin(params, (caddr_t)args, (u_int)i))) {
637 frame.tf_eax = error;
638 frame.tf_eflags |= PSL_C; /* carry bit */

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

667 /* nothing to do */
668done:
669 /*
670 * Reinitialize proc pointer `p' as it may be different
671 * if this is a child returning from fork syscall.
672 */
673 p = curproc;
674 while (i = CURSIG(p))
635 callp = &sysent[0];
636 else
637 callp = &sysent[code];
638
639 if ((i = callp->sy_narg * sizeof (int)) &&
640 (error = copyin(params, (caddr_t)args, (u_int)i))) {
641 frame.tf_eax = error;
642 frame.tf_eflags |= PSL_C; /* carry bit */

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

671 /* nothing to do */
672done:
673 /*
674 * Reinitialize proc pointer `p' as it may be different
675 * if this is a child returning from fork syscall.
676 */
677 p = curproc;
678 while (i = CURSIG(p))
675 psig(i);
676 p->p_pri = p->p_usrpri;
679 postsig(i);
680 p->p_priority = p->p_usrpri;
677 if (want_resched) {
678 int s;
679 /*
680 * Since we are curproc, clock will normally just change
681 * our priority without moving us from one queue to another
682 * (since the running process is not on a queue.)
681 if (want_resched) {
682 int s;
683 /*
684 * Since we are curproc, clock will normally just change
685 * our priority without moving us from one queue to another
686 * (since the running process is not on a queue.)
683 * If that happened after we setrq ourselves but before we
687 * If that happened after we setrunqueue ourselves but before we
684 * swtch()'ed, we might not be on the queue indicated by
685 * our priority.
686 */
687 s = splclock();
688 * swtch()'ed, we might not be on the queue indicated by
689 * our priority.
690 */
691 s = splclock();
688 setrq(p);
692 setrunqueue(p);
689 p->p_stats->p_ru.ru_nivcsw++;
693 p->p_stats->p_ru.ru_nivcsw++;
690 swtch();
694 mi_switch();
691 splx(s);
692 while (i = CURSIG(p))
695 splx(s);
696 while (i = CURSIG(p))
693 psig(i);
697 postsig(i);
694 }
695 if (p->p_stats->p_prof.pr_scale) {
698 }
699 if (p->p_stats->p_prof.pr_scale) {
696 int ticks;
697 struct timeval *tv = &p->p_stime;
700 u_quad_t ticks = p->p_sticks - sticks;
698
701
699 ticks = ((tv->tv_sec - syst.tv_sec) * 1000 +
700 (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000);
701 if (ticks) {
702#ifdef PROFTIMER
703 extern int profscale;
704 addupc(frame.tf_eip, &p->p_stats->p_prof,
705 ticks * profscale);
706#else
707 addupc(frame.tf_eip, &p->p_stats->p_prof, ticks);
708#endif
709 }
710 }
702 if (ticks) {
703#ifdef PROFTIMER
704 extern int profscale;
705 addupc(frame.tf_eip, &p->p_stats->p_prof,
706 ticks * profscale);
707#else
708 addupc(frame.tf_eip, &p->p_stats->p_prof, ticks);
709#endif
710 }
711 }
711 curpri = p->p_pri;
712 curpriority = p->p_priority;
712#ifdef KTRACE
713 if (KTRPOINT(p, KTR_SYSRET))
714 ktrsysret(p->p_tracep, code, error, rval[0]);
715#endif
713#ifdef KTRACE
714 if (KTRPOINT(p, KTR_SYSRET))
715 ktrsysret(p->p_tracep, code, error, rval[0]);
716#endif
716#ifdef DIAGNOSTICx
717{ extern int _udatasel, _ucodesel;
718 if (frame.tf_ss != _udatasel)
719 printf("ss %x call %d\n", frame.tf_ss, code);
720 if ((frame.tf_cs&0xffff) != _ucodesel)
721 printf("cs %x call %d\n", frame.tf_cs, code);
722 if (frame.tf_eip > VM_MAXUSER_ADDRESS) {
723 printf("eip %x call %d\n", frame.tf_eip, code);
724 frame.tf_eip = 0;
725 }
726}
717}
727#endif
728}