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.


deinitialization of interrupt state
[palacios.git] / palacios / src / palacios / vm_guest.c
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
21
22
23 #include <palacios/vm_guest.h>
24 #include <palacios/vmm_ctrl_regs.h>
25 #include <palacios/vmm.h>
26 #include <palacios/vmm_decoder.h>
27 #include <palacios/vmcb.h>
28 #include <palacios/vm_guest_mem.h>
29 #include <palacios/vmm_lowlevel.h>
30 #include <palacios/vmm_sprintf.h>
31 #include <palacios/vmm_muxer.h>
32 #include <palacios/vmm_xed.h>
33
34
35 v3_cpu_mode_t v3_get_vm_cpu_mode(struct guest_info * info) {
36     struct cr0_32 * cr0;
37     struct efer_64 * efer;
38     struct cr4_32 * cr4 = (struct cr4_32 *)&(info->ctrl_regs.cr4);
39     struct v3_segment * cs = &(info->segments.cs);
40     vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
41
42     if (info->shdw_pg_mode == SHADOW_PAGING) {
43         cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
44         efer = (struct efer_64 *)&(info->shdw_pg_state.guest_efer);
45     } else if (info->shdw_pg_mode == NESTED_PAGING) {
46         cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
47         efer = (struct efer_64 *)&(guest_state->efer);
48     } else {
49         PrintError("Invalid Paging Mode...\n");
50         V3_ASSERT(0);
51         return -1;
52     }
53
54     if (cr0->pe == 0) {
55         return REAL;
56     } else if ((cr4->pae == 0) && (efer->lme == 0)) {
57         return PROTECTED;
58     } else if (efer->lme == 0) {
59         return PROTECTED_PAE;
60     } else if ((efer->lme == 1) && (cs->long_mode == 1)) {
61         return LONG;
62     } else {
63         // What about LONG_16_COMPAT???
64         return LONG_32_COMPAT;
65     }
66 }
67
68 // Get address width in bytes
69 uint_t v3_get_addr_width(struct guest_info * info) {
70     struct cr0_32 * cr0;
71     struct cr4_32 * cr4 = (struct cr4_32 *)&(info->ctrl_regs.cr4);
72     struct efer_64 * efer;
73     struct v3_segment * cs = &(info->segments.cs);
74     vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
75
76     if (info->shdw_pg_mode == SHADOW_PAGING) {
77         cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
78         efer = (struct efer_64 *)&(info->shdw_pg_state.guest_efer);
79     } else if (info->shdw_pg_mode == NESTED_PAGING) {
80         cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
81         efer = (struct efer_64 *)&(guest_state->efer);
82     } else {
83         PrintError("Invalid Paging Mode...\n");
84         V3_ASSERT(0);
85         return -1;
86     }
87
88     if (cr0->pe == 0) {
89         return 2;
90     } else if ((cr4->pae == 0) && (efer->lme == 0)) {
91         return 4;
92     } else if (efer->lme == 0) {
93         return 4;
94     } else if ((efer->lme == 1) && (cs->long_mode == 1)) {
95         return 8;
96     } else {
97         // What about LONG_16_COMPAT???
98         return 4;
99     }
100 }
101
102
103 static const uchar_t REAL_STR[] = "Real";
104 static const uchar_t PROTECTED_STR[] = "Protected";
105 static const uchar_t PROTECTED_PAE_STR[] = "Protected+PAE";
106 static const uchar_t LONG_STR[] = "Long";
107 static const uchar_t LONG_32_COMPAT_STR[] = "32bit Compat";
108 static const uchar_t LONG_16_COMPAT_STR[] = "16bit Compat";
109
110 const uchar_t * v3_cpu_mode_to_str(v3_cpu_mode_t mode) {
111     switch (mode) {
112         case REAL:
113             return REAL_STR;
114         case PROTECTED:
115             return PROTECTED_STR;
116         case PROTECTED_PAE:
117             return PROTECTED_PAE_STR;
118         case LONG:
119             return LONG_STR;
120         case LONG_32_COMPAT:
121             return LONG_32_COMPAT_STR;
122         case LONG_16_COMPAT:
123             return LONG_16_COMPAT_STR;
124         default:
125             return NULL;
126     }
127 }
128
129 v3_mem_mode_t v3_get_vm_mem_mode(struct guest_info * info) {
130     struct cr0_32 * cr0;
131
132     if (info->shdw_pg_mode == SHADOW_PAGING) {
133         cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
134     } else if (info->shdw_pg_mode == NESTED_PAGING) {
135         cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
136     } else {
137         PrintError("Invalid Paging Mode...\n");
138         V3_ASSERT(0);
139         return -1;
140     }
141
142     if (cr0->pg == 0) {
143         return PHYSICAL_MEM;
144     } else {
145         return VIRTUAL_MEM;
146     }
147 }
148
149 static const uchar_t PHYS_MEM_STR[] = "Physical Memory";
150 static const uchar_t VIRT_MEM_STR[] = "Virtual Memory";
151
152 const uchar_t * v3_mem_mode_to_str(v3_mem_mode_t mode) {
153     switch (mode) {
154         case PHYSICAL_MEM:
155             return PHYS_MEM_STR;
156         case VIRTUAL_MEM:
157             return VIRT_MEM_STR;
158         default:
159             return NULL;
160     }
161 }
162
163
164 void v3_print_segments(struct v3_segments * segs) {
165     int i = 0;
166     struct v3_segment * seg_ptr;
167
168     seg_ptr=(struct v3_segment *)segs;
169   
170     char *seg_names[] = {"CS", "DS" , "ES", "FS", "GS", "SS" , "LDTR", "GDTR", "IDTR", "TR", NULL};
171     V3_Print("Segments\n");
172
173     for (i = 0; seg_names[i] != NULL; i++) {
174
175         V3_Print("\t%s: Sel=%x, base=%p, limit=%x (long_mode=%d, db=%d)\n", seg_names[i], seg_ptr[i].selector, 
176                    (void *)(addr_t)seg_ptr[i].base, seg_ptr[i].limit,
177                    seg_ptr[i].long_mode, seg_ptr[i].db);
178
179     }
180 }
181
182 //
183 // We don't handle those fancy 64 bit system segments...
184 //
185 int v3_translate_segment(struct guest_info * info, uint16_t selector, struct v3_segment * seg) {
186     struct v3_segment * gdt = &(info->segments.gdtr);
187     addr_t gdt_addr = 0;
188     uint16_t seg_offset = (selector & ~0x7);
189     addr_t seg_addr = 0;
190     struct gen_segment * gen_seg = NULL;
191     struct seg_selector sel;
192
193     memset(seg, 0, sizeof(struct v3_segment));
194
195     sel.value = selector;
196
197     if (sel.ti == 1) {
198         PrintError("LDT translations not supported\n");
199         return -1;
200     }
201
202     if (v3_gva_to_hva(info, gdt->base, &gdt_addr) == -1) {
203         PrintError("Unable to translate GDT address\n");
204         return -1;
205     }
206
207     seg_addr = gdt_addr + seg_offset;
208     gen_seg = (struct gen_segment *)seg_addr;
209
210     //translate
211     seg->selector = selector;
212
213     seg->limit = gen_seg->limit_hi;
214     seg->limit <<= 16;
215     seg->limit += gen_seg->limit_lo;
216
217     seg->base = gen_seg->base_hi;
218     seg->base <<= 24;
219     seg->base += gen_seg->base_lo;
220
221     if (gen_seg->granularity == 1) {
222         seg->limit <<= 12;
223         seg->limit |= 0xfff;
224     }
225
226     seg->type = gen_seg->type;
227     seg->system = gen_seg->system;
228     seg->dpl = gen_seg->dpl;
229     seg->present = gen_seg->present;
230     seg->avail = gen_seg->avail;
231     seg->long_mode = gen_seg->long_mode;
232     seg->db = gen_seg->db;
233     seg->granularity = gen_seg->granularity;
234     
235     return 0;
236 }
237
238
239
240
241 void v3_print_ctrl_regs(struct guest_info * info) {
242     struct v3_ctrl_regs * regs = &(info->ctrl_regs);
243     int i = 0;
244     v3_reg_t * reg_ptr;
245     char * reg_names[] = {"CR0", "CR2", "CR3", "CR4", "CR8", "FLAGS", NULL};
246     vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA(info->vmm_data);
247
248     reg_ptr = (v3_reg_t *)regs;
249
250     V3_Print("32 bit Ctrl Regs:\n");
251
252     for (i = 0; reg_names[i] != NULL; i++) {
253         V3_Print("\t%s=0x%p\n", reg_names[i], (void *)(addr_t)reg_ptr[i]);  
254     }
255
256     V3_Print("\tEFER=0x%p\n", (void*)(addr_t)(guest_state->efer));
257
258 }
259
260
261 static int safe_gva_to_hva(struct guest_info * info, addr_t linear_addr, addr_t * host_addr) {
262     /* select the proper translation based on guest mode */
263     if (info->mem_mode == PHYSICAL_MEM) {
264         if (v3_gpa_to_hva(info, linear_addr, host_addr) == -1) return -1;
265     } else if (info->mem_mode == VIRTUAL_MEM) {
266         if (v3_gva_to_hva(info, linear_addr, host_addr) == -1) return -1;
267     }
268     return 0;
269 }
270
271 static int v3_print_disassembly(struct guest_info * info) {
272     int passed_rip = 0;
273     addr_t rip, rip_linear, rip_host;
274
275     /* we don't know where the instructions preceding RIP start, so we just take
276      * a guess and hope the instruction stream synced up with our disassembly
277      * some time before RIP; if it has not we correct RIP at that point
278      */
279
280     /* start disassembly 64 bytes before current RIP, continue 32 bytes after */
281     rip = (addr_t) info->rip - 64;
282     while ((int) (rip - info->rip) < 32) {
283         /* always print RIP, even if the instructions before were bad */
284         if (!passed_rip && rip >= info->rip) {
285             if (rip != info->rip) {
286                 V3_Print("***** bad disassembly up to this point *****\n");
287                 rip = info->rip;
288             }
289             passed_rip = 1;
290         }
291
292         /* look up host virtual address for this instruction */
293         rip_linear = get_addr_linear(info, rip, &(info->segments.cs));
294         if (safe_gva_to_hva(info, rip_linear, &rip_host) < 0) {
295             rip++;
296             continue;
297         }
298
299         /* print disassembled instrcution (updates rip) */
300         if (v3_disasm(info, (void *) rip_host, &rip, rip == info->rip) < 0) {
301             rip++;
302             continue;
303         }
304     }
305
306     return 0;
307 }
308
309
310 void v3_print_guest_state(struct guest_info * info) {
311     addr_t linear_addr = 0; 
312
313     V3_Print("RIP: %p\n", (void *)(addr_t)(info->rip));
314     linear_addr = get_addr_linear(info, info->rip, &(info->segments.cs));
315     V3_Print("RIP Linear: %p\n", (void *)linear_addr);
316
317     V3_Print("NumExits: %u\n", (uint32_t)info->num_exits);
318
319     v3_print_segments(&(info->segments));
320     v3_print_ctrl_regs(info);
321
322     if (info->shdw_pg_mode == SHADOW_PAGING) {
323         V3_Print("Shadow Paging Guest Registers:\n");
324         V3_Print("\tGuest CR0=%p\n", (void *)(addr_t)(info->shdw_pg_state.guest_cr0));
325         V3_Print("\tGuest CR3=%p\n", (void *)(addr_t)(info->shdw_pg_state.guest_cr3));
326         V3_Print("\tGuest EFER=%p\n", (void *)(addr_t)(info->shdw_pg_state.guest_efer.value));
327         // CR4
328     }
329     v3_print_GPRs(info);
330
331     v3_print_mem_map(info->vm_info);
332
333     v3_print_stack(info);
334
335     v3_print_disassembly(info);
336 }
337
338
339 void v3_print_stack(struct guest_info * info) {
340     addr_t linear_addr = 0;
341     addr_t host_addr = 0;
342     int i = 0;
343     v3_cpu_mode_t cpu_mode = v3_get_vm_cpu_mode(info);
344
345
346     linear_addr = get_addr_linear(info, info->vm_regs.rsp, &(info->segments.ss));
347  
348     V3_Print("Stack  at %p:\n", (void *)linear_addr);
349    
350     if (info->mem_mode == PHYSICAL_MEM) {
351         if (v3_gpa_to_hva(info, linear_addr, &host_addr) == -1) {
352             PrintError("Could not translate Stack address\n");
353             return;
354         }
355     } else if (info->mem_mode == VIRTUAL_MEM) {
356         if (v3_gva_to_hva(info, linear_addr, &host_addr) == -1) {
357             PrintError("Could not translate Virtual Stack address\n");
358             return;
359         }
360     }
361     
362     V3_Print("Host Address of rsp = 0x%p\n", (void *)host_addr);
363  
364     // We start i at one because the current stack pointer points to an unused stack element
365     for (i = 0; i <= 24; i++) {
366         if (cpu_mode == LONG) {
367             V3_Print("\t%p\n", (void *)*(addr_t *)(host_addr + (i * 8)));
368         } else if (cpu_mode == REAL) {
369             V3_Print("Don't currently handle 16 bit stacks... \n");
370         } else {
371             // 32 bit stacks...
372             V3_Print("\t%.8x\n", *(uint32_t *)(host_addr + (i * 4)));
373         }
374     }
375
376 }    
377
378 #ifdef __V3_32BIT__
379
380 void v3_print_GPRs(struct guest_info * info) {
381     struct v3_gprs * regs = &(info->vm_regs);
382     int i = 0;
383     v3_reg_t * reg_ptr;
384     char * reg_names[] = { "RDI", "RSI", "RBP", "RSP", "RBX", "RDX", "RCX", "RAX", NULL};
385
386     reg_ptr = (v3_reg_t *)regs;
387
388     V3_Print("32 bit GPRs:\n");
389
390     for (i = 0; reg_names[i] != NULL; i++) {
391         V3_Print("\t%s=0x%p\n", reg_names[i], (void *)(addr_t)reg_ptr[i]);  
392     }
393 }
394
395 #elif __V3_64BIT__
396
397 void v3_print_GPRs(struct guest_info * info) {
398     struct v3_gprs * regs = &(info->vm_regs);
399     int i = 0;
400     v3_reg_t * reg_ptr;
401     char * reg_names[] = { "RDI", "RSI", "RBP", "RSP", "RBX", "RDX", "RCX", "RAX", \
402                            "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", NULL};
403
404     reg_ptr = (v3_reg_t *)regs;
405
406     V3_Print("64 bit GPRs:\n");
407
408     for (i = 0; reg_names[i] != NULL; i++) {
409         V3_Print("\t%s=0x%p\n", reg_names[i], (void *)(addr_t)reg_ptr[i]);  
410     }
411 }
412
413 #endif
414
415
416 #include <palacios/vmcs.h>
417 #include <palacios/vmcb.h>
418 static int info_hcall(struct guest_info * core, uint_t hcall_id, void * priv_data) {
419     v3_cpu_arch_t cpu_type = v3_get_cpu_type(V3_Get_CPU());
420     int cpu_valid = 0;
421
422     V3_Print("************** Guest State ************\n");
423     v3_print_guest_state(core);
424     
425     // init SVM/VMX
426 #ifdef CONFIG_SVM
427     if ((cpu_type == V3_SVM_CPU) || (cpu_type == V3_SVM_REV3_CPU)) {
428         cpu_valid = 1;
429         PrintDebugVMCB((vmcb_t *)(core->vmm_data));
430     }
431 #endif
432 #ifdef CONFIG_VMX
433     if ((cpu_type == V3_VMX_CPU) || (cpu_type == V3_VMX_EPT_CPU)) {
434         cpu_valid = 1;
435         v3_print_vmcs();
436     }
437 #endif
438     if (!cpu_valid) {
439         PrintError("Invalid CPU Type 0x%x\n", cpu_type);
440         return -1;
441     }
442     
443
444     return 0;
445 }
446
447
448 #ifdef CONFIG_SVM
449 #include <palacios/svm.h>
450 #include <palacios/svm_io.h>
451 #include <palacios/svm_msr.h>
452 #endif
453
454 #ifdef CONFIG_VMX
455 #include <palacios/vmx.h>
456 #include <palacios/vmx_io.h>
457 #include <palacios/vmx_msr.h>
458 #endif
459
460
461 int v3_init_vm(struct v3_vm_info * vm) {
462     v3_cpu_arch_t cpu_type = v3_get_cpu_type(V3_Get_CPU());
463     int cpu_valid = 0;
464
465     if (v3_get_foreground_vm() == NULL) {
466         v3_set_foreground_vm(vm);
467     }
468
469 #ifdef CONFIG_TELEMETRY
470     v3_init_telemetry(vm);
471 #endif
472
473     v3_init_hypercall_map(vm);
474     v3_init_io_map(vm);
475     v3_init_msr_map(vm);
476     v3_init_cpuid_map(vm);
477     v3_init_host_events(vm);
478     v3_init_intr_routers(vm);
479
480     // Initialize the memory map
481     if (v3_init_mem_map(vm) == -1) {
482         PrintError("Could not initialize shadow map\n");
483         return -1;
484     }
485
486     v3_init_mem_hooks(vm);
487
488     if (v3_init_shdw_impl(vm) == -1) {
489         PrintError("VM initialization error in shadow implementaion\n");
490         return -1;
491     }
492
493
494
495 #ifdef CONFIG_SYMBIOTIC
496     v3_init_symbiotic_vm(vm);
497 #endif
498
499     v3_init_dev_mgr(vm);
500
501
502     // init SVM/VMX
503 #ifdef CONFIG_SVM
504     if ((cpu_type == V3_SVM_CPU) || (cpu_type == V3_SVM_REV3_CPU)) {
505         v3_init_svm_io_map(vm);
506         v3_init_svm_msr_map(vm);
507         cpu_valid = 1;
508     } 
509 #endif
510 #ifdef CONFIG_VMX
511     if ((cpu_type == V3_VMX_CPU) || (cpu_type == V3_VMX_EPT_CPU)) {
512         v3_init_vmx_io_map(vm);
513         v3_init_vmx_msr_map(vm);
514         cpu_valid = 1;
515     }
516 #endif
517     if (!cpu_valid) {
518         PrintError("Invalid CPU Type 0x%x\n", cpu_type);
519         return -1;
520     }
521     
522     v3_register_hypercall(vm, GUEST_INFO_HCALL, info_hcall, NULL);
523
524     V3_Print("GUEST_INFO_HCALL=%x\n", GUEST_INFO_HCALL);
525
526     return 0;
527 }
528
529 int v3_init_core(struct guest_info * core) {
530     v3_cpu_arch_t cpu_type = v3_get_cpu_type(V3_Get_CPU());
531     struct v3_vm_info * vm = core->vm_info;
532
533     /*
534      * Initialize the subsystem data strutures
535      */
536 #ifdef CONFIG_TELEMETRY
537     v3_init_core_telemetry(core);
538 #endif
539
540     if (core->shdw_pg_mode == SHADOW_PAGING) {
541         v3_init_shdw_pg_state(core);
542     }
543
544     v3_init_time(core);
545     v3_init_intr_controllers(core);
546     v3_init_exception_state(core);
547
548     v3_init_decoder(core);
549
550
551 #ifdef CONFIG_SYMBIOTIC
552     v3_init_symbiotic_core(core);
553 #endif
554
555     // init SVM/VMX
556
557
558     switch (cpu_type) {
559 #ifdef CONFIG_SVM
560         case V3_SVM_CPU:
561         case V3_SVM_REV3_CPU:
562             if (v3_init_svm_vmcb(core, vm->vm_class) == -1) {
563                 PrintError("Error in SVM initialization\n");
564                 return -1;
565             }
566             break;
567 #endif
568 #ifdef CONFIG_VMX
569         case V3_VMX_CPU:
570         case V3_VMX_EPT_CPU:
571             if (v3_init_vmx_vmcs(core, vm->vm_class) == -1) {
572                 PrintError("Error in VMX initialization\n");
573                 return -1;
574             }
575             break;
576 #endif
577         default:
578             PrintError("Invalid CPU Type 0x%x\n", cpu_type);
579             return -1;
580     }
581
582     return 0;
583 }
584
585
586
587 int v3_free_core(struct guest_info * core) {
588     v3_cpu_arch_t cpu_type = v3_get_cpu_type(V3_Get_CPU());
589
590     
591 #ifdef CONFIG_SYMBIOTIC
592     //v3_deinit_symbiotic_core(core);
593 #endif
594
595     v3_deinit_decoder(core);
596
597     v3_deinit_intr_controllers(core);
598
599     switch (cpu_type) {
600 #ifdef CONFIG_SVM
601         case V3_SVM_CPU:
602         case V3_SVM_REV3_CPU:
603             if (v3_deinit_svm_vmcb(core) == -1) {
604                 PrintError("Error in SVM initialization\n");
605                 return -1;
606             }
607             break;
608 #endif
609 #ifdef CONFIG_VMX
610         case V3_VMX_CPU:
611         case V3_VMX_EPT_CPU:
612             if (v3_deinit_vmx_vmcs(core) == -1) {
613                 PrintError("Error in VMX initialization\n");
614                 return -1;
615             }
616             break;
617 #endif
618         default:
619             PrintError("Invalid CPU Type 0x%x\n", cpu_type);
620             return -1;
621     }
622
623     return 0;
624 }
625
626
627
628 int v3_free_vm_internal(struct v3_vm_info * vm) {
629
630     
631     return 0;
632 }