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.


*** empty log message ***
[palacios.git] / palacios / src / palacios / svm_handler.c
1 #include <palacios/svm_handler.h>
2 #include <palacios/vmm.h>
3 #include <palacios/vm_guest_mem.h>
4 #include <palacios/vmm_emulate.h>
5 #include <palacios/svm_ctrl_regs.h>
6 #include <palacios/svm_io.h>
7 #include <palacios/vmm_intr.h>
8
9 extern struct vmm_os_hooks * os_hooks;
10
11
12 int handle_svm_exit(struct guest_info * info) {
13   vmcb_ctrl_t * guest_ctrl = 0;
14   vmcb_saved_state_t * guest_state = 0;
15   ulong_t exit_code = 0;
16   
17   guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
18   guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
19   
20
21   // Update the high level state 
22   info->rip = guest_state->rip;
23   info->vm_regs.rsp = guest_state->rsp;
24   info->vm_regs.rax = guest_state->rax;
25   info->vm_regs.rsp = guest_state->rsp;
26
27
28
29   
30
31
32   exit_code = guest_ctrl->exit_code;
33   
34   // PrintDebugVMCB((vmcb_t*)(info->vmm_data));
35
36   
37   if (exit_code == VMEXIT_IOIO) {
38     struct svm_io_info * io_info = (struct svm_io_info *)&(guest_ctrl->exit_info1);
39     
40     if (io_info->type == 0) {
41       if (io_info->str) {
42         handle_svm_io_outs(info);
43       } else {
44         handle_svm_io_out(info);
45       }
46     } else {
47       if (io_info->str) {
48         handle_svm_io_ins(info);
49       } else {
50         handle_svm_io_in(info);
51       }
52     }
53   } else if (exit_code == VMEXIT_CR0_WRITE) {
54     PrintDebug("CR0 Write\n");
55
56     if (handle_cr0_write(info) == -1) {
57       return -1;
58     }
59     /*
60   } else if (( (exit_code == VMEXIT_CR3_READ)  ||
61                (exit_code == VMEXIT_CR3_WRITE) ||
62                (exit_code == VMEXIT_INVLPG)    ||
63                (exit_code == VMEXIT_INVLPGA)   || 
64                (exit_code == VMEXIT_EXCP14)) && 
65              (info->page_mode == SHADOW_PAGING)) {
66     handle_shadow_paging(info);
67     */
68   } else {
69     addr_t rip_addr = get_addr_linear(info, guest_state->rip, guest_state->cs.selector);
70     char buf[15];
71     addr_t host_addr;
72
73
74     PrintDebug("SVM Returned:(VMCB=%x)\n", info->vmm_data); 
75     PrintDebug("RIP: %x\n", guest_state->rip);
76     PrintDebug("RIP Linear: %x\n", rip_addr);
77     
78     PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); 
79     
80     PrintDebug("io_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1));
81     PrintDebug("io_info1 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
82     
83     PrintDebug("io_info2 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info2));
84     PrintDebug("io_info2 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
85
86     
87
88     if (guest_pa_to_host_pa(info, guest_state->rip, &host_addr) == -1) {
89       PrintDebug("Could not translate guest_state->rip to host address\n");
90       return -1;
91     }
92
93     PrintDebug("Host Address of rip = 0x%x\n", host_addr);
94
95     memset(buf, 0, 15);
96     
97     PrintDebug("Reading from 0x%x in guest\n", rip_addr);
98     
99     read_guest_pa_memory(info, rip_addr, 15, buf);
100
101     PrintTraceMemDump(buf, 15);
102
103     while(1);
104
105   }
106
107
108   // Update the low level state
109
110   if (intr_pending(&(info->intr_state))) {
111     guest_ctrl->EVENTINJ.vector = get_intr_number(&(info->intr_state));
112     guest_ctrl->EVENTINJ.valid = 1;
113  
114     switch (get_intr_type(&(info->intr_state))) {
115     case EXTERNAL_IRQ:
116       guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXTERNAL_INTR;
117       break;
118     case NMI:
119       guest_ctrl->EVENTINJ.type = SVM_INJECTION_NMI;
120       break;
121     case EXCEPTION:
122       guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION;
123       guest_ctrl->EVENTINJ.excp_error_code = info->intr_state.excp_error_code;
124       break;
125     case SOFTWARE:
126       guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
127       break;
128     case VIRTUAL:
129       guest_ctrl->EVENTINJ.type = SVM_INJECTION_VIRTUAL_INTR;
130       break;
131
132     case INVALID_INTR: 
133     default:
134       PrintDebug("Attempted to issue an invalid interrupt\n");
135       return -1;
136     }
137
138     // IMPORTANT TODO
139     // We need to figure out stack parameters....
140
141     //EVENTINJ.error_code
142
143   }
144
145   guest_state->rax = info->vm_regs.rax;
146   guest_state->rip = info->rip;
147   guest_state->rsp = info->vm_regs.rsp;
148
149   return 0;
150 }
151
152
153
154
155 int handle_shadow_paging(struct guest_info * info) {
156   vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
157   //  vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
158
159   if (guest_ctrl->exit_code == VMEXIT_CR3_READ) {
160
161   }
162
163   return 0;
164 }
165
166
167