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.


more namespace changes
[palacios.git] / palacios / src / palacios / svm_handler.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 #include <palacios/svm_handler.h>
22 #include <palacios/vmm.h>
23 #include <palacios/vm_guest_mem.h>
24 #include <palacios/vmm_decoder.h>
25 #include <palacios/vmm_ctrl_regs.h>
26 #include <palacios/svm_io.h>
27 #include <palacios/svm_halt.h>
28 #include <palacios/svm_pause.h>
29 #include <palacios/svm_wbinvd.h>
30 #include <palacios/vmm_intr.h>
31 #include <palacios/vmm_emulator.h>
32
33
34
35
36 static const uchar_t * vmexit_code_to_str(uint_t exit_code);
37
38
39 int v3_handle_svm_exit(struct guest_info * info) {
40   vmcb_ctrl_t * guest_ctrl = 0;
41   vmcb_saved_state_t * guest_state = 0;
42   ulong_t exit_code = 0;
43   
44   guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
45   guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
46   
47
48   // Update the high level state 
49   info->rip = guest_state->rip;
50   info->vm_regs.rsp = guest_state->rsp;
51   info->vm_regs.rax = guest_state->rax;
52
53   info->cpl = guest_state->cpl;
54
55
56   info->ctrl_regs.cr0 = guest_state->cr0;
57   info->ctrl_regs.cr2 = guest_state->cr2;
58   info->ctrl_regs.cr3 = guest_state->cr3;
59   info->ctrl_regs.cr4 = guest_state->cr4;
60   info->dbg_regs.dr6 = guest_state->dr6;
61   info->dbg_regs.dr7 = guest_state->dr7;
62   info->ctrl_regs.cr8 = guest_ctrl->guest_ctrl.V_TPR;
63   info->ctrl_regs.rflags = guest_state->rflags;
64   info->ctrl_regs.efer = guest_state->efer;
65
66   get_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
67   info->cpu_mode = v3_get_cpu_mode(info);
68   info->mem_mode = v3_get_mem_mode(info);
69
70
71   exit_code = guest_ctrl->exit_code;
72  
73
74   // Disable printing io exits due to bochs debug messages
75   //if (!((exit_code == VMEXIT_IOIO) && ((ushort_t)(guest_ctrl->exit_info1 >> 16) == 0x402))) {
76
77
78   //  PrintDebug("SVM Returned: Exit Code: 0x%x \t\t(tsc=%ul)\n",exit_code, (uint_t)info->time_state.guest_tsc); 
79   
80   if ((0) && (exit_code < 0x4f)) {
81     uchar_t instr[32];
82     int ret;
83     // Dump out the instr stream
84
85     //PrintDebug("RIP: %x\n", guest_state->rip);
86     PrintDebug("RIP Linear: %x\n", get_addr_linear(info, info->rip, &(info->segments.cs)));
87
88     // OK, now we will read the instruction
89     // The only difference between PROTECTED and PROTECTED_PG is whether we read
90     // from guest_pa or guest_va
91     if (info->mem_mode == PHYSICAL_MEM) { 
92       // The real rip address is actually a combination of the rip + CS base 
93       ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 32, instr);
94     } else { 
95       ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 32, instr);
96     }
97     
98     if (ret != 32) {
99       // I think we should inject a GPF into the guest
100       PrintDebug("Could not read instruction (ret=%d)\n", ret);
101     } else {
102
103       PrintDebug("Instr Stream:\n");
104       PrintTraceMemDump(instr, 32);
105     }
106   }
107
108
109     //  }
110   // PrintDebugVMCB((vmcb_t*)(info->vmm_data));
111
112
113   // PrintDebug("SVM Returned:(VMCB=%x)\n", info->vmm_data); 
114   //PrintDebug("RIP: %x\n", guest_state->rip);
115
116   
117   //PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); 
118
119   switch (exit_code) {
120
121   case VMEXIT_IOIO: {
122     struct svm_io_info * io_info = (struct svm_io_info *)&(guest_ctrl->exit_info1);
123     
124     if (io_info->type == 0) {
125       if (io_info->str) {
126         if (v3_handle_svm_io_outs(info) == -1 ) {
127           return -1;
128         }
129       } else {
130         if (v3_handle_svm_io_out(info) == -1) {
131           return -1;
132         }
133       }
134     } else {
135       if (io_info->str) {
136         if (v3_handle_svm_io_ins(info) == -1) {
137           return -1;
138         }
139       } else {
140         if (v3_handle_svm_io_in(info) == -1) {
141           return -1;
142         }
143       }
144     }
145   }
146     break;
147
148
149   case  VMEXIT_CR0_WRITE: {
150 #ifdef DEBUG_CTRL_REGS
151     PrintDebug("CR0 Write\n");
152 #endif
153     if (v3_handle_cr0_write(info) == -1) {
154       return -1;
155     }
156   } 
157     break;
158
159   case VMEXIT_CR0_READ: {
160 #ifdef DEBUG_CTRL_REGS
161     PrintDebug("CR0 Read\n");
162 #endif
163     if (v3_handle_cr0_read(info) == -1) {
164       return -1;
165     }
166   } 
167     break;
168
169   case VMEXIT_CR3_WRITE: {
170 #ifdef DEBUG_CTRL_REGS
171     PrintDebug("CR3 Write\n");
172 #endif
173     if (v3_handle_cr3_write(info) == -1) {
174       return -1;
175     }    
176   } 
177     break;
178
179   case  VMEXIT_CR3_READ: {
180 #ifdef DEBUG_CTRL_REGS
181     PrintDebug("CR3 Read\n");
182 #endif
183     if (v3_handle_cr3_read(info) == -1) {
184       return -1;
185     }
186   }
187     break;
188
189   case VMEXIT_EXCP14: {
190     addr_t fault_addr = guest_ctrl->exit_info2;
191     pf_error_t * error_code = (pf_error_t *)&(guest_ctrl->exit_info1);
192 #ifdef DEBUG_SHADOW_PAGING
193     PrintDebug("PageFault at %x (error=%d)\n", fault_addr, *error_code);
194 #endif
195     if (info->shdw_pg_mode == SHADOW_PAGING) {
196       if (v3_handle_shadow_pagefault(info, fault_addr, *error_code) == -1) {
197         return -1;
198       }
199     } else {
200       PrintError("Page fault in un implemented paging mode\n");
201       return -1;
202     }
203   } 
204     break;
205
206   case VMEXIT_NPF: {
207     PrintError("Currently unhandled Nested Page Fault\n");
208     return -1;
209     
210   } 
211     break;
212
213   case VMEXIT_INVLPG: {
214     if (info->shdw_pg_mode == SHADOW_PAGING) {
215 #ifdef DEBUG_SHADOW_PAGING
216       PrintDebug("Invlpg\n");
217 #endif
218       if (v3_handle_shadow_invlpg(info) == -1) {
219         return -1;
220       }
221     }
222    
223     /*
224       (exit_code == VMEXIT_INVLPGA)   || 
225     */
226     
227   } 
228     break;
229
230   case VMEXIT_INTR: { 
231     
232     // handled by interrupt dispatch earlier
233
234   } 
235     break;
236     
237   case VMEXIT_SMI: {
238     
239     //   handle_svm_smi(info); // ignored for now
240
241   } 
242     break;
243
244   case VMEXIT_HLT: {
245 #ifdef DEBUG_HALT
246     PrintDebug("Guest halted\n");
247 #endif
248     if (v3_handle_svm_halt(info) == -1) {
249       return -1;
250     }
251   } 
252     break;
253
254   case VMEXIT_PAUSE: {
255     //PrintDebug("Guest paused\n");
256     if (v3_handle_svm_pause(info) == -1) { 
257       return -1;
258     }
259   } 
260     break;
261
262   case VMEXIT_EXCP1: 
263     {
264 #ifdef DEBUG_EMULATOR
265       PrintDebug("DEBUG EXCEPTION\n");
266 #endif
267       if (info->run_state == VM_EMULATING) {
268         if (v3_emulation_exit_handler(info) == -1) {
269           return -1;
270         }
271       } else {
272         PrintError("VMMCALL with not emulator...\n");
273         return -1;
274       }
275       break;
276     } 
277
278
279   case VMEXIT_VMMCALL: 
280     {
281 #ifdef DEBUG_EMULATOR
282       PrintDebug("VMMCALL\n");
283 #endif
284       if (info->run_state == VM_EMULATING) {
285         if (v3_emulation_exit_handler(info) == -1) {
286           return -1;
287         }
288       } else {
289         /*
290         ulong_t tsc_spread = 0;
291         ullong_t exit_tsc = 0;
292
293         ulong_t rax = (ulong_t)info->vm_regs.rbx;
294         ulong_t rdx = (ulong_t)info->vm_regs.rcx;
295
296         *(ulong_t *)(&exit_tsc) = rax;
297         *(((ulong_t *)(&exit_tsc)) + 1) = rdx; 
298
299         tsc_spread = info->exit_tsc - exit_tsc;
300
301         PrintError("VMMCALL tsc diff = %lu\n",tsc_spread); 
302         info->rip += 3;
303         */
304         PrintError("VMMCALL with not emulator...\n");
305         return -1;
306       }
307       break;
308     } 
309     
310
311
312   case VMEXIT_WBINVD: 
313     {
314 #ifdef DEBUG_EMULATOR
315       PrintDebug("WBINVD\n");
316 #endif
317       if (!v3_handle_svm_wbinvd(info)) { 
318         return -1;
319       }
320       break;
321     }
322
323
324
325
326     /* Exits Following this line are NOT HANDLED */
327     /*=======================================================================*/
328
329   default: {
330
331     addr_t rip_addr;
332     uchar_t buf[15];
333     addr_t host_addr;
334
335     PrintDebug("Unhandled SVM Exit: %s\n", vmexit_code_to_str(exit_code));
336
337     rip_addr = get_addr_linear(info, guest_state->rip, &(info->segments.cs));
338
339
340     PrintError("SVM Returned:(VMCB=%x)\n", info->vmm_data); 
341     PrintError("RIP: %x\n", guest_state->rip);
342     PrintError("RIP Linear: %x\n", rip_addr);
343     
344     PrintError("SVM Returned: Exit Code: %x\n", exit_code); 
345     
346     PrintError("io_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1));
347     PrintError("io_info1 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
348     
349     PrintError("io_info2 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info2));
350     PrintError("io_info2 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
351
352     
353
354     if (info->mem_mode == PHYSICAL_MEM) {
355       if (guest_pa_to_host_pa(info, guest_state->rip, &host_addr) == -1) {
356         PrintError("Could not translate guest_state->rip to host address\n");
357         return -1;
358       }
359     } else if (info->mem_mode == VIRTUAL_MEM) {
360       if (guest_va_to_host_pa(info, guest_state->rip, &host_addr) == -1) {
361         PrintError("Could not translate guest_state->rip to host address\n");
362         return -1;
363       }
364     } else {
365       PrintError("Invalid memory mode\n");
366       return -1;
367     }
368     
369     PrintError("Host Address of rip = 0x%x\n", host_addr);
370     
371     memset(buf, 0, 32);
372     
373     PrintError("Reading instruction stream in guest\n", rip_addr);
374     
375     if (info->mem_mode == PHYSICAL_MEM) {
376       read_guest_pa_memory(info, rip_addr-16, 32, buf);
377     } else {
378       read_guest_va_memory(info, rip_addr-16, 32, buf);
379     }
380     
381     PrintDebug("16 bytes before Rip\n");
382     PrintTraceMemDump(buf, 16);
383     PrintDebug("Rip onward\n");
384     PrintTraceMemDump(buf+16, 16);
385     
386     return -1;
387
388   }
389     break;
390
391   }
392   // END OF SWITCH (EXIT_CODE)
393
394
395   // Update the low level state
396
397   if (v3_intr_pending(info)) {
398
399     switch (v3_get_intr_type(info)) {
400     case EXTERNAL_IRQ: 
401       {
402         uint_t irq = v3_get_intr_number(info);
403
404         // check to see if ==-1 (non exists)
405
406         /*      
407           guest_ctrl->EVENTINJ.vector = irq;
408           guest_ctrl->EVENTINJ.valid = 1;
409           guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXTERNAL_INTR;
410         */
411         
412         guest_ctrl->guest_ctrl.V_IRQ = 1;
413         guest_ctrl->guest_ctrl.V_INTR_VECTOR = irq;
414         guest_ctrl->guest_ctrl.V_IGN_TPR = 1;
415         guest_ctrl->guest_ctrl.V_INTR_PRIO = 0xf;
416 #ifdef DEBUG_INTERRUPTS
417         PrintDebug("Injecting Interrupt %d (EIP=%x)\n", guest_ctrl->guest_ctrl.V_INTR_VECTOR, info->rip);
418 #endif
419         v3_injecting_intr(info, irq, EXTERNAL_IRQ);
420         
421         break;
422       }
423     case NMI:
424       guest_ctrl->EVENTINJ.type = SVM_INJECTION_NMI;
425       break;
426     case EXCEPTION:
427       {
428         uint_t excp = v3_get_intr_number(info);
429
430         guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION;
431         
432         if (info->intr_state.excp_error_code_valid) {  //PAD
433           guest_ctrl->EVENTINJ.error_code = info->intr_state.excp_error_code;
434           guest_ctrl->EVENTINJ.ev = 1;
435 #ifdef DEBUG_INTERRUPTS
436           PrintDebug("Injecting error code %x\n", guest_ctrl->EVENTINJ.error_code);
437 #endif
438         }
439         
440         guest_ctrl->EVENTINJ.vector = excp;
441         
442         guest_ctrl->EVENTINJ.valid = 1;
443 #ifdef DEBUG_INTERRUPTS
444         PrintDebug("Injecting Interrupt %d (EIP=%x)\n", guest_ctrl->EVENTINJ.vector, info->rip);
445 #endif
446         v3_injecting_intr(info, excp, EXCEPTION);
447         break;
448       }
449     case SOFTWARE_INTR:
450       guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
451       break;
452     case VIRTUAL_INTR:
453       guest_ctrl->EVENTINJ.type = SVM_INJECTION_VIRTUAL_INTR;
454       break;
455
456     case INVALID_INTR: 
457     default:
458       PrintError("Attempted to issue an invalid interrupt\n");
459       return -1;
460     }
461
462   } else {
463 #ifdef DEBUG_INTERRUPTS
464     PrintDebug("No interrupts/exceptions pending\n");
465 #endif
466   }
467
468   guest_state->cr0 = info->ctrl_regs.cr0;
469   guest_state->cr2 = info->ctrl_regs.cr2;
470   guest_state->cr3 = info->ctrl_regs.cr3;
471   guest_state->cr4 = info->ctrl_regs.cr4;
472   guest_state->dr6 = info->dbg_regs.dr6;
473   guest_state->dr7 = info->dbg_regs.dr7;
474   guest_ctrl->guest_ctrl.V_TPR = info->ctrl_regs.cr8 & 0xff;
475   guest_state->rflags = info->ctrl_regs.rflags;
476   guest_state->efer = info->ctrl_regs.efer;
477
478   guest_state->cpl = info->cpl;
479
480   guest_state->rax = info->vm_regs.rax;
481   guest_state->rip = info->rip;
482   guest_state->rsp = info->vm_regs.rsp;
483
484
485   set_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
486
487   if (exit_code == VMEXIT_INTR) {
488     //PrintDebug("INTR ret IP = %x\n", guest_state->rip);
489   }
490
491   return 0;
492 }
493
494
495 static const uchar_t VMEXIT_CR0_READ_STR[] = "VMEXIT_CR0_READ";
496 static const uchar_t VMEXIT_CR1_READ_STR[] = "VMEXIT_CR1_READ";
497 static const uchar_t VMEXIT_CR2_READ_STR[] = "VMEXIT_CR2_READ";
498 static const uchar_t VMEXIT_CR3_READ_STR[] = "VMEXIT_CR3_READ";
499 static const uchar_t VMEXIT_CR4_READ_STR[] = "VMEXIT_CR4_READ";
500 static const uchar_t VMEXIT_CR5_READ_STR[] = "VMEXIT_CR5_READ";
501 static const uchar_t VMEXIT_CR6_READ_STR[] = "VMEXIT_CR6_READ";
502 static const uchar_t VMEXIT_CR7_READ_STR[] = "VMEXIT_CR7_READ";
503 static const uchar_t VMEXIT_CR8_READ_STR[] = "VMEXIT_CR8_READ";
504 static const uchar_t VMEXIT_CR9_READ_STR[] = "VMEXIT_CR9_READ";
505 static const uchar_t VMEXIT_CR10_READ_STR[] = "VMEXIT_CR10_READ";
506 static const uchar_t VMEXIT_CR11_READ_STR[] = "VMEXIT_CR11_READ";
507 static const uchar_t VMEXIT_CR12_READ_STR[] = "VMEXIT_CR12_READ";
508 static const uchar_t VMEXIT_CR13_READ_STR[] = "VMEXIT_CR13_READ";
509 static const uchar_t VMEXIT_CR14_READ_STR[] = "VMEXIT_CR14_READ";
510 static const uchar_t VMEXIT_CR15_READ_STR[] = "VMEXIT_CR15_READ";
511 static const uchar_t VMEXIT_CR0_WRITE_STR[] = "VMEXIT_CR0_WRITE";
512 static const uchar_t VMEXIT_CR1_WRITE_STR[] = "VMEXIT_CR1_WRITE";
513 static const uchar_t VMEXIT_CR2_WRITE_STR[] = "VMEXIT_CR2_WRITE";
514 static const uchar_t VMEXIT_CR3_WRITE_STR[] = "VMEXIT_CR3_WRITE";
515 static const uchar_t VMEXIT_CR4_WRITE_STR[] = "VMEXIT_CR4_WRITE";
516 static const uchar_t VMEXIT_CR5_WRITE_STR[] = "VMEXIT_CR5_WRITE";
517 static const uchar_t VMEXIT_CR6_WRITE_STR[] = "VMEXIT_CR6_WRITE";
518 static const uchar_t VMEXIT_CR7_WRITE_STR[] = "VMEXIT_CR7_WRITE";
519 static const uchar_t VMEXIT_CR8_WRITE_STR[] = "VMEXIT_CR8_WRITE";
520 static const uchar_t VMEXIT_CR9_WRITE_STR[] = "VMEXIT_CR9_WRITE";
521 static const uchar_t VMEXIT_CR10_WRITE_STR[] = "VMEXIT_CR10_WRITE";
522 static const uchar_t VMEXIT_CR11_WRITE_STR[] = "VMEXIT_CR11_WRITE";
523 static const uchar_t VMEXIT_CR12_WRITE_STR[] = "VMEXIT_CR12_WRITE";
524 static const uchar_t VMEXIT_CR13_WRITE_STR[] = "VMEXIT_CR13_WRITE";
525 static const uchar_t VMEXIT_CR14_WRITE_STR[] = "VMEXIT_CR14_WRITE";
526 static const uchar_t VMEXIT_CR15_WRITE_STR[] = "VMEXIT_CR15_WRITE";
527 static const uchar_t VMEXIT_DR0_READ_STR[] = "VMEXIT_DR0_READ";
528 static const uchar_t VMEXIT_DR1_READ_STR[] = "VMEXIT_DR1_READ";
529 static const uchar_t VMEXIT_DR2_READ_STR[] = "VMEXIT_DR2_READ";
530 static const uchar_t VMEXIT_DR3_READ_STR[] = "VMEXIT_DR3_READ";
531 static const uchar_t VMEXIT_DR4_READ_STR[] = "VMEXIT_DR4_READ";
532 static const uchar_t VMEXIT_DR5_READ_STR[] = "VMEXIT_DR5_READ";
533 static const uchar_t VMEXIT_DR6_READ_STR[] = "VMEXIT_DR6_READ";
534 static const uchar_t VMEXIT_DR7_READ_STR[] = "VMEXIT_DR7_READ";
535 static const uchar_t VMEXIT_DR8_READ_STR[] = "VMEXIT_DR8_READ";
536 static const uchar_t VMEXIT_DR9_READ_STR[] = "VMEXIT_DR9_READ";
537 static const uchar_t VMEXIT_DR10_READ_STR[] = "VMEXIT_DR10_READ";
538 static const uchar_t VMEXIT_DR11_READ_STR[] = "VMEXIT_DR11_READ";
539 static const uchar_t VMEXIT_DR12_READ_STR[] = "VMEXIT_DR12_READ";
540 static const uchar_t VMEXIT_DR13_READ_STR[] = "VMEXIT_DR13_READ";
541 static const uchar_t VMEXIT_DR14_READ_STR[] = "VMEXIT_DR14_READ";
542 static const uchar_t VMEXIT_DR15_READ_STR[] = "VMEXIT_DR15_READ";
543 static const uchar_t VMEXIT_DR0_WRITE_STR[] = "VMEXIT_DR0_WRITE";
544 static const uchar_t VMEXIT_DR1_WRITE_STR[] = "VMEXIT_DR1_WRITE";
545 static const uchar_t VMEXIT_DR2_WRITE_STR[] = "VMEXIT_DR2_WRITE";
546 static const uchar_t VMEXIT_DR3_WRITE_STR[] = "VMEXIT_DR3_WRITE";
547 static const uchar_t VMEXIT_DR4_WRITE_STR[] = "VMEXIT_DR4_WRITE";
548 static const uchar_t VMEXIT_DR5_WRITE_STR[] = "VMEXIT_DR5_WRITE";
549 static const uchar_t VMEXIT_DR6_WRITE_STR[] = "VMEXIT_DR6_WRITE";
550 static const uchar_t VMEXIT_DR7_WRITE_STR[] = "VMEXIT_DR7_WRITE";
551 static const uchar_t VMEXIT_DR8_WRITE_STR[] = "VMEXIT_DR8_WRITE";
552 static const uchar_t VMEXIT_DR9_WRITE_STR[] = "VMEXIT_DR9_WRITE";
553 static const uchar_t VMEXIT_DR10_WRITE_STR[] = "VMEXIT_DR10_WRITE";
554 static const uchar_t VMEXIT_DR11_WRITE_STR[] = "VMEXIT_DR11_WRITE";
555 static const uchar_t VMEXIT_DR12_WRITE_STR[] = "VMEXIT_DR12_WRITE";
556 static const uchar_t VMEXIT_DR13_WRITE_STR[] = "VMEXIT_DR13_WRITE";
557 static const uchar_t VMEXIT_DR14_WRITE_STR[] = "VMEXIT_DR14_WRITE";
558 static const uchar_t VMEXIT_DR15_WRITE_STR[] = "VMEXIT_DR15_WRITE";
559 static const uchar_t VMEXIT_EXCP0_STR[] = "VMEXIT_EXCP0";
560 static const uchar_t VMEXIT_EXCP1_STR[] = "VMEXIT_EXCP1";
561 static const uchar_t VMEXIT_EXCP2_STR[] = "VMEXIT_EXCP2";
562 static const uchar_t VMEXIT_EXCP3_STR[] = "VMEXIT_EXCP3";
563 static const uchar_t VMEXIT_EXCP4_STR[] = "VMEXIT_EXCP4";
564 static const uchar_t VMEXIT_EXCP5_STR[] = "VMEXIT_EXCP5";
565 static const uchar_t VMEXIT_EXCP6_STR[] = "VMEXIT_EXCP6";
566 static const uchar_t VMEXIT_EXCP7_STR[] = "VMEXIT_EXCP7";
567 static const uchar_t VMEXIT_EXCP8_STR[] = "VMEXIT_EXCP8";
568 static const uchar_t VMEXIT_EXCP9_STR[] = "VMEXIT_EXCP9";
569 static const uchar_t VMEXIT_EXCP10_STR[] = "VMEXIT_EXCP10";
570 static const uchar_t VMEXIT_EXCP11_STR[] = "VMEXIT_EXCP11";
571 static const uchar_t VMEXIT_EXCP12_STR[] = "VMEXIT_EXCP12";
572 static const uchar_t VMEXIT_EXCP13_STR[] = "VMEXIT_EXCP13";
573 static const uchar_t VMEXIT_EXCP14_STR[] = "VMEXIT_EXCP14";
574 static const uchar_t VMEXIT_EXCP15_STR[] = "VMEXIT_EXCP15";
575 static const uchar_t VMEXIT_EXCP16_STR[] = "VMEXIT_EXCP16";
576 static const uchar_t VMEXIT_EXCP17_STR[] = "VMEXIT_EXCP17";
577 static const uchar_t VMEXIT_EXCP18_STR[] = "VMEXIT_EXCP18";
578 static const uchar_t VMEXIT_EXCP19_STR[] = "VMEXIT_EXCP19";
579 static const uchar_t VMEXIT_EXCP20_STR[] = "VMEXIT_EXCP20";
580 static const uchar_t VMEXIT_EXCP21_STR[] = "VMEXIT_EXCP21";
581 static const uchar_t VMEXIT_EXCP22_STR[] = "VMEXIT_EXCP22";
582 static const uchar_t VMEXIT_EXCP23_STR[] = "VMEXIT_EXCP23";
583 static const uchar_t VMEXIT_EXCP24_STR[] = "VMEXIT_EXCP24";
584 static const uchar_t VMEXIT_EXCP25_STR[] = "VMEXIT_EXCP25";
585 static const uchar_t VMEXIT_EXCP26_STR[] = "VMEXIT_EXCP26";
586 static const uchar_t VMEXIT_EXCP27_STR[] = "VMEXIT_EXCP27";
587 static const uchar_t VMEXIT_EXCP28_STR[] = "VMEXIT_EXCP28";
588 static const uchar_t VMEXIT_EXCP29_STR[] = "VMEXIT_EXCP29";
589 static const uchar_t VMEXIT_EXCP30_STR[] = "VMEXIT_EXCP30";
590 static const uchar_t VMEXIT_EXCP31_STR[] = "VMEXIT_EXCP31";
591 static const uchar_t VMEXIT_INTR_STR[] = "VMEXIT_INTR";
592 static const uchar_t VMEXIT_NMI_STR[] = "VMEXIT_NMI";
593 static const uchar_t VMEXIT_SMI_STR[] = "VMEXIT_SMI";
594 static const uchar_t VMEXIT_INIT_STR[] = "VMEXIT_INIT";
595 static const uchar_t VMEXIT_VINITR_STR[] = "VMEXIT_VINITR";
596 static const uchar_t VMEXIT_CR0_SEL_WRITE_STR[] = "VMEXIT_CR0_SEL_WRITE";
597 static const uchar_t VMEXIT_IDTR_READ_STR[] = "VMEXIT_IDTR_READ";
598 static const uchar_t VMEXIT_GDTR_READ_STR[] = "VMEXIT_GDTR_READ";
599 static const uchar_t VMEXIT_LDTR_READ_STR[] = "VMEXIT_LDTR_READ";
600 static const uchar_t VMEXIT_TR_READ_STR[] = "VMEXIT_TR_READ";
601 static const uchar_t VMEXIT_IDTR_WRITE_STR[] = "VMEXIT_IDTR_WRITE";
602 static const uchar_t VMEXIT_GDTR_WRITE_STR[] = "VMEXIT_GDTR_WRITE";
603 static const uchar_t VMEXIT_LDTR_WRITE_STR[] = "VMEXIT_LDTR_WRITE";
604 static const uchar_t VMEXIT_TR_WRITE_STR[] = "VMEXIT_TR_WRITE";
605 static const uchar_t VMEXIT_RDTSC_STR[] = "VMEXIT_RDTSC";
606 static const uchar_t VMEXIT_RDPMC_STR[] = "VMEXIT_RDPMC";
607 static const uchar_t VMEXIT_PUSHF_STR[] = "VMEXIT_PUSHF";
608 static const uchar_t VMEXIT_POPF_STR[] = "VMEXIT_POPF";
609 static const uchar_t VMEXIT_CPUID_STR[] = "VMEXIT_CPUID";
610 static const uchar_t VMEXIT_RSM_STR[] = "VMEXIT_RSM";
611 static const uchar_t VMEXIT_IRET_STR[] = "VMEXIT_IRET";
612 static const uchar_t VMEXIT_SWINT_STR[] = "VMEXIT_SWINT";
613 static const uchar_t VMEXIT_INVD_STR[] = "VMEXIT_INVD";
614 static const uchar_t VMEXIT_PAUSE_STR[] = "VMEXIT_PAUSE";
615 static const uchar_t VMEXIT_HLT_STR[] = "VMEXIT_HLT";
616 static const uchar_t VMEXIT_INVLPG_STR[] = "VMEXIT_INVLPG";
617 static const uchar_t VMEXIT_INVLPGA_STR[] = "VMEXIT_INVLPGA";
618 static const uchar_t VMEXIT_IOIO_STR[] = "VMEXIT_IOIO";
619 static const uchar_t VMEXIT_MSR_STR[] = "VMEXIT_MSR";
620 static const uchar_t VMEXIT_TASK_SWITCH_STR[] = "VMEXIT_TASK_SWITCH";
621 static const uchar_t VMEXIT_FERR_FREEZE_STR[] = "VMEXIT_FERR_FREEZE";
622 static const uchar_t VMEXIT_SHUTDOWN_STR[] = "VMEXIT_SHUTDOWN";
623 static const uchar_t VMEXIT_VMRUN_STR[] = "VMEXIT_VMRUN";
624 static const uchar_t VMEXIT_VMMCALL_STR[] = "VMEXIT_VMMCALL";
625 static const uchar_t VMEXIT_VMLOAD_STR[] = "VMEXIT_VMLOAD";
626 static const uchar_t VMEXIT_VMSAVE_STR[] = "VMEXIT_VMSAVE";
627 static const uchar_t VMEXIT_STGI_STR[] = "VMEXIT_STGI";
628 static const uchar_t VMEXIT_CLGI_STR[] = "VMEXIT_CLGI";
629 static const uchar_t VMEXIT_SKINIT_STR[] = "VMEXIT_SKINIT";
630 static const uchar_t VMEXIT_RDTSCP_STR[] = "VMEXIT_RDTSCP";
631 static const uchar_t VMEXIT_ICEBP_STR[] = "VMEXIT_ICEBP";
632 static const uchar_t VMEXIT_WBINVD_STR[] = "VMEXIT_WBINVD";
633 static const uchar_t VMEXIT_MONITOR_STR[] = "VMEXIT_MONITOR";
634 static const uchar_t VMEXIT_MWAIT_STR[] = "VMEXIT_MWAIT";
635 static const uchar_t VMEXIT_MWAIT_CONDITIONAL_STR[] = "VMEXIT_MWAIT_CONDITIONAL";
636 static const uchar_t VMEXIT_NPF_STR[] = "VMEXIT_NPF";
637 static const uchar_t VMEXIT_INVALID_VMCB_STR[] = "VMEXIT_INVALID_VMCB";
638
639
640
641 const uchar_t * vmexit_code_to_str(uint_t exit_code) {
642   switch(exit_code) {
643   case VMEXIT_CR0_READ:
644     return VMEXIT_CR0_READ_STR;
645   case VMEXIT_CR1_READ:
646     return VMEXIT_CR1_READ_STR;
647   case VMEXIT_CR2_READ:
648     return VMEXIT_CR2_READ_STR;
649   case VMEXIT_CR3_READ:
650     return VMEXIT_CR3_READ_STR;
651   case VMEXIT_CR4_READ:
652     return VMEXIT_CR4_READ_STR;
653   case VMEXIT_CR5_READ:
654     return VMEXIT_CR5_READ_STR;
655   case VMEXIT_CR6_READ:
656     return VMEXIT_CR6_READ_STR;
657   case VMEXIT_CR7_READ:
658     return VMEXIT_CR7_READ_STR;
659   case VMEXIT_CR8_READ:
660     return VMEXIT_CR8_READ_STR;
661   case VMEXIT_CR9_READ:
662     return VMEXIT_CR9_READ_STR;
663   case VMEXIT_CR10_READ:
664     return VMEXIT_CR10_READ_STR;
665   case VMEXIT_CR11_READ:
666     return VMEXIT_CR11_READ_STR;
667   case VMEXIT_CR12_READ:
668     return VMEXIT_CR12_READ_STR;
669   case VMEXIT_CR13_READ:
670     return VMEXIT_CR13_READ_STR;
671   case VMEXIT_CR14_READ:
672     return VMEXIT_CR14_READ_STR;
673   case VMEXIT_CR15_READ:
674     return VMEXIT_CR15_READ_STR;
675   case VMEXIT_CR0_WRITE:
676     return VMEXIT_CR0_WRITE_STR;
677   case VMEXIT_CR1_WRITE:
678     return VMEXIT_CR1_WRITE_STR;
679   case VMEXIT_CR2_WRITE:
680     return VMEXIT_CR2_WRITE_STR;
681   case VMEXIT_CR3_WRITE:
682     return VMEXIT_CR3_WRITE_STR;
683   case VMEXIT_CR4_WRITE:
684     return VMEXIT_CR4_WRITE_STR;
685   case VMEXIT_CR5_WRITE:
686     return VMEXIT_CR5_WRITE_STR;
687   case VMEXIT_CR6_WRITE:
688     return VMEXIT_CR6_WRITE_STR;
689   case VMEXIT_CR7_WRITE:
690     return VMEXIT_CR7_WRITE_STR;
691   case VMEXIT_CR8_WRITE:
692     return VMEXIT_CR8_WRITE_STR;
693   case VMEXIT_CR9_WRITE:
694     return VMEXIT_CR9_WRITE_STR;
695   case VMEXIT_CR10_WRITE:
696     return VMEXIT_CR10_WRITE_STR;
697   case VMEXIT_CR11_WRITE:
698     return VMEXIT_CR11_WRITE_STR;
699   case VMEXIT_CR12_WRITE:
700     return VMEXIT_CR12_WRITE_STR;
701   case VMEXIT_CR13_WRITE:
702     return VMEXIT_CR13_WRITE_STR;
703   case VMEXIT_CR14_WRITE:
704     return VMEXIT_CR14_WRITE_STR;
705   case VMEXIT_CR15_WRITE:
706     return VMEXIT_CR15_WRITE_STR;
707   case VMEXIT_DR0_READ:
708     return VMEXIT_DR0_READ_STR;
709   case VMEXIT_DR1_READ:
710     return VMEXIT_DR1_READ_STR;
711   case VMEXIT_DR2_READ:
712     return VMEXIT_DR2_READ_STR;
713   case VMEXIT_DR3_READ:
714     return VMEXIT_DR3_READ_STR;
715   case VMEXIT_DR4_READ:
716     return VMEXIT_DR4_READ_STR;
717   case VMEXIT_DR5_READ:
718     return VMEXIT_DR5_READ_STR;
719   case VMEXIT_DR6_READ:
720     return VMEXIT_DR6_READ_STR;
721   case VMEXIT_DR7_READ:
722     return VMEXIT_DR7_READ_STR;
723   case VMEXIT_DR8_READ:
724     return VMEXIT_DR8_READ_STR;
725   case VMEXIT_DR9_READ:
726     return VMEXIT_DR9_READ_STR;
727   case VMEXIT_DR10_READ:
728     return VMEXIT_DR10_READ_STR;
729   case VMEXIT_DR11_READ:
730     return VMEXIT_DR11_READ_STR;
731   case VMEXIT_DR12_READ:
732     return VMEXIT_DR12_READ_STR;
733   case VMEXIT_DR13_READ:
734     return VMEXIT_DR13_READ_STR;
735   case VMEXIT_DR14_READ:
736     return VMEXIT_DR14_READ_STR;
737   case VMEXIT_DR15_READ:
738     return VMEXIT_DR15_READ_STR;
739   case VMEXIT_DR0_WRITE:
740     return VMEXIT_DR0_WRITE_STR;
741   case VMEXIT_DR1_WRITE:
742     return VMEXIT_DR1_WRITE_STR;
743   case VMEXIT_DR2_WRITE:
744     return VMEXIT_DR2_WRITE_STR;
745   case VMEXIT_DR3_WRITE:
746     return VMEXIT_DR3_WRITE_STR;
747   case VMEXIT_DR4_WRITE:
748     return VMEXIT_DR4_WRITE_STR;
749   case VMEXIT_DR5_WRITE:
750     return VMEXIT_DR5_WRITE_STR;
751   case VMEXIT_DR6_WRITE:
752     return VMEXIT_DR6_WRITE_STR;
753   case VMEXIT_DR7_WRITE:
754     return VMEXIT_DR7_WRITE_STR;
755   case VMEXIT_DR8_WRITE:
756     return VMEXIT_DR8_WRITE_STR;
757   case VMEXIT_DR9_WRITE:
758     return VMEXIT_DR9_WRITE_STR;
759   case VMEXIT_DR10_WRITE:
760     return VMEXIT_DR10_WRITE_STR;
761   case VMEXIT_DR11_WRITE:
762     return VMEXIT_DR11_WRITE_STR;
763   case VMEXIT_DR12_WRITE:
764     return VMEXIT_DR12_WRITE_STR;
765   case VMEXIT_DR13_WRITE:
766     return VMEXIT_DR13_WRITE_STR;
767   case VMEXIT_DR14_WRITE:
768     return VMEXIT_DR14_WRITE_STR;
769   case VMEXIT_DR15_WRITE:
770     return VMEXIT_DR15_WRITE_STR;
771   case VMEXIT_EXCP0:
772     return VMEXIT_EXCP0_STR;
773   case VMEXIT_EXCP1:
774     return VMEXIT_EXCP1_STR;
775   case VMEXIT_EXCP2:
776     return VMEXIT_EXCP2_STR;
777   case VMEXIT_EXCP3:
778     return VMEXIT_EXCP3_STR;
779   case VMEXIT_EXCP4:
780     return VMEXIT_EXCP4_STR;
781   case VMEXIT_EXCP5:
782     return VMEXIT_EXCP5_STR;
783   case VMEXIT_EXCP6:
784     return VMEXIT_EXCP6_STR;
785   case VMEXIT_EXCP7:
786     return VMEXIT_EXCP7_STR;
787   case VMEXIT_EXCP8:
788     return VMEXIT_EXCP8_STR;
789   case VMEXIT_EXCP9:
790     return VMEXIT_EXCP9_STR;
791   case VMEXIT_EXCP10:
792     return VMEXIT_EXCP10_STR;
793   case VMEXIT_EXCP11:
794     return VMEXIT_EXCP11_STR;
795   case VMEXIT_EXCP12:
796     return VMEXIT_EXCP12_STR;
797   case VMEXIT_EXCP13:
798     return VMEXIT_EXCP13_STR;
799   case VMEXIT_EXCP14:
800     return VMEXIT_EXCP14_STR;
801   case VMEXIT_EXCP15:
802     return VMEXIT_EXCP15_STR;
803   case VMEXIT_EXCP16:
804     return VMEXIT_EXCP16_STR;
805   case VMEXIT_EXCP17:
806     return VMEXIT_EXCP17_STR;
807   case VMEXIT_EXCP18:
808     return VMEXIT_EXCP18_STR;
809   case VMEXIT_EXCP19:
810     return VMEXIT_EXCP19_STR;
811   case VMEXIT_EXCP20:
812     return VMEXIT_EXCP20_STR;
813   case VMEXIT_EXCP21:
814     return VMEXIT_EXCP21_STR;
815   case VMEXIT_EXCP22:
816     return VMEXIT_EXCP22_STR;
817   case VMEXIT_EXCP23:
818     return VMEXIT_EXCP23_STR;
819   case VMEXIT_EXCP24:
820     return VMEXIT_EXCP24_STR;
821   case VMEXIT_EXCP25:
822     return VMEXIT_EXCP25_STR;
823   case VMEXIT_EXCP26:
824     return VMEXIT_EXCP26_STR;
825   case VMEXIT_EXCP27:
826     return VMEXIT_EXCP27_STR;
827   case VMEXIT_EXCP28:
828     return VMEXIT_EXCP28_STR;
829   case VMEXIT_EXCP29:
830     return VMEXIT_EXCP29_STR;
831   case VMEXIT_EXCP30:
832     return VMEXIT_EXCP30_STR;
833   case VMEXIT_EXCP31:
834     return VMEXIT_EXCP31_STR;
835   case VMEXIT_INTR:
836     return VMEXIT_INTR_STR;
837   case VMEXIT_NMI:
838     return VMEXIT_NMI_STR;
839   case VMEXIT_SMI:
840     return VMEXIT_SMI_STR;
841   case VMEXIT_INIT:
842     return VMEXIT_INIT_STR;
843   case VMEXIT_VINITR:
844     return VMEXIT_VINITR_STR;
845   case VMEXIT_CR0_SEL_WRITE:
846     return VMEXIT_CR0_SEL_WRITE_STR;
847   case VMEXIT_IDTR_READ:
848     return VMEXIT_IDTR_READ_STR;
849   case VMEXIT_GDTR_READ:
850     return VMEXIT_GDTR_READ_STR;
851   case VMEXIT_LDTR_READ:
852     return VMEXIT_LDTR_READ_STR;
853   case VMEXIT_TR_READ:
854     return VMEXIT_TR_READ_STR;
855   case VMEXIT_IDTR_WRITE:
856     return VMEXIT_IDTR_WRITE_STR;
857   case VMEXIT_GDTR_WRITE:
858     return VMEXIT_GDTR_WRITE_STR;
859   case VMEXIT_LDTR_WRITE:
860     return VMEXIT_LDTR_WRITE_STR;
861   case VMEXIT_TR_WRITE:
862     return VMEXIT_TR_WRITE_STR;
863   case VMEXIT_RDTSC:
864     return VMEXIT_RDTSC_STR;
865   case VMEXIT_RDPMC:
866     return VMEXIT_RDPMC_STR;
867   case VMEXIT_PUSHF:
868     return VMEXIT_PUSHF_STR;
869   case VMEXIT_POPF:
870     return VMEXIT_POPF_STR;
871   case VMEXIT_CPUID:
872     return VMEXIT_CPUID_STR;
873   case VMEXIT_RSM:
874     return VMEXIT_RSM_STR;
875   case VMEXIT_IRET:
876     return VMEXIT_IRET_STR;
877   case VMEXIT_SWINT:
878     return VMEXIT_SWINT_STR;
879   case VMEXIT_INVD:
880     return VMEXIT_INVD_STR;
881   case VMEXIT_PAUSE:
882     return VMEXIT_PAUSE_STR;
883   case VMEXIT_HLT:
884     return VMEXIT_HLT_STR;
885   case VMEXIT_INVLPG:
886     return VMEXIT_INVLPG_STR;
887   case VMEXIT_INVLPGA:
888     return VMEXIT_INVLPGA_STR;
889   case VMEXIT_IOIO:
890     return VMEXIT_IOIO_STR;
891   case VMEXIT_MSR:
892     return VMEXIT_MSR_STR;
893   case VMEXIT_TASK_SWITCH:
894     return VMEXIT_TASK_SWITCH_STR;
895   case VMEXIT_FERR_FREEZE:
896     return VMEXIT_FERR_FREEZE_STR;
897   case VMEXIT_SHUTDOWN:
898     return VMEXIT_SHUTDOWN_STR;
899   case VMEXIT_VMRUN:
900     return VMEXIT_VMRUN_STR;
901   case VMEXIT_VMMCALL:
902     return VMEXIT_VMMCALL_STR;
903   case VMEXIT_VMLOAD:
904     return VMEXIT_VMLOAD_STR;
905   case VMEXIT_VMSAVE:
906     return VMEXIT_VMSAVE_STR;
907   case VMEXIT_STGI:
908     return VMEXIT_STGI_STR;
909   case VMEXIT_CLGI:
910     return VMEXIT_CLGI_STR;
911   case VMEXIT_SKINIT:
912     return VMEXIT_SKINIT_STR;
913   case VMEXIT_RDTSCP:
914     return VMEXIT_RDTSCP_STR;
915   case VMEXIT_ICEBP:
916     return VMEXIT_ICEBP_STR;
917   case VMEXIT_WBINVD:
918     return VMEXIT_WBINVD_STR;
919   case VMEXIT_MONITOR:
920     return VMEXIT_MONITOR_STR;
921   case VMEXIT_MWAIT:
922     return VMEXIT_MWAIT_STR;
923   case VMEXIT_MWAIT_CONDITIONAL:
924     return VMEXIT_MWAIT_CONDITIONAL_STR;
925   case VMEXIT_NPF:
926     return VMEXIT_NPF_STR;
927   case VMEXIT_INVALID_VMCB:
928     return VMEXIT_INVALID_VMCB_STR;
929   }
930   return NULL;
931 }