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.


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