summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2006-07-27 22:32:30 +0000
committerjhb <jhb@FreeBSD.org>2006-07-27 22:32:30 +0000
commit12302c47d0774765f92ead9706c43dd6e9b1af80 (patch)
tree47879e45272c43d1dac6fed60572111e89f9a60b /sys
parentdc69447236a19f806729d1c133c456528b241db4 (diff)
downloadFreeBSD-src-12302c47d0774765f92ead9706c43dd6e9b1af80.zip
FreeBSD-src-12302c47d0774765f92ead9706c43dd6e9b1af80.tar.gz
Unify the checking for lock misbehavior in the various syscall()
implementations and adjust some of the checks while I'm here: - Add a new check to make sure we don't return from a syscall in a critical section. - Add a new explicit check before userret() to make sure we don't return with any locks held. The advantage here is that we can include the syscall number and name in syscall() whereas that info is not available in userret(). - Drop the mtx_assert()'s of sched_lock and Giant. They are replaced by the more general checks just added. MFC after: 2 weeks
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/trap.c20
-rw-r--r--sys/amd64/ia32/ia32_syscall.c18
-rw-r--r--sys/arm/arm/trap.c16
-rw-r--r--sys/conf/files2
-rw-r--r--sys/i386/i386/trap.c20
-rw-r--r--sys/ia64/ia32/ia32_trap.c20
-rw-r--r--sys/ia64/ia64/trap.c20
-rw-r--r--sys/powerpc/aim/trap.c18
-rw-r--r--sys/powerpc/powerpc/trap.c18
-rw-r--r--sys/sparc64/sparc64/trap.c18
10 files changed, 117 insertions, 53 deletions
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index d41318c..415d695 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -145,9 +145,7 @@ static int panic_on_nmi = 1;
SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RW,
&panic_on_nmi, 0, "Panic on NMI");
-#ifdef WITNESS
extern char *syscallnames[];
-#endif
/*
* Exception, fault, and trap interface to the FreeBSD kernel.
@@ -874,6 +872,19 @@ syscall(frame)
}
/*
+ * Check for misbehavior.
+ */
+ WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
+ KASSERT(td->td_critnest == 0,
+ ("System call %s returning in a critical section",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"));
+ KASSERT(td->td_locks == 0,
+ ("System call %s returning with %d locks held",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???",
+ td->td_locks));
+
+ /*
* Handle reschedule and other end-of-syscall issues
*/
userret(td, &frame);
@@ -894,9 +905,4 @@ syscall(frame)
STOPEVENT(p, S_SCX, code);
PTRACESTOP_SC(p, td, S_PT_SCX);
-
- WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
- (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
- mtx_assert(&sched_lock, MA_NOTOWNED);
- mtx_assert(&Giant, MA_NOTOWNED);
}
diff --git a/sys/amd64/ia32/ia32_syscall.c b/sys/amd64/ia32/ia32_syscall.c
index 5b3086a..644235d 100644
--- a/sys/amd64/ia32/ia32_syscall.c
+++ b/sys/amd64/ia32/ia32_syscall.c
@@ -244,6 +244,19 @@ ia32_syscall(struct trapframe frame)
}
/*
+ * Check for misbehavior.
+ */
+ WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? freebsd32_syscallnames[code] : "???");
+ KASSERT(td->td_critnest == 0,
+ ("System call %s returning in a critical section",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? freebsd32_syscallnames[code] : "???"));
+ KASSERT(td->td_locks == 0,
+ ("System call %s returning with %d locks held",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? freebsd32_syscallnames[code] : "???",
+ td->td_locks));
+
+ /*
* Handle reschedule and other end-of-syscall issues
*/
userret(td, &frame);
@@ -263,11 +276,6 @@ ia32_syscall(struct trapframe frame)
STOPEVENT(p, S_SCX, code);
PTRACESTOP_SC(p, td, S_PT_SCX);
-
- WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
- (code >= 0 && code < SYS_MAXSYSCALL) ? freebsd32_syscallnames[code] : "???");
- mtx_assert(&sched_lock, MA_NOTOWNED);
- mtx_assert(&Giant, MA_NOTOWNED);
}
diff --git a/sys/arm/arm/trap.c b/sys/arm/arm/trap.c
index b1534fe..1cb53db 100644
--- a/sys/arm/arm/trap.c
+++ b/sys/arm/arm/trap.c
@@ -133,6 +133,7 @@ void undefinedinstruction(trapframe_t *);
#include <machine/machdep.h>
extern char fusubailout[];
+extern char *syscallnames[];
#ifdef DEBUG
int last_fault_code; /* For the benefit of pmap_fault_fixup() */
@@ -979,8 +980,17 @@ bad:
}
if (locked && (callp->sy_narg & SYF_MPSAFE) == 0)
mtx_unlock(&Giant);
-
-
+
+ WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
+ KASSERT(td->td_critnest == 0,
+ ("System call %s returning in a critical section",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"));
+ KASSERT(td->td_locks == 0,
+ ("System call %s returning with %d locks held",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???",
+ td->td_locks));
+
userret(td, frame);
CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td,
td->td_proc->p_pid, td->td_proc->p_comm, code);
@@ -991,8 +1001,6 @@ bad:
if (KTRPOINT(td, KTR_SYSRET))
ktrsysret(code, error, td->td_retval[0]);
#endif
- mtx_assert(&sched_lock, MA_NOTOWNED);
- mtx_assert(&Giant, MA_NOTOWNED);
}
void
diff --git a/sys/conf/files b/sys/conf/files
index 24c8cf5..a02023b 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1402,7 +1402,7 @@ kern/sys_generic.c standard
kern/sys_pipe.c standard
kern/sys_process.c standard
kern/sys_socket.c standard
-kern/syscalls.c optional witness
+kern/syscalls.c optional witness | invariants
kern/sysv_ipc.c standard
kern/sysv_msg.c optional sysvmsg
kern/sysv_sem.c optional sysvsem
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index cce7038..da3ed95 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -159,9 +159,7 @@ static int panic_on_nmi = 1;
SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RW,
&panic_on_nmi, 0, "Panic on NMI");
-#ifdef WITNESS
extern char *syscallnames[];
-#endif
/*
* Exception, fault, and trap interface to the FreeBSD kernel.
@@ -1065,6 +1063,19 @@ syscall(frame)
}
/*
+ * Check for misbehavior.
+ */
+ WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
+ KASSERT(td->td_critnest == 0,
+ ("System call %s returning in a critical section",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"));
+ KASSERT(td->td_locks == 0,
+ ("System call %s returning with %d locks held",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???",
+ td->td_locks));
+
+ /*
* Handle reschedule and other end-of-syscall issues
*/
userret(td, &frame);
@@ -1085,10 +1096,5 @@ syscall(frame)
STOPEVENT(p, S_SCX, code);
PTRACESTOP_SC(p, td, S_PT_SCX);
-
- WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
- (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
- mtx_assert(&sched_lock, MA_NOTOWNED);
- mtx_assert(&Giant, MA_NOTOWNED);
}
diff --git a/sys/ia64/ia32/ia32_trap.c b/sys/ia64/ia32/ia32_trap.c
index c3cacf5..f63ae94 100644
--- a/sys/ia64/ia32/ia32_trap.c
+++ b/sys/ia64/ia32/ia32_trap.c
@@ -46,9 +46,7 @@ __FBSDID("$FreeBSD$");
#include <machine/md_var.h>
#include <i386/include/psl.h>
-#ifdef WITNESS
extern char *syscallnames[];
-#endif
static void
ia32_syscall(struct trapframe *tf)
@@ -183,6 +181,19 @@ ia32_syscall(struct trapframe *tf)
}
/*
+ * Check for misbehavior.
+ */
+ WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
+ KASSERT(td->td_critnest == 0,
+ ("System call %s returning in a critical section",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"));
+ KASSERT(td->td_locks == 0,
+ ("System call %s returning with %d locks held",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???",
+ td->td_locks));
+
+ /*
* End of syscall tracing.
*/
CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td,
@@ -200,11 +211,6 @@ ia32_syscall(struct trapframe *tf)
STOPEVENT(p, S_SCX, code);
PTRACESTOP_SC(p, td, S_PT_SCX);
-
- WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
- (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
- mtx_assert(&sched_lock, MA_NOTOWNED);
- mtx_assert(&Giant, MA_NOTOWNED);
}
/*
diff --git a/sys/ia64/ia64/trap.c b/sys/ia64/ia64/trap.c
index 93b518d..d0f3c98 100644
--- a/sys/ia64/ia64/trap.c
+++ b/sys/ia64/ia64/trap.c
@@ -85,9 +85,7 @@ static void break_syscall(struct trapframe *tf);
*/
extern struct fpswa_iface *fpswa_iface;
-#ifdef WITNESS
extern char *syscallnames[];
-#endif
static const char *ia64_vector_names[] = {
"VHPT Translation", /* 0 */
@@ -1049,6 +1047,19 @@ syscall(struct trapframe *tf)
}
/*
+ * Check for misbehavior.
+ */
+ WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
+ KASSERT(td->td_critnest == 0,
+ ("System call %s returning in a critical section",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"));
+ KASSERT(td->td_locks == 0,
+ ("System call %s returning with %d locks held",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???",
+ td->td_locks));
+
+ /*
* Handle reschedule and other end-of-syscall issues
*/
userret(td, tf);
@@ -1069,10 +1080,5 @@ syscall(struct trapframe *tf)
PTRACESTOP_SC(p, td, S_PT_SCX);
- WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
- (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
- mtx_assert(&sched_lock, MA_NOTOWNED);
- mtx_assert(&Giant, MA_NOTOWNED);
-
return (error);
}
diff --git a/sys/powerpc/aim/trap.c b/sys/powerpc/aim/trap.c
index 527e9fb..0f5961b 100644
--- a/sys/powerpc/aim/trap.c
+++ b/sys/powerpc/aim/trap.c
@@ -470,6 +470,19 @@ syscall(struct trapframe *frame)
if ((callp->sy_narg & SYF_MPSAFE) == 0)
mtx_unlock(&Giant);
+ /*
+ * Check for misbehavior.
+ */
+ WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
+ KASSERT(td->td_critnest == 0,
+ ("System call %s returning in a critical section",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"));
+ KASSERT(td->td_locks == 0,
+ ("System call %s returning with %d locks held",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???",
+ td->td_locks));
+
#ifdef KTRACE
if (KTRPOINT(td, KTR_SYSRET))
ktrsysret(code, error, td->td_retval[0]);
@@ -481,11 +494,6 @@ syscall(struct trapframe *frame)
STOPEVENT(p, S_SCX, code);
PTRACESTOP_SC(p, td, S_PT_SCX);
-
- WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
- (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
- mtx_assert(&sched_lock, MA_NOTOWNED);
- mtx_assert(&Giant, MA_NOTOWNED);
}
static int
diff --git a/sys/powerpc/powerpc/trap.c b/sys/powerpc/powerpc/trap.c
index 527e9fb..0f5961b 100644
--- a/sys/powerpc/powerpc/trap.c
+++ b/sys/powerpc/powerpc/trap.c
@@ -470,6 +470,19 @@ syscall(struct trapframe *frame)
if ((callp->sy_narg & SYF_MPSAFE) == 0)
mtx_unlock(&Giant);
+ /*
+ * Check for misbehavior.
+ */
+ WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
+ KASSERT(td->td_critnest == 0,
+ ("System call %s returning in a critical section",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"));
+ KASSERT(td->td_locks == 0,
+ ("System call %s returning with %d locks held",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???",
+ td->td_locks));
+
#ifdef KTRACE
if (KTRPOINT(td, KTR_SYSRET))
ktrsysret(code, error, td->td_retval[0]);
@@ -481,11 +494,6 @@ syscall(struct trapframe *frame)
STOPEVENT(p, S_SCX, code);
PTRACESTOP_SC(p, td, S_PT_SCX);
-
- WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
- (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
- mtx_assert(&sched_lock, MA_NOTOWNED);
- mtx_assert(&Giant, MA_NOTOWNED);
}
static int
diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c
index f45d273..b1c0dcc 100644
--- a/sys/sparc64/sparc64/trap.c
+++ b/sys/sparc64/sparc64/trap.c
@@ -648,6 +648,19 @@ syscall(struct trapframe *tf)
mtx_unlock(&Giant);
/*
+ * Check for misbehavior.
+ */
+ WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
+ KASSERT(td->td_critnest == 0,
+ ("System call %s returning in a critical section",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"));
+ KASSERT(td->td_locks == 0,
+ ("System call %s returning with %d locks held",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???",
+ td->td_locks));
+
+ /*
* Handle reschedule and other end-of-syscall issues
*/
userret(td, tf);
@@ -664,9 +677,4 @@ syscall(struct trapframe *tf)
STOPEVENT(p, S_SCX, code);
PTRACESTOP_SC(p, td, S_PT_SCX);
-
- WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
- (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
- mtx_assert(&sched_lock, MA_NOTOWNED);
- mtx_assert(&Giant, MA_NOTOWNED);
}
OpenPOWER on IntegriCloud