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.


increment rip after a successfull hypercall
[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/svm_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_profiler.h>
34 #include <palacios/vmm_hypercall.h>
35
36
37
38
39 int v3_handle_svm_exit(struct guest_info * info) {
40   vmcb_ctrl_t * guest_ctrl = 0;
41   vmcb_saved_state_t * guest_state = 0;
42   ulong_t exit_code = 0;
43   
44   guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
45   guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
46   
47
48   // Update the high level state 
49   info->rip = guest_state->rip;
50   info->vm_regs.rsp = guest_state->rsp;
51   info->vm_regs.rax = guest_state->rax;
52
53   info->cpl = guest_state->cpl;
54
55
56   info->ctrl_regs.cr0 = guest_state->cr0;
57   info->ctrl_regs.cr2 = guest_state->cr2;
58   info->ctrl_regs.cr3 = guest_state->cr3;
59   info->ctrl_regs.cr4 = guest_state->cr4;
60   info->dbg_regs.dr6 = guest_state->dr6;
61   info->dbg_regs.dr7 = guest_state->dr7;
62   info->ctrl_regs.cr8 = guest_ctrl->guest_ctrl.V_TPR;
63   info->ctrl_regs.rflags = guest_state->rflags;
64   info->ctrl_regs.efer = guest_state->efer;
65
66   get_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
67   info->cpu_mode = v3_get_cpu_mode(info);
68   info->mem_mode = v3_get_mem_mode(info);
69
70
71   exit_code = guest_ctrl->exit_code;
72
73
74
75   
76
77   // Disable printing io exits due to bochs debug messages
78   //if (!((exit_code == VMEXIT_IOIO) && ((ushort_t)(guest_ctrl->exit_info1 >> 16) == 0x402))) {
79
80
81   //  PrintDebug("SVM Returned: Exit Code: 0x%x \t\t(tsc=%ul)\n",exit_code, (uint_t)info->time_state.guest_tsc); 
82   
83   if ((0) && (exit_code <= VMEXIT_EXCP14)) {
84     uchar_t instr[32];
85     int ret;
86     // Dump out the instr stream
87
88     //PrintDebug("RIP: %x\n", guest_state->rip);
89     PrintDebug("\n\n\nRIP Linear: %p\n", (void *)get_addr_linear(info, info->rip, &(info->segments.cs)));
90
91     v3_print_GPRs(info);
92     v3_print_ctrl_regs(info);
93
94
95     // OK, now we will read the instruction
96     // The only difference between PROTECTED and PROTECTED_PG is whether we read
97     // from guest_pa or guest_va
98     if (info->mem_mode == PHYSICAL_MEM) { 
99       // The real rip address is actually a combination of the rip + CS base 
100       ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 32, instr);
101     } else { 
102       ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 32, instr);
103     }
104     
105
106
107     if (ret != 32) {
108       // I think we should inject a GPF into the guest
109       PrintDebug("Could not read instruction (ret=%d)\n", ret);
110     } else {
111
112       PrintDebug("Instr Stream:\n");
113       PrintTraceMemDump(instr, 32);
114     }
115   }
116
117
118
119   if (info->enable_profiler) {
120     rdtscll(info->profiler.start_time);
121   }
122
123   
124   //PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); 
125
126   switch (exit_code) {
127
128   case VMEXIT_IOIO: 
129     {
130       struct svm_io_info * io_info = (struct svm_io_info *)&(guest_ctrl->exit_info1);
131       
132       if (io_info->type == 0) {
133         if (io_info->str) {
134           if (v3_handle_svm_io_outs(info) == -1 ) {
135             return -1;
136           }
137         } else {
138           if (v3_handle_svm_io_out(info) == -1) {
139             return -1;
140           }
141         }
142       } else {
143         if (io_info->str) {
144           if (v3_handle_svm_io_ins(info) == -1) {
145             return -1;
146           }
147         } else {
148           if (v3_handle_svm_io_in(info) == -1) {
149             return -1;
150           }
151         }
152       }
153       break;
154     }
155   case VMEXIT_MSR:
156     {
157
158       if (guest_ctrl->exit_info1 == 0) {
159         if (v3_handle_msr_read(info) == -1) {
160           return -1;
161         }
162       } else if (guest_ctrl->exit_info1 == 1) {
163         if (v3_handle_msr_write(info) == -1) {
164           return -1;
165         }
166       } else {
167         PrintError("Invalid MSR Operation\n");
168         return -1;
169       }
170
171       break;
172     }
173   case VMEXIT_CR0_WRITE: 
174     {
175 #ifdef DEBUG_CTRL_REGS
176       PrintDebug("CR0 Write\n");
177 #endif
178       if (v3_handle_cr0_write(info) == -1) {
179         return -1;
180       }
181       break;
182     } 
183   case VMEXIT_CR0_READ: 
184     {
185 #ifdef DEBUG_CTRL_REGS
186       PrintDebug("CR0 Read\n");
187 #endif
188       if (v3_handle_cr0_read(info) == -1) {
189         return -1;
190       }
191       break;
192     } 
193   case VMEXIT_CR3_WRITE: 
194     {
195 #ifdef DEBUG_CTRL_REGS
196       PrintDebug("CR3 Write\n");
197 #endif
198       if (v3_handle_cr3_write(info) == -1) {
199         return -1;
200       }    
201       break;
202     }
203   case  VMEXIT_CR3_READ: 
204     {
205 #ifdef DEBUG_CTRL_REGS
206       PrintDebug("CR3 Read\n");
207 #endif
208       if (v3_handle_cr3_read(info) == -1) {
209         return -1;
210       }
211       break;
212     }
213   case VMEXIT_CR4_WRITE: 
214     {
215 #ifdef DEBUG_CTRL_REGS
216       PrintDebug("CR4 Write\n");
217 #endif
218       if (v3_handle_cr4_write(info) == -1) {
219         return -1;
220       }    
221       break;
222     }
223   case  VMEXIT_CR4_READ: 
224     {
225 #ifdef DEBUG_CTRL_REGS
226       PrintDebug("CR4 Read\n");
227 #endif
228       if (v3_handle_cr4_read(info) == -1) {
229         return -1;
230       }
231       break;
232     }
233
234   case VMEXIT_EXCP14: 
235     {
236       addr_t fault_addr = guest_ctrl->exit_info2;
237       pf_error_t * error_code = (pf_error_t *)&(guest_ctrl->exit_info1);
238 #ifdef DEBUG_SHADOW_PAGING
239       PrintDebug("PageFault at %p (error=%d)\n", 
240                  (void *)fault_addr, *(uint_t *)error_code);
241 #endif
242       if (info->shdw_pg_mode == SHADOW_PAGING) {
243         if (v3_handle_shadow_pagefault(info, fault_addr, *error_code) == -1) {
244           return -1;
245         }
246       } else {
247         PrintError("Page fault in un implemented paging mode\n");
248         return -1;
249       }
250       break;
251     } 
252   case VMEXIT_NPF: 
253     {
254       PrintError("Currently unhandled Nested Page Fault\n");
255       return -1;
256
257       break;
258     }
259   case VMEXIT_INVLPG: 
260     {
261       if (info->shdw_pg_mode == SHADOW_PAGING) {
262 #ifdef DEBUG_SHADOW_PAGING
263         PrintDebug("Invlpg\n");
264 #endif
265         if (v3_handle_shadow_invlpg(info) == -1) {
266           return -1;
267         }
268       }
269    
270       /*
271         (exit_code == VMEXIT_INVLPGA)   || 
272       */
273       break;
274     }
275
276
277
278   case VMEXIT_VMMCALL: 
279     { 
280       /* 
281        * Hypercall 
282        */
283
284       if (v3_handle_hypercall(info) == -1) {
285         return -1;
286       }
287
288       // VMMCALL is a 3 byte op
289       info->rip += 3;
290       break;
291     } 
292
293
294   case VMEXIT_INTR: 
295     {
296       // handled by interrupt dispatch earlier
297       break;
298     }    
299   case VMEXIT_SMI: 
300     {      
301       //   handle_svm_smi(info); // ignored for now
302       break;
303     }
304   case VMEXIT_HLT: 
305     {
306 #ifdef DEBUG_HALT
307       PrintDebug("Guest halted\n");
308 #endif
309       if (v3_handle_svm_halt(info) == -1) {
310         return -1;
311       }
312       break;
313     }
314   case VMEXIT_PAUSE: {
315     //PrintDebug("Guest paused\n");
316     if (v3_handle_svm_pause(info) == -1) { 
317       return -1;
318     }
319   } 
320     break;
321
322
323
324
325   case VMEXIT_WBINVD: 
326     {
327 #ifdef DEBUG_EMULATOR
328       PrintDebug("WBINVD\n");
329 #endif
330       if (v3_handle_svm_wbinvd(info) == -1) { 
331         return -1;
332       }
333       break;
334     }
335
336
337
338
339     /* Exits Following this line are NOT HANDLED */
340     /*=======================================================================*/
341
342   default: 
343     {
344
345       addr_t rip_addr;
346       
347       PrintDebug("Unhandled SVM Exit: %s\n", vmexit_code_to_str(exit_code));
348       
349       rip_addr = get_addr_linear(info, guest_state->rip, &(info->segments.cs));
350       
351       
352       PrintError("SVM Returned:(VMCB=%p)\n", (void *)(info->vmm_data)); 
353       PrintError("RIP: %p\n", (void *)(addr_t)(guest_state->rip));
354       PrintError("RIP Linear: %p\n", (void *)(addr_t)(rip_addr));
355       
356       PrintError("SVM Returned: Exit Code: %p\n", (void *)(addr_t)exit_code); 
357       
358       PrintError("io_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1));
359       PrintError("io_info1 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
360       
361       PrintError("io_info2 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info2));
362       PrintError("io_info2 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
363       
364       
365       if (info->shdw_pg_mode == SHADOW_PAGING) {
366         PrintHostPageTables(info, info->ctrl_regs.cr3);
367         //PrintGuestPageTables(info, info->shdw_pg_state.guest_cr3);
368       }
369       
370       return -1;
371       
372     }
373     break;
374     
375   }
376   // END OF SWITCH (EXIT_CODE)
377
378
379   if (info->enable_profiler) {
380     rdtscll(info->profiler.end_time);
381     v3_profile_exit(info, exit_code);
382   }
383       
384
385
386   // Update the low level state
387
388   if (v3_intr_pending(info)) {
389
390     switch (v3_get_intr_type(info)) {
391     case EXTERNAL_IRQ: 
392       {
393         uint_t irq = v3_get_intr_number(info);
394
395         // check to see if ==-1 (non exists)
396
397         /*      
398           guest_ctrl->EVENTINJ.vector = irq;
399           guest_ctrl->EVENTINJ.valid = 1;
400           guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXTERNAL_INTR;
401         */
402         
403         guest_ctrl->guest_ctrl.V_IRQ = 1;
404         guest_ctrl->guest_ctrl.V_INTR_VECTOR = irq;
405         guest_ctrl->guest_ctrl.V_IGN_TPR = 1;
406         guest_ctrl->guest_ctrl.V_INTR_PRIO = 0xf;
407 #ifdef DEBUG_INTERRUPTS
408         PrintDebug("Injecting Interrupt %d (EIP=%p)\n", 
409                    guest_ctrl->guest_ctrl.V_INTR_VECTOR, 
410                    (void *)(addr_t)info->rip);
411 #endif
412         v3_injecting_intr(info, irq, EXTERNAL_IRQ);
413         
414         break;
415       }
416     case NMI:
417       guest_ctrl->EVENTINJ.type = SVM_INJECTION_NMI;
418       break;
419     case EXCEPTION:
420       {
421         uint_t excp = v3_get_intr_number(info);
422
423         guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION;
424         
425         if (info->intr_state.excp_error_code_valid) {  //PAD
426           guest_ctrl->EVENTINJ.error_code = info->intr_state.excp_error_code;
427           guest_ctrl->EVENTINJ.ev = 1;
428 #ifdef DEBUG_INTERRUPTS
429           PrintDebug("Injecting error code %x\n", guest_ctrl->EVENTINJ.error_code);
430 #endif
431         }
432         
433         guest_ctrl->EVENTINJ.vector = excp;
434         
435         guest_ctrl->EVENTINJ.valid = 1;
436 #ifdef DEBUG_INTERRUPTS
437         PrintDebug("Injecting Interrupt %d (EIP=%p)\n", 
438                    guest_ctrl->EVENTINJ.vector, 
439                    (void *)(addr_t)info->rip);
440 #endif
441         v3_injecting_intr(info, excp, EXCEPTION);
442         break;
443       }
444     case SOFTWARE_INTR:
445       guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
446       break;
447     case VIRTUAL_INTR:
448       guest_ctrl->EVENTINJ.type = SVM_INJECTION_VIRTUAL_INTR;
449       break;
450
451     case INVALID_INTR: 
452     default:
453       PrintError("Attempted to issue an invalid interrupt\n");
454       return -1;
455     }
456
457   } else {
458 #ifdef DEBUG_INTERRUPTS
459     PrintDebug("No interrupts/exceptions pending\n");
460 #endif
461   }
462
463   guest_state->cr0 = info->ctrl_regs.cr0;
464   guest_state->cr2 = info->ctrl_regs.cr2;
465   guest_state->cr3 = info->ctrl_regs.cr3;
466   guest_state->cr4 = info->ctrl_regs.cr4;
467   guest_state->dr6 = info->dbg_regs.dr6;
468   guest_state->dr7 = info->dbg_regs.dr7;
469   guest_ctrl->guest_ctrl.V_TPR = info->ctrl_regs.cr8 & 0xff;
470   guest_state->rflags = info->ctrl_regs.rflags;
471   guest_state->efer = info->ctrl_regs.efer;
472
473   guest_state->cpl = info->cpl;
474
475   guest_state->rax = info->vm_regs.rax;
476   guest_state->rip = info->rip;
477   guest_state->rsp = info->vm_regs.rsp;
478
479
480   set_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
481
482   if (exit_code == VMEXIT_INTR) {
483     //PrintDebug("INTR ret IP = %x\n", guest_state->rip);
484   }
485
486   return 0;
487 }
488
489
490 static const char VMEXIT_CR0_READ_STR[] = "VMEXIT_CR0_READ";
491 static const char VMEXIT_CR1_READ_STR[] = "VMEXIT_CR1_READ";
492 static const char VMEXIT_CR2_READ_STR[] = "VMEXIT_CR2_READ";
493 static const char VMEXIT_CR3_READ_STR[] = "VMEXIT_CR3_READ";
494 static const char VMEXIT_CR4_READ_STR[] = "VMEXIT_CR4_READ";
495 static const char VMEXIT_CR5_READ_STR[] = "VMEXIT_CR5_READ";
496 static const char VMEXIT_CR6_READ_STR[] = "VMEXIT_CR6_READ";
497 static const char VMEXIT_CR7_READ_STR[] = "VMEXIT_CR7_READ";
498 static const char VMEXIT_CR8_READ_STR[] = "VMEXIT_CR8_READ";
499 static const char VMEXIT_CR9_READ_STR[] = "VMEXIT_CR9_READ";
500 static const char VMEXIT_CR10_READ_STR[] = "VMEXIT_CR10_READ";
501 static const char VMEXIT_CR11_READ_STR[] = "VMEXIT_CR11_READ";
502 static const char VMEXIT_CR12_READ_STR[] = "VMEXIT_CR12_READ";
503 static const char VMEXIT_CR13_READ_STR[] = "VMEXIT_CR13_READ";
504 static const char VMEXIT_CR14_READ_STR[] = "VMEXIT_CR14_READ";
505 static const char VMEXIT_CR15_READ_STR[] = "VMEXIT_CR15_READ";
506 static const char VMEXIT_CR0_WRITE_STR[] = "VMEXIT_CR0_WRITE";
507 static const char VMEXIT_CR1_WRITE_STR[] = "VMEXIT_CR1_WRITE";
508 static const char VMEXIT_CR2_WRITE_STR[] = "VMEXIT_CR2_WRITE";
509 static const char VMEXIT_CR3_WRITE_STR[] = "VMEXIT_CR3_WRITE";
510 static const char VMEXIT_CR4_WRITE_STR[] = "VMEXIT_CR4_WRITE";
511 static const char VMEXIT_CR5_WRITE_STR[] = "VMEXIT_CR5_WRITE";
512 static const char VMEXIT_CR6_WRITE_STR[] = "VMEXIT_CR6_WRITE";
513 static const char VMEXIT_CR7_WRITE_STR[] = "VMEXIT_CR7_WRITE";
514 static const char VMEXIT_CR8_WRITE_STR[] = "VMEXIT_CR8_WRITE";
515 static const char VMEXIT_CR9_WRITE_STR[] = "VMEXIT_CR9_WRITE";
516 static const char VMEXIT_CR10_WRITE_STR[] = "VMEXIT_CR10_WRITE";
517 static const char VMEXIT_CR11_WRITE_STR[] = "VMEXIT_CR11_WRITE";
518 static const char VMEXIT_CR12_WRITE_STR[] = "VMEXIT_CR12_WRITE";
519 static const char VMEXIT_CR13_WRITE_STR[] = "VMEXIT_CR13_WRITE";
520 static const char VMEXIT_CR14_WRITE_STR[] = "VMEXIT_CR14_WRITE";
521 static const char VMEXIT_CR15_WRITE_STR[] = "VMEXIT_CR15_WRITE";
522 static const char VMEXIT_DR0_READ_STR[] = "VMEXIT_DR0_READ";
523 static const char VMEXIT_DR1_READ_STR[] = "VMEXIT_DR1_READ";
524 static const char VMEXIT_DR2_READ_STR[] = "VMEXIT_DR2_READ";
525 static const char VMEXIT_DR3_READ_STR[] = "VMEXIT_DR3_READ";
526 static const char VMEXIT_DR4_READ_STR[] = "VMEXIT_DR4_READ";
527 static const char VMEXIT_DR5_READ_STR[] = "VMEXIT_DR5_READ";
528 static const char VMEXIT_DR6_READ_STR[] = "VMEXIT_DR6_READ";
529 static const char VMEXIT_DR7_READ_STR[] = "VMEXIT_DR7_READ";
530 static const char VMEXIT_DR8_READ_STR[] = "VMEXIT_DR8_READ";
531 static const char VMEXIT_DR9_READ_STR[] = "VMEXIT_DR9_READ";
532 static const char VMEXIT_DR10_READ_STR[] = "VMEXIT_DR10_READ";
533 static const char VMEXIT_DR11_READ_STR[] = "VMEXIT_DR11_READ";
534 static const char VMEXIT_DR12_READ_STR[] = "VMEXIT_DR12_READ";
535 static const char VMEXIT_DR13_READ_STR[] = "VMEXIT_DR13_READ";
536 static const char VMEXIT_DR14_READ_STR[] = "VMEXIT_DR14_READ";
537 static const char VMEXIT_DR15_READ_STR[] = "VMEXIT_DR15_READ";
538 static const char VMEXIT_DR0_WRITE_STR[] = "VMEXIT_DR0_WRITE";
539 static const char VMEXIT_DR1_WRITE_STR[] = "VMEXIT_DR1_WRITE";
540 static const char VMEXIT_DR2_WRITE_STR[] = "VMEXIT_DR2_WRITE";
541 static const char VMEXIT_DR3_WRITE_STR[] = "VMEXIT_DR3_WRITE";
542 static const char VMEXIT_DR4_WRITE_STR[] = "VMEXIT_DR4_WRITE";
543 static const char VMEXIT_DR5_WRITE_STR[] = "VMEXIT_DR5_WRITE";
544 static const char VMEXIT_DR6_WRITE_STR[] = "VMEXIT_DR6_WRITE";
545 static const char VMEXIT_DR7_WRITE_STR[] = "VMEXIT_DR7_WRITE";
546 static const char VMEXIT_DR8_WRITE_STR[] = "VMEXIT_DR8_WRITE";
547 static const char VMEXIT_DR9_WRITE_STR[] = "VMEXIT_DR9_WRITE";
548 static const char VMEXIT_DR10_WRITE_STR[] = "VMEXIT_DR10_WRITE";
549 static const char VMEXIT_DR11_WRITE_STR[] = "VMEXIT_DR11_WRITE";
550 static const char VMEXIT_DR12_WRITE_STR[] = "VMEXIT_DR12_WRITE";
551 static const char VMEXIT_DR13_WRITE_STR[] = "VMEXIT_DR13_WRITE";
552 static const char VMEXIT_DR14_WRITE_STR[] = "VMEXIT_DR14_WRITE";
553 static const char VMEXIT_DR15_WRITE_STR[] = "VMEXIT_DR15_WRITE";
554 static const char VMEXIT_EXCP0_STR[] = "VMEXIT_EXCP0";
555 static const char VMEXIT_EXCP1_STR[] = "VMEXIT_EXCP1";
556 static const char VMEXIT_EXCP2_STR[] = "VMEXIT_EXCP2";
557 static const char VMEXIT_EXCP3_STR[] = "VMEXIT_EXCP3";
558 static const char VMEXIT_EXCP4_STR[] = "VMEXIT_EXCP4";
559 static const char VMEXIT_EXCP5_STR[] = "VMEXIT_EXCP5";
560 static const char VMEXIT_EXCP6_STR[] = "VMEXIT_EXCP6";
561 static const char VMEXIT_EXCP7_STR[] = "VMEXIT_EXCP7";
562 static const char VMEXIT_EXCP8_STR[] = "VMEXIT_EXCP8";
563 static const char VMEXIT_EXCP9_STR[] = "VMEXIT_EXCP9";
564 static const char VMEXIT_EXCP10_STR[] = "VMEXIT_EXCP10";
565 static const char VMEXIT_EXCP11_STR[] = "VMEXIT_EXCP11";
566 static const char VMEXIT_EXCP12_STR[] = "VMEXIT_EXCP12";
567 static const char VMEXIT_EXCP13_STR[] = "VMEXIT_EXCP13";
568 static const char VMEXIT_EXCP14_STR[] = "VMEXIT_EXCP14";
569 static const char VMEXIT_EXCP15_STR[] = "VMEXIT_EXCP15";
570 static const char VMEXIT_EXCP16_STR[] = "VMEXIT_EXCP16";
571 static const char VMEXIT_EXCP17_STR[] = "VMEXIT_EXCP17";
572 static const char VMEXIT_EXCP18_STR[] = "VMEXIT_EXCP18";
573 static const char VMEXIT_EXCP19_STR[] = "VMEXIT_EXCP19";
574 static const char VMEXIT_EXCP20_STR[] = "VMEXIT_EXCP20";
575 static const char VMEXIT_EXCP21_STR[] = "VMEXIT_EXCP21";
576 static const char VMEXIT_EXCP22_STR[] = "VMEXIT_EXCP22";
577 static const char VMEXIT_EXCP23_STR[] = "VMEXIT_EXCP23";
578 static const char VMEXIT_EXCP24_STR[] = "VMEXIT_EXCP24";
579 static const char VMEXIT_EXCP25_STR[] = "VMEXIT_EXCP25";
580 static const char VMEXIT_EXCP26_STR[] = "VMEXIT_EXCP26";
581 static const char VMEXIT_EXCP27_STR[] = "VMEXIT_EXCP27";
582 static const char VMEXIT_EXCP28_STR[] = "VMEXIT_EXCP28";
583 static const char VMEXIT_EXCP29_STR[] = "VMEXIT_EXCP29";
584 static const char VMEXIT_EXCP30_STR[] = "VMEXIT_EXCP30";
585 static const char VMEXIT_EXCP31_STR[] = "VMEXIT_EXCP31";
586 static const char VMEXIT_INTR_STR[] = "VMEXIT_INTR";
587 static const char VMEXIT_NMI_STR[] = "VMEXIT_NMI";
588 static const char VMEXIT_SMI_STR[] = "VMEXIT_SMI";
589 static const char VMEXIT_INIT_STR[] = "VMEXIT_INIT";
590 static const char VMEXIT_VINITR_STR[] = "VMEXIT_VINITR";
591 static const char VMEXIT_CR0_SEL_WRITE_STR[] = "VMEXIT_CR0_SEL_WRITE";
592 static const char VMEXIT_IDTR_READ_STR[] = "VMEXIT_IDTR_READ";
593 static const char VMEXIT_GDTR_READ_STR[] = "VMEXIT_GDTR_READ";
594 static const char VMEXIT_LDTR_READ_STR[] = "VMEXIT_LDTR_READ";
595 static const char VMEXIT_TR_READ_STR[] = "VMEXIT_TR_READ";
596 static const char VMEXIT_IDTR_WRITE_STR[] = "VMEXIT_IDTR_WRITE";
597 static const char VMEXIT_GDTR_WRITE_STR[] = "VMEXIT_GDTR_WRITE";
598 static const char VMEXIT_LDTR_WRITE_STR[] = "VMEXIT_LDTR_WRITE";
599 static const char VMEXIT_TR_WRITE_STR[] = "VMEXIT_TR_WRITE";
600 static const char VMEXIT_RDTSC_STR[] = "VMEXIT_RDTSC";
601 static const char VMEXIT_RDPMC_STR[] = "VMEXIT_RDPMC";
602 static const char VMEXIT_PUSHF_STR[] = "VMEXIT_PUSHF";
603 static const char VMEXIT_POPF_STR[] = "VMEXIT_POPF";
604 static const char VMEXIT_CPUID_STR[] = "VMEXIT_CPUID";
605 static const char VMEXIT_RSM_STR[] = "VMEXIT_RSM";
606 static const char VMEXIT_IRET_STR[] = "VMEXIT_IRET";
607 static const char VMEXIT_SWINT_STR[] = "VMEXIT_SWINT";
608 static const char VMEXIT_INVD_STR[] = "VMEXIT_INVD";
609 static const char VMEXIT_PAUSE_STR[] = "VMEXIT_PAUSE";
610 static const char VMEXIT_HLT_STR[] = "VMEXIT_HLT";
611 static const char VMEXIT_INVLPG_STR[] = "VMEXIT_INVLPG";
612 static const char VMEXIT_INVLPGA_STR[] = "VMEXIT_INVLPGA";
613 static const char VMEXIT_IOIO_STR[] = "VMEXIT_IOIO";
614 static const char VMEXIT_MSR_STR[] = "VMEXIT_MSR";
615 static const char VMEXIT_TASK_SWITCH_STR[] = "VMEXIT_TASK_SWITCH";
616 static const char VMEXIT_FERR_FREEZE_STR[] = "VMEXIT_FERR_FREEZE";
617 static const char VMEXIT_SHUTDOWN_STR[] = "VMEXIT_SHUTDOWN";
618 static const char VMEXIT_VMRUN_STR[] = "VMEXIT_VMRUN";
619 static const char VMEXIT_VMMCALL_STR[] = "VMEXIT_VMMCALL";
620 static const char VMEXIT_VMLOAD_STR[] = "VMEXIT_VMLOAD";
621 static const char VMEXIT_VMSAVE_STR[] = "VMEXIT_VMSAVE";
622 static const char VMEXIT_STGI_STR[] = "VMEXIT_STGI";
623 static const char VMEXIT_CLGI_STR[] = "VMEXIT_CLGI";
624 static const char VMEXIT_SKINIT_STR[] = "VMEXIT_SKINIT";
625 static const char VMEXIT_RDTSCP_STR[] = "VMEXIT_RDTSCP";
626 static const char VMEXIT_ICEBP_STR[] = "VMEXIT_ICEBP";
627 static const char VMEXIT_WBINVD_STR[] = "VMEXIT_WBINVD";
628 static const char VMEXIT_MONITOR_STR[] = "VMEXIT_MONITOR";
629 static const char VMEXIT_MWAIT_STR[] = "VMEXIT_MWAIT";
630 static const char VMEXIT_MWAIT_CONDITIONAL_STR[] = "VMEXIT_MWAIT_CONDITIONAL";
631 static const char VMEXIT_NPF_STR[] = "VMEXIT_NPF";
632 static const char VMEXIT_INVALID_VMCB_STR[] = "VMEXIT_INVALID_VMCB";
633
634
635
636 const char * vmexit_code_to_str(uint_t exit_code) {
637   switch(exit_code) {
638   case VMEXIT_CR0_READ:
639     return VMEXIT_CR0_READ_STR;
640   case VMEXIT_CR1_READ:
641     return VMEXIT_CR1_READ_STR;
642   case VMEXIT_CR2_READ:
643     return VMEXIT_CR2_READ_STR;
644   case VMEXIT_CR3_READ:
645     return VMEXIT_CR3_READ_STR;
646   case VMEXIT_CR4_READ:
647     return VMEXIT_CR4_READ_STR;
648   case VMEXIT_CR5_READ:
649     return VMEXIT_CR5_READ_STR;
650   case VMEXIT_CR6_READ:
651     return VMEXIT_CR6_READ_STR;
652   case VMEXIT_CR7_READ:
653     return VMEXIT_CR7_READ_STR;
654   case VMEXIT_CR8_READ:
655     return VMEXIT_CR8_READ_STR;
656   case VMEXIT_CR9_READ:
657     return VMEXIT_CR9_READ_STR;
658   case VMEXIT_CR10_READ:
659     return VMEXIT_CR10_READ_STR;
660   case VMEXIT_CR11_READ:
661     return VMEXIT_CR11_READ_STR;
662   case VMEXIT_CR12_READ:
663     return VMEXIT_CR12_READ_STR;
664   case VMEXIT_CR13_READ:
665     return VMEXIT_CR13_READ_STR;
666   case VMEXIT_CR14_READ:
667     return VMEXIT_CR14_READ_STR;
668   case VMEXIT_CR15_READ:
669     return VMEXIT_CR15_READ_STR;
670   case VMEXIT_CR0_WRITE:
671     return VMEXIT_CR0_WRITE_STR;
672   case VMEXIT_CR1_WRITE:
673     return VMEXIT_CR1_WRITE_STR;
674   case VMEXIT_CR2_WRITE:
675     return VMEXIT_CR2_WRITE_STR;
676   case VMEXIT_CR3_WRITE:
677     return VMEXIT_CR3_WRITE_STR;
678   case VMEXIT_CR4_WRITE:
679     return VMEXIT_CR4_WRITE_STR;
680   case VMEXIT_CR5_WRITE:
681     return VMEXIT_CR5_WRITE_STR;
682   case VMEXIT_CR6_WRITE:
683     return VMEXIT_CR6_WRITE_STR;
684   case VMEXIT_CR7_WRITE:
685     return VMEXIT_CR7_WRITE_STR;
686   case VMEXIT_CR8_WRITE:
687     return VMEXIT_CR8_WRITE_STR;
688   case VMEXIT_CR9_WRITE:
689     return VMEXIT_CR9_WRITE_STR;
690   case VMEXIT_CR10_WRITE:
691     return VMEXIT_CR10_WRITE_STR;
692   case VMEXIT_CR11_WRITE:
693     return VMEXIT_CR11_WRITE_STR;
694   case VMEXIT_CR12_WRITE:
695     return VMEXIT_CR12_WRITE_STR;
696   case VMEXIT_CR13_WRITE:
697     return VMEXIT_CR13_WRITE_STR;
698   case VMEXIT_CR14_WRITE:
699     return VMEXIT_CR14_WRITE_STR;
700   case VMEXIT_CR15_WRITE:
701     return VMEXIT_CR15_WRITE_STR;
702   case VMEXIT_DR0_READ:
703     return VMEXIT_DR0_READ_STR;
704   case VMEXIT_DR1_READ:
705     return VMEXIT_DR1_READ_STR;
706   case VMEXIT_DR2_READ:
707     return VMEXIT_DR2_READ_STR;
708   case VMEXIT_DR3_READ:
709     return VMEXIT_DR3_READ_STR;
710   case VMEXIT_DR4_READ:
711     return VMEXIT_DR4_READ_STR;
712   case VMEXIT_DR5_READ:
713     return VMEXIT_DR5_READ_STR;
714   case VMEXIT_DR6_READ:
715     return VMEXIT_DR6_READ_STR;
716   case VMEXIT_DR7_READ:
717     return VMEXIT_DR7_READ_STR;
718   case VMEXIT_DR8_READ:
719     return VMEXIT_DR8_READ_STR;
720   case VMEXIT_DR9_READ:
721     return VMEXIT_DR9_READ_STR;
722   case VMEXIT_DR10_READ:
723     return VMEXIT_DR10_READ_STR;
724   case VMEXIT_DR11_READ:
725     return VMEXIT_DR11_READ_STR;
726   case VMEXIT_DR12_READ:
727     return VMEXIT_DR12_READ_STR;
728   case VMEXIT_DR13_READ:
729     return VMEXIT_DR13_READ_STR;
730   case VMEXIT_DR14_READ:
731     return VMEXIT_DR14_READ_STR;
732   case VMEXIT_DR15_READ:
733     return VMEXIT_DR15_READ_STR;
734   case VMEXIT_DR0_WRITE:
735     return VMEXIT_DR0_WRITE_STR;
736   case VMEXIT_DR1_WRITE:
737     return VMEXIT_DR1_WRITE_STR;
738   case VMEXIT_DR2_WRITE:
739     return VMEXIT_DR2_WRITE_STR;
740   case VMEXIT_DR3_WRITE:
741     return VMEXIT_DR3_WRITE_STR;
742   case VMEXIT_DR4_WRITE:
743     return VMEXIT_DR4_WRITE_STR;
744   case VMEXIT_DR5_WRITE:
745     return VMEXIT_DR5_WRITE_STR;
746   case VMEXIT_DR6_WRITE:
747     return VMEXIT_DR6_WRITE_STR;
748   case VMEXIT_DR7_WRITE:
749     return VMEXIT_DR7_WRITE_STR;
750   case VMEXIT_DR8_WRITE:
751     return VMEXIT_DR8_WRITE_STR;
752   case VMEXIT_DR9_WRITE:
753     return VMEXIT_DR9_WRITE_STR;
754   case VMEXIT_DR10_WRITE:
755     return VMEXIT_DR10_WRITE_STR;
756   case VMEXIT_DR11_WRITE:
757     return VMEXIT_DR11_WRITE_STR;
758   case VMEXIT_DR12_WRITE:
759     return VMEXIT_DR12_WRITE_STR;
760   case VMEXIT_DR13_WRITE:
761     return VMEXIT_DR13_WRITE_STR;
762   case VMEXIT_DR14_WRITE:
763     return VMEXIT_DR14_WRITE_STR;
764   case VMEXIT_DR15_WRITE:
765     return VMEXIT_DR15_WRITE_STR;
766   case VMEXIT_EXCP0:
767     return VMEXIT_EXCP0_STR;
768   case VMEXIT_EXCP1:
769     return VMEXIT_EXCP1_STR;
770   case VMEXIT_EXCP2:
771     return VMEXIT_EXCP2_STR;
772   case VMEXIT_EXCP3:
773     return VMEXIT_EXCP3_STR;
774   case VMEXIT_EXCP4:
775     return VMEXIT_EXCP4_STR;
776   case VMEXIT_EXCP5:
777     return VMEXIT_EXCP5_STR;
778   case VMEXIT_EXCP6:
779     return VMEXIT_EXCP6_STR;
780   case VMEXIT_EXCP7:
781     return VMEXIT_EXCP7_STR;
782   case VMEXIT_EXCP8:
783     return VMEXIT_EXCP8_STR;
784   case VMEXIT_EXCP9:
785     return VMEXIT_EXCP9_STR;
786   case VMEXIT_EXCP10:
787     return VMEXIT_EXCP10_STR;
788   case VMEXIT_EXCP11:
789     return VMEXIT_EXCP11_STR;
790   case VMEXIT_EXCP12:
791     return VMEXIT_EXCP12_STR;
792   case VMEXIT_EXCP13:
793     return VMEXIT_EXCP13_STR;
794   case VMEXIT_EXCP14:
795     return VMEXIT_EXCP14_STR;
796   case VMEXIT_EXCP15:
797     return VMEXIT_EXCP15_STR;
798   case VMEXIT_EXCP16:
799     return VMEXIT_EXCP16_STR;
800   case VMEXIT_EXCP17:
801     return VMEXIT_EXCP17_STR;
802   case VMEXIT_EXCP18:
803     return VMEXIT_EXCP18_STR;
804   case VMEXIT_EXCP19:
805     return VMEXIT_EXCP19_STR;
806   case VMEXIT_EXCP20:
807     return VMEXIT_EXCP20_STR;
808   case VMEXIT_EXCP21:
809     return VMEXIT_EXCP21_STR;
810   case VMEXIT_EXCP22:
811     return VMEXIT_EXCP22_STR;
812   case VMEXIT_EXCP23:
813     return VMEXIT_EXCP23_STR;
814   case VMEXIT_EXCP24:
815     return VMEXIT_EXCP24_STR;
816   case VMEXIT_EXCP25:
817     return VMEXIT_EXCP25_STR;
818   case VMEXIT_EXCP26:
819     return VMEXIT_EXCP26_STR;
820   case VMEXIT_EXCP27:
821     return VMEXIT_EXCP27_STR;
822   case VMEXIT_EXCP28:
823     return VMEXIT_EXCP28_STR;
824   case VMEXIT_EXCP29:
825     return VMEXIT_EXCP29_STR;
826   case VMEXIT_EXCP30:
827     return VMEXIT_EXCP30_STR;
828   case VMEXIT_EXCP31:
829     return VMEXIT_EXCP31_STR;
830   case VMEXIT_INTR:
831     return VMEXIT_INTR_STR;
832   case VMEXIT_NMI:
833     return VMEXIT_NMI_STR;
834   case VMEXIT_SMI:
835     return VMEXIT_SMI_STR;
836   case VMEXIT_INIT:
837     return VMEXIT_INIT_STR;
838   case VMEXIT_VINITR:
839     return VMEXIT_VINITR_STR;
840   case VMEXIT_CR0_SEL_WRITE:
841     return VMEXIT_CR0_SEL_WRITE_STR;
842   case VMEXIT_IDTR_READ:
843     return VMEXIT_IDTR_READ_STR;
844   case VMEXIT_GDTR_READ:
845     return VMEXIT_GDTR_READ_STR;
846   case VMEXIT_LDTR_READ:
847     return VMEXIT_LDTR_READ_STR;
848   case VMEXIT_TR_READ:
849     return VMEXIT_TR_READ_STR;
850   case VMEXIT_IDTR_WRITE:
851     return VMEXIT_IDTR_WRITE_STR;
852   case VMEXIT_GDTR_WRITE:
853     return VMEXIT_GDTR_WRITE_STR;
854   case VMEXIT_LDTR_WRITE:
855     return VMEXIT_LDTR_WRITE_STR;
856   case VMEXIT_TR_WRITE:
857     return VMEXIT_TR_WRITE_STR;
858   case VMEXIT_RDTSC:
859     return VMEXIT_RDTSC_STR;
860   case VMEXIT_RDPMC:
861     return VMEXIT_RDPMC_STR;
862   case VMEXIT_PUSHF:
863     return VMEXIT_PUSHF_STR;
864   case VMEXIT_POPF:
865     return VMEXIT_POPF_STR;
866   case VMEXIT_CPUID:
867     return VMEXIT_CPUID_STR;
868   case VMEXIT_RSM:
869     return VMEXIT_RSM_STR;
870   case VMEXIT_IRET:
871     return VMEXIT_IRET_STR;
872   case VMEXIT_SWINT:
873     return VMEXIT_SWINT_STR;
874   case VMEXIT_INVD:
875     return VMEXIT_INVD_STR;
876   case VMEXIT_PAUSE:
877     return VMEXIT_PAUSE_STR;
878   case VMEXIT_HLT:
879     return VMEXIT_HLT_STR;
880   case VMEXIT_INVLPG:
881     return VMEXIT_INVLPG_STR;
882   case VMEXIT_INVLPGA:
883     return VMEXIT_INVLPGA_STR;
884   case VMEXIT_IOIO:
885     return VMEXIT_IOIO_STR;
886   case VMEXIT_MSR:
887     return VMEXIT_MSR_STR;
888   case VMEXIT_TASK_SWITCH:
889     return VMEXIT_TASK_SWITCH_STR;
890   case VMEXIT_FERR_FREEZE:
891     return VMEXIT_FERR_FREEZE_STR;
892   case VMEXIT_SHUTDOWN:
893     return VMEXIT_SHUTDOWN_STR;
894   case VMEXIT_VMRUN:
895     return VMEXIT_VMRUN_STR;
896   case VMEXIT_VMMCALL:
897     return VMEXIT_VMMCALL_STR;
898   case VMEXIT_VMLOAD:
899     return VMEXIT_VMLOAD_STR;
900   case VMEXIT_VMSAVE:
901     return VMEXIT_VMSAVE_STR;
902   case VMEXIT_STGI:
903     return VMEXIT_STGI_STR;
904   case VMEXIT_CLGI:
905     return VMEXIT_CLGI_STR;
906   case VMEXIT_SKINIT:
907     return VMEXIT_SKINIT_STR;
908   case VMEXIT_RDTSCP:
909     return VMEXIT_RDTSCP_STR;
910   case VMEXIT_ICEBP:
911     return VMEXIT_ICEBP_STR;
912   case VMEXIT_WBINVD:
913     return VMEXIT_WBINVD_STR;
914   case VMEXIT_MONITOR:
915     return VMEXIT_MONITOR_STR;
916   case VMEXIT_MWAIT:
917     return VMEXIT_MWAIT_STR;
918   case VMEXIT_MWAIT_CONDITIONAL:
919     return VMEXIT_MWAIT_CONDITIONAL_STR;
920   case VMEXIT_NPF:
921     return VMEXIT_NPF_STR;
922   case VMEXIT_INVALID_VMCB:
923     return VMEXIT_INVALID_VMCB_STR;
924   }
925   return NULL;
926 }