svn commit: r206347 - in stable/8/sys: compat/freebsd32 kern sys

Konstantin Belousov kib at FreeBSD.org
Wed Apr 7 14:28:48 UTC 2010


Author: kib
Date: Wed Apr  7 14:28:47 2010
New Revision: 206347
URL: http://svn.freebsd.org/changeset/base/206347

Log:
  MFC r205321:
  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.

Modified:
  stable/8/sys/compat/freebsd32/freebsd32_misc.c
  stable/8/sys/compat/freebsd32/freebsd32_util.h
  stable/8/sys/kern/kern_syscalls.c
  stable/8/sys/sys/sysent.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/compat/freebsd32/freebsd32_misc.c
==============================================================================
--- stable/8/sys/compat/freebsd32/freebsd32_misc.c	Wed Apr  7 14:22:38 2010	(r206346)
+++ stable/8/sys/compat/freebsd32/freebsd32_misc.c	Wed Apr  7 14:28:47 2010	(r206347)
@@ -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: stable/8/sys/compat/freebsd32/freebsd32_util.h
==============================================================================
--- stable/8/sys/compat/freebsd32/freebsd32_util.h	Wed Apr  7 14:22:38 2010	(r206346)
+++ stable/8/sys/compat/freebsd32/freebsd32_util.h	Wed Apr  7 14:28:47 2010	(r206347)
@@ -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: stable/8/sys/kern/kern_syscalls.c
==============================================================================
--- stable/8/sys/kern/kern_syscalls.c	Wed Apr  7 14:22:38 2010	(r206346)
+++ stable/8/sys/kern/kern_syscalls.c	Wed Apr  7 14:28:47 2010	(r206347)
@@ -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: stable/8/sys/sys/sysent.h
==============================================================================
--- stable/8/sys/sys/sysent.h	Wed Apr  7 14:22:38 2010	(r206346)
+++ stable/8/sys/sys/sysent.h	Wed Apr  7 14:28:47 2010	(r206347)
@@ -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-all mailing list