From owner-svn-src-head@freebsd.org Tue Feb 20 18:08:59 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D437AF1B441; Tue, 20 Feb 2018 18:08:58 +0000 (UTC) (envelope-from brooks@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 8419C83D5D; Tue, 20 Feb 2018 18:08:58 +0000 (UTC) (envelope-from brooks@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 7E7C55181; Tue, 20 Feb 2018 18:08:58 +0000 (UTC) (envelope-from brooks@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w1KI8wIe074656; Tue, 20 Feb 2018 18:08:58 GMT (envelope-from brooks@FreeBSD.org) Received: (from brooks@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w1KI8wjA074652; Tue, 20 Feb 2018 18:08:58 GMT (envelope-from brooks@FreeBSD.org) Message-Id: <201802201808.w1KI8wjA074652@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: brooks set sender to brooks@FreeBSD.org using -f From: Brooks Davis Date: Tue, 20 Feb 2018 18:08:58 +0000 (UTC) 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 X-SVN-Group: head X-SVN-Commit-Author: brooks X-SVN-Commit-Paths: in head/sys: compat/freebsd32 kern sys X-SVN-Commit-Revision: 329647 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Feb 2018 18:08:59 -0000 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);