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.


Implementation of resource control host os interface for Linux
[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 "palacios.h"
18 #include "mm.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 *)vnet_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 static void *
143 host_allocate_pages(int num_pages, unsigned int alignment, int node_id)
144 {
145     // allocates pages preferentially on the caller's node
146     return palacios_allocate_pages(num_pages, alignment, node_id, 0, 0);
147 }
148
149
150
151 static struct vnet_host_hooks vnet_host_hooks = {
152     .timer_create               = host_create_timer,
153     .timer_del                  = host_del_timer,
154     .timer_start                = host_start_timer,
155     .timer_stop                 = host_stop_timer,
156     .timer_reset                = host_reset_timer,
157
158     .thread_start               = palacios_create_and_start_kernel_thread,
159     .thread_sleep               = host_kthread_sleep,
160     .thread_wakeup              = host_kthread_wakeup,
161     .thread_stop                = host_kthread_stop,
162     .thread_should_stop         = host_kthread_should_stop,
163     .udelay                     = host_udelay,
164
165     .yield_cpu                  = palacios_yield_cpu,
166     .mutex_alloc                = palacios_mutex_alloc,
167     .mutex_free                 = palacios_mutex_free,
168     .mutex_lock                 = palacios_mutex_lock, 
169     .mutex_unlock               = palacios_mutex_unlock,
170     .mutex_lock_irqsave         = palacios_mutex_lock_irqsave, 
171     .mutex_unlock_irqrestore    = palacios_mutex_unlock_irqrestore,
172
173     .print                      = palacios_print_scoped,
174     .allocate_pages             = host_allocate_pages,
175     .free_pages                 = palacios_free_pages,
176     .malloc                     = palacios_alloc,
177     .free                       = palacios_free,
178     .vaddr_to_paddr             = palacios_vaddr_to_paddr,
179     .paddr_to_vaddr             = palacios_paddr_to_vaddr,
180 };
181
182
183
184 static int vnet_init( void ) {
185     init_vnet(&vnet_host_hooks);
186         
187     vnet_bridge_init();
188     vnet_ctrl_init();
189
190     INFO("V3 VNET Inited\n");
191         
192     return 0;
193 }
194
195
196 static int vnet_deinit( void ) {
197
198     INFO("V3 Control Deinit Start\n");
199
200     vnet_ctrl_deinit();
201
202     INFO("V3 Bridge Deinit Start\n");
203
204     vnet_bridge_deinit();
205
206     INFO("V3 VNET Deinit Start\n");
207
208     deinit_vnet();
209
210     INFO("V3 VNET Deinited\n");
211
212     return 0;
213 }
214
215 static struct linux_ext vnet_ext = {
216     .name = "VNET",
217     .init = vnet_init,
218     .deinit = vnet_deinit,
219     .guest_init = NULL,
220     .guest_deinit = NULL
221 };
222
223 register_extension(&vnet_ext);