Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


bb67a5fe554cee0bf99713438e292f0aa05e6d0f
[palacios.git] / palacios / src / palacios / vmm_emulator.c
1 /* 
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.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
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.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
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>
26
27 #ifndef DEBUG_EMULATOR
28 #undef PrintDebug
29 #define PrintDebug(fmt, args...)
30 #endif
31
32
33
34
35
36
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   uint_t emulation_length = 0;
41   addr_t tmp_rcx = 0;
42   addr_t src_addr = 0;
43
44   if (dec_instr->op_type == V3_OP_MOVS) {
45     PrintDebug("MOVS emulation\n");
46
47     if (dec_instr->dst_operand.operand != write_gva) {
48       PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
49                  (void *)dec_instr->dst_operand.operand, (void *)write_gva);
50       return -1;
51     }
52
53     emulation_length = ( (dec_instr->str_op_length  < (0x1000 - PAGE_OFFSET_4KB(write_gva))) ? 
54                          dec_instr->str_op_length :
55                          (0x1000 - PAGE_OFFSET_4KB(write_gva)));
56     /* ** Fix emulation length so that it doesn't overrun over the src page either ** */
57
58
59     PrintDebug("STR_OP_LEN: %d, Page Len: %d\n", 
60                (uint_t)dec_instr->str_op_length, 
61                (uint_t)(0x1000 - PAGE_OFFSET_4KB(write_gva)));
62     PrintDebug("Emulation length: %d\n", emulation_length);
63     tmp_rcx = emulation_length;
64  
65     if (guest_pa_to_host_va(info, write_gpa, dst_addr) == -1) {
66       PrintError("Could not translate write destination to host VA\n");
67       return -1;
68     }
69
70     // figure out addresses here....
71     if (info->mem_mode == PHYSICAL_MEM) {
72       if (guest_pa_to_host_va(info, dec_instr->src_operand.operand, &src_addr) == -1) {
73         PrintError("Could not translate write Source (Physical) to host VA\n");
74         return -1;
75       }
76     } else {
77       if (guest_va_to_host_va(info, dec_instr->src_operand.operand, &src_addr) == -1) {
78         PrintError("Could not translate write Source (Virtual) to host VA\n");
79         return -1;
80       }
81     }
82
83
84     PrintDebug("Dst Operand: %p (size=%d), Src Operand: %p\n", 
85                (void *)dec_instr->dst_operand.operand, 
86                dec_instr->dst_operand.size,
87                (void *)dec_instr->src_operand.operand);
88     PrintDebug("Dst Addr: %p, Src Addr: %p\n", (void *)(addr_t *)*dst_addr, (void *)src_addr);
89
90     //return -1;
91
92
93  
94
95
96     if (dec_instr->dst_operand.size == 1) {
97       movs8(dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
98     } else if (dec_instr->dst_operand.size == 2) {
99       movs16(dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
100     } else if (dec_instr->dst_operand.size == 4) {
101       movs32(dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
102     } else {
103       PrintError("Invalid operand length\n");
104       return -1;
105     }
106
107
108
109
110
111     PrintDebug("RDI=%p, RSI=%p, RCX=%p\n", 
112                (void *)*(addr_t *)&(info->vm_regs.rdi), 
113                (void *)*(addr_t *)&(info->vm_regs.rsi), 
114                (void *)*(addr_t *)&(info->vm_regs.rcx)); 
115
116     info->vm_regs.rdi += emulation_length;
117     info->vm_regs.rsi += emulation_length;
118     info->vm_regs.rcx -= emulation_length;
119     
120     PrintDebug("RDI=%p, RSI=%p, RCX=%p\n", 
121                (void *)*(addr_t *)&(info->vm_regs.rdi), 
122                (void *)*(addr_t *)&(info->vm_regs.rsi), 
123                (void *)*(addr_t *)&(info->vm_regs.rcx)); 
124
125     if (emulation_length == dec_instr->str_op_length) {
126       info->rip += dec_instr->instr_length;
127     }
128
129     return emulation_length;
130   }
131
132   
133
134
135   return -1;
136 }
137
138
139 int v3_emulate_write_op(struct guest_info * info, addr_t write_gva, addr_t write_gpa, addr_t * dst_addr) {
140   struct x86_instr dec_instr;
141   uchar_t instr[15];
142   int ret = 0;
143   addr_t src_addr = 0;
144
145
146   PrintDebug("Emulating Write for instruction at %p\n", (void *)(addr_t)(info->rip));
147   PrintDebug("GPA=%p, GVA=%p\n", (void *)write_gpa, (void *)write_gva);
148
149   if (info->mem_mode == PHYSICAL_MEM) { 
150     ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
151   } else { 
152     ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
153   }
154
155   if (ret == -1) {
156     return -1;
157   }
158
159
160   if (guest_pa_to_host_va(info, write_gpa, dst_addr) == -1) {
161     PrintError("Could not translate write destination to host VA\n");
162     return -1;
163   }
164
165   if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
166     PrintError("Decoding Error\n");
167     // Kick off single step emulator
168     return -1;
169   }
170   
171   if (dec_instr.is_str_op) {
172     return emulate_string_write_op(info, &dec_instr, write_gva, write_gpa, dst_addr);
173   }
174
175
176   if ((dec_instr.dst_operand.type != MEM_OPERAND) ||
177       (dec_instr.dst_operand.operand != write_gva)) {
178     PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
179                (void *)dec_instr.dst_operand.operand, (void *)write_gva);
180     return -1;
181   }
182
183
184   if (dec_instr.src_operand.type == MEM_OPERAND) {
185     if (info->mem_mode == PHYSICAL_MEM) {
186       if (guest_pa_to_host_va(info, dec_instr.src_operand.operand, &src_addr) == -1) {
187         PrintError("Could not translate write Source (Physical) to host VA\n");
188         return -1;
189       }
190     } else {
191       if (guest_va_to_host_va(info, dec_instr.src_operand.operand, &src_addr) == -1) {
192         PrintError("Could not translate write Source (Virtual) to host VA\n");
193         return -1;
194       }
195     }
196   } else if (dec_instr.src_operand.type == REG_OPERAND) {
197     src_addr = dec_instr.src_operand.operand;
198   } else {
199     src_addr = (addr_t)&(dec_instr.src_operand.operand);
200   }
201
202
203   PrintDebug("Dst_Addr Ptr = %p (val=%p), SRC operand = %p\n", 
204              (void *)dst_addr, (void *)*dst_addr, (void *)src_addr);
205
206
207   if (dec_instr.dst_operand.size == 1) {
208
209     switch (dec_instr.op_type) {
210     case V3_OP_ADC:
211       adc8((addr_t *)*dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
212       break;
213     case V3_OP_ADD:
214       add8((addr_t *)*dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
215       break;
216     case V3_OP_AND:
217       and8((addr_t *)*dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
218       break;
219     case V3_OP_OR:
220       or8((addr_t *)*dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
221       break;
222     case V3_OP_XOR:
223       xor8((addr_t *)*dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
224       break;
225     case V3_OP_SUB:
226       sub8((addr_t *)*dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
227       break;
228
229     case V3_OP_MOV:
230       mov8((addr_t *)*dst_addr, (addr_t *)src_addr);
231       break;
232     case V3_OP_NOT:
233       not8((addr_t *)*dst_addr);
234       break;
235     case V3_OP_XCHG:
236       xchg8((addr_t *)*dst_addr, (addr_t *)src_addr);
237       break;
238       
239
240     case V3_OP_INC:
241       inc8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
242       break;
243     case V3_OP_DEC:
244       dec8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
245       break;
246     case V3_OP_NEG:
247       neg8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
248       break;
249     case V3_OP_SETB:
250       setb8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
251       break;
252     case V3_OP_SETBE:
253       setbe8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
254       break;
255     case V3_OP_SETL:
256       setl8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
257       break;
258     case V3_OP_SETLE:
259       setle8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
260       break;
261     case V3_OP_SETNB:
262       setnb8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
263       break;
264     case V3_OP_SETNBE:
265       setnbe8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
266       break;
267     case V3_OP_SETNL:
268       setnl8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
269       break;
270     case V3_OP_SETNLE:
271       setnle8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
272       break;
273     case V3_OP_SETNO:
274       setno8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
275       break;
276     case V3_OP_SETNP:
277       setnp8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
278       break;
279     case V3_OP_SETNS:
280       setns8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
281       break;
282     case V3_OP_SETNZ:
283       setnz8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
284       break;
285     case V3_OP_SETO:
286       seto8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
287       break;
288     case V3_OP_SETP:
289       setp8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
290       break;
291     case V3_OP_SETS:
292       sets8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
293       break;
294     case V3_OP_SETZ:
295       setz8((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
296       break;
297
298     default:
299       PrintError("Unknown 8 bit instruction\n");
300       return -1;
301     }
302
303   } else if (dec_instr.dst_operand.size == 2) {
304
305     switch (dec_instr.op_type) {
306     case V3_OP_ADC:
307       adc16((addr_t *)*dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
308       break;
309     case V3_OP_ADD:
310       add16((addr_t *)*dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
311       break;
312     case V3_OP_AND:
313       and16((addr_t *)*dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
314       break;
315     case V3_OP_OR:
316       or16((addr_t *)*dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
317       break;
318     case V3_OP_XOR:
319       xor16((addr_t *)*dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
320       break;
321     case V3_OP_SUB:
322       sub16((addr_t *)*dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
323       break;
324
325
326     case V3_OP_INC:
327       inc16((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
328       break;
329     case V3_OP_DEC:
330       dec16((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
331       break;
332     case V3_OP_NEG:
333       neg16((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
334       break;
335
336     case V3_OP_MOV:
337       mov16((addr_t *)*dst_addr, (addr_t *)src_addr);
338       break;
339     case V3_OP_NOT:
340       not16((addr_t *)*dst_addr);
341       break;
342     case V3_OP_XCHG:
343       xchg16((addr_t *)*dst_addr, (addr_t *)src_addr);
344       break;
345       
346     default:
347       PrintError("Unknown 16 bit instruction\n");
348       return -1;
349     }
350
351   } else if (dec_instr.dst_operand.size == 4) {
352
353     switch (dec_instr.op_type) {
354     case V3_OP_ADC:
355       adc32((addr_t *)*dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
356       break;
357     case V3_OP_ADD:
358       add32((addr_t *)*dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
359       break;
360     case V3_OP_AND:
361       and32((addr_t *)*dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
362       break;
363     case V3_OP_OR:
364       or32((addr_t *)*dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
365       break;
366     case V3_OP_XOR:
367       xor32((addr_t *)*dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
368       break;
369     case V3_OP_SUB:
370       sub32((addr_t *)*dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
371       break;
372
373     case V3_OP_INC:
374       inc32((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
375       break;
376     case V3_OP_DEC:
377       dec32((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
378       break;
379     case V3_OP_NEG:
380       neg32((addr_t *)*dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
381       break;
382
383     case V3_OP_MOV:
384       mov32((addr_t *)*dst_addr, (addr_t *)src_addr);
385       break;
386     case V3_OP_NOT:
387       not32((addr_t *)*dst_addr);
388       break;
389     case V3_OP_XCHG:
390       xchg32((addr_t *)*dst_addr, (addr_t *)src_addr);
391       break;
392       
393     default:
394       PrintError("Unknown 32 bit instruction\n");
395       return -1;
396     }
397
398   } else if (dec_instr.dst_operand.size == 8) {
399     PrintError("64 bit instructions not handled\n");
400     return -1;
401   } else {
402     PrintError("Invalid Operation Size\n");
403     return -1;
404   }
405
406   info->rip += dec_instr.instr_length;
407
408   return dec_instr.dst_operand.size;
409 }
410