Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Corrected vnet locking with irqsave/restore
[palacios.git] / linux_module / palacios-vnet.c
1 /* 
2  * Palacios VNET Host Hooks Implementations 
3  * Lei Xia 2010
4  */
5
6 #include <linux/kernel.h>
7 #include <linux/kthread.h>
8 #include <linux/spinlock.h>
9 #include <linux/gfp.h>
10 #include <linux/sched.h>
11 #include <linux/uaccess.h>
12 #include <linux/init.h>
13 #include <asm/delay.h>
14 #include <linux/timer.h>
15
16 #include <vnet/vnet.h>
17 #include "mm.h"
18 #include "palacios.h"
19 #include "palacios-vnet.h"
20 #include "linux-exts.h"
21
22
23
24
25 static void host_kthread_sleep(long timeout){
26     set_current_state(TASK_INTERRUPTIBLE);
27
28     if(timeout <= 0){
29         schedule();
30     }else {
31        schedule_timeout(timeout);
32     }
33
34     return;
35 }
36
37 static void host_kthread_wakeup(void * thread){
38     struct task_struct * kthread = (struct task_struct *)thread;
39         
40     wake_up_process(kthread);
41 }
42
43 static void host_kthread_stop(void * thread){
44     struct task_struct * kthread = (struct task_struct *)thread;
45
46     while (kthread_stop(kthread)==-EINTR)
47         ;
48 }
49
50 static int host_kthread_should_stop(void){
51     return kthread_should_stop();
52 }
53
54
55 static void host_udelay(unsigned long usecs){
56     udelay(usecs);
57 }
58
59
60
61
62
63
64
65 struct host_timer {
66     struct timer_list timer;
67     unsigned long interval;
68
69     int active;
70     void (* timer_fun)(void * private_data);
71     void * pri_data;
72 };
73
74
75 void timeout_fn(unsigned long arg){
76     struct host_timer * timer = (struct host_timer *)arg;
77
78     if(timer->active){
79         timer->timer_fun(timer->pri_data);
80         
81         mod_timer(&(timer->timer), timer->interval);
82     }
83 }
84
85 static void *
86 host_create_timer(unsigned long interval, 
87                   void (* timer_fun)(void * priv_data), 
88                   void * data){
89     struct host_timer * timer = (struct host_timer *)palacios_alloc(sizeof(struct host_timer));
90
91     if (!timer) { 
92         ERROR("Unable to allocate timer in VNET\n");
93         return NULL;
94     }
95
96     timer->interval = interval;
97     timer->timer_fun = timer_fun;
98     timer->pri_data = data;
99
100     init_timer(&(timer->timer));
101
102     timer->timer.data = (unsigned long)timer;
103     timer->timer.function = timeout_fn;
104     timer->timer.expires = interval;
105
106     return timer;
107 }
108
109 static void
110 host_start_timer(void * vnet_timer){
111     struct host_timer * timer = (struct host_timer *)vnet_timer;
112
113     timer->active = 1;
114     add_timer(&(timer->timer));
115 }
116
117 static void
118 host_reset_timer(void * vnet_timer, unsigned long interval){
119     struct host_timer * timer = (struct host_timer *)timer;
120
121     timer->interval = interval;
122 }
123
124 static void
125 host_stop_timer(void * vnet_timer){
126     struct host_timer * timer = (struct host_timer *)vnet_timer;
127
128     timer->active = 0;
129     del_timer(&(timer->timer));
130 }
131
132 static void
133 host_del_timer(void * vnet_timer){
134     struct host_timer * timer = (struct host_timer *)vnet_timer;
135
136     del_timer(&(timer->timer));
137
138     palacios_free(timer);
139 }
140
141
142
143
144
145 static struct vnet_host_hooks vnet_host_hooks = {
146     .timer_create               = host_create_timer,
147     .timer_del                  = host_del_timer,
148     .timer_start                = host_start_timer,
149     .timer_stop                 = host_stop_timer,
150     .timer_reset                = host_reset_timer,
151
152     .thread_start               = palacios_start_kernel_thread,
153     .thread_sleep               = host_kthread_sleep,
154     .thread_wakeup              = host_kthread_wakeup,
155     .thread_stop                = host_kthread_stop,
156     .thread_should_stop         = host_kthread_should_stop,
157     .udelay                     = host_udelay,
158
159     .yield_cpu                  = palacios_yield_cpu,
160     .mutex_alloc                = palacios_mutex_alloc,
161     .mutex_free                 = palacios_mutex_free,
162     .mutex_lock                 = palacios_mutex_lock, 
163     .mutex_unlock               = palacios_mutex_unlock,
164     .mutex_lock_irqsave         = palacios_mutex_lock_irqsave, 
165     .mutex_unlock_irqrestore    = palacios_mutex_unlock_irqrestore,
166
167     .print                      = palacios_print,
168     .allocate_pages             = palacios_allocate_pages,
169     .free_pages                 = palacios_free_pages,
170     .malloc                     = palacios_alloc,
171     .free                       = palacios_free,
172     .vaddr_to_paddr             = palacios_vaddr_to_paddr,
173     .paddr_to_vaddr             = palacios_paddr_to_vaddr,
174 };
175
176
177
178 static int vnet_init( void ) {
179     init_vnet(&vnet_host_hooks);
180         
181     vnet_bridge_init();
182     vnet_ctrl_init();
183
184     INFO("V3 VNET Inited\n");
185         
186     return 0;
187 }
188
189
190 static int vnet_deinit( void ) {
191
192     INFO("V3 Control Deinit Start\n");
193
194     vnet_ctrl_deinit();
195
196     INFO("V3 Bridge Deinit Start\n");
197
198     vnet_bridge_deinit();
199
200     INFO("V3 VNET Deinit Start\n");
201
202     deinit_vnet();
203
204     INFO("V3 VNET Deinited\n");
205
206     return 0;
207 }
208
209 static struct linux_ext vnet_ext = {
210     .name = "VNET",
211     .init = vnet_init,
212     .deinit = vnet_deinit,
213     .guest_init = NULL,
214     .guest_deinit = NULL
215 };
216
217 register_extension(&vnet_ext);