2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #include <palacios/vmm.h>
21 #include <palacios/vmm_emulator.h>
22 #include <palacios/vm_guest_mem.h>
23 #include <palacios/vmm_decoder.h>
24 #include <palacios/vmm_paging.h>
25 #include <palacios/vmm_instr_emulator.h>
27 #ifndef DEBUG_EMULATOR
29 #define PrintDebug(fmt, args...)
33 static int run_op(struct guest_info * info, v3_op_type_t op_type, addr_t src_addr, addr_t dst_addr, int src_op_size, int dst_op_size);
35 // We emulate up to the next 4KB page boundry
36 static int emulate_string_write_op(struct guest_info * info, struct x86_instr * dec_instr,
37 addr_t write_gva, addr_t write_gpa, addr_t dst_addr,
38 int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
40 uint_t emulation_length = 0;
44 if (dec_instr->dst_operand.operand != write_gva) {
45 PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
46 (void *)dec_instr->dst_operand.operand, (void *)write_gva);
50 emulation_length = ( (dec_instr->str_op_length < (0x1000 - PAGE_OFFSET_4KB(write_gva))) ?
51 dec_instr->str_op_length :
52 (0x1000 - PAGE_OFFSET_4KB(write_gva)));
54 /* ** Fix emulation length so that it doesn't overrun over the src page either ** */
55 tmp_rcx = emulation_length / dec_instr->dst_operand.size;
57 if (dec_instr->op_type == V3_OP_MOVS) {
59 // figure out addresses here....
60 if (info->mem_mode == PHYSICAL_MEM) {
61 if (guest_pa_to_host_va(info, dec_instr->src_operand.operand, &src_addr) == -1) {
62 PrintError("Could not translate write Source (Physical) to host VA\n");
66 if (guest_va_to_host_va(info, dec_instr->src_operand.operand, &src_addr) == -1) {
67 PrintError("Could not translate write Source (Virtual) to host VA\n");
72 if (dec_instr->dst_operand.size == 1) {
73 movs8((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
74 } else if (dec_instr->dst_operand.size == 2) {
75 movs16((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
76 } else if (dec_instr->dst_operand.size == 4) {
77 movs32((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
79 } else if (dec_instr->dst_operand.size == 8) {
80 movs64((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
83 PrintError("Invalid operand length\n");
87 info->vm_regs.rdi += emulation_length;
88 info->vm_regs.rsi += emulation_length;
90 // RCX is only modified if the rep prefix is present
91 if (dec_instr->prefixes.rep == 1) {
92 info->vm_regs.rcx -= emulation_length;
95 } else if (dec_instr->op_type == V3_OP_STOS) {
97 if (dec_instr->dst_operand.size == 1) {
98 stos8((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
99 } else if (dec_instr->dst_operand.size == 2) {
100 stos16((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
101 } else if (dec_instr->dst_operand.size == 4) {
102 stos32((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
104 } else if (dec_instr->dst_operand.size == 8) {
105 stos64((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
108 PrintError("Invalid operand length\n");
112 info->vm_regs.rdi += emulation_length;
114 // RCX is only modified if the rep prefix is present
115 if (dec_instr->prefixes.rep == 1) {
116 info->vm_regs.rcx -= emulation_length;
120 PrintError("Unimplemented String operation\n");
124 if (write_fn(write_gpa, (void *)dst_addr, emulation_length, priv_data) != emulation_length) {
125 PrintError("Did not fully read hooked data\n");
129 if (emulation_length == dec_instr->str_op_length) {
130 info->rip += dec_instr->instr_length;
133 return emulation_length;
137 static int emulate_xchg_write_op(struct guest_info * info, struct x86_instr * dec_instr,
138 addr_t write_gva, addr_t write_gpa, addr_t dst_addr,
139 int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
142 addr_t em_dst_addr = 0;
145 PrintDebug("Emulating XCHG write\n");
147 if (dec_instr->src_operand.type == MEM_OPERAND) {
148 if (info->shdw_pg_mode == SHADOW_PAGING) {
149 if (dec_instr->src_operand.operand != write_gva) {
150 PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
151 (void *)dec_instr->src_operand.operand, (void *)write_gva);
157 } else if (dec_instr->src_operand.type == REG_OPERAND) {
158 src_addr = dec_instr->src_operand.operand;
160 src_addr = (addr_t)&(dec_instr->src_operand.operand);
165 if (dec_instr->dst_operand.type == MEM_OPERAND) {
166 if (info->shdw_pg_mode == SHADOW_PAGING) {
167 if (dec_instr->dst_operand.operand != write_gva) {
168 PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
169 (void *)dec_instr->dst_operand.operand, (void *)write_gva);
173 //check that the operand (GVA) maps to the the faulting GPA
176 em_dst_addr = dst_addr;
177 } else if (dec_instr->src_operand.type == REG_OPERAND) {
178 em_dst_addr = dec_instr->src_operand.operand;
180 em_dst_addr = (addr_t)&(dec_instr->src_operand.operand);
183 dst_op_len = dec_instr->dst_operand.size;
184 src_op_len = dec_instr->src_operand.size;
186 PrintDebug("Dst_Addr = %p, SRC operand = %p\n",
187 (void *)dst_addr, (void *)src_addr);
190 if (run_op(info, dec_instr->op_type, src_addr, em_dst_addr, src_op_len, dst_op_len) == -1) {
191 PrintError("Instruction Emulation Failed\n");
195 if (write_fn(write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
196 PrintError("Did not fully write hooked data\n");
200 info->rip += dec_instr->instr_length;
207 static int emulate_xchg_read_op(struct guest_info * info, struct x86_instr * dec_instr,
208 addr_t read_gva, addr_t read_gpa, addr_t src_addr,
209 int (*read_fn)(addr_t guest_addr, void * dst, uint_t length, void * priv_data),
210 int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
212 addr_t em_src_addr = 0;
213 addr_t em_dst_addr = 0;
217 PrintDebug("Emulating XCHG Read\n");
219 if (dec_instr->src_operand.type == MEM_OPERAND) {
220 if (dec_instr->src_operand.operand != read_gva) {
221 PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
222 (void *)dec_instr->src_operand.operand, (void *)read_gva);
226 em_src_addr = src_addr;
227 } else if (dec_instr->src_operand.type == REG_OPERAND) {
228 em_src_addr = dec_instr->src_operand.operand;
230 em_src_addr = (addr_t)&(dec_instr->src_operand.operand);
235 if (dec_instr->dst_operand.type == MEM_OPERAND) {
236 if (info->shdw_pg_mode == SHADOW_PAGING) {
237 if (dec_instr->dst_operand.operand != read_gva) {
238 PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
239 (void *)dec_instr->dst_operand.operand, (void *)read_gva);
243 //check that the operand (GVA) maps to the the faulting GPA
246 em_dst_addr = src_addr;
247 } else if (dec_instr->src_operand.type == REG_OPERAND) {
248 em_dst_addr = dec_instr->src_operand.operand;
250 em_dst_addr = (addr_t)&(dec_instr->src_operand.operand);
253 dst_op_len = dec_instr->dst_operand.size;
254 src_op_len = dec_instr->src_operand.size;
256 PrintDebug("Dst_Addr = %p, SRC operand = %p\n",
257 (void *)em_dst_addr, (void *)em_src_addr);
260 if (read_fn(read_gpa, (void *)src_addr, src_op_len, priv_data) != src_op_len) {
261 PrintError("Did not fully read hooked data\n");
265 if (run_op(info, dec_instr->op_type, em_src_addr, em_dst_addr, src_op_len, dst_op_len) == -1) {
266 PrintError("Instruction Emulation Failed\n");
270 if (write_fn(read_gpa, (void *)src_addr, dst_op_len, priv_data) != dst_op_len) {
271 PrintError("Did not fully write hooked data\n");
275 info->rip += dec_instr->instr_length;
283 int v3_emulate_write_op(struct guest_info * info, addr_t write_gva, addr_t write_gpa, addr_t dst_addr,
284 int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
286 struct x86_instr dec_instr;
293 PrintDebug("Emulating Write for instruction at %p\n", (void *)(addr_t)(info->rip));
294 PrintDebug("GVA=%p Dst_Addr=%p\n", (void *)write_gva, (void *)dst_addr);
296 if (info->mem_mode == PHYSICAL_MEM) {
297 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
299 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
306 if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
307 PrintError("Decoding Error\n");
308 // Kick off single step emulator
313 * Instructions needing to be special cased.... *
315 if (dec_instr.is_str_op) {
316 return emulate_string_write_op(info, &dec_instr, write_gva, write_gpa, dst_addr, write_fn, priv_data);
317 } else if (dec_instr.op_type == V3_OP_XCHG) {
318 return emulate_xchg_write_op(info, &dec_instr, write_gva, write_gpa, dst_addr, write_fn, priv_data);
322 if (info->shdw_pg_mode == SHADOW_PAGING) {
323 if ((dec_instr.dst_operand.type != MEM_OPERAND) ||
324 (dec_instr.dst_operand.operand != write_gva)) {
325 PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
326 (void *)dec_instr.dst_operand.operand, (void *)write_gva);
330 //check that the operand (GVA) maps to the the faulting GPA
334 if (dec_instr.src_operand.type == MEM_OPERAND) {
335 if (info->mem_mode == PHYSICAL_MEM) {
336 if (guest_pa_to_host_va(info, dec_instr.src_operand.operand, &src_addr) == -1) {
337 PrintError("Could not translate write Source (Physical) to host VA\n");
341 if (guest_va_to_host_va(info, dec_instr.src_operand.operand, &src_addr) == -1) {
342 PrintError("Could not translate write Source (Virtual) to host VA\n");
346 } else if (dec_instr.src_operand.type == REG_OPERAND) {
347 src_addr = dec_instr.src_operand.operand;
349 src_addr = (addr_t)&(dec_instr.src_operand.operand);
352 dst_op_len = dec_instr.dst_operand.size;
353 src_op_len = dec_instr.src_operand.size;
355 PrintDebug("Dst_Addr = %p, SRC operand = %p\n",
356 (void *)dst_addr, (void *)src_addr);
359 if (run_op(info, dec_instr.op_type, src_addr, dst_addr, src_op_len, dst_op_len) == -1) {
360 PrintError("Instruction Emulation Failed\n");
364 if (write_fn(write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
365 PrintError("Did not fully write hooked data\n");
369 info->rip += dec_instr.instr_length;
375 int v3_emulate_read_op(struct guest_info * info, addr_t read_gva, addr_t read_gpa, addr_t src_addr,
376 int (*read_fn)(addr_t guest_addr, void * dst, uint_t length, void * priv_data),
377 int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
379 struct x86_instr dec_instr;
386 PrintDebug("Emulating Read for instruction at %p\n", (void *)(addr_t)(info->rip));
387 PrintDebug("GVA=%p\n", (void *)read_gva);
389 if (info->mem_mode == PHYSICAL_MEM) {
390 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
392 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
396 PrintError("Could not read instruction for Emulated Read at %p\n", (void *)(addr_t)(info->rip));
401 if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
402 PrintError("Decoding Error\n");
403 // Kick off single step emulator
407 if (dec_instr.is_str_op) {
408 PrintError("String operations not implemented on fully hooked regions\n");
410 } else if (dec_instr.op_type == V3_OP_XCHG) {
411 return emulate_xchg_read_op(info, &dec_instr, read_gva, read_gpa, src_addr, read_fn, write_fn, priv_data);
414 if (info->shdw_pg_mode == SHADOW_PAGING) {
415 if ((dec_instr.src_operand.type != MEM_OPERAND) ||
416 (dec_instr.src_operand.operand != read_gva)) {
417 PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p operand_type=%d\n",
418 (void *)dec_instr.src_operand.operand, (void *)read_gva, dec_instr.src_operand.type);
422 //check that the operand (GVA) maps to the the faulting GPA
425 if (dec_instr.dst_operand.type == MEM_OPERAND) {
426 if (info->mem_mode == PHYSICAL_MEM) {
427 if (guest_pa_to_host_va(info, dec_instr.dst_operand.operand, &dst_addr) == -1) {
428 PrintError("Could not translate Read Destination (Physical) to host VA\n");
432 if (guest_va_to_host_va(info, dec_instr.dst_operand.operand, &dst_addr) == -1) {
433 PrintError("Could not translate Read Destination (Virtual) to host VA\n");
437 } else if (dec_instr.dst_operand.type == REG_OPERAND) {
438 dst_addr = dec_instr.dst_operand.operand;
440 dst_addr = (addr_t)&(dec_instr.dst_operand.operand);
443 src_op_len = dec_instr.src_operand.size;
444 dst_op_len = dec_instr.dst_operand.size;
446 PrintDebug("Dst_Addr = %p, SRC Addr = %p\n",
447 (void *)dst_addr, (void *)src_addr);
449 if (read_fn(read_gpa, (void *)src_addr, src_op_len, priv_data) != src_op_len) {
450 PrintError("Did not fully read hooked data\n");
454 if (run_op(info, dec_instr.op_type, src_addr, dst_addr, src_op_len, dst_op_len) == -1) {
455 PrintError("Instruction Emulation Failed\n");
459 info->rip += dec_instr.instr_length;
469 static int run_op(struct guest_info * info, v3_op_type_t op_type, addr_t src_addr, addr_t dst_addr, int src_op_size, int dst_op_size) {
471 if (src_op_size == 1) {
472 PrintDebug("Executing 8 bit instruction\n");
476 adc8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
479 add8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
482 and8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
485 or8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
488 xor8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
491 sub8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
495 mov8((addr_t *)dst_addr, (addr_t *)src_addr);
499 movzx8((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
502 movsx8((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
506 not8((addr_t *)dst_addr);
509 xchg8((addr_t *)dst_addr, (addr_t *)src_addr);
514 inc8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
517 dec8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
520 neg8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
523 setb8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
526 setbe8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
529 setl8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
532 setle8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
535 setnb8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
538 setnbe8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
541 setnl8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
544 setnle8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
547 setno8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
550 setnp8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
553 setns8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
556 setnz8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
559 seto8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
562 setp8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
565 sets8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
568 setz8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
572 PrintError("Unknown 8 bit instruction\n");
576 } else if (src_op_size == 2) {
577 PrintDebug("Executing 16 bit instruction\n");
581 adc16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
584 add16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
587 and16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
590 or16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
593 xor16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
596 sub16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
601 inc16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
604 dec16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
607 neg16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
611 mov16((addr_t *)dst_addr, (addr_t *)src_addr);
614 movzx16((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
617 movsx16((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
620 not16((addr_t *)dst_addr);
623 xchg16((addr_t *)dst_addr, (addr_t *)src_addr);
627 PrintError("Unknown 16 bit instruction\n");
631 } else if (src_op_size == 4) {
632 PrintDebug("Executing 32 bit instruction\n");
636 adc32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
639 add32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
642 and32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
645 or32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
648 xor32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
651 sub32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
655 inc32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
658 dec32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
661 neg32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
665 mov32((addr_t *)dst_addr, (addr_t *)src_addr);
669 not32((addr_t *)dst_addr);
672 xchg32((addr_t *)dst_addr, (addr_t *)src_addr);
676 PrintError("Unknown 32 bit instruction\n");
681 } else if (src_op_size == 8) {
682 PrintDebug("Executing 64 bit instruction\n");
686 adc64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
689 add64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
692 and64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
695 or64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
698 xor64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
701 sub64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
705 inc64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
708 dec64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
711 neg64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
715 mov64((addr_t *)dst_addr, (addr_t *)src_addr);
719 not64((addr_t *)dst_addr);
722 xchg64((addr_t *)dst_addr, (addr_t *)src_addr);
726 PrintError("Unknown 64 bit instruction\n");
732 PrintError("Invalid Operation Size\n");