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.


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