svn commit: r205321 - in head/sys: compat/freebsd32 kern sys
Konstantin Belousov
kib at FreeBSD.org
Fri Mar 19 10:56:30 UTC 2010
Author: kib
Date: Fri Mar 19 10:56:30 2010
New Revision: 205321
URL: http://svn.freebsd.org/changeset/base/205321
Log:
Introduce SYSCALL_INIT_HELPER and SYSCALL32_INIT_HELPER macros and
neccessary support functions to allow registering dynamically loaded
syscalls from the MOD_LOAD handlers. Helpers handle registration
failures semi-automatically.
Reviewed by: jhb
MFC after: 2 weeks
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 Fri Mar 19 10:52:54 2010 (r205320)
+++ head/sys/compat/freebsd32/freebsd32_misc.c Fri Mar 19 10:56:30 2010 (r205321)
@@ -3084,6 +3084,36 @@ syscall32_module_handler(struct module *
}
}
+int
+syscall32_helper_register(struct syscall_helper_data *sd)
+{
+ 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);
+ if (error != 0) {
+ syscall32_helper_unregister(sd);
+ return (error);
+ }
+ sd1->registered = 1;
+ }
+ return (0);
+}
+
+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);
+}
+
register_t *
freebsd32_copyout_strings(struct image_params *imgp)
{
Modified: head/sys/compat/freebsd32/freebsd32_util.h
==============================================================================
--- head/sys/compat/freebsd32/freebsd32_util.h Fri Mar 19 10:52:54 2010 (r205320)
+++ head/sys/compat/freebsd32/freebsd32_util.h Fri Mar 19 10:56:30 2010 (r205321)
@@ -78,10 +78,21 @@ SYSCALL32_MODULE(syscallname,
& syscallname##_syscall32, & syscallname##_sysent32,\
NULL, NULL);
+#define SYSCALL32_INIT_HELPER(syscallname) { \
+ .new_sysent = { \
+ .sy_narg = (sizeof(struct syscallname ## _args ) \
+ / sizeof(register_t)), \
+ .sy_call = (sy_call_t *)& syscallname, \
+ }, \
+ .syscall_no = FREEBSD32_SYS_##syscallname \
+}
+
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);
+int syscall32_helper_register(struct syscall_helper_data *sd);
+int syscall32_helper_unregister(struct syscall_helper_data *sd);
register_t *freebsd32_copyout_strings(struct image_params *imgp);
struct iovec32;
Modified: head/sys/kern/kern_syscalls.c
==============================================================================
--- head/sys/kern/kern_syscalls.c Fri Mar 19 10:52:54 2010 (r205320)
+++ head/sys/kern/kern_syscalls.c Fri Mar 19 10:56:30 2010 (r205321)
@@ -135,3 +135,33 @@ syscall_module_handler(struct module *mo
else
return (0);
}
+
+int
+syscall_helper_register(struct syscall_helper_data *sd)
+{
+ 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);
+ if (error != 0) {
+ syscall_helper_unregister(sd);
+ return (error);
+ }
+ sd1->registered = 1;
+ }
+ return (0);
+}
+
+int
+syscall_helper_unregister(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);
+ sd1->registered = 0;
+ }
+ return (0);
+}
Modified: head/sys/sys/sysent.h
==============================================================================
--- head/sys/sys/sysent.h Fri Mar 19 10:52:54 2010 (r205320)
+++ head/sys/sys/sysent.h Fri Mar 19 10:56:30 2010 (r205321)
@@ -166,10 +166,34 @@ SYSCALL_MODULE(syscallname, \
(sysent[SYS_##syscallname].sy_call != (sy_call_t *)lkmnosys && \
sysent[SYS_##syscallname].sy_call != (sy_call_t *)lkmressys)
+/*
+ * Syscall registration helpers with resource allocation handling.
+ */
+struct syscall_helper_data {
+ struct sysent new_sysent;
+ struct sysent old_sysent;
+ int syscall_no;
+ int registered;
+};
+#define SYSCALL_INIT_HELPER(syscallname) { \
+ .new_sysent = { \
+ .sy_narg = (sizeof(struct syscallname ## _args ) \
+ / sizeof(register_t)), \
+ .sy_call = (sy_call_t *)& syscallname, \
+ .sy_auevent = SYS_AUE_##syscallname \
+ }, \
+ .syscall_no = SYS_##syscallname \
+}
+#define SYSCALL_INIT_LAST { \
+ .syscall_no = NO_SYSCALL \
+}
+
int syscall_register(int *offset, struct sysent *new_sysent,
struct sysent *old_sysent);
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 syscall_helper_unregister(struct syscall_helper_data *sd);
/* Special purpose system call functions. */
struct nosys_args;
More information about the svn-src-head
mailing list