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.


fixed bug in time initialization, and added deinitialization
[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     v3_init_time_vm(vm);
495
496
497 #ifdef CONFIG_SYMBIOTIC
498     v3_init_symbiotic_vm(vm);
499 #endif
500
501     v3_init_dev_mgr(vm);
502
503
504     // init SVM/VMX
505 #ifdef CONFIG_SVM
506     if ((cpu_type == V3_SVM_CPU) || (cpu_type == V3_SVM_REV3_CPU)) {
507         v3_init_svm_io_map(vm);
508         v3_init_svm_msr_map(vm);
509         cpu_valid = 1;
510     } 
511 #endif
512 #ifdef CONFIG_VMX
513     if ((cpu_type == V3_VMX_CPU) || (cpu_type == V3_VMX_EPT_CPU)) {
514         v3_init_vmx_io_map(vm);
515         v3_init_vmx_msr_map(vm);
516         cpu_valid = 1;
517     }
518 #endif
519     if (!cpu_valid) {
520         PrintError("Invalid CPU Type 0x%x\n", cpu_type);
521         return -1;
522     }
523     
524     v3_register_hypercall(vm, GUEST_INFO_HCALL, info_hcall, NULL);
525
526     V3_Print("GUEST_INFO_HCALL=%x\n", GUEST_INFO_HCALL);
527
528     return 0;
529 }
530
531 int v3_init_core(struct guest_info * core) {
532     v3_cpu_arch_t cpu_type = v3_get_cpu_type(V3_Get_CPU());
533     struct v3_vm_info * vm = core->vm_info;
534
535     /*
536      * Initialize the subsystem data strutures
537      */
538 #ifdef CONFIG_TELEMETRY
539     v3_init_core_telemetry(core);
540 #endif
541
542     if (core->shdw_pg_mode == SHADOW_PAGING) {
543         v3_init_shdw_pg_state(core);
544     }
545
546     v3_init_time_core(core);
547     v3_init_intr_controllers(core);
548     v3_init_exception_state(core);
549
550     v3_init_decoder(core);
551
552
553 #ifdef CONFIG_SYMBIOTIC
554     v3_init_symbiotic_core(core);
555 #endif
556
557     // init SVM/VMX
558
559
560     switch (cpu_type) {
561 #ifdef CONFIG_SVM
562         case V3_SVM_CPU:
563         case V3_SVM_REV3_CPU:
564             if (v3_init_svm_vmcb(core, vm->vm_class) == -1) {
565                 PrintError("Error in SVM initialization\n");
566                 return -1;
567             }
568             break;
569 #endif
570 #ifdef CONFIG_VMX
571         case V3_VMX_CPU:
572         case V3_VMX_EPT_CPU:
573             if (v3_init_vmx_vmcs(core, vm->vm_class) == -1) {
574                 PrintError("Error in VMX initialization\n");
575                 return -1;
576             }
577             break;
578 #endif
579         default:
580             PrintError("Invalid CPU Type 0x%x\n", cpu_type);
581             return -1;
582     }
583
584     return 0;
585 }
586
587
588
589 int v3_free_core(struct guest_info * core) {
590     v3_cpu_arch_t cpu_type = v3_get_cpu_type(V3_Get_CPU());
591
592     
593 #ifdef CONFIG_SYMBIOTIC
594     //v3_deinit_symbiotic_core(core);
595 #endif
596
597     v3_deinit_decoder(core);
598
599     v3_deinit_intr_controllers(core);
600     v3_deinit_time_core(core);
601
602     switch (cpu_type) {
603 #ifdef CONFIG_SVM
604         case V3_SVM_CPU:
605         case V3_SVM_REV3_CPU:
606             if (v3_deinit_svm_vmcb(core) == -1) {
607                 PrintError("Error in SVM initialization\n");
608                 return -1;
609             }
610             break;
611 #endif
612 #ifdef CONFIG_VMX
613         case V3_VMX_CPU:
614         case V3_VMX_EPT_CPU:
615             if (v3_deinit_vmx_vmcs(core) == -1) {
616                 PrintError("Error in VMX initialization\n");
617                 return -1;
618             }
619             break;
620 #endif
621         default:
622             PrintError("Invalid CPU Type 0x%x\n", cpu_type);
623             return -1;
624     }
625
626     return 0;
627 }
628
629
630
631 int v3_free_vm_internal(struct v3_vm_info * vm) {
632
633     
634     return 0;
635 }