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 initial VirtIO and symbiotic swap devices
[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 #include <palacios/vm_guest.h>
25 #include <palacios/vmm_mem.h>
26 #include <palacios/vmm_types.h>
27
28
29
30 #ifdef __V3VEE__
31
32 //#include <palacios/vmm_types.h>
33 #include <palacios/vmm_string.h>
34
35
36 //#include <palacios/vmm_paging.h>
37
38 /* utility definitions */
39
40
41 #define PrintDebug(fmt, args...)                        \
42     do {                                                \
43         extern struct v3_os_hooks * os_hooks;           \
44         if ((os_hooks) && (os_hooks)->print_debug) {    \
45             (os_hooks)->print_debug((fmt), ##args);     \
46         }                                               \
47     } while (0)                                         
48
49 #if 1
50 #else
51 #define PrintDebug(fmt,args ...)
52 #endif
53
54
55
56 #define PrintError(fmt, args...)                                        \
57     do {                                                                \
58         extern struct v3_os_hooks * os_hooks;                           \
59         if ((os_hooks) && (os_hooks)->print_debug) {                    \
60             (os_hooks)->print_debug("%s(%d): " fmt, __FILE__, __LINE__, ##args); \
61         }                                                               \
62     } while (0)                                         
63
64
65
66 #ifdef VMM_INFO
67 #define PrintInfo(fmt, args...)                         \
68     do {                                                \
69         extern struct v3_os_hooks * os_hooks;           \
70         if ((os_hooks) && (os_hooks)->print_info) {     \
71             (os_hooks)->print_info((fmt), ##args);      \
72         }                                               \
73     } while (0)                                         
74 #else
75 #define PrintInfo(fmt, args...)
76 #endif
77
78
79 #ifdef VMM_TRACE
80 #define PrintTrace(fmt, args...)                        \
81     do {                                                \
82         extern struct v3_os_hooks * os_hooks;           \
83         if ((os_hooks) && (os_hooks)->print_trace) {    \
84             (os_hooks)->print_trace(fmt, ##args);       \
85         }                                               \
86     } while (0)                                         
87 #else
88 #define PrintTrace(fmt, args...)
89 #endif
90
91
92 #define V3_AllocPages(num_pages)                                \
93     ({                                                          \
94         extern struct v3_os_hooks * os_hooks;                   \
95         void * ptr = 0;                                         \
96         if ((os_hooks) && (os_hooks)->allocate_pages) {         \
97             ptr = (os_hooks)->allocate_pages(num_pages);        \
98         }                                                       \
99         ptr;                                                    \
100     })
101
102
103 #define V3_FreePage(page)                               \
104     do {                                                \
105         extern struct v3_os_hooks * os_hooks;           \
106         if ((os_hooks) && (os_hooks)->free_page) {      \
107             (os_hooks)->free_page(page);                \
108         }                                               \
109     } while(0)
110
111
112 #define V3_VAddr(addr) ({                                       \
113             extern struct v3_os_hooks * os_hooks;               \
114             void * var = 0;                                     \
115             if ((os_hooks) && (os_hooks)->paddr_to_vaddr) {     \
116                 var = (os_hooks)->paddr_to_vaddr(addr);         \
117             }                                                   \
118             var;                                                \
119         })
120
121
122 #define V3_PAddr(addr) ({                                       \
123             extern struct v3_os_hooks * os_hooks;               \
124             void * var = 0;                                     \
125             if ((os_hooks) && (os_hooks)->vaddr_to_paddr) {     \
126                 var = (os_hooks)->vaddr_to_paddr(addr);         \
127             }                                                   \
128             var;                                                \
129         })
130
131
132
133 #define V3_Malloc(size) ({                              \
134             extern struct v3_os_hooks * os_hooks;       \
135             void * var = 0;                             \
136             if ((os_hooks) && (os_hooks)->malloc) {     \
137                 var = (os_hooks)->malloc(size);         \
138             }                                           \
139             var;                                        \
140         })
141
142 // We need to check the hook structure at runtime to ensure its SAFE
143 #define V3_Free(addr)                           \
144     do {                                        \
145         extern struct v3_os_hooks * os_hooks;   \
146         if ((os_hooks) && (os_hooks)->free) {   \
147             (os_hooks)->free(addr);             \
148         }                                       \
149     } while (0)
150
151 // uint_t V3_CPU_KHZ();
152 #define V3_CPU_KHZ() ({                                                 \
153             unsigned int khz = 0;                                       \
154             extern struct v3_os_hooks * os_hooks;                       \
155             if ((os_hooks) && (os_hooks)->get_cpu_khz) {                \
156                 khz = (os_hooks)->get_cpu_khz();                        \
157             }                                                           \
158             khz;                                                        \
159         })                                                              \
160         
161
162
163 #define V3_CREATE_THREAD(fn, arg, name)                         \
164     do {                                                        \
165         extern struct v3_os_hooks * os_hooks;                   \
166         if ((os_hooks) && (os_hooks)->start_kernel_thread) {    \
167             (os_hooks)->start_kernel_thread(fn, arg, name);     \
168         }                                                       \
169     } while (0)
170
171
172 #define V3_Hook_Interrupt(irq, opaque) ({                               \
173             int ret = 0;                                                \
174             extern struct v3_os_hooks * os_hooks;                       \
175             if ((os_hooks) && (os_hooks)->hook_interrupt) {             \
176                 ret = (os_hooks)->hook_interrupt(irq, opaque);          \
177             }                                                           \
178             ret;                                                        \
179         })                                                              \
180         
181
182 #define V3_ACK_IRQ(irq)                                         \
183     do {                                                        \
184         extern struct v3_os_hooks * os_hooks;                   \
185         if ((os_hooks) && (os_hooks)->ack_irq) {                \
186             (os_hooks)->ack_irq(irq);                           \
187         }                                                       \
188     } while (0)
189
190
191 #define V3_Yield(addr)                                  \
192     do {                                                \
193         extern struct v3_os_hooks * os_hooks;           \
194         if ((os_hooks) && (os_hooks)->yield_cpu) {      \
195             (os_hooks)->yield_cpu();                    \
196         }                                               \
197     } while (0)                                         \
198                                                         \
199                                                         \
200                                                         \
201                                                         \
202                                                         \
203 /* ** */
204
205 #define V3_ASSERT(x)                                                    \
206     do {                                                                \
207         if (!(x)) {                                                     \
208             PrintDebug("Failed assertion in %s: %s at %s, line %d, RA=%lx\n", \
209                        __func__, #x, __FILE__, __LINE__,                \
210                        (ulong_t) __builtin_return_address(0));          \
211             while(1);                                                   \
212         }                                                               \
213     } while(0)                                                          \
214         
215
216
217
218 #define VMM_INVALID_CPU 0
219 #define VMM_VMX_CPU 1
220 #define VMM_SVM_CPU 2
221
222
223 // Maybe make this a define....
224 typedef enum v3_cpu_arch {V3_INVALID_CPU, V3_SVM_CPU, V3_SVM_REV3_CPU, V3_VMX_CPU, V3_VMX_EPT_CPU} v3_cpu_arch_t;
225
226
227 v3_cpu_mode_t v3_get_host_cpu_mode();
228
229
230 #endif //!__V3VEE__
231
232
233
234 struct guest_info;
235
236 /* This will contain function pointers that provide OS services */
237 struct v3_os_hooks {
238     void (*print_info)(const char * format, ...)
239         __attribute__ ((format (printf, 1, 2)));
240     void (*print_debug)(const char * format, ...)
241         __attribute__ ((format (printf, 1, 2)));
242     void (*print_trace)(const char * format, ...)
243         __attribute__ ((format (printf, 1, 2)));
244   
245     void *(*allocate_pages)(int numPages);
246     void (*free_page)(void * page);
247
248     void *(*malloc)(unsigned int size);
249     void (*free)(void * addr);
250
251     void *(*paddr_to_vaddr)(void *addr);
252     void *(*vaddr_to_paddr)(void *addr);
253
254     int (*hook_interrupt)(struct guest_info * vm, unsigned int irq);
255
256     int (*ack_irq)(int irq);
257
258     unsigned int (*get_cpu_khz)(void);
259
260     void (*start_kernel_thread)(int (*fn)(void * arg), void * arg, char * thread_name); 
261
262     void (*yield_cpu)(void); 
263
264     void *(*mutex_alloc)(void);
265     void (*mutex_free)(void * mutex);
266     void (*mutex_lock)(void * mutex, int must_spin);
267     void (*mutex_unlock)(void * mutex);
268 };
269
270
271
272 typedef enum {NONE, HARDDRIVE, CDROM, VIRTIO} v3_disk_type_t;
273 typedef enum {RAM, NETWORK} v3_disk_connection_t;
274
275 union v3_disk_info {
276     struct {
277         void * data_ptr;
278         int size;
279     } ram;
280
281     struct {
282         char * ip_str;
283         int port;
284         char * disk_name;
285     } net;
286 };
287
288 struct v3_vm_config {
289     void * rombios;
290     int rombios_size;
291
292     void * vgabios;
293     int vgabios_size;
294
295     unsigned long mem_size; // in bytes, var should be natural size of cpu
296     // so we can specify maximum physical address size
297     // (We're screwed if we want to do 32 bit host/64 bit guest)
298
299     int enable_profiling;
300     int enable_nested_paging;
301
302     int enable_pci;
303
304     int enable_swap;
305
306     v3_disk_type_t pri_disk_type;
307     v3_disk_connection_t pri_disk_con;
308     union v3_disk_info pri_disk_info;
309    
310     v3_disk_type_t sec_disk_type;
311     v3_disk_connection_t sec_disk_con;
312     union v3_disk_info sec_disk_info;
313 };
314
315
316
317 /* This will contain Function pointers that control the VMs */
318 struct v3_ctrl_ops {
319     struct guest_info *(*allocate_guest)(void);
320
321     int (*init_guest)(struct guest_info * info, struct v3_vm_config * config_ptr);
322     int (*start_guest)(struct guest_info * info);
323     //  int (*stop_vm)(uint_t vm_id);
324
325     int (*has_nested_paging)(void);
326
327     //  v3_cpu_arch_t (*get_cpu_arch)();
328 };
329
330
331
332
333 //
334 //
335 // This is the interrupt state that the VMM's interrupt handlers need to see
336 //
337 struct v3_interrupt {
338     unsigned int irq;
339     unsigned int error;
340
341     unsigned int should_ack;  // Should the vmm ack this interrupt, or will
342     // the host OS do it?
343 };
344
345
346
347
348 void Init_V3(struct v3_os_hooks * hooks, struct v3_ctrl_ops * vmm_ops);
349
350 int v3_deliver_irq(struct guest_info * vm, struct v3_interrupt * intr);
351
352
353
354 #endif