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.


Context-based output infrastructure (V3_Print, etc) and modifications to use it
[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 static struct vnet_host_hooks vnet_host_hooks = {
144     .timer_create               = host_create_timer,
145     .timer_del                  = host_del_timer,
146     .timer_start                = host_start_timer,
147     .timer_stop                 = host_stop_timer,
148     .timer_reset                = host_reset_timer,
149
150     .thread_start               = palacios_start_kernel_thread,
151     .thread_sleep               = host_kthread_sleep,
152     .thread_wakeup              = host_kthread_wakeup,
153     .thread_stop                = host_kthread_stop,
154     .thread_should_stop         = host_kthread_should_stop,
155     .udelay                     = host_udelay,
156
157     .yield_cpu                  = palacios_yield_cpu,
158     .mutex_alloc                = palacios_mutex_alloc,
159     .mutex_free                 = palacios_mutex_free,
160     .mutex_lock                 = palacios_mutex_lock, 
161     .mutex_unlock               = palacios_mutex_unlock,
162     .mutex_lock_irqsave         = palacios_mutex_lock_irqsave, 
163     .mutex_unlock_irqrestore    = palacios_mutex_unlock_irqrestore,
164
165     .print                      = palacios_print_scoped,
166     .allocate_pages             = palacios_allocate_pages,
167     .free_pages                 = palacios_free_pages,
168     .malloc                     = palacios_alloc,
169     .free                       = palacios_free,
170     .vaddr_to_paddr             = palacios_vaddr_to_paddr,
171     .paddr_to_vaddr             = palacios_paddr_to_vaddr,
172 };
173
174
175
176 static int vnet_init( void ) {
177     init_vnet(&vnet_host_hooks);
178         
179     vnet_bridge_init();
180     vnet_ctrl_init();
181
182     INFO("V3 VNET Inited\n");
183         
184     return 0;
185 }
186
187
188 static int vnet_deinit( void ) {
189
190     INFO("V3 Control Deinit Start\n");
191
192     vnet_ctrl_deinit();
193
194     INFO("V3 Bridge Deinit Start\n");
195
196     vnet_bridge_deinit();
197
198     INFO("V3 VNET Deinit Start\n");
199
200     deinit_vnet();
201
202     INFO("V3 VNET Deinited\n");
203
204     return 0;
205 }
206
207 static struct linux_ext vnet_ext = {
208     .name = "VNET",
209     .init = vnet_init,
210     .deinit = vnet_deinit,
211     .guest_init = NULL,
212     .guest_deinit = NULL
213 };
214
215 register_extension(&vnet_ext);