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   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
77
78     /*
79   } else if (( (exit_code == VMEXIT_CR3_READ)  ||
80                (exit_code == VMEXIT_CR3_WRITE) ||
81                (exit_code == VMEXIT_INVLPG)    ||
82                (exit_code == VMEXIT_INVLPGA)   || 
83                (exit_code == VMEXIT_EXCP14)) && 
84              (info->page_mode == SHADOW_PAGING)) {
85     handle_shadow_paging(info);
86     */
87
88   } else if (exit_code == VMEXIT_INTR) {
89
90     //    handle_svm_intr(info);
91
92   } else if (exit_code == VMEXIT_HLT) {
93     PrintDebug("Guest halted\n");
94     return -1;
95   } else {
96     addr_t rip_addr = get_addr_linear(info, guest_state->rip, guest_state->cs.selector);
97     char buf[15];
98     addr_t host_addr;
99
100
101     PrintDebug("SVM Returned:(VMCB=%x)\n", info->vmm_data); 
102     PrintDebug("RIP: %x\n", guest_state->rip);
103     PrintDebug("RIP Linear: %x\n", rip_addr);
104     
105     PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); 
106     
107     PrintDebug("io_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1));
108     PrintDebug("io_info1 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
109     
110     PrintDebug("io_info2 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info2));
111     PrintDebug("io_info2 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
112
113     
114
115     if (guest_pa_to_host_pa(info, guest_state->rip, &host_addr) == -1) {
116       PrintDebug("Could not translate guest_state->rip to host address\n");
117       return -1;
118     }
119
120     PrintDebug("Host Address of rip = 0x%x\n", host_addr);
121
122     memset(buf, 0, 15);
123     
124     PrintDebug("Reading from 0x%x in guest\n", rip_addr);
125     
126     read_guest_pa_memory(info, rip_addr, 15, buf);
127
128     PrintTraceMemDump(buf, 15);
129
130     while(1);
131
132   }
133
134
135   // Update the low level state
136
137   if (intr_pending(&(info->intr_state))) {
138
139     switch (get_intr_type(&(info->intr_state))) {
140     case EXTERNAL_IRQ:
141       guest_ctrl->EVENTINJ.vector = get_intr_number(&(info->intr_state));
142       guest_ctrl->EVENTINJ.valid = 1;
143       guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXTERNAL_INTR;
144       break;
145     case NMI:
146       guest_ctrl->EVENTINJ.type = SVM_INJECTION_NMI;
147       break;
148     case EXCEPTION:
149       guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION;
150       guest_ctrl->EVENTINJ.error_code = info->intr_state.excp_error_code;
151       break;
152     case SOFTWARE:
153       guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
154       break;
155     case VIRTUAL:
156       guest_ctrl->EVENTINJ.type = SVM_INJECTION_VIRTUAL_INTR;
157       break;
158
159     case INVALID_INTR: 
160     default:
161       PrintDebug("Attempted to issue an invalid interrupt\n");
162       return -1;
163     }
164
165
166     PrintDebug("Injecting Interrupt %d\n", guest_ctrl->EVENTINJ.vector);
167  
168
169     // IMPORTANT TODO
170     // We need to figure out stack parameters....
171
172     //EVENTINJ.error_code
173
174   }
175
176   guest_state->rax = info->vm_regs.rax;
177   guest_state->rip = info->rip;
178   guest_state->rsp = info->vm_regs.rsp;
179
180   return 0;
181 }
182
183
184
185
186 int handle_shadow_paging(struct guest_info * info) {
187   vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
188   //  vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
189
190   if (guest_ctrl->exit_code == VMEXIT_CR3_READ) {
191
192   }
193
194   return 0;
195 }
196
197
198
199 int handle_svm_intr(struct guest_info * info) {
200   vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
201   // vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
202
203   //struct Interrupt_Info * int_info = &(guest_ctrl->exit_int_info);
204
205   //struct vmm_irq_hook * get_irq_hook(&(info->irq_map), int_info->vector);
206
207   PrintDebug("SVM Returned: Exit Code: %x\n",guest_ctrl->exit_code); 
208   PrintDebug("V_INTR_VECTOR: 0x%x\n", guest_ctrl->guest_ctrl.V_INTR_VECTOR);
209   
210
211
212
213   while(1);
214
215                                      
216
217
218
219   
220  
221  
222     
223   return 0;
224 }