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.


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