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