diff options
author | Brooks Davis <brooks@FreeBSD.org> | 2018-02-20 18:08:57 +0000 |
---|---|---|
committer | Brooks Davis <brooks@FreeBSD.org> | 2018-02-20 18:08:57 +0000 |
commit | b81e88d29696f9d263c62735b1598b55095f791e (patch) | |
tree | 52d6ec073ffa10df6cb291e1e93cddca29693480 /sys/kern/kern_syscalls.c | |
parent | 2765f3ac26a3f84f4f8d8d57248e364565735595 (diff) | |
download | src-b81e88d29696f9d263c62735b1598b55095f791e.tar.gz src-b81e88d29696f9d263c62735b1598b55095f791e.zip |
Reduce duplication in dynamic syscall registration code.
Remove the unused syscall_(de)register() functions in favor of the
better documented and easier to use syscall_helper_(un)register(9)
functions.
The default and freebsd32 versions differed in which array of struct
sysents they used and a few missing updates to the 32-bit code as
features were added to the main code.
Reviewed by: cem
Sponsored by: DARPA, AFRL
Differential Revision: https://reviews.freebsd.org/D14337
Notes
Notes:
svn path=/head/; revision=329647
Diffstat (limited to 'sys/kern/kern_syscalls.c')
-rw-r--r-- | sys/kern/kern_syscalls.c | 67 |
1 files changed, 47 insertions, 20 deletions
diff --git a/sys/kern/kern_syscalls.c b/sys/kern/kern_syscalls.c index 756a83e229d9..93d40d420541 100644 --- a/sys/kern/kern_syscalls.c +++ b/sys/kern/kern_syscalls.c @@ -109,8 +109,8 @@ syscall_thread_exit(struct thread *td, struct sysent *se) } int -syscall_register(int *offset, struct sysent *new_sysent, - struct sysent *old_sysent, int flags) +kern_syscall_register(struct sysent *sysents, int *offset, + struct sysent *new_sysent, struct sysent *old_sysent, int flags) { int i; @@ -119,53 +119,62 @@ syscall_register(int *offset, struct sysent *new_sysent, if (*offset == NO_SYSCALL) { for (i = 1; i < SYS_MAXSYSCALL; ++i) - if (sysent[i].sy_call == (sy_call_t *)lkmnosys) + if (sysents[i].sy_call == (sy_call_t *)lkmnosys) break; if (i == SYS_MAXSYSCALL) return (ENFILE); *offset = i; } else if (*offset < 0 || *offset >= SYS_MAXSYSCALL) return (EINVAL); - else if (sysent[*offset].sy_call != (sy_call_t *)lkmnosys && - sysent[*offset].sy_call != (sy_call_t *)lkmressys) + else if (sysents[*offset].sy_call != (sy_call_t *)lkmnosys && + sysents[*offset].sy_call != (sy_call_t *)lkmressys) return (EEXIST); - KASSERT(sysent[*offset].sy_thrcnt == SY_THR_ABSENT, + KASSERT(sysents[*offset].sy_thrcnt == SY_THR_ABSENT, ("dynamic syscall is not protected")); - *old_sysent = sysent[*offset]; + *old_sysent = sysents[*offset]; new_sysent->sy_thrcnt = SY_THR_ABSENT; - sysent[*offset] = *new_sysent; - atomic_store_rel_32(&sysent[*offset].sy_thrcnt, flags); + sysents[*offset] = *new_sysent; + atomic_store_rel_32(&sysents[*offset].sy_thrcnt, flags); return (0); } int -syscall_deregister(int *offset, struct sysent *old_sysent) +kern_syscall_deregister(struct sysent *sysents, int offset, + const struct sysent *old_sysent) { struct sysent *se; - if (*offset == 0) + if (offset == 0) return (0); /* XXX? */ - se = &sysent[*offset]; + se = &sysents[offset]; if ((se->sy_thrcnt & SY_THR_STATIC) != 0) return (EINVAL); syscall_thread_drain(se); - sysent[*offset] = *old_sysent; + sysent[offset] = *old_sysent; return (0); } int syscall_module_handler(struct module *mod, int what, void *arg) { + + return (kern_syscall_module_handler(sysent, mod, what, arg)); +} + +int +kern_syscall_module_handler(struct sysent *sysents, struct module *mod, + int what, void *arg) +{ struct syscall_module_data *data = arg; modspecific_t ms; int error; switch (what) { case MOD_LOAD: - error = syscall_register(data->offset, data->new_sysent, - &data->old_sysent, data->flags); + error = kern_syscall_register(sysents, data->offset, + data->new_sysent, &data->old_sysent, data->flags); if (error) { /* Leave a mark so we know to safely unload below. */ data->offset = NULL; @@ -191,7 +200,8 @@ syscall_module_handler(struct module *mod, int what, void *arg) if (error) return error; } - error = syscall_deregister(data->offset, &data->old_sysent); + error = kern_syscall_deregister(sysents, *data->offset, + &data->old_sysent); return (error); default: if (data->chainevh) @@ -205,14 +215,22 @@ syscall_module_handler(struct module *mod, int what, void *arg) int syscall_helper_register(struct syscall_helper_data *sd, int flags) { + + return (kern_syscall_helper_register(sysent, sd, flags)); +} + +int +kern_syscall_helper_register(struct sysent *sysents, + 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, flags); + error = kern_syscall_register(sysents, &sd1->syscall_no, + &sd1->new_sysent, &sd1->old_sysent, flags); if (error != 0) { - syscall_helper_unregister(sd); + kern_syscall_helper_unregister(sysents, sd); return (error); } sd1->registered = 1; @@ -223,10 +241,19 @@ syscall_helper_register(struct syscall_helper_data *sd, int flags) int syscall_helper_unregister(struct syscall_helper_data *sd) { + + return (kern_syscall_helper_unregister(sysent, sd)); +} + +int +kern_syscall_helper_unregister(struct sysent *sysents, + struct syscall_helper_data *sd) +{ struct syscall_helper_data *sd1; for (sd1 = sd; sd1->registered != 0; sd1++) { - syscall_deregister(&sd1->syscall_no, &sd1->old_sysent); + kern_syscall_deregister(sysents, sd1->syscall_no, + &sd1->old_sysent); sd1->registered = 0; } return (0); |