aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/spufs/syscalls.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs/syscalls.c')
-rw-r--r--arch/powerpc/platforms/cell/spufs/syscalls.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c
new file mode 100644
index 0000000000..d549aa7ebe
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/syscalls.c
@@ -0,0 +1,101 @@
1#include <linux/file.h>
2#include <linux/fs.h>
3#include <linux/module.h>
4#include <linux/mount.h>
5#include <linux/namei.h>
6
7#include <asm/uaccess.h>
8
9#include "spufs.h"
10
11/**
12 * sys_spu_run - run code loaded into an SPU
13 *
14 * @unpc: next program counter for the SPU
15 * @ustatus: status of the SPU
16 *
17 * This system call transfers the control of execution of a
18 * user space thread to an SPU. It will return when the
19 * SPU has finished executing or when it hits an error
20 * condition and it will be interrupted if a signal needs
21 * to be delivered to a handler in user space.
22 *
23 * The next program counter is set to the passed value
24 * before the SPU starts fetching code and the user space
25 * pointer gets updated with the new value when returning
26 * from kernel space.
27 *
28 * The status value returned from spu_run reflects the
29 * value of the spu_status register after the SPU has stopped.
30 *
31 */
32long do_spu_run(struct file *filp, __u32 __user *unpc, __u32 __user *ustatus)
33{
34 long ret;
35 struct spufs_inode_info *i;
36 u32 npc, status;
37
38 ret = -EFAULT;
39 if (get_user(npc, unpc) || get_user(status, ustatus))
40 goto out;
41
42 /* check if this file was created by spu_create */
43 ret = -EINVAL;
44 if (filp->f_op != &spufs_context_fops)
45 goto out;
46
47 i = SPUFS_I(filp->f_dentry->d_inode);
48 ret = spufs_run_spu(filp, i->i_ctx, &npc, &status);
49
50 if (put_user(npc, unpc) || put_user(status, ustatus))
51 ret = -EFAULT;
52out:
53 return ret;
54}
55
56#ifndef MODULE
57asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
58{
59 int fput_needed;
60 struct file *filp;
61 long ret;
62
63 ret = -EBADF;
64 filp = fget_light(fd, &fput_needed);
65 if (filp) {
66 ret = do_spu_run(filp, unpc, ustatus);
67 fput_light(filp, fput_needed);
68 }
69
70 return ret;
71}
72#endif
73
74asmlinkage long sys_spu_create(const char __user *pathname,
75 unsigned int flags, mode_t mode)
76{
77 char *tmp;
78 int ret;
79
80 tmp = getname(pathname);
81 ret = PTR_ERR(tmp);
82 if (!IS_ERR(tmp)) {
83 struct nameidata nd;
84
85 ret = path_lookup(tmp, LOOKUP_PARENT|
86 LOOKUP_OPEN|LOOKUP_CREATE, &nd);
87 if (!ret) {
88 ret = spufs_create_thread(&nd, flags, mode);
89 path_release(&nd);
90 }
91 putname(tmp);
92 }
93
94 return ret;
95}
96
97struct spufs_calls spufs_calls = {
98 .create_thread = sys_spu_create,
99 .spu_run = do_spu_run,
100 .owner = THIS_MODULE,
101};