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.


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