[patch 3/6] sys_indirect RFC - sys_indirect core

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is the core skeleton for the new sys_indirect() system call.



Signed-off-by: Davide Libenzi <[email protected]>


- Davide



---
 include/linux/indirect.h |   32 +++++++++++++
 include/linux/syscalls.h |    5 ++
 kernel/Makefile          |    2 
 kernel/sys_indirect.c    |  109 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 147 insertions(+), 1 deletion(-)

Index: linux-2.6.mod/include/linux/syscalls.h
===================================================================
--- linux-2.6.mod.orig/include/linux/syscalls.h	2007-06-29 12:12:41.000000000 -0700
+++ linux-2.6.mod/include/linux/syscalls.h	2007-06-29 12:12:51.000000000 -0700
@@ -65,6 +65,7 @@
 #include <asm/signal.h>
 #include <linux/quota.h>
 #include <linux/key.h>
+#include <linux/indirect.h>
 
 asmlinkage long sys_time(time_t __user *tloc);
 asmlinkage long sys_stime(time_t __user *tptr);
@@ -608,6 +609,10 @@
 asmlinkage long sys_timerfd(int ufd, int clockid, int flags,
 			    const struct itimerspec __user *utmr);
 asmlinkage long sys_eventfd(unsigned int count);
+asmlinkage long sys_indirect(unsigned int nr,
+			     const struct indirect_ctx __user * __user *ctxs,
+			     unsigned int nctxs,
+			     const unsigned long __user *params);
 
 int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
 
Index: linux-2.6.mod/kernel/Makefile
===================================================================
--- linux-2.6.mod.orig/kernel/Makefile	2007-06-29 12:12:41.000000000 -0700
+++ linux-2.6.mod/kernel/Makefile	2007-06-29 12:12:51.000000000 -0700
@@ -5,7 +5,7 @@
 obj-y     = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
 	    exit.o itimer.o time.o softirq.o resource.o \
 	    sysctl.o capability.o ptrace.o timer.o user.o \
-	    signal.o sys.o kmod.o workqueue.o pid.o \
+	    signal.o sys.o sys_indirect.o kmod.o workqueue.o pid.o \
 	    rcupdate.o extable.o params.o posix-timers.o \
 	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
 	    hrtimer.o rwsem.o latency.o nsproxy.o srcu.o die_notifier.o
Index: linux-2.6.mod/kernel/sys_indirect.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.mod/kernel/sys_indirect.c	2007-06-29 12:57:56.000000000 -0700
@@ -0,0 +1,109 @@
+/*
+ *  kernel/sys_indirect.c
+ *
+ *  Copyright (C) 2007  Davide Libenzi <[email protected]>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/fs.h>
+#include <linux/resource.h>
+#include <linux/kernel.h>
+#include <linux/syscalls.h>
+#include <linux/fsalloc.h>
+#include <linux/indirect.h>
+
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+
+struct indirect_procs {
+	int (*set)(struct fsa_context *, const struct indirect_ctx __user *,
+		   struct indirect_op **);
+	void (*unset)(struct indirect_op *);
+};
+
+static const struct indirect_procs inprocs[] =
+{
+	{ NULL, NULL },
+};
+
+/**
+ * indirect_set_context - Walks through the user-specified context-set operations
+ *                        and sets the new task context according to it
+ *
+ * @ator:   [in]  Pointer the the allocator to be used to allocate context
+ *                operation nodes
+ * @ctxs:   [in]  Pointer to context data to be set before the syscall
+ * @nctxs:  [in]  Number of valid contexts in @ictxs and @ctxs
+ * @first:  [out] Pointer to the head of the operation chain
+ *
+ * Returns zero in case of success, or a negative error code in case of error.
+ */
+int indirect_set_context(struct fsa_context *ator,
+			 const struct indirect_ctx __user * __user *ctxs,
+			 unsigned int nctxs, struct indirect_op **first)
+{
+	unsigned int i;
+	int error;
+	u32 ctx;
+	const struct indirect_ctx __user *pctx;
+	struct indirect_op *new;
+
+	*first = NULL;
+	for (i = 0; i < nctxs; i++) {
+		if (get_user(pctx, &ctxs[i]) || get_user(ctx, &pctx->ctx))
+			return -EFAULT;
+		if (unlikely(ctx >= ARRAY_SIZE(inprocs) || !inprocs[ctx].set))
+			return -EINVAL;
+		error = (*inprocs[ctx].set)(ator, pctx, &new);
+		if (unlikely(error))
+			return error;
+		new->next = *first;
+		*first = new;
+	}
+
+	return 0;
+}
+
+/**
+ * indirect_unset_context - Undo the chain of task context set operations
+ *                          done by a previous call to indirect_set_context()
+ *
+ * @curr:  [in] Pointer to the head of the operations chain
+ *
+ */
+void indirect_unset_context(struct indirect_op *curr)
+{
+	for (; curr; curr = curr->next)
+		if (likely(inprocs[curr->ctx].unset))
+			(*inprocs[curr->ctx].unset)(curr);
+}
+
+asmlinkage long sys_indirect(unsigned int nr,
+			     const struct indirect_ctx __user * __user *ctxs,
+			     unsigned int nctxs,
+			     const unsigned long __user *params)
+{
+	long res;
+	struct indirect_op *iops = NULL;
+	unsigned long kparams[6];
+	struct fsa_context ator;
+	char ator_cache[128];
+
+	if (!indirect_call_ok(nr))
+		return -EINVAL;
+	if (copy_from_user(kparams, params, 6 * sizeof(unsigned long)))
+		return -EFAULT;
+	fsa_init(&ator, ator_cache, sizeof(ator_cache));
+	res = indirect_set_context(&ator, ctxs, nctxs, &iops);
+	if (likely(res == 0)) {
+		res = call_syscall(nr, kparams);
+		indirect_unset_context(iops);
+	}
+	fsa_cleanup(&ator);
+
+	return res;
+}
+
Index: linux-2.6.mod/include/linux/indirect.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.mod/include/linux/indirect.h	2007-06-29 12:57:56.000000000 -0700
@@ -0,0 +1,32 @@
+/*
+ *  include/linux/indirect.h
+ *
+ *  Copyright (C) 2007  Davide Libenzi <[email protected]>
+ *
+ */
+
+#ifndef _LINUX_INDIRECT_H
+#define _LINUX_INDIRECT_H
+
+struct indirect_ctx {
+	__u32 ctx;
+};
+
+#ifdef __KERNEL__
+
+#include <linux/fsalloc.h>
+
+struct indirect_op {
+	struct indirect_op *next;
+	unsigned int ctx;
+};
+
+int indirect_set_context(struct fsa_context *ator,
+			 const struct indirect_ctx __user * __user *ctxs,
+			 unsigned int nctxs, struct indirect_op **first);
+void indirect_unset_context(struct indirect_op *curr);
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_INDIRECT_H */
+

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux