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 extern void SerialMemDump(unsigned char *start, int n);
13 /* Segmentation is a problem here...
15 * When we get a memory operand, presumably we use the default segment (which is?)
16 * unless an alternate segment was specfied in the prefix...
20 int handle_cr0_write(struct guest_info * info) {
24 switch (info->cpu_mode) {
30 PrintDebug("Real Mode write to CR0 at linear guest pa 0x%x\n",get_addr_linear(info,info->rip,&(info->segments.cs)));
32 // The real rip address is actually a combination of the rip + CS base
33 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
35 // I think we should inject a GPF into the guest
36 PrintDebug("Could not read instruction (ret=%d)\n", ret);
40 while (is_prefix_byte(instr[index])) {
44 if ((instr[index] == cr_access_byte) &&
45 (instr[index + 1] == lmsw_byte) &&
46 (MODRM_REG(instr[index + 2]) == lmsw_reg_byte)) {
49 addr_t second_operand;
50 struct cr0_real *real_cr0;
51 struct cr0_real *new_cr0;
52 operand_type_t addr_type;
58 real_cr0 = (struct cr0_real*)&(info->ctrl_regs.cr0);
60 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG16);
63 if (addr_type == REG_OPERAND) {
64 new_cr0 = (struct cr0_real *)first_operand;
65 } else if (addr_type == MEM_OPERAND) {
68 if (guest_pa_to_host_va(info, first_operand + (info->segments.ds.base << 4), &host_addr) == -1) {
73 new_cr0 = (struct cr0_real *)host_addr;
75 PrintDebug("Memory operand in real mode write to CR0 is UNIMPLEMENTED\n");
76 // error... don't know what to do
80 if ((new_cr0->pe == 1) && (real_cr0->pe == 0)) {
81 info->cpu_mode = PROTECTED;
82 } else if ((new_cr0->pe == 0) && (real_cr0->pe == 1)) {
83 info->cpu_mode = REAL;
86 new_cr0_val = *(char*)(new_cr0) & 0x0f;
89 if (info->shdw_pg_mode == SHADOW_PAGING) {
90 struct cr0_real * shadow_cr0 = (struct cr0_real*)&(info->shdw_pg_state.guest_cr0);
92 PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
93 /* struct cr0_real is only 4 bits wide,
94 * so we can overwrite the real_cr0 without worrying about the shadow fields
96 *(char*)real_cr0 &= 0xf0;
97 *(char*)real_cr0 |= new_cr0_val;
99 *(char*)shadow_cr0 &= 0xf0;
100 *(char*)shadow_cr0 |= new_cr0_val;
103 PrintDebug("New CR0=%x, New Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
105 PrintDebug("Old CR0=%x\n", *real_cr0);
106 // for now we just pass through....
107 *(char*)real_cr0 &= 0xf0;
108 *(char*)real_cr0 |= new_cr0_val;
110 PrintDebug("New CR0=%x\n", *real_cr0);
116 } else if ((instr[index] == cr_access_byte) &&
117 (instr[index + 1] == clts_byte)) {
119 PrintDebug("CLTS unhandled in CR0 write\n");
122 } else if ((instr[index] == cr_access_byte) &&
123 (instr[index + 1] = mov_to_cr_byte)) {
124 addr_t first_operand;
125 addr_t second_operand;
126 struct cr0_32 *real_cr0;
127 struct cr0_32 *new_cr0;
128 operand_type_t addr_type;
133 real_cr0 = (struct cr0_32*)&(info->ctrl_regs.cr0);
135 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
137 if (addr_type != REG_OPERAND) {
138 PrintDebug("Moving to CR0 from non-register operand in CR0 write\n");
139 /* Mov to CR0 Can only be a 32 bit register */
144 new_cr0 = (struct cr0_32 *)first_operand;
146 if (new_cr0->pe == 1) {
147 PrintDebug("Entering Protected Mode\n");
148 info->cpu_mode = PROTECTED;
151 if (new_cr0->pe == 0) {
152 PrintDebug("Entering Real Mode\n");
153 info->cpu_mode = REAL;
157 if (new_cr0->pg == 1) {
158 PrintDebug("Paging is already turned on in switch to protected mode in CR0 write\n");
164 if (info->shdw_pg_mode == SHADOW_PAGING) {
165 struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
167 PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
168 *real_cr0 = *new_cr0;
172 *shadow_cr0 = *new_cr0;
175 PrintDebug("New CR0=%x, New Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
177 PrintDebug("Old CR0=%x\n", *real_cr0);
178 *real_cr0 = *new_cr0;
179 PrintDebug("New CR0=%x\n", *real_cr0);
185 PrintDebug("Unsupported Instruction\n");
186 // unsupported instruction, UD the guest
199 PrintDebug("Protected %s Mode write to CR0 at guest %s linear rip 0x%x\n",
200 info->mem_mode == VIRTUAL_MEM ? "Paged" : "",
201 info->mem_mode == VIRTUAL_MEM ? "virtual" : "",
202 get_addr_linear(info, info->rip, &(info->segments.cs)));
204 // OK, now we will read the instruction
205 // The only difference between PROTECTED and PROTECTED_PG is whether we read
206 // from guest_pa or guest_va
207 if (info->mem_mode == PHYSICAL_MEM) {
208 // The real rip address is actually a combination of the rip + CS base
209 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
211 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
216 // I think we should inject a GPF into the guest
217 PrintDebug("Could not read instruction (ret=%d)\n", ret);
221 while (is_prefix_byte(instr[index])) {
225 struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
227 struct cr0_32 * real_cr0 = (struct cr0_32*)&(info->ctrl_regs.cr0);
229 if ((instr[index] == cr_access_byte) &&
230 (instr[index + 1] == mov_to_cr_byte)) {
234 addr_t first_operand;
235 addr_t second_operand;
236 struct cr0_32 *new_cr0;
237 operand_type_t addr_type;
241 PrintDebug("MovToCR0 instr:\n");
242 PrintTraceMemDump(instr, 15);
243 PrintDebug("EAX=%x\n", *(uint_t*)&(info->vm_regs.rax));
245 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
247 if (addr_type != REG_OPERAND) {
248 PrintDebug("Non-register operand in write to CR0\n");
252 new_cr0 = (struct cr0_32 *)first_operand;
254 PrintDebug("first operand=%x\n", *(uint_t *)first_operand);
256 if (info->shdw_pg_mode == SHADOW_PAGING) {
257 struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
259 if (new_cr0->pg == 1){
260 // This should be new_cr0->pg && !(old_cr->pg), right?
261 // and then a case for turning paging off?
263 struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
265 info->mem_mode = VIRTUAL_MEM;
267 *shadow_cr0 = *new_cr0;
268 *real_cr0 = *new_cr0;
273 // Activate Shadow Paging
275 PrintDebug("Turning on paging in the guest\n");
277 info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3;
280 } else if (new_cr0->pe == 0) {
281 info->cpu_mode = REAL;
282 info->mem_mode = PHYSICAL_MEM;
283 PrintDebug("Entering Real Mode\n");
285 PrintV3CtrlRegs(&(info->ctrl_regs));
286 // reinstate the identity mapped paged tables
287 // But keep the shadow tables around to handle TLB issues.... UGH...
288 //info->shdw_pg_state.shadow_cr3 &= 0x00000fff;
289 //info->shdw_pg_state.shadow_cr3 |= ((addr_t)create_passthrough_pde32_pts(info) & ~0xfff);
291 //info->ctrl_regs.cr3 = info->shdw_pg_state.shadow_cr3;
292 info->ctrl_regs.cr3 = ((addr_t)create_passthrough_pde32_pts(info) & ~0xfff);
295 *shadow_cr0 = *new_cr0;
296 *real_cr0 = *new_cr0;
305 *real_cr0 = *new_cr0;
310 } else if ((instr[index] == 0x0f) &&
311 (instr[index + 1] == 0x06)) {
313 PrintDebug("CLTS instruction - clearing TS flag of real and shadow CR0\n");
322 PrintDebug("Unkown instruction: \n");
323 SerialMemDump(instr,15);
330 PrintDebug("Protected PAE Mode write to CR0 is UNIMPLEMENTED\n");
334 PrintDebug("Protected Long Mode write to CR0 is UNIMPLEMENTED\n");
339 PrintDebug("Unknown Mode write to CR0 (info->cpu_mode=0x%x\n)",info->cpu_mode);
350 int handle_cr0_read(struct guest_info * info) {
353 switch (info->cpu_mode) {
361 PrintDebug("Real Mode read from CR0 at linear guest pa 0x%x\n",get_addr_linear(info,info->rip,&(info->segments.cs)));
363 // The real rip address is actually a combination of the rip + CS base
364 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
366 // I think we should inject a GPF into the guest
367 PrintDebug("Could not read Real Mode instruction (ret=%d)\n", ret);
372 while (is_prefix_byte(instr[index])) {
376 if ((instr[index] == cr_access_byte) &&
377 (instr[index + 1] == smsw_byte) &&
378 (MODRM_REG(instr[index + 2]) == smsw_reg_byte)) {
380 // SMSW (store machine status word)
382 addr_t first_operand;
383 addr_t second_operand;
384 struct cr0_real *cr0;
385 operand_type_t addr_type;
390 cr0 = (struct cr0_real*)&(info->ctrl_regs.cr0);
393 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG16);
395 if (addr_type == MEM_OPERAND) {
398 if (guest_pa_to_host_va(info, first_operand + (info->segments.ds.base << 4), &host_addr) == -1) {
400 PrintDebug("Could not convert guest physical address to host virtual address\n");
404 first_operand = host_addr;
410 cr0_val = *(char*)cr0 & 0x0f;
412 *(char *)first_operand &= 0xf0;
413 *(char *)first_operand |= cr0_val;
415 PrintDebug("index = %d, rip = %x\n", index, (ulong_t)(info->rip));
417 PrintDebug("new_rip = %x\n", (ulong_t)(info->rip));
420 } else if ((instr[index] == cr_access_byte) &&
421 (instr[index+1] == mov_from_cr_byte)) {
423 * This can only take a 32 bit register argument in anything less than 64 bit mode.
425 addr_t first_operand;
426 addr_t second_operand;
427 operand_type_t addr_type;
429 struct cr0_32 * real_cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
433 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
435 struct cr0_32 * virt_cr0 = (struct cr0_32 *)first_operand;
437 if (addr_type != REG_OPERAND) {
438 // invalid opcode to guest
439 PrintDebug("Invalid operand type in mov from CR0\n");
443 if (info->shdw_pg_mode == SHADOW_PAGING) {
444 *virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
446 *virt_cr0 = *real_cr0;
452 PrintDebug("Unknown read instr from CR0\n");
466 PrintDebug("Protected %s Mode read from CR0 at guest %s linear rip 0x%x\n",
467 info->mem_mode == VIRTUAL_MEM ? "Paged" : "",
468 info->mem_mode == VIRTUAL_MEM ? "virtual" : "",
469 get_addr_linear(info, info->rip, &(info->segments.cs)));
471 // We need to read the instruction, which is at CS:IP, but that
472 // linear address is guest physical without PG and guest virtual with PG
473 if (info->cpu_mode == PHYSICAL_MEM) {
474 // The real rip address is actually a combination of the rip + CS base
475 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
477 // The real rip address is actually a combination of the rip + CS base
478 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
482 // I think we should inject a GPF into the guest
483 PrintDebug("Could not read Protected %s mode instruction (ret=%d)\n",
484 info->cpu_mode == VIRTUAL_MEM ? "Paged" : "", ret);
488 while (is_prefix_byte(instr[index])) {
493 if ((instr[index] == cr_access_byte) &&
494 (instr[index+1] == mov_from_cr_byte)) {
496 // MOV from CR0 to register
498 addr_t first_operand;
499 addr_t second_operand;
500 operand_type_t addr_type;
501 struct cr0_32 * virt_cr0;
502 struct cr0_32 * real_cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
506 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
508 if (addr_type != REG_OPERAND) {
509 PrintDebug("Invalid operand type in mov from CR0\n");
513 virt_cr0 = (struct cr0_32 *)first_operand;
515 if (info->shdw_pg_mode == SHADOW_PAGING) {
516 *virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
518 if (info->mem_mode == PHYSICAL_MEM) {
519 virt_cr0->pg = 0; // clear the pg bit because guest doesn't think it's on
522 PrintDebug("real CR0: %x\n", *(uint_t*)real_cr0);
523 PrintDebug("returned CR0: %x\n", *(uint_t*)virt_cr0);
527 *virt_cr0 = *real_cr0;
533 PrintDebug("Unknown read instruction from CR0\n");
540 PrintDebug("Protected PAE Mode read to CR0 is UNIMPLEMENTED\n");
544 PrintDebug("Protected Long Mode read to CR0 is UNIMPLEMENTED\n");
550 PrintDebug("Unknown Mode read from CR0 (info->cpu_mode=0x%x)\n",info->cpu_mode);
563 int handle_cr3_write(struct guest_info * info) {
564 if (info->cpu_mode == PROTECTED) {
569 PrintDebug("Protected %s mode write to CR3 at %s 0x%x\n",
570 info->cpu_mode==PROTECTED ? "" : "Paged",
571 info->cpu_mode==PROTECTED ? "guest physical" : "guest virtual",
572 get_addr_linear(info,info->rip,&(info->segments.cs)));
574 // We need to read the instruction, which is at CS:IP, but that
575 // linear address is guest physical without PG and guest virtual with PG
576 if (info->mem_mode == PHYSICAL_MEM) {
577 // The real rip address is actually a combination of the rip + CS base
578 PrintDebug("Writing Guest CR3 Write (Physical Address)\n");
579 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
581 PrintDebug("Writing Guest CR3 Write (Virtual Address)\n");
582 // The real rip address is actually a combination of the rip + CS base
583 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
587 PrintDebug("Could not read instruction (ret=%d)\n", ret);
591 while (is_prefix_byte(instr[index])) {
595 if ((instr[index] == cr_access_byte) &&
596 (instr[index + 1] == mov_to_cr_byte)) {
598 addr_t first_operand;
599 addr_t second_operand;
600 struct cr3_32 * new_cr3;
601 // struct cr3_32 * real_cr3;
602 operand_type_t addr_type;
606 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
608 if (addr_type != REG_OPERAND) {
609 /* Mov to CR3 can only be a 32 bit register */
613 new_cr3 = (struct cr3_32 *)first_operand;
615 if (info->shdw_pg_mode == SHADOW_PAGING) {
617 struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
618 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
621 if (CR3_TO_PDE32(*(uint_t*)shadow_cr3) != 0) {
622 PrintDebug("Shadow Page Table\n");
623 PrintDebugPageTables((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
626 /* Delete the current Page Tables */
627 delete_page_tables_pde32((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
629 PrintDebug("Old Shadow CR3=%x; Old Guest CR3=%x\n",
630 *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
633 *guest_cr3 = *new_cr3;
637 // Something like this
638 shadow_pt = create_new_shadow_pt32(info);
639 //shadow_pt = setup_shadow_pt32(info, CR3_TO_PDE32(*(addr_t *)new_cr3));
641 /* Copy Various flags */
642 *shadow_cr3 = *new_cr3;
646 guest_pa_to_host_va(info, ((*(uint_t*)guest_cr3) & 0xfffff000), &tmp_addr);
647 PrintDebug("Guest PD\n");
648 PrintPD32((pde32_t *)tmp_addr);
654 shadow_cr3->pdt_base_addr = PD32_BASE_ADDR(shadow_pt);
656 PrintDebug("New Shadow CR3=%x; New Guest CR3=%x\n",
657 *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
661 if (info->mem_mode == VIRTUAL_MEM) {
662 // If we aren't in paged mode then we have to preserve the identity mapped CR3
663 info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3;
670 PrintDebug("Unknown Instruction\n");
671 SerialMemDump(instr,15);
675 PrintDebug("Invalid operating Mode (0x%x)\n", info->cpu_mode);
685 int handle_cr3_read(struct guest_info * info) {
687 if (info->cpu_mode == REAL) {
688 // what does this mean???
693 addr_t linear_addr = 0;
697 linear_addr = get_addr_linear(info, info->rip, &(info->segments.cs));
700 PrintDebug("RIP Linear: %x\n", linear_addr);
701 PrintV3Segments(&(info->segments));
704 if (info->mem_mode == PHYSICAL_MEM) {
705 guest_pa_to_host_pa(info, linear_addr, &host_addr);
706 } else if (info->mem_mode == VIRTUAL_MEM) {
707 guest_va_to_host_pa(info, linear_addr, &host_addr);
711 pt32_lookup((pde32_t *)CR3_TO_PDE32(info->shdw_pg_state.shadow_cr3), , addr_t * paddr);
716 } else if (info->cpu_mode == PROTECTED) {
723 // We need to read the instruction, which is at CS:IP, but that
724 // linear address is guest physical without PG and guest virtual with PG
725 if (info->cpu_mode == PHYSICAL_MEM) {
726 // The real rip address is actually a combination of the rip + CS base
727 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
729 // The real rip address is actually a combination of the rip + CS base
730 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
734 PrintDebug("Could not read instruction (ret=%d)\n", ret);
738 while (is_prefix_byte(instr[index])) {
742 if ((instr[index] == cr_access_byte) &&
743 (instr[index + 1] == mov_from_cr_byte)) {
744 addr_t first_operand;
745 addr_t second_operand;
746 struct cr3_32 * virt_cr3;
747 struct cr3_32 * real_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
748 operand_type_t addr_type;
752 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
754 if (addr_type != REG_OPERAND) {
755 /* Mov to CR3 can only be a 32 bit register */
759 virt_cr3 = (struct cr3_32 *)first_operand;
761 if (info->shdw_pg_mode == SHADOW_PAGING) {
762 *virt_cr3 = *(struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
764 *virt_cr3 = *real_cr3;
769 PrintDebug("Unknown Instruction\n");
770 SerialMemDump(instr,15);
774 PrintDebug("Invalid operating Mode (0x%x), control registers follow\n", info->cpu_mode);
775 PrintV3CtrlRegs(&(info->ctrl_regs));