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.


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