1 /* $NetBSD: kern_proc.c,v 1.58 2003/02/15 18:10:16 dsl Exp $ */ 2 3 /*- 4 * Copyright (c) 1999 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * Copyright (c) 1982, 1986, 1989, 1991, 1993 42 * The Regents of the University of California. All rights reserved. 43 * 44 * Redistribution and use in source and binary forms, with or without 45 * modification, are permitted provided that the following conditions 46 * are met: 47 * 1. Redistributions of source code must retain the above copyright 48 * notice, this list of conditions and the following disclaimer. 49 * 2. Redistributions in binary form must reproduce the above copyright 50 * notice, this list of conditions and the following disclaimer in the 51 * documentation and/or other materials provided with the distribution. 52 * 3. All advertising materials mentioning features or use of this software 53 * must display the following acknowledgement: 54 * This product includes software developed by the University of 55 * California, Berkeley and its contributors. 56 * 4. Neither the name of the University nor the names of its contributors 57 * may be used to endorse or promote products derived from this software 58 * without specific prior written permission. 59 * 60 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 61 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 62 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 63 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 64 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 65 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 66 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 70 * SUCH DAMAGE. 71 * 72 * @(#)kern_proc.c 8.7 (Berkeley) 2/14/95 73 */ 74 75 #include <sys/cdefs.h> 76 __KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.58 2003/02/15 18:10:16 dsl Exp $"); 77 78 #include "opt_kstack.h" 79 80 #include <sys/param.h> 81 #include <sys/systm.h> 82 #include <sys/kernel.h> 83 #include <sys/proc.h> 84 #include <sys/resourcevar.h> 85 #include <sys/buf.h> 86 #include <sys/acct.h> 87 #include <sys/wait.h> 88 #include <sys/file.h> 89 #include <ufs/ufs/quota.h> 90 #include <sys/uio.h> 91 #include <sys/malloc.h> 92 #include <sys/pool.h> 93 #include <sys/mbuf.h> 94 #include <sys/ioctl.h> 95 #include <sys/tty.h> 96 #include <sys/signalvar.h> 97 #include <sys/ras.h> 98 #include <sys/sa.h> 99 #include <sys/savar.h> 100 101 /* 102 * Structure associated with user cacheing. 103 */ 104 struct uidinfo { 105 LIST_ENTRY(uidinfo) ui_hash; 106 uid_t ui_uid; 107 long ui_proccnt; 108 }; 109 #define UIHASH(uid) (&uihashtbl[(uid) & uihash]) 110 LIST_HEAD(uihashhead, uidinfo) *uihashtbl; 111 u_long uihash; /* size of hash table - 1 */ 112 113 /* 114 * Other process lists 115 */ 116 struct pidhashhead *pidhashtbl; 117 u_long pidhash; 118 struct pgrphashhead *pgrphashtbl; 119 u_long pgrphash; 120 121 struct proclist allproc; 122 struct proclist zombproc; /* resources have been freed */ 123 124 125 /* 126 * Process list locking: 127 * 128 * We have two types of locks on the proclists: read locks and write 129 * locks. Read locks can be used in interrupt context, so while we 130 * hold the write lock, we must also block clock interrupts to 131 * lock out any scheduling changes that may happen in interrupt 132 * context. 133 * 134 * The proclist lock locks the following structures: 135 * 136 * allproc 137 * zombproc 138 * pidhashtbl 139 */ 140 struct lock proclist_lock; 141 142 /* 143 * Locking of this proclist is special; it's accessed in a 144 * critical section of process exit, and thus locking it can't 145 * modify interrupt state. We use a simple spin lock for this 146 * proclist. Processes on this proclist are also on zombproc; 147 * we use the p_hash member to linkup to deadproc. 148 */ 149 struct simplelock deadproc_slock; 150 struct proclist deadproc; /* dead, but not yet undead */ 151 152 struct pool proc_pool; 153 struct pool lwp_pool; 154 struct pool lwp_uc_pool; 155 struct pool pcred_pool; 156 struct pool plimit_pool; 157 struct pool pstats_pool; 158 struct pool pgrp_pool; 159 struct pool rusage_pool; 160 struct pool ras_pool; 161 struct pool sadata_pool; 162 struct pool saupcall_pool; 163 struct pool ptimer_pool; 164 165 MALLOC_DEFINE(M_EMULDATA, "emuldata", "Per-process emulation data"); 166 MALLOC_DEFINE(M_PROC, "proc", "Proc structures"); 167 MALLOC_DEFINE(M_SESSION, "session", "session header"); 168 MALLOC_DEFINE(M_SUBPROC, "subproc", "Proc sub-structures"); 169 170 /* 171 * The process list descriptors, used during pid allocation and 172 * by sysctl. No locking on this data structure is needed since 173 * it is completely static. 174 */ 175 const struct proclist_desc proclists[] = { 176 { &allproc }, 177 { &zombproc }, 178 { NULL }, 179 }; 180 181 static void orphanpg __P((struct pgrp *)); 182 #ifdef DEBUG 183 void pgrpdump __P((void)); 184 #endif 185 186 /* 187 * Initialize global process hashing structures. 188 */ 189 void 190 procinit() 191 { 192 const struct proclist_desc *pd; 193 194 for (pd = proclists; pd->pd_list != NULL; pd++) 195 LIST_INIT(pd->pd_list); 196 197 spinlockinit(&proclist_lock, "proclk", 0); 198 199 LIST_INIT(&deadproc); 200 simple_lock_init(&deadproc_slock); 201 202 LIST_INIT(&alllwp); 203 LIST_INIT(&deadlwp); 204 LIST_INIT(&zomblwp); 205 206 pidhashtbl = 207 hashinit(maxproc / 4, HASH_LIST, M_PROC, M_WAITOK, &pidhash); 208 pgrphashtbl = 209 hashinit(maxproc / 4, HASH_LIST, M_PROC, M_WAITOK, &pgrphash); 210 uihashtbl = 211 hashinit(maxproc / 16, HASH_LIST, M_PROC, M_WAITOK, &uihash); 212 213 pool_init(&proc_pool, sizeof(struct proc), 0, 0, 0, "procpl", 214 &pool_allocator_nointr); 215 pool_init(&lwp_pool, sizeof(struct lwp), 0, 0, 0, "lwppl", 216 &pool_allocator_nointr); 217 pool_init(&lwp_uc_pool, sizeof(ucontext_t), 0, 0, 0, "lwpucpl", 218 &pool_allocator_nointr); 219 pool_init(&pgrp_pool, sizeof(struct pgrp), 0, 0, 0, "pgrppl", 220 &pool_allocator_nointr); 221 pool_init(&pcred_pool, sizeof(struct pcred), 0, 0, 0, "pcredpl", 222 &pool_allocator_nointr); 223 pool_init(&plimit_pool, sizeof(struct plimit), 0, 0, 0, "plimitpl", 224 &pool_allocator_nointr); 225 pool_init(&pstats_pool, sizeof(struct pstats), 0, 0, 0, "pstatspl", 226 &pool_allocator_nointr); 227 pool_init(&rusage_pool, sizeof(struct rusage), 0, 0, 0, "rusgepl", 228 &pool_allocator_nointr); 229 pool_init(&ras_pool, sizeof(struct ras), 0, 0, 0, "raspl", 230 &pool_allocator_nointr); 231 pool_init(&sadata_pool, sizeof(struct sadata), 0, 0, 0, "sadatapl", 232 &pool_allocator_nointr); 233 pool_init(&saupcall_pool, sizeof(struct sadata_upcall), 0, 0, 0, 234 "saupcpl", 235 &pool_allocator_nointr); 236 pool_init(&ptimer_pool, sizeof(struct ptimer), 0, 0, 0, "ptimerpl", 237 &pool_allocator_nointr); 238 } 239 240 /* 241 * Acquire a read lock on the proclist. 242 */ 243 void 244 proclist_lock_read() 245 { 246 int error; 247 248 error = spinlockmgr(&proclist_lock, LK_SHARED, NULL); 249 #ifdef DIAGNOSTIC 250 if (__predict_false(error != 0)) 251 panic("proclist_lock_read: failed to acquire lock"); 252 #endif 253 } 254 255 /* 256 * Release a read lock on the proclist. 257 */ 258 void 259 proclist_unlock_read() 260 { 261 262 (void) spinlockmgr(&proclist_lock, LK_RELEASE, NULL); 263 } 264 265 /* 266 * Acquire a write lock on the proclist. 267 */ 268 int 269 proclist_lock_write() 270 { 271 int s, error; 272 273 s = splclock(); 274 error = spinlockmgr(&proclist_lock, LK_EXCLUSIVE, NULL); 275 #ifdef DIAGNOSTIC 276 if (__predict_false(error != 0)) 277 panic("proclist_lock: failed to acquire lock"); 278 #endif 279 return (s); 280 } 281 282 /* 283 * Release a write lock on the proclist. 284 */ 285 void 286 proclist_unlock_write(s) 287 int s; 288 { 289 290 (void) spinlockmgr(&proclist_lock, LK_RELEASE, NULL); 291 splx(s); 292 } 293 294 /* 295 * Change the count associated with number of processes 296 * a given user is using. 297 */ 298 int 299 chgproccnt(uid, diff) 300 uid_t uid; 301 int diff; 302 { 303 struct uidinfo *uip; 304 struct uihashhead *uipp; 305 306 uipp = UIHASH(uid); 307 308 LIST_FOREACH(uip, uipp, ui_hash) 309 if (uip->ui_uid == uid) 310 break; 311 312 if (uip) { 313 uip->ui_proccnt += diff; 314 if (uip->ui_proccnt > 0) 315 return (uip->ui_proccnt); 316 if (uip->ui_proccnt < 0) 317 panic("chgproccnt: procs < 0"); 318 LIST_REMOVE(uip, ui_hash); 319 FREE(uip, M_PROC); 320 return (0); 321 } 322 if (diff <= 0) { 323 if (diff == 0) 324 return(0); 325 panic("chgproccnt: lost user"); 326 } 327 MALLOC(uip, struct uidinfo *, sizeof(*uip), M_PROC, M_WAITOK); 328 LIST_INSERT_HEAD(uipp, uip, ui_hash); 329 uip->ui_uid = uid; 330 uip->ui_proccnt = diff; 331 return (diff); 332 } 333 334 /* 335 * Is p an inferior of q? 336 */ 337 int 338 inferior(p, q) 339 struct proc *p; 340 struct proc *q; 341 { 342 343 for (; p != q; p = p->p_pptr) 344 if (p->p_pid == 0) 345 return (0); 346 return (1); 347 } 348 349 /* 350 * Locate a process by number 351 */ 352 struct proc * 353 pfind(pid) 354 pid_t pid; 355 { 356 struct proc *p; 357 358 proclist_lock_read(); 359 LIST_FOREACH(p, PIDHASH(pid), p_hash) 360 if (p->p_pid == pid) 361 goto out; 362 out: 363 proclist_unlock_read(); 364 return (p); 365 } 366 367 /* 368 * Locate a process group by number 369 */ 370 struct pgrp * 371 pgfind(pgid) 372 pid_t pgid; 373 { 374 struct pgrp *pgrp; 375 376 LIST_FOREACH(pgrp, PGRPHASH(pgid), pg_hash) 377 if (pgrp->pg_id == pgid) 378 return (pgrp); 379 return (NULL); 380 } 381 382 /* 383 * Move p to a new or existing process group (and session) 384 */ 385 int 386 enterpgrp(p, pgid, mksess) 387 struct proc *p; 388 pid_t pgid; 389 int mksess; 390 { 391 struct pgrp *pgrp = pgfind(pgid); 392 393 #ifdef DIAGNOSTIC 394 if (__predict_false(pgrp != NULL && mksess)) /* firewalls */ 395 panic("enterpgrp: setsid into non-empty pgrp"); 396 if (__predict_false(SESS_LEADER(p))) 397 panic("enterpgrp: session leader attempted setpgrp"); 398 #endif 399 if (pgrp == NULL) { 400 pid_t savepid = p->p_pid; 401 struct proc *np; 402 /* 403 * new process group 404 */ 405 #ifdef DIAGNOSTIC 406 if (__predict_false(p->p_pid != pgid)) 407 panic("enterpgrp: new pgrp and pid != pgid"); 408 #endif 409 pgrp = pool_get(&pgrp_pool, PR_WAITOK); 410 if ((np = pfind(savepid)) == NULL || np != p) { 411 pool_put(&pgrp_pool, pgrp); 412 return (ESRCH); 413 } 414 if (mksess) { 415 struct session *sess; 416 417 /* 418 * new session 419 */ 420 MALLOC(sess, struct session *, sizeof(struct session), 421 M_SESSION, M_WAITOK); 422 if ((np = pfind(savepid)) == NULL || np != p) { 423 FREE(sess, M_SESSION); 424 pool_put(&pgrp_pool, pgrp); 425 return (ESRCH); 426 } 427 sess->s_sid = p->p_pid; 428 sess->s_leader = p; 429 sess->s_count = 1; 430 sess->s_ttyvp = NULL; 431 sess->s_ttyp = NULL; 432 sess->s_flags = p->p_session->s_flags & ~S_LOGIN_SET; 433 memcpy(sess->s_login, p->p_session->s_login, 434 sizeof(sess->s_login)); 435 p->p_flag &= ~P_CONTROLT; 436 pgrp->pg_session = sess; 437 #ifdef DIAGNOSTIC 438 if (__predict_false(p != curproc)) 439 panic("enterpgrp: mksession and p != curlwp"); 440 #endif 441 } else { 442 SESSHOLD(p->p_session); 443 pgrp->pg_session = p->p_session; 444 } 445 pgrp->pg_id = pgid; 446 LIST_INIT(&pgrp->pg_members); 447 LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash); 448 pgrp->pg_jobc = 0; 449 } else if (pgrp == p->p_pgrp) 450 return (0); 451 452 /* 453 * Adjust eligibility of affected pgrps to participate in job control. 454 * Increment eligibility counts before decrementing, otherwise we 455 * could reach 0 spuriously during the first call. 456 */ 457 fixjobc(p, pgrp, 1); 458 fixjobc(p, p->p_pgrp, 0); 459 460 LIST_REMOVE(p, p_pglist); 461 if (LIST_EMPTY(&p->p_pgrp->pg_members)) 462 pgdelete(p->p_pgrp); 463 p->p_pgrp = pgrp; 464 LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist); 465 return (0); 466 } 467 468 /* 469 * remove process from process group 470 */ 471 int 472 leavepgrp(p) 473 struct proc *p; 474 { 475 476 LIST_REMOVE(p, p_pglist); 477 if (LIST_EMPTY(&p->p_pgrp->pg_members)) 478 pgdelete(p->p_pgrp); 479 p->p_pgrp = 0; 480 return (0); 481 } 482 483 /* 484 * delete a process group 485 */ 486 void 487 pgdelete(pgrp) 488 struct pgrp *pgrp; 489 { 490 491 /* Remove reference (if any) from tty to this process group */ 492 if (pgrp->pg_session->s_ttyp != NULL && 493 pgrp->pg_session->s_ttyp->t_pgrp == pgrp) 494 pgrp->pg_session->s_ttyp->t_pgrp = NULL; 495 LIST_REMOVE(pgrp, pg_hash); 496 SESSRELE(pgrp->pg_session); 497 pool_put(&pgrp_pool, pgrp); 498 } 499 500 /* 501 * Adjust pgrp jobc counters when specified process changes process group. 502 * We count the number of processes in each process group that "qualify" 503 * the group for terminal job control (those with a parent in a different 504 * process group of the same session). If that count reaches zero, the 505 * process group becomes orphaned. Check both the specified process' 506 * process group and that of its children. 507 * entering == 0 => p is leaving specified group. 508 * entering == 1 => p is entering specified group. 509 */ 510 void 511 fixjobc(p, pgrp, entering) 512 struct proc *p; 513 struct pgrp *pgrp; 514 int entering; 515 { 516 struct pgrp *hispgrp; 517 struct session *mysession = pgrp->pg_session; 518 519 /* 520 * Check p's parent to see whether p qualifies its own process 521 * group; if so, adjust count for p's process group. 522 */ 523 if ((hispgrp = p->p_pptr->p_pgrp) != pgrp && 524 hispgrp->pg_session == mysession) { 525 if (entering) 526 pgrp->pg_jobc++; 527 else if (--pgrp->pg_jobc == 0) 528 orphanpg(pgrp); 529 } 530 531 /* 532 * Check this process' children to see whether they qualify 533 * their process groups; if so, adjust counts for children's 534 * process groups. 535 */ 536 LIST_FOREACH(p, &p->p_children, p_sibling) { 537 if ((hispgrp = p->p_pgrp) != pgrp && 538 hispgrp->pg_session == mysession && 539 P_ZOMBIE(p) == 0) { 540 if (entering) 541 hispgrp->pg_jobc++; 542 else if (--hispgrp->pg_jobc == 0) 543 orphanpg(hispgrp); 544 } 545 } 546 } 547 548 /* 549 * A process group has become orphaned; 550 * if there are any stopped processes in the group, 551 * hang-up all process in that group. 552 */ 553 static void 554 orphanpg(pg) 555 struct pgrp *pg; 556 { 557 struct proc *p; 558 559 LIST_FOREACH(p, &pg->pg_members, p_pglist) { 560 if (p->p_stat == SSTOP) { 561 LIST_FOREACH(p, &pg->pg_members, p_pglist) { 562 psignal(p, SIGHUP); 563 psignal(p, SIGCONT); 564 } 565 return; 566 } 567 } 568 } 569 570 /* mark process as suid/sgid, reset some values do defaults */ 571 void 572 p_sugid(p) 573 struct proc *p; 574 { 575 struct plimit *newlim; 576 577 p->p_flag |= P_SUGID; 578 /* reset what needs to be reset in plimit */ 579 if (p->p_limit->pl_corename != defcorename) { 580 if (p->p_limit->p_refcnt > 1 && 581 (p->p_limit->p_lflags & PL_SHAREMOD) == 0) { 582 newlim = limcopy(p->p_limit); 583 limfree(p->p_limit); 584 p->p_limit = newlim; 585 } 586 free(p->p_limit->pl_corename, M_TEMP); 587 p->p_limit->pl_corename = defcorename; 588 } 589 } 590 591 #ifdef DEBUG 592 void 593 pgrpdump() 594 { 595 struct pgrp *pgrp; 596 struct proc *p; 597 int i; 598 599 for (i = 0; i <= pgrphash; i++) { 600 if ((pgrp = LIST_FIRST(&pgrphashtbl[i])) != NULL) { 601 printf("\tindx %d\n", i); 602 for (; pgrp != 0; pgrp = pgrp->pg_hash.le_next) { 603 printf("\tpgrp %p, pgid %d, sess %p, " 604 "sesscnt %d, mem %p\n", 605 pgrp, pgrp->pg_id, pgrp->pg_session, 606 pgrp->pg_session->s_count, 607 LIST_FIRST(&pgrp->pg_members)); 608 LIST_FOREACH(p, &pgrp->pg_members, p_pglist) { 609 printf("\t\tpid %d addr %p pgrp %p\n", 610 p->p_pid, p, p->p_pgrp); 611 } 612 } 613 } 614 } 615 } 616 #endif /* DEBUG */ 617 618 #ifdef KSTACK_CHECK_MAGIC 619 #include <sys/user.h> 620 621 #define KSTACK_MAGIC 0xdeadbeaf 622 623 /* XXX should be per process basis? */ 624 int kstackleftmin = KSTACK_SIZE; 625 int kstackleftthres = KSTACK_SIZE / 8; /* warn if remaining stack is 626 less than this */ 627 628 void 629 kstack_setup_magic(const struct lwp *l) 630 { 631 u_int32_t *ip; 632 u_int32_t const *end; 633 634 KASSERT(l != NULL); 635 KASSERT(l != &lwp0); 636 637 /* 638 * fill all the stack with magic number 639 * so that later modification on it can be detected. 640 */ 641 ip = (u_int32_t *)KSTACK_LOWEST_ADDR(l); 642 end = (u_int32_t *)((caddr_t)KSTACK_LOWEST_ADDR(l) + KSTACK_SIZE); 643 for (; ip < end; ip++) { 644 *ip = KSTACK_MAGIC; 645 } 646 } 647 648 void 649 kstack_check_magic(const struct lwp *l) 650 { 651 u_int32_t const *ip, *end; 652 int stackleft; 653 654 KASSERT(l != NULL); 655 656 /* don't check proc0 */ /*XXX*/ 657 if (l == &lwp0) 658 return; 659 660 #ifdef __MACHINE_STACK_GROWS_UP 661 /* stack grows upwards (eg. hppa) */ 662 ip = (u_int32_t *)((caddr_t)KSTACK_LOWEST_ADDR(l) + KSTACK_SIZE); 663 end = (u_int32_t *)KSTACK_LOWEST_ADDR(l); 664 for (ip--; ip >= end; ip--) 665 if (*ip != KSTACK_MAGIC) 666 break; 667 668 stackleft = (caddr_t)KSTACK_LOWEST_ADDR(l) + KSTACK_SIZE - (caddr_t)ip; 669 #else /* __MACHINE_STACK_GROWS_UP */ 670 /* stack grows downwards (eg. i386) */ 671 ip = (u_int32_t *)KSTACK_LOWEST_ADDR(l); 672 end = (u_int32_t *)((caddr_t)KSTACK_LOWEST_ADDR(l) + KSTACK_SIZE); 673 for (; ip < end; ip++) 674 if (*ip != KSTACK_MAGIC) 675 break; 676 677 stackleft = (caddr_t)ip - KSTACK_LOWEST_ADDR(l); 678 #endif /* __MACHINE_STACK_GROWS_UP */ 679 680 if (kstackleftmin > stackleft) { 681 kstackleftmin = stackleft; 682 if (stackleft < kstackleftthres) 683 printf("warning: kernel stack left %d bytes" 684 "(pid %u:lid %u)\n", stackleft, 685 (u_int)l->l_proc->p_pid, (u_int)l->l_lid); 686 } 687 688 if (stackleft <= 0) { 689 panic("magic on the top of kernel stack changed for " 690 "pid %u, lid %u: maybe kernel stack overflow", 691 (u_int)l->l_proc->p_pid, (u_int)l->l_lid); 692 } 693 } 694 #endif /* KSTACK_CHECK_MAGIC */ 695