summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2007-11-27 18:04:02 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2007-11-27 18:04:02 +0000
commita38b2fbb3705b793598a6e2cf7ce27746f398676 (patch)
treea417e6e13a8331dca2b2e34d65d8cc8da6d28574 /sys
parent922d37fc9056808e0aba874018477acff6582bda (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.sh19
-rw-r--r--sys/sys/systm.h7
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