Print this page
XXX AVX procfs
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/fs/proc/prcontrol.c
+++ new/usr/src/uts/common/fs/proc/prcontrol.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27 #include <sys/types.h>
28 28 #include <sys/uio.h>
29 29 #include <sys/param.h>
30 30 #include <sys/cmn_err.h>
31 31 #include <sys/cred.h>
32 32 #include <sys/policy.h>
33 33 #include <sys/debug.h>
34 34 #include <sys/errno.h>
35 35 #include <sys/file.h>
36 36 #include <sys/inline.h>
37 37 #include <sys/kmem.h>
38 38 #include <sys/proc.h>
39 39 #include <sys/brand.h>
40 40 #include <sys/regset.h>
41 41 #include <sys/sysmacros.h>
42 42 #include <sys/systm.h>
43 43 #include <sys/vfs.h>
44 44 #include <sys/vnode.h>
45 45 #include <sys/signal.h>
46 46 #include <sys/auxv.h>
47 47 #include <sys/user.h>
48 48 #include <sys/class.h>
49 49 #include <sys/fault.h>
50 50 #include <sys/syscall.h>
51 51 #include <sys/procfs.h>
↓ open down ↓ |
51 lines elided |
↑ open up ↑ |
52 52 #include <sys/zone.h>
53 53 #include <sys/copyops.h>
54 54 #include <sys/schedctl.h>
55 55 #include <vm/as.h>
56 56 #include <vm/seg.h>
57 57 #include <fs/proc/prdata.h>
58 58 #include <sys/contract/process_impl.h>
59 59
60 60 static void pr_settrace(proc_t *, sigset_t *);
61 61 static int pr_setfpregs(prnode_t *, prfpregset_t *);
62 -#if defined(__sparc)
63 62 static int pr_setxregs(prnode_t *, prxregset_t *);
63 +#if defined(__sparc)
64 64 static int pr_setasrs(prnode_t *, asrset_t);
65 65 #endif
66 66 static int pr_setvaddr(prnode_t *, caddr_t);
67 67 static int pr_clearsig(prnode_t *);
68 68 static int pr_clearflt(prnode_t *);
69 69 static int pr_watch(prnode_t *, prwatch_t *, int *);
70 70 static int pr_agent(prnode_t *, prgregset_t, int *);
71 71 static int pr_rdwr(proc_t *, enum uio_rw, priovec_t *);
72 72 static int pr_scred(proc_t *, prcred_t *, cred_t *, boolean_t);
73 73 static int pr_spriv(proc_t *, prpriv_t *, cred_t *);
74 74 static int pr_szoneid(proc_t *, zoneid_t, cred_t *);
75 75 static void pauselwps(proc_t *);
76 76 static void unpauselwps(proc_t *);
77 77
78 78 typedef union {
79 79 long sig; /* PCKILL, PCUNKILL */
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
80 80 long nice; /* PCNICE */
81 81 long timeo; /* PCTWSTOP */
82 82 ulong_t flags; /* PCRUN, PCSET, PCUNSET */
83 83 caddr_t vaddr; /* PCSVADDR */
84 84 siginfo_t siginfo; /* PCSSIG */
85 85 sigset_t sigset; /* PCSTRACE, PCSHOLD */
86 86 fltset_t fltset; /* PCSFAULT */
87 87 sysset_t sysset; /* PCSENTRY, PCSEXIT */
88 88 prgregset_t prgregset; /* PCSREG, PCAGENT */
89 89 prfpregset_t prfpregset; /* PCSFPREG */
90 -#if defined(__sparc)
91 90 prxregset_t prxregset; /* PCSXREG */
91 +#if defined(__sparc)
92 92 asrset_t asrset; /* PCSASRS */
93 93 #endif
94 94 prwatch_t prwatch; /* PCWATCH */
95 95 priovec_t priovec; /* PCREAD, PCWRITE */
96 96 prcred_t prcred; /* PCSCRED */
97 97 prpriv_t prpriv; /* PCSPRIV */
98 98 long przoneid; /* PCSZONE */
99 99 } arg_t;
100 100
101 101 static int pr_control(long, arg_t *, prnode_t *, cred_t *);
102 102
103 103 static size_t
104 104 ctlsize(long cmd, size_t resid, arg_t *argp)
105 105 {
106 106 size_t size = sizeof (long);
107 107 size_t rnd;
108 108 int ngrp;
109 109
110 110 switch (cmd) {
111 111 case PCNULL:
112 112 case PCSTOP:
113 113 case PCDSTOP:
114 114 case PCWSTOP:
115 115 case PCCSIG:
116 116 case PCCFAULT:
117 117 break;
118 118 case PCSSIG:
119 119 size += sizeof (siginfo_t);
120 120 break;
121 121 case PCTWSTOP:
122 122 size += sizeof (long);
123 123 break;
124 124 case PCKILL:
125 125 case PCUNKILL:
126 126 case PCNICE:
127 127 size += sizeof (long);
128 128 break;
129 129 case PCRUN:
130 130 case PCSET:
131 131 case PCUNSET:
132 132 size += sizeof (ulong_t);
133 133 break;
134 134 case PCSVADDR:
135 135 size += sizeof (caddr_t);
136 136 break;
137 137 case PCSTRACE:
138 138 case PCSHOLD:
139 139 size += sizeof (sigset_t);
140 140 break;
141 141 case PCSFAULT:
142 142 size += sizeof (fltset_t);
143 143 break;
144 144 case PCSENTRY:
↓ open down ↓ |
43 lines elided |
↑ open up ↑ |
145 145 case PCSEXIT:
146 146 size += sizeof (sysset_t);
147 147 break;
148 148 case PCSREG:
149 149 case PCAGENT:
150 150 size += sizeof (prgregset_t);
151 151 break;
152 152 case PCSFPREG:
153 153 size += sizeof (prfpregset_t);
154 154 break;
155 -#if defined(__sparc)
156 155 case PCSXREG:
157 156 size += sizeof (prxregset_t);
158 157 break;
158 +#if defined(__sparc)
159 159 case PCSASRS:
160 160 size += sizeof (asrset_t);
161 161 break;
162 162 #endif
163 163 case PCWATCH:
164 164 size += sizeof (prwatch_t);
165 165 break;
166 166 case PCREAD:
167 167 case PCWRITE:
168 168 size += sizeof (priovec_t);
169 169 break;
170 170 case PCSCRED:
171 171 size += sizeof (prcred_t);
172 172 break;
173 173 case PCSCREDX:
174 174 /*
175 175 * We cannot derefence the pr_ngroups fields if it
176 176 * we don't have enough data.
177 177 */
178 178 if (resid < size + sizeof (prcred_t) - sizeof (gid_t))
179 179 return (0);
180 180 ngrp = argp->prcred.pr_ngroups;
181 181 if (ngrp < 0 || ngrp > ngroups_max)
182 182 return (0);
183 183
184 184 /* The result can be smaller than sizeof (prcred_t) */
185 185 size += sizeof (prcred_t) - sizeof (gid_t);
186 186 size += ngrp * sizeof (gid_t);
187 187 break;
188 188 case PCSPRIV:
189 189 if (resid >= size + sizeof (prpriv_t))
190 190 size += priv_prgetprivsize(&argp->prpriv);
191 191 else
192 192 return (0);
193 193 break;
194 194 case PCSZONE:
195 195 size += sizeof (long);
196 196 break;
197 197 default:
198 198 return (0);
199 199 }
200 200
201 201 /* Round up to a multiple of long, unless exact amount written */
202 202 if (size < resid) {
203 203 rnd = size & (sizeof (long) - 1);
204 204
205 205 if (rnd != 0)
206 206 size += sizeof (long) - rnd;
207 207 }
208 208
209 209 if (size > resid)
210 210 return (0);
211 211 return (size);
212 212 }
213 213
214 214 /*
215 215 * Control operations (lots).
216 216 */
217 217 int
218 218 prwritectl(vnode_t *vp, uio_t *uiop, cred_t *cr)
219 219 {
220 220 #define MY_BUFFER_SIZE \
221 221 100 > 1 + sizeof (arg_t) / sizeof (long) ? \
222 222 100 : 1 + sizeof (arg_t) / sizeof (long)
223 223 long buf[MY_BUFFER_SIZE];
224 224 long *bufp;
225 225 size_t resid = 0;
226 226 size_t size;
227 227 prnode_t *pnp = VTOP(vp);
228 228 int error;
229 229 int locked = 0;
230 230
231 231 while (uiop->uio_resid) {
232 232 /*
233 233 * Read several commands in one gulp.
234 234 */
235 235 bufp = buf;
236 236 if (resid) { /* move incomplete command to front of buffer */
237 237 long *tail;
238 238
239 239 if (resid >= sizeof (buf))
240 240 break;
241 241 tail = (long *)((char *)buf + sizeof (buf) - resid);
242 242 do {
243 243 *bufp++ = *tail++;
244 244 } while ((resid -= sizeof (long)) != 0);
245 245 }
246 246 resid = sizeof (buf) - ((char *)bufp - (char *)buf);
247 247 if (resid > uiop->uio_resid)
248 248 resid = uiop->uio_resid;
249 249 if (error = uiomove((caddr_t)bufp, resid, UIO_WRITE, uiop))
250 250 return (error);
251 251 resid += (char *)bufp - (char *)buf;
252 252 bufp = buf;
253 253
254 254 do { /* loop over commands in buffer */
255 255 long cmd = bufp[0];
256 256 arg_t *argp = (arg_t *)&bufp[1];
257 257
258 258 size = ctlsize(cmd, resid, argp);
259 259 if (size == 0) /* incomplete or invalid command */
260 260 break;
261 261 /*
262 262 * Perform the specified control operation.
263 263 */
264 264 if (!locked) {
265 265 if ((error = prlock(pnp, ZNO)) != 0)
266 266 return (error);
267 267 locked = 1;
268 268 }
269 269 if (error = pr_control(cmd, argp, pnp, cr)) {
270 270 if (error == -1) /* -1 is timeout */
271 271 locked = 0;
272 272 else
273 273 return (error);
274 274 }
275 275 bufp = (long *)((char *)bufp + size);
276 276 } while ((resid -= size) != 0);
277 277
278 278 if (locked) {
279 279 prunlock(pnp);
280 280 locked = 0;
281 281 }
282 282 }
283 283 return (resid? EINVAL : 0);
284 284 }
285 285
286 286 static int
287 287 pr_control(long cmd, arg_t *argp, prnode_t *pnp, cred_t *cr)
288 288 {
289 289 prcommon_t *pcp;
290 290 proc_t *p;
291 291 int unlocked;
292 292 int error = 0;
293 293
294 294 if (cmd == PCNULL)
295 295 return (0);
296 296
297 297 pcp = pnp->pr_common;
298 298 p = pcp->prc_proc;
299 299 ASSERT(p != NULL);
300 300
301 301 /* System processes defy control. */
302 302 if (p->p_flag & SSYS) {
303 303 prunlock(pnp);
304 304 return (EBUSY);
305 305 }
306 306
307 307 switch (cmd) {
308 308
309 309 default:
310 310 error = EINVAL;
311 311 break;
312 312
313 313 case PCSTOP: /* direct process or lwp to stop and wait for stop */
314 314 case PCDSTOP: /* direct process or lwp to stop, don't wait */
315 315 case PCWSTOP: /* wait for process or lwp to stop */
316 316 case PCTWSTOP: /* wait for process or lwp to stop, with timeout */
317 317 {
318 318 time_t timeo;
319 319
320 320 /*
321 321 * Can't apply to a system process.
322 322 */
323 323 if (p->p_as == &kas) {
324 324 error = EBUSY;
325 325 break;
326 326 }
327 327
328 328 if (cmd == PCSTOP || cmd == PCDSTOP)
329 329 pr_stop(pnp);
330 330
331 331 if (cmd == PCDSTOP)
332 332 break;
333 333
334 334 /*
335 335 * If an lwp is waiting for itself or its process,
336 336 * don't wait. The stopped lwp would never see the
337 337 * fact that it is stopped.
338 338 */
339 339 if ((pcp->prc_flags & PRC_LWP)?
340 340 (pcp->prc_thread == curthread) : (p == curproc)) {
341 341 if (cmd == PCWSTOP || cmd == PCTWSTOP)
342 342 error = EBUSY;
343 343 break;
344 344 }
345 345
346 346 timeo = (cmd == PCTWSTOP)? (time_t)argp->timeo : 0;
347 347 if ((error = pr_wait_stop(pnp, timeo)) != 0)
348 348 return (error);
349 349
350 350 break;
351 351 }
352 352
353 353 case PCRUN: /* make lwp or process runnable */
354 354 error = pr_setrun(pnp, argp->flags);
355 355 break;
356 356
357 357 case PCSTRACE: /* set signal trace mask */
358 358 pr_settrace(p, &argp->sigset);
359 359 break;
360 360
361 361 case PCSSIG: /* set current signal */
362 362 error = pr_setsig(pnp, &argp->siginfo);
363 363 if (argp->siginfo.si_signo == SIGKILL && error == 0) {
364 364 prunlock(pnp);
365 365 pr_wait_die(pnp);
366 366 return (-1);
367 367 }
368 368 break;
369 369
370 370 case PCKILL: /* send signal */
371 371 error = pr_kill(pnp, (int)argp->sig, cr);
372 372 if (error == 0 && argp->sig == SIGKILL) {
373 373 prunlock(pnp);
374 374 pr_wait_die(pnp);
375 375 return (-1);
376 376 }
377 377 break;
378 378
379 379 case PCUNKILL: /* delete a pending signal */
380 380 error = pr_unkill(pnp, (int)argp->sig);
381 381 break;
382 382
383 383 case PCNICE: /* set nice priority */
384 384 error = pr_nice(p, (int)argp->nice, cr);
385 385 break;
386 386
387 387 case PCSENTRY: /* set syscall entry bit mask */
388 388 case PCSEXIT: /* set syscall exit bit mask */
389 389 pr_setentryexit(p, &argp->sysset, cmd == PCSENTRY);
390 390 break;
391 391
392 392 case PCSET: /* set process flags */
393 393 error = pr_set(p, argp->flags);
394 394 break;
395 395
396 396 case PCUNSET: /* unset process flags */
397 397 error = pr_unset(p, argp->flags);
398 398 break;
399 399
400 400 case PCSREG: /* set general registers */
401 401 {
402 402 kthread_t *t = pr_thread(pnp);
403 403
404 404 if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) {
405 405 thread_unlock(t);
406 406 error = EBUSY;
407 407 } else {
408 408 thread_unlock(t);
409 409 mutex_exit(&p->p_lock);
410 410 prsetprregs(ttolwp(t), argp->prgregset, 0);
↓ open down ↓ |
242 lines elided |
↑ open up ↑ |
411 411 mutex_enter(&p->p_lock);
412 412 }
413 413 break;
414 414 }
415 415
416 416 case PCSFPREG: /* set floating-point registers */
417 417 error = pr_setfpregs(pnp, &argp->prfpregset);
418 418 break;
419 419
420 420 case PCSXREG: /* set extra registers */
421 -#if defined(__sparc)
422 421 error = pr_setxregs(pnp, &argp->prxregset);
423 -#else
424 - error = EINVAL;
425 -#endif
426 422 break;
427 423
428 424 #if defined(__sparc)
429 425 case PCSASRS: /* set ancillary state registers */
430 426 error = pr_setasrs(pnp, argp->asrset);
431 427 break;
432 428 #endif
433 429
434 430 case PCSVADDR: /* set virtual address at which to resume */
435 431 error = pr_setvaddr(pnp, argp->vaddr);
436 432 break;
437 433
438 434 case PCSHOLD: /* set signal-hold mask */
439 435 pr_sethold(pnp, &argp->sigset);
440 436 break;
441 437
442 438 case PCSFAULT: /* set mask of traced faults */
443 439 pr_setfault(p, &argp->fltset);
444 440 break;
445 441
446 442 case PCCSIG: /* clear current signal */
447 443 error = pr_clearsig(pnp);
448 444 break;
449 445
450 446 case PCCFAULT: /* clear current fault */
451 447 error = pr_clearflt(pnp);
452 448 break;
453 449
454 450 case PCWATCH: /* set or clear watched areas */
455 451 error = pr_watch(pnp, &argp->prwatch, &unlocked);
456 452 if (error && unlocked)
457 453 return (error);
458 454 break;
459 455
460 456 case PCAGENT: /* create the /proc agent lwp in the target process */
461 457 error = pr_agent(pnp, argp->prgregset, &unlocked);
462 458 if (error && unlocked)
463 459 return (error);
464 460 break;
465 461
466 462 case PCREAD: /* read from the address space */
467 463 error = pr_rdwr(p, UIO_READ, &argp->priovec);
468 464 break;
469 465
470 466 case PCWRITE: /* write to the address space */
471 467 error = pr_rdwr(p, UIO_WRITE, &argp->priovec);
472 468 break;
473 469
474 470 case PCSCRED: /* set the process credentials */
475 471 case PCSCREDX:
476 472 error = pr_scred(p, &argp->prcred, cr, cmd == PCSCREDX);
477 473 break;
478 474
479 475 case PCSPRIV: /* set the process privileges */
480 476 error = pr_spriv(p, &argp->prpriv, cr);
481 477 break;
482 478 case PCSZONE: /* set the process's zoneid credentials */
483 479 error = pr_szoneid(p, (zoneid_t)argp->przoneid, cr);
484 480 break;
485 481 }
486 482
487 483 if (error)
488 484 prunlock(pnp);
489 485 return (error);
490 486 }
491 487
492 488 #ifdef _SYSCALL32_IMPL
493 489
494 490 typedef union {
495 491 int32_t sig; /* PCKILL, PCUNKILL */
↓ open down ↓ |
60 lines elided |
↑ open up ↑ |
496 492 int32_t nice; /* PCNICE */
497 493 int32_t timeo; /* PCTWSTOP */
498 494 uint32_t flags; /* PCRUN, PCSET, PCUNSET */
499 495 caddr32_t vaddr; /* PCSVADDR */
500 496 siginfo32_t siginfo; /* PCSSIG */
501 497 sigset_t sigset; /* PCSTRACE, PCSHOLD */
502 498 fltset_t fltset; /* PCSFAULT */
503 499 sysset_t sysset; /* PCSENTRY, PCSEXIT */
504 500 prgregset32_t prgregset; /* PCSREG, PCAGENT */
505 501 prfpregset32_t prfpregset; /* PCSFPREG */
506 -#if defined(__sparc)
507 502 prxregset_t prxregset; /* PCSXREG */
508 -#endif
509 503 prwatch32_t prwatch; /* PCWATCH */
510 504 priovec32_t priovec; /* PCREAD, PCWRITE */
511 505 prcred32_t prcred; /* PCSCRED */
512 506 prpriv_t prpriv; /* PCSPRIV */
513 507 int32_t przoneid; /* PCSZONE */
514 508 } arg32_t;
515 509
516 510 static int pr_control32(int32_t, arg32_t *, prnode_t *, cred_t *);
517 511 static int pr_setfpregs32(prnode_t *, prfpregset32_t *);
518 512
519 513 /*
520 514 * Note that while ctlsize32() can use argp, it must do so only in a way
521 515 * that assumes 32-bit rather than 64-bit alignment as argp is a pointer
522 516 * to an array of 32-bit values and only 32-bit alignment is ensured.
523 517 */
524 518 static size_t
525 519 ctlsize32(int32_t cmd, size_t resid, arg32_t *argp)
526 520 {
527 521 size_t size = sizeof (int32_t);
528 522 size_t rnd;
529 523 int ngrp;
530 524
531 525 switch (cmd) {
532 526 case PCNULL:
533 527 case PCSTOP:
534 528 case PCDSTOP:
535 529 case PCWSTOP:
536 530 case PCCSIG:
537 531 case PCCFAULT:
538 532 break;
539 533 case PCSSIG:
540 534 size += sizeof (siginfo32_t);
541 535 break;
542 536 case PCTWSTOP:
543 537 size += sizeof (int32_t);
544 538 break;
545 539 case PCKILL:
546 540 case PCUNKILL:
547 541 case PCNICE:
548 542 size += sizeof (int32_t);
549 543 break;
550 544 case PCRUN:
551 545 case PCSET:
552 546 case PCUNSET:
553 547 size += sizeof (uint32_t);
554 548 break;
555 549 case PCSVADDR:
556 550 size += sizeof (caddr32_t);
557 551 break;
558 552 case PCSTRACE:
559 553 case PCSHOLD:
560 554 size += sizeof (sigset_t);
561 555 break;
562 556 case PCSFAULT:
563 557 size += sizeof (fltset_t);
564 558 break;
565 559 case PCSENTRY:
↓ open down ↓ |
47 lines elided |
↑ open up ↑ |
566 560 case PCSEXIT:
567 561 size += sizeof (sysset_t);
568 562 break;
569 563 case PCSREG:
570 564 case PCAGENT:
571 565 size += sizeof (prgregset32_t);
572 566 break;
573 567 case PCSFPREG:
574 568 size += sizeof (prfpregset32_t);
575 569 break;
576 -#if defined(__sparc)
577 570 case PCSXREG:
578 571 size += sizeof (prxregset_t);
579 572 break;
580 -#endif
581 573 case PCWATCH:
582 574 size += sizeof (prwatch32_t);
583 575 break;
584 576 case PCREAD:
585 577 case PCWRITE:
586 578 size += sizeof (priovec32_t);
587 579 break;
588 580 case PCSCRED:
589 581 size += sizeof (prcred32_t);
590 582 break;
591 583 case PCSCREDX:
592 584 /*
593 585 * We cannot derefence the pr_ngroups fields if it
594 586 * we don't have enough data.
595 587 */
596 588 if (resid < size + sizeof (prcred32_t) - sizeof (gid32_t))
597 589 return (0);
598 590 ngrp = argp->prcred.pr_ngroups;
599 591 if (ngrp < 0 || ngrp > ngroups_max)
600 592 return (0);
601 593
602 594 /* The result can be smaller than sizeof (prcred32_t) */
603 595 size += sizeof (prcred32_t) - sizeof (gid32_t);
604 596 size += ngrp * sizeof (gid32_t);
605 597 break;
606 598 case PCSPRIV:
607 599 if (resid >= size + sizeof (prpriv_t))
608 600 size += priv_prgetprivsize(&argp->prpriv);
609 601 else
610 602 return (0);
611 603 break;
612 604 case PCSZONE:
613 605 size += sizeof (int32_t);
614 606 break;
615 607 default:
616 608 return (0);
617 609 }
618 610
619 611 /* Round up to a multiple of int32_t */
620 612 rnd = size & (sizeof (int32_t) - 1);
621 613
622 614 if (rnd != 0)
623 615 size += sizeof (int32_t) - rnd;
624 616
625 617 if (size > resid)
626 618 return (0);
627 619 return (size);
628 620 }
629 621
630 622 /*
631 623 * Control operations (lots).
632 624 */
633 625 int
634 626 prwritectl32(struct vnode *vp, struct uio *uiop, cred_t *cr)
635 627 {
636 628 #define MY_BUFFER_SIZE32 \
637 629 100 > 1 + sizeof (arg32_t) / sizeof (int32_t) ? \
638 630 100 : 1 + sizeof (arg32_t) / sizeof (int32_t)
639 631 int32_t buf[MY_BUFFER_SIZE32];
640 632 int32_t *bufp;
641 633 arg32_t arg;
642 634 size_t resid = 0;
643 635 size_t size;
644 636 prnode_t *pnp = VTOP(vp);
645 637 int error;
646 638 int locked = 0;
647 639
648 640 while (uiop->uio_resid) {
649 641 /*
650 642 * Read several commands in one gulp.
651 643 */
652 644 bufp = buf;
653 645 if (resid) { /* move incomplete command to front of buffer */
654 646 int32_t *tail;
655 647
656 648 if (resid >= sizeof (buf))
657 649 break;
658 650 tail = (int32_t *)((char *)buf + sizeof (buf) - resid);
659 651 do {
660 652 *bufp++ = *tail++;
661 653 } while ((resid -= sizeof (int32_t)) != 0);
662 654 }
663 655 resid = sizeof (buf) - ((char *)bufp - (char *)buf);
664 656 if (resid > uiop->uio_resid)
665 657 resid = uiop->uio_resid;
666 658 if (error = uiomove((caddr_t)bufp, resid, UIO_WRITE, uiop))
667 659 return (error);
668 660 resid += (char *)bufp - (char *)buf;
669 661 bufp = buf;
670 662
671 663 do { /* loop over commands in buffer */
672 664 int32_t cmd = bufp[0];
673 665 arg32_t *argp = (arg32_t *)&bufp[1];
674 666
675 667 size = ctlsize32(cmd, resid, argp);
676 668 if (size == 0) /* incomplete or invalid command */
677 669 break;
678 670 /*
679 671 * Perform the specified control operation.
680 672 */
681 673 if (!locked) {
682 674 if ((error = prlock(pnp, ZNO)) != 0)
683 675 return (error);
684 676 locked = 1;
685 677 }
686 678
687 679 /*
688 680 * Since some members of the arg32_t union contain
689 681 * 64-bit values (which must be 64-bit aligned), we
690 682 * can't simply pass a pointer to the structure as
691 683 * it may be unaligned. Note that we do pass the
692 684 * potentially unaligned structure to ctlsize32()
693 685 * above, but that uses it a way that makes no
694 686 * assumptions about alignment.
695 687 */
696 688 ASSERT(size - sizeof (cmd) <= sizeof (arg));
697 689 bcopy(argp, &arg, size - sizeof (cmd));
698 690
699 691 if (error = pr_control32(cmd, &arg, pnp, cr)) {
700 692 if (error == -1) /* -1 is timeout */
701 693 locked = 0;
702 694 else
703 695 return (error);
704 696 }
705 697 bufp = (int32_t *)((char *)bufp + size);
706 698 } while ((resid -= size) != 0);
707 699
708 700 if (locked) {
709 701 prunlock(pnp);
710 702 locked = 0;
711 703 }
712 704 }
713 705 return (resid? EINVAL : 0);
714 706 }
715 707
716 708 static int
717 709 pr_control32(int32_t cmd, arg32_t *argp, prnode_t *pnp, cred_t *cr)
718 710 {
719 711 prcommon_t *pcp;
720 712 proc_t *p;
721 713 int unlocked;
722 714 int error = 0;
723 715
724 716 if (cmd == PCNULL)
725 717 return (0);
726 718
727 719 pcp = pnp->pr_common;
728 720 p = pcp->prc_proc;
729 721 ASSERT(p != NULL);
730 722
731 723 if (p->p_flag & SSYS) {
732 724 prunlock(pnp);
733 725 return (EBUSY);
734 726 }
735 727
736 728 switch (cmd) {
737 729
738 730 default:
739 731 error = EINVAL;
740 732 break;
741 733
742 734 case PCSTOP: /* direct process or lwp to stop and wait for stop */
743 735 case PCDSTOP: /* direct process or lwp to stop, don't wait */
744 736 case PCWSTOP: /* wait for process or lwp to stop */
745 737 case PCTWSTOP: /* wait for process or lwp to stop, with timeout */
746 738 {
747 739 time_t timeo;
748 740
749 741 /*
750 742 * Can't apply to a system process.
751 743 */
752 744 if (p->p_as == &kas) {
753 745 error = EBUSY;
754 746 break;
755 747 }
756 748
757 749 if (cmd == PCSTOP || cmd == PCDSTOP)
758 750 pr_stop(pnp);
759 751
760 752 if (cmd == PCDSTOP)
761 753 break;
762 754
763 755 /*
764 756 * If an lwp is waiting for itself or its process,
765 757 * don't wait. The lwp will never see the fact that
766 758 * itself is stopped.
767 759 */
768 760 if ((pcp->prc_flags & PRC_LWP)?
769 761 (pcp->prc_thread == curthread) : (p == curproc)) {
770 762 if (cmd == PCWSTOP || cmd == PCTWSTOP)
771 763 error = EBUSY;
772 764 break;
773 765 }
774 766
775 767 timeo = (cmd == PCTWSTOP)? (time_t)argp->timeo : 0;
776 768 if ((error = pr_wait_stop(pnp, timeo)) != 0)
777 769 return (error);
778 770
779 771 break;
780 772 }
781 773
782 774 case PCRUN: /* make lwp or process runnable */
783 775 error = pr_setrun(pnp, (ulong_t)argp->flags);
784 776 break;
785 777
786 778 case PCSTRACE: /* set signal trace mask */
787 779 pr_settrace(p, &argp->sigset);
788 780 break;
789 781
790 782 case PCSSIG: /* set current signal */
791 783 if (PROCESS_NOT_32BIT(p))
792 784 error = EOVERFLOW;
793 785 else {
794 786 int sig = (int)argp->siginfo.si_signo;
795 787 siginfo_t siginfo;
796 788
797 789 bzero(&siginfo, sizeof (siginfo));
798 790 siginfo_32tok(&argp->siginfo, (k_siginfo_t *)&siginfo);
799 791 error = pr_setsig(pnp, &siginfo);
800 792 if (sig == SIGKILL && error == 0) {
801 793 prunlock(pnp);
802 794 pr_wait_die(pnp);
803 795 return (-1);
804 796 }
805 797 }
806 798 break;
807 799
808 800 case PCKILL: /* send signal */
809 801 error = pr_kill(pnp, (int)argp->sig, cr);
810 802 if (error == 0 && argp->sig == SIGKILL) {
811 803 prunlock(pnp);
812 804 pr_wait_die(pnp);
813 805 return (-1);
814 806 }
815 807 break;
816 808
817 809 case PCUNKILL: /* delete a pending signal */
818 810 error = pr_unkill(pnp, (int)argp->sig);
819 811 break;
820 812
821 813 case PCNICE: /* set nice priority */
822 814 error = pr_nice(p, (int)argp->nice, cr);
823 815 break;
824 816
825 817 case PCSENTRY: /* set syscall entry bit mask */
826 818 case PCSEXIT: /* set syscall exit bit mask */
827 819 pr_setentryexit(p, &argp->sysset, cmd == PCSENTRY);
828 820 break;
829 821
830 822 case PCSET: /* set process flags */
831 823 error = pr_set(p, (long)argp->flags);
832 824 break;
833 825
834 826 case PCUNSET: /* unset process flags */
835 827 error = pr_unset(p, (long)argp->flags);
836 828 break;
837 829
838 830 case PCSREG: /* set general registers */
839 831 if (PROCESS_NOT_32BIT(p))
840 832 error = EOVERFLOW;
841 833 else {
842 834 kthread_t *t = pr_thread(pnp);
843 835
844 836 if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) {
845 837 thread_unlock(t);
846 838 error = EBUSY;
847 839 } else {
848 840 prgregset_t prgregset;
849 841 klwp_t *lwp = ttolwp(t);
850 842
851 843 thread_unlock(t);
852 844 mutex_exit(&p->p_lock);
853 845 prgregset_32ton(lwp, argp->prgregset,
854 846 prgregset);
855 847 prsetprregs(lwp, prgregset, 0);
856 848 mutex_enter(&p->p_lock);
857 849 }
858 850 }
↓ open down ↓ |
268 lines elided |
↑ open up ↑ |
859 851 break;
860 852
861 853 case PCSFPREG: /* set floating-point registers */
862 854 if (PROCESS_NOT_32BIT(p))
863 855 error = EOVERFLOW;
864 856 else
865 857 error = pr_setfpregs32(pnp, &argp->prfpregset);
866 858 break;
867 859
868 860 case PCSXREG: /* set extra registers */
869 -#if defined(__sparc)
870 861 if (PROCESS_NOT_32BIT(p))
871 862 error = EOVERFLOW;
872 863 else
873 864 error = pr_setxregs(pnp, &argp->prxregset);
874 -#else
875 - error = EINVAL;
876 -#endif
877 865 break;
878 866
879 867 case PCSVADDR: /* set virtual address at which to resume */
880 868 if (PROCESS_NOT_32BIT(p))
881 869 error = EOVERFLOW;
882 870 else
883 871 error = pr_setvaddr(pnp,
884 872 (caddr_t)(uintptr_t)argp->vaddr);
885 873 break;
886 874
887 875 case PCSHOLD: /* set signal-hold mask */
888 876 pr_sethold(pnp, &argp->sigset);
889 877 break;
890 878
891 879 case PCSFAULT: /* set mask of traced faults */
892 880 pr_setfault(p, &argp->fltset);
893 881 break;
894 882
895 883 case PCCSIG: /* clear current signal */
896 884 error = pr_clearsig(pnp);
897 885 break;
898 886
899 887 case PCCFAULT: /* clear current fault */
900 888 error = pr_clearflt(pnp);
901 889 break;
902 890
903 891 case PCWATCH: /* set or clear watched areas */
904 892 if (PROCESS_NOT_32BIT(p))
905 893 error = EOVERFLOW;
906 894 else {
907 895 prwatch_t prwatch;
908 896
909 897 prwatch.pr_vaddr = argp->prwatch.pr_vaddr;
910 898 prwatch.pr_size = argp->prwatch.pr_size;
911 899 prwatch.pr_wflags = argp->prwatch.pr_wflags;
912 900 prwatch.pr_pad = argp->prwatch.pr_pad;
913 901 error = pr_watch(pnp, &prwatch, &unlocked);
914 902 if (error && unlocked)
915 903 return (error);
916 904 }
917 905 break;
918 906
919 907 case PCAGENT: /* create the /proc agent lwp in the target process */
920 908 if (PROCESS_NOT_32BIT(p))
921 909 error = EOVERFLOW;
922 910 else {
923 911 prgregset_t prgregset;
924 912 kthread_t *t = pr_thread(pnp);
925 913 klwp_t *lwp = ttolwp(t);
926 914 thread_unlock(t);
927 915 mutex_exit(&p->p_lock);
928 916 prgregset_32ton(lwp, argp->prgregset, prgregset);
929 917 mutex_enter(&p->p_lock);
930 918 error = pr_agent(pnp, prgregset, &unlocked);
931 919 if (error && unlocked)
932 920 return (error);
933 921 }
934 922 break;
935 923
936 924 case PCREAD: /* read from the address space */
937 925 case PCWRITE: /* write to the address space */
938 926 if (PROCESS_NOT_32BIT(p))
939 927 error = EOVERFLOW;
940 928 else {
941 929 enum uio_rw rw = (cmd == PCREAD)? UIO_READ : UIO_WRITE;
942 930 priovec_t priovec;
943 931
944 932 priovec.pio_base =
945 933 (void *)(uintptr_t)argp->priovec.pio_base;
946 934 priovec.pio_len = (size_t)argp->priovec.pio_len;
947 935 priovec.pio_offset = (off_t)
948 936 (uint32_t)argp->priovec.pio_offset;
949 937 error = pr_rdwr(p, rw, &priovec);
950 938 }
951 939 break;
952 940
953 941 case PCSCRED: /* set the process credentials */
954 942 case PCSCREDX:
955 943 {
956 944 /*
957 945 * All the fields in these structures are exactly the
958 946 * same and so the structures are compatible. In case
959 947 * this ever changes, we catch this with the ASSERT
960 948 * below.
961 949 */
962 950 prcred_t *prcred = (prcred_t *)&argp->prcred;
963 951
964 952 #ifndef __lint
965 953 ASSERT(sizeof (prcred_t) == sizeof (prcred32_t));
966 954 #endif
967 955
968 956 error = pr_scred(p, prcred, cr, cmd == PCSCREDX);
969 957 break;
970 958 }
971 959
972 960 case PCSPRIV: /* set the process privileges */
973 961 error = pr_spriv(p, &argp->prpriv, cr);
974 962 break;
975 963
976 964 case PCSZONE: /* set the process's zoneid */
977 965 error = pr_szoneid(p, (zoneid_t)argp->przoneid, cr);
978 966 break;
979 967 }
980 968
981 969 if (error)
982 970 prunlock(pnp);
983 971 return (error);
984 972 }
985 973
986 974 #endif /* _SYSCALL32_IMPL */
987 975
988 976 /*
989 977 * Return the specific or chosen thread/lwp for a control operation.
990 978 * Returns with the thread locked via thread_lock(t).
991 979 */
992 980 kthread_t *
993 981 pr_thread(prnode_t *pnp)
994 982 {
995 983 prcommon_t *pcp = pnp->pr_common;
996 984 kthread_t *t;
997 985
998 986 if (pcp->prc_flags & PRC_LWP) {
999 987 t = pcp->prc_thread;
1000 988 ASSERT(t != NULL);
1001 989 thread_lock(t);
1002 990 } else {
1003 991 proc_t *p = pcp->prc_proc;
1004 992 t = prchoose(p); /* returns locked thread */
1005 993 ASSERT(t != NULL);
1006 994 }
1007 995
1008 996 return (t);
1009 997 }
1010 998
1011 999 /*
1012 1000 * Direct the process or lwp to stop.
1013 1001 */
1014 1002 void
1015 1003 pr_stop(prnode_t *pnp)
1016 1004 {
1017 1005 prcommon_t *pcp = pnp->pr_common;
1018 1006 proc_t *p = pcp->prc_proc;
1019 1007 kthread_t *t;
1020 1008 vnode_t *vp;
1021 1009
1022 1010 /*
1023 1011 * If already stopped, do nothing; otherwise flag
1024 1012 * it to be stopped the next time it tries to run.
1025 1013 * If sleeping at interruptible priority, set it
1026 1014 * running so it will stop within cv_wait_sig().
1027 1015 *
1028 1016 * Take care to cooperate with jobcontrol: if an lwp
1029 1017 * is stopped due to the default action of a jobcontrol
1030 1018 * stop signal, flag it to be stopped the next time it
1031 1019 * starts due to a SIGCONT signal.
1032 1020 */
1033 1021 if (pcp->prc_flags & PRC_LWP)
1034 1022 t = pcp->prc_thread;
1035 1023 else
1036 1024 t = p->p_tlist;
1037 1025 ASSERT(t != NULL);
1038 1026
1039 1027 do {
1040 1028 int notify;
1041 1029
1042 1030 notify = 0;
1043 1031 thread_lock(t);
1044 1032 if (!ISTOPPED(t)) {
1045 1033 t->t_proc_flag |= TP_PRSTOP;
1046 1034 t->t_sig_check = 1; /* do ISSIG */
1047 1035 }
1048 1036
1049 1037 /* Move the thread from wait queue to run queue */
1050 1038 if (ISWAITING(t))
1051 1039 setrun_locked(t);
1052 1040
1053 1041 if (ISWAKEABLE(t)) {
1054 1042 if (t->t_wchan0 == NULL)
1055 1043 setrun_locked(t);
1056 1044 else if (!VSTOPPED(t)) {
1057 1045 /*
1058 1046 * Mark it virtually stopped.
1059 1047 */
1060 1048 t->t_proc_flag |= TP_PRVSTOP;
1061 1049 notify = 1;
1062 1050 }
1063 1051 }
1064 1052 /*
1065 1053 * force the thread into the kernel
1066 1054 * if it is not already there.
1067 1055 */
1068 1056 prpokethread(t);
1069 1057 thread_unlock(t);
1070 1058 if (notify &&
1071 1059 (vp = p->p_lwpdir[t->t_dslot].ld_entry->le_trace) != NULL)
1072 1060 prnotify(vp);
1073 1061 if (pcp->prc_flags & PRC_LWP)
1074 1062 break;
1075 1063 } while ((t = t->t_forw) != p->p_tlist);
1076 1064
1077 1065 /*
1078 1066 * We do this just in case the thread we asked
1079 1067 * to stop is in holdlwps() (called from cfork()).
1080 1068 */
1081 1069 cv_broadcast(&p->p_holdlwps);
1082 1070 }
1083 1071
1084 1072 /*
1085 1073 * Sleep until the lwp stops, but cooperate with
1086 1074 * jobcontrol: Don't wake up if the lwp is stopped
1087 1075 * due to the default action of a jobcontrol stop signal.
1088 1076 * If this is the process file descriptor, sleep
1089 1077 * until all of the process's lwps stop.
1090 1078 */
1091 1079 int
1092 1080 pr_wait_stop(prnode_t *pnp, time_t timeo)
1093 1081 {
1094 1082 prcommon_t *pcp = pnp->pr_common;
1095 1083 proc_t *p = pcp->prc_proc;
1096 1084 timestruc_t rqtime;
1097 1085 timestruc_t *rqtp = NULL;
1098 1086 int timecheck = 0;
1099 1087 kthread_t *t;
1100 1088 int error;
1101 1089
1102 1090 if (timeo > 0) { /* millisecond timeout */
1103 1091 /*
1104 1092 * Determine the precise future time of the requested timeout.
1105 1093 */
1106 1094 timestruc_t now;
1107 1095
1108 1096 timecheck = timechanged;
1109 1097 gethrestime(&now);
1110 1098 rqtp = &rqtime;
1111 1099 rqtp->tv_sec = timeo / MILLISEC;
1112 1100 rqtp->tv_nsec = (timeo % MILLISEC) * MICROSEC;
1113 1101 timespecadd(rqtp, &now);
1114 1102 }
1115 1103
1116 1104 if (pcp->prc_flags & PRC_LWP) { /* lwp file descriptor */
1117 1105 t = pcp->prc_thread;
1118 1106 ASSERT(t != NULL);
1119 1107 thread_lock(t);
1120 1108 while (!ISTOPPED(t) && !VSTOPPED(t)) {
1121 1109 thread_unlock(t);
1122 1110 mutex_enter(&pcp->prc_mutex);
1123 1111 prunlock(pnp);
1124 1112 error = pr_wait(pcp, rqtp, timecheck);
1125 1113 if (error) /* -1 is timeout */
1126 1114 return (error);
1127 1115 if ((error = prlock(pnp, ZNO)) != 0)
1128 1116 return (error);
1129 1117 ASSERT(p == pcp->prc_proc);
1130 1118 ASSERT(t == pcp->prc_thread);
1131 1119 thread_lock(t);
1132 1120 }
1133 1121 thread_unlock(t);
1134 1122 } else { /* process file descriptor */
1135 1123 t = prchoose(p); /* returns locked thread */
1136 1124 ASSERT(t != NULL);
1137 1125 ASSERT(MUTEX_HELD(&p->p_lock));
1138 1126 while ((!ISTOPPED(t) && !VSTOPPED(t) && !SUSPENDED(t)) ||
1139 1127 (p->p_flag & SEXITLWPS)) {
1140 1128 thread_unlock(t);
1141 1129 mutex_enter(&pcp->prc_mutex);
1142 1130 prunlock(pnp);
1143 1131 error = pr_wait(pcp, rqtp, timecheck);
1144 1132 if (error) /* -1 is timeout */
1145 1133 return (error);
1146 1134 if ((error = prlock(pnp, ZNO)) != 0)
1147 1135 return (error);
1148 1136 ASSERT(p == pcp->prc_proc);
1149 1137 t = prchoose(p); /* returns locked t */
1150 1138 ASSERT(t != NULL);
1151 1139 }
1152 1140 thread_unlock(t);
1153 1141 }
1154 1142
1155 1143 ASSERT(!(pcp->prc_flags & PRC_DESTROY) && p->p_stat != SZOMB &&
1156 1144 t != NULL && t->t_state != TS_ZOMB);
1157 1145
1158 1146 return (0);
1159 1147 }
1160 1148
1161 1149 int
1162 1150 pr_setrun(prnode_t *pnp, ulong_t flags)
1163 1151 {
1164 1152 prcommon_t *pcp = pnp->pr_common;
1165 1153 proc_t *p = pcp->prc_proc;
1166 1154 kthread_t *t;
1167 1155 klwp_t *lwp;
1168 1156
1169 1157 /*
1170 1158 * Cannot set an lwp running if it is not stopped.
1171 1159 * Also, no lwp other than the /proc agent lwp can
1172 1160 * be set running so long as the /proc agent lwp exists.
1173 1161 */
1174 1162 t = pr_thread(pnp); /* returns locked thread */
1175 1163 if ((!ISTOPPED(t) && !VSTOPPED(t) &&
1176 1164 !(t->t_proc_flag & TP_PRSTOP)) ||
1177 1165 (p->p_agenttp != NULL &&
1178 1166 (t != p->p_agenttp || !(pcp->prc_flags & PRC_LWP)))) {
1179 1167 thread_unlock(t);
1180 1168 return (EBUSY);
1181 1169 }
1182 1170 thread_unlock(t);
1183 1171 if (flags & ~(PRCSIG|PRCFAULT|PRSTEP|PRSTOP|PRSABORT))
1184 1172 return (EINVAL);
1185 1173 lwp = ttolwp(t);
1186 1174 if ((flags & PRCSIG) && lwp->lwp_cursig != SIGKILL) {
1187 1175 /*
1188 1176 * Discard current siginfo_t, if any.
1189 1177 */
1190 1178 lwp->lwp_cursig = 0;
1191 1179 lwp->lwp_extsig = 0;
1192 1180 if (lwp->lwp_curinfo) {
1193 1181 siginfofree(lwp->lwp_curinfo);
1194 1182 lwp->lwp_curinfo = NULL;
1195 1183 }
1196 1184 }
1197 1185 if (flags & PRCFAULT)
1198 1186 lwp->lwp_curflt = 0;
1199 1187 /*
1200 1188 * We can't hold p->p_lock when we touch the lwp's registers.
1201 1189 * It may be swapped out and we will get a page fault.
1202 1190 */
1203 1191 if (flags & PRSTEP) {
1204 1192 mutex_exit(&p->p_lock);
1205 1193 prstep(lwp, 0);
1206 1194 mutex_enter(&p->p_lock);
1207 1195 }
1208 1196 if (flags & PRSTOP) {
1209 1197 t->t_proc_flag |= TP_PRSTOP;
1210 1198 t->t_sig_check = 1; /* do ISSIG */
1211 1199 }
1212 1200 if (flags & PRSABORT)
1213 1201 lwp->lwp_sysabort = 1;
1214 1202 thread_lock(t);
1215 1203 if ((pcp->prc_flags & PRC_LWP) || (flags & (PRSTEP|PRSTOP))) {
1216 1204 /*
1217 1205 * Here, we are dealing with a single lwp.
1218 1206 */
1219 1207 if (ISTOPPED(t)) {
1220 1208 t->t_schedflag |= TS_PSTART;
1221 1209 t->t_dtrace_stop = 0;
1222 1210 setrun_locked(t);
1223 1211 } else if (flags & PRSABORT) {
1224 1212 t->t_proc_flag &=
1225 1213 ~(TP_PRSTOP|TP_PRVSTOP|TP_STOPPING);
1226 1214 setrun_locked(t);
1227 1215 } else if (!(flags & PRSTOP)) {
1228 1216 t->t_proc_flag &=
1229 1217 ~(TP_PRSTOP|TP_PRVSTOP|TP_STOPPING);
1230 1218 }
1231 1219 thread_unlock(t);
1232 1220 } else {
1233 1221 /*
1234 1222 * Here, we are dealing with the whole process.
1235 1223 */
1236 1224 if (ISTOPPED(t)) {
1237 1225 /*
1238 1226 * The representative lwp is stopped on an event
1239 1227 * of interest. We demote it to PR_REQUESTED and
1240 1228 * choose another representative lwp. If the new
1241 1229 * representative lwp is not stopped on an event of
1242 1230 * interest (other than PR_REQUESTED), we set the
1243 1231 * whole process running, else we leave the process
1244 1232 * stopped showing the next event of interest.
1245 1233 */
1246 1234 kthread_t *tx = NULL;
1247 1235
1248 1236 if (!(flags & PRSABORT) &&
1249 1237 t->t_whystop == PR_SYSENTRY &&
1250 1238 t->t_whatstop == SYS_lwp_exit)
1251 1239 tx = t; /* remember the exiting lwp */
1252 1240 t->t_whystop = PR_REQUESTED;
1253 1241 t->t_whatstop = 0;
1254 1242 thread_unlock(t);
1255 1243 t = prchoose(p); /* returns locked t */
1256 1244 ASSERT(ISTOPPED(t) || VSTOPPED(t));
1257 1245 if (VSTOPPED(t) ||
1258 1246 t->t_whystop == PR_REQUESTED) {
1259 1247 thread_unlock(t);
1260 1248 allsetrun(p);
1261 1249 } else {
1262 1250 thread_unlock(t);
1263 1251 /*
1264 1252 * As a special case, if the old representative
1265 1253 * lwp was stopped on entry to _lwp_exit()
1266 1254 * (and we are not aborting the system call),
1267 1255 * we set the old representative lwp running.
1268 1256 * We do this so that the next process stop
1269 1257 * will find the exiting lwp gone.
1270 1258 */
1271 1259 if (tx != NULL) {
1272 1260 thread_lock(tx);
1273 1261 tx->t_schedflag |= TS_PSTART;
1274 1262 t->t_dtrace_stop = 0;
1275 1263 setrun_locked(tx);
1276 1264 thread_unlock(tx);
1277 1265 }
1278 1266 }
1279 1267 } else {
1280 1268 /*
1281 1269 * No event of interest; set all of the lwps running.
1282 1270 */
1283 1271 if (flags & PRSABORT) {
1284 1272 t->t_proc_flag &=
1285 1273 ~(TP_PRSTOP|TP_PRVSTOP|TP_STOPPING);
1286 1274 setrun_locked(t);
1287 1275 }
1288 1276 thread_unlock(t);
1289 1277 allsetrun(p);
1290 1278 }
1291 1279 }
1292 1280 return (0);
1293 1281 }
1294 1282
1295 1283 /*
1296 1284 * Wait until process/lwp stops or until timer expires.
1297 1285 * Return EINTR for an interruption, -1 for timeout, else 0.
1298 1286 */
1299 1287 int
1300 1288 pr_wait(prcommon_t *pcp, /* prcommon referring to process/lwp */
1301 1289 timestruc_t *ts, /* absolute time of timeout, if any */
1302 1290 int timecheck)
1303 1291 {
1304 1292 int rval;
1305 1293
1306 1294 ASSERT(MUTEX_HELD(&pcp->prc_mutex));
1307 1295 rval = cv_waituntil_sig(&pcp->prc_wait, &pcp->prc_mutex, ts, timecheck);
1308 1296 mutex_exit(&pcp->prc_mutex);
1309 1297 switch (rval) {
1310 1298 case 0:
1311 1299 return (EINTR);
1312 1300 case -1:
1313 1301 return (-1);
1314 1302 default:
1315 1303 return (0);
1316 1304 }
1317 1305 }
1318 1306
1319 1307 /*
1320 1308 * Make all threads in the process runnable.
1321 1309 */
1322 1310 void
1323 1311 allsetrun(proc_t *p)
1324 1312 {
1325 1313 kthread_t *t;
1326 1314
1327 1315 ASSERT(MUTEX_HELD(&p->p_lock));
1328 1316
1329 1317 if ((t = p->p_tlist) != NULL) {
1330 1318 do {
1331 1319 thread_lock(t);
1332 1320 ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
1333 1321 t->t_proc_flag &= ~(TP_PRSTOP|TP_PRVSTOP|TP_STOPPING);
1334 1322 if (ISTOPPED(t)) {
1335 1323 t->t_schedflag |= TS_PSTART;
1336 1324 t->t_dtrace_stop = 0;
1337 1325 setrun_locked(t);
1338 1326 }
1339 1327 thread_unlock(t);
1340 1328 } while ((t = t->t_forw) != p->p_tlist);
1341 1329 }
1342 1330 }
1343 1331
1344 1332 /*
1345 1333 * Wait for the process to die.
1346 1334 * We do this after sending SIGKILL because we know it will
1347 1335 * die soon and we want subsequent operations to return ENOENT.
1348 1336 */
1349 1337 void
1350 1338 pr_wait_die(prnode_t *pnp)
1351 1339 {
1352 1340 proc_t *p;
1353 1341
1354 1342 mutex_enter(&pidlock);
1355 1343 while ((p = pnp->pr_common->prc_proc) != NULL && p->p_stat != SZOMB) {
1356 1344 if (!cv_wait_sig(&p->p_srwchan_cv, &pidlock))
1357 1345 break;
1358 1346 }
1359 1347 mutex_exit(&pidlock);
1360 1348 }
1361 1349
1362 1350 static void
1363 1351 pr_settrace(proc_t *p, sigset_t *sp)
1364 1352 {
1365 1353 prdelset(sp, SIGKILL);
1366 1354 prassignset(&p->p_sigmask, sp);
1367 1355 if (!sigisempty(&p->p_sigmask))
1368 1356 p->p_proc_flag |= P_PR_TRACE;
1369 1357 else if (prisempty(&p->p_fltmask)) {
1370 1358 user_t *up = PTOU(p);
1371 1359 if (up->u_systrap == 0)
1372 1360 p->p_proc_flag &= ~P_PR_TRACE;
1373 1361 }
1374 1362 }
1375 1363
1376 1364 int
1377 1365 pr_setsig(prnode_t *pnp, siginfo_t *sip)
1378 1366 {
1379 1367 int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
1380 1368 int sig = sip->si_signo;
1381 1369 prcommon_t *pcp = pnp->pr_common;
1382 1370 proc_t *p = pcp->prc_proc;
1383 1371 kthread_t *t;
1384 1372 klwp_t *lwp;
1385 1373 int error = 0;
1386 1374
1387 1375 t = pr_thread(pnp); /* returns locked thread */
1388 1376 thread_unlock(t);
1389 1377 lwp = ttolwp(t);
1390 1378 if (sig < 0 || sig >= nsig)
1391 1379 /* Zero allowed here */
1392 1380 error = EINVAL;
1393 1381 else if (lwp->lwp_cursig == SIGKILL)
1394 1382 /* "can't happen", but just in case */
1395 1383 error = EBUSY;
1396 1384 else if ((lwp->lwp_cursig = (uchar_t)sig) == 0) {
1397 1385 lwp->lwp_extsig = 0;
1398 1386 /*
1399 1387 * Discard current siginfo_t, if any.
1400 1388 */
1401 1389 if (lwp->lwp_curinfo) {
1402 1390 siginfofree(lwp->lwp_curinfo);
1403 1391 lwp->lwp_curinfo = NULL;
1404 1392 }
1405 1393 } else {
1406 1394 kthread_t *tx;
1407 1395 sigqueue_t *sqp;
1408 1396
1409 1397 /* drop p_lock to do kmem_alloc(KM_SLEEP) */
1410 1398 mutex_exit(&p->p_lock);
1411 1399 sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP);
1412 1400 mutex_enter(&p->p_lock);
1413 1401
1414 1402 if (lwp->lwp_curinfo == NULL)
1415 1403 lwp->lwp_curinfo = sqp;
1416 1404 else
1417 1405 kmem_free(sqp, sizeof (sigqueue_t));
1418 1406 /*
1419 1407 * Copy contents of info to current siginfo_t.
1420 1408 */
1421 1409 bcopy(sip, &lwp->lwp_curinfo->sq_info,
1422 1410 sizeof (lwp->lwp_curinfo->sq_info));
1423 1411 /*
1424 1412 * Prevent contents published by si_zoneid-unaware /proc
1425 1413 * consumers from being incorrectly filtered. Because
1426 1414 * an uninitialized si_zoneid is the same as
1427 1415 * GLOBAL_ZONEID, this means that you can't pr_setsig a
1428 1416 * process in a non-global zone with a siginfo which
1429 1417 * appears to come from the global zone.
1430 1418 */
1431 1419 if (SI_FROMUSER(sip) && sip->si_zoneid == 0)
1432 1420 lwp->lwp_curinfo->sq_info.si_zoneid =
1433 1421 p->p_zone->zone_id;
1434 1422 /*
1435 1423 * Side-effects for SIGKILL and jobcontrol signals.
1436 1424 */
1437 1425 if (sig == SIGKILL) {
1438 1426 p->p_flag |= SKILLED;
1439 1427 p->p_flag &= ~SEXTKILLED;
1440 1428 } else if (sig == SIGCONT) {
1441 1429 p->p_flag |= SSCONT;
1442 1430 sigdelq(p, NULL, SIGSTOP);
1443 1431 sigdelq(p, NULL, SIGTSTP);
1444 1432 sigdelq(p, NULL, SIGTTOU);
1445 1433 sigdelq(p, NULL, SIGTTIN);
1446 1434 sigdiffset(&p->p_sig, &stopdefault);
1447 1435 sigdiffset(&p->p_extsig, &stopdefault);
1448 1436 if ((tx = p->p_tlist) != NULL) {
1449 1437 do {
1450 1438 sigdelq(p, tx, SIGSTOP);
1451 1439 sigdelq(p, tx, SIGTSTP);
1452 1440 sigdelq(p, tx, SIGTTOU);
1453 1441 sigdelq(p, tx, SIGTTIN);
1454 1442 sigdiffset(&tx->t_sig, &stopdefault);
1455 1443 sigdiffset(&tx->t_extsig, &stopdefault);
1456 1444 } while ((tx = tx->t_forw) != p->p_tlist);
1457 1445 }
1458 1446 } else if (sigismember(&stopdefault, sig)) {
1459 1447 if (PTOU(p)->u_signal[sig-1] == SIG_DFL &&
1460 1448 (sig == SIGSTOP || !p->p_pgidp->pid_pgorphaned))
1461 1449 p->p_flag &= ~SSCONT;
1462 1450 sigdelq(p, NULL, SIGCONT);
1463 1451 sigdelset(&p->p_sig, SIGCONT);
1464 1452 sigdelset(&p->p_extsig, SIGCONT);
1465 1453 if ((tx = p->p_tlist) != NULL) {
1466 1454 do {
1467 1455 sigdelq(p, tx, SIGCONT);
1468 1456 sigdelset(&tx->t_sig, SIGCONT);
1469 1457 sigdelset(&tx->t_extsig, SIGCONT);
1470 1458 } while ((tx = tx->t_forw) != p->p_tlist);
1471 1459 }
1472 1460 }
1473 1461 thread_lock(t);
1474 1462 if (ISWAKEABLE(t) || ISWAITING(t)) {
1475 1463 /* Set signaled sleeping/waiting lwp running */
1476 1464 setrun_locked(t);
1477 1465 } else if (t->t_state == TS_STOPPED && sig == SIGKILL) {
1478 1466 /* If SIGKILL, set stopped lwp running */
1479 1467 p->p_stopsig = 0;
1480 1468 t->t_schedflag |= TS_XSTART | TS_PSTART;
1481 1469 t->t_dtrace_stop = 0;
1482 1470 setrun_locked(t);
1483 1471 }
1484 1472 t->t_sig_check = 1; /* so ISSIG will be done */
1485 1473 thread_unlock(t);
1486 1474 /*
1487 1475 * More jobcontrol side-effects.
1488 1476 */
1489 1477 if (sig == SIGCONT && (tx = p->p_tlist) != NULL) {
1490 1478 p->p_stopsig = 0;
1491 1479 do {
1492 1480 thread_lock(tx);
1493 1481 if (tx->t_state == TS_STOPPED &&
1494 1482 tx->t_whystop == PR_JOBCONTROL) {
1495 1483 tx->t_schedflag |= TS_XSTART;
1496 1484 setrun_locked(tx);
1497 1485 }
1498 1486 thread_unlock(tx);
1499 1487 } while ((tx = tx->t_forw) != p->p_tlist);
1500 1488 }
1501 1489 }
1502 1490 return (error);
1503 1491 }
1504 1492
1505 1493 int
1506 1494 pr_kill(prnode_t *pnp, int sig, cred_t *cr)
1507 1495 {
1508 1496 int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
1509 1497 prcommon_t *pcp = pnp->pr_common;
1510 1498 proc_t *p = pcp->prc_proc;
1511 1499 k_siginfo_t info;
1512 1500
1513 1501 if (sig <= 0 || sig >= nsig)
1514 1502 return (EINVAL);
1515 1503
1516 1504 bzero(&info, sizeof (info));
1517 1505 info.si_signo = sig;
1518 1506 info.si_code = SI_USER;
1519 1507 info.si_pid = curproc->p_pid;
1520 1508 info.si_ctid = PRCTID(curproc);
1521 1509 info.si_zoneid = getzoneid();
1522 1510 info.si_uid = crgetruid(cr);
1523 1511 sigaddq(p, (pcp->prc_flags & PRC_LWP)?
1524 1512 pcp->prc_thread : NULL, &info, KM_NOSLEEP);
1525 1513
1526 1514 return (0);
1527 1515 }
1528 1516
1529 1517 int
1530 1518 pr_unkill(prnode_t *pnp, int sig)
1531 1519 {
1532 1520 int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
1533 1521 prcommon_t *pcp = pnp->pr_common;
1534 1522 proc_t *p = pcp->prc_proc;
1535 1523 sigqueue_t *infop = NULL;
1536 1524
1537 1525 if (sig <= 0 || sig >= nsig || sig == SIGKILL)
1538 1526 return (EINVAL);
1539 1527
1540 1528 if (pcp->prc_flags & PRC_LWP)
1541 1529 sigdeq(p, pcp->prc_thread, sig, &infop);
1542 1530 else
1543 1531 sigdeq(p, NULL, sig, &infop);
1544 1532
1545 1533 if (infop)
1546 1534 siginfofree(infop);
1547 1535
1548 1536 return (0);
1549 1537 }
1550 1538
1551 1539 int
1552 1540 pr_nice(proc_t *p, int nice, cred_t *cr)
1553 1541 {
1554 1542 kthread_t *t;
1555 1543 int err;
1556 1544 int error = 0;
1557 1545
1558 1546 t = p->p_tlist;
1559 1547 do {
1560 1548 ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
1561 1549 err = CL_DONICE(t, cr, nice, (int *)NULL);
1562 1550 schedctl_set_cidpri(t);
1563 1551 if (error == 0)
1564 1552 error = err;
1565 1553 } while ((t = t->t_forw) != p->p_tlist);
1566 1554
1567 1555 return (error);
1568 1556 }
1569 1557
1570 1558 void
1571 1559 pr_setentryexit(proc_t *p, sysset_t *sysset, int entry)
1572 1560 {
1573 1561 user_t *up = PTOU(p);
1574 1562
1575 1563 if (entry) {
1576 1564 prassignset(&up->u_entrymask, sysset);
1577 1565 } else {
1578 1566 prassignset(&up->u_exitmask, sysset);
1579 1567 }
1580 1568 if (!prisempty(&up->u_entrymask) ||
1581 1569 !prisempty(&up->u_exitmask)) {
1582 1570 up->u_systrap = 1;
1583 1571 p->p_proc_flag |= P_PR_TRACE;
1584 1572 set_proc_sys(p); /* set pre and post-sys flags */
1585 1573 } else {
1586 1574 up->u_systrap = 0;
1587 1575 if (sigisempty(&p->p_sigmask) &&
1588 1576 prisempty(&p->p_fltmask))
1589 1577 p->p_proc_flag &= ~P_PR_TRACE;
1590 1578 }
1591 1579 }
1592 1580
1593 1581 #define ALLFLAGS \
1594 1582 (PR_FORK|PR_RLC|PR_KLC|PR_ASYNC|PR_BPTADJ|PR_MSACCT|PR_MSFORK|PR_PTRACE)
1595 1583
1596 1584 int
1597 1585 pr_set(proc_t *p, long flags)
1598 1586 {
1599 1587 if ((p->p_flag & SSYS) || p->p_as == &kas)
1600 1588 return (EBUSY);
1601 1589
1602 1590 if (flags & ~ALLFLAGS)
1603 1591 return (EINVAL);
1604 1592
1605 1593 if (flags & PR_FORK)
1606 1594 p->p_proc_flag |= P_PR_FORK;
1607 1595 if (flags & PR_RLC)
1608 1596 p->p_proc_flag |= P_PR_RUNLCL;
1609 1597 if (flags & PR_KLC)
1610 1598 p->p_proc_flag |= P_PR_KILLCL;
1611 1599 if (flags & PR_ASYNC)
1612 1600 p->p_proc_flag |= P_PR_ASYNC;
1613 1601 if (flags & PR_BPTADJ)
1614 1602 p->p_proc_flag |= P_PR_BPTADJ;
1615 1603 if (flags & PR_MSACCT)
1616 1604 if ((p->p_flag & SMSACCT) == 0)
1617 1605 estimate_msacct(p->p_tlist, gethrtime());
1618 1606 if (flags & PR_MSFORK)
1619 1607 p->p_flag |= SMSFORK;
1620 1608 if (flags & PR_PTRACE) {
1621 1609 p->p_proc_flag |= P_PR_PTRACE;
1622 1610 /* ptraced process must die if parent dead */
1623 1611 if (p->p_ppid == 1)
1624 1612 sigtoproc(p, NULL, SIGKILL);
1625 1613 }
1626 1614
1627 1615 return (0);
1628 1616 }
1629 1617
1630 1618 int
1631 1619 pr_unset(proc_t *p, long flags)
1632 1620 {
1633 1621 if ((p->p_flag & SSYS) || p->p_as == &kas)
1634 1622 return (EBUSY);
1635 1623
1636 1624 if (flags & ~ALLFLAGS)
1637 1625 return (EINVAL);
1638 1626
1639 1627 if (flags & PR_FORK)
1640 1628 p->p_proc_flag &= ~P_PR_FORK;
1641 1629 if (flags & PR_RLC)
1642 1630 p->p_proc_flag &= ~P_PR_RUNLCL;
1643 1631 if (flags & PR_KLC)
1644 1632 p->p_proc_flag &= ~P_PR_KILLCL;
1645 1633 if (flags & PR_ASYNC)
1646 1634 p->p_proc_flag &= ~P_PR_ASYNC;
1647 1635 if (flags & PR_BPTADJ)
1648 1636 p->p_proc_flag &= ~P_PR_BPTADJ;
1649 1637 if (flags & PR_MSACCT)
1650 1638 disable_msacct(p);
1651 1639 if (flags & PR_MSFORK)
1652 1640 p->p_flag &= ~SMSFORK;
1653 1641 if (flags & PR_PTRACE)
1654 1642 p->p_proc_flag &= ~P_PR_PTRACE;
1655 1643
1656 1644 return (0);
1657 1645 }
1658 1646
1659 1647 static int
1660 1648 pr_setfpregs(prnode_t *pnp, prfpregset_t *prfpregset)
1661 1649 {
1662 1650 proc_t *p = pnp->pr_common->prc_proc;
1663 1651 kthread_t *t = pr_thread(pnp); /* returns locked thread */
1664 1652
1665 1653 if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) {
1666 1654 thread_unlock(t);
1667 1655 return (EBUSY);
1668 1656 }
1669 1657 if (!prhasfp()) {
1670 1658 thread_unlock(t);
1671 1659 return (EINVAL); /* No FP support */
1672 1660 }
1673 1661
1674 1662 /* drop p_lock while touching the lwp's stack */
1675 1663 thread_unlock(t);
1676 1664 mutex_exit(&p->p_lock);
1677 1665 prsetprfpregs(ttolwp(t), prfpregset);
1678 1666 mutex_enter(&p->p_lock);
1679 1667
1680 1668 return (0);
1681 1669 }
1682 1670
1683 1671 #ifdef _SYSCALL32_IMPL
1684 1672 static int
1685 1673 pr_setfpregs32(prnode_t *pnp, prfpregset32_t *prfpregset)
1686 1674 {
1687 1675 proc_t *p = pnp->pr_common->prc_proc;
1688 1676 kthread_t *t = pr_thread(pnp); /* returns locked thread */
1689 1677
1690 1678 if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) {
1691 1679 thread_unlock(t);
1692 1680 return (EBUSY);
1693 1681 }
1694 1682 if (!prhasfp()) {
1695 1683 thread_unlock(t);
1696 1684 return (EINVAL); /* No FP support */
1697 1685 }
1698 1686
↓ open down ↓ |
812 lines elided |
↑ open up ↑ |
1699 1687 /* drop p_lock while touching the lwp's stack */
1700 1688 thread_unlock(t);
1701 1689 mutex_exit(&p->p_lock);
1702 1690 prsetprfpregs32(ttolwp(t), prfpregset);
1703 1691 mutex_enter(&p->p_lock);
1704 1692
1705 1693 return (0);
1706 1694 }
1707 1695 #endif /* _SYSCALL32_IMPL */
1708 1696
1709 -#if defined(__sparc)
1710 1697 /* ARGSUSED */
1711 1698 static int
1712 1699 pr_setxregs(prnode_t *pnp, prxregset_t *prxregset)
1713 1700 {
1714 1701 proc_t *p = pnp->pr_common->prc_proc;
1715 1702 kthread_t *t = pr_thread(pnp); /* returns locked thread */
1716 1703
1717 1704 if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) {
1718 1705 thread_unlock(t);
1719 1706 return (EBUSY);
1720 1707 }
1721 1708 thread_unlock(t);
1722 1709
1723 1710 if (!prhasx(p))
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
1724 1711 return (EINVAL); /* No extra register support */
1725 1712
1726 1713 /* drop p_lock while touching the lwp's stack */
1727 1714 mutex_exit(&p->p_lock);
1728 1715 prsetprxregs(ttolwp(t), (caddr_t)prxregset);
1729 1716 mutex_enter(&p->p_lock);
1730 1717
1731 1718 return (0);
1732 1719 }
1733 1720
1721 +#if defined(__sparc)
1734 1722 static int
1735 1723 pr_setasrs(prnode_t *pnp, asrset_t asrset)
1736 1724 {
1737 1725 proc_t *p = pnp->pr_common->prc_proc;
1738 1726 kthread_t *t = pr_thread(pnp); /* returns locked thread */
1739 1727
1740 1728 if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) {
1741 1729 thread_unlock(t);
1742 1730 return (EBUSY);
1743 1731 }
1744 1732 thread_unlock(t);
1745 1733
1746 1734 /* drop p_lock while touching the lwp's stack */
1747 1735 mutex_exit(&p->p_lock);
1748 1736 prsetasregs(ttolwp(t), asrset);
1749 1737 mutex_enter(&p->p_lock);
1750 1738
1751 1739 return (0);
1752 1740 }
1753 1741 #endif
1754 1742
1755 1743 static int
1756 1744 pr_setvaddr(prnode_t *pnp, caddr_t vaddr)
1757 1745 {
1758 1746 proc_t *p = pnp->pr_common->prc_proc;
1759 1747 kthread_t *t = pr_thread(pnp); /* returns locked thread */
1760 1748
1761 1749 if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) {
1762 1750 thread_unlock(t);
1763 1751 return (EBUSY);
1764 1752 }
1765 1753
1766 1754 /* drop p_lock while touching the lwp's stack */
1767 1755 thread_unlock(t);
1768 1756 mutex_exit(&p->p_lock);
1769 1757 prsvaddr(ttolwp(t), vaddr);
1770 1758 mutex_enter(&p->p_lock);
1771 1759
1772 1760 return (0);
1773 1761 }
1774 1762
1775 1763 void
1776 1764 pr_sethold(prnode_t *pnp, sigset_t *sp)
1777 1765 {
1778 1766 proc_t *p = pnp->pr_common->prc_proc;
1779 1767 kthread_t *t = pr_thread(pnp); /* returns locked thread */
1780 1768
1781 1769 schedctl_finish_sigblock(t);
1782 1770 sigutok(sp, &t->t_hold);
1783 1771 if (ISWAKEABLE(t) &&
1784 1772 (fsig(&p->p_sig, t) || fsig(&t->t_sig, t)))
1785 1773 setrun_locked(t);
1786 1774 t->t_sig_check = 1; /* so thread will see new holdmask */
1787 1775 thread_unlock(t);
1788 1776 }
1789 1777
1790 1778 void
1791 1779 pr_setfault(proc_t *p, fltset_t *fltp)
1792 1780 {
1793 1781 prassignset(&p->p_fltmask, fltp);
1794 1782 if (!prisempty(&p->p_fltmask))
1795 1783 p->p_proc_flag |= P_PR_TRACE;
1796 1784 else if (sigisempty(&p->p_sigmask)) {
1797 1785 user_t *up = PTOU(p);
1798 1786 if (up->u_systrap == 0)
1799 1787 p->p_proc_flag &= ~P_PR_TRACE;
1800 1788 }
1801 1789 }
1802 1790
1803 1791 static int
1804 1792 pr_clearsig(prnode_t *pnp)
1805 1793 {
1806 1794 kthread_t *t = pr_thread(pnp); /* returns locked thread */
1807 1795 klwp_t *lwp = ttolwp(t);
1808 1796
1809 1797 thread_unlock(t);
1810 1798 if (lwp->lwp_cursig == SIGKILL)
1811 1799 return (EBUSY);
1812 1800
1813 1801 /*
1814 1802 * Discard current siginfo_t, if any.
1815 1803 */
1816 1804 lwp->lwp_cursig = 0;
1817 1805 lwp->lwp_extsig = 0;
1818 1806 if (lwp->lwp_curinfo) {
1819 1807 siginfofree(lwp->lwp_curinfo);
1820 1808 lwp->lwp_curinfo = NULL;
1821 1809 }
1822 1810
1823 1811 return (0);
1824 1812 }
1825 1813
1826 1814 static int
1827 1815 pr_clearflt(prnode_t *pnp)
1828 1816 {
1829 1817 kthread_t *t = pr_thread(pnp); /* returns locked thread */
1830 1818
1831 1819 thread_unlock(t);
1832 1820 ttolwp(t)->lwp_curflt = 0;
1833 1821
1834 1822 return (0);
1835 1823 }
1836 1824
1837 1825 static int
1838 1826 pr_watch(prnode_t *pnp, prwatch_t *pwp, int *unlocked)
1839 1827 {
1840 1828 proc_t *p = pnp->pr_common->prc_proc;
1841 1829 struct as *as = p->p_as;
1842 1830 uintptr_t vaddr = pwp->pr_vaddr;
1843 1831 size_t size = pwp->pr_size;
1844 1832 int wflags = pwp->pr_wflags;
1845 1833 ulong_t newpage = 0;
1846 1834 struct watched_area *pwa;
1847 1835 int error;
1848 1836
1849 1837 *unlocked = 0;
1850 1838
1851 1839 /*
1852 1840 * Can't apply to a system process.
1853 1841 */
1854 1842 if ((p->p_flag & SSYS) || p->p_as == &kas)
1855 1843 return (EBUSY);
1856 1844
1857 1845 /*
1858 1846 * Verify that the address range does not wrap
1859 1847 * and that only the proper flags were specified.
1860 1848 */
1861 1849 if ((wflags & ~WA_TRAPAFTER) == 0)
1862 1850 size = 0;
1863 1851 if (vaddr + size < vaddr ||
1864 1852 (wflags & ~(WA_READ|WA_WRITE|WA_EXEC|WA_TRAPAFTER)) != 0 ||
1865 1853 ((wflags & ~WA_TRAPAFTER) != 0 && size == 0))
1866 1854 return (EINVAL);
1867 1855
1868 1856 /*
1869 1857 * Don't let the address range go above as->a_userlimit.
1870 1858 * There is no error here, just a limitation.
1871 1859 */
1872 1860 if (vaddr >= (uintptr_t)as->a_userlimit)
1873 1861 return (0);
1874 1862 if (vaddr + size > (uintptr_t)as->a_userlimit)
1875 1863 size = (uintptr_t)as->a_userlimit - vaddr;
1876 1864
1877 1865 /*
1878 1866 * Compute maximum number of pages this will add.
1879 1867 */
1880 1868 if ((wflags & ~WA_TRAPAFTER) != 0) {
1881 1869 ulong_t pagespan = (vaddr + size) - (vaddr & PAGEMASK);
1882 1870 newpage = btopr(pagespan);
1883 1871 if (newpage > 2 * prnwatch)
1884 1872 return (E2BIG);
1885 1873 }
1886 1874
1887 1875 /*
1888 1876 * Force the process to be fully stopped.
1889 1877 */
1890 1878 if (p == curproc) {
1891 1879 prunlock(pnp);
1892 1880 while (holdwatch() != 0)
1893 1881 continue;
1894 1882 if ((error = prlock(pnp, ZNO)) != 0) {
1895 1883 continuelwps(p);
1896 1884 *unlocked = 1;
1897 1885 return (error);
1898 1886 }
1899 1887 } else {
1900 1888 pauselwps(p);
1901 1889 while (pr_allstopped(p, 0) > 0) {
1902 1890 /*
1903 1891 * This cv/mutex pair is persistent even
1904 1892 * if the process disappears after we
1905 1893 * unmark it and drop p->p_lock.
1906 1894 */
1907 1895 kcondvar_t *cv = &pr_pid_cv[p->p_slot];
1908 1896 kmutex_t *mp = &p->p_lock;
1909 1897
1910 1898 prunmark(p);
1911 1899 (void) cv_wait(cv, mp);
1912 1900 mutex_exit(mp);
1913 1901 if ((error = prlock(pnp, ZNO)) != 0) {
1914 1902 /*
1915 1903 * Unpause the process if it exists.
1916 1904 */
1917 1905 p = pr_p_lock(pnp);
1918 1906 mutex_exit(&pr_pidlock);
1919 1907 if (p != NULL) {
1920 1908 unpauselwps(p);
1921 1909 prunlock(pnp);
1922 1910 }
1923 1911 *unlocked = 1;
1924 1912 return (error);
1925 1913 }
1926 1914 }
1927 1915 }
1928 1916
1929 1917 /*
1930 1918 * Drop p->p_lock in order to perform the rest of this.
1931 1919 * The process is still locked with the P_PR_LOCK flag.
1932 1920 */
1933 1921 mutex_exit(&p->p_lock);
1934 1922
1935 1923 pwa = kmem_alloc(sizeof (struct watched_area), KM_SLEEP);
1936 1924 pwa->wa_vaddr = (caddr_t)vaddr;
1937 1925 pwa->wa_eaddr = (caddr_t)vaddr + size;
1938 1926 pwa->wa_flags = (ulong_t)wflags;
1939 1927
1940 1928 error = ((pwa->wa_flags & ~WA_TRAPAFTER) == 0)?
1941 1929 clear_watched_area(p, pwa) : set_watched_area(p, pwa);
1942 1930
1943 1931 if (p == curproc) {
1944 1932 setallwatch();
1945 1933 mutex_enter(&p->p_lock);
1946 1934 continuelwps(p);
1947 1935 } else {
1948 1936 mutex_enter(&p->p_lock);
1949 1937 unpauselwps(p);
1950 1938 }
1951 1939
1952 1940 return (error);
1953 1941 }
1954 1942
1955 1943 /* jobcontrol stopped, but with a /proc directed stop in effect */
1956 1944 #define JDSTOPPED(t) \
1957 1945 ((t)->t_state == TS_STOPPED && \
1958 1946 (t)->t_whystop == PR_JOBCONTROL && \
1959 1947 ((t)->t_proc_flag & TP_PRSTOP))
1960 1948
1961 1949 /*
1962 1950 * pr_agent() creates the agent lwp. If the process is exiting while
1963 1951 * we are creating an agent lwp, then exitlwps() waits until the
1964 1952 * agent has been created using prbarrier().
1965 1953 */
1966 1954 static int
1967 1955 pr_agent(prnode_t *pnp, prgregset_t prgregset, int *unlocked)
1968 1956 {
1969 1957 proc_t *p = pnp->pr_common->prc_proc;
1970 1958 prcommon_t *pcp;
1971 1959 kthread_t *t;
1972 1960 kthread_t *ct;
1973 1961 klwp_t *clwp;
1974 1962 k_sigset_t smask;
1975 1963 int cid;
1976 1964 void *bufp = NULL;
1977 1965 int error;
1978 1966
1979 1967 *unlocked = 0;
1980 1968
1981 1969 /*
1982 1970 * Cannot create the /proc agent lwp if :-
1983 1971 * - the process is not fully stopped or directed to stop.
1984 1972 * - there is an agent lwp already.
1985 1973 * - the process has been killed.
1986 1974 * - the process is exiting.
1987 1975 * - it's a vfork(2) parent.
1988 1976 */
1989 1977 t = prchoose(p); /* returns locked thread */
1990 1978 ASSERT(t != NULL);
1991 1979
1992 1980 if ((!ISTOPPED(t) && !VSTOPPED(t) && !SUSPENDED(t) && !JDSTOPPED(t)) ||
1993 1981 p->p_agenttp != NULL ||
1994 1982 (p->p_flag & (SKILLED | SEXITING | SVFWAIT))) {
1995 1983 thread_unlock(t);
1996 1984 return (EBUSY);
1997 1985 }
1998 1986
1999 1987 thread_unlock(t);
2000 1988 mutex_exit(&p->p_lock);
2001 1989
2002 1990 sigfillset(&smask);
2003 1991 sigdiffset(&smask, &cantmask);
2004 1992 clwp = lwp_create(lwp_rtt, NULL, 0, p, TS_STOPPED,
2005 1993 t->t_pri, &smask, NOCLASS, 0);
2006 1994 if (clwp == NULL) {
2007 1995 mutex_enter(&p->p_lock);
2008 1996 return (ENOMEM);
2009 1997 }
2010 1998 prsetprregs(clwp, prgregset, 1);
2011 1999 retry:
2012 2000 cid = t->t_cid;
2013 2001 (void) CL_ALLOC(&bufp, cid, KM_SLEEP);
2014 2002 mutex_enter(&p->p_lock);
2015 2003 if (cid != t->t_cid) {
2016 2004 /*
2017 2005 * Someone just changed this thread's scheduling class,
2018 2006 * so try pre-allocating the buffer again. Hopefully we
2019 2007 * don't hit this often.
2020 2008 */
2021 2009 mutex_exit(&p->p_lock);
2022 2010 CL_FREE(cid, bufp);
2023 2011 goto retry;
2024 2012 }
2025 2013
2026 2014 clwp->lwp_ap = clwp->lwp_arg;
2027 2015 clwp->lwp_eosys = NORMALRETURN;
2028 2016 ct = lwptot(clwp);
2029 2017 ct->t_clfuncs = t->t_clfuncs;
2030 2018 CL_FORK(t, ct, bufp);
2031 2019 ct->t_cid = t->t_cid;
2032 2020 ct->t_proc_flag |= TP_PRSTOP;
2033 2021 /*
2034 2022 * Setting t_sysnum to zero causes post_syscall()
2035 2023 * to bypass all syscall checks and go directly to
2036 2024 * if (issig()) psig();
2037 2025 * so that the agent lwp will stop in issig_forreal()
2038 2026 * showing PR_REQUESTED.
2039 2027 */
2040 2028 ct->t_sysnum = 0;
2041 2029 ct->t_post_sys = 1;
2042 2030 ct->t_sig_check = 1;
2043 2031 p->p_agenttp = ct;
2044 2032 ct->t_proc_flag &= ~TP_HOLDLWP;
2045 2033
2046 2034 pcp = pnp->pr_pcommon;
2047 2035 mutex_enter(&pcp->prc_mutex);
2048 2036
2049 2037 lwp_create_done(ct);
2050 2038
2051 2039 /*
2052 2040 * Don't return until the agent is stopped on PR_REQUESTED.
2053 2041 */
2054 2042
2055 2043 for (;;) {
2056 2044 prunlock(pnp);
2057 2045 *unlocked = 1;
2058 2046
2059 2047 /*
2060 2048 * Wait for the agent to stop and notify us.
2061 2049 * If we've been interrupted, return that information.
2062 2050 */
2063 2051 error = pr_wait(pcp, NULL, 0);
2064 2052 if (error == EINTR) {
2065 2053 error = 0;
2066 2054 break;
2067 2055 }
2068 2056
2069 2057 /*
2070 2058 * Confirm that the agent LWP has stopped.
2071 2059 */
2072 2060
2073 2061 if ((error = prlock(pnp, ZNO)) != 0)
2074 2062 break;
2075 2063 *unlocked = 0;
2076 2064
2077 2065 /*
2078 2066 * Since we dropped the lock on the process, the agent
2079 2067 * may have disappeared or changed. Grab the current
2080 2068 * agent and check fail if it has disappeared.
2081 2069 */
2082 2070 if ((ct = p->p_agenttp) == NULL) {
2083 2071 error = ENOENT;
2084 2072 break;
2085 2073 }
2086 2074
2087 2075 mutex_enter(&pcp->prc_mutex);
2088 2076 thread_lock(ct);
2089 2077
2090 2078 if (ISTOPPED(ct)) {
2091 2079 thread_unlock(ct);
2092 2080 mutex_exit(&pcp->prc_mutex);
2093 2081 break;
2094 2082 }
2095 2083
2096 2084 thread_unlock(ct);
2097 2085 }
2098 2086
2099 2087 return (error ? error : -1);
2100 2088 }
2101 2089
2102 2090 static int
2103 2091 pr_rdwr(proc_t *p, enum uio_rw rw, priovec_t *pio)
2104 2092 {
2105 2093 caddr_t base = (caddr_t)pio->pio_base;
2106 2094 size_t cnt = pio->pio_len;
2107 2095 uintptr_t offset = (uintptr_t)pio->pio_offset;
2108 2096 struct uio auio;
2109 2097 struct iovec aiov;
2110 2098 int error = 0;
2111 2099
2112 2100 if ((p->p_flag & SSYS) || p->p_as == &kas)
2113 2101 error = EIO;
2114 2102 else if ((base + cnt) < base || (offset + cnt) < offset)
2115 2103 error = EINVAL;
2116 2104 else if (cnt != 0) {
2117 2105 aiov.iov_base = base;
2118 2106 aiov.iov_len = cnt;
2119 2107
2120 2108 auio.uio_loffset = offset;
2121 2109 auio.uio_iov = &aiov;
2122 2110 auio.uio_iovcnt = 1;
2123 2111 auio.uio_resid = cnt;
2124 2112 auio.uio_segflg = UIO_USERSPACE;
2125 2113 auio.uio_llimit = (longlong_t)MAXOFFSET_T;
2126 2114 auio.uio_fmode = FREAD|FWRITE;
2127 2115 auio.uio_extflg = UIO_COPY_DEFAULT;
2128 2116
2129 2117 mutex_exit(&p->p_lock);
2130 2118 error = prusrio(p, rw, &auio, 0);
2131 2119 mutex_enter(&p->p_lock);
2132 2120
2133 2121 /*
2134 2122 * We have no way to return the i/o count,
2135 2123 * like read() or write() would do, so we
2136 2124 * return an error if the i/o was truncated.
2137 2125 */
2138 2126 if (auio.uio_resid != 0 && error == 0)
2139 2127 error = EIO;
2140 2128 }
2141 2129
2142 2130 return (error);
2143 2131 }
2144 2132
2145 2133 static int
2146 2134 pr_scred(proc_t *p, prcred_t *prcred, cred_t *cr, boolean_t dogrps)
2147 2135 {
2148 2136 kthread_t *t;
2149 2137 cred_t *oldcred;
2150 2138 cred_t *newcred;
2151 2139 uid_t oldruid;
2152 2140 int error;
2153 2141 zone_t *zone = crgetzone(cr);
2154 2142
2155 2143 if (!VALID_UID(prcred->pr_euid, zone) ||
2156 2144 !VALID_UID(prcred->pr_ruid, zone) ||
2157 2145 !VALID_UID(prcred->pr_suid, zone) ||
2158 2146 !VALID_GID(prcred->pr_egid, zone) ||
2159 2147 !VALID_GID(prcred->pr_rgid, zone) ||
2160 2148 !VALID_GID(prcred->pr_sgid, zone))
2161 2149 return (EINVAL);
2162 2150
2163 2151 if (dogrps) {
2164 2152 int ngrp = prcred->pr_ngroups;
2165 2153 int i;
2166 2154
2167 2155 if (ngrp < 0 || ngrp > ngroups_max)
2168 2156 return (EINVAL);
2169 2157
2170 2158 for (i = 0; i < ngrp; i++) {
2171 2159 if (!VALID_GID(prcred->pr_groups[i], zone))
2172 2160 return (EINVAL);
2173 2161 }
2174 2162 }
2175 2163
2176 2164 error = secpolicy_allow_setid(cr, prcred->pr_euid, B_FALSE);
2177 2165
2178 2166 if (error == 0 && prcred->pr_ruid != prcred->pr_euid)
2179 2167 error = secpolicy_allow_setid(cr, prcred->pr_ruid, B_FALSE);
2180 2168
2181 2169 if (error == 0 && prcred->pr_suid != prcred->pr_euid &&
2182 2170 prcred->pr_suid != prcred->pr_ruid)
2183 2171 error = secpolicy_allow_setid(cr, prcred->pr_suid, B_FALSE);
2184 2172
2185 2173 if (error)
2186 2174 return (error);
2187 2175
2188 2176 mutex_exit(&p->p_lock);
2189 2177
2190 2178 /* hold old cred so it doesn't disappear while we dup it */
2191 2179 mutex_enter(&p->p_crlock);
2192 2180 crhold(oldcred = p->p_cred);
2193 2181 mutex_exit(&p->p_crlock);
2194 2182 newcred = crdup(oldcred);
2195 2183 oldruid = crgetruid(oldcred);
2196 2184 crfree(oldcred);
2197 2185
2198 2186 /* Error checking done above */
2199 2187 (void) crsetresuid(newcred, prcred->pr_ruid, prcred->pr_euid,
2200 2188 prcred->pr_suid);
2201 2189 (void) crsetresgid(newcred, prcred->pr_rgid, prcred->pr_egid,
2202 2190 prcred->pr_sgid);
2203 2191
2204 2192 if (dogrps) {
2205 2193 (void) crsetgroups(newcred, prcred->pr_ngroups,
2206 2194 prcred->pr_groups);
2207 2195
2208 2196 }
2209 2197
2210 2198 mutex_enter(&p->p_crlock);
2211 2199 oldcred = p->p_cred;
2212 2200 p->p_cred = newcred;
2213 2201 mutex_exit(&p->p_crlock);
2214 2202 crfree(oldcred);
2215 2203
2216 2204 /*
2217 2205 * Keep count of processes per uid consistent.
2218 2206 */
2219 2207 if (oldruid != prcred->pr_ruid) {
2220 2208 zoneid_t zoneid = crgetzoneid(newcred);
2221 2209
2222 2210 mutex_enter(&pidlock);
2223 2211 upcount_dec(oldruid, zoneid);
2224 2212 upcount_inc(prcred->pr_ruid, zoneid);
2225 2213 mutex_exit(&pidlock);
2226 2214 }
2227 2215
2228 2216 /*
2229 2217 * Broadcast the cred change to the threads.
2230 2218 */
2231 2219 mutex_enter(&p->p_lock);
2232 2220 t = p->p_tlist;
2233 2221 do {
2234 2222 t->t_pre_sys = 1; /* so syscall will get new cred */
2235 2223 } while ((t = t->t_forw) != p->p_tlist);
2236 2224
2237 2225 return (0);
2238 2226 }
2239 2227
2240 2228 /*
2241 2229 * Change process credentials to specified zone. Used to temporarily
2242 2230 * set a process to run in the global zone; only transitions between
2243 2231 * the process's actual zone and the global zone are allowed.
2244 2232 */
2245 2233 static int
2246 2234 pr_szoneid(proc_t *p, zoneid_t zoneid, cred_t *cr)
2247 2235 {
2248 2236 kthread_t *t;
2249 2237 cred_t *oldcred;
2250 2238 cred_t *newcred;
2251 2239 zone_t *zptr;
2252 2240 zoneid_t oldzoneid;
2253 2241
2254 2242 if (secpolicy_zone_config(cr) != 0)
2255 2243 return (EPERM);
2256 2244 if (zoneid != GLOBAL_ZONEID && zoneid != p->p_zone->zone_id)
2257 2245 return (EINVAL);
2258 2246 if ((zptr = zone_find_by_id(zoneid)) == NULL)
2259 2247 return (EINVAL);
2260 2248 mutex_exit(&p->p_lock);
2261 2249 mutex_enter(&p->p_crlock);
2262 2250 oldcred = p->p_cred;
2263 2251 crhold(oldcred);
2264 2252 mutex_exit(&p->p_crlock);
2265 2253 newcred = crdup(oldcred);
2266 2254 oldzoneid = crgetzoneid(oldcred);
2267 2255 crfree(oldcred);
2268 2256
2269 2257 crsetzone(newcred, zptr);
2270 2258 zone_rele(zptr);
2271 2259
2272 2260 mutex_enter(&p->p_crlock);
2273 2261 oldcred = p->p_cred;
2274 2262 p->p_cred = newcred;
2275 2263 mutex_exit(&p->p_crlock);
2276 2264 crfree(oldcred);
2277 2265
2278 2266 /*
2279 2267 * The target process is changing zones (according to its cred), so
2280 2268 * update the per-zone upcounts, which are based on process creds.
2281 2269 */
2282 2270 if (oldzoneid != zoneid) {
2283 2271 uid_t ruid = crgetruid(newcred);
2284 2272
2285 2273 mutex_enter(&pidlock);
2286 2274 upcount_dec(ruid, oldzoneid);
2287 2275 upcount_inc(ruid, zoneid);
2288 2276 mutex_exit(&pidlock);
2289 2277 }
2290 2278 /*
2291 2279 * Broadcast the cred change to the threads.
2292 2280 */
2293 2281 mutex_enter(&p->p_lock);
2294 2282 t = p->p_tlist;
2295 2283 do {
2296 2284 t->t_pre_sys = 1; /* so syscall will get new cred */
2297 2285 } while ((t = t->t_forw) != p->p_tlist);
2298 2286
2299 2287 return (0);
2300 2288 }
2301 2289
2302 2290 static int
2303 2291 pr_spriv(proc_t *p, prpriv_t *prpriv, cred_t *cr)
2304 2292 {
2305 2293 kthread_t *t;
2306 2294 int err;
2307 2295
2308 2296 ASSERT(MUTEX_HELD(&p->p_lock));
2309 2297
2310 2298 if ((err = priv_pr_spriv(p, prpriv, cr)) == 0) {
2311 2299 /*
2312 2300 * Broadcast the cred change to the threads.
2313 2301 */
2314 2302 t = p->p_tlist;
2315 2303 do {
2316 2304 t->t_pre_sys = 1; /* so syscall will get new cred */
2317 2305 } while ((t = t->t_forw) != p->p_tlist);
2318 2306 }
2319 2307
2320 2308 return (err);
2321 2309 }
2322 2310
2323 2311 /*
2324 2312 * Return -1 if the process is the parent of a vfork(1) whose child has yet to
2325 2313 * terminate or perform an exec(2).
2326 2314 *
2327 2315 * Returns 0 if the process is fully stopped except for the current thread (if
2328 2316 * we are operating on our own process), 1 otherwise.
2329 2317 *
2330 2318 * If the watchstop flag is set, then we ignore threads with TP_WATCHSTOP set.
2331 2319 * See holdwatch() for details.
2332 2320 */
2333 2321 int
2334 2322 pr_allstopped(proc_t *p, int watchstop)
2335 2323 {
2336 2324 kthread_t *t;
2337 2325 int rv = 0;
2338 2326
2339 2327 ASSERT(MUTEX_HELD(&p->p_lock));
2340 2328
2341 2329 if (p->p_flag & SVFWAIT) /* waiting for vfork'd child to exec */
2342 2330 return (-1);
2343 2331
2344 2332 if ((t = p->p_tlist) != NULL) {
2345 2333 do {
2346 2334 if (t == curthread || VSTOPPED(t) ||
2347 2335 (watchstop && (t->t_proc_flag & TP_WATCHSTOP)))
2348 2336 continue;
2349 2337 thread_lock(t);
2350 2338 switch (t->t_state) {
2351 2339 case TS_ZOMB:
2352 2340 case TS_STOPPED:
2353 2341 break;
2354 2342 case TS_SLEEP:
2355 2343 if (!(t->t_flag & T_WAKEABLE) ||
2356 2344 t->t_wchan0 == NULL)
2357 2345 rv = 1;
2358 2346 break;
2359 2347 default:
2360 2348 rv = 1;
2361 2349 break;
2362 2350 }
2363 2351 thread_unlock(t);
2364 2352 } while (rv == 0 && (t = t->t_forw) != p->p_tlist);
2365 2353 }
2366 2354
2367 2355 return (rv);
2368 2356 }
2369 2357
2370 2358 /*
2371 2359 * Cause all lwps in the process to pause (for watchpoint operations).
2372 2360 */
2373 2361 static void
2374 2362 pauselwps(proc_t *p)
2375 2363 {
2376 2364 kthread_t *t;
2377 2365
2378 2366 ASSERT(MUTEX_HELD(&p->p_lock));
2379 2367 ASSERT(p != curproc);
2380 2368
2381 2369 if ((t = p->p_tlist) != NULL) {
2382 2370 do {
2383 2371 thread_lock(t);
2384 2372 t->t_proc_flag |= TP_PAUSE;
2385 2373 aston(t);
2386 2374 if ((ISWAKEABLE(t) && (t->t_wchan0 == NULL)) ||
2387 2375 ISWAITING(t)) {
2388 2376 setrun_locked(t);
2389 2377 }
2390 2378 prpokethread(t);
2391 2379 thread_unlock(t);
2392 2380 } while ((t = t->t_forw) != p->p_tlist);
2393 2381 }
2394 2382 }
2395 2383
2396 2384 /*
2397 2385 * undo the effects of pauselwps()
2398 2386 */
2399 2387 static void
2400 2388 unpauselwps(proc_t *p)
2401 2389 {
2402 2390 kthread_t *t;
2403 2391
2404 2392 ASSERT(MUTEX_HELD(&p->p_lock));
2405 2393 ASSERT(p != curproc);
2406 2394
2407 2395 if ((t = p->p_tlist) != NULL) {
2408 2396 do {
2409 2397 thread_lock(t);
2410 2398 t->t_proc_flag &= ~TP_PAUSE;
2411 2399 if (t->t_state == TS_STOPPED) {
2412 2400 t->t_schedflag |= TS_UNPAUSE;
2413 2401 t->t_dtrace_stop = 0;
2414 2402 setrun_locked(t);
2415 2403 }
2416 2404 thread_unlock(t);
2417 2405 } while ((t = t->t_forw) != p->p_tlist);
2418 2406 }
2419 2407 }
2420 2408
2421 2409 /*
2422 2410 * Cancel all watched areas. Called from prclose().
2423 2411 */
2424 2412 proc_t *
2425 2413 pr_cancel_watch(prnode_t *pnp)
2426 2414 {
2427 2415 proc_t *p = pnp->pr_pcommon->prc_proc;
2428 2416 struct as *as;
2429 2417 kthread_t *t;
2430 2418
2431 2419 ASSERT(MUTEX_HELD(&p->p_lock) && (p->p_proc_flag & P_PR_LOCK));
2432 2420
2433 2421 if (!pr_watch_active(p))
2434 2422 return (p);
2435 2423
2436 2424 /*
2437 2425 * Pause the process before dealing with the watchpoints.
2438 2426 */
2439 2427 if (p == curproc) {
2440 2428 prunlock(pnp);
2441 2429 while (holdwatch() != 0)
2442 2430 continue;
2443 2431 p = pr_p_lock(pnp);
2444 2432 mutex_exit(&pr_pidlock);
2445 2433 ASSERT(p == curproc);
2446 2434 } else {
2447 2435 pauselwps(p);
2448 2436 while (p != NULL && pr_allstopped(p, 0) > 0) {
2449 2437 /*
2450 2438 * This cv/mutex pair is persistent even
2451 2439 * if the process disappears after we
2452 2440 * unmark it and drop p->p_lock.
2453 2441 */
2454 2442 kcondvar_t *cv = &pr_pid_cv[p->p_slot];
2455 2443 kmutex_t *mp = &p->p_lock;
2456 2444
2457 2445 prunmark(p);
2458 2446 (void) cv_wait(cv, mp);
2459 2447 mutex_exit(mp);
2460 2448 p = pr_p_lock(pnp); /* NULL if process disappeared */
2461 2449 mutex_exit(&pr_pidlock);
2462 2450 }
2463 2451 }
2464 2452
2465 2453 if (p == NULL) /* the process disappeared */
2466 2454 return (NULL);
2467 2455
2468 2456 ASSERT(p == pnp->pr_pcommon->prc_proc);
2469 2457 ASSERT(MUTEX_HELD(&p->p_lock) && (p->p_proc_flag & P_PR_LOCK));
2470 2458
2471 2459 if (pr_watch_active(p)) {
2472 2460 pr_free_watchpoints(p);
2473 2461 if ((t = p->p_tlist) != NULL) {
2474 2462 do {
2475 2463 watch_disable(t);
2476 2464
2477 2465 } while ((t = t->t_forw) != p->p_tlist);
2478 2466 }
2479 2467 }
2480 2468
2481 2469 if ((as = p->p_as) != NULL) {
2482 2470 avl_tree_t *tree;
2483 2471 struct watched_page *pwp;
2484 2472
2485 2473 /*
2486 2474 * If this is the parent of a vfork, the watched page
2487 2475 * list has been moved temporarily to p->p_wpage.
2488 2476 */
2489 2477 if (avl_numnodes(&p->p_wpage) != 0)
2490 2478 tree = &p->p_wpage;
2491 2479 else
2492 2480 tree = &as->a_wpage;
2493 2481
2494 2482 mutex_exit(&p->p_lock);
2495 2483 AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
2496 2484
2497 2485 for (pwp = avl_first(tree); pwp != NULL;
2498 2486 pwp = AVL_NEXT(tree, pwp)) {
2499 2487 pwp->wp_read = 0;
2500 2488 pwp->wp_write = 0;
2501 2489 pwp->wp_exec = 0;
2502 2490 if ((pwp->wp_flags & WP_SETPROT) == 0) {
2503 2491 pwp->wp_flags |= WP_SETPROT;
2504 2492 pwp->wp_prot = pwp->wp_oprot;
2505 2493 pwp->wp_list = p->p_wprot;
2506 2494 p->p_wprot = pwp;
2507 2495 }
2508 2496 }
2509 2497
2510 2498 AS_LOCK_EXIT(as, &as->a_lock);
2511 2499 mutex_enter(&p->p_lock);
2512 2500 }
2513 2501
2514 2502 /*
2515 2503 * Unpause the process now.
2516 2504 */
2517 2505 if (p == curproc)
2518 2506 continuelwps(p);
2519 2507 else
2520 2508 unpauselwps(p);
2521 2509
2522 2510 return (p);
2523 2511 }
↓ open down ↓ |
780 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX