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.


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