1 #include <palacios/svm_ctrl_regs.h>
2 #include <palacios/vmm_mem.h>
3 #include <palacios/vmm.h>
4 #include <palacios/vmcb.h>
5 #include <palacios/vmm_emulate.h>
6 #include <palacios/vm_guest_mem.h>
7 #include <palacios/vmm_ctrl_regs.h>
10 /* Segmentation is a problem here...
12 * When we get a memory operand, presumably we use the default segment (which is?)
13 * unless an alternate segment was specfied in the prefix...
17 int handle_cr0_write(struct guest_info * info) {
18 //vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t *)(info->vmm_data));
19 vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
23 if (info->cpu_mode == REAL) {
27 // The real rip address is actually a combination of the rip + CS base
28 ret = read_guest_pa_memory(info, get_addr_linear(info, guest_state->rip, guest_state->cs.selector), 15, instr);
30 // I think we should inject a GPF into the guest
31 PrintDebug("Could not read instruction (ret=%d)\n", ret);
35 while (is_prefix_byte(instr[index])) {
39 if ((instr[index] == cr_access_byte) &&
40 (instr[index + 1] == lmsw_byte) &&
41 (MODRM_REG(instr[index + 2]) == lmsw_reg_byte)) {
44 addr_t second_operand;
45 struct cr0_real *real_cr0;
46 struct cr0_real *new_cr0;
47 operand_type_t addr_type;
53 real_cr0 = (struct cr0_real*)&(guest_state->cr0);
55 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG16);
58 if (addr_type == REG_OPERAND) {
59 new_cr0 = (struct cr0_real *)first_operand;
60 } else if (addr_type == MEM_OPERAND) {
63 if (guest_pa_to_host_va(info, first_operand + (guest_state->ds.base << 4), &host_addr) == -1) {
68 new_cr0 = (struct cr0_real *)host_addr;
70 // error... don't know what to do
74 if ((new_cr0->pe == 1) && (real_cr0->pe == 0)) {
75 info->cpu_mode = PROTECTED;
76 } else if ((new_cr0->pe == 0) && (real_cr0->pe == 1)) {
77 info->cpu_mode = REAL;
80 new_cr0_val = *(char*)(new_cr0) & 0x0f;
83 if (info->page_mode == SHADOW_PAGING) {
84 struct cr0_real * shadow_cr0 = (struct cr0_real*)&(info->shdw_pg_state.guest_cr0);
86 PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
87 /* struct cr0_real is only 4 bits wide,
88 * so we can overwrite the real_cr0 without worrying about the shadow fields
90 *(char*)real_cr0 &= 0xf0;
91 *(char*)real_cr0 |= new_cr0_val;
93 *(char*)shadow_cr0 &= 0xf0;
94 *(char*)shadow_cr0 |= new_cr0_val;
96 PrintDebug("New CR0=%x, New Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
98 PrintDebug("Old CR0=%x\n", *real_cr0);
99 // for now we just pass through....
100 *(char*)real_cr0 &= 0xf0;
101 *(char*)real_cr0 |= new_cr0_val;
103 PrintDebug("New CR0=%x\n", *real_cr0);
109 } else if ((instr[index] == cr_access_byte) &&
110 (instr[index + 1] == clts_byte)) {
114 } else if ((instr[index] == cr_access_byte) &&
115 (instr[index + 1] = mov_to_cr_byte)) {
116 addr_t first_operand;
117 addr_t second_operand;
118 struct cr0_32 *real_cr0;
119 struct cr0_32 *new_cr0;
120 operand_type_t addr_type;
125 real_cr0 = (struct cr0_32*)&(guest_state->cr0);
127 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
129 if (addr_type != REG_OPERAND) {
130 /* Mov to CR0 Can only be a 32 bit register */
135 new_cr0 = (struct cr0_32 *)first_operand;
137 if (new_cr0->pe == 1) {
138 PrintDebug("Entering Protected Mode\n");
139 info->cpu_mode = PROTECTED;
142 if (new_cr0->pg == 1) {
147 if (info->page_mode == SHADOW_PAGING) {
148 struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
150 PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
151 *real_cr0 = *new_cr0;
154 *shadow_cr0 = *new_cr0;
156 PrintDebug("New CR0=%x, New Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
158 PrintDebug("Old CR0=%x\n", *real_cr0);
159 *real_cr0 = *new_cr0;
160 PrintDebug("New CR0=%x\n", *real_cr0);
166 PrintDebug("Unsupported Instruction\n");
167 // unsupported instruction, UD the guest
172 } else if (info->cpu_mode == PROTECTED) {
176 PrintDebug("Protected Mode write to CR0\n");
178 // The real rip address is actually a combination of the rip + CS base
179 ret = read_guest_pa_memory(info, get_addr_linear(info, guest_state->rip, guest_state->cs.base), 15, instr);
181 // I think we should inject a GPF into the guest
182 PrintDebug("Could not read instruction (ret=%d)\n", ret);
186 while (is_prefix_byte(instr[index])) {
190 if ((instr[index] == cr_access_byte) &&
191 (instr[index + 1] == mov_to_cr_byte)) {
193 addr_t first_operand;
194 addr_t second_operand;
195 struct cr0_32 *real_cr0;
196 struct cr0_32 *new_cr0;
197 operand_type_t addr_type;
201 real_cr0 = (struct cr0_32*)&(guest_state->cr0);
203 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
205 if (addr_type != REG_OPERAND) {
209 new_cr0 = (struct cr0_32 *)first_operand;
212 if (info->page_mode == SHADOW_PAGING) {
213 struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
215 if (new_cr0->pg == 1){
216 struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
218 info->cpu_mode = PROTECTED_PG;
220 *shadow_cr0 = *new_cr0;
221 *real_cr0 = *new_cr0;
224 // Activate Shadow Paging
226 PrintDebug("Turning on paging in the guest\n");
228 guest_state->cr3 = *(addr_t*)shadow_cr3;
231 } else if (new_cr0->pe == 0) {
232 info->cpu_mode = REAL;
234 *shadow_cr0 = *new_cr0;
235 *real_cr0 = *new_cr0;
241 *real_cr0 = *new_cr0;
248 PrintDebug("Unknown Mode write to CR0\n");
255 int handle_cr0_read(struct guest_info * info) {
256 //vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t *)(info->vmm_data));
257 vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
260 if (info->cpu_mode == REAL) {
264 // The real rip address is actually a combination of the rip + CS base
265 ret = read_guest_pa_memory(info, get_addr_linear(info, guest_state->rip, guest_state->cs.selector), 15, instr);
267 // I think we should inject a GPF into the guest
268 PrintDebug("Could not read Real Mode instruction (ret=%d)\n", ret);
273 while (is_prefix_byte(instr[index])) {
277 if ((instr[index] == cr_access_byte) &&
278 (instr[index + 1] == smsw_byte) &&
279 (MODRM_REG(instr[index + 2]) == smsw_reg_byte)) {
281 addr_t first_operand;
282 addr_t second_operand;
283 struct cr0_real *cr0;
284 operand_type_t addr_type;
289 cr0 = (struct cr0_real*)&(guest_state->cr0);
292 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG16);
294 if (addr_type == MEM_OPERAND) {
297 if (guest_pa_to_host_va(info, first_operand + (guest_state->ds.base << 4), &host_addr) == -1) {
302 first_operand = host_addr;
304 // error... don't know what to do
308 cr0_val = *(char*)cr0 & 0x0f;
310 *(char *)first_operand &= 0xf0;
311 *(char *)first_operand |= cr0_val;
313 PrintDebug("index = %d, rip = %x\n", index, (ulong_t)(info->rip));
315 PrintDebug("new_rip = %x\n", (ulong_t)(info->rip));
316 } else if ((instr[index] == cr_access_byte) &&
317 (instr[index+1] == mov_from_cr_byte)) {
319 * This can only take a 32 bit register argument in anything less than 64 bit mode.
321 addr_t first_operand;
322 addr_t second_operand;
323 operand_type_t addr_type;
325 struct cr0_32 * real_cr0 = (struct cr0_32 *)&(guest_state->cr0);
329 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
331 struct cr0_32 * virt_cr0 = (struct cr0_32 *)first_operand;
333 if (addr_type != REG_OPERAND) {
334 // invalid opcode to guest
335 PrintDebug("Invalid operand type in mov from CR0\n");
339 if (info->page_mode == SHADOW_PAGING) {
340 *virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
342 *virt_cr0 = *real_cr0;
348 PrintDebug("Unknown read instr from CR0\n");
352 } else if (info->cpu_mode == PROTECTED) {
356 // The real rip address is actually a combination of the rip + CS base
357 ret = read_guest_pa_memory(info, get_addr_linear(info, guest_state->rip, guest_state->cs.base), 15, instr);
359 // I think we should inject a GPF into the guest
360 PrintDebug("Could not read Proteced mode instruction (ret=%d)\n", ret);
364 while (is_prefix_byte(instr[index])) {
369 if ((instr[index] == cr_access_byte) &&
370 (instr[index+1] == mov_from_cr_byte)) {
371 addr_t first_operand;
372 addr_t second_operand;
373 operand_type_t addr_type;
374 struct cr0_32 * virt_cr0;
375 struct cr0_32 * real_cr0 = (struct cr0_32 *)&(guest_state->cr0);
379 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
381 if (addr_type != REG_OPERAND) {
382 PrintDebug("Invalid operand type in mov from CR0\n");
386 virt_cr0 = (struct cr0_32 *)first_operand;
388 if (info->page_mode == SHADOW_PAGING) {
389 *virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
391 *virt_cr0 = *real_cr0;
397 PrintDebug("Unknown read instruction from CR0\n");
402 PrintDebug("Unknown mode read from CR0\n");
413 int handle_cr3_write(struct guest_info * info) {
414 vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
417 if ((info->cpu_mode == PROTECTED) || (info->cpu_mode == PROTECTED_PG)) {
422 ret = read_guest_pa_memory(info, get_addr_linear(info, guest_state->rip, guest_state->cs.base), 15, instr);
424 PrintDebug("Could not read instruction (ret=%d)\n", ret);
428 while (is_prefix_byte(instr[index])) {
432 if ((instr[index] == cr_access_byte) &&
433 (instr[index + 1] == mov_to_cr_byte)) {
435 addr_t first_operand;
436 addr_t second_operand;
437 struct cr3_32 * new_cr3;
438 // struct cr3_32 * real_cr3;
439 operand_type_t addr_type;
443 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
445 if (addr_type != REG_OPERAND) {
446 /* Mov to CR3 can only be a 32 bit register */
450 new_cr3 = (struct cr3_32 *)first_operand;
452 if (info->page_mode == SHADOW_PAGING) {
454 struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
455 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
458 *guest_cr3 = *new_cr3;
460 // Something like this
461 shadow_pt = create_new_shadow_pt32(info);
462 //shadow_pt = setup_shadow_pt32(info, CR3_TO_PDE32(*(addr_t *)new_cr3));
464 /* Copy Various flags */
465 *shadow_cr3 = *new_cr3;
467 shadow_cr3->pdt_base_addr = PD32_BASE_ADDR(shadow_pt);
469 if (info->cpu_mode == PROTECTED_PG) {
470 // If we aren't in paged mode then we have to preserve the identity mapped CR3
471 guest_state->cr3 = *(addr_t*)shadow_cr3;
478 PrintDebug("Unknown Instruction\n");
482 PrintDebug("Invalid operating Mode\n");
492 int handle_cr3_read(struct guest_info * info) {
493 vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
495 if ((info->cpu_mode == PROTECTED) || (info->cpu_mode == PROTECTED_PG)) {
500 ret = read_guest_pa_memory(info, get_addr_linear(info, guest_state->rip, guest_state->cs.base), 15, instr);
502 PrintDebug("Could not read instruction (ret=%d)\n", ret);
506 while (is_prefix_byte(instr[index])) {
510 if ((instr[index] == cr_access_byte) &&
511 (instr[index + 1] == mov_from_cr_byte)) {
512 addr_t first_operand;
513 addr_t second_operand;
514 struct cr3_32 * virt_cr3;
515 struct cr3_32 * real_cr3 = (struct cr3_32 *)&(guest_state->cr3);
516 operand_type_t addr_type;
520 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
522 if (addr_type != REG_OPERAND) {
523 /* Mov to CR3 can only be a 32 bit register */
527 virt_cr3 = (struct cr3_32 *)first_operand;
529 if (info->page_mode == SHADOW_PAGING) {
530 *virt_cr3 = *(struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
532 *virt_cr3 = *real_cr3;
537 PrintDebug("Unknown Instruction\n");
541 PrintDebug("Invalid operating Mode\n");