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.


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