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