[patch 3/6] sys_indirect RFC - sys_indirect core

From: Davide Libenzi
Date: Fri Jun 29 2007 - 17:50:52 EST


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



Signed-off-by: Davide Libenzi <davidel@xxxxxxxxxxxxxxx>


- 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 <davidel@xxxxxxxxxxxxxxx>
+ *
+ */
+
+#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 <davidel@xxxxxxxxxxxxxxx>
+ *
+ */
+
+#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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/