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) {
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);
459 if (CR3_TO_PDE32(*(uint_t*)shadow_cr3) != 0) {
460 PrintDebug("Shadow Page Table\n");
461 PrintDebugPageTables((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
465 /* Delete the current Page Tables */
466 delete_page_tables_pde32((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
468 PrintDebug("Old Shadow CR3=%x; Old Guest CR3=%x\n",
469 *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
472 *guest_cr3 = *new_cr3;
476 // Something like this
477 shadow_pt = create_new_shadow_pt32(info);
478 //shadow_pt = setup_shadow_pt32(info, CR3_TO_PDE32(*(addr_t *)new_cr3));
480 /* Copy Various flags */
481 *shadow_cr3 = *new_cr3;
486 guest_pa_to_host_va(info, ((*(uint_t*)guest_cr3) & 0xfffff000), &tmp_addr);
487 PrintDebug("Guest PD\n");
488 PrintPD32((pde32_t *)tmp_addr);
494 shadow_cr3->pdt_base_addr = PD32_BASE_ADDR(shadow_pt);
496 PrintDebug("New Shadow CR3=%x; New Guest CR3=%x\n",
497 *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
506 PrintDebug("Unknown Instruction\n");
507 PrintTraceMemDump(instr,15);
513 } else if (info->cpu_mode == PROTECTED) {
518 PrintDebug("Protected %s mode write to CR3 at %s 0x%x\n",
519 info->cpu_mode==PROTECTED ? "" : "Paged",
520 info->cpu_mode==PROTECTED ? "guest physical" : "guest virtual",
521 get_addr_linear(info,info->rip,&(info->segments.cs)));
523 // We need to read the instruction, which is at CS:IP, but that
524 // linear address is guest physical without PG and guest virtual with PG
525 if (info->mem_mode == PHYSICAL_MEM) {
526 // The real rip address is actually a combination of the rip + CS base
527 //PrintDebug("Writing Guest CR3 Write (Physical Address)\n");
528 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
530 //PrintDebug("Writing Guest CR3 Write (Virtual Address)\n");
531 // The real rip address is actually a combination of the rip + CS base
532 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
536 PrintDebug("Could not read instruction (ret=%d)\n", ret);
540 while (is_prefix_byte(instr[index])) {
541 switch(instr[index]) {
542 case PREFIX_CS_OVERRIDE:
543 case PREFIX_SS_OVERRIDE:
544 case PREFIX_DS_OVERRIDE:
545 case PREFIX_ES_OVERRIDE:
546 case PREFIX_FS_OVERRIDE:
547 case PREFIX_GS_OVERRIDE:
548 PrintDebug("Segment Override!!\n");
558 while (is_prefix_byte(instr[index])) {
563 if ((instr[index] == cr_access_byte) &&
564 (instr[index + 1] == mov_to_cr_byte)) {
566 addr_t first_operand;
567 addr_t second_operand;
568 struct cr3_32 * new_cr3;
569 // struct cr3_32 * real_cr3;
570 operand_type_t addr_type;
574 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
576 if (addr_type != REG_OPERAND) {
577 /* Mov to CR3 can only be a 32 bit register */
581 new_cr3 = (struct cr3_32 *)first_operand;
583 if (info->shdw_pg_mode == SHADOW_PAGING) {
585 struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
586 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
590 if (CR3_TO_PDE32(*(uint_t*)shadow_cr3) != 0) {
591 PrintDebug("Shadow Page Table\n");
592 PrintDebugPageTables((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
596 /* Delete the current Page Tables */
597 delete_page_tables_pde32((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
599 PrintDebug("Old Shadow CR3=%x; Old Guest CR3=%x\n",
600 *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
603 *guest_cr3 = *new_cr3;
607 // Something like this
608 shadow_pt = create_new_shadow_pt32(info);
609 //shadow_pt = setup_shadow_pt32(info, CR3_TO_PDE32(*(addr_t *)new_cr3));
611 /* Copy Various flags */
612 *shadow_cr3 = *new_cr3;
617 guest_pa_to_host_va(info, ((*(uint_t*)guest_cr3) & 0xfffff000), &tmp_addr);
618 PrintDebug("Guest PD\n");
619 PrintPD32((pde32_t *)tmp_addr);
625 shadow_cr3->pdt_base_addr = PD32_BASE_ADDR(shadow_pt);
627 PrintDebug("New Shadow CR3=%x; New Guest CR3=%x\n",
628 *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
632 if (info->mem_mode == VIRTUAL_MEM) {
633 // If we aren't in paged mode then we have to preserve the identity mapped CR3
634 info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3;
641 PrintDebug("Unknown Instruction\n");
642 PrintTraceMemDump(instr,15);
646 PrintDebug("Invalid operating Mode (0x%x)\n", info->cpu_mode);
656 int handle_cr3_read(struct guest_info * info) {
658 if (info->cpu_mode == REAL) {
662 addr_t linear_addr = 0;
664 linear_addr = get_addr_linear(info, info->rip, &(info->segments.cs));
667 //PrintDebug("RIP Linear: %x\n", linear_addr);
668 //PrintV3Segments(info);
670 ret = read_guest_pa_memory(info, linear_addr, 15, instr);
673 PrintDebug("Could not read instruction (ret=%d)\n", ret);
677 while (is_prefix_byte(instr[index])) {
678 switch(instr[index]) {
679 case PREFIX_CS_OVERRIDE:
680 case PREFIX_SS_OVERRIDE:
681 case PREFIX_DS_OVERRIDE:
682 case PREFIX_ES_OVERRIDE:
683 case PREFIX_FS_OVERRIDE:
684 case PREFIX_GS_OVERRIDE:
685 PrintDebug("Segment Override!!\n");
695 if ((instr[index] == cr_access_byte) &&
696 (instr[index + 1] == mov_from_cr_byte)) {
697 addr_t first_operand;
698 addr_t second_operand;
699 struct cr3_32 * virt_cr3;
700 struct cr3_32 * real_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
701 operand_type_t addr_type;
705 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
707 if (addr_type != REG_OPERAND) {
708 /* Mov to CR3 can only be a 32 bit register */
712 virt_cr3 = (struct cr3_32 *)first_operand;
714 if (info->shdw_pg_mode == SHADOW_PAGING) {
715 *virt_cr3 = *(struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
717 *virt_cr3 = *real_cr3;
722 PrintDebug("Unknown Instruction\n");
723 PrintTraceMemDump(instr,15);
729 } else if (info->cpu_mode == PROTECTED) {
736 // We need to read the instruction, which is at CS:IP, but that
737 // linear address is guest physical without PG and guest virtual with PG
738 if (info->cpu_mode == PHYSICAL_MEM) {
739 // The real rip address is actually a combination of the rip + CS base
740 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
742 // The real rip address is actually a combination of the rip + CS base
743 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
747 PrintDebug("Could not read instruction (ret=%d)\n", ret);
751 while (is_prefix_byte(instr[index])) {
752 switch(instr[index]) {
753 case PREFIX_CS_OVERRIDE:
754 case PREFIX_SS_OVERRIDE:
755 case PREFIX_DS_OVERRIDE:
756 case PREFIX_ES_OVERRIDE:
757 case PREFIX_FS_OVERRIDE:
758 case PREFIX_GS_OVERRIDE:
759 PrintDebug("Segment Override!!\n");
769 while (is_prefix_byte(instr[index])) {
774 if ((instr[index] == cr_access_byte) &&
775 (instr[index + 1] == mov_from_cr_byte)) {
776 addr_t first_operand;
777 addr_t second_operand;
778 struct cr3_32 * virt_cr3;
779 struct cr3_32 * real_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
780 operand_type_t addr_type;
784 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
786 if (addr_type != REG_OPERAND) {
787 /* Mov to CR3 can only be a 32 bit register */
791 virt_cr3 = (struct cr3_32 *)first_operand;
793 if (info->shdw_pg_mode == SHADOW_PAGING) {
794 *virt_cr3 = *(struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
796 *virt_cr3 = *real_cr3;
801 PrintDebug("Unknown Instruction\n");
802 PrintTraceMemDump(instr,15);
806 PrintDebug("Invalid operating Mode (0x%x), control registers follow\n", info->cpu_mode);
807 PrintV3CtrlRegs(info);