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.


integrated decoder
[palacios.git] / palacios / include / palacios / vmm_decoder.h
1 #ifndef __VMM_EMULATE_H
2 #define __VMM_EMULATE_H
3
4 #ifdef __V3VEE__
5
6 #include <palacios/vm_guest.h>
7 #include <palacios/vmm.h>
8
9 /*
10  * This is where we do the hideous X86 instruction parsing among other things
11  * We can parse out the instruction prefixes, as well as decode the operands 
12  */
13
14
15
16
17
18 typedef enum {INVALID_OPERAND, REG_OPERAND, MEM_OPERAND} operand_type_t;
19
20 struct x86_operand {
21   addr_t operand;
22   uint_t size;
23   operand_type_t type;
24 };
25
26 struct x86_prefix_list {
27   uint_t lock   : 1;  // 0xF0
28   uint_t repne  : 1;  // 0xF2
29   uint_t repnz  : 1;  // 0xF2
30   uint_t rep    : 1;  // 0xF3
31   uint_t repe   : 1;  // 0xF3
32   uint_t repz   : 1;  // 0xF3
33   uint_t cs_override : 1;  // 0x2E
34   uint_t ss_override : 1;  // 0x36
35   uint_t ds_override : 1;  // 0x3E
36   uint_t es_override : 1;  // 0x26
37   uint_t fs_override : 1;  // 0x64
38   uint_t gs_override : 1;  // 0x65
39   uint_t br_not_taken : 1;  // 0x2E
40   uint_t br_takend   : 1;  // 0x3E
41   uint_t op_size     : 1;  // 0x66
42   uint_t addr_size   : 1;  // 0x67
43 };
44
45
46 struct x86_instr {
47   uint_t instr_length;                // output
48   addr_t opcode;                      // output
49   uint_t  opcode_length;               // output
50   struct x86_prefix_list prefixes;    // output
51   struct x86_operand src_operand;     // output
52   struct x86_operand dst_operand;     // output
53   struct x86_operand extra_operand;
54 };
55
56
57   /************************/
58  /* EXTERNAL DECODER API */
59 /************************/
60 /* 
61    This is an External API definition that must be implemented by a decoder
62 */
63
64
65 /* 
66  * Initializes a decoder
67  */
68 int init_decoder();
69
70 /* 
71  * Decodes an instruction 
72  * All addresses in arguments are in the host address space
73  * instr_ptr is the host address of the instruction 
74  * IMPORTANT: make sure the instr_ptr is in contiguous host memory
75  *   ie. Copy it to a buffer before the call
76  */
77 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr);
78
79 /* 
80  * Encodes an instruction
81  * All addresses in arguments are in the host address space
82  * The instruction is encoded from the struct, and copied into a 15 byte host buffer
83  * referenced by instr_buf
84  * any unused bytes at the end of instr_buf will be filled with nops
85  * IMPORTANT: instr_buf must be allocated and 15 bytes long
86  */
87 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf);
88
89
90
91
92
93
94
95
96
97 /* 
98  * JRL: Some of this was taken from the Xen sources... 
99  */
100
101 #define PACKED __attribute__((packed))
102
103 #define MODRM_MOD(x) ((x >> 6) & 0x3)
104 #define MODRM_REG(x) ((x >> 3) & 0x7)
105 #define MODRM_RM(x)  (x & 0x7)
106
107 struct modrm_byte {
108   uint_t rm   :   3 PACKED;
109   uint_t reg  :   3 PACKED;
110   uint_t mod  :   2 PACKED;
111 };
112
113
114 #define SIB_BASE(x) ((x >> 6) & 0x3)
115 #define SIB_INDEX(x) ((x >> 3) & 0x7)
116 #define SIB_SCALE(x) (x & 0x7)
117
118 struct sib_byte {
119   uint_t base     :   3 PACKED;
120   uint_t index    :   3 PACKED;
121   uint_t scale    :   2 PACKED;
122 };
123
124
125
126 #define MAKE_INSTR(nm, ...) static const uchar_t OPCODE_##nm[] = { __VA_ARGS__ }
127
128 /* 
129  * Here's how it works:
130  * First byte: Length. 
131  * Following bytes: Opcode bytes. 
132  * Special case: Last byte, if zero, doesn't need to match. 
133  */
134 MAKE_INSTR(INVD,   2, 0x0f, 0x08);
135 MAKE_INSTR(CPUID,  2, 0x0f, 0xa2);
136 MAKE_INSTR(RDMSR,  2, 0x0f, 0x32);
137 MAKE_INSTR(WRMSR,  2, 0x0f, 0x30);
138 MAKE_INSTR(RDTSC,  2, 0x0f, 0x31);
139 MAKE_INSTR(RDTSCP, 3, 0x0f, 0x01, 0xf9);
140 MAKE_INSTR(CLI,    1, 0xfa);
141 MAKE_INSTR(STI,    1, 0xfb);
142 MAKE_INSTR(RDPMC,  2, 0x0f, 0x33);
143 MAKE_INSTR(CLGI,   3, 0x0f, 0x01, 0xdd);
144 MAKE_INSTR(STGI,   3, 0x0f, 0x01, 0xdc);
145 MAKE_INSTR(VMRUN,  3, 0x0f, 0x01, 0xd8);
146 MAKE_INSTR(VMLOAD, 3, 0x0f, 0x01, 0xda);
147 MAKE_INSTR(VMSAVE, 3, 0x0f, 0x01, 0xdb);
148 MAKE_INSTR(VMCALL, 3, 0x0f, 0x01, 0xd9);
149 MAKE_INSTR(PAUSE,  2, 0xf3, 0x90);
150 MAKE_INSTR(SKINIT, 3, 0x0f, 0x01, 0xde);
151 MAKE_INSTR(MOV2CR, 3, 0x0f, 0x22, 0x00);
152 MAKE_INSTR(MOVCR2, 3, 0x0f, 0x20, 0x00);
153 MAKE_INSTR(MOV2DR, 3, 0x0f, 0x23, 0x00);
154 MAKE_INSTR(MOVDR2, 3, 0x0f, 0x21, 0x00);
155 MAKE_INSTR(PUSHF,  1, 0x9c);
156 MAKE_INSTR(POPF,   1, 0x9d);
157 MAKE_INSTR(RSM,    2, 0x0f, 0xaa);
158 MAKE_INSTR(INVLPG, 3, 0x0f, 0x01, 0x00);
159 MAKE_INSTR(INVLPGA,3, 0x0f, 0x01, 0xdf);
160 MAKE_INSTR(HLT,    1, 0xf4);
161 MAKE_INSTR(CLTS,   2, 0x0f, 0x06);
162 MAKE_INSTR(LMSW,   3, 0x0f, 0x01, 0x00);
163 MAKE_INSTR(SMSW,   3, 0x0f, 0x01, 0x00);
164
165
166 #define PREFIX_LOCK         0xF0
167 #define PREFIX_REPNE        0xF2
168 #define PREFIX_REPNZ        0xF2
169 #define PREFIX_REP          0xF3
170 #define PREFIX_REPE         0xF3
171 #define PREFIX_REPZ         0xF3
172 #define PREFIX_CS_OVERRIDE  0x2E
173 #define PREFIX_SS_OVERRIDE  0x36
174 #define PREFIX_DS_OVERRIDE  0x3E
175 #define PREFIX_ES_OVERRIDE  0x26
176 #define PREFIX_FS_OVERRIDE  0x64
177 #define PREFIX_GS_OVERRIDE  0x65
178 #define PREFIX_BR_NOT_TAKEN 0x2E
179 #define PREFIX_BR_TAKEN     0x3E
180 #define PREFIX_OP_SIZE      0x66
181 #define PREFIX_ADDR_SIZE    0x67
182
183 static inline int is_prefix_byte(char byte) {
184   switch (byte) {
185   case 0xF0:      // lock
186   case 0xF2:      // REPNE/REPNZ
187   case 0xF3:      // REP or REPE/REPZ
188   case 0x2E:      // CS override or Branch hint not taken (with Jcc instrs)
189   case 0x36:      // SS override
190   case 0x3E:      // DS override or Branch hint taken (with Jcc instrs)
191   case 0x26:      // ES override
192   case 0x64:      // FS override
193   case 0x65:      // GS override
194     //case 0x2E:      // branch not taken hint
195     //  case 0x3E:      // branch taken hint
196   case 0x66:      // operand size override
197   case 0x67:      // address size override
198     return 1;
199     break;
200   default:
201     return 0;
202     break;
203   }
204 }
205
206
207 static inline v3_reg_t get_gpr_mask(struct guest_info * info) {
208   switch (info->cpu_mode) {
209   case REAL: 
210     return 0xffff;
211     break;
212   case PROTECTED:
213     return 0xffffffff;
214   default:
215     V3_ASSERT(0);
216     return 0;
217   }
218 }
219
220
221 static inline addr_t get_addr_linear(struct guest_info * info, addr_t addr, struct v3_segment * seg) {
222   switch (info->cpu_mode) {
223   case REAL:
224     // It appears that the segment values are computed and cached in the vmcb structure 
225     // We Need to check this for Intel
226     /*   return addr + (seg->selector << 4);
227          break;*/
228
229   case PROTECTED:
230     return addr + seg->base;
231     break;
232   default:
233     V3_ASSERT(0);
234     return 0;
235   }
236 }
237
238
239 typedef enum {INVALID_ADDR_TYPE, REG, DISP0, DISP8, DISP16, DISP32} modrm_mode_t;
240 typedef enum {INVALID_REG_SIZE, REG64, REG32, REG16, REG8} reg_size_t;
241
242
243
244
245
246
247 struct v3_gprs;
248
249 static inline addr_t decode_register(struct v3_gprs * gprs, char reg_code, reg_size_t reg_size) {
250   addr_t reg_addr;
251
252   switch (reg_code) {
253   case 0:
254     reg_addr = (addr_t)&(gprs->rax);
255     break;
256   case 1:
257     reg_addr = (addr_t)&(gprs->rcx);
258     break;
259   case 2:
260     reg_addr = (addr_t)&(gprs->rdx);
261     break;
262   case 3:
263     reg_addr = (addr_t)&(gprs->rbx);
264     break;
265   case 4:
266     if (reg_size == REG8) {
267       reg_addr = (addr_t)&(gprs->rax) + 1;
268     } else {
269       reg_addr = (addr_t)&(gprs->rsp);
270     }
271     break;
272   case 5:
273     if (reg_size == REG8) {
274       reg_addr = (addr_t)&(gprs->rcx) + 1;
275     } else {
276       reg_addr = (addr_t)&(gprs->rbp);
277     }
278     break;
279   case 6:
280     if (reg_size == REG8) {
281       reg_addr = (addr_t)&(gprs->rdx) + 1;
282     } else {
283       reg_addr = (addr_t)&(gprs->rsi);
284     }
285     break;
286   case 7:
287     if (reg_size == REG8) {
288       reg_addr = (addr_t)&(gprs->rbx) + 1;
289     } else {
290       reg_addr = (addr_t)&(gprs->rdi);
291     }
292     break;
293   default:
294     reg_addr = 0;
295     break;
296   }
297
298   return reg_addr;
299 }
300
301
302
303 static inline operand_type_t decode_operands16(struct v3_gprs * gprs, // input/output
304                                                char * modrm_instr,       // input
305                                                int * offset,             // output
306                                                addr_t * first_operand,   // output
307                                                addr_t * second_operand,  // output
308                                                reg_size_t reg_size) {    // input
309   
310   struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
311   addr_t base_addr = 0;
312   modrm_mode_t mod_mode = 0;
313   operand_type_t addr_type = INVALID_OPERAND;
314   char * instr_cursor = modrm_instr;
315
316   //  PrintDebug("ModRM mod=%d\n", modrm->mod);
317
318   instr_cursor += 1;
319
320   if (modrm->mod == 3) {
321     mod_mode = REG;
322     addr_type = REG_OPERAND;
323     //PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
324
325     *first_operand = decode_register(gprs, modrm->rm, reg_size);
326
327   } else {
328
329     addr_type = MEM_OPERAND;
330
331     if (modrm->mod == 0) {
332       mod_mode = DISP0;
333     } else if (modrm->mod == 1) {
334       mod_mode = DISP8;
335     } else if (modrm->mod == 2) {
336       mod_mode = DISP16;
337     }
338
339     switch (modrm->rm) {
340     case 0:
341       base_addr = gprs->rbx + gprs->rsi;
342       break;
343     case 1:
344       base_addr = gprs->rbx + gprs->rdi;
345       break;
346     case 2:
347       base_addr = gprs->rbp + gprs->rsi;
348       break;
349     case 3:
350       base_addr = gprs->rbp + gprs->rdi;
351       break;
352     case 4:
353       base_addr = gprs->rsi;
354       break;
355     case 5:
356       base_addr = gprs->rdi;
357       break;
358     case 6:
359       if (modrm->mod == 0) {
360         base_addr = 0;
361         mod_mode = DISP16;
362       } else {
363         base_addr = gprs->rbp;
364       }
365       break;
366     case 7:
367       base_addr = gprs->rbx;
368       break;
369     }
370
371
372
373     if (mod_mode == DISP8) {
374       base_addr += (uchar_t)*(instr_cursor);
375       instr_cursor += 1;
376     } else if (mod_mode == DISP16) {
377       base_addr += (ushort_t)*(instr_cursor);
378       instr_cursor += 2;
379     }
380     
381     *first_operand = base_addr;
382   }
383
384   *offset +=  (instr_cursor - modrm_instr);
385   *second_operand = decode_register(gprs, modrm->reg, reg_size);
386
387   return addr_type;
388 }
389
390
391
392 static inline operand_type_t decode_operands32(struct v3_gprs * gprs, // input/output
393                                                char * modrm_instr,       // input
394                                                int * offset,             // output
395                                                addr_t * first_operand,   // output
396                                                addr_t * second_operand,  // output
397                                                reg_size_t reg_size) {    // input
398   
399   char * instr_cursor = modrm_instr;
400   struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
401   addr_t base_addr = 0;
402   modrm_mode_t mod_mode = 0;
403   uint_t has_sib_byte = 0;
404   operand_type_t addr_type = INVALID_OPERAND;
405
406
407
408   instr_cursor += 1;
409
410   if (modrm->mod == 3) {
411     mod_mode = REG;
412     addr_type = REG_OPERAND;
413     
414     //    PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
415
416     *first_operand = decode_register(gprs, modrm->rm, reg_size);
417
418   } else {
419
420     addr_type = MEM_OPERAND;
421
422     if (modrm->mod == 0) {
423       mod_mode = DISP0;
424     } else if (modrm->mod == 1) {
425       mod_mode = DISP8;
426     } else if (modrm->mod == 2) {
427       mod_mode = DISP32;
428     }
429     
430     switch (modrm->rm) {
431     case 0:
432       base_addr = gprs->rax;
433       break;
434     case 1:
435       base_addr = gprs->rcx;
436       break;
437     case 2:
438       base_addr = gprs->rdx;
439       break;
440     case 3:
441       base_addr = gprs->rbx;
442       break;
443     case 4:
444       has_sib_byte = 1;
445       break;
446     case 5:
447       if (modrm->mod == 0) {
448         base_addr = 0;
449         mod_mode = DISP32;
450       } else {
451         base_addr = gprs->rbp;
452       }
453       break;
454     case 6:
455       base_addr = gprs->rsi;
456       break;
457     case 7:
458       base_addr = gprs->rdi;
459       break;
460     }
461
462     if (has_sib_byte) {
463       instr_cursor += 1;
464       struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
465       int scale = 1;
466
467       instr_cursor += 1;
468
469
470       if (sib->scale == 1) {
471         scale = 2;
472       } else if (sib->scale == 2) {
473         scale = 4;
474       } else if (sib->scale == 3) {
475         scale = 8;
476       }
477
478
479       switch (sib->index) {
480       case 0:
481         base_addr = gprs->rax;
482         break;
483       case 1:
484         base_addr = gprs->rcx;
485         break;
486       case 2:
487         base_addr = gprs->rdx;
488         break;
489       case 3:
490         base_addr = gprs->rbx;
491         break;
492       case 4:
493         base_addr = 0;
494         break;
495       case 5:
496         base_addr = gprs->rbp;
497         break;
498       case 6:
499         base_addr = gprs->rsi;
500         break;
501       case 7:
502         base_addr = gprs->rdi;
503         break;
504       }
505
506       base_addr *= scale;
507
508
509       switch (sib->base) {
510       case 0:
511         base_addr += gprs->rax;
512         break;
513       case 1:
514         base_addr += gprs->rcx;
515         break;
516       case 2:
517         base_addr += gprs->rdx;
518         break;
519       case 3:
520         base_addr += gprs->rbx;
521         break;
522       case 4:
523         base_addr += gprs->rsp;
524         break;
525       case 5:
526         if (modrm->mod != 0) {
527           base_addr += gprs->rbp;
528         }
529         break;
530       case 6:
531         base_addr += gprs->rsi;
532         break;
533       case 7:
534         base_addr += gprs->rdi;
535         break;
536       }
537
538     } 
539
540
541     if (mod_mode == DISP8) {
542       base_addr += (uchar_t)*(instr_cursor);
543       instr_cursor += 1;
544     } else if (mod_mode == DISP32) {
545       base_addr += (uint_t)*(instr_cursor);
546       instr_cursor += 4;
547     }
548     
549
550     *first_operand = base_addr;
551   }
552
553   *offset += (instr_cursor - modrm_instr);
554
555   *second_operand = decode_register(gprs, modrm->reg, reg_size);
556
557   return addr_type;
558 }
559
560
561
562 #endif // !__V3VEE__
563
564
565 #endif