From owner-svn-src-all@FreeBSD.ORG Wed Jan 21 16:14:44 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 699B4106566C; Wed, 21 Jan 2009 16:14:44 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 55B8E8FC18; Wed, 21 Jan 2009 16:14:44 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n0LGEiP6082750; Wed, 21 Jan 2009 16:14:44 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n0LGEiFM082747; Wed, 21 Jan 2009 16:14:44 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <200901211614.n0LGEiFM082747@svn.freebsd.org> From: John Baldwin Date: Wed, 21 Jan 2009 16:14:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r187535 - in stable/7/sys: . compat/freebsd32 compat/ia32 contrib/pf dev/ath/ath_hal dev/cxgb X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 Jan 2009 16:14:45 -0000 Author: jhb Date: Wed Jan 21 16:14:43 2009 New Revision: 187535 URL: http://svn.freebsd.org/changeset/base/187535 Log: MFC: Add support for installing 32-bit system calls from kernel modules. Modified: stable/7/sys/ (props changed) stable/7/sys/compat/freebsd32/freebsd32_misc.c stable/7/sys/compat/freebsd32/freebsd32_util.h stable/7/sys/compat/ia32/ia32_sysvec.c stable/7/sys/contrib/pf/ (props changed) stable/7/sys/dev/ath/ath_hal/ (props changed) stable/7/sys/dev/cxgb/ (props changed) Modified: stable/7/sys/compat/freebsd32/freebsd32_misc.c ============================================================================== --- stable/7/sys/compat/freebsd32/freebsd32_misc.c Wed Jan 21 15:51:15 2009 (r187534) +++ stable/7/sys/compat/freebsd32/freebsd32_misc.c Wed Jan 21 16:14:43 2009 (r187535) @@ -2589,3 +2589,83 @@ freebsd32_xxx(struct thread *td, struct return (error); } #endif + +int +syscall32_register(int *offset, struct sysent *new_sysent, + struct sysent *old_sysent) +{ + 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; + return 0; +} + +int +syscall32_deregister(int *offset, struct sysent *old_sysent) +{ + + if (*offset) + 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); + 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); + } +} Modified: stable/7/sys/compat/freebsd32/freebsd32_util.h ============================================================================== --- stable/7/sys/compat/freebsd32/freebsd32_util.h Wed Jan 21 15:51:15 2009 (r187534) +++ stable/7/sys/compat/freebsd32/freebsd32_util.h Wed Jan 21 16:14:43 2009 (r187535) @@ -28,14 +28,16 @@ * $FreeBSD$ */ -#include -#include -#include - +#ifndef _COMPAT_FREEBSD32_FREEBSD32_UTIL_H_ +#define _COMPAT_FREEBSD32_FREEBSD32_UTIL_H_ +#include #include #include -#include + +#include +#include +#include struct freebsd32_ps_strings { u_int32_t ps_argvstr; /* first of 0 or more argument strings */ @@ -50,3 +52,35 @@ struct freebsd32_ps_strings { #define FREEBSD32_PS_STRINGS \ (FREEBSD32_USRSTACK - sizeof(struct freebsd32_ps_strings)) + +extern struct sysent freebsd32_sysent[]; + +#define SYSCALL32_MODULE(name, offset, new_sysent, evh, arg) \ +static struct syscall_module_data name##_syscall32_mod = { \ + evh, arg, offset, new_sysent, { 0, NULL } \ +}; \ + \ +static moduledata_t name##32_mod = { \ + #name, \ + syscall32_module_handler, \ + &name##_syscall32_mod \ +}; \ +DECLARE_MODULE(name##32, name##32_mod, SI_SUB_SYSCALLS, SI_ORDER_MIDDLE) + +#define SYSCALL32_MODULE_HELPER(syscallname) \ +static int syscallname##_syscall32 = FREEBSD32_SYS_##syscallname; \ +static struct sysent syscallname##_sysent32 = { \ + (sizeof(struct syscallname ## _args ) \ + / sizeof(register_t)), \ + (sy_call_t *)& syscallname \ +}; \ +SYSCALL32_MODULE(syscallname, \ + & syscallname##_syscall32, & syscallname##_sysent32,\ + NULL, NULL); + +int syscall32_register(int *offset, struct sysent *new_sysent, + struct sysent *old_sysent); +int syscall32_deregister(int *offset, struct sysent *old_sysent); +int syscall32_module_handler(struct module *mod, int what, void *arg); + +#endif /* !_COMPAT_FREEBSD32_FREEBSD32_UTIL_H_ */ Modified: stable/7/sys/compat/ia32/ia32_sysvec.c ============================================================================== --- stable/7/sys/compat/ia32/ia32_sysvec.c Wed Jan 21 15:51:15 2009 (r187534) +++ stable/7/sys/compat/ia32/ia32_sysvec.c Wed Jan 21 16:14:43 2009 (r187535) @@ -96,8 +96,6 @@ CTASSERT(sizeof(struct ia32_sigframe4) = static register_t *ia32_copyout_strings(struct image_params *imgp); static void ia32_fixlimit(struct rlimit *rl, int which); -extern struct sysent freebsd32_sysent[]; - SYSCTL_NODE(_compat, OID_AUTO, ia32, CTLFLAG_RW, 0, "ia32 mode"); static u_long ia32_maxdsiz = IA32_MAXDSIZ;