kern_subr.c revision 1.211 1 /* $NetBSD: kern_subr.c,v 1.211 2011/08/31 23:42:46 jmcneill Exp $ */
2
3 /*-
4 * Copyright (c) 1997, 1998, 1999, 2002, 2007, 2008 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, and by Luke Mewburn.
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 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * Copyright (c) 1982, 1986, 1991, 1993
35 * The Regents of the University of California. All rights reserved.
36 * (c) UNIX System Laboratories, Inc.
37 * All or some portions of this file are derived from material licensed
38 * to the University of California by American Telephone and Telegraph
39 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
40 * the permission of UNIX System Laboratories, Inc.
41 *
42 * Copyright (c) 1992, 1993
43 * The Regents of the University of California. All rights reserved.
44 *
45 * This software was developed by the Computer Systems Engineering group
46 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
47 * contributed to Berkeley.
48 *
49 * All advertising materials mentioning features or use of this software
50 * must display the following acknowledgement:
51 * This product includes software developed by the University of
52 * California, Lawrence Berkeley Laboratory.
53 *
54 * Redistribution and use in source and binary forms, with or without
55 * modification, are permitted provided that the following conditions
56 * are met:
57 * 1. Redistributions of source code must retain the above copyright
58 * notice, this list of conditions and the following disclaimer.
59 * 2. Redistributions in binary form must reproduce the above copyright
60 * notice, this list of conditions and the following disclaimer in the
61 * documentation and/or other materials provided with the distribution.
62 * 3. Neither the name of the University nor the names of its contributors
63 * may be used to endorse or promote products derived from this software
64 * without specific prior written permission.
65 *
66 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
67 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
68 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
69 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
70 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
71 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
72 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
73 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
74 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
75 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
76 * SUCH DAMAGE.
77 *
78 * @(#)kern_subr.c 8.4 (Berkeley) 2/14/95
79 */
80
81 #include <sys/cdefs.h>
82 __KERNEL_RCSID(0, "$NetBSD: kern_subr.c,v 1.211 2011/08/31 23:42:46 jmcneill Exp $");
83
84 #include "opt_ddb.h"
85 #include "opt_md.h"
86 #include "opt_syscall_debug.h"
87 #include "opt_ktrace.h"
88 #include "opt_ptrace.h"
89 #include "opt_tftproot.h"
90
91 #include <sys/param.h>
92 #include <sys/systm.h>
93 #include <sys/proc.h>
94 #include <sys/mount.h>
95 #include <sys/device.h>
96 #include <sys/reboot.h>
97 #include <sys/conf.h>
98 #include <sys/disk.h>
99 #include <sys/disklabel.h>
100 #include <sys/queue.h>
101 #include <sys/ktrace.h>
102 #include <sys/ptrace.h>
103 #include <sys/fcntl.h>
104 #include <sys/kauth.h>
105 #include <sys/stat.h>
106 #include <sys/vnode.h>
107 #include <sys/module.h>
108
109 #include <dev/cons.h>
110
111 #include <net/if.h>
112
113 /* XXX these should eventually move to subr_autoconf.c */
114 static device_t finddevice(const char *);
115 static device_t getdisk(char *, int, int, dev_t *, int);
116 static device_t parsedisk(char *, int, int, dev_t *);
117 static const char *getwedgename(const char *, int);
118
119 #ifdef TFTPROOT
120 int tftproot_dhcpboot(device_t);
121 #endif
122
123 dev_t dumpcdev; /* for savecore */
124
125 static int
126 isswap(device_t dv)
127 {
128 struct dkwedge_info wi;
129 struct vnode *vn;
130 int error;
131
132 if (device_class(dv) != DV_DISK || !device_is_a(dv, "dk"))
133 return 0;
134
135 if ((vn = opendisk(dv)) == NULL)
136 return 0;
137
138 error = VOP_IOCTL(vn, DIOCGWEDGEINFO, &wi, FREAD, NOCRED);
139 VOP_CLOSE(vn, FREAD, NOCRED);
140 vput(vn);
141 if (error) {
142 #ifdef DEBUG_WEDGE
143 printf("%s: Get wedge info returned %d\n", device_xname(dv), error);
144 #endif
145 return 0;
146 }
147 return strcmp(wi.dkw_ptype, DKW_PTYPE_SWAP) == 0;
148 }
149
150 /*
151 * Determine the root device and, if instructed to, the root file system.
152 */
153
154 #ifdef MEMORY_DISK_IS_ROOT
155 int md_is_root = 1;
156 #else
157 int md_is_root = 0;
158 #endif
159
160 /*
161 * The device and wedge that we booted from. If booted_wedge is NULL,
162 * the we might consult booted_partition.
163 */
164 device_t booted_device;
165 device_t booted_wedge;
166 int booted_partition;
167
168 /*
169 * Use partition letters if it's a disk class but not a wedge.
170 * XXX Check for wedge is kinda gross.
171 */
172 #define DEV_USES_PARTITIONS(dv) \
173 (device_class((dv)) == DV_DISK && \
174 !device_is_a((dv), "dk"))
175
176 void
177 setroot(device_t bootdv, int bootpartition)
178 {
179 device_t dv;
180 deviter_t di;
181 int len, majdev;
182 dev_t nrootdev;
183 dev_t ndumpdev = NODEV;
184 char buf[128];
185 const char *rootdevname;
186 const char *dumpdevname;
187 device_t rootdv = NULL; /* XXX gcc -Wuninitialized */
188 device_t dumpdv = NULL;
189 struct ifnet *ifp;
190 const char *deffsname;
191 struct vfsops *vops;
192
193 #ifdef TFTPROOT
194 if (tftproot_dhcpboot(bootdv) != 0)
195 boothowto |= RB_ASKNAME;
196 #endif
197
198 /*
199 * For root on md0 we have to force the attachment of md0.
200 */
201 if (md_is_root) {
202 int md_major;
203 dev_t md_dev;
204
205 bootdv = NULL;
206 md_major = devsw_name2blk("md", NULL, 0);
207 if (md_major >= 0) {
208 md_dev = MAKEDISKDEV(md_major, 0, RAW_PART);
209 if (bdev_open(md_dev, FREAD, S_IFBLK, curlwp) == 0)
210 bootdv = device_find_by_xname("md0");
211 }
212 if (bootdv == NULL)
213 panic("Cannot open \"md0\" (root)");
214 }
215
216 /*
217 * If NFS is specified as the file system, and we found
218 * a DV_DISK boot device (or no boot device at all), then
219 * find a reasonable network interface for "rootspec".
220 */
221 vops = vfs_getopsbyname(MOUNT_NFS);
222 if (vops != NULL && strcmp(rootfstype, MOUNT_NFS) == 0 &&
223 rootspec == NULL &&
224 (bootdv == NULL || device_class(bootdv) != DV_IFNET)) {
225 IFNET_FOREACH(ifp) {
226 if ((ifp->if_flags &
227 (IFF_LOOPBACK|IFF_POINTOPOINT)) == 0)
228 break;
229 }
230 if (ifp == NULL) {
231 /*
232 * Can't find a suitable interface; ask the
233 * user.
234 */
235 boothowto |= RB_ASKNAME;
236 } else {
237 /*
238 * Have a suitable interface; behave as if
239 * the user specified this interface.
240 */
241 rootspec = (const char *)ifp->if_xname;
242 }
243 }
244 if (vops != NULL)
245 vfs_delref(vops);
246
247 /*
248 * If wildcarded root and we the boot device wasn't determined,
249 * ask the user.
250 */
251 if (rootspec == NULL && bootdv == NULL)
252 boothowto |= RB_ASKNAME;
253
254 top:
255 if (boothowto & RB_ASKNAME) {
256 device_t defdumpdv;
257
258 for (;;) {
259 printf("root device");
260 if (bootdv != NULL) {
261 printf(" (default %s", device_xname(bootdv));
262 if (DEV_USES_PARTITIONS(bootdv))
263 printf("%c", bootpartition + 'a');
264 printf(")");
265 }
266 printf(": ");
267 len = cngetsn(buf, sizeof(buf));
268 if (len == 0 && bootdv != NULL) {
269 strlcpy(buf, device_xname(bootdv), sizeof(buf));
270 len = strlen(buf);
271 }
272 if (len > 0 && buf[len - 1] == '*') {
273 buf[--len] = '\0';
274 dv = getdisk(buf, len, 1, &nrootdev, 0);
275 if (dv != NULL) {
276 rootdv = dv;
277 break;
278 }
279 }
280 dv = getdisk(buf, len, bootpartition, &nrootdev, 0);
281 if (dv != NULL) {
282 rootdv = dv;
283 break;
284 }
285 }
286
287 /*
288 * Set up the default dump device. If root is on
289 * a network device, there is no default dump
290 * device, since we don't support dumps to the
291 * network.
292 */
293 if (DEV_USES_PARTITIONS(rootdv) == 0)
294 defdumpdv = NULL;
295 else
296 defdumpdv = rootdv;
297
298 for (;;) {
299 printf("dump device");
300 if (defdumpdv != NULL) {
301 /*
302 * Note, we know it's a disk if we get here.
303 */
304 printf(" (default %sb)", device_xname(defdumpdv));
305 }
306 printf(": ");
307 len = cngetsn(buf, sizeof(buf));
308 if (len == 0) {
309 if (defdumpdv != NULL) {
310 ndumpdev = MAKEDISKDEV(major(nrootdev),
311 DISKUNIT(nrootdev), 1);
312 }
313 dumpdv = defdumpdv;
314 break;
315 }
316 if (len == 4 && strcmp(buf, "none") == 0) {
317 dumpdv = NULL;
318 break;
319 }
320 dv = getdisk(buf, len, 1, &ndumpdev, 1);
321 if (dv != NULL) {
322 dumpdv = dv;
323 break;
324 }
325 }
326
327 rootdev = nrootdev;
328 dumpdev = ndumpdev;
329
330 for (vops = LIST_FIRST(&vfs_list); vops != NULL;
331 vops = LIST_NEXT(vops, vfs_list)) {
332 if (vops->vfs_mountroot != NULL &&
333 strcmp(rootfstype, vops->vfs_name) == 0)
334 break;
335 }
336
337 if (vops == NULL) {
338 deffsname = "generic";
339 } else
340 deffsname = vops->vfs_name;
341
342 for (;;) {
343 printf("file system (default %s): ", deffsname);
344 len = cngetsn(buf, sizeof(buf));
345 if (len == 0) {
346 if (strcmp(deffsname, "generic") == 0)
347 rootfstype = ROOT_FSTYPE_ANY;
348 break;
349 }
350 if (len == 4 && strcmp(buf, "halt") == 0)
351 cpu_reboot(RB_HALT, NULL);
352 else if (len == 6 && strcmp(buf, "reboot") == 0)
353 cpu_reboot(0, NULL);
354 #if defined(DDB)
355 else if (len == 3 && strcmp(buf, "ddb") == 0) {
356 console_debugger();
357 }
358 #endif
359 else if (len == 7 && strcmp(buf, "generic") == 0) {
360 rootfstype = ROOT_FSTYPE_ANY;
361 break;
362 }
363 vops = vfs_getopsbyname(buf);
364 if (vops == NULL || vops->vfs_mountroot == NULL) {
365 printf("use one of: generic");
366 for (vops = LIST_FIRST(&vfs_list);
367 vops != NULL;
368 vops = LIST_NEXT(vops, vfs_list)) {
369 if (vops->vfs_mountroot != NULL)
370 printf(" %s", vops->vfs_name);
371 }
372 if (vops != NULL)
373 vfs_delref(vops);
374 #if defined(DDB)
375 printf(" ddb");
376 #endif
377 printf(" halt reboot\n");
378 } else {
379 /*
380 * XXX If *vops gets freed between here and
381 * the call to mountroot(), rootfstype will
382 * point to something unexpected. But in
383 * this case the system will fail anyway.
384 */
385 rootfstype = vops->vfs_name;
386 vfs_delref(vops);
387 break;
388 }
389 }
390
391 } else if (rootspec == NULL) {
392 /*
393 * Wildcarded root; use the boot device.
394 */
395 rootdv = bootdv;
396
397 if (bootdv)
398 majdev = devsw_name2blk(device_xname(bootdv), NULL, 0);
399 else
400 majdev = -1;
401 if (majdev >= 0) {
402 /*
403 * Root is on a disk. `bootpartition' is root,
404 * unless the device does not use partitions.
405 */
406 if (DEV_USES_PARTITIONS(bootdv))
407 rootdev = MAKEDISKDEV(majdev,
408 device_unit(bootdv),
409 bootpartition);
410 else
411 rootdev = makedev(majdev, device_unit(bootdv));
412 }
413 } else {
414
415 /*
416 * `root on <dev> ...'
417 */
418
419 /*
420 * If it's a network interface, we can bail out
421 * early.
422 */
423 dv = finddevice(rootspec);
424 if (dv != NULL && device_class(dv) == DV_IFNET) {
425 rootdv = dv;
426 goto haveroot;
427 }
428
429 if (rootdev == NODEV &&
430 device_class(dv) == DV_DISK && device_is_a(dv, "dk") &&
431 (majdev = devsw_name2blk(device_xname(dv), NULL, 0)) >= 0)
432 rootdev = makedev(majdev, device_unit(dv));
433
434 rootdevname = devsw_blk2name(major(rootdev));
435 if (rootdevname == NULL) {
436 printf("unknown device major 0x%llx\n",
437 (unsigned long long)rootdev);
438 boothowto |= RB_ASKNAME;
439 goto top;
440 }
441 memset(buf, 0, sizeof(buf));
442 snprintf(buf, sizeof(buf), "%s%llu", rootdevname,
443 (unsigned long long)DISKUNIT(rootdev));
444
445 rootdv = finddevice(buf);
446 if (rootdv == NULL) {
447 printf("device %s (0x%llx) not configured\n",
448 buf, (unsigned long long)rootdev);
449 boothowto |= RB_ASKNAME;
450 goto top;
451 }
452 }
453
454 haveroot:
455
456 root_device = rootdv;
457
458 switch (device_class(rootdv)) {
459 case DV_IFNET:
460 case DV_DISK:
461 aprint_normal("root on %s", device_xname(rootdv));
462 if (DEV_USES_PARTITIONS(rootdv))
463 aprint_normal("%c", (int)DISKPART(rootdev) + 'a');
464 break;
465
466 default:
467 printf("can't determine root device\n");
468 boothowto |= RB_ASKNAME;
469 goto top;
470 }
471
472 /*
473 * Now configure the dump device.
474 *
475 * If we haven't figured out the dump device, do so, with
476 * the following rules:
477 *
478 * (a) We already know dumpdv in the RB_ASKNAME case.
479 *
480 * (b) If dumpspec is set, try to use it. If the device
481 * is not available, punt.
482 *
483 * (c) If dumpspec is not set, the dump device is
484 * wildcarded or unspecified. If the root device
485 * is DV_IFNET, punt. Otherwise, use partition b
486 * of the root device.
487 */
488
489 if (boothowto & RB_ASKNAME) { /* (a) */
490 if (dumpdv == NULL)
491 goto nodumpdev;
492 } else if (dumpspec != NULL) { /* (b) */
493 if (strcmp(dumpspec, "none") == 0 || dumpdev == NODEV) {
494 /*
495 * Operator doesn't want a dump device.
496 * Or looks like they tried to pick a network
497 * device. Oops.
498 */
499 goto nodumpdev;
500 }
501
502 dumpdevname = devsw_blk2name(major(dumpdev));
503 if (dumpdevname == NULL)
504 goto nodumpdev;
505 memset(buf, 0, sizeof(buf));
506 snprintf(buf, sizeof(buf), "%s%llu", dumpdevname,
507 (unsigned long long)DISKUNIT(dumpdev));
508
509 dumpdv = finddevice(buf);
510 if (dumpdv == NULL) {
511 /*
512 * Device not configured.
513 */
514 goto nodumpdev;
515 }
516 } else { /* (c) */
517 if (DEV_USES_PARTITIONS(rootdv) == 0) {
518 for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
519 dv != NULL;
520 dv = deviter_next(&di))
521 if (isswap(dv))
522 break;
523 deviter_release(&di);
524 if (dv == NULL)
525 goto nodumpdev;
526
527 majdev = devsw_name2blk(device_xname(dv), NULL, 0);
528 if (majdev < 0)
529 goto nodumpdev;
530 dumpdv = dv;
531 dumpdev = makedev(majdev, device_unit(dumpdv));
532 } else {
533 dumpdv = rootdv;
534 dumpdev = MAKEDISKDEV(major(rootdev),
535 device_unit(dumpdv), 1);
536 }
537 }
538
539 dumpcdev = devsw_blk2chr(dumpdev);
540 aprint_normal(" dumps on %s", device_xname(dumpdv));
541 if (DEV_USES_PARTITIONS(dumpdv))
542 aprint_normal("%c", (int)DISKPART(dumpdev) + 'a');
543 aprint_normal("\n");
544 return;
545
546 nodumpdev:
547 dumpdev = NODEV;
548 dumpcdev = NODEV;
549 aprint_normal("\n");
550 }
551
552 static device_t
553 finddevice(const char *name)
554 {
555 const char *wname;
556
557 if ((wname = getwedgename(name, strlen(name))) != NULL)
558 return dkwedge_find_by_wname(wname);
559
560 return device_find_by_xname(name);
561 }
562
563 static device_t
564 getdisk(char *str, int len, int defpart, dev_t *devp, int isdump)
565 {
566 device_t dv;
567 deviter_t di;
568
569 if ((dv = parsedisk(str, len, defpart, devp)) == NULL) {
570 printf("use one of:");
571 for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL;
572 dv = deviter_next(&di)) {
573 if (DEV_USES_PARTITIONS(dv))
574 printf(" %s[a-%c]", device_xname(dv),
575 'a' + MAXPARTITIONS - 1);
576 else if (device_class(dv) == DV_DISK)
577 printf(" %s", device_xname(dv));
578 if (isdump == 0 && device_class(dv) == DV_IFNET)
579 printf(" %s", device_xname(dv));
580 }
581 deviter_release(&di);
582 dkwedge_print_wnames();
583 if (isdump)
584 printf(" none");
585 #if defined(DDB)
586 printf(" ddb");
587 #endif
588 printf(" halt reboot\n");
589 }
590 return dv;
591 }
592
593 static const char *
594 getwedgename(const char *name, int namelen)
595 {
596 const char *wpfx = "wedge:";
597 const int wpfxlen = strlen(wpfx);
598
599 if (namelen < wpfxlen || strncmp(name, wpfx, wpfxlen) != 0)
600 return NULL;
601
602 return name + wpfxlen;
603 }
604
605 static device_t
606 parsedisk(char *str, int len, int defpart, dev_t *devp)
607 {
608 device_t dv;
609 const char *wname;
610 char *cp, c;
611 int majdev, part;
612 if (len == 0)
613 return (NULL);
614
615 if (len == 4 && strcmp(str, "halt") == 0)
616 cpu_reboot(RB_HALT, NULL);
617 else if (len == 6 && strcmp(str, "reboot") == 0)
618 cpu_reboot(0, NULL);
619 #if defined(DDB)
620 else if (len == 3 && strcmp(str, "ddb") == 0)
621 console_debugger();
622 #endif
623
624 cp = str + len - 1;
625 c = *cp;
626
627 if ((wname = getwedgename(str, len)) != NULL) {
628 if ((dv = dkwedge_find_by_wname(wname)) == NULL)
629 return NULL;
630 part = defpart;
631 goto gotdisk;
632 } else if (c >= 'a' && c <= ('a' + MAXPARTITIONS - 1)) {
633 part = c - 'a';
634 *cp = '\0';
635 } else
636 part = defpart;
637
638 dv = finddevice(str);
639 if (dv != NULL) {
640 if (device_class(dv) == DV_DISK) {
641 gotdisk:
642 majdev = devsw_name2blk(device_xname(dv), NULL, 0);
643 if (majdev < 0)
644 panic("parsedisk");
645 if (DEV_USES_PARTITIONS(dv))
646 *devp = MAKEDISKDEV(majdev, device_unit(dv),
647 part);
648 else
649 *devp = makedev(majdev, device_unit(dv));
650 }
651
652 if (device_class(dv) == DV_IFNET)
653 *devp = NODEV;
654 }
655
656 *cp = c;
657 return (dv);
658 }
659
660 /*
661 * Return true if system call tracing is enabled for the specified process.
662 */
663 bool
664 trace_is_enabled(struct proc *p)
665 {
666 #ifdef SYSCALL_DEBUG
667 return (true);
668 #endif
669 #ifdef KTRACE
670 if (ISSET(p->p_traceflag, (KTRFAC_SYSCALL | KTRFAC_SYSRET)))
671 return (true);
672 #endif
673 #ifdef PTRACE
674 if (ISSET(p->p_slflag, PSL_SYSCALL))
675 return (true);
676 #endif
677
678 return (false);
679 }
680
681 /*
682 * Start trace of particular system call. If process is being traced,
683 * this routine is called by MD syscall dispatch code just before
684 * a system call is actually executed.
685 */
686 int
687 trace_enter(register_t code, const register_t *args, int narg)
688 {
689 int error = 0;
690
691 #ifdef SYSCALL_DEBUG
692 scdebug_call(code, args);
693 #endif /* SYSCALL_DEBUG */
694
695 ktrsyscall(code, args, narg);
696
697 #ifdef PTRACE
698 if ((curlwp->l_proc->p_slflag & (PSL_SYSCALL|PSL_TRACED)) ==
699 (PSL_SYSCALL|PSL_TRACED)) {
700 process_stoptrace();
701 if (curlwp->l_proc->p_slflag & PSL_SYSCALLEMU) {
702 /* tracer will emulate syscall for us */
703 error = EJUSTRETURN;
704 }
705 }
706 #endif
707 return error;
708 }
709
710 /*
711 * End trace of particular system call. If process is being traced,
712 * this routine is called by MD syscall dispatch code just after
713 * a system call finishes.
714 * MD caller guarantees the passed 'code' is within the supported
715 * system call number range for emulation the process runs under.
716 */
717 void
718 trace_exit(register_t code, register_t rval[], int error)
719 {
720 struct proc *p = curlwp->l_proc;
721
722 #ifdef SYSCALL_DEBUG
723 scdebug_ret(code, error, rval);
724 #endif /* SYSCALL_DEBUG */
725
726 ktrsysret(code, error, rval);
727
728 #ifdef PTRACE
729 if ((p->p_slflag & (PSL_SYSCALL|PSL_TRACED|PSL_SYSCALLEMU)) ==
730 (PSL_SYSCALL|PSL_TRACED))
731 process_stoptrace();
732 CLR(p->p_slflag, PSL_SYSCALLEMU);
733 #endif
734 }
735