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.


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