1 #include <palacios/vmm_mem.h>
2 #include <palacios/vmm.h>
3 #include <palacios/vmcb.h>
4 #include <palacios/vmm_decoder.h>
5 #include <palacios/vm_guest_mem.h>
6 #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 #ifndef DEBUG_CTRL_REGS
19 #define PrintDebug(fmt, args...)
28 int handle_cr0_write(struct guest_info * info) {
31 struct x86_instr dec_instr;
33 if (info->mem_mode == PHYSICAL_MEM) {
34 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
36 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
40 // I think we should inject a GPF into the guest
41 PrintError("Could not read instruction (ret=%d)\n", ret);
45 if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
46 PrintError("Could not decode instruction\n");
51 if (opcode_cmp(V3_OPCODE_LMSW, (const uchar_t *)(dec_instr.opcode)) == 0) {
52 struct cr0_real *real_cr0 = (struct cr0_real*)&(info->ctrl_regs.cr0);
53 struct cr0_real *new_cr0 = (struct cr0_real *)(dec_instr.first_operand.operand);
58 new_cr0_val = (*(char*)(new_cr0)) & 0x0f;
60 PrintDebug("OperandVal = %x\n", new_cr0_val);
62 PrintDebug("Old CR0=%x\n", *real_cr0);
63 *(uchar_t*)real_cr0 &= 0xf0;
64 *(uchar_t*)real_cr0 |= new_cr0_val;
65 PrintDebug("New CR0=%x\n", *real_cr0);
68 if (info->shdw_pg_mode == SHADOW_PAGING) {
69 struct cr0_real * shadow_cr0 = (struct cr0_real*)&(info->shdw_pg_state.guest_cr0);
71 PrintDebug(" Old Shadow CR0=%x\n", *shadow_cr0);
72 *(uchar_t*)shadow_cr0 &= 0xf0;
73 *(uchar_t*)shadow_cr0 |= new_cr0_val;
74 PrintDebug("New Shadow CR0=%x\n", *shadow_cr0);
76 } else if (opcode_cmp(V3_OPCODE_MOV2CR, (const uchar_t *)(dec_instr.opcode)) == 0) {
77 PrintDebug("MOV2CR0\n");
79 if (info->cpu_mode == LONG) {
83 struct cr0_32 *real_cr0 = (struct cr0_32*)&(info->ctrl_regs.cr0);
84 struct cr0_32 *new_cr0= (struct cr0_32 *)(dec_instr.second_operand.operand);
86 PrintDebug("OperandVal = %x, length=%d\n", *new_cr0, dec_instr.first_operand.size);
89 PrintDebug("Old CR0=%x\n", *real_cr0);
93 if (info->shdw_pg_mode == SHADOW_PAGING) {
94 struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
96 PrintDebug("Old Shadow CR0=%x\n", *shadow_cr0);
100 *shadow_cr0 = *new_cr0;
103 if (get_mem_mode(info) == VIRTUAL_MEM) {
104 struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
106 info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3;
108 info->ctrl_regs.cr3 = *(addr_t*)&(info->direct_map_pt);
112 PrintDebug("New Shadow CR0=%x\n",*shadow_cr0);
114 PrintDebug("New CR0=%x\n", *real_cr0);
117 } else if (opcode_cmp(V3_OPCODE_CLTS, (const uchar_t *)(dec_instr.opcode)) == 0) {
119 struct cr0_32 *real_cr0 = (struct cr0_32*)&(info->ctrl_regs.cr0);
123 if (info->shdw_pg_mode == SHADOW_PAGING) {
124 struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
129 info->rip += dec_instr.instr_length;
135 int handle_cr0_read(struct guest_info * info) {
138 switch (info->cpu_mode) {
146 PrintDebug("Real Mode read from CR0 at linear guest pa 0x%x\n",get_addr_linear(info,info->rip,&(info->segments.cs)));
147 //PrintV3Segments(info);
149 // The real rip address is actually a combination of the rip + CS base
150 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
152 // I think we should inject a GPF into the guest
153 PrintDebug("Could not read Real Mode instruction (ret=%d)\n", ret);
158 while (is_prefix_byte(instr[index])) {
159 switch(instr[index]) {
160 case PREFIX_CS_OVERRIDE:
161 case PREFIX_SS_OVERRIDE:
162 case PREFIX_DS_OVERRIDE:
163 case PREFIX_ES_OVERRIDE:
164 case PREFIX_FS_OVERRIDE:
165 case PREFIX_GS_OVERRIDE:
166 PrintDebug("Segment Override!!\n");
176 while (is_prefix_byte(instr[index])) {
181 if ((instr[index] == cr_access_byte) &&
182 (instr[index + 1] == smsw_byte) &&
183 (MODRM_REG(instr[index + 2]) == smsw_reg_byte)) {
185 // SMSW (store machine status word)
187 addr_t first_operand;
188 addr_t second_operand;
189 struct cr0_real *cr0;
190 operand_type_t addr_type;
195 cr0 = (struct cr0_real*)&(info->ctrl_regs.cr0);
198 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG16);
200 if (addr_type == MEM_OPERAND) {
203 if (guest_pa_to_host_va(info, first_operand + (info->segments.ds.base << 4), &host_addr) == -1) {
205 PrintDebug("Could not convert guest physical address to host virtual address\n");
209 first_operand = host_addr;
215 cr0_val = *(char*)cr0 & 0x0f;
217 *(char *)first_operand &= 0xf0;
218 *(char *)first_operand |= cr0_val;
220 PrintDebug("index = %d, rip = %x\n", index, (ulong_t)(info->rip));
222 PrintDebug("new_rip = %x\n", (ulong_t)(info->rip));
225 } else if ((instr[index] == cr_access_byte) &&
226 (instr[index+1] == mov_from_cr_byte)) {
228 * This can only take a 32 bit register argument in anything less than 64 bit mode.
230 addr_t first_operand;
231 addr_t second_operand;
232 operand_type_t addr_type;
234 struct cr0_32 * real_cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
238 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
240 struct cr0_32 * virt_cr0 = (struct cr0_32 *)first_operand;
242 if (addr_type != REG_OPERAND) {
243 // invalid opcode to guest
244 PrintDebug("Invalid operand type in mov from CR0\n");
248 if (info->shdw_pg_mode == SHADOW_PAGING) {
249 *virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
251 *virt_cr0 = *real_cr0;
254 PrintDebug("Returning CR0: %x\n", *virt_cr0);
259 PrintDebug("Unknown read instr from CR0\n");
273 PrintDebug("Protected %s Mode read from CR0 at guest %s linear rip 0x%x\n",
274 info->mem_mode == VIRTUAL_MEM ? "Paged" : "",
275 info->mem_mode == VIRTUAL_MEM ? "virtual" : "",
276 get_addr_linear(info, info->rip, &(info->segments.cs)));
278 // We need to read the instruction, which is at CS:IP, but that
279 // linear address is guest physical without PG and guest virtual with PG
280 if (info->cpu_mode == PHYSICAL_MEM) {
281 // The real rip address is actually a combination of the rip + CS base
282 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
284 // The real rip address is actually a combination of the rip + CS base
285 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
290 PrintDebug("Instr (15 bytes) at %x:\n", instr);
291 PrintTraceMemDump((char*)instr, 15);
295 // I think we should inject a GPF into the guest
296 PrintDebug("Could not read Protected %s mode instruction (ret=%d)\n",
297 info->cpu_mode == VIRTUAL_MEM ? "Paged" : "", ret);
302 while (is_prefix_byte(instr[index])) {
303 switch(instr[index]) {
304 case PREFIX_CS_OVERRIDE:
305 case PREFIX_SS_OVERRIDE:
306 case PREFIX_DS_OVERRIDE:
307 case PREFIX_ES_OVERRIDE:
308 case PREFIX_FS_OVERRIDE:
309 case PREFIX_GS_OVERRIDE:
310 PrintDebug("Segment Override!!\n");
321 while (is_prefix_byte(instr[index])) {
326 if ((instr[index] == cr_access_byte) &&
327 (instr[index+1] == mov_from_cr_byte)) {
329 // MOV from CR0 to register
331 addr_t first_operand;
332 addr_t second_operand;
333 operand_type_t addr_type;
334 struct cr0_32 * virt_cr0;
335 struct cr0_32 * real_cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
339 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
341 if (addr_type != REG_OPERAND) {
342 PrintDebug("Invalid operand type in mov from CR0\n");
346 virt_cr0 = (struct cr0_32 *)first_operand;
348 if (info->shdw_pg_mode == SHADOW_PAGING) {
349 *virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
351 if (info->mem_mode == PHYSICAL_MEM) {
352 virt_cr0->pg = 0; // clear the pg bit because guest doesn't think it's on
356 *virt_cr0 = *real_cr0;
359 PrintDebug("real CR0: %x\n", *(uint_t*)real_cr0);
360 PrintDebug("returned CR0: %x\n", *(uint_t*)virt_cr0);
365 PrintDebug("Unknown read instruction from CR0\n");
372 PrintDebug("Protected PAE Mode read to CR0 is UNIMPLEMENTED\n");
376 PrintDebug("Protected Long Mode read to CR0 is UNIMPLEMENTED\n");
382 PrintDebug("Unknown Mode read from CR0 (info->cpu_mode=0x%x)\n",info->cpu_mode);
395 int handle_cr3_write(struct guest_info * info) {
396 if (info->cpu_mode == REAL) {
397 // WHAT THE HELL DOES THIS EVEN MEAN?????
403 PrintDebug("Real Mode Write to CR3.\n");
404 // We need to read the instruction, which is at CS:IP, but that
405 // linear address is guest physical without PG and guest virtual with PG
407 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
410 PrintDebug("Could not read instruction (ret=%d)\n", ret);
414 while (is_prefix_byte(instr[index])) {
415 switch(instr[index]) {
416 case PREFIX_CS_OVERRIDE:
417 case PREFIX_SS_OVERRIDE:
418 case PREFIX_DS_OVERRIDE:
419 case PREFIX_ES_OVERRIDE:
420 case PREFIX_FS_OVERRIDE:
421 case PREFIX_GS_OVERRIDE:
422 PrintDebug("Segment Override!!\n");
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_operands16(&(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->shdw_pg_mode == SHADOW_PAGING) {
455 struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
456 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
460 if (CR3_TO_PDE32(*(uint_t*)shadow_cr3) != 0) {
461 PrintDebug("Shadow Page Table\n");
462 PrintDebugPageTables((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
466 /* Delete the current Page Tables */
467 if (!CR3_32_SAME_BASE(new_cr3,guest_cr3)) {
468 PrintDebug("New CR3 is different - flushing shadow page table\n");
469 delete_page_tables_pde32((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
472 PrintDebug("New CR3 (0x%x) has same base as previous CR3 (0x%x) - reusing shadow page table\n", *((uint_t*)new_cr3), *((uint_t*)guest_cr3));
475 PrintDebug("Old Shadow CR3=%x; Old Guest CR3=%x\n",
476 *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
479 *guest_cr3 = *new_cr3;
483 // Something like this
484 shadow_pt = create_new_shadow_pt32(info);
485 //shadow_pt = setup_shadow_pt32(info, CR3_TO_PDE32(*(addr_t *)new_cr3));
487 shadow_pt = shadow_cr3->pdt_base_addr<<12;
490 /* Copy Various flags */
491 *shadow_cr3 = *new_cr3;
496 guest_pa_to_host_va(info, ((*(uint_t*)guest_cr3) & 0xfffff000), &tmp_addr);
497 PrintDebug("Guest PD\n");
498 PrintPD32((pde32_t *)tmp_addr);
504 shadow_cr3->pdt_base_addr = PD32_BASE_ADDR(shadow_pt);
506 PrintDebug("New Shadow CR3=%x; New Guest CR3=%x\n",
507 *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
513 PrintDebug("Unknown Instruction\n");
514 PrintTraceMemDump(instr,15);
520 } else if (info->cpu_mode == PROTECTED) {
525 PrintDebug("Protected %s mode write to CR3 at %s 0x%x\n",
526 info->cpu_mode==PROTECTED ? "" : "Paged",
527 info->cpu_mode==PROTECTED ? "guest physical" : "guest virtual",
528 get_addr_linear(info,info->rip,&(info->segments.cs)));
530 // We need to read the instruction, which is at CS:IP, but that
531 // linear address is guest physical without PG and guest virtual with PG
532 if (info->mem_mode == PHYSICAL_MEM) {
533 // The real rip address is actually a combination of the rip + CS base
534 //PrintDebug("Writing Guest CR3 Write (Physical Address)\n");
535 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
537 //PrintDebug("Writing Guest CR3 Write (Virtual Address)\n");
538 // The real rip address is actually a combination of the rip + CS base
539 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
543 PrintDebug("Could not read instruction (ret=%d)\n", ret);
547 while (is_prefix_byte(instr[index])) {
548 switch(instr[index]) {
549 case PREFIX_CS_OVERRIDE:
550 case PREFIX_SS_OVERRIDE:
551 case PREFIX_DS_OVERRIDE:
552 case PREFIX_ES_OVERRIDE:
553 case PREFIX_FS_OVERRIDE:
554 case PREFIX_GS_OVERRIDE:
555 PrintDebug("Segment Override!!\n");
565 while (is_prefix_byte(instr[index])) {
570 if ((instr[index] == cr_access_byte) &&
571 (instr[index + 1] == mov_to_cr_byte)) {
573 addr_t first_operand;
574 addr_t second_operand;
575 struct cr3_32 * new_cr3;
576 // struct cr3_32 * real_cr3;
577 operand_type_t addr_type;
581 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
583 if (addr_type != REG_OPERAND) {
584 /* Mov to CR3 can only be a 32 bit register */
588 new_cr3 = (struct cr3_32 *)first_operand;
590 if (info->shdw_pg_mode == SHADOW_PAGING) {
593 struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
594 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
598 if (CR3_TO_PDE32(*(uint_t*)shadow_cr3) != 0) {
599 PrintDebug("Shadow Page Table\n");
600 PrintDebugPageTables((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
604 /* Delete the current Page Tables */
605 if (!CR3_32_SAME_BASE(guest_cr3,new_cr3)) {
606 PrintDebug("New CR3 is different - flushing shadow page table\n");
607 delete_page_tables_pde32((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
610 PrintDebug("New CR3 (0x%x) has same base as previous CR3 (0x%x) - reusing shadow page table\n",*((uint_t*)new_cr3), *((uint_t*)guest_cr3));
613 PrintDebug("Old Shadow CR3=%x; Old Guest CR3=%x\n",
614 *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
617 *guest_cr3 = *new_cr3;
620 // Something like this
621 shadow_pt = create_new_shadow_pt32(info);
622 //shadow_pt = setup_shadow_pt32(info, CR3_TO_PDE32(*(addr_t *)new_cr3));
624 shadow_pt =shadow_cr3->pdt_base_addr << 12;
628 /* Copy Various flags */
629 *shadow_cr3 = *new_cr3;
634 guest_pa_to_host_va(info, ((*(uint_t*)guest_cr3) & 0xfffff000), &tmp_addr);
635 PrintDebug("Guest PD\n");
636 PrintPD32((pde32_t *)tmp_addr);
642 shadow_cr3->pdt_base_addr = PD32_BASE_ADDR(shadow_pt);
644 PrintDebug("New Shadow CR3=%x; New Guest CR3=%x\n",
645 *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
649 if (info->mem_mode == VIRTUAL_MEM) {
650 // If we aren't in paged mode then we have to preserve the identity mapped CR3
651 info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3;
658 PrintDebug("Unknown Instruction\n");
659 PrintTraceMemDump(instr,15);
663 PrintDebug("Invalid operating Mode (0x%x)\n", info->cpu_mode);
673 int handle_cr3_read(struct guest_info * info) {
675 if (info->cpu_mode == REAL) {
679 addr_t linear_addr = 0;
681 linear_addr = get_addr_linear(info, info->rip, &(info->segments.cs));
684 //PrintDebug("RIP Linear: %x\n", linear_addr);
685 //PrintV3Segments(info);
687 ret = read_guest_pa_memory(info, linear_addr, 15, instr);
690 PrintDebug("Could not read instruction (ret=%d)\n", ret);
694 while (is_prefix_byte(instr[index])) {
695 switch(instr[index]) {
696 case PREFIX_CS_OVERRIDE:
697 case PREFIX_SS_OVERRIDE:
698 case PREFIX_DS_OVERRIDE:
699 case PREFIX_ES_OVERRIDE:
700 case PREFIX_FS_OVERRIDE:
701 case PREFIX_GS_OVERRIDE:
702 PrintDebug("Segment Override!!\n");
712 if ((instr[index] == cr_access_byte) &&
713 (instr[index + 1] == mov_from_cr_byte)) {
714 addr_t first_operand;
715 addr_t second_operand;
716 struct cr3_32 * virt_cr3;
717 struct cr3_32 * real_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
718 operand_type_t addr_type;
722 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
724 if (addr_type != REG_OPERAND) {
725 /* Mov to CR3 can only be a 32 bit register */
729 virt_cr3 = (struct cr3_32 *)first_operand;
731 if (info->shdw_pg_mode == SHADOW_PAGING) {
732 *virt_cr3 = *(struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
734 *virt_cr3 = *real_cr3;
739 PrintDebug("Unknown Instruction\n");
740 PrintTraceMemDump(instr,15);
746 } else if (info->cpu_mode == PROTECTED) {
753 // We need to read the instruction, which is at CS:IP, but that
754 // linear address is guest physical without PG and guest virtual with PG
755 if (info->cpu_mode == PHYSICAL_MEM) {
756 // The real rip address is actually a combination of the rip + CS base
757 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
759 // The real rip address is actually a combination of the rip + CS base
760 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
764 PrintDebug("Could not read instruction (ret=%d)\n", ret);
768 while (is_prefix_byte(instr[index])) {
769 switch(instr[index]) {
770 case PREFIX_CS_OVERRIDE:
771 case PREFIX_SS_OVERRIDE:
772 case PREFIX_DS_OVERRIDE:
773 case PREFIX_ES_OVERRIDE:
774 case PREFIX_FS_OVERRIDE:
775 case PREFIX_GS_OVERRIDE:
776 PrintDebug("Segment Override!!\n");
786 while (is_prefix_byte(instr[index])) {
791 if ((instr[index] == cr_access_byte) &&
792 (instr[index + 1] == mov_from_cr_byte)) {
793 addr_t first_operand;
794 addr_t second_operand;
795 struct cr3_32 * virt_cr3;
796 struct cr3_32 * real_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
797 operand_type_t addr_type;
801 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
803 if (addr_type != REG_OPERAND) {
804 /* Mov to CR3 can only be a 32 bit register */
808 virt_cr3 = (struct cr3_32 *)first_operand;
810 if (info->shdw_pg_mode == SHADOW_PAGING) {
811 *virt_cr3 = *(struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
813 *virt_cr3 = *real_cr3;
818 PrintDebug("Unknown Instruction\n");
819 PrintTraceMemDump(instr,15);
823 PrintDebug("Invalid operating Mode (0x%x), control registers follow\n", info->cpu_mode);
824 PrintV3CtrlRegs(info);