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.


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