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.


a guest kernel that works equally well on the dell+HP
[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     guest_ctrl->EVENTINJ.vector = get_intr_number(&(info->intr_state));
140     guest_ctrl->EVENTINJ.valid = 1;
141
142     PrintDebug("Injecting Interrupt %d\n", guest_ctrl->EVENTINJ.vector);
143  
144     switch (get_intr_type(&(info->intr_state))) {
145     case EXTERNAL_IRQ:
146       guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXTERNAL_INTR;
147       break;
148     case NMI:
149       guest_ctrl->EVENTINJ.type = SVM_INJECTION_NMI;
150       break;
151     case EXCEPTION:
152       guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION;
153       guest_ctrl->EVENTINJ.error_code = info->intr_state.excp_error_code;
154       break;
155     case SOFTWARE:
156       guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
157       break;
158     case VIRTUAL:
159       guest_ctrl->EVENTINJ.type = SVM_INJECTION_VIRTUAL_INTR;
160       break;
161
162     case INVALID_INTR: 
163     default:
164       PrintDebug("Attempted to issue an invalid interrupt\n");
165       return -1;
166     }
167
168     // IMPORTANT TODO
169     // We need to figure out stack parameters....
170
171     //EVENTINJ.error_code
172
173   }
174
175   guest_state->rax = info->vm_regs.rax;
176   guest_state->rip = info->rip;
177   guest_state->rsp = info->vm_regs.rsp;
178
179   return 0;
180 }
181
182
183
184
185 int handle_shadow_paging(struct guest_info * info) {
186   vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
187   //  vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
188
189   if (guest_ctrl->exit_code == VMEXIT_CR3_READ) {
190
191   }
192
193   return 0;
194 }
195
196
197
198 int handle_svm_intr(struct guest_info * info) {
199   vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
200   // vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
201
202   //struct Interrupt_Info * int_info = &(guest_ctrl->exit_int_info);
203
204   //struct vmm_irq_hook * get_irq_hook(&(info->irq_map), int_info->vector);
205
206   PrintDebug("SVM Returned: Exit Code: %x\n",guest_ctrl->exit_code); 
207   PrintDebug("V_INTR_VECTOR: 0x%x\n", guest_ctrl->guest_ctrl.V_INTR_VECTOR);
208   
209
210
211
212   while(1);
213
214                                      
215
216
217
218   
219  
220  
221     
222   return 0;
223 }