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.


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