From b81e88d29696f9d263c62735b1598b55095f791e Mon Sep 17 00:00:00 2001 From: Brooks Davis Date: Tue, 20 Feb 2018 18:08:57 +0000 Subject: 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 --- sys/kern/kern_syscalls.c | 67 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 20 deletions(-) (limited to 'sys/kern/kern_syscalls.c') 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,44 +119,53 @@ 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; @@ -164,8 +173,8 @@ 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->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) @@ -204,15 +214,23 @@ 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; @@ -222,11 +240,20 @@ 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); -- cgit v1.2.3