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.


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