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.


architecture independence work
[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/vmm_ctrl_regs.h>
6 #include <palacios/svm_io.h>
7 #include <palacios/vmm_intr.h>
8
9
10 extern struct vmm_os_hooks * os_hooks;
11
12
13 int handle_svm_exit(struct guest_info * info) {
14   vmcb_ctrl_t * guest_ctrl = 0;
15   vmcb_saved_state_t * guest_state = 0;
16   ulong_t exit_code = 0;
17   
18   guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
19   guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
20   
21
22   // Update the high level state 
23   info->rip = guest_state->rip;
24   info->vm_regs.rsp = guest_state->rsp;
25   info->vm_regs.rax = guest_state->rax;
26   info->vm_regs.rsp = guest_state->rsp;  
27
28
29   info->ctrl_regs.cr0 = guest_state->cr0;
30   info->ctrl_regs.cr2 = guest_state->cr2;
31   info->ctrl_regs.cr3 = guest_state->cr3;
32   info->ctrl_regs.cr4 = guest_state->cr4;
33   info->ctrl_regs.cr8 = guest_ctrl->guest_ctrl.V_TPR;
34   info->ctrl_regs.rflags = guest_state->rflags;
35
36   get_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
37
38
39   exit_code = guest_ctrl->exit_code;
40  
41   PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); 
42   // PrintDebugVMCB((vmcb_t*)(info->vmm_data));
43
44
45   // PrintDebug("SVM Returned:(VMCB=%x)\n", info->vmm_data); 
46   //PrintDebug("RIP: %x\n", guest_state->rip);
47
48   
49   //PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); 
50   
51   if (exit_code == VMEXIT_IOIO) {
52     struct svm_io_info * io_info = (struct svm_io_info *)&(guest_ctrl->exit_info1);
53     
54     if (io_info->type == 0) {
55       if (io_info->str) {
56         if (handle_svm_io_outs(info) == -1 ) {
57           return -1;
58         }
59       } else {
60         if (handle_svm_io_out(info) == -1) {
61           return -1;
62         }
63       }
64     } else {
65       if (io_info->str) {
66         if (handle_svm_io_ins(info) == -1) {
67           return -1;
68         }
69       } else {
70         if (handle_svm_io_in(info) == -1) {
71           return -1;
72         }
73       }
74     }
75   } else if (exit_code == VMEXIT_CR0_WRITE) {
76     PrintDebug("CR0 Write\n");
77
78     if (handle_cr0_write(info) == -1) {
79       return -1;
80     }
81   } else if (exit_code == VMEXIT_CR0_READ) {
82     PrintDebug("CR0 Read\n");
83
84     if (handle_cr0_read(info) == -1) {
85       return -1;
86     }
87   } else if (exit_code == VMEXIT_CR3_WRITE) {
88     PrintDebug("CR3 Write\n");
89
90     if (handle_cr3_write(info) == -1) {
91       return -1;
92     }    
93   } else if (exit_code == VMEXIT_CR3_READ) {
94     PrintDebug("CR3 Read\n");
95
96     if (handle_cr3_read(info) == -1) {
97       return -1;
98     }
99
100   } else if (exit_code == VMEXIT_EXCP14) {
101     addr_t fault_addr = guest_ctrl->exit_info2;
102     pf_error_t * error_code = (pf_error_t *)&(guest_ctrl->exit_info1);
103     
104     PrintDebug("PageFault at %x (error=%d)\n", fault_addr, *error_code);
105
106   
107
108     if (handle_shadow_pagefault(info, fault_addr, *error_code) == -1) {
109       return -1;
110     }
111
112     /*
113       } else if (( (exit_code == VMEXIT_CR3_READ)  ||
114       (exit_code == VMEXIT_CR3_WRITE) ||
115       (exit_code == VMEXIT_INVLPG)    ||
116       (exit_code == VMEXIT_INVLPGA)   || 
117       (exit_code == VMEXIT_EXCP14)) && 
118       (info->page_mode == SHADOW_PAGING)) {
119       handle_shadow_paging(info);
120     */
121     
122   } else if (exit_code == VMEXIT_INTR) {
123
124     //    handle_svm_intr(info);
125
126   } else if (exit_code == VMEXIT_HLT) {
127     PrintDebug("Guest halted\n");
128     return -1;
129   } else {
130     addr_t rip_addr;
131     char buf[15];
132     addr_t host_addr;
133
134
135     rip_addr = get_addr_linear(info, guest_state->rip, &(info->segments.cs));
136
137
138
139     PrintDebug("SVM Returned:(VMCB=%x)\n", info->vmm_data); 
140     PrintDebug("RIP: %x\n", guest_state->rip);
141     PrintDebug("RIP Linear: %x\n", rip_addr);
142     
143     PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); 
144     
145     PrintDebug("io_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1));
146     PrintDebug("io_info1 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
147     
148     PrintDebug("io_info2 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info2));
149     PrintDebug("io_info2 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
150
151     
152
153     if (guest_pa_to_host_pa(info, guest_state->rip, &host_addr) == -1) {
154       PrintDebug("Could not translate guest_state->rip to host address\n");
155       return -1;
156     }
157
158     PrintDebug("Host Address of rip = 0x%x\n", host_addr);
159
160     memset(buf, 0, 15);
161     
162     PrintDebug("Reading from 0x%x in guest\n", rip_addr);
163     
164     read_guest_pa_memory(info, rip_addr, 15, buf);
165
166     PrintTraceMemDump(buf, 15);
167
168     while(1);
169
170   }
171
172
173   // Update the low level state
174
175   if (intr_pending(&(info->intr_state))) {
176
177     switch (get_intr_type(&(info->intr_state))) {
178     case EXTERNAL_IRQ:
179       guest_ctrl->EVENTINJ.vector = get_intr_number(&(info->intr_state));
180       guest_ctrl->EVENTINJ.valid = 1;
181       guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXTERNAL_INTR;
182       
183       break;
184     case NMI:
185       guest_ctrl->EVENTINJ.type = SVM_INJECTION_NMI;
186       break;
187     case EXCEPTION:
188       guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION;
189       guest_ctrl->EVENTINJ.error_code = info->intr_state.excp_error_code;
190       break;
191     case SOFTWARE:
192       guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
193       break;
194     case VIRTUAL:
195       guest_ctrl->EVENTINJ.type = SVM_INJECTION_VIRTUAL_INTR;
196       break;
197
198     case INVALID_INTR: 
199     default:
200       PrintDebug("Attempted to issue an invalid interrupt\n");
201       return -1;
202     }
203
204
205     PrintDebug("Injecting Interrupt %d (EIP=%x)\n", guest_ctrl->EVENTINJ.vector, info->rip);
206  
207
208     // IMPORTANT TODO
209     // We need to figure out stack parameters....
210
211     //EVENTINJ.error_code
212
213   }
214
215
216   guest_state->cr0 = info->ctrl_regs.cr0;
217   guest_state->cr2 = info->ctrl_regs.cr2;
218   guest_state->cr3 = info->ctrl_regs.cr3;
219   guest_state->cr4 = info->ctrl_regs.cr4;
220   guest_ctrl->guest_ctrl.V_TPR = info->ctrl_regs.cr8 & 0xff;
221   guest_state->rflags = info->ctrl_regs.rflags;
222
223
224   guest_state->rax = info->vm_regs.rax;
225   guest_state->rip = info->rip;
226   guest_state->rsp = info->vm_regs.rsp;
227
228
229   set_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
230
231   if (exit_code == VMEXIT_INTR) {
232     PrintDebug("INTR ret IP = %x\n", guest_state->rip);
233   }
234
235   return 0;
236 }
237
238
239
240
241 int handle_shadow_paging(struct guest_info * info) {
242   vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
243   //  vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
244
245   if (guest_ctrl->exit_code == VMEXIT_CR3_READ) {
246
247   }
248
249   return 0;
250 }
251
252
253
254 int handle_svm_intr(struct guest_info * info) {
255   vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
256   // vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
257
258   //struct Interrupt_Info * int_info = &(guest_ctrl->exit_int_info);
259
260   //struct vmm_irq_hook * get_irq_hook(&(info->irq_map), int_info->vector);
261
262   PrintDebug("SVM Returned: Exit Code: %x\n",guest_ctrl->exit_code); 
263   PrintDebug("V_INTR_VECTOR: 0x%x\n", guest_ctrl->guest_ctrl.V_INTR_VECTOR);
264
265   while(1);
266     
267   return 0;
268 }