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 non-contiguous memory region support.
[palacios.git] / palacios / include / palacios / vmm.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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.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 __VMM_H__
21 #define __VMM_H__
22
23
24
25
26 #ifdef __V3VEE__
27 #include <palacios/vmm_mem.h>
28 #include <palacios/vmm_types.h>
29 #include <palacios/vmm_string.h>
30
31
32
33
34 /* utility definitions */
35
36 #define VM_NONE ((struct v3_vm_info *)0)
37 #define VCORE_NONE ((struct guest_info *)0)
38
39 void    *v3_get_host_vm(struct v3_vm_info *);
40 int      v3_get_vcore(struct guest_info *);
41
42 #define V3_Print(vm, vcore, fmt, args...)       \
43   do {                                                          \
44     extern struct v3_os_hooks * os_hooks;                       \
45     if ((os_hooks) && (os_hooks)->print) {                      \
46       (os_hooks)->print(v3_get_host_vm(vm), v3_get_vcore(vcore), (fmt), ##args); \
47     }                                                                   \
48   } while (0)   
49
50
51 #define PrintDebug(vm, vcore, fmt, args...)   V3_Print(vm, vcore, "DEBUG: " fmt, ##args)
52
53 #define PrintError(vm, vcore, fmt, args...)  V3_Print(vm, vcore, "ERROR at %s(%d): " fmt, __FILE__, __LINE__, ##args)
54
55
56
57 /* 4KB-aligned */
58 #define V3_AllocPages(num_pages)                                        \
59     ({                                                                  \
60         extern struct v3_os_hooks * os_hooks;                           \
61         void * ptr = 0;                                                 \
62         if ((os_hooks) && (os_hooks)->allocate_pages) {                 \
63             ptr = (os_hooks)->allocate_pages(num_pages,PAGE_SIZE_4KB,-1);       \
64         }                                                               \
65         ptr;                                                            \
66     })
67
68
69 #define V3_AllocAlignedPages(num_pages, align)                          \
70     ({                                                                  \
71         extern struct v3_os_hooks * os_hooks;                           \
72         void * ptr = 0;                                                 \
73         if ((os_hooks) && (os_hooks)->allocate_pages) {                 \
74             ptr = (os_hooks)->allocate_pages(num_pages,align,-1);       \
75         }                                                               \
76         ptr;                                                            \
77     })
78
79
80 #define V3_AllocPagesNode(num_pages, node_id)                           \
81     ({                                                                  \
82         extern struct v3_os_hooks * os_hooks;                           \
83         void * ptr = 0;                                                 \
84         if ((os_hooks) && (os_hooks)->allocate_pages) {                 \
85             ptr = (os_hooks)->allocate_pages(num_pages, PAGE_SIZE_4KB, node_id); \
86         }                                                               \
87         ptr;                                                            \
88     })
89
90
91
92 #define V3_FreePages(page, num_pages)                   \
93     do {                                                \
94         extern struct v3_os_hooks * os_hooks;           \
95         if ((os_hooks) && (os_hooks)->free_pages) {     \
96             (os_hooks)->free_pages(page, num_pages);    \
97         }                                               \
98     } while(0)
99
100
101 #define V3_VAddr(addr) ({                                       \
102             extern struct v3_os_hooks * os_hooks;               \
103             void * var = 0;                                     \
104             if ((os_hooks) && (os_hooks)->paddr_to_vaddr) {     \
105                 var = (os_hooks)->paddr_to_vaddr(addr);         \
106             }                                                   \
107             var;                                                \
108         })
109
110
111 #define V3_PAddr(addr) ({                                       \
112             extern struct v3_os_hooks * os_hooks;               \
113             void * var = 0;                                     \
114             if ((os_hooks) && (os_hooks)->vaddr_to_paddr) {     \
115                 var = (os_hooks)->vaddr_to_paddr(addr);         \
116             }                                                   \
117             var;                                                \
118         })
119
120
121
122 #define V3_Malloc(size) ({                              \
123             extern struct v3_os_hooks * os_hooks;       \
124             void * var = 0;                             \
125             if ((os_hooks) && (os_hooks)->malloc) {     \
126                 var = (os_hooks)->malloc(size);         \
127             }                                           \
128             if (!var) PrintError(VM_NONE,VCORE_NONE,"MALLOC FAILURE. Memory LEAK!!\n"); \
129             var;                                        \
130         })
131
132 // We need to check the hook structure at runtime to ensure its SAFE
133 #define V3_Free(addr)                           \
134     do {                                        \
135         extern struct v3_os_hooks * os_hooks;   \
136         if ((os_hooks) && (os_hooks)->free) {   \
137             (os_hooks)->free(addr);             \
138         }                                       \
139     } while (0)
140
141 // uint_t V3_CPU_KHZ();
142 #define V3_CPU_KHZ() ({                                                 \
143             unsigned int khz = 0;                                       \
144             extern struct v3_os_hooks * os_hooks;                       \
145             if ((os_hooks) && (os_hooks)->get_cpu_khz) {                \
146                 khz = (os_hooks)->get_cpu_khz();                        \
147             }                                                           \
148             khz;                                                        \
149         })                                                              \
150         
151
152
153
154 #define V3_Hook_Interrupt(vm, irq) ({                                   \
155             int ret = 0;                                                \
156             extern struct v3_os_hooks * os_hooks;                       \
157             if ((os_hooks) && (os_hooks)->hook_interrupt) {             \
158                 ret = (os_hooks)->hook_interrupt(vm, irq);              \
159             }                                                           \
160             ret;                                                        \
161         })                                                              \
162         
163
164 #define V3_ACK_IRQ(irq)                                         \
165     do {                                                        \
166         extern struct v3_os_hooks * os_hooks;                   \
167         if ((os_hooks) && (os_hooks)->ack_irq) {                \
168             (os_hooks)->ack_irq(irq);                           \
169         }                                                       \
170     } while (0)
171
172
173
174 #define V3_Get_CPU() ({                                                 \
175             int ret = 0;                                                \
176             extern struct v3_os_hooks * os_hooks;                       \
177             if ((os_hooks) && (os_hooks)->get_cpu) {                    \
178                 ret = (os_hooks)->get_cpu();                            \
179             }                                                           \
180             ret;                                                        \
181         })
182
183
184
185
186 #define V3_CREATE_THREAD(fn, arg, name) ({                              \
187             void * thread = NULL;                                       \
188             extern struct v3_os_hooks * os_hooks;                       \
189             if ((os_hooks) && (os_hooks)->start_kernel_thread) {        \
190                 thread = (os_hooks)->start_kernel_thread(fn, arg, name); \
191             }                                                           \
192             thread;                                                     \
193         })
194
195
196
197
198 #define V3_Call_On_CPU(cpu, fn, arg)                    \
199     do {                                                \
200         extern struct v3_os_hooks * os_hooks;           \
201         if ((os_hooks) && (os_hooks)->call_on_cpu) {    \
202             (os_hooks)->call_on_cpu(cpu, fn, arg);      \
203         }                                               \
204     } while (0)
205
206
207
208 #define V3_CREATE_THREAD_ON_CPU(cpu, fn, arg, name) ({                  \
209             void * thread = NULL;                                       \
210             extern struct v3_os_hooks * os_hooks;                       \
211             if ((os_hooks) && (os_hooks)->start_thread_on_cpu) {        \
212                 thread = (os_hooks)->start_thread_on_cpu(cpu, fn, arg, name); \
213             }                                                           \
214             thread;                                                     \
215         })
216
217 #define V3_MOVE_THREAD_TO_CPU(pcpu, thread) ({                          \
218         int ret = -1;                                                   \
219         extern struct v3_os_hooks * os_hooks;                           \
220         if((os_hooks) && (os_hooks)->move_thread_to_cpu) {              \
221             ret = (os_hooks)->move_thread_to_cpu(pcpu, thread);         \
222         }                                                               \
223         ret;                                                            \
224     })
225     
226
227 /* ** */
228
229
230 #define V3_ASSERT(vm, vcore, x)                                         \
231     do {                                                                \
232         extern struct v3_os_hooks * os_hooks;                           \
233         if (!(x)) {                                                     \
234           PrintDebug(vm, vcore, "Failed assertion in %s: %s at %s, line %d, RA=%lx\n", \
235                        __func__, #x, __FILE__, __LINE__,                \
236                        (ulong_t) __builtin_return_address(0));          \
237             while(1){                                                   \
238                 if ((os_hooks) && (os_hooks)->yield_cpu) {              \
239                         (os_hooks)->yield_cpu();                        \
240                 }                                                       \
241             }                                                           \
242         }                                                               \
243     } while(0)                                                          \
244         
245
246
247 #define V3_Yield()                                      \
248     do {                                                \
249         extern struct v3_os_hooks * os_hooks;           \
250         if ((os_hooks) && (os_hooks)->yield_cpu) {      \
251             (os_hooks)->yield_cpu();                    \
252         }                                               \
253     } while (0)                                         \
254
255
256 #define V3_Sleep(usec)                          \
257     do {                                                \
258         extern struct v3_os_hooks * os_hooks;           \
259         if ((os_hooks) && (os_hooks)->sleep_cpu) {\
260             (os_hooks)->sleep_cpu(usec);                \
261         } else {                                        \
262             V3_Yield();                                 \
263         }                                               \
264     }  while (0)                                        \
265
266 #define V3_Wakeup(cpu)                                  \
267     do {                                                \
268         extern struct v3_os_hooks * os_hooks;           \
269         if ((os_hooks) && (os_hooks)->wakeup_cpu) {     \
270             (os_hooks)->wakeup_cpu(cpu);                        \
271         }                                               \
272     } while (0)                                         \
273
274
275 typedef enum v3_vm_class {V3_INVALID_VM, V3_PC_VM, V3_CRAY_VM} v3_vm_class_t;
276
277
278 // Maybe make this a define....
279 typedef enum v3_cpu_arch {V3_INVALID_CPU, V3_SVM_CPU, V3_SVM_REV3_CPU, V3_VMX_CPU, V3_VMX_EPT_CPU, V3_VMX_EPT_UG_CPU} v3_cpu_arch_t;
280
281
282 v3_cpu_mode_t v3_get_host_cpu_mode();
283
284 void v3_yield(struct guest_info * info, int usec);
285 void v3_yield_cond(struct guest_info * info, int usec);
286 void v3_print_cond(const char * fmt, ...);
287
288 void v3_interrupt_cpu(struct v3_vm_info * vm, int logical_cpu, int vector);
289
290
291
292 v3_cpu_arch_t v3_get_cpu_type(int cpu_id);
293
294
295 int v3_vm_enter(struct guest_info * info);
296 int v3_reset_vm_core(struct guest_info * core, addr_t rip);
297
298
299 #endif /*!__V3VEE__ */
300
301
302
303 struct v3_vm_info;
304
305 /* This will contain function pointers that provide OS services */
306 struct v3_os_hooks {
307   // the vm pointer is the host os's "priv_data" from v3_create_vm
308   // if vm is null, this is a general palacios printout
309   // if vm is not null, and vcore is negative, this is a general print form the vm
310   // if vm is not null, and vcore is non-negative, this is a print from a specific vcore
311     void (*print)(void *vm, int vcore, const char * format, ...)
312         __attribute__ ((format (printf, 3, 4)));
313   
314     void *(*allocate_pages)(int num_pages, unsigned int alignment, int node_id);
315     void (*free_pages)(void * page, int num_pages);
316
317     void *(*malloc)(unsigned int size);
318     void (*free)(void * addr);
319
320     void *(*paddr_to_vaddr)(void * addr);
321     void *(*vaddr_to_paddr)(void * addr);
322
323     int (*hook_interrupt)(struct v3_vm_info * vm, unsigned int irq);
324     int (*ack_irq)(int irq);
325
326     unsigned int (*get_cpu_khz)(void);
327
328     void (*yield_cpu)(void); 
329     void (*sleep_cpu)(unsigned int usec);
330     void (*wakeup_cpu)(void *cpu);
331
332     void *(*mutex_alloc)(void);
333     void (*mutex_free)(void * mutex);
334     void (*mutex_lock)(void * mutex, int must_spin);
335     void (*mutex_unlock)(void * mutex);
336     void *(*mutex_lock_irqsave)(void * mutex, int must_spin);
337     void (*mutex_unlock_irqrestore)(void * mutex, void *flags);
338
339     unsigned int (*get_cpu)(void);
340
341
342
343     void * (*start_kernel_thread)(int (*fn)(void * arg), void * arg, char * thread_name); 
344     void (*interrupt_cpu)(struct v3_vm_info * vm, int logical_cpu, int vector);
345     void (*call_on_cpu)(int logical_cpu, void (*fn)(void * arg), void * arg);
346     void * (*start_thread_on_cpu)(int cpu_id, int (*fn)(void * arg), void * arg, char * thread_name);
347     int (*move_thread_to_cpu)(int cpu_id,  void * thread);
348 };
349
350
351 /*
352  *
353  * This is the interrupt state that the VMM's interrupt handlers need to see
354  */
355 struct v3_interrupt {
356     unsigned int irq;
357     unsigned int error;
358
359     unsigned int should_ack;  /* Should the vmm ack this interrupt, or will
360                                * the host OS do it? */
361 };
362
363
364 typedef enum {V3_VM_UNKNOWN, V3_VM_INVALID, V3_VM_RUNNING, V3_VM_STOPPED, V3_VM_PAUSED, V3_VM_ERROR, V3_VM_SIMULATING} v3_vm_state_t;
365 typedef enum {V3_VCORE_UNKNOWN, V3_VCORE_INVALID, V3_VCORE_RUNNING, V3_VCORE_STOPPED} v3_vcore_state_t;
366 typedef enum {V3_VCORE_CPU_UNKNOWN, V3_VCORE_CPU_REAL, V3_VCORE_CPU_PROTECTED, V3_VCORE_CPU_PROTECTED_PAE, V3_VCORE_CPU_LONG, V3_VCORE_CPU_LONG_32_COMPAT, V3_VCORE_CPU_LONG_16_COMPAT} v3_vcore_cpu_mode_t;
367
368 typedef enum {V3_VCORE_MEM_STATE_UNKNOWN, V3_VCORE_MEM_STATE_SHADOW, V3_VCORE_MEM_STATE_NESTED} v3_vcore_mem_state_t;
369 typedef enum {V3_VCORE_MEM_MODE_UNKNOWN, V3_VCORE_MEM_MODE_PHYSICAL, V3_VCORE_MEM_MODE_VIRTUAL} v3_vcore_mem_mode_t;
370
371
372 struct v3_vm_base_state {
373     v3_vm_state_t       state;
374 };
375
376 struct v3_vm_vcore_state {
377   v3_vcore_state_t state;
378   v3_vcore_cpu_mode_t cpu_mode;
379   v3_vcore_mem_state_t mem_state;
380   v3_vcore_mem_mode_t mem_mode;
381   unsigned long pcore;
382   void *   last_rip;
383   unsigned long long num_exits;
384 };
385
386 struct v3_vm_core_state {
387     unsigned long         num_vcores;
388     struct v3_vm_vcore_state vcore[];
389 };
390
391 struct v3_vm_mem_region {
392     void               *host_paddr;
393     unsigned long long  size;
394 };
395
396 struct v3_vm_mem_state {
397     unsigned long long      mem_size;
398     unsigned long           num_regions;
399     struct v3_vm_mem_region region[]; 
400 };
401
402 char *v3_lookup_option(char *name);
403 void Init_V3(struct v3_os_hooks * hooks, char * cpus, int num_cpus, char *options);
404 void Shutdown_V3( void );
405
406
407 struct v3_vm_info * v3_create_vm(void * cfg, void * priv_data, char * name);
408 int v3_start_vm(struct v3_vm_info * vm, unsigned int cpu_mask);
409 int v3_stop_vm(struct v3_vm_info * vm);
410 int v3_pause_vm(struct v3_vm_info * vm);
411 int v3_continue_vm(struct v3_vm_info * vm);
412 int v3_simulate_vm(struct v3_vm_info * vm, unsigned int msecs);
413
414 int v3_save_vm(struct v3_vm_info * vm, char * store, char * url, unsigned long long opts);
415 int v3_load_vm(struct v3_vm_info * vm, char * store, char * url, unsigned long long opts);
416
417 int v3_send_vm(struct v3_vm_info * vm, char * store, char * url, unsigned long long opts);
418 int v3_receive_vm(struct v3_vm_info * vm, char * store, char * url, unsigned long long opts);
419
420 int v3_move_vm_core(struct v3_vm_info * vm, int vcore_id, int target_cpu);
421
422 int v3_free_vm(struct v3_vm_info * vm);
423
424 int v3_get_state_vm(struct v3_vm_info        *vm, 
425                     struct v3_vm_base_state  *base,
426                     struct v3_vm_core_state  *core,
427                     struct v3_vm_mem_state   *mem);
428
429
430 int v3_deliver_irq(struct v3_vm_info * vm, struct v3_interrupt * intr);
431
432
433 #endif