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.


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