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.


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