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