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.


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