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.


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