aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_syscalls.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_syscalls.c')
-rw-r--r--sys/kern/kern_syscalls.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/sys/kern/kern_syscalls.c b/sys/kern/kern_syscalls.c
index 03f6088403de..78d2a852cfb2 100644
--- a/sys/kern/kern_syscalls.c
+++ b/sys/kern/kern_syscalls.c
@@ -105,10 +105,13 @@ syscall_thread_exit(struct thread *td, struct sysent *se)
int
syscall_register(int *offset, struct sysent *new_sysent,
- struct sysent *old_sysent)
+ struct sysent *old_sysent, int flags)
{
int i;
+ if ((flags & ~SY_THR_STATIC) != 0)
+ return (EINVAL);
+
if (*offset == NO_SYSCALL) {
for (i = 1; i < SYS_MAXSYSCALL; ++i)
if (sysent[i].sy_call == (sy_call_t *)lkmnosys)
@@ -127,18 +130,23 @@ syscall_register(int *offset, struct sysent *new_sysent,
*old_sysent = sysent[*offset];
new_sysent->sy_thrcnt = SY_THR_ABSENT;
sysent[*offset] = *new_sysent;
- atomic_store_rel_32(&sysent[*offset].sy_thrcnt, 0);
+ atomic_store_rel_32(&sysent[*offset].sy_thrcnt, flags);
return (0);
}
int
syscall_deregister(int *offset, struct sysent *old_sysent)
{
+ struct sysent *se;
- if (*offset) {
- syscall_thread_drain(&sysent[*offset]);
- sysent[*offset] = *old_sysent;
- }
+ if (*offset == 0)
+ return (0); /* XXX? */
+
+ se = &sysent[*offset];
+ if ((se->sy_thrcnt & SY_THR_STATIC) != 0)
+ return (EINVAL);
+ syscall_thread_drain(se);
+ sysent[*offset] = *old_sysent;
return (0);
}
@@ -152,7 +160,7 @@ syscall_module_handler(struct module *mod, int what, void *arg)
switch (what) {
case MOD_LOAD:
error = syscall_register(data->offset, data->new_sysent,
- &data->old_sysent);
+ &data->old_sysent, SY_THR_STATIC_KLD);
if (error) {
/* Leave a mark so we know to safely unload below. */
data->offset = NULL;
@@ -190,14 +198,14 @@ syscall_module_handler(struct module *mod, int what, void *arg)
}
int
-syscall_helper_register(struct syscall_helper_data *sd)
+syscall_helper_register(struct syscall_helper_data *sd, int flags)
{
struct syscall_helper_data *sd1;
int error;
for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) {
error = syscall_register(&sd1->syscall_no, &sd1->new_sysent,
- &sd1->old_sysent);
+ &sd1->old_sysent, flags);
if (error != 0) {
syscall_helper_unregister(sd);
return (error);