Date: Tue, 20 Feb 2018 18:08:58 +0000 (UTC) From: Brooks Davis <brooks@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r329647 - in head/sys: compat/freebsd32 kern sys Message-ID: <201802201808.w1KI8wjA074652@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: brooks Date: Tue Feb 20 18:08:57 2018 New Revision: 329647 URL: https://svnweb.freebsd.org/changeset/base/329647 Log: 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 Modified: head/sys/compat/freebsd32/freebsd32_misc.c head/sys/compat/freebsd32/freebsd32_util.h head/sys/kern/kern_syscalls.c head/sys/sys/sysent.h Modified: head/sys/compat/freebsd32/freebsd32_misc.c ============================================================================== --- head/sys/compat/freebsd32/freebsd32_misc.c Tue Feb 20 18:05:21 2018 (r329646) +++ head/sys/compat/freebsd32/freebsd32_misc.c Tue Feb 20 18:08:57 2018 (r329647) @@ -3089,120 +3089,24 @@ freebsd32_xxx(struct thread *td, struct freebsd32_xxx_ #endif int -syscall32_register(int *offset, struct sysent *new_sysent, - struct sysent *old_sysent, int flags) -{ - - if ((flags & ~SY_THR_STATIC) != 0) - return (EINVAL); - - if (*offset == NO_SYSCALL) { - int i; - - for (i = 1; i < SYS_MAXSYSCALL; ++i) - if (freebsd32_sysent[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 (freebsd32_sysent[*offset].sy_call != (sy_call_t *)lkmnosys && - freebsd32_sysent[*offset].sy_call != (sy_call_t *)lkmressys) - return (EEXIST); - - *old_sysent = freebsd32_sysent[*offset]; - freebsd32_sysent[*offset] = *new_sysent; - atomic_store_rel_32(&freebsd32_sysent[*offset].sy_thrcnt, flags); - return (0); -} - -int -syscall32_deregister(int *offset, struct sysent *old_sysent) -{ - - if (*offset == 0) - return (0); - - freebsd32_sysent[*offset] = *old_sysent; - return (0); -} - -int syscall32_module_handler(struct module *mod, int what, void *arg) { - struct syscall_module_data *data = (struct syscall_module_data*)arg; - modspecific_t ms; - int error; - switch (what) { - case MOD_LOAD: - error = syscall32_register(data->offset, data->new_sysent, - &data->old_sysent, SY_THR_STATIC_KLD); - if (error) { - /* Leave a mark so we know to safely unload below. */ - data->offset = NULL; - return error; - } - ms.intval = *data->offset; - MOD_XLOCK; - module_setspecific(mod, &ms); - MOD_XUNLOCK; - if (data->chainevh) - error = data->chainevh(mod, what, data->chainarg); - return (error); - case MOD_UNLOAD: - /* - * MOD_LOAD failed, so just return without calling the - * chained handler since we didn't pass along the MOD_LOAD - * event. - */ - if (data->offset == NULL) - return (0); - if (data->chainevh) { - error = data->chainevh(mod, what, data->chainarg); - if (error) - return (error); - } - error = syscall32_deregister(data->offset, &data->old_sysent); - return (error); - default: - error = EOPNOTSUPP; - if (data->chainevh) - error = data->chainevh(mod, what, data->chainarg); - return (error); - } + return (kern_syscall_module_handler(freebsd32_sysent, mod, what, arg)); } int 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, flags); - if (error != 0) { - syscall32_helper_unregister(sd); - return (error); - } - sd1->registered = 1; - } - return (0); + return (kern_syscall_helper_register(freebsd32_sysent, sd, flags)); } int syscall32_helper_unregister(struct syscall_helper_data *sd) { - struct syscall_helper_data *sd1; - for (sd1 = sd; sd1->registered != 0; sd1++) { - syscall32_deregister(&sd1->syscall_no, &sd1->old_sysent); - sd1->registered = 0; - } - return (0); + return (kern_syscall_helper_unregister(freebsd32_sysent, sd)); } register_t * Modified: head/sys/compat/freebsd32/freebsd32_util.h ============================================================================== --- head/sys/compat/freebsd32/freebsd32_util.h Tue Feb 20 18:05:21 2018 (r329646) +++ head/sys/compat/freebsd32/freebsd32_util.h Tue Feb 20 18:08:57 2018 (r329647) @@ -106,9 +106,6 @@ SYSCALL32_MODULE(syscallname, #define SYSCALL32_INIT_HELPER_COMPAT(syscallname) \ SYSCALL32_INIT_HELPER_COMPAT_F(syscallname, 0) -int syscall32_register(int *offset, struct sysent *new_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 flags); int syscall32_helper_unregister(struct syscall_helper_data *sd); Modified: head/sys/kern/kern_syscalls.c ============================================================================== --- head/sys/kern/kern_syscalls.c Tue Feb 20 18:05:21 2018 (r329646) +++ head/sys/kern/kern_syscalls.c Tue Feb 20 18:08:57 2018 (r329647) @@ -109,8 +109,8 @@ syscall_thread_exit(struct thread *td, struct sysent * } 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_sysen 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, v 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, v 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 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); Modified: head/sys/sys/sysent.h ============================================================================== --- head/sys/sys/sysent.h Tue Feb 20 18:05:21 2018 (r329646) +++ head/sys/sys/sysent.h Tue Feb 20 18:08:57 2018 (r329647) @@ -262,12 +262,20 @@ struct syscall_helper_data { .syscall_no = NO_SYSCALL \ } -int syscall_register(int *offset, struct sysent *new_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 flags); int syscall_helper_unregister(struct syscall_helper_data *sd); +/* Implementation, exposed for COMPAT code */ +int kern_syscall_register(struct sysent *sysents, int *offset, + struct sysent *new_sysent, struct sysent *old_sysent, int flags); +int kern_syscall_deregister(struct sysent *sysents, int offset, + const struct sysent *old_sysent); +int kern_syscall_module_handler(struct sysent *sysents, + struct module *mod, int what, void *arg); +int kern_syscall_helper_register(struct sysent *sysents, + struct syscall_helper_data *sd, int flags); +int kern_syscall_helper_unregister(struct sysent *sysents, + struct syscall_helper_data *sd); struct proc; const char *syscallname(struct proc *p, u_int code);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201802201808.w1KI8wjA074652>