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.


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