fix xsegbd to work with the new scheme. needs further testing
[archipelago] / xseg / drivers / kernel / xseg_pthread.c
1 /* xseg_pthread.c
2  * kernel driver for pthread peers
3  */
4
5 #include <linux/module.h>
6 #include <linux/moduleparam.h>
7 #include <linux/init.h>
8 #include <linux/sched.h>
9 #include <linux/kernel.h>
10 #include <linux/slab.h>
11 #include <linux/fs.h>
12 #include <linux/errno.h>
13 #include <linux/timer.h>
14 #include <linux/types.h>
15 #include <linux/vmalloc.h>
16 #include <linux/genhd.h>
17 #include <linux/blkdev.h>
18 #include <linux/bio.h>
19 #include <linux/device.h>
20 #include <linux/completion.h>
21
22 #include <xseg/xseg.h>
23 #include <sys/kernel/segdev.h>
24 #include <sys/util.h>
25 #include <xtypes/xpool.h>
26
27 MODULE_DESCRIPTION("xseg_pthread");
28 MODULE_AUTHOR("XSEG");
29 MODULE_LICENSE("GPL");
30
31 static int pthread_signal_init(void)
32 {
33         return 0;
34 }
35
36 static void pthread_signal_quit(void)
37 {
38         return;
39 }
40
41 static int pthread_prepare_wait(struct xseg *xseg, uint32_t portno)
42 {
43         return -1;
44 }
45
46 static int pthread_cancel_wait(struct xseg *xseg, uint32_t portno)
47 {
48         return -1;
49 }
50
51 static int pthread_wait_signal(struct xseg *xseg, uint32_t timeout)
52 {
53         return -1;
54 }
55
56 static int pthread_signal(struct xseg *xseg, uint32_t portno)
57 {
58         struct pid *pid;
59         struct task_struct *task;
60         int ret = -ENOENT;
61         xpool_data data;
62         xpool_index idx;
63         struct xseg_port *port = xseg_get_port(xseg, portno);
64         if (!port) 
65                 return -1;
66
67         rcu_read_lock();
68         /* XXX Security: xseg peers can kill anyone */
69         idx = xpool_peek(&port->waiters, &data, portno); //FIXME portno is not the caller but the callee
70         if (idx == NoIndex)
71                 /* no waiters */
72                 goto out;
73
74         pid = find_vpid((pid_t) data);
75         if (!pid)
76                 goto out;
77         task = pid_task(pid, PIDTYPE_PID);
78         if (!task)
79                 goto out;
80
81         ret = send_sig(SIGIO, task, 1);
82 out:
83         rcu_read_unlock();
84         return ret;
85 }
86
87 static void *pthread_malloc(uint64_t size)
88 {
89         return NULL;
90 }
91
92 static void *pthread_realloc(void *mem, uint64_t size)
93 {
94         return NULL;
95 }
96
97 static void pthread_mfree(void *mem) { }
98
99 static struct xseg_peer xseg_peer_pthread = {
100         /* xseg signal operations */
101         {
102                 .signal_init = pthread_signal_init,
103                 .signal_quit = pthread_signal_quit,
104                 .cancel_wait = pthread_cancel_wait,
105                 .prepare_wait = pthread_prepare_wait,
106                 .wait_signal = pthread_wait_signal,
107                 .signal = pthread_signal,
108                 .malloc = pthread_malloc,
109                 .realloc = pthread_realloc,
110                 .mfree = pthread_mfree
111         },
112         /* name */
113         "pthread"
114 };
115
116 static int pthread_init(void)
117 {
118         int r;
119
120         XSEGLOG("registering xseg types");
121
122         r = xseg_register_peer(&xseg_peer_pthread);
123
124         return r;
125 }
126
127 static int pthread_quit(void)
128 {
129         xseg_unregister_peer(xseg_peer_pthread.name);
130         return 0;
131 }
132
133 /* *************************** */
134 /* ** Module Initialization ** */
135 /* *************************** */
136
137 static int __init xseg_pthread_init(void)
138 {
139         int ret = -ENOSYS;
140
141         ret = pthread_init();
142         if (ret)
143                 goto out;
144
145         XSEGLOG("initialization complete");
146 out:
147         return ret;
148 }
149
150 static void __exit xseg_pthread_exit(void)
151 {
152         pthread_quit();
153 }
154
155 module_init(xseg_pthread_init);
156 module_exit(xseg_pthread_exit);