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.


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