diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index d909a71ff270..8ec949f9d803 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -2628,8 +2628,12 @@ freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) int syscall32_register(int *offset, struct sysent *new_sysent, - struct sysent *old_sysent) + struct sysent *old_sysent, int flags) { + + if ((flags & ~SY_THR_STATIC) != 0) + return (EINVAL); + if (*offset == NO_SYSCALL) { int i; @@ -2648,16 +2652,19 @@ syscall32_register(int *offset, struct sysent *new_sysent, *old_sysent = freebsd32_sysent[*offset]; freebsd32_sysent[*offset] = *new_sysent; - return 0; + atomic_store_rel_32(&freebsd32_sysent[*offset].sy_thrcnt, flags); + return (0); } int syscall32_deregister(int *offset, struct sysent *old_sysent) { - if (*offset) - freebsd32_sysent[*offset] = *old_sysent; - return 0; + if (*offset == 0) + return (0); + + freebsd32_sysent[*offset] = *old_sysent; + return (0); } int @@ -2670,7 +2677,7 @@ syscall32_module_handler(struct module *mod, int what, void *arg) switch (what) { case MOD_LOAD: error = syscall32_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; @@ -2707,14 +2714,14 @@ syscall32_module_handler(struct module *mod, int what, void *arg) } int -syscall32_helper_register(struct syscall_helper_data *sd) +syscall32_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 = syscall32_register(&sd1->syscall_no, &sd1->new_sysent, - &sd1->old_sysent); + &sd1->old_sysent, flags); if (error != 0) { syscall32_helper_unregister(sd); return (error); diff --git a/sys/compat/freebsd32/freebsd32_util.h b/sys/compat/freebsd32/freebsd32_util.h index a5945cfbbe7e..d62bca1fa8f9 100644 --- a/sys/compat/freebsd32/freebsd32_util.h +++ b/sys/compat/freebsd32/freebsd32_util.h @@ -98,10 +98,10 @@ SYSCALL32_MODULE(syscallname, \ } int syscall32_register(int *offset, struct sysent *new_sysent, - struct sysent *old_sysent); + struct sysent *old_sysent, int flags); int syscall32_deregister(int *offset, struct sysent *old_sysent); int syscall32_module_handler(struct module *mod, int what, void *arg); -int syscall32_helper_register(struct syscall_helper_data *sd); +int syscall32_helper_register(struct syscall_helper_data *sd, int flags); int syscall32_helper_unregister(struct syscall_helper_data *sd); struct iovec32; 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); diff --git a/sys/kern/sysv_msg.c b/sys/kern/sysv_msg.c index a572a0e0c145..acc44710a78a 100644 --- a/sys/kern/sysv_msg.c +++ b/sys/kern/sysv_msg.c @@ -252,11 +252,11 @@ msginit() } mtx_init(&msq_mtx, "msq", NULL, MTX_DEF); - error = syscall_helper_register(msg_syscalls); + error = syscall_helper_register(msg_syscalls, SY_THR_STATIC_KLD); if (error != 0) return (error); #ifdef COMPAT_FREEBSD32 - error = syscall32_helper_register(msg32_syscalls); + error = syscall32_helper_register(msg32_syscalls, SY_THR_STATIC_KLD); if (error != 0) return (error); #endif diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c index c63290240799..6ff578926a51 100644 --- a/sys/kern/sysv_sem.c +++ b/sys/kern/sysv_sem.c @@ -278,11 +278,11 @@ seminit(void) semexit_tag = EVENTHANDLER_REGISTER(process_exit, semexit_myhook, NULL, EVENTHANDLER_PRI_ANY); - error = syscall_helper_register(sem_syscalls); + error = syscall_helper_register(sem_syscalls, SY_THR_STATIC_KLD); if (error != 0) return (error); #ifdef COMPAT_FREEBSD32 - error = syscall32_helper_register(sem32_syscalls); + error = syscall32_helper_register(sem32_syscalls, SY_THR_STATIC_KLD); if (error != 0) return (error); #endif diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c index 3480d1140070..15ee910971ec 100644 --- a/sys/kern/sysv_shm.c +++ b/sys/kern/sysv_shm.c @@ -910,11 +910,11 @@ shminit() shmexit_hook = &shmexit_myhook; shmfork_hook = &shmfork_myhook; - error = syscall_helper_register(shm_syscalls); + error = syscall_helper_register(shm_syscalls, SY_THR_STATIC_KLD); if (error != 0) return (error); #ifdef COMPAT_FREEBSD32 - error = syscall32_helper_register(shm32_syscalls); + error = syscall32_helper_register(shm32_syscalls, SY_THR_STATIC_KLD); if (error != 0) return (error); #endif diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c index 154c1e76613d..e3fb1491f8c1 100644 --- a/sys/kern/uipc_mqueue.c +++ b/sys/kern/uipc_mqueue.c @@ -2809,11 +2809,11 @@ mqinit(void) { int error; - error = syscall_helper_register(mq_syscalls); + error = syscall_helper_register(mq_syscalls, SY_THR_STATIC_KLD); if (error != 0) return (error); #ifdef COMPAT_FREEBSD32 - error = syscall32_helper_register(mq32_syscalls); + error = syscall32_helper_register(mq32_syscalls, SY_THR_STATIC_KLD); if (error != 0) return (error); #endif diff --git a/sys/kern/uipc_sem.c b/sys/kern/uipc_sem.c index 63b1cec0e036..935a245632e6 100644 --- a/sys/kern/uipc_sem.c +++ b/sys/kern/uipc_sem.c @@ -993,11 +993,11 @@ ksem_module_init(void) p31b_setcfg(CTL_P1003_1B_SEM_NSEMS_MAX, SEM_MAX); p31b_setcfg(CTL_P1003_1B_SEM_VALUE_MAX, SEM_VALUE_MAX); - error = syscall_helper_register(ksem_syscalls); + error = syscall_helper_register(ksem_syscalls, SY_THR_STATIC_KLD); if (error) return (error); #ifdef COMPAT_FREEBSD32 - error = syscall32_helper_register(ksem32_syscalls); + error = syscall32_helper_register(ksem32_syscalls, SY_THR_STATIC_KLD); if (error) return (error); #endif diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index b47d713c0825..c7e602e2eb86 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -511,11 +511,11 @@ aio_onceonly(void) p31b_setcfg(CTL_P1003_1B_AIO_MAX, MAX_AIO_QUEUE); p31b_setcfg(CTL_P1003_1B_AIO_PRIO_DELTA_MAX, 0); - error = syscall_helper_register(aio_syscalls); + error = syscall_helper_register(aio_syscalls, SY_THR_STATIC_KLD); if (error) return (error); #ifdef COMPAT_FREEBSD32 - error = syscall32_helper_register(aio32_syscalls); + error = syscall32_helper_register(aio32_syscalls, SY_THR_STATIC_KLD); if (error) return (error); #endif diff --git a/sys/kgssapi/gss_impl.c b/sys/kgssapi/gss_impl.c index 172471aa4826..ab6e55bc377d 100644 --- a/sys/kgssapi/gss_impl.c +++ b/sys/kgssapi/gss_impl.c @@ -70,7 +70,7 @@ kgss_init(void *dummy) LIST_INIT(&kgss_mechs); error = syscall_register(&gssd_syscall_offset, &gssd_syscall_sysent, - &gssd_syscall_prev_sysent); + &gssd_syscall_prev_sysent, SY_THR_STATIC_KLD); if (error) printf("Can't register GSSD syscall\n"); else diff --git a/sys/netinet/sctp_syscalls.c b/sys/netinet/sctp_syscalls.c index 3d0f549997a7..3161abcc2c01 100644 --- a/sys/netinet/sctp_syscalls.c +++ b/sys/netinet/sctp_syscalls.c @@ -94,11 +94,11 @@ sctp_syscalls_init(void *unused __unused) { int error; - error = syscall_helper_register(sctp_syscalls); + error = syscall_helper_register(sctp_syscalls, SY_THR_STATIC); KASSERT((error == 0), ("%s: syscall_helper_register failed for sctp syscalls", __func__)); #ifdef COMPAT_FREEBSD32 - error = syscall32_helper_register(sctp_syscalls); + error = syscall32_helper_register(sctp_syscalls, SY_THR_STATIC); KASSERT((error == 0), ("%s: syscall32_helper_register failed for sctp syscalls", __func__)); diff --git a/sys/nfs/nfs_nfssvc.c b/sys/nfs/nfs_nfssvc.c index 3f925a13170a..c0d78e0280c8 100644 --- a/sys/nfs/nfs_nfssvc.c +++ b/sys/nfs/nfs_nfssvc.c @@ -123,7 +123,7 @@ nfssvc_modevent(module_t mod, int type, void *data) switch (type) { case MOD_LOAD: error = syscall_register(&nfssvc_offset, &nfssvc_sysent, - &nfssvc_prev_sysent); + &nfssvc_prev_sysent, SY_THR_STATIC_KLD); if (error) break; registered = 1; diff --git a/sys/nlm/nlm_prot_impl.c b/sys/nlm/nlm_prot_impl.c index 74fae870efa3..5f202066ab70 100644 --- a/sys/nlm/nlm_prot_impl.c +++ b/sys/nlm/nlm_prot_impl.c @@ -295,7 +295,7 @@ nlm_init(void *dummy) TAILQ_INIT(&nlm_hosts); error = syscall_register(&nlm_syscall_offset, &nlm_syscall_sysent, - &nlm_syscall_prev_sysent); + &nlm_syscall_prev_sysent, SY_THR_STATIC_KLD); if (error) NLM_ERR("Can't register NLM syscall\n"); else diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h index 0f1c256135f1..dabc8e843300 100644 --- a/sys/sys/sysent.h +++ b/sys/sys/sysent.h @@ -76,6 +76,12 @@ struct sysent { /* system call table */ #define SY_THR_ABSENT 0x4 #define SY_THR_INCR 0x8 +#ifdef KLD_MODULE +#define SY_THR_STATIC_KLD 0 +#else +#define SY_THR_STATIC_KLD SY_THR_STATIC +#endif + struct image_params; struct __sigset; struct syscall_args; @@ -242,10 +248,10 @@ struct syscall_helper_data { } int syscall_register(int *offset, struct sysent *new_sysent, - struct sysent *old_sysent); + struct sysent *old_sysent, int flags); int syscall_deregister(int *offset, struct sysent *old_sysent); int syscall_module_handler(struct module *mod, int what, void *arg); -int syscall_helper_register(struct syscall_helper_data *sd); +int syscall_helper_register(struct syscall_helper_data *sd, int flags); int syscall_helper_unregister(struct syscall_helper_data *sd); struct proc;