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.


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