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.


cleaned up handler code
[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
456   switch(exit_code) {
457   case VMEXIT_CR0_READ:
458     return VMEXIT_CR0_READ_STR;
459   case VMEXIT_CR1_READ:
460     return VMEXIT_CR1_READ_STR;
461   case VMEXIT_CR2_READ:
462     return VMEXIT_CR2_READ_STR;
463   case VMEXIT_CR3_READ:
464     return VMEXIT_CR3_READ_STR;
465   case VMEXIT_CR4_READ:
466     return VMEXIT_CR4_READ_STR;
467   case VMEXIT_CR5_READ:
468     return VMEXIT_CR5_READ_STR;
469   case VMEXIT_CR6_READ:
470     return VMEXIT_CR6_READ_STR;
471   case VMEXIT_CR7_READ:
472     return VMEXIT_CR7_READ_STR;
473   case VMEXIT_CR8_READ:
474     return VMEXIT_CR8_READ_STR;
475   case VMEXIT_CR9_READ:
476     return VMEXIT_CR9_READ_STR;
477   case VMEXIT_CR10_READ:
478     return VMEXIT_CR10_READ_STR;
479   case VMEXIT_CR11_READ:
480     return VMEXIT_CR11_READ_STR;
481   case VMEXIT_CR12_READ:
482     return VMEXIT_CR12_READ_STR;
483   case VMEXIT_CR13_READ:
484     return VMEXIT_CR13_READ_STR;
485   case VMEXIT_CR14_READ:
486     return VMEXIT_CR14_READ_STR;
487   case VMEXIT_CR15_READ:
488     return VMEXIT_CR15_READ_STR;
489   case VMEXIT_CR0_WRITE:
490     return VMEXIT_CR0_WRITE_STR;
491   case VMEXIT_CR1_WRITE:
492     return VMEXIT_CR1_WRITE_STR;
493   case VMEXIT_CR2_WRITE:
494     return VMEXIT_CR2_WRITE_STR;
495   case VMEXIT_CR3_WRITE:
496     return VMEXIT_CR3_WRITE_STR;
497   case VMEXIT_CR4_WRITE:
498     return VMEXIT_CR4_WRITE_STR;
499   case VMEXIT_CR5_WRITE:
500     return VMEXIT_CR5_WRITE_STR;
501   case VMEXIT_CR6_WRITE:
502     return VMEXIT_CR6_WRITE_STR;
503   case VMEXIT_CR7_WRITE:
504     return VMEXIT_CR7_WRITE_STR;
505   case VMEXIT_CR8_WRITE:
506     return VMEXIT_CR8_WRITE_STR;
507   case VMEXIT_CR9_WRITE:
508     return VMEXIT_CR9_WRITE_STR;
509   case VMEXIT_CR10_WRITE:
510     return VMEXIT_CR10_WRITE_STR;
511   case VMEXIT_CR11_WRITE:
512     return VMEXIT_CR11_WRITE_STR;
513   case VMEXIT_CR12_WRITE:
514     return VMEXIT_CR12_WRITE_STR;
515   case VMEXIT_CR13_WRITE:
516     return VMEXIT_CR13_WRITE_STR;
517   case VMEXIT_CR14_WRITE:
518     return VMEXIT_CR14_WRITE_STR;
519   case VMEXIT_CR15_WRITE:
520     return VMEXIT_CR15_WRITE_STR;
521   case VMEXIT_DR0_READ:
522     return VMEXIT_DR0_READ_STR;
523   case VMEXIT_DR1_READ:
524     return VMEXIT_DR1_READ_STR;
525   case VMEXIT_DR2_READ:
526     return VMEXIT_DR2_READ_STR;
527   case VMEXIT_DR3_READ:
528     return VMEXIT_DR3_READ_STR;
529   case VMEXIT_DR4_READ:
530     return VMEXIT_DR4_READ_STR;
531   case VMEXIT_DR5_READ:
532     return VMEXIT_DR5_READ_STR;
533   case VMEXIT_DR6_READ:
534     return VMEXIT_DR6_READ_STR;
535   case VMEXIT_DR7_READ:
536     return VMEXIT_DR7_READ_STR;
537   case VMEXIT_DR8_READ:
538     return VMEXIT_DR8_READ_STR;
539   case VMEXIT_DR9_READ:
540     return VMEXIT_DR9_READ_STR;
541   case VMEXIT_DR10_READ:
542     return VMEXIT_DR10_READ_STR;
543   case VMEXIT_DR11_READ:
544     return VMEXIT_DR11_READ_STR;
545   case VMEXIT_DR12_READ:
546     return VMEXIT_DR12_READ_STR;
547   case VMEXIT_DR13_READ:
548     return VMEXIT_DR13_READ_STR;
549   case VMEXIT_DR14_READ:
550     return VMEXIT_DR14_READ_STR;
551   case VMEXIT_DR15_READ:
552     return VMEXIT_DR15_READ_STR;
553   case VMEXIT_DR0_WRITE:
554     return VMEXIT_DR0_WRITE_STR;
555   case VMEXIT_DR1_WRITE:
556     return VMEXIT_DR1_WRITE_STR;
557   case VMEXIT_DR2_WRITE:
558     return VMEXIT_DR2_WRITE_STR;
559   case VMEXIT_DR3_WRITE:
560     return VMEXIT_DR3_WRITE_STR;
561   case VMEXIT_DR4_WRITE:
562     return VMEXIT_DR4_WRITE_STR;
563   case VMEXIT_DR5_WRITE:
564     return VMEXIT_DR5_WRITE_STR;
565   case VMEXIT_DR6_WRITE:
566     return VMEXIT_DR6_WRITE_STR;
567   case VMEXIT_DR7_WRITE:
568     return VMEXIT_DR7_WRITE_STR;
569   case VMEXIT_DR8_WRITE:
570     return VMEXIT_DR8_WRITE_STR;
571   case VMEXIT_DR9_WRITE:
572     return VMEXIT_DR9_WRITE_STR;
573   case VMEXIT_DR10_WRITE:
574     return VMEXIT_DR10_WRITE_STR;
575   case VMEXIT_DR11_WRITE:
576     return VMEXIT_DR11_WRITE_STR;
577   case VMEXIT_DR12_WRITE:
578     return VMEXIT_DR12_WRITE_STR;
579   case VMEXIT_DR13_WRITE:
580     return VMEXIT_DR13_WRITE_STR;
581   case VMEXIT_DR14_WRITE:
582     return VMEXIT_DR14_WRITE_STR;
583   case VMEXIT_DR15_WRITE:
584     return VMEXIT_DR15_WRITE_STR;
585   case VMEXIT_EXCP0:
586     return VMEXIT_EXCP0_STR;
587   case VMEXIT_EXCP1:
588     return VMEXIT_EXCP1_STR;
589   case VMEXIT_EXCP2:
590     return VMEXIT_EXCP2_STR;
591   case VMEXIT_EXCP3:
592     return VMEXIT_EXCP3_STR;
593   case VMEXIT_EXCP4:
594     return VMEXIT_EXCP4_STR;
595   case VMEXIT_EXCP5:
596     return VMEXIT_EXCP5_STR;
597   case VMEXIT_EXCP6:
598     return VMEXIT_EXCP6_STR;
599   case VMEXIT_EXCP7:
600     return VMEXIT_EXCP7_STR;
601   case VMEXIT_EXCP8:
602     return VMEXIT_EXCP8_STR;
603   case VMEXIT_EXCP9:
604     return VMEXIT_EXCP9_STR;
605   case VMEXIT_EXCP10:
606     return VMEXIT_EXCP10_STR;
607   case VMEXIT_EXCP11:
608     return VMEXIT_EXCP11_STR;
609   case VMEXIT_EXCP12:
610     return VMEXIT_EXCP12_STR;
611   case VMEXIT_EXCP13:
612     return VMEXIT_EXCP13_STR;
613   case VMEXIT_EXCP14:
614     return VMEXIT_EXCP14_STR;
615   case VMEXIT_EXCP15:
616     return VMEXIT_EXCP15_STR;
617   case VMEXIT_EXCP16:
618     return VMEXIT_EXCP16_STR;
619   case VMEXIT_EXCP17:
620     return VMEXIT_EXCP17_STR;
621   case VMEXIT_EXCP18:
622     return VMEXIT_EXCP18_STR;
623   case VMEXIT_EXCP19:
624     return VMEXIT_EXCP19_STR;
625   case VMEXIT_EXCP20:
626     return VMEXIT_EXCP20_STR;
627   case VMEXIT_EXCP21:
628     return VMEXIT_EXCP21_STR;
629   case VMEXIT_EXCP22:
630     return VMEXIT_EXCP22_STR;
631   case VMEXIT_EXCP23:
632     return VMEXIT_EXCP23_STR;
633   case VMEXIT_EXCP24:
634     return VMEXIT_EXCP24_STR;
635   case VMEXIT_EXCP25:
636     return VMEXIT_EXCP25_STR;
637   case VMEXIT_EXCP26:
638     return VMEXIT_EXCP26_STR;
639   case VMEXIT_EXCP27:
640     return VMEXIT_EXCP27_STR;
641   case VMEXIT_EXCP28:
642     return VMEXIT_EXCP28_STR;
643   case VMEXIT_EXCP29:
644     return VMEXIT_EXCP29_STR;
645   case VMEXIT_EXCP30:
646     return VMEXIT_EXCP30_STR;
647   case VMEXIT_EXCP31:
648     return VMEXIT_EXCP31_STR;
649   case VMEXIT_INTR:
650     return VMEXIT_INTR_STR;
651   case VMEXIT_NMI:
652     return VMEXIT_NMI_STR;
653   case VMEXIT_SMI:
654     return VMEXIT_SMI_STR;
655   case VMEXIT_INIT:
656     return VMEXIT_INIT_STR;
657   case VMEXIT_VINITR:
658     return VMEXIT_VINITR_STR;
659   case VMEXIT_CR0_SEL_WRITE:
660     return VMEXIT_CR0_SEL_WRITE_STR;
661   case VMEXIT_IDTR_READ:
662     return VMEXIT_IDTR_READ_STR;
663   case VMEXIT_GDTR_READ:
664     return VMEXIT_GDTR_READ_STR;
665   case VMEXIT_LDTR_READ:
666     return VMEXIT_LDTR_READ_STR;
667   case VMEXIT_TR_READ:
668     return VMEXIT_TR_READ_STR;
669   case VMEXIT_IDTR_WRITE:
670     return VMEXIT_IDTR_WRITE_STR;
671   case VMEXIT_GDTR_WRITE:
672     return VMEXIT_GDTR_WRITE_STR;
673   case VMEXIT_LDTR_WRITE:
674     return VMEXIT_LDTR_WRITE_STR;
675   case VMEXIT_TR_WRITE:
676     return VMEXIT_TR_WRITE_STR;
677   case VMEXIT_RDTSC:
678     return VMEXIT_RDTSC_STR;
679   case VMEXIT_RDPMC:
680     return VMEXIT_RDPMC_STR;
681   case VMEXIT_PUSHF:
682     return VMEXIT_PUSHF_STR;
683   case VMEXIT_POPF:
684     return VMEXIT_POPF_STR;
685   case VMEXIT_CPUID:
686     return VMEXIT_CPUID_STR;
687   case VMEXIT_RSM:
688     return VMEXIT_RSM_STR;
689   case VMEXIT_IRET:
690     return VMEXIT_IRET_STR;
691   case VMEXIT_SWINT:
692     return VMEXIT_SWINT_STR;
693   case VMEXIT_INVD:
694     return VMEXIT_INVD_STR;
695   case VMEXIT_PAUSE:
696     return VMEXIT_PAUSE_STR;
697   case VMEXIT_HLT:
698     return VMEXIT_HLT_STR;
699   case VMEXIT_INVLPG:
700     return VMEXIT_INVLPG_STR;
701   case VMEXIT_INVLPGA:
702     return VMEXIT_INVLPGA_STR;
703   case VMEXIT_IOIO:
704     return VMEXIT_IOIO_STR;
705   case VMEXIT_MSR:
706     return VMEXIT_MSR_STR;
707   case VMEXIT_TASK_SWITCH:
708     return VMEXIT_TASK_SWITCH_STR;
709   case VMEXIT_FERR_FREEZE:
710     return VMEXIT_FERR_FREEZE_STR;
711   case VMEXIT_SHUTDOWN:
712     return VMEXIT_SHUTDOWN_STR;
713   case VMEXIT_VMRUN:
714     return VMEXIT_VMRUN_STR;
715   case VMEXIT_VMMCALL:
716     return VMEXIT_VMMCALL_STR;
717   case VMEXIT_VMLOAD:
718     return VMEXIT_VMLOAD_STR;
719   case VMEXIT_VMSAVE:
720     return VMEXIT_VMSAVE_STR;
721   case VMEXIT_STGI:
722     return VMEXIT_STGI_STR;
723   case VMEXIT_CLGI:
724     return VMEXIT_CLGI_STR;
725   case VMEXIT_SKINIT:
726     return VMEXIT_SKINIT_STR;
727   case VMEXIT_RDTSCP:
728     return VMEXIT_RDTSCP_STR;
729   case VMEXIT_ICEBP:
730     return VMEXIT_ICEBP_STR;
731   case VMEXIT_WBINVD:
732     return VMEXIT_WBINVD_STR;
733   case VMEXIT_MONITOR:
734     return VMEXIT_MONITOR_STR;
735   case VMEXIT_MWAIT:
736     return VMEXIT_MWAIT_STR;
737   case VMEXIT_MWAIT_CONDITIONAL:
738     return VMEXIT_MWAIT_CONDITIONAL_STR;
739   case VMEXIT_NPF:
740     return VMEXIT_NPF_STR;
741   case VMEXIT_INVALID_VMCB:
742     return VMEXIT_INVALID_VMCB_STR;
743   }
744   return NULL;
745 }