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.


b270907c95822e0a194b375e58367f8bfd28f1fb
[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 <gears/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
60     //    PrintDebug("SVM Returned: Exit Code: %p\n", (void *)exit_code); 
61
62     switch (exit_code) {
63         case SVM_EXIT_IOIO: {
64             struct svm_io_info * io_info = (struct svm_io_info *)&(exit_info1);
65
66             if (io_info->type == 0) {
67                 if (io_info->str) {
68
69                     if (v3_handle_svm_io_outs(info, io_info) == -1 ) {
70                         return -1;
71                     }
72                 } else {
73                     if (v3_handle_svm_io_out(info, io_info) == -1) {
74                         return -1;
75                     }
76                 }
77
78             } else {
79
80                 if (io_info->str) {
81                     if (v3_handle_svm_io_ins(info, io_info) == -1) {
82                         return -1;
83                     }
84                 } else {
85                     if (v3_handle_svm_io_in(info, io_info) == -1) {
86                         return -1;
87                     }
88                 }
89             }
90
91             info->rip = exit_info2;
92
93             break;
94         }
95         case SVM_EXIT_MSR:
96
97             if (exit_info1 == 0) {
98                 if (v3_handle_msr_read(info) == -1) {
99                     return -1;
100                 }
101             } else if (exit_info1 == 1) {
102                 if (v3_handle_msr_write(info) == -1) {
103                     return -1;
104                 }
105             } else {
106                 PrintError("Invalid MSR Operation\n");
107                 return -1;
108             }
109                 
110             break;
111
112         case SVM_EXIT_CPUID:
113             if (v3_handle_cpuid(info) == -1) {
114                 PrintError("Error handling CPUID\n");
115                 return -1;
116             }
117
118             break;
119         case SVM_EXIT_CR0_WRITE: 
120 #ifdef V3_CONFIG_DEBUG_CTRL_REGS
121             PrintDebug("CR0 Write\n");
122 #endif
123             if (v3_handle_cr0_write(info) == -1) {
124                 return -1;
125             }
126             break;
127         case SVM_EXIT_CR0_READ: 
128 #ifdef V3_CONFIG_DEBUG_CTRL_REGS
129             PrintDebug("CR0 Read\n");
130 #endif
131             if (v3_handle_cr0_read(info) == -1) {
132                 return -1;
133             }
134             break;
135         case SVM_EXIT_CR3_WRITE: 
136 #ifdef V3_CONFIG_DEBUG_CTRL_REGS
137             PrintDebug("CR3 Write\n");
138 #endif
139             if (v3_handle_cr3_write(info) == -1) {
140                 return -1;
141             }    
142
143             break;
144         case  SVM_EXIT_CR3_READ: 
145 #ifdef V3_CONFIG_DEBUG_CTRL_REGS
146             PrintDebug("CR3 Read\n");
147 #endif
148             if (v3_handle_cr3_read(info) == -1) {
149                 return -1;
150             }
151             break;
152         case SVM_EXIT_CR4_WRITE: 
153 #ifdef V3_CONFIG_DEBUG_CTRL_REGS
154             PrintDebug("CR4 Write\n");
155 #endif
156             if (v3_handle_cr4_write(info) == -1) {
157                 return -1;
158             }    
159             break;
160         case  SVM_EXIT_CR4_READ: 
161 #ifdef V3_CONFIG_DEBUG_CTRL_REGS
162             PrintDebug("CR4 Read\n");
163 #endif
164             if (v3_handle_cr4_read(info) == -1) {
165                 return -1;
166             }
167             break;
168         case SVM_EXIT_EXCP14: {
169             addr_t fault_addr = exit_info2;
170             pf_error_t * error_code = (pf_error_t *)&(exit_info1);
171 #ifdef V3_CONFIG_DEBUG_SHADOW_PAGING
172             PrintDebug("PageFault at %p (error=%d)\n", 
173                        (void *)fault_addr, *(uint_t *)error_code);
174 #endif
175             if (info->shdw_pg_mode == SHADOW_PAGING) {
176                 if (v3_handle_shadow_pagefault(info, fault_addr, *error_code) == -1) {
177                     return -1;
178                 }
179             } else {
180                 PrintError("Page fault in un implemented paging mode\n");
181                 return -1;
182             }
183             break;
184         } 
185         case SVM_EXIT_NPF: {
186             addr_t fault_addr = exit_info2;
187             pf_error_t * error_code = (pf_error_t *)&(exit_info1);
188
189             if (info->shdw_pg_mode == NESTED_PAGING) {
190                 if (v3_handle_nested_pagefault(info, fault_addr, *error_code) == -1) {
191                     return -1;
192                 }
193             } else {
194                 PrintError("Currently unhandled Nested Page Fault\n");
195                 return -1;
196                     }
197             break;
198             }
199         case SVM_EXIT_INVLPG: 
200             if (info->shdw_pg_mode == SHADOW_PAGING) {
201 #ifdef V3_CONFIG_DEBUG_SHADOW_PAGING
202                 PrintDebug("Invlpg\n");
203 #endif
204                 if (v3_handle_shadow_invlpg(info) == -1) {
205                     return -1;
206                 }
207             }
208             break;    
209         case SVM_EXIT_VMMCALL: 
210             /* 
211              * Hypercall 
212              */
213
214             // VMMCALL is a 3 byte op
215             // We do this early because some hypercalls can change the rip...
216             info->rip += 3;         
217
218             if (v3_handle_hypercall(info) == -1) {
219                 PrintError("Error handling Hypercall\n");
220                 return -1;
221             }
222
223             break;      
224         case SVM_EXIT_NMI:
225             // handled by interrupt dispatcher
226             break;
227         case SVM_EXIT_INTR:
228             // handled by interrupt dispatch earlier
229             break;
230         case SVM_EXIT_SMI:
231             //   handle_svm_smi(info); // ignored for now
232             break;
233         case SVM_EXIT_HLT:
234 #ifdef V3_CONFIG_DEBUG_HALT
235             PrintDebug("Guest halted\n");
236 #endif
237             if (v3_handle_halt(info) == -1) {
238                 return -1;
239             }
240             break;
241         case SVM_EXIT_PAUSE:
242             //      PrintDebug("Guest paused\n");
243             if (v3_handle_svm_pause(info) == -1) { 
244                 return -1;
245             }
246             break;
247         case SVM_EXIT_WBINVD:   
248 #ifdef V3_CONFIG_DEBUG_EMULATOR
249             PrintDebug("WBINVD\n");
250 #endif
251             if (v3_handle_svm_wbinvd(info) == -1) { 
252                 return -1;
253             }
254             break;
255         case SVM_EXIT_RDTSC:
256 #ifdef V3_CONFIG_DEBUG_TIME
257             PrintDebug("RDTSC/RDTSCP\n");
258 #endif 
259             if (v3_dispatch_exit_hook(info, V3_EXIT_RDTSC, NULL) == -1) {
260                 PrintError("Error Handling RDTSC instruction\n");
261                 return -1;
262             }
263             break;
264         case SVM_EXIT_RDTSCP:
265 #ifdef V3_CONFIG_DEBUG_TIME
266             PrintDebug("RDTSCP\n");
267 #endif 
268             if (v3_dispatch_exit_hook(info, V3_EXIT_RDTSCP, NULL) == -1) {
269                 PrintError("Error handling RDTSCP instruction\n");
270                 return -1;
271             }
272             
273             break;
274         case SVM_EXIT_SHUTDOWN:
275             PrintDebug("Guest-initiated shutdown\n");
276
277             info->vm_info->run_state = VM_STOPPED;
278
279             // Force exit on other cores
280
281             break;
282 #ifdef V3_CONFIG_EXT_SW_INTERRUPTS
283     case SVM_EXIT_SWINT:
284 #ifdef V3_CONFIG_DEBUG_EXT_SW_INTERRUPTS
285         PrintDebug("Intercepted a software interrupt\n");
286 #endif
287         if (v3_handle_swintr(info) == -1) {
288             PrintError("Error handling software interrupt\n");
289             return -1;
290         }
291         break;
292 #endif
293
294
295             /* Exits Following this line are NOT HANDLED */
296             /*=======================================================================*/
297             
298         default: {
299
300             addr_t rip_addr;
301             
302             PrintError("Unhandled SVM Exit: %s\n", v3_svm_exit_code_to_str(exit_code));
303             
304             rip_addr = get_addr_linear(info, info->rip, &(info->segments.cs));
305             
306             
307             PrintError("SVM Returned:(VMCB=%p)\n", (void *)(info->vmm_data)); 
308             PrintError("RIP: %p\n", (void *)(addr_t)(info->rip));
309             PrintError("RIP Linear: %p\n", (void *)(addr_t)(rip_addr));
310             
311             PrintError("SVM Returned: Exit Code: %p\n", (void *)(addr_t)exit_code); 
312             
313             PrintError("io_info1 low = 0x%.8x\n", *(uint_t*)&(exit_info1));
314             PrintError("io_info1 high = 0x%.8x\n", *(uint_t *)(((uint8_t *)&(exit_info1)) + 4));
315             
316             PrintError("io_info2 low = 0x%.8x\n", *(uint_t*)&(exit_info2));
317             PrintError("io_info2 high = 0x%.8x\n", *(uint_t *)(((uint8_t *)&(exit_info2)) + 4));
318             
319             
320             if (info->shdw_pg_mode == SHADOW_PAGING) {
321                 //      PrintHostPageTables(info, info->ctrl_regs.cr3);
322                 //PrintGuestPageTables(info, info->shdw_pg_state.guest_cr3);
323             }
324             
325             return -1;              
326         }
327     }
328     // END OF SWITCH (EXIT_CODE)
329
330 #ifdef V3_CONFIG_TELEMETRY
331     if (info->vm_info->enable_telemetry) {
332         v3_telemetry_end_exit(info, exit_code);
333     }
334 #endif
335
336
337     if (exit_code == SVM_EXIT_INTR) {
338         //PrintDebug("INTR ret IP = %x\n", guest_state->rip);
339     }
340     
341     return 0;
342 }
343
344
345 static const char SVM_EXIT_CR0_READ_STR[] = "SVM_EXIT_CR0_READ";
346 static const char SVM_EXIT_CR1_READ_STR[] = "SVM_EXIT_CR1_READ";
347 static const char SVM_EXIT_CR2_READ_STR[] = "SVM_EXIT_CR2_READ";
348 static const char SVM_EXIT_CR3_READ_STR[] = "SVM_EXIT_CR3_READ";
349 static const char SVM_EXIT_CR4_READ_STR[] = "SVM_EXIT_CR4_READ";
350 static const char SVM_EXIT_CR5_READ_STR[] = "SVM_EXIT_CR5_READ";
351 static const char SVM_EXIT_CR6_READ_STR[] = "SVM_EXIT_CR6_READ";
352 static const char SVM_EXIT_CR7_READ_STR[] = "SVM_EXIT_CR7_READ";
353 static const char SVM_EXIT_CR8_READ_STR[] = "SVM_EXIT_CR8_READ";
354 static const char SVM_EXIT_CR9_READ_STR[] = "SVM_EXIT_CR9_READ";
355 static const char SVM_EXIT_CR10_READ_STR[] = "SVM_EXIT_CR10_READ";
356 static const char SVM_EXIT_CR11_READ_STR[] = "SVM_EXIT_CR11_READ";
357 static const char SVM_EXIT_CR12_READ_STR[] = "SVM_EXIT_CR12_READ";
358 static const char SVM_EXIT_CR13_READ_STR[] = "SVM_EXIT_CR13_READ";
359 static const char SVM_EXIT_CR14_READ_STR[] = "SVM_EXIT_CR14_READ";
360 static const char SVM_EXIT_CR15_READ_STR[] = "SVM_EXIT_CR15_READ";
361 static const char SVM_EXIT_CR0_WRITE_STR[] = "SVM_EXIT_CR0_WRITE";
362 static const char SVM_EXIT_CR1_WRITE_STR[] = "SVM_EXIT_CR1_WRITE";
363 static const char SVM_EXIT_CR2_WRITE_STR[] = "SVM_EXIT_CR2_WRITE";
364 static const char SVM_EXIT_CR3_WRITE_STR[] = "SVM_EXIT_CR3_WRITE";
365 static const char SVM_EXIT_CR4_WRITE_STR[] = "SVM_EXIT_CR4_WRITE";
366 static const char SVM_EXIT_CR5_WRITE_STR[] = "SVM_EXIT_CR5_WRITE";
367 static const char SVM_EXIT_CR6_WRITE_STR[] = "SVM_EXIT_CR6_WRITE";
368 static const char SVM_EXIT_CR7_WRITE_STR[] = "SVM_EXIT_CR7_WRITE";
369 static const char SVM_EXIT_CR8_WRITE_STR[] = "SVM_EXIT_CR8_WRITE";
370 static const char SVM_EXIT_CR9_WRITE_STR[] = "SVM_EXIT_CR9_WRITE";
371 static const char SVM_EXIT_CR10_WRITE_STR[] = "SVM_EXIT_CR10_WRITE";
372 static const char SVM_EXIT_CR11_WRITE_STR[] = "SVM_EXIT_CR11_WRITE";
373 static const char SVM_EXIT_CR12_WRITE_STR[] = "SVM_EXIT_CR12_WRITE";
374 static const char SVM_EXIT_CR13_WRITE_STR[] = "SVM_EXIT_CR13_WRITE";
375 static const char SVM_EXIT_CR14_WRITE_STR[] = "SVM_EXIT_CR14_WRITE";
376 static const char SVM_EXIT_CR15_WRITE_STR[] = "SVM_EXIT_CR15_WRITE";
377 static const char SVM_EXIT_DR0_READ_STR[] = "SVM_EXIT_DR0_READ";
378 static const char SVM_EXIT_DR1_READ_STR[] = "SVM_EXIT_DR1_READ";
379 static const char SVM_EXIT_DR2_READ_STR[] = "SVM_EXIT_DR2_READ";
380 static const char SVM_EXIT_DR3_READ_STR[] = "SVM_EXIT_DR3_READ";
381 static const char SVM_EXIT_DR4_READ_STR[] = "SVM_EXIT_DR4_READ";
382 static const char SVM_EXIT_DR5_READ_STR[] = "SVM_EXIT_DR5_READ";
383 static const char SVM_EXIT_DR6_READ_STR[] = "SVM_EXIT_DR6_READ";
384 static const char SVM_EXIT_DR7_READ_STR[] = "SVM_EXIT_DR7_READ";
385 static const char SVM_EXIT_DR8_READ_STR[] = "SVM_EXIT_DR8_READ";
386 static const char SVM_EXIT_DR9_READ_STR[] = "SVM_EXIT_DR9_READ";
387 static const char SVM_EXIT_DR10_READ_STR[] = "SVM_EXIT_DR10_READ";
388 static const char SVM_EXIT_DR11_READ_STR[] = "SVM_EXIT_DR11_READ";
389 static const char SVM_EXIT_DR12_READ_STR[] = "SVM_EXIT_DR12_READ";
390 static const char SVM_EXIT_DR13_READ_STR[] = "SVM_EXIT_DR13_READ";
391 static const char SVM_EXIT_DR14_READ_STR[] = "SVM_EXIT_DR14_READ";
392 static const char SVM_EXIT_DR15_READ_STR[] = "SVM_EXIT_DR15_READ";
393 static const char SVM_EXIT_DR0_WRITE_STR[] = "SVM_EXIT_DR0_WRITE";
394 static const char SVM_EXIT_DR1_WRITE_STR[] = "SVM_EXIT_DR1_WRITE";
395 static const char SVM_EXIT_DR2_WRITE_STR[] = "SVM_EXIT_DR2_WRITE";
396 static const char SVM_EXIT_DR3_WRITE_STR[] = "SVM_EXIT_DR3_WRITE";
397 static const char SVM_EXIT_DR4_WRITE_STR[] = "SVM_EXIT_DR4_WRITE";
398 static const char SVM_EXIT_DR5_WRITE_STR[] = "SVM_EXIT_DR5_WRITE";
399 static const char SVM_EXIT_DR6_WRITE_STR[] = "SVM_EXIT_DR6_WRITE";
400 static const char SVM_EXIT_DR7_WRITE_STR[] = "SVM_EXIT_DR7_WRITE";
401 static const char SVM_EXIT_DR8_WRITE_STR[] = "SVM_EXIT_DR8_WRITE";
402 static const char SVM_EXIT_DR9_WRITE_STR[] = "SVM_EXIT_DR9_WRITE";
403 static const char SVM_EXIT_DR10_WRITE_STR[] = "SVM_EXIT_DR10_WRITE";
404 static const char SVM_EXIT_DR11_WRITE_STR[] = "SVM_EXIT_DR11_WRITE";
405 static const char SVM_EXIT_DR12_WRITE_STR[] = "SVM_EXIT_DR12_WRITE";
406 static const char SVM_EXIT_DR13_WRITE_STR[] = "SVM_EXIT_DR13_WRITE";
407 static const char SVM_EXIT_DR14_WRITE_STR[] = "SVM_EXIT_DR14_WRITE";
408 static const char SVM_EXIT_DR15_WRITE_STR[] = "SVM_EXIT_DR15_WRITE";
409 static const char SVM_EXIT_EXCP0_STR[] = "SVM_EXIT_EXCP0";
410 static const char SVM_EXIT_EXCP1_STR[] = "SVM_EXIT_EXCP1";
411 static const char SVM_EXIT_EXCP2_STR[] = "SVM_EXIT_EXCP2";
412 static const char SVM_EXIT_EXCP3_STR[] = "SVM_EXIT_EXCP3";
413 static const char SVM_EXIT_EXCP4_STR[] = "SVM_EXIT_EXCP4";
414 static const char SVM_EXIT_EXCP5_STR[] = "SVM_EXIT_EXCP5";
415 static const char SVM_EXIT_EXCP6_STR[] = "SVM_EXIT_EXCP6";
416 static const char SVM_EXIT_EXCP7_STR[] = "SVM_EXIT_EXCP7";
417 static const char SVM_EXIT_EXCP8_STR[] = "SVM_EXIT_EXCP8";
418 static const char SVM_EXIT_EXCP9_STR[] = "SVM_EXIT_EXCP9";
419 static const char SVM_EXIT_EXCP10_STR[] = "SVM_EXIT_EXCP10";
420 static const char SVM_EXIT_EXCP11_STR[] = "SVM_EXIT_EXCP11";
421 static const char SVM_EXIT_EXCP12_STR[] = "SVM_EXIT_EXCP12";
422 static const char SVM_EXIT_EXCP13_STR[] = "SVM_EXIT_EXCP13";
423 static const char SVM_EXIT_EXCP14_STR[] = "SVM_EXIT_EXCP14";
424 static const char SVM_EXIT_EXCP15_STR[] = "SVM_EXIT_EXCP15";
425 static const char SVM_EXIT_EXCP16_STR[] = "SVM_EXIT_EXCP16";
426 static const char SVM_EXIT_EXCP17_STR[] = "SVM_EXIT_EXCP17";
427 static const char SVM_EXIT_EXCP18_STR[] = "SVM_EXIT_EXCP18";
428 static const char SVM_EXIT_EXCP19_STR[] = "SVM_EXIT_EXCP19";
429 static const char SVM_EXIT_EXCP20_STR[] = "SVM_EXIT_EXCP20";
430 static const char SVM_EXIT_EXCP21_STR[] = "SVM_EXIT_EXCP21";
431 static const char SVM_EXIT_EXCP22_STR[] = "SVM_EXIT_EXCP22";
432 static const char SVM_EXIT_EXCP23_STR[] = "SVM_EXIT_EXCP23";
433 static const char SVM_EXIT_EXCP24_STR[] = "SVM_EXIT_EXCP24";
434 static const char SVM_EXIT_EXCP25_STR[] = "SVM_EXIT_EXCP25";
435 static const char SVM_EXIT_EXCP26_STR[] = "SVM_EXIT_EXCP26";
436 static const char SVM_EXIT_EXCP27_STR[] = "SVM_EXIT_EXCP27";
437 static const char SVM_EXIT_EXCP28_STR[] = "SVM_EXIT_EXCP28";
438 static const char SVM_EXIT_EXCP29_STR[] = "SVM_EXIT_EXCP29";
439 static const char SVM_EXIT_EXCP30_STR[] = "SVM_EXIT_EXCP30";
440 static const char SVM_EXIT_EXCP31_STR[] = "SVM_EXIT_EXCP31";
441 static const char SVM_EXIT_INTR_STR[] = "SVM_EXIT_INTR";
442 static const char SVM_EXIT_NMI_STR[] = "SVM_EXIT_NMI";
443 static const char SVM_EXIT_SMI_STR[] = "SVM_EXIT_SMI";
444 static const char SVM_EXIT_INIT_STR[] = "SVM_EXIT_INIT";
445 static const char SVM_EXIT_VINITR_STR[] = "SVM_EXIT_VINITR";
446 static const char SVM_EXIT_CR0_SEL_WRITE_STR[] = "SVM_EXIT_CR0_SEL_WRITE";
447 static const char SVM_EXIT_IDTR_READ_STR[] = "SVM_EXIT_IDTR_READ";
448 static const char SVM_EXIT_GDTR_READ_STR[] = "SVM_EXIT_GDTR_READ";
449 static const char SVM_EXIT_LDTR_READ_STR[] = "SVM_EXIT_LDTR_READ";
450 static const char SVM_EXIT_TR_READ_STR[] = "SVM_EXIT_TR_READ";
451 static const char SVM_EXIT_IDTR_WRITE_STR[] = "SVM_EXIT_IDTR_WRITE";
452 static const char SVM_EXIT_GDTR_WRITE_STR[] = "SVM_EXIT_GDTR_WRITE";
453 static const char SVM_EXIT_LDTR_WRITE_STR[] = "SVM_EXIT_LDTR_WRITE";
454 static const char SVM_EXIT_TR_WRITE_STR[] = "SVM_EXIT_TR_WRITE";
455 static const char SVM_EXIT_RDTSC_STR[] = "SVM_EXIT_RDTSC";
456 static const char SVM_EXIT_RDPMC_STR[] = "SVM_EXIT_RDPMC";
457 static const char SVM_EXIT_PUSHF_STR[] = "SVM_EXIT_PUSHF";
458 static const char SVM_EXIT_POPF_STR[] = "SVM_EXIT_POPF";
459 static const char SVM_EXIT_CPUID_STR[] = "SVM_EXIT_CPUID";
460 static const char SVM_EXIT_RSM_STR[] = "SVM_EXIT_RSM";
461 static const char SVM_EXIT_IRET_STR[] = "SVM_EXIT_IRET";
462 static const char SVM_EXIT_SWINT_STR[] = "SVM_EXIT_SWINT";
463 static const char SVM_EXIT_INVD_STR[] = "SVM_EXIT_INVD";
464 static const char SVM_EXIT_PAUSE_STR[] = "SVM_EXIT_PAUSE";
465 static const char SVM_EXIT_HLT_STR[] = "SVM_EXIT_HLT";
466 static const char SVM_EXIT_INVLPG_STR[] = "SVM_EXIT_INVLPG";
467 static const char SVM_EXIT_INVLPGA_STR[] = "SVM_EXIT_INVLPGA";
468 static const char SVM_EXIT_IOIO_STR[] = "SVM_EXIT_IOIO";
469 static const char SVM_EXIT_MSR_STR[] = "SVM_EXIT_MSR";
470 static const char SVM_EXIT_TASK_SWITCH_STR[] = "SVM_EXIT_TASK_SWITCH";
471 static const char SVM_EXIT_FERR_FREEZE_STR[] = "SVM_EXIT_FERR_FREEZE";
472 static const char SVM_EXIT_SHUTDOWN_STR[] = "SVM_EXIT_SHUTDOWN";
473 static const char SVM_EXIT_VMRUN_STR[] = "SVM_EXIT_VMRUN";
474 static const char SVM_EXIT_VMMCALL_STR[] = "SVM_EXIT_VMMCALL";
475 static const char SVM_EXIT_VMLOAD_STR[] = "SVM_EXIT_VMLOAD";
476 static const char SVM_EXIT_VMSAVE_STR[] = "SVM_EXIT_VMSAVE";
477 static const char SVM_EXIT_STGI_STR[] = "SVM_EXIT_STGI";
478 static const char SVM_EXIT_CLGI_STR[] = "SVM_EXIT_CLGI";
479 static const char SVM_EXIT_SKINIT_STR[] = "SVM_EXIT_SKINIT";
480 static const char SVM_EXIT_RDTSCP_STR[] = "SVM_EXIT_RDTSCP";
481 static const char SVM_EXIT_ICEBP_STR[] = "SVM_EXIT_ICEBP";
482 static const char SVM_EXIT_WBINVD_STR[] = "SVM_EXIT_WBINVD";
483 static const char SVM_EXIT_MONITOR_STR[] = "SVM_EXIT_MONITOR";
484 static const char SVM_EXIT_MWAIT_STR[] = "SVM_EXIT_MWAIT";
485 static const char SVM_EXIT_MWAIT_CONDITIONAL_STR[] = "SVM_EXIT_MWAIT_CONDITIONAL";
486 static const char SVM_EXIT_NPF_STR[] = "SVM_EXIT_NPF";
487 static const char SVM_EXIT_INVALID_VMCB_STR[] = "SVM_EXIT_INVALID_VMCB";
488
489
490
491 const char * v3_svm_exit_code_to_str(uint_t exit_code) {
492     switch(exit_code) {
493         case SVM_EXIT_CR0_READ:
494             return SVM_EXIT_CR0_READ_STR;
495         case SVM_EXIT_CR1_READ:
496             return SVM_EXIT_CR1_READ_STR;
497         case SVM_EXIT_CR2_READ:
498             return SVM_EXIT_CR2_READ_STR;
499         case SVM_EXIT_CR3_READ:
500             return SVM_EXIT_CR3_READ_STR;
501         case SVM_EXIT_CR4_READ:
502             return SVM_EXIT_CR4_READ_STR;
503         case SVM_EXIT_CR5_READ:
504             return SVM_EXIT_CR5_READ_STR;
505         case SVM_EXIT_CR6_READ:
506             return SVM_EXIT_CR6_READ_STR;
507         case SVM_EXIT_CR7_READ:
508             return SVM_EXIT_CR7_READ_STR;
509         case SVM_EXIT_CR8_READ:
510             return SVM_EXIT_CR8_READ_STR;
511         case SVM_EXIT_CR9_READ:
512             return SVM_EXIT_CR9_READ_STR;
513         case SVM_EXIT_CR10_READ:
514             return SVM_EXIT_CR10_READ_STR;
515         case SVM_EXIT_CR11_READ:
516             return SVM_EXIT_CR11_READ_STR;
517         case SVM_EXIT_CR12_READ:
518             return SVM_EXIT_CR12_READ_STR;
519         case SVM_EXIT_CR13_READ:
520             return SVM_EXIT_CR13_READ_STR;
521         case SVM_EXIT_CR14_READ:
522             return SVM_EXIT_CR14_READ_STR;
523         case SVM_EXIT_CR15_READ:
524             return SVM_EXIT_CR15_READ_STR;
525         case SVM_EXIT_CR0_WRITE:
526             return SVM_EXIT_CR0_WRITE_STR;
527         case SVM_EXIT_CR1_WRITE:
528             return SVM_EXIT_CR1_WRITE_STR;
529         case SVM_EXIT_CR2_WRITE:
530             return SVM_EXIT_CR2_WRITE_STR;
531         case SVM_EXIT_CR3_WRITE:
532             return SVM_EXIT_CR3_WRITE_STR;
533         case SVM_EXIT_CR4_WRITE:
534             return SVM_EXIT_CR4_WRITE_STR;
535         case SVM_EXIT_CR5_WRITE:
536             return SVM_EXIT_CR5_WRITE_STR;
537         case SVM_EXIT_CR6_WRITE:
538             return SVM_EXIT_CR6_WRITE_STR;
539         case SVM_EXIT_CR7_WRITE:
540             return SVM_EXIT_CR7_WRITE_STR;
541         case SVM_EXIT_CR8_WRITE:
542             return SVM_EXIT_CR8_WRITE_STR;
543         case SVM_EXIT_CR9_WRITE:
544             return SVM_EXIT_CR9_WRITE_STR;
545         case SVM_EXIT_CR10_WRITE:
546             return SVM_EXIT_CR10_WRITE_STR;
547         case SVM_EXIT_CR11_WRITE:
548             return SVM_EXIT_CR11_WRITE_STR;
549         case SVM_EXIT_CR12_WRITE:
550             return SVM_EXIT_CR12_WRITE_STR;
551         case SVM_EXIT_CR13_WRITE:
552             return SVM_EXIT_CR13_WRITE_STR;
553         case SVM_EXIT_CR14_WRITE:
554             return SVM_EXIT_CR14_WRITE_STR;
555         case SVM_EXIT_CR15_WRITE:
556             return SVM_EXIT_CR15_WRITE_STR;
557         case SVM_EXIT_DR0_READ:
558             return SVM_EXIT_DR0_READ_STR;
559         case SVM_EXIT_DR1_READ:
560             return SVM_EXIT_DR1_READ_STR;
561         case SVM_EXIT_DR2_READ:
562             return SVM_EXIT_DR2_READ_STR;
563         case SVM_EXIT_DR3_READ:
564             return SVM_EXIT_DR3_READ_STR;
565         case SVM_EXIT_DR4_READ:
566             return SVM_EXIT_DR4_READ_STR;
567         case SVM_EXIT_DR5_READ:
568             return SVM_EXIT_DR5_READ_STR;
569         case SVM_EXIT_DR6_READ:
570             return SVM_EXIT_DR6_READ_STR;
571         case SVM_EXIT_DR7_READ:
572             return SVM_EXIT_DR7_READ_STR;
573         case SVM_EXIT_DR8_READ:
574             return SVM_EXIT_DR8_READ_STR;
575         case SVM_EXIT_DR9_READ:
576             return SVM_EXIT_DR9_READ_STR;
577         case SVM_EXIT_DR10_READ:
578             return SVM_EXIT_DR10_READ_STR;
579         case SVM_EXIT_DR11_READ:
580             return SVM_EXIT_DR11_READ_STR;
581         case SVM_EXIT_DR12_READ:
582             return SVM_EXIT_DR12_READ_STR;
583         case SVM_EXIT_DR13_READ:
584             return SVM_EXIT_DR13_READ_STR;
585         case SVM_EXIT_DR14_READ:
586             return SVM_EXIT_DR14_READ_STR;
587         case SVM_EXIT_DR15_READ:
588             return SVM_EXIT_DR15_READ_STR;
589         case SVM_EXIT_DR0_WRITE:
590             return SVM_EXIT_DR0_WRITE_STR;
591         case SVM_EXIT_DR1_WRITE:
592             return SVM_EXIT_DR1_WRITE_STR;
593         case SVM_EXIT_DR2_WRITE:
594             return SVM_EXIT_DR2_WRITE_STR;
595         case SVM_EXIT_DR3_WRITE:
596             return SVM_EXIT_DR3_WRITE_STR;
597         case SVM_EXIT_DR4_WRITE:
598             return SVM_EXIT_DR4_WRITE_STR;
599         case SVM_EXIT_DR5_WRITE:
600             return SVM_EXIT_DR5_WRITE_STR;
601         case SVM_EXIT_DR6_WRITE:
602             return SVM_EXIT_DR6_WRITE_STR;
603         case SVM_EXIT_DR7_WRITE:
604             return SVM_EXIT_DR7_WRITE_STR;
605         case SVM_EXIT_DR8_WRITE:
606             return SVM_EXIT_DR8_WRITE_STR;
607         case SVM_EXIT_DR9_WRITE:
608             return SVM_EXIT_DR9_WRITE_STR;
609         case SVM_EXIT_DR10_WRITE:
610             return SVM_EXIT_DR10_WRITE_STR;
611         case SVM_EXIT_DR11_WRITE:
612             return SVM_EXIT_DR11_WRITE_STR;
613         case SVM_EXIT_DR12_WRITE:
614             return SVM_EXIT_DR12_WRITE_STR;
615         case SVM_EXIT_DR13_WRITE:
616             return SVM_EXIT_DR13_WRITE_STR;
617         case SVM_EXIT_DR14_WRITE:
618             return SVM_EXIT_DR14_WRITE_STR;
619         case SVM_EXIT_DR15_WRITE:
620             return SVM_EXIT_DR15_WRITE_STR;
621         case SVM_EXIT_EXCP0:
622             return SVM_EXIT_EXCP0_STR;
623         case SVM_EXIT_EXCP1:
624             return SVM_EXIT_EXCP1_STR;
625         case SVM_EXIT_EXCP2:
626             return SVM_EXIT_EXCP2_STR;
627         case SVM_EXIT_EXCP3:
628             return SVM_EXIT_EXCP3_STR;
629         case SVM_EXIT_EXCP4:
630             return SVM_EXIT_EXCP4_STR;
631         case SVM_EXIT_EXCP5:
632             return SVM_EXIT_EXCP5_STR;
633         case SVM_EXIT_EXCP6:
634             return SVM_EXIT_EXCP6_STR;
635         case SVM_EXIT_EXCP7:
636             return SVM_EXIT_EXCP7_STR;
637         case SVM_EXIT_EXCP8:
638             return SVM_EXIT_EXCP8_STR;
639         case SVM_EXIT_EXCP9:
640             return SVM_EXIT_EXCP9_STR;
641         case SVM_EXIT_EXCP10:
642             return SVM_EXIT_EXCP10_STR;
643         case SVM_EXIT_EXCP11:
644             return SVM_EXIT_EXCP11_STR;
645         case SVM_EXIT_EXCP12:
646             return SVM_EXIT_EXCP12_STR;
647         case SVM_EXIT_EXCP13:
648             return SVM_EXIT_EXCP13_STR;
649         case SVM_EXIT_EXCP14:
650             return SVM_EXIT_EXCP14_STR;
651         case SVM_EXIT_EXCP15:
652             return SVM_EXIT_EXCP15_STR;
653         case SVM_EXIT_EXCP16:
654             return SVM_EXIT_EXCP16_STR;
655         case SVM_EXIT_EXCP17:
656             return SVM_EXIT_EXCP17_STR;
657         case SVM_EXIT_EXCP18:
658             return SVM_EXIT_EXCP18_STR;
659         case SVM_EXIT_EXCP19:
660             return SVM_EXIT_EXCP19_STR;
661         case SVM_EXIT_EXCP20:
662             return SVM_EXIT_EXCP20_STR;
663         case SVM_EXIT_EXCP21:
664             return SVM_EXIT_EXCP21_STR;
665         case SVM_EXIT_EXCP22:
666             return SVM_EXIT_EXCP22_STR;
667         case SVM_EXIT_EXCP23:
668             return SVM_EXIT_EXCP23_STR;
669         case SVM_EXIT_EXCP24:
670             return SVM_EXIT_EXCP24_STR;
671         case SVM_EXIT_EXCP25:
672             return SVM_EXIT_EXCP25_STR;
673         case SVM_EXIT_EXCP26:
674             return SVM_EXIT_EXCP26_STR;
675         case SVM_EXIT_EXCP27:
676             return SVM_EXIT_EXCP27_STR;
677         case SVM_EXIT_EXCP28:
678             return SVM_EXIT_EXCP28_STR;
679         case SVM_EXIT_EXCP29:
680             return SVM_EXIT_EXCP29_STR;
681         case SVM_EXIT_EXCP30:
682             return SVM_EXIT_EXCP30_STR;
683         case SVM_EXIT_EXCP31:
684             return SVM_EXIT_EXCP31_STR;
685         case SVM_EXIT_INTR:
686             return SVM_EXIT_INTR_STR;
687         case SVM_EXIT_NMI:
688             return SVM_EXIT_NMI_STR;
689         case SVM_EXIT_SMI:
690             return SVM_EXIT_SMI_STR;
691         case SVM_EXIT_INIT:
692             return SVM_EXIT_INIT_STR;
693         case SVM_EXIT_VINITR:
694             return SVM_EXIT_VINITR_STR;
695         case SVM_EXIT_CR0_SEL_WRITE:
696             return SVM_EXIT_CR0_SEL_WRITE_STR;
697         case SVM_EXIT_IDTR_READ:
698             return SVM_EXIT_IDTR_READ_STR;
699         case SVM_EXIT_GDTR_READ:
700             return SVM_EXIT_GDTR_READ_STR;
701         case SVM_EXIT_LDTR_READ:
702             return SVM_EXIT_LDTR_READ_STR;
703         case SVM_EXIT_TR_READ:
704             return SVM_EXIT_TR_READ_STR;
705         case SVM_EXIT_IDTR_WRITE:
706             return SVM_EXIT_IDTR_WRITE_STR;
707         case SVM_EXIT_GDTR_WRITE:
708             return SVM_EXIT_GDTR_WRITE_STR;
709         case SVM_EXIT_LDTR_WRITE:
710             return SVM_EXIT_LDTR_WRITE_STR;
711         case SVM_EXIT_TR_WRITE:
712             return SVM_EXIT_TR_WRITE_STR;
713         case SVM_EXIT_RDTSC:
714             return SVM_EXIT_RDTSC_STR;
715         case SVM_EXIT_RDPMC:
716             return SVM_EXIT_RDPMC_STR;
717         case SVM_EXIT_PUSHF:
718             return SVM_EXIT_PUSHF_STR;
719         case SVM_EXIT_POPF:
720             return SVM_EXIT_POPF_STR;
721         case SVM_EXIT_CPUID:
722             return SVM_EXIT_CPUID_STR;
723         case SVM_EXIT_RSM:
724             return SVM_EXIT_RSM_STR;
725         case SVM_EXIT_IRET:
726             return SVM_EXIT_IRET_STR;
727         case SVM_EXIT_SWINT:
728             return SVM_EXIT_SWINT_STR;
729         case SVM_EXIT_INVD:
730             return SVM_EXIT_INVD_STR;
731         case SVM_EXIT_PAUSE:
732             return SVM_EXIT_PAUSE_STR;
733         case SVM_EXIT_HLT:
734             return SVM_EXIT_HLT_STR;
735         case SVM_EXIT_INVLPG:
736             return SVM_EXIT_INVLPG_STR;
737         case SVM_EXIT_INVLPGA:
738             return SVM_EXIT_INVLPGA_STR;
739         case SVM_EXIT_IOIO:
740             return SVM_EXIT_IOIO_STR;
741         case SVM_EXIT_MSR:
742             return SVM_EXIT_MSR_STR;
743         case SVM_EXIT_TASK_SWITCH:
744             return SVM_EXIT_TASK_SWITCH_STR;
745         case SVM_EXIT_FERR_FREEZE:
746             return SVM_EXIT_FERR_FREEZE_STR;
747         case SVM_EXIT_SHUTDOWN:
748             return SVM_EXIT_SHUTDOWN_STR;
749         case SVM_EXIT_VMRUN:
750             return SVM_EXIT_VMRUN_STR;
751         case SVM_EXIT_VMMCALL:
752             return SVM_EXIT_VMMCALL_STR;
753         case SVM_EXIT_VMLOAD:
754             return SVM_EXIT_VMLOAD_STR;
755         case SVM_EXIT_VMSAVE:
756             return SVM_EXIT_VMSAVE_STR;
757         case SVM_EXIT_STGI:
758             return SVM_EXIT_STGI_STR;
759         case SVM_EXIT_CLGI:
760             return SVM_EXIT_CLGI_STR;
761         case SVM_EXIT_SKINIT:
762             return SVM_EXIT_SKINIT_STR;
763         case SVM_EXIT_RDTSCP:
764             return SVM_EXIT_RDTSCP_STR;
765         case SVM_EXIT_ICEBP:
766             return SVM_EXIT_ICEBP_STR;
767         case SVM_EXIT_WBINVD:
768             return SVM_EXIT_WBINVD_STR;
769         case SVM_EXIT_MONITOR:
770             return SVM_EXIT_MONITOR_STR;
771         case SVM_EXIT_MWAIT:
772             return SVM_EXIT_MWAIT_STR;
773         case SVM_EXIT_MWAIT_CONDITIONAL:
774             return SVM_EXIT_MWAIT_CONDITIONAL_STR;
775         case SVM_EXIT_NPF:
776             return SVM_EXIT_NPF_STR;
777         case SVM_EXIT_INVALID_VMCB:
778             return SVM_EXIT_INVALID_VMCB_STR;
779     }
780     return NULL;
781 }