Sanitize vcoreid from untrusted sources
[akaros.git] / kern / src / taskqueue.c
1 /* Copyright (c) 2015 Google Inc
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Hacked BSD taskqueues.  In lieu of actually running a kproc or something that
6  * sleeps on a queue of tasks, we'll just blast out a kmsg.  We can always
7  * change the implementation if we need more control. */
8
9 #include <taskqueue.h>
10 #include <trap.h>
11 #include <kthread.h>
12
13 /* BSD Taskqueue wrappers. */
14 int taskqueue_enqueue(struct taskqueue *queue, struct task *task)
15 {
16         run_as_rkm(task->ta_func, task->ta_context, 0);
17         return 0;
18 }
19
20 /* Linux workqueue wrappers */
21 void flush_workqueue(struct workqueue_struct *wq)
22 {
23 }
24
25 void destroy_workqueue(struct workqueue_struct *wq)
26 {
27 }
28
29 struct workqueue_struct *create_singlethread_workqueue(char *name)
30 {
31         /* Non-canonical addr on AMD64.  No one should be derefing this. */
32         return (void*)0xf0f0f0f0f0f0f0f0;
33 }
34
35 static void __wq_wrapper(uint32_t srcid, long a0, long a1, long a2)
36 {
37         struct work_struct *work = (struct work_struct*)a0;
38         work->func(work);
39 }
40
41 /* Linux callers use jiffies as the unit of delay.  We pretend to be a 1000 HZ
42  * machine with 1 msec jiffies. */
43 static void __wq_wrapper_delay(uint32_t srcid, long a0, long a1, long a2)
44 {
45         struct work_struct *work = (struct work_struct*)a0;
46         unsigned long delay = (unsigned long)a1;
47
48         kthread_usleep(delay * 1000);
49         work->func(work);
50 }
51
52 static void send_work(int coreid, struct work_struct *work)
53 {
54         send_kernel_message(coreid, __wq_wrapper, (long)work, 0, 0,
55                             KMSG_ROUTINE);
56 }
57
58 static void send_work_delay(int coreid, struct delayed_work *work,
59                             unsigned long delay)
60 {
61         send_kernel_message(coreid, __wq_wrapper_delay, (long)work, (long)delay,
62                             0, KMSG_ROUTINE);
63 }
64
65 bool queue_work(struct workqueue_struct *wq, struct work_struct *work)
66 {
67         send_work(core_id(), work);
68         return TRUE;
69 }
70
71 bool schedule_work(struct work_struct *work)
72 {
73         send_work(0, work);
74         return TRUE;
75 }
76
77 bool cancel_work(struct work_struct *dwork)
78 {
79         return FALSE;
80 }
81
82 bool cancel_work_sync(struct work_struct *dwork)
83 {
84         return FALSE;
85 }
86
87 bool queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork,
88                         unsigned long delay)
89 {
90         send_work_delay(core_id(), dwork, delay);
91         return TRUE;
92 }
93
94 bool schedule_delayed_work(struct delayed_work *dwork, unsigned long delay)
95 {
96         send_work_delay(0, dwork, delay);
97         return TRUE;
98 }
99
100 bool cancel_delayed_work(struct delayed_work *dwork)
101 {
102         return FALSE;
103 }
104
105 bool cancel_delayed_work_sync(struct delayed_work *dwork)
106 {
107         return FALSE;
108 }