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.


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