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.


Context-based output infrastructure (V3_Print, etc) and modifications to use it
[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  * Authors: Jack Lange <jarusl@cs.northwestern.edu>
15  *          Peter Dinda <pdinda@northwestern.edu> (full hook/string ops)
16  *
17  * This is free software.  You are permitted to use,
18  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
19  */
20
21 #include <palacios/vmm.h>
22 #include <palacios/vmm_emulator.h>
23 #include <palacios/vmm_decoder.h>
24 #include <palacios/vmm_instr_emulator.h>
25 #include <palacios/vmm_ctrl_regs.h>
26
27 #ifndef V3_CONFIG_DEBUG_EMULATOR
28 #undef PrintDebug
29 #define PrintDebug(fmt, args...)
30 #endif
31
32
33 static int run_op(struct guest_info * info, v3_op_type_t op_type, 
34                   addr_t src_addr, addr_t dst_addr, 
35                   int src_op_size, int dst_op_size) {
36
37     if (src_op_size == 1) {
38         PrintDebug(info->vm_info, info, "Executing 8 bit instruction\n");
39
40         switch (op_type) {
41             case V3_OP_ADC:
42                 adc8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
43                 break;
44             case V3_OP_ADD:
45                 add8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
46                 break;
47             case V3_OP_AND:
48                 and8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
49                 break;
50             case V3_OP_OR:
51                 or8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
52                 break;
53             case V3_OP_XOR:
54                 xor8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
55                 break;
56             case V3_OP_SUB:
57                 sub8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
58                 break;
59
60             case V3_OP_MOV:
61                 mov8((addr_t *)dst_addr, (addr_t *)src_addr);
62                 break;
63
64             case V3_OP_MOVZX:
65                 movzx8((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
66                 break;
67             case V3_OP_MOVSX:
68                 movsx8((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
69                 break;
70
71             case V3_OP_NOT:
72                 not8((addr_t *)dst_addr);
73                 break;
74             case V3_OP_XCHG:
75                 xchg8((addr_t *)dst_addr, (addr_t *)src_addr);
76                 break;
77       
78
79             case V3_OP_INC:
80                 inc8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
81                 break;
82             case V3_OP_DEC:
83                 dec8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
84                 break;
85             case V3_OP_NEG:
86                 neg8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
87                 break;
88             case V3_OP_SETB:
89                 setb8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
90                 break;
91             case V3_OP_SETBE:
92                 setbe8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
93                 break;
94             case V3_OP_SETL:
95                 setl8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
96                 break;
97             case V3_OP_SETLE:
98                 setle8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
99                 break;
100             case V3_OP_SETNB:
101                 setnb8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
102                 break;
103             case V3_OP_SETNBE:
104                 setnbe8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
105                 break;
106             case V3_OP_SETNL:
107                 setnl8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
108                 break;
109             case V3_OP_SETNLE:
110                 setnle8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
111                 break;
112             case V3_OP_SETNO:
113                 setno8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
114                 break;
115             case V3_OP_SETNP:
116                 setnp8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
117                 break;
118             case V3_OP_SETNS:
119                 setns8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
120                 break;
121             case V3_OP_SETNZ:
122                 setnz8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
123                 break;
124             case V3_OP_SETO:
125                 seto8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
126                 break;
127             case V3_OP_SETP:
128                 setp8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
129                 break;
130             case V3_OP_SETS:
131                 sets8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
132                 break;
133             case V3_OP_SETZ:
134                 setz8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
135                 break;
136
137             default:
138                 PrintError(info->vm_info, info, "Unknown 8 bit instruction\n");
139                 return -1;
140         }
141
142     } else if (src_op_size == 2) {
143         PrintDebug(info->vm_info, info, "Executing 16 bit instruction\n");
144
145         switch (op_type) {
146             case V3_OP_ADC:
147                 adc16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
148                 break;
149             case V3_OP_ADD:
150                 add16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
151                 break;
152             case V3_OP_AND:
153                 and16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
154                 break;
155             case V3_OP_OR:
156                 or16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
157                 break;
158             case V3_OP_XOR:
159                 xor16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
160                 break;
161             case V3_OP_SUB:
162                 sub16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
163                 break;
164
165
166             case V3_OP_INC:
167                 inc16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
168                 break;
169             case V3_OP_DEC:
170                 dec16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
171                 break;
172             case V3_OP_NEG:
173                 neg16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
174                 break;
175
176             case V3_OP_MOV:
177                 mov16((addr_t *)dst_addr, (addr_t *)src_addr);
178                 break;
179             case V3_OP_MOVZX:
180                 movzx16((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
181                 break;
182             case V3_OP_MOVSX:
183                 movsx16((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
184                 break;
185             case V3_OP_NOT:
186                 not16((addr_t *)dst_addr);
187                 break;
188             case V3_OP_XCHG:
189                 xchg16((addr_t *)dst_addr, (addr_t *)src_addr);
190                 break;
191       
192             default:
193                 PrintError(info->vm_info, info, "Unknown 16 bit instruction\n");
194                 return -1;
195         }
196
197     } else if (src_op_size == 4) {
198         PrintDebug(info->vm_info, info, "Executing 32 bit instruction\n");
199
200         switch (op_type) {
201             case V3_OP_ADC:
202                 adc32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
203                 break;
204             case V3_OP_ADD:
205                 add32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
206                 break;
207             case V3_OP_AND:
208                 and32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
209                 break;
210             case V3_OP_OR:
211                 or32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
212                 break;
213             case V3_OP_XOR:
214                 xor32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
215                 break;
216             case V3_OP_SUB:
217                 sub32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
218                 break;
219
220             case V3_OP_INC:
221                 inc32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
222                 break;
223             case V3_OP_DEC:
224                 dec32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
225                 break;
226             case V3_OP_NEG:
227                 neg32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
228                 break;
229
230             case V3_OP_MOV:
231                 mov32((addr_t *)dst_addr, (addr_t *)src_addr);
232                 break;
233
234             case V3_OP_NOT:
235                 not32((addr_t *)dst_addr);
236                 break;
237             case V3_OP_XCHG:
238                 xchg32((addr_t *)dst_addr, (addr_t *)src_addr);
239                 break;
240       
241             default:
242                 PrintError(info->vm_info, info, "Unknown 32 bit instruction\n");
243                 return -1;
244         }
245
246 #ifdef __V3_64BIT__
247     } else if (src_op_size == 8) {
248         PrintDebug(info->vm_info, info, "Executing 64 bit instruction\n");
249
250         switch (op_type) {
251             case V3_OP_ADC:
252                 adc64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
253                 break;
254             case V3_OP_ADD:
255                 add64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
256                 break;
257             case V3_OP_AND:
258                 and64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
259                 break;
260             case V3_OP_OR:
261                 or64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
262                 break;
263             case V3_OP_XOR:
264                 xor64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
265                 break;
266             case V3_OP_SUB:
267                 sub64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
268                 break;
269
270             case V3_OP_INC:
271                 inc64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
272                 break;
273             case V3_OP_DEC:
274                 dec64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
275                 break;
276             case V3_OP_NEG:
277                 neg64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
278                 break;
279
280             case V3_OP_MOV:
281                 mov64((addr_t *)dst_addr, (addr_t *)src_addr);
282                 break;
283
284             case V3_OP_NOT:
285                 not64((addr_t *)dst_addr);
286                 break;
287             case V3_OP_XCHG:
288                 xchg64((addr_t *)dst_addr, (addr_t *)src_addr);
289                 break;
290       
291             default:
292                 PrintError(info->vm_info, info, "Unknown 64 bit instruction\n");
293                 return -1;
294         }
295 #endif
296
297     } else {
298         PrintError(info->vm_info, info, "Invalid Operation Size\n");
299         return -1;
300     }
301
302     return 0;
303 }
304
305
306
307 /* Returns the number of bytes written, or -1 if there is an error */
308 static int run_str_op(struct guest_info * core, struct x86_instr * instr, 
309                       addr_t src_addr, addr_t dst_addr, 
310                       int op_size, int rep_cnt) {
311
312     addr_t tmp_rcx = rep_cnt;
313     int emulation_length = op_size * rep_cnt;
314     struct rflags * flags_reg = (struct rflags *)&(core->ctrl_regs.rflags);
315
316
317     PrintDebug(core->vm_info, core, "Emulation_len=%d, tmp_rcx=%d\n", emulation_length, (uint_t)tmp_rcx);
318
319
320     if (instr->op_type == V3_OP_MOVS) {
321         if (op_size== 1) {
322             movs8((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(core->ctrl_regs.rflags));
323         } else if (op_size == 2) {
324             movs16((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(core->ctrl_regs.rflags));
325         } else if (op_size == 4) {
326             movs32((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(core->ctrl_regs.rflags));
327 #ifdef __V3_64BIT__
328         } else if (op_size == 8) {
329             movs64((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(core->ctrl_regs.rflags));
330 #endif
331         } else {
332             PrintError(core->vm_info, core, "Invalid operand length\n");
333             return -1;
334         }
335
336         if (flags_reg->df == 0) {
337             core->vm_regs.rdi += emulation_length;
338             core->vm_regs.rsi += emulation_length;
339         } else {
340             core->vm_regs.rdi -= emulation_length;
341             core->vm_regs.rsi -= emulation_length;
342         }
343
344         // RCX is only modified if the rep prefix is present
345         if (instr->prefixes.rep == 1) {
346             core->vm_regs.rcx -= rep_cnt;
347         }
348
349      } else if (instr->op_type == V3_OP_STOS) {
350         if (op_size == 1) {
351             stos8((addr_t *)&dst_addr, (addr_t  *)&(core->vm_regs.rax), &tmp_rcx, (addr_t *)&(core->ctrl_regs.rflags));
352         } else if (op_size == 2) {
353             stos16((addr_t *)&dst_addr, (addr_t  *)&(core->vm_regs.rax), &tmp_rcx, (addr_t *)&(core->ctrl_regs.rflags));
354         } else if (op_size == 4) {
355             stos32((addr_t *)&dst_addr, (addr_t  *)&(core->vm_regs.rax), &tmp_rcx, (addr_t *)&(core->ctrl_regs.rflags));
356 #ifdef __V3_64BIT__
357         } else if (op_size == 8) {
358             stos64((addr_t *)&dst_addr, (addr_t  *)&(core->vm_regs.rax), &tmp_rcx, (addr_t *)&(core->ctrl_regs.rflags));
359 #endif
360         } else {
361             PrintError(core->vm_info, core, "Invalid operand length\n");
362             return -1;
363         }
364
365
366
367         if (flags_reg->df == 0) {
368             core->vm_regs.rdi += emulation_length;
369         } else {
370             core->vm_regs.rdi -= emulation_length;
371         }
372
373         // RCX is only modified if the rep prefix is present
374         if (instr->prefixes.rep == 1) {
375             core->vm_regs.rcx -= rep_cnt;
376         }
377     } else {
378         PrintError(core->vm_info, core, "Unimplemented String operation\n");
379         return -1;
380     }
381     
382     return emulation_length;
383 }
384
385
386
387 int v3_emulate(struct guest_info * core, struct x86_instr * instr, 
388                int mem_op_size, addr_t mem_hva_src, addr_t mem_hva_dst) {
389
390     addr_t src_hva = 0;
391     addr_t dst_hva = 0;
392
393
394     if (instr->src_operand.type == MEM_OPERAND) {
395         src_hva = mem_hva_src;
396     } else if (instr->src_operand.type == REG_OPERAND) {
397         src_hva = instr->src_operand.operand;
398     } else {
399         src_hva = (addr_t)&(instr->src_operand.operand);
400     }
401
402     if (instr->dst_operand.type == MEM_OPERAND) {
403         dst_hva = mem_hva_dst;
404     } else if (instr->dst_operand.type == REG_OPERAND) {
405         dst_hva = instr->dst_operand.operand;
406     } else {
407         dst_hva = (addr_t)&(instr->dst_operand.operand);
408     }
409  
410
411     if (instr->is_str_op == 0) {
412         int src_op_len = instr->src_operand.size;
413         int dst_op_len = instr->dst_operand.size;
414         
415         run_op(core, instr->op_type, src_hva, dst_hva, src_op_len, dst_op_len);
416
417         return dst_op_len;
418     } else {
419         // String Operation
420         int rep_cnt = 0;
421
422         /* Both src and dst operand sizes should be identical */
423         rep_cnt = mem_op_size / instr->src_operand.size;
424
425         return run_str_op(core, instr, src_hva, dst_hva, instr->src_operand.size, rep_cnt);
426     }
427
428
429     return -1;
430 }