subr_syscall.c (827) | subr_syscall.c (849) |
---|---|
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 --- 20 unchanged lines hidden (view full) --- 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 | 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 --- 20 unchanged lines hidden (view full) --- 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 |
37 * $Id: trap.c,v 1.9 1993/11/28 09:28:54 davidg Exp $ | 37 * $Id: trap.c,v 1.10 1993/12/03 05:07:45 alm Exp $ |
38 */ 39 40/* 41 * 386 Trap and System call handleing 42 */ 43 44#include "npx.h" 45#include "machine/cpu.h" --- 30 unchanged lines hidden (view full) --- 76 77u_short read_gs __P((void)); 78void write_gs __P((/* promoted u_short */ int gs)); 79 80#endif /* __GNUC__ */ 81 82struct sysent sysent[]; 83int nsysent; | 38 */ 39 40/* 41 * 386 Trap and System call handleing 42 */ 43 44#include "npx.h" 45#include "machine/cpu.h" --- 30 unchanged lines hidden (view full) --- 76 77u_short read_gs __P((void)); 78void write_gs __P((/* promoted u_short */ int gs)); 79 80#endif /* __GNUC__ */ 81 82struct sysent sysent[]; 83int nsysent; |
84int dostacklimits; | |
85unsigned rcr2(); 86extern short cpl; 87 88#define MAX_TRAP_MSG 27 89char *trap_msg[] = { 90 "reserved addressing fault", /* 0 T_RESADFLT */ 91 "privileged instruction fault", /* 1 T_PRIVINFLT */ 92 "reserved operand fault", /* 2 T_RESOPFLT */ --- 19 unchanged lines hidden (view full) --- 112 "FPU device not available", /* 22 T_DNA */ 113 "double fault", /* 23 T_DOUBLEFLT */ 114 "FPU operand fetch fault", /* 24 T_FPOPFLT */ 115 "invalid TSS fault", /* 25 T_TSSFLT */ 116 "segment not present fault", /* 26 T_SEGNPFLT */ 117 "stack fault", /* 27 T_STKFLT */ 118}; 119 | 84unsigned rcr2(); 85extern short cpl; 86 87#define MAX_TRAP_MSG 27 88char *trap_msg[] = { 89 "reserved addressing fault", /* 0 T_RESADFLT */ 90 "privileged instruction fault", /* 1 T_PRIVINFLT */ 91 "reserved operand fault", /* 2 T_RESOPFLT */ --- 19 unchanged lines hidden (view full) --- 111 "FPU device not available", /* 22 T_DNA */ 112 "double fault", /* 23 T_DOUBLEFLT */ 113 "FPU operand fetch fault", /* 24 T_FPOPFLT */ 114 "invalid TSS fault", /* 25 T_TSSFLT */ 115 "segment not present fault", /* 26 T_SEGNPFLT */ 116 "stack fault", /* 27 T_STKFLT */ 117}; 118 |
119#define pde_v(v) (PTD[((v)>>PD_SHIFT)&1023].pd_v) |
|
120 121/* 122 * trap(frame): 123 * Exception, fault, and trap interface to BSD kernel. This 124 * common code is called from assembly language IDT gate entry 125 * routines that prepare a suitable stack frame, and restore this 126 * frame after the exception has been processed. Note that the 127 * effect is as if the arguments were passed call by reference. --- 154 unchanged lines hidden (view full) --- 282#endif 283 284 /* fall into */ 285 case T_PAGEFLT|T_USER: /* page fault */ 286 { 287 register vm_offset_t va; 288 register struct vmspace *vm = p->p_vmspace; 289 register vm_map_t map; | 120 121/* 122 * trap(frame): 123 * Exception, fault, and trap interface to BSD kernel. This 124 * common code is called from assembly language IDT gate entry 125 * routines that prepare a suitable stack frame, and restore this 126 * frame after the exception has been processed. Note that the 127 * effect is as if the arguments were passed call by reference. --- 154 unchanged lines hidden (view full) --- 282#endif 283 284 /* fall into */ 285 case T_PAGEFLT|T_USER: /* page fault */ 286 { 287 register vm_offset_t va; 288 register struct vmspace *vm = p->p_vmspace; 289 register vm_map_t map; |
290 int rv; | 290 int rv = 0; |
291 vm_prot_t ftype; 292 extern vm_map_t kernel_map; | 291 vm_prot_t ftype; 292 extern vm_map_t kernel_map; |
293 unsigned nss,v; | 293 unsigned nss; 294 char *v; |
294 295 va = trunc_page((vm_offset_t)eva); 296 /* 297 * It is only a kernel address space fault iff: 298 * 1. (type & T_USER) == 0 and 299 * 2. pcb_onfault not set or 300 * 3. pcb_onfault set but supervisor space fault 301 * The last can occur during an exec() copyin where the --- 16 unchanged lines hidden (view full) --- 318#endif 319 320 /* 321 * XXX: rude hack to make stack limits "work" 322 */ 323 nss = 0; 324 if ((caddr_t)va >= vm->vm_maxsaddr 325 && (caddr_t)va < (caddr_t)USRSTACK | 295 296 va = trunc_page((vm_offset_t)eva); 297 /* 298 * It is only a kernel address space fault iff: 299 * 1. (type & T_USER) == 0 and 300 * 2. pcb_onfault not set or 301 * 3. pcb_onfault set but supervisor space fault 302 * The last can occur during an exec() copyin where the --- 16 unchanged lines hidden (view full) --- 319#endif 320 321 /* 322 * XXX: rude hack to make stack limits "work" 323 */ 324 nss = 0; 325 if ((caddr_t)va >= vm->vm_maxsaddr 326 && (caddr_t)va < (caddr_t)USRSTACK |
326 && map != kernel_map 327 && dostacklimits) { 328 nss = clrnd(btoc((unsigned)vm->vm_maxsaddr 329 + MAXSSIZ - (unsigned)va)); 330 if (nss > btoc(p->p_rlimit[RLIMIT_STACK].rlim_cur)) { 331/*pg("trap rlimit %d, maxsaddr %x va %x ", nss, vm->vm_maxsaddr, va);*/ | 327 && map != kernel_map) { 328 nss = roundup(USRSTACK - (unsigned)va, PAGE_SIZE); 329 if (nss > p->p_rlimit[RLIMIT_STACK].rlim_cur) { |
332 rv = KERN_FAILURE; 333 goto nogo; 334 } | 330 rv = KERN_FAILURE; 331 goto nogo; 332 } |
333 334 if (vm->vm_ssize && roundup(vm->vm_ssize << PGSHIFT, 335 DFLSSIZ) < nss) { 336 int grow_amount; 337 /* 338 * If necessary, grow the VM that the stack occupies 339 * to allow for the rlimit. This allows us to not have 340 * to allocate all of the VM up-front in execve (which 341 * is expensive). 342 * Grow the VM by the amount requested rounded up to 343 * the nearest DFLSSIZ to provide for some hysteresis. 344 */ 345 grow_amount = roundup(nss, DFLSSIZ); 346 v = (char *)USRSTACK - roundup(vm->vm_ssize << PGSHIFT, 347 DFLSSIZ) - grow_amount; 348 /* 349 * If there isn't enough room to extend by DFLSSIZ, then 350 * just extend to the maximum size 351 */ 352 if (v < vm->vm_maxsaddr) { 353 v = vm->vm_maxsaddr; 354 grow_amount = MAXSSIZ - (vm->vm_ssize << PGSHIFT); 355 } 356 if (vm_allocate(&vm->vm_map, &v, grow_amount, FALSE) != 357 KERN_SUCCESS) { 358 goto nogo; 359 } 360 } |
|
335 } 336 337 /* check if page table is mapped, if not, fault it first */ | 361 } 362 363 /* check if page table is mapped, if not, fault it first */ |
338#define pde_v(v) (PTD[((v)>>PD_SHIFT)&1023].pd_v) | |
339 if (!pde_v(va)) { | 364 if (!pde_v(va)) { |
340 v = trunc_page(vtopte(va)); | 365 v = (char *)trunc_page(vtopte(va)); |
341 rv = vm_fault(map, v, ftype, FALSE); 342 if (rv != KERN_SUCCESS) goto nogo; 343 /* check if page table fault, increment wiring */ 344 vm_map_pageable(map, v, round_page(v+1), FALSE); 345 } else v=0; 346 rv = vm_fault(map, va, ftype, FALSE); 347 if (rv == KERN_SUCCESS) { 348 /* 349 * XXX: continuation of rude stack hack 350 */ | 366 rv = vm_fault(map, v, ftype, FALSE); 367 if (rv != KERN_SUCCESS) goto nogo; 368 /* check if page table fault, increment wiring */ 369 vm_map_pageable(map, v, round_page(v+1), FALSE); 370 } else v=0; 371 rv = vm_fault(map, va, ftype, FALSE); 372 if (rv == KERN_SUCCESS) { 373 /* 374 * XXX: continuation of rude stack hack 375 */ |
376 nss = nss >> PGSHIFT; |
|
351 if (nss > vm->vm_ssize) 352 vm->vm_ssize = nss; | 377 if (nss > vm->vm_ssize) 378 vm->vm_ssize = nss; |
379 /* 380 * va could be a page table address, if the fault 381 * occurred from within copyout. In that case, 382 * we have to wire it. (EWS 12/11/93) 383 */ 384 if (ispt(va)) 385 vm_map_pageable(map, va, round_page(va+1), FALSE); |
|
353 va = trunc_page(vtopte(va)); | 386 va = trunc_page(vtopte(va)); |
354 /* for page table, increment wiring 355 as long as not a page table fault as well */ | 387 /* 388 * for page table, increment wiring 389 * as long as not a page table fault as well 390 */ |
356 if (!v && type != T_PAGEFLT) | 391 if (!v && type != T_PAGEFLT) |
357 vm_map_pageable(map, va, round_page(va+1), FALSE); | 392 vm_map_pageable(map, va, round_page(va+1), FALSE); |
358 if (type == T_PAGEFLT) 359 return; 360 goto out; 361 } 362nogo: 363 if (type == T_PAGEFLT) { 364 if (curpcb->pcb_onfault) 365 goto copyfault; 366 printf("vm_fault(%x, %x, %x, 0) -> %x\n", 367 map, va, ftype, rv); 368 printf(" type %x, code %x\n", 369 type, code); 370 goto we_re_toast; 371 } 372 i = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV; | 393 if (type == T_PAGEFLT) 394 return; 395 goto out; 396 } 397nogo: 398 if (type == T_PAGEFLT) { 399 if (curpcb->pcb_onfault) 400 goto copyfault; 401 printf("vm_fault(%x, %x, %x, 0) -> %x\n", 402 map, va, ftype, rv); 403 printf(" type %x, code %x\n", 404 type, code); 405 goto we_re_toast; 406 } 407 i = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV; |
408 409 /* kludge to pass faulting virtual address to sendsig */ |
|
373 ucode = type &~ T_USER; 374 frame.tf_err = eva; | 410 ucode = type &~ T_USER; 411 frame.tf_err = eva; |
375 /* kludge to pass faulting virtual address to sendsig */ | 412 |
376 break; 377 } 378 379#if NDDB == 0 380 case T_TRCTRAP: /* trace trap -- someone single stepping lcall's */ 381 frame.tf_eflags &= ~PSL_T; 382 383 /* Q: how do we turn it on again? */ --- 75 unchanged lines hidden (view full) --- 459 */ 460int trapwrite(addr) 461 unsigned addr; 462{ 463 unsigned nss; 464 struct proc *p; 465 vm_offset_t va; 466 struct vmspace *vm; | 413 break; 414 } 415 416#if NDDB == 0 417 case T_TRCTRAP: /* trace trap -- someone single stepping lcall's */ 418 frame.tf_eflags &= ~PSL_T; 419 420 /* Q: how do we turn it on again? */ --- 75 unchanged lines hidden (view full) --- 496 */ 497int trapwrite(addr) 498 unsigned addr; 499{ 500 unsigned nss; 501 struct proc *p; 502 vm_offset_t va; 503 struct vmspace *vm; |
504 char *v; |
|
467 468 va = trunc_page((vm_offset_t)addr); 469 /* 470 * XXX - MAX is END. Changed > to >= for temp. fix. 471 */ 472 if (va >= VM_MAXUSER_ADDRESS) 473 return (1); 474 /* 475 * XXX: rude stack hack adapted from trap(). 476 */ 477 nss = 0; 478 p = curproc; 479 vm = p->p_vmspace; 480 if ((caddr_t)va >= vm->vm_maxsaddr | 505 506 va = trunc_page((vm_offset_t)addr); 507 /* 508 * XXX - MAX is END. Changed > to >= for temp. fix. 509 */ 510 if (va >= VM_MAXUSER_ADDRESS) 511 return (1); 512 /* 513 * XXX: rude stack hack adapted from trap(). 514 */ 515 nss = 0; 516 p = curproc; 517 vm = p->p_vmspace; 518 if ((caddr_t)va >= vm->vm_maxsaddr |
481 && (caddr_t)va < (caddr_t)USRSTACK /* EWS 11/27/93 */ 482 && dostacklimits) { 483 nss = clrnd(btoc((unsigned)vm->vm_maxsaddr + MAXSSIZ 484 - (unsigned)va)); 485 if (nss > btoc(p->p_rlimit[RLIMIT_STACK].rlim_cur)) | 519 && (caddr_t)va < (caddr_t)USRSTACK) { 520 nss = roundup(USRSTACK - (unsigned)va, PAGE_SIZE); 521 if (nss > p->p_rlimit[RLIMIT_STACK].rlim_cur) |
486 return (1); | 522 return (1); |
523 524 if (vm->vm_ssize && roundup(vm->vm_ssize << PGSHIFT, 525 DFLSSIZ) < nss) { 526 int grow_amount; 527 /* 528 * If necessary, grow the VM that the stack occupies 529 * to allow for the rlimit. This allows us to not have 530 * to allocate all of the VM up-front in execve (which 531 * is expensive). 532 * Grow the VM by the amount requested rounded up to 533 * the nearest DFLSSIZ to provide for some hysteresis. 534 */ 535 grow_amount = roundup(nss, DFLSSIZ); 536 v = (char *)USRSTACK - roundup(vm->vm_ssize << PGSHIFT, DFLSSIZ) - 537 grow_amount; 538 /* 539 * If there isn't enough room to extend by DFLSSIZ, then 540 * just extend to the maximum size 541 */ 542 if (v < vm->vm_maxsaddr) { 543 v = vm->vm_maxsaddr; 544 grow_amount = MAXSSIZ - (vm->vm_ssize << PGSHIFT); 545 } 546 if (vm_allocate(&vm->vm_map, &v, grow_amount, FALSE) != 547 KERN_SUCCESS) { 548 return(1); 549 } 550 } |
|
487 } 488 489 if (vm_fault(&vm->vm_map, va, VM_PROT_READ | VM_PROT_WRITE, FALSE) 490 != KERN_SUCCESS) 491 return (1); 492 493 /* 494 * XXX: continuation of rude stack hack 495 */ | 551 } 552 553 if (vm_fault(&vm->vm_map, va, VM_PROT_READ | VM_PROT_WRITE, FALSE) 554 != KERN_SUCCESS) 555 return (1); 556 557 /* 558 * XXX: continuation of rude stack hack 559 */ |
560 nss = nss >> PGSHIFT; |
|
496 if (nss > vm->vm_ssize) 497 vm->vm_ssize = nss; 498 499 return (0); 500} 501 502/* 503 * syscall(frame): --- 135 unchanged lines hidden --- | 561 if (nss > vm->vm_ssize) 562 vm->vm_ssize = nss; 563 564 return (0); 565} 566 567/* 568 * syscall(frame): --- 135 unchanged lines hidden --- |