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 support for wbinvd instruction exit (which windows uses)
[palacios.git] / palacios / src / palacios / svm_handler.c
1 #include <palacios/svm_handler.h>
2 #include <palacios/vmm.h>
3 #include <palacios/vm_guest_mem.h>
4 #include <palacios/vmm_decoder.h>
5 #include <palacios/vmm_ctrl_regs.h>
6 #include <palacios/svm_io.h>
7 #include <palacios/svm_halt.h>
8 #include <palacios/svm_pause.h>
9 #include <palacios/svm_wbinvd.h>
10 #include <palacios/vmm_intr.h>
11 #include <palacios/vmm_emulator.h>
12
13 int handle_svm_exit(struct guest_info * info) {
14   vmcb_ctrl_t * guest_ctrl = 0;
15   vmcb_saved_state_t * guest_state = 0;
16   ulong_t exit_code = 0;
17   
18   guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
19   guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
20   
21
22   // Update the high level state 
23   info->rip = guest_state->rip;
24   info->vm_regs.rsp = guest_state->rsp;
25   info->vm_regs.rax = guest_state->rax;
26
27   info->cpl = guest_state->cpl;
28
29
30   info->ctrl_regs.cr0 = guest_state->cr0;
31   info->ctrl_regs.cr2 = guest_state->cr2;
32   info->ctrl_regs.cr3 = guest_state->cr3;
33   info->ctrl_regs.cr4 = guest_state->cr4;
34   info->dbg_regs.dr6 = guest_state->dr6;
35   info->dbg_regs.dr7 = guest_state->dr7;
36   info->ctrl_regs.cr8 = guest_ctrl->guest_ctrl.V_TPR;
37   info->ctrl_regs.rflags = guest_state->rflags;
38   info->ctrl_regs.efer = guest_state->efer;
39
40   get_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
41   info->cpu_mode = get_cpu_mode(info);
42   info->mem_mode = get_mem_mode(info);
43
44
45   exit_code = guest_ctrl->exit_code;
46  
47
48   // Disable printing io exits due to bochs debug messages
49   //if (!((exit_code == VMEXIT_IOIO) && ((ushort_t)(guest_ctrl->exit_info1 >> 16) == 0x402))) {
50
51
52   //  PrintDebug("SVM Returned: Exit Code: 0x%x \t\t(tsc=%ul)\n",exit_code, (uint_t)info->time_state.guest_tsc); 
53   
54   if ((0) && (exit_code < 0x4f)) {
55     char instr[32];
56     int ret;
57     // Dump out the instr stream
58
59     //PrintDebug("RIP: %x\n", guest_state->rip);
60     PrintDebug("RIP Linear: %x\n", get_addr_linear(info, info->rip, &(info->segments.cs)));
61
62     // OK, now we will read the instruction
63     // The only difference between PROTECTED and PROTECTED_PG is whether we read
64     // from guest_pa or guest_va
65     if (info->mem_mode == PHYSICAL_MEM) { 
66       // The real rip address is actually a combination of the rip + CS base 
67       ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 32, instr);
68     } else { 
69       ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 32, instr);
70     }
71     
72     if (ret != 32) {
73       // I think we should inject a GPF into the guest
74       PrintDebug("Could not read instruction (ret=%d)\n", ret);
75     } else {
76
77       PrintDebug("Instr Stream:\n");
78       PrintTraceMemDump(instr, 32);
79     }
80   }
81
82
83     //  }
84   // PrintDebugVMCB((vmcb_t*)(info->vmm_data));
85
86
87   // PrintDebug("SVM Returned:(VMCB=%x)\n", info->vmm_data); 
88   //PrintDebug("RIP: %x\n", guest_state->rip);
89
90   
91   //PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); 
92
93   switch (exit_code) {
94
95   case VMEXIT_IOIO: {
96     struct svm_io_info * io_info = (struct svm_io_info *)&(guest_ctrl->exit_info1);
97     
98     if (io_info->type == 0) {
99       if (io_info->str) {
100         if (handle_svm_io_outs(info) == -1 ) {
101           return -1;
102         }
103       } else {
104         if (handle_svm_io_out(info) == -1) {
105           return -1;
106         }
107       }
108     } else {
109       if (io_info->str) {
110         if (handle_svm_io_ins(info) == -1) {
111           return -1;
112         }
113       } else {
114         if (handle_svm_io_in(info) == -1) {
115           return -1;
116         }
117       }
118     }
119   }
120     break;
121
122
123   case  VMEXIT_CR0_WRITE: {
124 #ifdef DEBUG_CTRL_REGS
125     PrintDebug("CR0 Write\n");
126 #endif
127     if (handle_cr0_write(info) == -1) {
128       return -1;
129     }
130   } 
131     break;
132
133   case VMEXIT_CR0_READ: {
134 #ifdef DEBUG_CTRL_REGS
135     PrintDebug("CR0 Read\n");
136 #endif
137     if (handle_cr0_read(info) == -1) {
138       return -1;
139     }
140   } 
141     break;
142
143   case VMEXIT_CR3_WRITE: {
144 #ifdef DEBUG_CTRL_REGS
145     PrintDebug("CR3 Write\n");
146 #endif
147     if (handle_cr3_write(info) == -1) {
148       return -1;
149     }    
150   } 
151     break;
152
153   case  VMEXIT_CR3_READ: {
154 #ifdef DEBUG_CTRL_REGS
155     PrintDebug("CR3 Read\n");
156 #endif
157     if (handle_cr3_read(info) == -1) {
158       return -1;
159     }
160   }
161     break;
162
163   case VMEXIT_EXCP14: {
164     addr_t fault_addr = guest_ctrl->exit_info2;
165     pf_error_t * error_code = (pf_error_t *)&(guest_ctrl->exit_info1);
166 #ifdef DEBUG_SHADOW_PAGING
167     PrintDebug("PageFault at %x (error=%d)\n", fault_addr, *error_code);
168 #endif
169     if (info->shdw_pg_mode == SHADOW_PAGING) {
170       if (handle_shadow_pagefault(info, fault_addr, *error_code) == -1) {
171         return -1;
172       }
173     } else {
174       PrintError("Page fault in un implemented paging mode\n");
175       return -1;
176     }
177   } 
178     break;
179
180   case VMEXIT_NPF: {
181     PrintError("Currently unhandled Nested Page Fault\n");
182     return -1;
183     
184   } 
185     break;
186
187   case VMEXIT_INVLPG: {
188     if (info->shdw_pg_mode == SHADOW_PAGING) {
189 #ifdef DEBUG_SHADOW_PAGING
190       PrintDebug("Invlpg\n");
191 #endif
192       if (handle_shadow_invlpg(info) == -1) {
193         return -1;
194       }
195     }
196    
197     /*
198       (exit_code == VMEXIT_INVLPGA)   || 
199     */
200     
201   } 
202     break;
203
204   case VMEXIT_INTR: { 
205     
206     //    handle_svm_intr(info); // handled by interrupt dispatch earlier
207
208   } 
209     break;
210     
211   case VMEXIT_SMI: {
212     
213     //   handle_svm_smi(info); // ignored for now
214
215   } 
216     break;
217
218   case VMEXIT_HLT: {
219     PrintDebug("Guest halted\n");
220     if (handle_svm_halt(info) == -1) {
221       return -1;
222     }
223   } 
224     break;
225
226   case VMEXIT_PAUSE: {
227     PrintDebug("Guest paused\n");
228     if (handle_svm_pause(info) == -1) { 
229       return -1;
230     }
231   } 
232     break;
233
234   case VMEXIT_EXCP1: {
235 #ifdef DEBUG_EMULATOR
236     PrintDebug("DEBUG EXCEPTION\n");
237 #endif
238     if (info->run_state == VM_EMULATING) {
239       if (v3_emulation_exit_handler(info) == -1) {
240         return -1;
241       }
242     } else {
243       PrintError("VMMCALL with not emulator...\n");
244       return -1;
245     }
246   } 
247     break;
248
249   case VMEXIT_VMMCALL: {
250 #ifdef DEBUG_EMULATOR
251     PrintDebug("VMMCALL\n");
252 #endif
253     if (info->run_state == VM_EMULATING) {
254       if (v3_emulation_exit_handler(info) == -1) {
255         return -1;
256       }
257     } else {
258       PrintError("VMMCALL with not emulator...\n");
259       return -1;
260     }
261     
262   } 
263     break;
264
265
266   case VMEXIT_WBINVD: {
267 #ifdef DEBUG_EMULATOR
268     PrintDebug("WBINVD\n");
269 #endif
270     if (!handle_svm_wbinvd(info)) { 
271       return -1;
272     }
273   }
274     break;
275
276
277
278     /* Exits Following this line are NOT HANDLED */
279     /*=======================================================================*/
280
281   case VMEXIT_CR_READ_MASK:
282     PrintDebug("Unhandled SVM Exit: VMEXIT_CR_READ_MASK\n"); 
283     goto unhandled_exit;
284     break;
285     
286   case VMEXIT_CR_WRITE_MASK:
287     PrintDebug("Unhandled SVM Exit: VMEXIT_CR_WRITE_MASK\n");
288     goto unhandled_exit;
289     break;
290
291   case VMEXIT_CR1_READ:
292     PrintDebug("Unhandled SVM Exit: VMEXIT_CR1_READ\n");
293     goto unhandled_exit;
294     break;
295      
296   case VMEXIT_CR1_WRITE:
297     PrintDebug("Unhandled SVM Exit: VMEXIT_CR1_WRITE\n");
298     goto unhandled_exit;
299     break;
300
301   case VMEXIT_CR2_READ:
302     PrintDebug("Unhandled SVM Exit: VMEXIT_CR2_READ\n");
303     goto unhandled_exit;
304     break;
305      
306   case VMEXIT_CR2_WRITE:
307     PrintDebug("Unhandled SVM Exit: VMEXIT_CR2_WRITE\n");
308     goto unhandled_exit;
309     break;
310
311   case VMEXIT_CR4_READ:
312     PrintDebug("Unhandled SVM Exit: VMEXIT_CR4_READ\n");
313     goto unhandled_exit;
314     break;
315
316   case VMEXIT_CR4_WRITE:
317     PrintDebug("Unhandled SVM Exit: VMEXIT_CR4_WRITE\n");
318     goto unhandled_exit;
319     break;
320
321   case VMEXIT_CR5_READ:
322     PrintDebug("Unhandled SVM Exit: VMEXIT_CR5_READ\n");
323     goto unhandled_exit;
324     break;
325
326   case VMEXIT_CR5_WRITE:
327     PrintDebug("Unhandled SVM Exit: VMEXIT_CR5_WRITE\n");
328     goto unhandled_exit;
329     break;
330
331   case VMEXIT_CR6_READ:
332     PrintDebug("Unhandled SVM Exit: VMEXIT_CR6_READ\n");
333     goto unhandled_exit;
334     break;
335
336   case VMEXIT_CR6_WRITE:
337     PrintDebug("Unhandled SVM Exit: VMEXIT_CR6_WRITE\n");
338     goto unhandled_exit;
339     break;
340
341   case VMEXIT_CR7_READ:
342     PrintDebug("Unhandled SVM Exit: VMEXIT_CR7_READ\n");
343     goto unhandled_exit;
344     break;
345
346   case VMEXIT_CR7_WRITE:
347     PrintDebug("Unhandled SVM Exit: VMEXIT_CR7_WRITE\n");
348     goto unhandled_exit;
349     break;
350
351   case VMEXIT_CR8_READ:
352     PrintDebug("Unhandled SVM Exit: VMEXIT_CR8_READ\n");
353     goto unhandled_exit;
354     break;
355
356   case VMEXIT_CR8_WRITE:
357     PrintDebug("Unhandled SVM Exit: VMEXIT_CR8_WRITE\n");
358     goto unhandled_exit;
359     break;
360
361   case VMEXIT_CR9_READ:
362     PrintDebug("Unhandled SVM Exit: VMEXIT_CR9_READ\n");
363     goto unhandled_exit;
364     break;
365
366   case VMEXIT_CR9_WRITE:
367     PrintDebug("Unhandled SVM Exit: VMEXIT_CR9_WRITE\n");
368     goto unhandled_exit;
369     break;
370
371   case VMEXIT_CR10_READ:
372     PrintDebug("Unhandled SVM Exit: VMEXIT_CR10_READ\n");
373     goto unhandled_exit;
374     break;
375
376   case VMEXIT_CR10_WRITE:
377     PrintDebug("Unhandled SVM Exit: VMEXIT_CR10_WRITE\n");
378     goto unhandled_exit;
379     break;
380
381   case VMEXIT_CR11_READ:
382     PrintDebug("Unhandled SVM Exit: VMEXIT_CR11_READ\n");
383     goto unhandled_exit;
384     break;
385
386   case VMEXIT_CR11_WRITE:
387     PrintDebug("Unhandled SVM Exit: VMEXIT_CR11_WRITE\n");
388     goto unhandled_exit;
389     break;
390
391   case VMEXIT_CR12_READ:
392     PrintDebug("Unhandled SVM Exit: VMEXIT_CR12_READ\n");
393     goto unhandled_exit;
394     break;
395
396   case VMEXIT_CR12_WRITE:
397     PrintDebug("Unhandled SVM Exit: VMEXIT_CR12_WRITE\n");
398     goto unhandled_exit;
399     break;
400
401   case VMEXIT_CR13_READ:
402     PrintDebug("Unhandled SVM Exit: VMEXIT_CR13_READ\n");
403     goto unhandled_exit;
404     break;
405
406   case VMEXIT_CR13_WRITE:
407     PrintDebug("Unhandled SVM Exit: VMEXIT_CR13_WRITE\n");
408     goto unhandled_exit;
409     break;
410
411   case VMEXIT_CR14_READ:
412     PrintDebug("Unhandled SVM Exit: VMEXIT_CR14_READ\n");
413     goto unhandled_exit;
414     break;
415
416   case VMEXIT_CR14_WRITE:
417     PrintDebug("Unhandled SVM Exit: VMEXIT_CR14_WRITE\n");
418     goto unhandled_exit;
419     break;
420
421   case VMEXIT_CR15_READ:
422     PrintDebug("Unhandled SVM Exit: VMEXIT_CR15_READ\n");
423     goto unhandled_exit;
424     break;
425
426   case VMEXIT_CR15_WRITE:
427     PrintDebug("Unhandled SVM Exit: VMEXIT_CR15_WRITE\n");
428     goto unhandled_exit;
429     break;
430
431
432   case VMEXIT_DR_READ_MASK:
433     PrintDebug("Unhandled SVM Exit: VMEXIT_DR_READ_MASK\n");
434     goto unhandled_exit;
435     break;
436
437   case VMEXIT_DR_WRITE_MASK:
438     PrintDebug("Unhandled SVM Exit: VMEXIT_DR_WRITE_MASK\n");
439     goto unhandled_exit;
440     break;
441
442   case VMEXIT_DR0_READ:
443     PrintDebug("Unhandled SVM Exit: VMEXIT_DR0_READ\n");
444     goto unhandled_exit;
445     break;
446
447   case VMEXIT_DR0_WRITE:
448     PrintDebug("Unhandled SVM Exit: VMEXIT_DR0_WRITE\n");
449     goto unhandled_exit;
450     break;
451
452   case VMEXIT_DR1_READ:
453     PrintDebug("Unhandled SVM Exit: VMEXIT_DR1_READ\n");
454     goto unhandled_exit;
455     break;
456
457   case VMEXIT_DR1_WRITE:
458     PrintDebug("Unhandled SVM Exit: VMEXIT_DR1_WRITE\n");
459     goto unhandled_exit;
460     break;
461
462   case VMEXIT_DR2_READ:
463     PrintDebug("Unhandled SVM Exit: VMEXIT_DR2_READ\n");
464     goto unhandled_exit;
465     break;
466
467   case VMEXIT_DR2_WRITE:
468     PrintDebug("Unhandled SVM Exit: VMEXIT_DR2_WRITE\n");
469     goto unhandled_exit;
470     break;
471
472   case VMEXIT_DR3_READ:
473     PrintDebug("Unhandled SVM Exit: VMEXIT_DR3_READ\n");
474     goto unhandled_exit;
475     break;
476
477   case VMEXIT_DR3_WRITE:
478     PrintDebug("Unhandled SVM Exit: VMEXIT_DR3_WRITE\n");
479     goto unhandled_exit;
480     break;
481
482   case VMEXIT_DR4_READ:
483     PrintDebug("Unhandled SVM Exit: VMEXIT_DR4_READ\n");
484     goto unhandled_exit;
485     break;
486
487   case VMEXIT_DR4_WRITE:
488     PrintDebug("Unhandled SVM Exit: VMEXIT_DR4_WRITE\n");
489     goto unhandled_exit;
490     break;
491
492   case VMEXIT_DR5_READ:
493     PrintDebug("Unhandled SVM Exit: VMEXIT_DR5_READ\n");
494     goto unhandled_exit;
495     break;
496
497   case VMEXIT_DR5_WRITE:
498     PrintDebug("Unhandled SVM Exit: VMEXIT_DR5_WRITE\n");
499     goto unhandled_exit;
500     break;
501
502   case VMEXIT_DR6_READ:
503     PrintDebug("Unhandled SVM Exit: VMEXIT_DR6_READ\n");
504     goto unhandled_exit;
505     break;
506
507   case VMEXIT_DR6_WRITE:
508     PrintDebug("Unhandled SVM Exit: VMEXIT_DR6_WRITE\n");
509     goto unhandled_exit;
510     break;
511
512   case VMEXIT_DR7_READ:
513     PrintDebug("Unhandled SVM Exit: VMEXIT_DR7_READ\n");
514     goto unhandled_exit;
515     break;
516
517   case VMEXIT_DR7_WRITE:
518     PrintDebug("Unhandled SVM Exit: VMEXIT_DR7_WRITE\n");
519     goto unhandled_exit;
520     break;
521
522   case VMEXIT_DR8_READ:
523     PrintDebug("Unhandled SVM Exit: VMEXIT_DR8_READ\n");
524     goto unhandled_exit;
525     break;
526
527   case VMEXIT_DR8_WRITE:
528     PrintDebug("Unhandled SVM Exit: VMEXIT_DR8_WRITE\n");
529     goto unhandled_exit;
530     break;
531
532   case VMEXIT_DR9_READ:
533     PrintDebug("Unhandled SVM Exit: VMEXIT_DR9_READ\n");
534     goto unhandled_exit;
535     break;
536
537   case VMEXIT_DR9_WRITE:
538     PrintDebug("Unhandled SVM Exit: VMEXIT_DR9_WRITE\n");
539     goto unhandled_exit;
540     break;
541
542   case VMEXIT_DR10_READ:
543     PrintDebug("Unhandled SVM Exit: VMEXIT_DR10_READ\n");
544     goto unhandled_exit;
545     break;
546
547   case VMEXIT_DR10_WRITE:
548     PrintDebug("Unhandled SVM Exit: VMEXIT_DR10_WRITE\n");
549     goto unhandled_exit;
550     break;
551
552   case VMEXIT_DR11_READ:
553     PrintDebug("Unhandled SVM Exit: VMEXIT_DR11_READ\n");
554     goto unhandled_exit;
555     break;
556
557   case VMEXIT_DR11_WRITE:
558     PrintDebug("Unhandled SVM Exit: VMEXIT_DR11_WRITE\n");
559     goto unhandled_exit;
560     break;
561
562   case VMEXIT_DR12_READ:
563     PrintDebug("Unhandled SVM Exit: VMEXIT_DR12_READ\n");
564     goto unhandled_exit;
565     break;
566
567   case VMEXIT_DR12_WRITE:
568     PrintDebug("Unhandled SVM Exit: VMEXIT_DR12_WRITE\n");
569     goto unhandled_exit;
570     break;
571
572   case VMEXIT_DR13_READ:
573     PrintDebug("Unhandled SVM Exit: VMEXIT_DR13_READ\n");
574     goto unhandled_exit;
575     break;
576
577   case VMEXIT_DR13_WRITE:
578     PrintDebug("Unhandled SVM Exit: VMEXIT_DR13_WRITE\n");
579     goto unhandled_exit;
580     break;
581
582   case VMEXIT_DR14_READ:
583     PrintDebug("Unhandled SVM Exit: VMEXIT_DR14_READ\n");
584     goto unhandled_exit;
585     break;
586
587   case VMEXIT_DR14_WRITE:
588     PrintDebug("Unhandled SVM Exit: VMEXIT_DR14_WRITE\n");
589     goto unhandled_exit;
590     break;
591
592   case VMEXIT_DR15_READ:
593     PrintDebug("Unhandled SVM Exit: VMEXIT_DR15_READ\n");
594     goto unhandled_exit;
595     break;
596
597   case VMEXIT_DR15_WRITE:
598     PrintDebug("Unhandled SVM Exit: VMEXIT_DR15_WRITE\n");
599     goto unhandled_exit;
600     break;
601
602     
603   case VMEXIT_EXCP_MASK:
604     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP_MASK\n");
605     goto unhandled_exit;
606     break;
607
608   case VMEXIT_EXCP0:
609     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP0\n");
610     goto unhandled_exit;
611     break;
612
613   case VMEXIT_EXCP2:
614     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP2\n");
615     goto unhandled_exit;
616     break;
617
618   case VMEXIT_EXCP3:
619     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP3\n");
620     goto unhandled_exit;
621     break;
622
623   case VMEXIT_EXCP4:
624     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP4\n");
625     goto unhandled_exit;
626     break;
627
628   case VMEXIT_EXCP5:
629     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP5\n");
630     goto unhandled_exit;
631     break;
632
633   case VMEXIT_EXCP6:
634     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP6\n");
635     goto unhandled_exit;
636     break;
637
638   case VMEXIT_EXCP7:
639     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP7\n");
640     goto unhandled_exit;
641     break;
642
643   case VMEXIT_EXCP8:
644     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP8\n");
645     goto unhandled_exit;
646     break;
647
648   case VMEXIT_EXCP9:
649     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP9\n");
650     goto unhandled_exit;
651     break;
652
653   case VMEXIT_EXCP10:
654     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP10\n");
655     goto unhandled_exit;
656     break;
657
658   case VMEXIT_EXCP11:
659     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP11\n");
660     goto unhandled_exit;
661     break;
662
663   case VMEXIT_EXCP12:
664     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP12\n");
665     goto unhandled_exit;
666     break;
667
668   case VMEXIT_EXCP13:
669     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP13\n");
670     goto unhandled_exit;
671     break;
672
673   case VMEXIT_EXCP15:
674     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP15\n");
675     goto unhandled_exit;
676     break;
677
678   case VMEXIT_EXCP16:
679     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP16\n");
680     goto unhandled_exit;
681     break;
682
683   case VMEXIT_EXCP17:
684     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP17\n");
685     goto unhandled_exit;
686     break;
687
688   case VMEXIT_EXCP18:
689     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP18\n");
690     goto unhandled_exit;
691     break;
692
693   case VMEXIT_EXCP19:
694     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP19\n");
695     goto unhandled_exit;
696     break;
697
698   case VMEXIT_EXCP20:
699     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP20\n");
700     goto unhandled_exit;
701     break;
702
703   case VMEXIT_EXCP21:
704     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP21\n");
705     goto unhandled_exit;
706     break;
707
708   case VMEXIT_EXCP22:
709     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP22\n");
710     goto unhandled_exit;
711     break;
712
713   case VMEXIT_EXCP23:
714     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP23\n");
715     goto unhandled_exit;
716     break;
717
718   case VMEXIT_EXCP24:
719     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP24\n");
720     goto unhandled_exit;
721     break;
722
723   case VMEXIT_EXCP25:
724     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP25\n");
725     goto unhandled_exit;
726     break;
727
728   case VMEXIT_EXCP26:
729     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP26\n");
730     goto unhandled_exit;
731     break;
732
733   case VMEXIT_EXCP27:
734     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP27\n");
735     goto unhandled_exit;
736     break;
737
738   case VMEXIT_EXCP28:
739     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP28\n");
740     goto unhandled_exit;
741     break;
742
743   case VMEXIT_EXCP29:
744     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP29\n");
745     goto unhandled_exit;
746     break;
747
748   case VMEXIT_EXCP30:
749     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP30\n");
750     goto unhandled_exit;
751     break;
752
753   case VMEXIT_EXCP31:
754     PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP31\n");
755     goto unhandled_exit;
756     break;
757
758     
759   case VMEXIT_NMI:
760     PrintDebug("Unhandled SVM Exit: VMEXIT_NMI\n");
761     goto unhandled_exit;
762     break;
763
764   case VMEXIT_INIT:
765     PrintDebug("Unhandled SVM Exit: VMEXIT_INIT\n");
766     goto unhandled_exit;
767     break;
768
769   case VMEXIT_VINITR:
770     PrintDebug("Unhandled SVM Exit: VMEXIT_VINITR\n");
771     goto unhandled_exit;
772     break;
773
774   case VMEXIT_CR0_SEL_WRITE:
775     PrintDebug("Unhandled SVM Exit: VMEXIT_CR0_SEL_WRITE\n");
776     goto unhandled_exit;
777     break;
778
779   case VMEXIT_IDTR_READ:
780     PrintDebug("Unhandled SVM Exit: VMEXIT_IDTR_READ\n");
781     goto unhandled_exit;
782     break;
783
784   case VMEXIT_IDTR_WRITE:
785     PrintDebug("Unhandled SVM Exit: VMEXIT_IDTR_WRITE\n");
786     goto unhandled_exit;
787     break;
788
789   case VMEXIT_GDTR_READ:
790     PrintDebug("Unhandled SVM Exit: VMEXIT_GDTR_READ\n");
791     goto unhandled_exit;
792     break;
793
794   case VMEXIT_GDTR_WRITE:
795     PrintDebug("Unhandled SVM Exit: VMEXIT_GDTR_WRITE\n");
796     goto unhandled_exit;
797     break;
798
799   case VMEXIT_LDTR_READ:
800     PrintDebug("Unhandled SVM Exit: VMEXIT_LDTR_READ\n");
801     goto unhandled_exit;
802     break;
803
804   case VMEXIT_LDTR_WRITE:
805     PrintDebug("Unhandled SVM Exit: VMEXIT_LDTR_WRITE\n");
806     goto unhandled_exit;
807     break;
808
809   case VMEXIT_TR_READ:
810     PrintDebug("Unhandled SVM Exit: VMEXIT_TR_READ\n");
811     goto unhandled_exit;
812     break;
813
814   case VMEXIT_TR_WRITE:
815     PrintDebug("Unhandled SVM Exit: VMEXIT_TR_WRITE\n");
816     goto unhandled_exit;
817     break;
818
819   case VMEXIT_RDTSC:
820     PrintDebug("Unhandled SVM Exit: VMEXIT_RDTSC\n");
821     goto unhandled_exit;
822     break;
823
824   case VMEXIT_RDPMC:
825     PrintDebug("Unhandled SVM Exit: VMEXIT_RDPMC\n");
826     goto unhandled_exit;
827     break;
828
829   case VMEXIT_PUSHF:
830     PrintDebug("Unhandled SVM Exit: VMEXIT_PUSHF\n");
831     goto unhandled_exit;
832     break;
833
834   case VMEXIT_POPF:
835     PrintDebug("Unhandled SVM Exit: VMEXIT_POPF\n");
836     goto unhandled_exit;
837     break;
838
839   case VMEXIT_CPUID:
840     PrintDebug("Unhandled SVM Exit: VMEXIT_CPUID\n");
841     goto unhandled_exit;
842     break;
843
844   case VMEXIT_RSM:
845     PrintDebug("Unhandled SVM Exit: VMEXIT_RSM\n");
846     goto unhandled_exit;
847     break;
848
849   case VMEXIT_IRET:
850     PrintDebug("Unhandled SVM Exit: VMEXIT_IRET\n");
851     goto unhandled_exit;
852     break;
853
854   case VMEXIT_SWINT:
855     PrintDebug("Unhandled SVM Exit: VMEXIT_SWINT\n");
856     goto unhandled_exit;
857     break;
858
859   case VMEXIT_INVD:
860     PrintDebug("Unhandled SVM Exit: VMEXIT_INVD\n");
861     goto unhandled_exit;
862     break;
863
864   case VMEXIT_INVLPGA:
865     PrintDebug("Unhandled SVM Exit: VMEXIT_INVLPGA\n");
866     goto unhandled_exit;
867     break;
868
869   case VMEXIT_TASK_SWITCH:
870     PrintDebug("Unhandled SVM Exit: VMEXIT_TASK_SWITCH\n");
871     goto unhandled_exit;
872     break;
873
874   case VMEXIT_FERR_FREEZE:
875     PrintDebug("Unhandled SVM Exit: VMEXIT_FERR_FREEZE\n");
876     goto unhandled_exit;
877     break;
878
879   case VMEXIT_SHUTDOWN:
880     PrintDebug("Unhandled SVM Exit: VMEXIT_SHUTDOWN\n");
881     goto unhandled_exit;
882     break;
883
884   case VMEXIT_VMRUN:
885     PrintDebug("Unhandled SVM Exit: VMEXIT_VMRUN\n");
886     goto unhandled_exit;
887     break;
888
889
890   case VMEXIT_STGI:
891     PrintDebug("Unhandled SVM Exit: VMEXIT_STGI\n");
892     goto unhandled_exit;
893     break;
894
895   case VMEXIT_CLGI:
896     PrintDebug("Unhandled SVM Exit: VMEXIT_CLGI\n");
897     goto unhandled_exit;
898     break;
899
900   case VMEXIT_SKINIT:
901     PrintDebug("Unhandled SVM Exit: VMEXIT_SKINIT\n");
902     goto unhandled_exit;
903     break;
904
905   case VMEXIT_RDTSCP:
906     PrintDebug("Unhandled SVM Exit: VMEXIT_RDTSCP\n");
907     goto unhandled_exit;
908     break;
909
910   case VMEXIT_ICEBP:
911     PrintDebug("Unhandled SVM Exit: VMEXIT_ICEBP\n");
912     goto unhandled_exit;
913     break;
914
915   case VMEXIT_MONITOR:
916     PrintDebug("Unhandled SVM Exit: VMEXIT_MONITOR\n");
917     goto unhandled_exit;
918     break;
919
920   case VMEXIT_MWAIT:
921     PrintDebug("Unhandled SVM Exit: VMEXIT_MWAIT\n");
922     goto unhandled_exit;
923     break;
924
925   case VMEXIT_MWAIT_CONDITIONAL:
926     PrintDebug("Unhandled SVM Exit: VMEXIT_MWAIT_CONDITIONAL\n");
927     goto unhandled_exit;
928     break;
929
930     
931   case VMEXIT_INVALID_VMCB:
932     PrintDebug("Unhandled SVM Exit: VMEXIT_INVALID_VMCB\n");
933     goto unhandled_exit;
934     break;
935
936
937   unhandled_exit:
938
939   default: {
940   
941     addr_t rip_addr;
942     char buf[15];
943     addr_t host_addr;
944
945
946     rip_addr = get_addr_linear(info, guest_state->rip, &(info->segments.cs));
947
948
949     PrintError("SVM Returned:(VMCB=%x)\n", info->vmm_data); 
950     PrintError("RIP: %x\n", guest_state->rip);
951     PrintError("RIP Linear: %x\n", rip_addr);
952     
953     PrintError("SVM Returned: Exit Code: %x\n",exit_code); 
954     
955     PrintError("io_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1));
956     PrintError("io_info1 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
957     
958     PrintError("io_info2 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info2));
959     PrintError("io_info2 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
960
961     
962
963     if (info->mem_mode == PHYSICAL_MEM) {
964       if (guest_pa_to_host_pa(info, guest_state->rip, &host_addr) == -1) {
965         PrintError("Could not translate guest_state->rip to host address\n");
966         return -1;
967       }
968     } else if (info->mem_mode == VIRTUAL_MEM) {
969       if (guest_va_to_host_pa(info, guest_state->rip, &host_addr) == -1) {
970         PrintError("Could not translate guest_state->rip to host address\n");
971         return -1;
972       }
973     } else {
974       PrintError("Invalid memory mode\n");
975       return -1;
976     }
977     
978     PrintError("Host Address of rip = 0x%x\n", host_addr);
979     
980     memset(buf, 0, 32);
981     
982     PrintError("Reading instruction stream in guest\n", rip_addr);
983     
984     if (info->mem_mode == PHYSICAL_MEM) {
985       read_guest_pa_memory(info, rip_addr-16, 32, buf);
986     } else {
987       read_guest_va_memory(info, rip_addr-16, 32, buf);
988     }
989     
990     PrintDebug("16 bytes before Rip\n");
991     PrintTraceMemDump(buf, 16);
992     PrintDebug("Rip onward\n");
993     PrintTraceMemDump(buf+16, 16);
994     
995     return -1;
996
997   }
998     break;
999
1000   }
1001   // END OF SWITCH (EXIT_CODE)
1002
1003
1004   // Update the low level state
1005
1006   if (intr_pending(info)) {
1007
1008     switch (get_intr_type(info)) {
1009     case EXTERNAL_IRQ: 
1010       {
1011         uint_t irq = get_intr_number(info);
1012
1013         // check to see if ==-1 (non exists)
1014
1015         /*      
1016           guest_ctrl->EVENTINJ.vector = irq;
1017           guest_ctrl->EVENTINJ.valid = 1;
1018           guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXTERNAL_INTR;
1019         */
1020         
1021         guest_ctrl->guest_ctrl.V_IRQ = 1;
1022         guest_ctrl->guest_ctrl.V_INTR_VECTOR = irq;
1023         guest_ctrl->guest_ctrl.V_IGN_TPR = 1;
1024         guest_ctrl->guest_ctrl.V_INTR_PRIO = 0xf;
1025 #ifdef DEBUG_INTERRUPTS
1026         PrintDebug("Injecting Interrupt %d (EIP=%x)\n", guest_ctrl->guest_ctrl.V_INTR_VECTOR, info->rip);
1027 #endif
1028         injecting_intr(info, irq, EXTERNAL_IRQ);
1029         
1030         break;
1031       }
1032     case NMI:
1033       guest_ctrl->EVENTINJ.type = SVM_INJECTION_NMI;
1034       break;
1035     case EXCEPTION:
1036       {
1037         uint_t excp = get_intr_number(info);
1038
1039         guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION;
1040         
1041         if (info->intr_state.excp_error_code_valid) {  //PAD
1042           guest_ctrl->EVENTINJ.error_code = info->intr_state.excp_error_code;
1043           guest_ctrl->EVENTINJ.ev = 1;
1044 #ifdef DEBUG_INTERRUPTS
1045           PrintDebug("Injecting error code %x\n", guest_ctrl->EVENTINJ.error_code);
1046 #endif
1047         }
1048         
1049         guest_ctrl->EVENTINJ.vector = excp;
1050         
1051         guest_ctrl->EVENTINJ.valid = 1;
1052 #ifdef DEBUG_INTERRUPTS
1053         PrintDebug("Injecting Interrupt %d (EIP=%x)\n", guest_ctrl->EVENTINJ.vector, info->rip);
1054 #endif
1055         injecting_intr(info, excp, EXCEPTION);
1056         break;
1057       }
1058     case SOFTWARE_INTR:
1059       guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
1060       break;
1061     case VIRTUAL_INTR:
1062       guest_ctrl->EVENTINJ.type = SVM_INJECTION_VIRTUAL_INTR;
1063       break;
1064
1065     case INVALID_INTR: 
1066     default:
1067       PrintError("Attempted to issue an invalid interrupt\n");
1068       return -1;
1069     }
1070
1071   } else {
1072 #ifdef DEBUG_INTERRUPTS
1073     PrintDebug("No interrupts/exceptions pending\n");
1074 #endif
1075   }
1076
1077   guest_state->cr0 = info->ctrl_regs.cr0;
1078   guest_state->cr2 = info->ctrl_regs.cr2;
1079   guest_state->cr3 = info->ctrl_regs.cr3;
1080   guest_state->cr4 = info->ctrl_regs.cr4;
1081   guest_state->dr6 = info->dbg_regs.dr6;
1082   guest_state->dr7 = info->dbg_regs.dr7;
1083   guest_ctrl->guest_ctrl.V_TPR = info->ctrl_regs.cr8 & 0xff;
1084   guest_state->rflags = info->ctrl_regs.rflags;
1085   guest_state->efer = info->ctrl_regs.efer;
1086
1087   guest_state->cpl = info->cpl;
1088
1089   guest_state->rax = info->vm_regs.rax;
1090   guest_state->rip = info->rip;
1091   guest_state->rsp = info->vm_regs.rsp;
1092
1093
1094   set_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
1095
1096   if (exit_code == VMEXIT_INTR) {
1097     //PrintDebug("INTR ret IP = %x\n", guest_state->rip);
1098   }
1099
1100   return 0;
1101 }
1102