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...)
35 static int run_op(struct guest_info * info, v3_op_type_t op_type, addr_t src_addr, addr_t dst_addr, int op_size);
37 // We emulate up to the next 4KB page boundry
38 static int emulate_string_write_op(struct guest_info * info, struct x86_instr * dec_instr,
39 addr_t write_gva, addr_t write_gpa, addr_t dst_addr,
40 int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
42 uint_t emulation_length = 0;
46 if (dec_instr->op_type == V3_OP_MOVS) {
47 PrintError("MOVS emulation\n");
49 if (dec_instr->dst_operand.operand != write_gva) {
50 PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
51 (void *)dec_instr->dst_operand.operand, (void *)write_gva);
55 emulation_length = ( (dec_instr->str_op_length < (0x1000 - PAGE_OFFSET_4KB(write_gva))) ?
56 dec_instr->str_op_length :
57 (0x1000 - PAGE_OFFSET_4KB(write_gva)));
58 /* ** Fix emulation length so that it doesn't overrun over the src page either ** */
61 PrintDebug("STR_OP_LEN: %d, Page Len: %d\n",
62 (uint_t)dec_instr->str_op_length,
63 (uint_t)(0x1000 - PAGE_OFFSET_4KB(write_gva)));
64 PrintDebug("Emulation length: %d\n", emulation_length);
65 tmp_rcx = emulation_length;
69 // figure out addresses here....
70 if (info->mem_mode == PHYSICAL_MEM) {
71 if (guest_pa_to_host_va(info, dec_instr->src_operand.operand, &src_addr) == -1) {
72 PrintError("Could not translate write Source (Physical) to host VA\n");
76 if (guest_va_to_host_va(info, dec_instr->src_operand.operand, &src_addr) == -1) {
77 PrintError("Could not translate write Source (Virtual) to host VA\n");
83 PrintDebug("Dst Operand: %p (size=%d), Src Operand: %p\n",
84 (void *)dec_instr->dst_operand.operand,
85 dec_instr->dst_operand.size,
86 (void *)dec_instr->src_operand.operand);
87 PrintDebug("Dst Addr: %p, Src Addr: %p\n", (void *)dst_addr, (void *)src_addr);
95 if (dec_instr->dst_operand.size == 1) {
96 movs8((addr_t *)dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
97 } else if (dec_instr->dst_operand.size == 2) {
98 movs16((addr_t *)dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
99 } else if (dec_instr->dst_operand.size == 4) {
100 movs32((addr_t*)dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
102 PrintError("Invalid operand length\n");
107 if (write_fn(write_gpa, (void *)dst_addr, emulation_length, priv_data) != emulation_length) {
108 PrintError("Did not fully read hooked data\n");
113 PrintDebug("RDI=%p, RSI=%p, RCX=%p\n",
114 (void *)*(addr_t *)&(info->vm_regs.rdi),
115 (void *)*(addr_t *)&(info->vm_regs.rsi),
116 (void *)*(addr_t *)&(info->vm_regs.rcx));
118 info->vm_regs.rdi += emulation_length;
119 info->vm_regs.rsi += emulation_length;
120 info->vm_regs.rcx -= emulation_length;
122 PrintDebug("RDI=%p, RSI=%p, RCX=%p\n",
123 (void *)*(addr_t *)&(info->vm_regs.rdi),
124 (void *)*(addr_t *)&(info->vm_regs.rsi),
125 (void *)*(addr_t *)&(info->vm_regs.rcx));
127 if (emulation_length == dec_instr->str_op_length) {
128 info->rip += dec_instr->instr_length;
131 return emulation_length;
144 int v3_emulate_write_op(struct guest_info * info, addr_t write_gva, addr_t write_gpa, addr_t dst_addr,
145 int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
147 struct x86_instr dec_instr;
153 PrintDebug("Emulating Write for instruction at %p\n", (void *)(addr_t)(info->rip));
154 PrintDebug("GVA=%p\n", (void *)write_gva);
156 if (info->mem_mode == PHYSICAL_MEM) {
157 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
159 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
166 if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
167 PrintError("Decoding Error\n");
168 // Kick off single step emulator
172 if (dec_instr.is_str_op) {
173 return emulate_string_write_op(info, &dec_instr, write_gva, write_gpa, dst_addr, write_fn, priv_data);
177 if ((dec_instr.dst_operand.type != MEM_OPERAND) ||
178 (dec_instr.dst_operand.operand != write_gva)) {
179 PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
180 (void *)dec_instr.dst_operand.operand, (void *)write_gva);
185 if (dec_instr.src_operand.type == MEM_OPERAND) {
186 if (info->mem_mode == PHYSICAL_MEM) {
187 if (guest_pa_to_host_va(info, dec_instr.src_operand.operand, &src_addr) == -1) {
188 PrintError("Could not translate write Source (Physical) to host VA\n");
192 if (guest_va_to_host_va(info, dec_instr.src_operand.operand, &src_addr) == -1) {
193 PrintError("Could not translate write Source (Virtual) to host VA\n");
197 } else if (dec_instr.src_operand.type == REG_OPERAND) {
198 src_addr = dec_instr.src_operand.operand;
200 src_addr = (addr_t)&(dec_instr.src_operand.operand);
203 op_len = dec_instr.dst_operand.size;
205 PrintDebug("Dst_Addr = %p, SRC operand = %p\n",
206 (void *)dst_addr, (void *)src_addr);
209 if (run_op(info, dec_instr.op_type, src_addr, dst_addr, op_len) == -1) {
210 PrintError("Instruction Emulation Failed\n");
214 if (write_fn(write_gpa, (void *)dst_addr, op_len, priv_data) != op_len) {
215 PrintError("Did not fully read hooked data\n");
219 info->rip += dec_instr.instr_length;
225 int v3_emulate_read_op(struct guest_info * info, addr_t read_gva, addr_t read_gpa, addr_t src_addr,
226 int (*read_fn)(addr_t guest_addr, void * dst, uint_t length, void * priv_data),
228 struct x86_instr dec_instr;
234 PrintDebug("Emulating Read for instruction at %p\n", (void *)(addr_t)(info->rip));
235 PrintDebug("GVA=%p\n", (void *)write_gva);
237 if (info->mem_mode == PHYSICAL_MEM) {
238 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
240 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
247 if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
248 PrintError("Decoding Error\n");
249 // Kick off single step emulator
253 if (dec_instr.is_str_op) {
254 PrintError("String operations not implemented on fully hooked regions\n");
259 if ((dec_instr.src_operand.type != MEM_OPERAND) ||
260 (dec_instr.src_operand.operand != read_gva)) {
261 PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
262 (void *)dec_instr.src_operand.operand, (void *)read_gva);
267 if (dec_instr.dst_operand.type == MEM_OPERAND) {
268 if (info->mem_mode == PHYSICAL_MEM) {
269 if (guest_pa_to_host_va(info, dec_instr.dst_operand.operand, &dst_addr) == -1) {
270 PrintError("Could not translate Read Destination (Physical) to host VA\n");
274 if (guest_va_to_host_va(info, dec_instr.dst_operand.operand, &dst_addr) == -1) {
275 PrintError("Could not translate Read Destination (Virtual) to host VA\n");
279 } else if (dec_instr.dst_operand.type == REG_OPERAND) {
280 dst_addr = dec_instr.dst_operand.operand;
282 dst_addr = (addr_t)&(dec_instr.dst_operand.operand);
285 op_len = dec_instr.src_operand.size;
287 PrintDebug("Dst_Addr = %p, SRC Addr = %p\n",
288 (void *)dst_addr, (void *)src_addr);
290 if (read_fn(read_gpa, (void *)src_addr,op_len, priv_data) != op_len) {
291 PrintError("Did not fully read hooked data\n");
295 if (run_op(info, dec_instr.op_type, src_addr, dst_addr, op_len) == -1) {
296 PrintError("Instruction Emulation Failed\n");
300 info->rip += dec_instr.instr_length;
310 static int run_op(struct guest_info * info, v3_op_type_t op_type, addr_t src_addr, addr_t dst_addr, int op_size) {
316 adc8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
319 add8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
322 and8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
325 or8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
328 xor8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
331 sub8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
335 mov8((addr_t *)dst_addr, (addr_t *)src_addr);
338 not8((addr_t *)dst_addr);
341 xchg8((addr_t *)dst_addr, (addr_t *)src_addr);
346 inc8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
349 dec8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
352 neg8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
355 setb8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
358 setbe8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
361 setl8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
364 setle8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
367 setnb8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
370 setnbe8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
373 setnl8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
376 setnle8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
379 setno8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
382 setnp8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
385 setns8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
388 setnz8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
391 seto8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
394 setp8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
397 sets8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
400 setz8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
404 PrintError("Unknown 8 bit instruction\n");
408 } else if (op_size == 2) {
412 adc16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
415 add16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
418 and16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
421 or16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
424 xor16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
427 sub16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
432 inc16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
435 dec16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
438 neg16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
442 mov16((addr_t *)dst_addr, (addr_t *)src_addr);
445 not16((addr_t *)dst_addr);
448 xchg16((addr_t *)dst_addr, (addr_t *)src_addr);
452 PrintError("Unknown 16 bit instruction\n");
456 } else if (op_size == 4) {
460 adc32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
463 add32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
466 and32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
469 or32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
472 xor32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
475 sub32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
479 inc32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
482 dec32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
485 neg32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
489 mov32((addr_t *)dst_addr, (addr_t *)src_addr);
492 not32((addr_t *)dst_addr);
495 xchg32((addr_t *)dst_addr, (addr_t *)src_addr);
499 PrintError("Unknown 32 bit instruction\n");
504 } else if (op_size == 8) {
509 adc64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
512 add64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
515 and64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
518 or64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
521 xor64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
524 sub64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
528 inc64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
531 dec64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
534 neg64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
538 mov64((addr_t *)dst_addr, (addr_t *)src_addr);
541 not64((addr_t *)dst_addr);
544 xchg64((addr_t *)dst_addr, (addr_t *)src_addr);
548 PrintError("Unknown 64 bit instruction\n");
554 PrintError("Invalid Operation Size\n");