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.


Merge branch 'devel' of newskysaw.cs.northwestern.edu:/home/palacios/palacios into...
[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 <linux/smp_lock.h>
14 #include <asm/delay.h>
15 #include <linux/timer.h>
16
17 #include <vnet/vnet.h>
18 #include "mm.h"
19 #include "palacios-vnet.h"
20 #include "linux-exts.h"
21
22 static void host_print(const char *     fmt, ...) {
23
24     va_list ap;
25     va_start(ap, fmt);
26     vprintk(fmt, ap);
27     va_end(ap);
28
29     return;
30 }
31
32
33 static void * host_allocate_pages(int num_pages, unsigned int alignment){
34     uintptr_t addr = 0; 
35     struct page * pgs = NULL;
36     int order = get_order(num_pages * PAGE_SIZE);
37          
38     pgs = alloc_pages(GFP_KERNEL, order);
39     
40     WARN(!pgs, "Could not allocate pages\n");
41        
42     addr = page_to_pfn(pgs) << PAGE_SHIFT; 
43    
44     return (void *)addr;
45 }
46
47
48 static void host_free_pages(void * page_paddr, int num_pages) {
49     uintptr_t pg_addr = (uintptr_t)page_paddr;
50         
51     __free_pages(pfn_to_page(pg_addr >> PAGE_SHIFT), get_order(num_pages * PAGE_SIZE));
52 }
53
54
55 static void *
56 host_alloc(unsigned int size) {
57     void * addr;
58     addr =  kmalloc(size, GFP_KERNEL);
59
60     return addr;
61 }
62
63 static void
64 host_free(
65         void *                  addr
66 )
67 {
68     kfree(addr);
69     return;
70 }
71
72 static void *
73 host_vaddr_to_paddr(void * vaddr)
74 {
75     return (void*) __pa(vaddr);
76
77 }
78
79 static void *
80 host_paddr_to_vaddr(void * paddr)
81 {
82     return __va(paddr);
83 }
84
85
86 static void *
87 host_start_kernel_thread(
88         int (*fn)(void * arg),
89         void * arg,
90         char * thread_name) {
91     struct task_struct * thread = NULL;
92
93     thread = kthread_run(fn, arg, thread_name );
94
95     return thread;
96 }
97
98 static void host_kthread_sleep(long timeout){
99     set_current_state(TASK_INTERRUPTIBLE);
100
101     if(timeout <= 0){
102         schedule();
103     }else {
104        schedule_timeout(timeout);
105     }
106
107     return;
108 }
109
110 static void host_kthread_wakeup(void * thread){
111     struct task_struct * kthread = (struct task_struct *)thread;
112         
113     wake_up_process(kthread);
114 }
115
116 static void host_kthread_stop(void * thread){
117     struct task_struct * kthread = (struct task_struct *)thread;
118
119     kthread_stop(kthread);
120 }
121
122 static int host_kthread_should_stop(void){
123     return kthread_should_stop();
124 }
125
126
127 static void host_udelay(unsigned long usecs){
128     udelay(usecs);
129 }
130
131
132
133 static void
134 host_yield_cpu(void)
135 {
136     schedule();
137     return;
138 }
139
140 static void *
141 host_mutex_alloc(void)
142 {
143     spinlock_t * lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL);
144
145     if (lock) {
146         spin_lock_init(lock);
147     }
148
149     return lock;
150 }
151
152 static void
153 host_mutex_free(
154         void * mutex
155
156 {
157     kfree(mutex);
158 }
159
160 static void 
161 host_mutex_lock(void * mutex, 
162                 int must_spin)
163 {
164     spin_lock((spinlock_t *)mutex);
165 }
166
167 static void 
168 host_mutex_unlock(void * mutex) 
169 {
170     spin_unlock((spinlock_t *)mutex);
171 }
172
173
174
175
176 struct host_timer {
177     struct timer_list timer;
178     unsigned long interval;
179
180     int active;
181     void (* timer_fun)(void * private_data);
182     void * pri_data;
183 };
184
185
186 void timeout_fn(unsigned long arg){
187     struct host_timer * timer = (struct host_timer *)arg;
188
189     if(timer->active){
190         timer->timer_fun(timer->pri_data);
191         
192         mod_timer(&(timer->timer), timer->interval);
193     }
194 }
195
196 static void *
197 host_create_timer(unsigned long interval, 
198                   void (* timer_fun)(void * priv_data), 
199                   void * data){
200     struct host_timer * timer = (struct host_timer *)kmalloc(sizeof(struct host_timer), GFP_KERNEL);
201
202     timer->interval = interval;
203     timer->timer_fun = timer_fun;
204     timer->pri_data = data;
205
206     init_timer(&(timer->timer));
207
208     timer->timer.data = (unsigned long)timer;
209     timer->timer.function = timeout_fn;
210     timer->timer.expires = interval;
211
212     return timer;
213 }
214
215 static void
216 host_start_timer(void * vnet_timer){
217     struct host_timer * timer = (struct host_timer *)vnet_timer;
218
219     timer->active = 1;
220     add_timer(&(timer->timer));
221 }
222
223 static void
224 host_reset_timer(void * vnet_timer, unsigned long interval){
225     struct host_timer * timer = (struct host_timer *)timer;
226
227     timer->interval = interval;
228 }
229
230 static void
231 host_stop_timer(void * vnet_timer){
232     struct host_timer * timer = (struct host_timer *)vnet_timer;
233
234     timer->active = 0;
235     del_timer(&(timer->timer));
236 }
237
238 static void
239 host_del_timer(void * vnet_timer){
240     struct host_timer * timer = (struct host_timer *)vnet_timer;
241
242     del_timer(&(timer->timer));
243
244     kfree(timer);
245 }
246
247
248
249
250
251 static struct vnet_host_hooks vnet_host_hooks = {
252     .timer_create       = host_create_timer,
253     .timer_del          = host_del_timer,
254     .timer_start                = host_start_timer,
255     .timer_stop         = host_stop_timer,
256     .timer_reset        = host_reset_timer,
257
258     .thread_start       = host_start_kernel_thread,
259     .thread_sleep       = host_kthread_sleep,
260     .thread_wakeup      = host_kthread_wakeup,
261     .thread_stop        = host_kthread_stop,
262     .thread_should_stop = host_kthread_should_stop,
263     .udelay     = host_udelay,
264
265     .yield_cpu          = host_yield_cpu,
266     .mutex_alloc        = host_mutex_alloc,
267     .mutex_free = host_mutex_free,
268     .mutex_lock = host_mutex_lock, 
269     .mutex_unlock       = host_mutex_unlock,
270
271     .print                      = host_print,
272     .allocate_pages     = host_allocate_pages,
273     .free_pages = host_free_pages,
274     .malloc             = host_alloc,
275     .free                       = host_free,
276     .vaddr_to_paddr             = host_vaddr_to_paddr,
277     .paddr_to_vaddr             = host_paddr_to_vaddr,
278 };
279
280
281
282 static int vnet_init( void ) {
283     init_vnet(&vnet_host_hooks);
284         
285     vnet_bridge_init();
286     vnet_ctrl_init();
287
288     printk("V3 VNET Inited\n");
289         
290     return 0;
291 }
292
293
294 static int vnet_deinit( void ) {
295     deinit_vnet();
296
297     vnet_bridge_deinit();
298     vnet_ctrl_deinit();
299
300     printk("V3 VNET Deinited\n");
301
302     return 0;
303 }
304
305 static struct linux_ext vnet_ext = {
306     .name = "VNET",
307     .init = vnet_init,
308     .deinit = vnet_deinit,
309     .guest_init = NULL,
310     .guest_deinit = NULL
311 };
312
313 register_extension(&vnet_ext);