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.


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