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.


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