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.


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