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.


cleaned up the emulation code to be more general
[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 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("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("Unknown 8 bit instruction\n");
139                 return -1;
140         }
141
142     } else if (src_op_size == 2) {
143         PrintDebug("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("Unknown 16 bit instruction\n");
194                 return -1;
195         }
196
197     } else if (src_op_size == 4) {
198         PrintDebug("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("Unknown 32 bit instruction\n");
243                 return -1;
244         }
245
246 #ifdef __V3_64BIT__
247     } else if (src_op_size == 8) {
248         PrintDebug("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("Unknown 64 bit instruction\n");
293                 return -1;
294         }
295 #endif
296
297     } else {
298         PrintError("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     if (instr->op_type == V3_OP_MOVS) {
317         if (op_size== 1) {
318             movs8((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(core->ctrl_regs.rflags));
319         } else if (op_size == 2) {
320             movs16((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(core->ctrl_regs.rflags));
321         } else if (op_size == 4) {
322             movs32((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(core->ctrl_regs.rflags));
323 #ifdef __V3_64BIT__
324         } else if (op_size == 8) {
325             movs64((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(core->ctrl_regs.rflags));
326 #endif
327         } else {
328             PrintError("Invalid operand length\n");
329             return -1;
330         }
331
332         if (flags_reg->df == 0) {
333             core->vm_regs.rdi += emulation_length;
334             core->vm_regs.rsi += emulation_length;
335         } else {
336             core->vm_regs.rdi -= emulation_length;
337             core->vm_regs.rsi -= emulation_length;
338         }
339
340         // RCX is only modified if the rep prefix is present
341         if (instr->prefixes.rep == 1) {
342             core->vm_regs.rcx -= rep_cnt;
343         }
344
345      } else if (instr->op_type == V3_OP_STOS) {
346         if (op_size == 1) {
347             stos8((addr_t *)&dst_addr, (addr_t  *)&(core->vm_regs.rax), &tmp_rcx, (addr_t *)&(core->ctrl_regs.rflags));
348         } else if (op_size == 2) {
349             stos16((addr_t *)&dst_addr, (addr_t  *)&(core->vm_regs.rax), &tmp_rcx, (addr_t *)&(core->ctrl_regs.rflags));
350         } else if (op_size == 4) {
351             stos32((addr_t *)&dst_addr, (addr_t  *)&(core->vm_regs.rax), &tmp_rcx, (addr_t *)&(core->ctrl_regs.rflags));
352 #ifdef __V3_64BIT__
353         } else if (op_size == 8) {
354             stos64((addr_t *)&dst_addr, (addr_t  *)&(core->vm_regs.rax), &tmp_rcx, (addr_t *)&(core->ctrl_regs.rflags));
355 #endif
356         } else {
357             PrintError("Invalid operand length\n");
358             return -1;
359         }
360
361         if (flags_reg->df == 0) {
362             core->vm_regs.rdi += emulation_length;
363         } else {
364             core->vm_regs.rdi -= emulation_length;
365         }
366
367         // RCX is only modified if the rep prefix is present
368         if (instr->prefixes.rep == 1) {
369             core->vm_regs.rcx -= rep_cnt;
370         }
371     } else {
372         PrintError("Unimplemented String operation\n");
373         return -1;
374     }
375     
376     return emulation_length;
377 }
378
379
380
381 int v3_emulate(struct guest_info * core, struct x86_instr * instr, 
382                int mem_op_size, addr_t mem_hva_src, addr_t mem_hva_dst) {
383
384     addr_t src_hva = 0;
385     addr_t dst_hva = 0;
386     
387     PrintError("USING THE NEW EMULATOR\n");
388
389     if (instr->src_operand.type == MEM_OPERAND) {
390         src_hva = mem_hva_src;
391     } else if (instr->src_operand.type == REG_OPERAND) {
392         src_hva = instr->src_operand.operand;
393     } else {
394         src_hva = (addr_t)&(instr->src_operand.operand);
395     }
396         
397     if (instr->dst_operand.type == MEM_OPERAND) {
398         dst_hva = mem_hva_dst;
399     } else if (instr->dst_operand.type == REG_OPERAND) {
400         dst_hva = instr->dst_operand.operand;
401     } else {
402         dst_hva = (addr_t)&(instr->dst_operand.operand);
403     }
404     
405
406     if (instr->is_str_op == 0) {
407         int src_op_len = instr->src_operand.size;
408         int dst_op_len = instr->dst_operand.size;
409         
410         run_op(core, instr->op_type, src_hva, dst_hva, src_op_len, dst_op_len);
411
412         return dst_op_len;
413     } else {
414         // String Operation
415         int rep_cnt = 0;
416
417         /* Both src and dst operand sizes should be identical */
418         rep_cnt = mem_op_size / instr->src_operand.size;
419
420         return run_str_op(core, instr, src_hva, dst_hva, instr->src_operand.size, rep_cnt);
421     }
422
423
424
425     return -1;
426 }