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.


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