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.


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