Merge branch 'hotfix-0.3.5'
[archipelago] / xseg / drivers / kernel / xseg_pthread.c
1 /*
2  * Copyright (C) 2012 GRNET S.A.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19
20 /* xseg_pthread.c
21  * kernel driver for pthread peers
22  */
23
24 #include <linux/module.h>
25 #include <linux/moduleparam.h>
26 #include <linux/init.h>
27 #include <linux/sched.h>
28 #include <linux/kernel.h>
29 #include <linux/slab.h>
30 #include <linux/fs.h>
31 #include <linux/errno.h>
32 #include <linux/timer.h>
33 #include <linux/types.h>
34 #include <linux/vmalloc.h>
35 #include <linux/genhd.h>
36 #include <linux/blkdev.h>
37 #include <linux/bio.h>
38 #include <linux/device.h>
39 #include <linux/completion.h>
40
41 #include <xseg/xseg.h>
42 #include <sys/kernel/segdev.h>
43 #include <sys/util.h>
44 #include <xtypes/xpool.h>
45 #include <drivers/xseg_pthread.h>
46
47 MODULE_DESCRIPTION("xseg_pthread");
48 MODULE_AUTHOR("XSEG");
49 MODULE_LICENSE("GPL");
50
51 static int pthread_remote_signal_init(void)
52 {
53         return 0;
54 }
55
56 static void pthread_remote_signal_quit(void)
57 {
58         return;
59 }
60
61 static int pthread_local_signal_init(struct xseg *xseg, xport portno)
62 {
63         return -1;
64 }
65
66 static void pthread_local_signal_quit(struct xseg *xseg, xport portno)
67 {
68         return;
69 }
70
71 static int pthread_prepare_wait(struct xseg *xseg, uint32_t portno)
72 {
73         return -1;
74 }
75
76 static int pthread_cancel_wait(struct xseg *xseg, uint32_t portno)
77 {
78         return -1;
79 }
80
81 static int pthread_wait_signal(struct xseg *xseg, uint32_t timeout)
82 {
83         return -1;
84 }
85
86 static int pthread_signal(struct xseg *xseg, uint32_t portno)
87 {
88         struct pid *pid;
89         int i;
90         pid_t cue = 0;
91         struct task_struct *task;
92         int ret = -ENOENT;
93         struct pthread_signal_desc *psd;
94         struct xseg_port *port = xseg_get_port(xseg, portno);
95         if (!port) 
96                 return -1;
97         psd = xseg_get_signal_desc(xseg, port);
98         if (!psd)
99                 return -1;
100
101         rcu_read_lock();
102         /* XXX Security: xseg peers can kill anyone */
103
104         for (i = 0; i < MAX_WAITERS; i++) {
105                 cue = psd->pids[i];
106                 if (cue)
107                         break;
108         }
109         if (!cue){
110                 /* no waiters found */
111                 ret = 0;
112                 goto out;
113         }
114
115
116         pid = find_vpid(cue);
117         if (!pid)
118                 goto out;
119         task = pid_task(pid, PIDTYPE_PID);
120         if (!task)
121                 goto out;
122
123         ret = send_sig(SIGIO, task, 1);
124 out:
125         rcu_read_unlock();
126         return ret;
127 }
128
129 static void *pthread_malloc(uint64_t size)
130 {
131         return NULL;
132 }
133
134 static void *pthread_realloc(void *mem, uint64_t size)
135 {
136         return NULL;
137 }
138
139 static void pthread_mfree(void *mem) { }
140
141 int pthread_init_signal_desc(struct xseg *xseg, void *sd)
142 {
143         return -1;
144 }
145
146 void pthread_quit_signal_desc(struct xseg *xseg, void *sd)
147 {
148         return;
149 }
150
151 void * pthread_alloc_data(struct xseg *xseg)
152 {
153         return NULL;
154 }
155
156 void pthread_free_data(struct xseg *xseg, void *data)
157 {
158         return;
159 }
160
161 void *pthread_alloc_signal_desc(struct xseg *xseg, void *data)
162 {
163         return NULL;
164 }
165
166 void pthread_free_signal_desc(struct xseg *xseg, void *data, void *sd)
167 {
168         return;
169 }
170
171
172 static struct xseg_peer xseg_peer_pthread = {
173         /* xseg signal operations */
174         {
175                 .init_signal_desc   = pthread_init_signal_desc,
176                 .quit_signal_desc   = pthread_quit_signal_desc,
177                 .alloc_data         = pthread_alloc_data,
178                 .free_data          = pthread_free_data,
179                 .alloc_signal_desc  = pthread_alloc_signal_desc,
180                 .free_signal_desc   = pthread_free_signal_desc,
181                 .local_signal_init  = pthread_local_signal_init,
182                 .local_signal_quit  = pthread_local_signal_quit,
183                 .remote_signal_init = pthread_remote_signal_init,
184                 .remote_signal_quit = pthread_remote_signal_quit,
185                 .prepare_wait       = pthread_prepare_wait,
186                 .cancel_wait = pthread_cancel_wait,
187                 .prepare_wait = pthread_prepare_wait,
188                 .wait_signal = pthread_wait_signal,
189                 .signal = pthread_signal,
190                 .malloc = pthread_malloc,
191                 .realloc = pthread_realloc,
192                 .mfree = pthread_mfree
193         },
194         /* name */
195         "pthread"
196 };
197
198 static int pthread_init(void)
199 {
200         int r;
201
202         XSEGLOG("registering xseg types");
203
204         r = xseg_register_peer(&xseg_peer_pthread);
205
206         return r;
207 }
208
209 static int pthread_quit(void)
210 {
211         xseg_unregister_peer(xseg_peer_pthread.name);
212         return 0;
213 }
214
215 /* *************************** */
216 /* ** Module Initialization ** */
217 /* *************************** */
218
219 static int __init xseg_pthread_init(void)
220 {
221         int ret = -ENOSYS;
222
223         ret = pthread_init();
224         if (ret)
225                 goto out;
226
227         XSEGLOG("initialization complete");
228 out:
229         return ret;
230 }
231
232 static void __exit xseg_pthread_exit(void)
233 {
234         pthread_quit();
235 }
236
237 module_init(xseg_pthread_init);
238 module_exit(xseg_pthread_exit);