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