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.


reworked the hash table implementation
[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     {
236 #ifdef DEBUG_EMULATOR
237       PrintDebug("DEBUG EXCEPTION\n");
238 #endif
239       if (info->run_state == VM_EMULATING) {
240         if (v3_emulation_exit_handler(info) == -1) {
241           return -1;
242         }
243       } else {
244         PrintError("VMMCALL with not emulator...\n");
245         return -1;
246       }
247       break;
248     } 
249
250
251   case VMEXIT_VMMCALL: 
252     {
253 #ifdef DEBUG_EMULATOR
254       PrintDebug("VMMCALL\n");
255 #endif
256       if (info->run_state == VM_EMULATING) {
257         if (v3_emulation_exit_handler(info) == -1) {
258           return -1;
259         }
260       } else {
261         PrintError("VMMCALL with not emulator...\n");
262         return -1;
263       }
264       break;
265     } 
266     
267
268
269   case VMEXIT_WBINVD: 
270     {
271 #ifdef DEBUG_EMULATOR
272       PrintDebug("WBINVD\n");
273 #endif
274       if (!handle_svm_wbinvd(info)) { 
275         return -1;
276       }
277       break;
278     }
279
280
281
282
283     /* Exits Following this line are NOT HANDLED */
284     /*=======================================================================*/
285
286   default: {
287
288     addr_t rip_addr;
289     char buf[15];
290     addr_t host_addr;
291
292     PrintDebug("Unhandled SVM Exit: %s\n", vmexit_code_to_str(exit_code));
293
294     rip_addr = get_addr_linear(info, guest_state->rip, &(info->segments.cs));
295
296
297     PrintError("SVM Returned:(VMCB=%x)\n", info->vmm_data); 
298     PrintError("RIP: %x\n", guest_state->rip);
299     PrintError("RIP Linear: %x\n", rip_addr);
300     
301     PrintError("SVM Returned: Exit Code: %x\n", exit_code); 
302     
303     PrintError("io_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1));
304     PrintError("io_info1 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
305     
306     PrintError("io_info2 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info2));
307     PrintError("io_info2 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
308
309     
310
311     if (info->mem_mode == PHYSICAL_MEM) {
312       if (guest_pa_to_host_pa(info, guest_state->rip, &host_addr) == -1) {
313         PrintError("Could not translate guest_state->rip to host address\n");
314         return -1;
315       }
316     } else if (info->mem_mode == VIRTUAL_MEM) {
317       if (guest_va_to_host_pa(info, guest_state->rip, &host_addr) == -1) {
318         PrintError("Could not translate guest_state->rip to host address\n");
319         return -1;
320       }
321     } else {
322       PrintError("Invalid memory mode\n");
323       return -1;
324     }
325     
326     PrintError("Host Address of rip = 0x%x\n", host_addr);
327     
328     memset(buf, 0, 32);
329     
330     PrintError("Reading instruction stream in guest\n", rip_addr);
331     
332     if (info->mem_mode == PHYSICAL_MEM) {
333       read_guest_pa_memory(info, rip_addr-16, 32, buf);
334     } else {
335       read_guest_va_memory(info, rip_addr-16, 32, buf);
336     }
337     
338     PrintDebug("16 bytes before Rip\n");
339     PrintTraceMemDump(buf, 16);
340     PrintDebug("Rip onward\n");
341     PrintTraceMemDump(buf+16, 16);
342     
343     return -1;
344
345   }
346     break;
347
348   }
349   // END OF SWITCH (EXIT_CODE)
350
351
352   // Update the low level state
353
354   if (intr_pending(info)) {
355
356     switch (get_intr_type(info)) {
357     case EXTERNAL_IRQ: 
358       {
359         uint_t irq = get_intr_number(info);
360
361         // check to see if ==-1 (non exists)
362
363         /*      
364           guest_ctrl->EVENTINJ.vector = irq;
365           guest_ctrl->EVENTINJ.valid = 1;
366           guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXTERNAL_INTR;
367         */
368         
369         guest_ctrl->guest_ctrl.V_IRQ = 1;
370         guest_ctrl->guest_ctrl.V_INTR_VECTOR = irq;
371         guest_ctrl->guest_ctrl.V_IGN_TPR = 1;
372         guest_ctrl->guest_ctrl.V_INTR_PRIO = 0xf;
373 #ifdef DEBUG_INTERRUPTS
374         PrintDebug("Injecting Interrupt %d (EIP=%x)\n", guest_ctrl->guest_ctrl.V_INTR_VECTOR, info->rip);
375 #endif
376         injecting_intr(info, irq, EXTERNAL_IRQ);
377         
378         break;
379       }
380     case NMI:
381       guest_ctrl->EVENTINJ.type = SVM_INJECTION_NMI;
382       break;
383     case EXCEPTION:
384       {
385         uint_t excp = get_intr_number(info);
386
387         guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION;
388         
389         if (info->intr_state.excp_error_code_valid) {  //PAD
390           guest_ctrl->EVENTINJ.error_code = info->intr_state.excp_error_code;
391           guest_ctrl->EVENTINJ.ev = 1;
392 #ifdef DEBUG_INTERRUPTS
393           PrintDebug("Injecting error code %x\n", guest_ctrl->EVENTINJ.error_code);
394 #endif
395         }
396         
397         guest_ctrl->EVENTINJ.vector = excp;
398         
399         guest_ctrl->EVENTINJ.valid = 1;
400 #ifdef DEBUG_INTERRUPTS
401         PrintDebug("Injecting Interrupt %d (EIP=%x)\n", guest_ctrl->EVENTINJ.vector, info->rip);
402 #endif
403         injecting_intr(info, excp, EXCEPTION);
404         break;
405       }
406     case SOFTWARE_INTR:
407       guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
408       break;
409     case VIRTUAL_INTR:
410       guest_ctrl->EVENTINJ.type = SVM_INJECTION_VIRTUAL_INTR;
411       break;
412
413     case INVALID_INTR: 
414     default:
415       PrintError("Attempted to issue an invalid interrupt\n");
416       return -1;
417     }
418
419   } else {
420 #ifdef DEBUG_INTERRUPTS
421     PrintDebug("No interrupts/exceptions pending\n");
422 #endif
423   }
424
425   guest_state->cr0 = info->ctrl_regs.cr0;
426   guest_state->cr2 = info->ctrl_regs.cr2;
427   guest_state->cr3 = info->ctrl_regs.cr3;
428   guest_state->cr4 = info->ctrl_regs.cr4;
429   guest_state->dr6 = info->dbg_regs.dr6;
430   guest_state->dr7 = info->dbg_regs.dr7;
431   guest_ctrl->guest_ctrl.V_TPR = info->ctrl_regs.cr8 & 0xff;
432   guest_state->rflags = info->ctrl_regs.rflags;
433   guest_state->efer = info->ctrl_regs.efer;
434
435   guest_state->cpl = info->cpl;
436
437   guest_state->rax = info->vm_regs.rax;
438   guest_state->rip = info->rip;
439   guest_state->rsp = info->vm_regs.rsp;
440
441
442   set_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
443
444   if (exit_code == VMEXIT_INTR) {
445     //PrintDebug("INTR ret IP = %x\n", guest_state->rip);
446   }
447
448   return 0;
449 }
450
451
452
453
454 const uchar_t * vmexit_code_to_str(uint_t exit_code) {
455   switch(exit_code) {
456   case VMEXIT_CR0_READ:
457     return VMEXIT_CR0_READ_STR;
458   case VMEXIT_CR1_READ:
459     return VMEXIT_CR1_READ_STR;
460   case VMEXIT_CR2_READ:
461     return VMEXIT_CR2_READ_STR;
462   case VMEXIT_CR3_READ:
463     return VMEXIT_CR3_READ_STR;
464   case VMEXIT_CR4_READ:
465     return VMEXIT_CR4_READ_STR;
466   case VMEXIT_CR5_READ:
467     return VMEXIT_CR5_READ_STR;
468   case VMEXIT_CR6_READ:
469     return VMEXIT_CR6_READ_STR;
470   case VMEXIT_CR7_READ:
471     return VMEXIT_CR7_READ_STR;
472   case VMEXIT_CR8_READ:
473     return VMEXIT_CR8_READ_STR;
474   case VMEXIT_CR9_READ:
475     return VMEXIT_CR9_READ_STR;
476   case VMEXIT_CR10_READ:
477     return VMEXIT_CR10_READ_STR;
478   case VMEXIT_CR11_READ:
479     return VMEXIT_CR11_READ_STR;
480   case VMEXIT_CR12_READ:
481     return VMEXIT_CR12_READ_STR;
482   case VMEXIT_CR13_READ:
483     return VMEXIT_CR13_READ_STR;
484   case VMEXIT_CR14_READ:
485     return VMEXIT_CR14_READ_STR;
486   case VMEXIT_CR15_READ:
487     return VMEXIT_CR15_READ_STR;
488   case VMEXIT_CR0_WRITE:
489     return VMEXIT_CR0_WRITE_STR;
490   case VMEXIT_CR1_WRITE:
491     return VMEXIT_CR1_WRITE_STR;
492   case VMEXIT_CR2_WRITE:
493     return VMEXIT_CR2_WRITE_STR;
494   case VMEXIT_CR3_WRITE:
495     return VMEXIT_CR3_WRITE_STR;
496   case VMEXIT_CR4_WRITE:
497     return VMEXIT_CR4_WRITE_STR;
498   case VMEXIT_CR5_WRITE:
499     return VMEXIT_CR5_WRITE_STR;
500   case VMEXIT_CR6_WRITE:
501     return VMEXIT_CR6_WRITE_STR;
502   case VMEXIT_CR7_WRITE:
503     return VMEXIT_CR7_WRITE_STR;
504   case VMEXIT_CR8_WRITE:
505     return VMEXIT_CR8_WRITE_STR;
506   case VMEXIT_CR9_WRITE:
507     return VMEXIT_CR9_WRITE_STR;
508   case VMEXIT_CR10_WRITE:
509     return VMEXIT_CR10_WRITE_STR;
510   case VMEXIT_CR11_WRITE:
511     return VMEXIT_CR11_WRITE_STR;
512   case VMEXIT_CR12_WRITE:
513     return VMEXIT_CR12_WRITE_STR;
514   case VMEXIT_CR13_WRITE:
515     return VMEXIT_CR13_WRITE_STR;
516   case VMEXIT_CR14_WRITE:
517     return VMEXIT_CR14_WRITE_STR;
518   case VMEXIT_CR15_WRITE:
519     return VMEXIT_CR15_WRITE_STR;
520   case VMEXIT_DR0_READ:
521     return VMEXIT_DR0_READ_STR;
522   case VMEXIT_DR1_READ:
523     return VMEXIT_DR1_READ_STR;
524   case VMEXIT_DR2_READ:
525     return VMEXIT_DR2_READ_STR;
526   case VMEXIT_DR3_READ:
527     return VMEXIT_DR3_READ_STR;
528   case VMEXIT_DR4_READ:
529     return VMEXIT_DR4_READ_STR;
530   case VMEXIT_DR5_READ:
531     return VMEXIT_DR5_READ_STR;
532   case VMEXIT_DR6_READ:
533     return VMEXIT_DR6_READ_STR;
534   case VMEXIT_DR7_READ:
535     return VMEXIT_DR7_READ_STR;
536   case VMEXIT_DR8_READ:
537     return VMEXIT_DR8_READ_STR;
538   case VMEXIT_DR9_READ:
539     return VMEXIT_DR9_READ_STR;
540   case VMEXIT_DR10_READ:
541     return VMEXIT_DR10_READ_STR;
542   case VMEXIT_DR11_READ:
543     return VMEXIT_DR11_READ_STR;
544   case VMEXIT_DR12_READ:
545     return VMEXIT_DR12_READ_STR;
546   case VMEXIT_DR13_READ:
547     return VMEXIT_DR13_READ_STR;
548   case VMEXIT_DR14_READ:
549     return VMEXIT_DR14_READ_STR;
550   case VMEXIT_DR15_READ:
551     return VMEXIT_DR15_READ_STR;
552   case VMEXIT_DR0_WRITE:
553     return VMEXIT_DR0_WRITE_STR;
554   case VMEXIT_DR1_WRITE:
555     return VMEXIT_DR1_WRITE_STR;
556   case VMEXIT_DR2_WRITE:
557     return VMEXIT_DR2_WRITE_STR;
558   case VMEXIT_DR3_WRITE:
559     return VMEXIT_DR3_WRITE_STR;
560   case VMEXIT_DR4_WRITE:
561     return VMEXIT_DR4_WRITE_STR;
562   case VMEXIT_DR5_WRITE:
563     return VMEXIT_DR5_WRITE_STR;
564   case VMEXIT_DR6_WRITE:
565     return VMEXIT_DR6_WRITE_STR;
566   case VMEXIT_DR7_WRITE:
567     return VMEXIT_DR7_WRITE_STR;
568   case VMEXIT_DR8_WRITE:
569     return VMEXIT_DR8_WRITE_STR;
570   case VMEXIT_DR9_WRITE:
571     return VMEXIT_DR9_WRITE_STR;
572   case VMEXIT_DR10_WRITE:
573     return VMEXIT_DR10_WRITE_STR;
574   case VMEXIT_DR11_WRITE:
575     return VMEXIT_DR11_WRITE_STR;
576   case VMEXIT_DR12_WRITE:
577     return VMEXIT_DR12_WRITE_STR;
578   case VMEXIT_DR13_WRITE:
579     return VMEXIT_DR13_WRITE_STR;
580   case VMEXIT_DR14_WRITE:
581     return VMEXIT_DR14_WRITE_STR;
582   case VMEXIT_DR15_WRITE:
583     return VMEXIT_DR15_WRITE_STR;
584   case VMEXIT_EXCP0:
585     return VMEXIT_EXCP0_STR;
586   case VMEXIT_EXCP1:
587     return VMEXIT_EXCP1_STR;
588   case VMEXIT_EXCP2:
589     return VMEXIT_EXCP2_STR;
590   case VMEXIT_EXCP3:
591     return VMEXIT_EXCP3_STR;
592   case VMEXIT_EXCP4:
593     return VMEXIT_EXCP4_STR;
594   case VMEXIT_EXCP5:
595     return VMEXIT_EXCP5_STR;
596   case VMEXIT_EXCP6:
597     return VMEXIT_EXCP6_STR;
598   case VMEXIT_EXCP7:
599     return VMEXIT_EXCP7_STR;
600   case VMEXIT_EXCP8:
601     return VMEXIT_EXCP8_STR;
602   case VMEXIT_EXCP9:
603     return VMEXIT_EXCP9_STR;
604   case VMEXIT_EXCP10:
605     return VMEXIT_EXCP10_STR;
606   case VMEXIT_EXCP11:
607     return VMEXIT_EXCP11_STR;
608   case VMEXIT_EXCP12:
609     return VMEXIT_EXCP12_STR;
610   case VMEXIT_EXCP13:
611     return VMEXIT_EXCP13_STR;
612   case VMEXIT_EXCP14:
613     return VMEXIT_EXCP14_STR;
614   case VMEXIT_EXCP15:
615     return VMEXIT_EXCP15_STR;
616   case VMEXIT_EXCP16:
617     return VMEXIT_EXCP16_STR;
618   case VMEXIT_EXCP17:
619     return VMEXIT_EXCP17_STR;
620   case VMEXIT_EXCP18:
621     return VMEXIT_EXCP18_STR;
622   case VMEXIT_EXCP19:
623     return VMEXIT_EXCP19_STR;
624   case VMEXIT_EXCP20:
625     return VMEXIT_EXCP20_STR;
626   case VMEXIT_EXCP21:
627     return VMEXIT_EXCP21_STR;
628   case VMEXIT_EXCP22:
629     return VMEXIT_EXCP22_STR;
630   case VMEXIT_EXCP23:
631     return VMEXIT_EXCP23_STR;
632   case VMEXIT_EXCP24:
633     return VMEXIT_EXCP24_STR;
634   case VMEXIT_EXCP25:
635     return VMEXIT_EXCP25_STR;
636   case VMEXIT_EXCP26:
637     return VMEXIT_EXCP26_STR;
638   case VMEXIT_EXCP27:
639     return VMEXIT_EXCP27_STR;
640   case VMEXIT_EXCP28:
641     return VMEXIT_EXCP28_STR;
642   case VMEXIT_EXCP29:
643     return VMEXIT_EXCP29_STR;
644   case VMEXIT_EXCP30:
645     return VMEXIT_EXCP30_STR;
646   case VMEXIT_EXCP31:
647     return VMEXIT_EXCP31_STR;
648   case VMEXIT_INTR:
649     return VMEXIT_INTR_STR;
650   case VMEXIT_NMI:
651     return VMEXIT_NMI_STR;
652   case VMEXIT_SMI:
653     return VMEXIT_SMI_STR;
654   case VMEXIT_INIT:
655     return VMEXIT_INIT_STR;
656   case VMEXIT_VINITR:
657     return VMEXIT_VINITR_STR;
658   case VMEXIT_CR0_SEL_WRITE:
659     return VMEXIT_CR0_SEL_WRITE_STR;
660   case VMEXIT_IDTR_READ:
661     return VMEXIT_IDTR_READ_STR;
662   case VMEXIT_GDTR_READ:
663     return VMEXIT_GDTR_READ_STR;
664   case VMEXIT_LDTR_READ:
665     return VMEXIT_LDTR_READ_STR;
666   case VMEXIT_TR_READ:
667     return VMEXIT_TR_READ_STR;
668   case VMEXIT_IDTR_WRITE:
669     return VMEXIT_IDTR_WRITE_STR;
670   case VMEXIT_GDTR_WRITE:
671     return VMEXIT_GDTR_WRITE_STR;
672   case VMEXIT_LDTR_WRITE:
673     return VMEXIT_LDTR_WRITE_STR;
674   case VMEXIT_TR_WRITE:
675     return VMEXIT_TR_WRITE_STR;
676   case VMEXIT_RDTSC:
677     return VMEXIT_RDTSC_STR;
678   case VMEXIT_RDPMC:
679     return VMEXIT_RDPMC_STR;
680   case VMEXIT_PUSHF:
681     return VMEXIT_PUSHF_STR;
682   case VMEXIT_POPF:
683     return VMEXIT_POPF_STR;
684   case VMEXIT_CPUID:
685     return VMEXIT_CPUID_STR;
686   case VMEXIT_RSM:
687     return VMEXIT_RSM_STR;
688   case VMEXIT_IRET:
689     return VMEXIT_IRET_STR;
690   case VMEXIT_SWINT:
691     return VMEXIT_SWINT_STR;
692   case VMEXIT_INVD:
693     return VMEXIT_INVD_STR;
694   case VMEXIT_PAUSE:
695     return VMEXIT_PAUSE_STR;
696   case VMEXIT_HLT:
697     return VMEXIT_HLT_STR;
698   case VMEXIT_INVLPG:
699     return VMEXIT_INVLPG_STR;
700   case VMEXIT_INVLPGA:
701     return VMEXIT_INVLPGA_STR;
702   case VMEXIT_IOIO:
703     return VMEXIT_IOIO_STR;
704   case VMEXIT_MSR:
705     return VMEXIT_MSR_STR;
706   case VMEXIT_TASK_SWITCH:
707     return VMEXIT_TASK_SWITCH_STR;
708   case VMEXIT_FERR_FREEZE:
709     return VMEXIT_FERR_FREEZE_STR;
710   case VMEXIT_SHUTDOWN:
711     return VMEXIT_SHUTDOWN_STR;
712   case VMEXIT_VMRUN:
713     return VMEXIT_VMRUN_STR;
714   case VMEXIT_VMMCALL:
715     return VMEXIT_VMMCALL_STR;
716   case VMEXIT_VMLOAD:
717     return VMEXIT_VMLOAD_STR;
718   case VMEXIT_VMSAVE:
719     return VMEXIT_VMSAVE_STR;
720   case VMEXIT_STGI:
721     return VMEXIT_STGI_STR;
722   case VMEXIT_CLGI:
723     return VMEXIT_CLGI_STR;
724   case VMEXIT_SKINIT:
725     return VMEXIT_SKINIT_STR;
726   case VMEXIT_RDTSCP:
727     return VMEXIT_RDTSCP_STR;
728   case VMEXIT_ICEBP:
729     return VMEXIT_ICEBP_STR;
730   case VMEXIT_WBINVD:
731     return VMEXIT_WBINVD_STR;
732   case VMEXIT_MONITOR:
733     return VMEXIT_MONITOR_STR;
734   case VMEXIT_MWAIT:
735     return VMEXIT_MWAIT_STR;
736   case VMEXIT_MWAIT_CONDITIONAL:
737     return VMEXIT_MWAIT_CONDITIONAL_STR;
738   case VMEXIT_NPF:
739     return VMEXIT_NPF_STR;
740   case VMEXIT_INVALID_VMCB:
741     return VMEXIT_INVALID_VMCB_STR;
742   }
743   return NULL;
744 }