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.


Updates to VNET. Most importantly, better yielding in the transmit kick threads and...
[palacios.git] / palacios / include / vnet / vnet_host.h
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2011, Lei Xia <lxia@northwestern.edu> 
11  * Copyright (c) 2011, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Lei Xia <lxia@northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #ifndef __VNET_HOST_H__
21 #define __VNET_HOST_H__
22
23 #include <vnet/vnet_base.h>
24 #include <vnet/vnet_vmm.h>
25
26 struct vnet_thread {
27     void * host_thread;
28 };
29
30 struct vnet_timer {
31     void * host_timer;
32 };
33
34 typedef unsigned long vnet_lock_t;
35
36
37
38 struct vnet_host_hooks {
39     void *(*thread_start)(int (*fn)(void * arg), 
40                           void * arg, 
41                           char * thread_name);
42
43     void (*thread_sleep)(long timeout);
44     void (*thread_wakeup)(void * thread);
45     void (*thread_stop)(void * thread);
46     int (*thread_should_stop)(void);
47
48     void *(*timer_create)(unsigned long interval, 
49                           void (* timer_fun)(void * priv_data), 
50                           void * data);
51
52     void (*timer_del)(void * timer);
53     void (*timer_start)(void * timer);
54     void (*timer_stop)(void * timer);
55     void (*timer_reset)(void * timer, unsigned long interval);
56
57     void (*udelay)(unsigned long usecs);
58
59     /* duplicate part from os_hooks */
60     void (*yield_cpu)(void); 
61     void (*print)(const char * format, ...)
62         __attribute__ ((format (printf, 1, 2)));
63   
64     void *(*allocate_pages)(int num_pages, unsigned int alignment);
65     void (*free_pages)(void * page, int num_pages);
66
67     void *(*malloc)(unsigned int size);
68     void (*free)(void * addr);
69
70     void *(*paddr_to_vaddr)(void * addr);
71     void *(*vaddr_to_paddr)(void * addr);
72
73     void *(*mutex_alloc)(void);
74     void (*mutex_free)(void * mutex);
75     void (*mutex_lock)(void * mutex, int must_spin);
76     void (*mutex_unlock)(void * mutex);
77 };
78
79
80
81 #ifdef __V3VEE__
82
83 extern struct vnet_host_hooks * host_hooks;
84
85
86 /* MEMORY ALLOCATE/DEALLOCATE */
87
88 #define PAGE_SIZE_4KB 4096
89                 
90 /* 4KB-aligned */
91 static inline void * Vnet_AllocPages(int num_pages){
92     if ((host_hooks) && host_hooks->allocate_pages) {
93         return host_hooks->allocate_pages(num_pages, PAGE_SIZE_4KB);
94     }
95
96     return NULL;
97 }
98
99 static inline void Vnet_FreePages(void * page, int num_pages){
100     if ((host_hooks) && host_hooks->free_pages) {       
101         host_hooks->free_pages(page, num_pages);
102     }
103
104
105 static inline void * Vnet_VAddr(void * addr) {
106     if ((host_hooks) && host_hooks->paddr_to_vaddr){
107         return host_hooks->paddr_to_vaddr(addr);
108     }
109
110     return NULL;
111 }
112
113 static inline void * Vnet_PAddr(void * addr) {
114     if ((host_hooks) && host_hooks->vaddr_to_paddr) {
115         return host_hooks->vaddr_to_paddr(addr);
116     }
117
118     return NULL;
119 }
120
121 static inline void * Vnet_Malloc(uint32_t size){
122     if ((host_hooks) && host_hooks->malloc) {
123         return host_hooks->malloc(size);
124     }
125
126     return NULL;
127 }
128
129 static inline void Vnet_Free(void * addr){  
130     if ((host_hooks) && host_hooks->free) {
131         host_hooks->free(addr);
132     }
133 }
134
135
136 static inline void Vnet_Yield(void){
137     if ((host_hooks) && (host_hooks)->yield_cpu) {
138         host_hooks->yield_cpu();
139     }
140 }
141
142 /* THREAD FUNCTIONS */
143 struct vnet_thread * vnet_start_thread(int (*func)(void *), void *arg, char * name);
144
145 static inline void vnet_thread_sleep(long timeout){
146     if((host_hooks) && host_hooks->thread_sleep){
147         host_hooks->thread_sleep(timeout);
148     }
149 }
150
151 static inline void vnet_thread_wakeup(struct vnet_thread * thread){
152     if((host_hooks) && host_hooks->thread_wakeup){
153         host_hooks->thread_wakeup(thread->host_thread);
154     }
155 }
156
157
158 static inline void vnet_thread_stop(struct vnet_thread * thread){
159     if((host_hooks) && host_hooks->thread_stop){
160         host_hooks->thread_stop(thread->host_thread);
161     }
162 }
163
164 static inline int vnet_thread_should_stop(void){
165     if((host_hooks) && host_hooks->thread_should_stop){
166         return host_hooks->thread_should_stop();
167     }
168
169     return 0;
170 }
171
172 static inline void  vnet_udelay(unsigned long usecs){
173     if((host_hooks) && host_hooks->udelay){
174         host_hooks->udelay(usecs);
175     }
176 }
177
178 /* TIMER FUNCTIONS */
179 /* interval, in jittes */
180 struct vnet_timer * vnet_create_timer(unsigned long interval, 
181                                       void (* timer_fun)(void * priv_data), 
182                                       void * pri_data);
183
184 static inline void vnet_del_timer(struct vnet_timer * timer){
185     if((host_hooks) && host_hooks->timer_del){
186         host_hooks->timer_del(timer->host_timer);
187         Vnet_Free(timer);
188     }
189 }
190         
191 static inline void vnet_start_timer(struct vnet_timer * timer){
192     if((host_hooks) && host_hooks->timer_start){
193         host_hooks->timer_start(timer->host_timer);
194     }
195 }
196
197 static inline void vnet_stop_timer(struct vnet_timer * timer){
198     if((host_hooks) && host_hooks->timer_stop){
199         host_hooks->timer_stop(timer->host_timer);
200     }
201 }
202
203 static inline void vnet_reset_timer(struct vnet_timer * timer, 
204                                     unsigned long new_interval){
205     if((host_hooks) && host_hooks->timer_reset){
206         host_hooks->timer_reset(timer->host_timer, new_interval);
207     }
208 }
209
210
211
212 #define Vnet_Print(level, fmt, args...)                                 \
213     do {                                                                \
214         extern int net_debug;                                           \
215         if(level <= net_debug) {                                        \
216             extern struct vnet_host_hooks * host_hooks;                 \
217             if ((host_hooks) && (host_hooks)->print) {                  \
218                 (host_hooks)->print((fmt), ##args);                     \
219             }                                                           \
220         }                                                               \
221     } while (0) 
222
223
224 #define Vnet_Debug(fmt, args...)                                        \
225     do {                                                                \
226             extern struct vnet_host_hooks * host_hooks;                 \
227             if ((host_hooks) && (host_hooks)->print) {                  \
228                 (host_hooks)->print((fmt), ##args);                     \
229             }                                                           \
230     } while (0) 
231
232
233
234
235 /* Lock Utilities */
236 static inline int vnet_lock_init(vnet_lock_t * lock) {
237     if((host_hooks) && host_hooks->mutex_alloc){
238         *lock = (addr_t)(host_hooks->mutex_alloc());
239         if (*lock) {
240             return 0;
241         }
242     }
243     return -1;
244 }
245
246 static inline void vnet_lock_deinit(vnet_lock_t * lock) {
247     if (host_hooks && (host_hooks->mutex_free)) { 
248         host_hooks->mutex_free((void *)*lock);
249         *lock = 0;
250     }
251 }
252
253 static inline void vnet_lock(vnet_lock_t lock) {
254     if (host_hooks && (host_hooks->mutex_lock)) { 
255         host_hooks->mutex_lock((void *)lock, 0);    
256     }
257 }
258
259 static inline void vnet_unlock(vnet_lock_t lock) {
260     if (host_hooks && (host_hooks->mutex_lock)) { 
261         host_hooks->mutex_unlock((void *)lock);
262     }
263 }
264
265 static inline unsigned long vnet_lock_irqsave(vnet_lock_t lock) {
266     if (host_hooks && host_hooks->mutex_lock) { 
267         host_hooks->mutex_lock((void *)lock, 1);
268         return 0;
269     } else {
270         return -1;
271     }
272 }
273
274
275 static inline void vnet_unlock_irqrestore(vnet_lock_t lock, addr_t irq_state) {
276     if (host_hooks && (host_hooks->mutex_unlock)) {
277         host_hooks->mutex_unlock((void *)lock);
278     }
279 }
280
281 #endif
282
283
284 void init_vnet(struct vnet_host_hooks * hooks);
285 void deinit_vnet(void);
286
287
288 #endif
289
290