diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2007-11-27 18:04:02 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2007-11-27 18:04:02 +0000 |
commit | a38b2fbb3705b793598a6e2cf7ce27746f398676 (patch) | |
tree | a417e6e13a8331dca2b2e34d65d8cc8da6d28574 /sys | |
parent | 922d37fc9056808e0aba874018477acff6582bda (diff) |
Add possibility to add flags to syscalls in syscalls.master to mark
syscalls as NOLOCK and MPSAFE. The flags have slightly different semantics:
NOLOCK - the syscall doesn't grab any locks whatsoever.
MPSAFE - the syscall deals with its own locking.
What this means in practice is that NOLOCK syscalls can always be done
without the biglock. The MPSAFE syscalls can be done without the biglock
on CPUs that don't handle interrupts that require biglock (to preserve
lock ordering).
deraadt@ ok
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/makesyscalls.sh | 19 | ||||
-rw-r--r-- | sys/sys/systm.h | 7 |
2 files changed, 20 insertions, 6 deletions
diff --git a/sys/kern/makesyscalls.sh b/sys/kern/makesyscalls.sh index e641fe5df65..1f162b3fda3 100644 --- a/sys/kern/makesyscalls.sh +++ b/sys/kern/makesyscalls.sh @@ -1,5 +1,5 @@ #! /bin/sh - -# $OpenBSD: makesyscalls.sh,v 1.10 2002/03/14 23:44:37 millert Exp $ +# $OpenBSD: makesyscalls.sh,v 1.11 2007/11/27 18:04:01 art Exp $ # $NetBSD: makesyscalls.sh,v 1.26 1998/01/09 06:17:51 thorpej Exp $ # # Copyright (c) 1994,1996 Christopher G. Demetriou @@ -247,6 +247,7 @@ function parserr(was, wanted) { } function parseline() { f=3 # toss number and type + sycall_flags="0" if ($NF != "}") { funcalias=$NF end=NF-1 @@ -254,6 +255,14 @@ function parseline() { funcalias="" end=NF } + if ($f == "MPSAFE") { # allow MP-safe syscalls + sycall_flags = sprintf("SY_MPSAFE | %s", sycall_flags) + f++ + } + if ($f == "NOLOCK") { # syscall does not need locks + sycall_flags = sprintf("SY_NOLOCK | %s", sycall_flags) + f++ + } if ($f ~ /^[a-z0-9_]*$/) { # allow syscall alias funcalias=$f f++ @@ -359,8 +368,8 @@ function putent(nodefs, compatwrap) { # output syscall switch entry if (nodefs == "INDIR") { - printf("\t{ 0, 0,\n\t sys_nosys },\t\t\t/* %d = %s (indir) */\n", \ - syscall, funcalias) > sysent + printf("\t{ 0, 0, %s,\n\t sys_nosys },\t\t\t/* %d = %s (indir) */\n", \ + sycall_flags, syscall, funcalias) > sysent } else { # printf("\t{ { %d", argc) > sysent # for (i = 1; i <= argc; i++) { @@ -382,7 +391,7 @@ function putent(nodefs, compatwrap) { wfn = sprintf("%s", funcname); else wfn = sprintf("%s(%s)", compatwrap, funcname); - printf(",\n\t %s },", wfn) > sysent + printf(", %s,\n\t %s },", sycall_flags, wfn) > sysent for (i = 0; i < (33 - length(wfn)) / 8; i++) printf("\t") > sysent if (compatwrap == "") @@ -451,7 +460,7 @@ $2 == "OBSOL" || $2 == "UNIMPL" { for (i = 3; i <= NF; i++) comment=comment " " $i - printf("\t{ 0, 0,\n\t sys_nosys },\t\t\t/* %d = %s */\n", \ + printf("\t{ 0, 0, 0,\n\t sys_nosys },\t\t\t/* %d = %s */\n", \ syscall, comment) > sysent printf("\t\"#%d (%s)\",\t\t/* %d = %s */\n", \ syscall, comment, syscall, comment) > sysnames diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 2e36c9997cc..abddd429c1c 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -1,4 +1,4 @@ -/* $OpenBSD: systm.h,v 1.72 2007/06/01 19:25:08 deraadt Exp $ */ +/* $OpenBSD: systm.h,v 1.73 2007/11/27 18:04:01 art Exp $ */ /* $NetBSD: systm.h,v 1.50 1996/06/09 04:55:09 briggs Exp $ */ /*- @@ -110,8 +110,13 @@ typedef int sy_call_t(struct proc *, void *, register_t *); extern struct sysent { /* system call table */ short sy_narg; /* number of args */ short sy_argsize; /* total size of arguments */ + int sy_flags; sy_call_t *sy_call; /* implementing function */ } sysent[]; + +#define SY_MPSAFE 0x01 +#define SY_NOLOCK 0x02 + #if _BYTE_ORDER == _BIG_ENDIAN #define SCARG(p, k) ((p)->k.be.datum) /* get arg from args pointer */ #elif _BYTE_ORDER == _LITTLE_ENDIAN |