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.


added stos instruction to the emulator
[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 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);
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                                    int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data), 
41                                    void * priv_data) {
42   uint_t emulation_length = 0;
43   addr_t tmp_rcx = 0;
44   addr_t src_addr = 0;
45
46   if (dec_instr->dst_operand.operand != write_gva) {
47     PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
48                (void *)dec_instr->dst_operand.operand, (void *)write_gva);
49     return -1;
50   }
51   
52   emulation_length = ( (dec_instr->str_op_length  < (0x1000 - PAGE_OFFSET_4KB(write_gva))) ? 
53                        dec_instr->str_op_length :
54                        (0x1000 - PAGE_OFFSET_4KB(write_gva)));
55   
56   /* ** Fix emulation length so that it doesn't overrun over the src page either ** */
57   tmp_rcx = emulation_length;
58   
59
60
61
62   if (dec_instr->op_type == V3_OP_MOVS) {
63
64   // figure out addresses here....
65   if (info->mem_mode == PHYSICAL_MEM) {
66     if (guest_pa_to_host_va(info, dec_instr->src_operand.operand, &src_addr) == -1) {
67       PrintError("Could not translate write Source (Physical) to host VA\n");
68       return -1;
69     }
70   } else {
71     if (guest_va_to_host_va(info, dec_instr->src_operand.operand, &src_addr) == -1) {
72       PrintError("Could not translate write Source (Virtual) to host VA\n");
73       return -1;
74     }
75   }
76
77     if (dec_instr->dst_operand.size == 1) {
78       movs8((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
79     } else if (dec_instr->dst_operand.size == 2) {
80       movs16((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
81     } else if (dec_instr->dst_operand.size == 4) {
82       movs32((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
83 #ifdef __V3_64BIT__
84     } else if (dec_instr->dst_operand.size == 8) {
85       movs64((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
86 #endif
87     } else {
88       PrintError("Invalid operand length\n");
89       return -1;
90     }
91
92     info->vm_regs.rdi += emulation_length;
93     info->vm_regs.rsi += emulation_length;
94
95     // RCX is only modified if the rep prefix is present
96     if (dec_instr->prefixes.rep == 1) {
97       info->vm_regs.rcx -= emulation_length;
98     }
99
100   } else if (dec_instr->op_type == V3_OP_STOS) {
101
102     if (dec_instr->dst_operand.size == 1) {
103       stos8((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 == 2) {
105       stos16((addr_t *)&dst_addr, (addr_t  *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
106     } else if (dec_instr->dst_operand.size == 4) {
107       stos32((addr_t *)&dst_addr, (addr_t  *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
108 #ifdef __V3_64BIT__
109     } else if (dec_instr->dst_operand.size == 8) {
110       stos64((addr_t *)&dst_addr, (addr_t  *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
111 #endif
112     } else {
113       PrintError("Invalid operand length\n");
114       return -1;
115     }
116
117     info->vm_regs.rdi += emulation_length;
118     
119     // RCX is only modified if the rep prefix is present
120     if (dec_instr->prefixes.rep == 1) {
121       info->vm_regs.rcx -= emulation_length;
122     }
123
124   } else {
125     PrintError("Unimplemented String operation\n");
126     return -1;
127   }
128
129   if (write_fn(write_gpa, (void *)dst_addr, emulation_length, priv_data) != emulation_length) {
130     PrintError("Did not fully read hooked data\n");
131     return -1;
132   }
133
134   if (emulation_length == dec_instr->str_op_length) {
135     info->rip += dec_instr->instr_length;
136   }
137
138   return emulation_length;
139
140
141   
142
143
144 }
145
146
147
148
149
150 int v3_emulate_write_op(struct guest_info * info, addr_t write_gva, addr_t write_gpa,  addr_t dst_addr, 
151                        int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data), 
152                        void * priv_data) {
153   struct x86_instr dec_instr;
154   uchar_t instr[15];
155   int ret = 0;
156   addr_t src_addr = 0;
157   int src_op_len = 0;
158   int dst_op_len = 0;
159
160   PrintDebug("Emulating Write for instruction at %p\n", (void *)(addr_t)(info->rip));
161   PrintDebug("GVA=%p\n", (void *)write_gva);
162
163   if (info->mem_mode == PHYSICAL_MEM) { 
164     ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
165   } else { 
166     ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
167   }
168
169   if (ret == -1) {
170     return -1;
171   }
172
173   if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
174     PrintError("Decoding Error\n");
175     // Kick off single step emulator
176     return -1;
177   }
178   
179   if (dec_instr.is_str_op) {
180     return emulate_string_write_op(info, &dec_instr, write_gva, write_gpa, dst_addr, write_fn, priv_data);
181   }
182
183
184   if ((dec_instr.dst_operand.type != MEM_OPERAND) ||
185       (dec_instr.dst_operand.operand != write_gva)) {
186     PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
187                (void *)dec_instr.dst_operand.operand, (void *)write_gva);
188     return -1;
189   }
190
191
192   if (dec_instr.src_operand.type == MEM_OPERAND) {
193     if (info->mem_mode == PHYSICAL_MEM) {
194       if (guest_pa_to_host_va(info, dec_instr.src_operand.operand, &src_addr) == -1) {
195         PrintError("Could not translate write Source (Physical) to host VA\n");
196         return -1;
197       }
198     } else {
199       if (guest_va_to_host_va(info, dec_instr.src_operand.operand, &src_addr) == -1) {
200         PrintError("Could not translate write Source (Virtual) to host VA\n");
201         return -1;
202       }
203     }
204   } else if (dec_instr.src_operand.type == REG_OPERAND) {
205     src_addr = dec_instr.src_operand.operand;
206   } else {
207     src_addr = (addr_t)&(dec_instr.src_operand.operand);
208   }
209
210   dst_op_len = dec_instr.dst_operand.size;
211   src_op_len = dec_instr.src_operand.size;
212
213   PrintDebug("Dst_Addr = %p, SRC operand = %p\n", 
214              (void *)dst_addr, (void *)src_addr);
215
216
217   if (run_op(info, dec_instr.op_type, src_addr, dst_addr, src_op_len, dst_op_len) == -1) {
218     PrintError("Instruction Emulation Failed\n");
219     return -1;
220   }
221
222   if (write_fn(write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
223     PrintError("Did not fully write hooked data\n");
224     return -1;
225   }
226
227   info->rip += dec_instr.instr_length;
228
229   return dst_op_len;
230 }
231
232
233 int v3_emulate_read_op(struct guest_info * info, addr_t read_gva, addr_t read_gpa, addr_t src_addr,
234                        int (*read_fn)(addr_t guest_addr, void * dst, uint_t length, void * priv_data), 
235                        void * priv_data) {
236   struct x86_instr dec_instr;
237   uchar_t instr[15];
238   int ret = 0;
239   addr_t dst_addr = 0;
240   int src_op_len = 0;
241   int dst_op_len = 0;
242
243   PrintDebug("Emulating Read for instruction at %p\n", (void *)(addr_t)(info->rip));
244   PrintDebug("GVA=%p\n", (void *)read_gva);
245
246   if (info->mem_mode == PHYSICAL_MEM) { 
247     ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
248   } else { 
249     ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
250   }
251
252   if (ret == -1) {
253     return -1;
254   }
255
256   if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
257     PrintError("Decoding Error\n");
258     // Kick off single step emulator
259     return -1;
260   }
261   
262   if (dec_instr.is_str_op) {
263     PrintError("String operations not implemented on fully hooked regions\n");
264     return -1;
265   }
266
267
268   if ((dec_instr.src_operand.type != MEM_OPERAND) ||
269       (dec_instr.src_operand.operand != read_gva)) {
270     PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
271                (void *)dec_instr.src_operand.operand, (void *)read_gva);
272     return -1;
273   }
274
275
276   if (dec_instr.dst_operand.type == MEM_OPERAND) {
277     if (info->mem_mode == PHYSICAL_MEM) {
278       if (guest_pa_to_host_va(info, dec_instr.dst_operand.operand, &dst_addr) == -1) {
279         PrintError("Could not translate Read Destination (Physical) to host VA\n");
280         return -1;
281       }
282     } else {
283       if (guest_va_to_host_va(info, dec_instr.dst_operand.operand, &dst_addr) == -1) {
284         PrintError("Could not translate Read Destination (Virtual) to host VA\n");
285         return -1;
286       }
287     }
288   } else if (dec_instr.dst_operand.type == REG_OPERAND) {
289     dst_addr = dec_instr.dst_operand.operand;
290   } else {
291     dst_addr = (addr_t)&(dec_instr.dst_operand.operand);
292   }
293
294   src_op_len = dec_instr.src_operand.size;
295   dst_op_len = dec_instr.dst_operand.size;
296
297   PrintDebug("Dst_Addr = %p, SRC Addr = %p\n", 
298              (void *)dst_addr, (void *)src_addr);
299
300   if (read_fn(read_gpa, (void *)src_addr, src_op_len, priv_data) != src_op_len) {
301     PrintError("Did not fully read hooked data\n");
302     return -1;
303   }
304
305   if (run_op(info, dec_instr.op_type, src_addr, dst_addr, src_op_len, dst_op_len) == -1) {
306     PrintError("Instruction Emulation Failed\n");
307     return -1;
308   }
309
310   info->rip += dec_instr.instr_length;
311
312   return src_op_len;
313 }
314
315
316
317
318
319
320 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) {
321
322   if (src_op_size == 1) {
323
324     switch (op_type) {
325     case V3_OP_ADC:
326       adc8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
327       break;
328     case V3_OP_ADD:
329       add8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
330       break;
331     case V3_OP_AND:
332       and8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
333       break;
334     case V3_OP_OR:
335       or8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
336       break;
337     case V3_OP_XOR:
338       xor8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
339       break;
340     case V3_OP_SUB:
341       sub8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
342       break;
343
344     case V3_OP_MOV:
345       mov8((addr_t *)dst_addr, (addr_t *)src_addr);
346       break;
347
348     case V3_OP_MOVZX:
349       movzx8((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
350       break;
351     case V3_OP_MOVSX:
352       movsx8((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
353       break;
354
355     case V3_OP_NOT:
356       not8((addr_t *)dst_addr);
357       break;
358     case V3_OP_XCHG:
359       xchg8((addr_t *)dst_addr, (addr_t *)src_addr);
360       break;
361       
362
363     case V3_OP_INC:
364       inc8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
365       break;
366     case V3_OP_DEC:
367       dec8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
368       break;
369     case V3_OP_NEG:
370       neg8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
371       break;
372     case V3_OP_SETB:
373       setb8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
374       break;
375     case V3_OP_SETBE:
376       setbe8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
377       break;
378     case V3_OP_SETL:
379       setl8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
380       break;
381     case V3_OP_SETLE:
382       setle8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
383       break;
384     case V3_OP_SETNB:
385       setnb8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
386       break;
387     case V3_OP_SETNBE:
388       setnbe8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
389       break;
390     case V3_OP_SETNL:
391       setnl8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
392       break;
393     case V3_OP_SETNLE:
394       setnle8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
395       break;
396     case V3_OP_SETNO:
397       setno8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
398       break;
399     case V3_OP_SETNP:
400       setnp8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
401       break;
402     case V3_OP_SETNS:
403       setns8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
404       break;
405     case V3_OP_SETNZ:
406       setnz8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
407       break;
408     case V3_OP_SETO:
409       seto8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
410       break;
411     case V3_OP_SETP:
412       setp8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
413       break;
414     case V3_OP_SETS:
415       sets8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
416       break;
417     case V3_OP_SETZ:
418       setz8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
419       break;
420
421     default:
422       PrintError("Unknown 8 bit instruction\n");
423       return -1;
424     }
425
426   } else if (src_op_size == 2) {
427
428     switch (op_type) {
429     case V3_OP_ADC:
430       adc16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
431       break;
432     case V3_OP_ADD:
433       add16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
434       break;
435     case V3_OP_AND:
436       and16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
437       break;
438     case V3_OP_OR:
439       or16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
440       break;
441     case V3_OP_XOR:
442       xor16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
443       break;
444     case V3_OP_SUB:
445       sub16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
446       break;
447
448
449     case V3_OP_INC:
450       inc16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
451       break;
452     case V3_OP_DEC:
453       dec16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
454       break;
455     case V3_OP_NEG:
456       neg16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
457       break;
458
459     case V3_OP_MOV:
460       mov16((addr_t *)dst_addr, (addr_t *)src_addr);
461       break;
462     case V3_OP_MOVZX:
463       movzx16((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
464       break;
465     case V3_OP_MOVSX:
466       movsx16((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
467       break;
468     case V3_OP_NOT:
469       not16((addr_t *)dst_addr);
470       break;
471     case V3_OP_XCHG:
472       xchg16((addr_t *)dst_addr, (addr_t *)src_addr);
473       break;
474       
475     default:
476       PrintError("Unknown 16 bit instruction\n");
477       return -1;
478     }
479
480   } else if (src_op_size == 4) {
481
482     switch (op_type) {
483     case V3_OP_ADC:
484       adc32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
485       break;
486     case V3_OP_ADD:
487       add32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
488       break;
489     case V3_OP_AND:
490       and32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
491       break;
492     case V3_OP_OR:
493       or32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
494       break;
495     case V3_OP_XOR:
496       xor32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
497       break;
498     case V3_OP_SUB:
499       sub32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
500       break;
501
502     case V3_OP_INC:
503       inc32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
504       break;
505     case V3_OP_DEC:
506       dec32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
507       break;
508     case V3_OP_NEG:
509       neg32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
510       break;
511
512     case V3_OP_MOV:
513       mov32((addr_t *)dst_addr, (addr_t *)src_addr);
514       break;
515
516     case V3_OP_NOT:
517       not32((addr_t *)dst_addr);
518       break;
519     case V3_OP_XCHG:
520       xchg32((addr_t *)dst_addr, (addr_t *)src_addr);
521       break;
522       
523     default:
524       PrintError("Unknown 32 bit instruction\n");
525       return -1;
526     }
527
528 #ifdef __V3_64BIT__
529   } else if (src_op_size == 8) {
530
531
532     switch (op_type) {
533     case V3_OP_ADC:
534       adc64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
535       break;
536     case V3_OP_ADD:
537       add64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
538       break;
539     case V3_OP_AND:
540       and64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
541       break;
542     case V3_OP_OR:
543       or64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
544       break;
545     case V3_OP_XOR:
546       xor64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
547       break;
548     case V3_OP_SUB:
549       sub64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
550       break;
551
552     case V3_OP_INC:
553       inc64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
554       break;
555     case V3_OP_DEC:
556       dec64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
557       break;
558     case V3_OP_NEG:
559       neg64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
560       break;
561
562     case V3_OP_MOV:
563       mov64((addr_t *)dst_addr, (addr_t *)src_addr);
564       break;
565
566     case V3_OP_NOT:
567       not64((addr_t *)dst_addr);
568       break;
569     case V3_OP_XCHG:
570       xchg64((addr_t *)dst_addr, (addr_t *)src_addr);
571       break;
572       
573     default:
574       PrintError("Unknown 64 bit instruction\n");
575       return -1;
576     }
577 #endif
578
579   } else {
580     PrintError("Invalid Operation Size\n");
581     return -1;
582   }
583
584   return 0;
585 }