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.


reformatting include files
[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             return 0xffff;
254             break;
255         case PROTECTED:
256         case PROTECTED_PAE:
257             return 0xffffffff;
258         case LONG:
259         case LONG_32_COMPAT:
260         case LONG_16_COMPAT:
261         default:
262             PrintError("Unsupported Address Mode\n");
263             return -1;
264     }
265 }
266
267
268 static inline addr_t get_addr_linear(struct guest_info * info, addr_t addr, struct v3_segment * seg) {
269     switch (info->cpu_mode) {
270         case REAL:
271             // It appears that the segment values are computed and cached in the vmcb structure 
272             // We Need to check this for Intel
273             /*   return addr + (seg->selector << 4);
274                  break;*/
275
276         case PROTECTED:
277         case PROTECTED_PAE:
278         case LONG_32_COMPAT:
279             return addr + seg->base;
280             break;
281
282         case LONG:
283             // In long mode the segment bases are disregarded (forced to 0), unless using 
284             // FS or GS, then the base addresses are added
285             return addr + seg->base;
286
287         case LONG_16_COMPAT:
288         default:
289             PrintError("Unsupported CPU Mode: %d\n", info->cpu_mode);
290             return -1;
291     }
292 }
293
294
295 typedef enum {INVALID_ADDR_TYPE, REG, DISP0, DISP8, DISP16, DISP32} modrm_mode_t;
296 typedef enum {INVALID_REG_SIZE, REG64, REG32, REG16, REG8} reg_size_t;
297
298
299
300
301
302
303 struct v3_gprs;
304
305 static inline addr_t decode_register(struct v3_gprs * gprs, char reg_code, reg_size_t reg_size) {
306     addr_t reg_addr;
307
308     switch (reg_code) {
309         case 0:
310             reg_addr = (addr_t)&(gprs->rax);
311             break;
312         case 1:
313             reg_addr = (addr_t)&(gprs->rcx);
314             break;
315         case 2:
316             reg_addr = (addr_t)&(gprs->rdx);
317             break;
318         case 3:
319             reg_addr = (addr_t)&(gprs->rbx);
320             break;
321         case 4:
322             if (reg_size == REG8) {
323                 reg_addr = (addr_t)&(gprs->rax) + 1;
324             } else {
325                 reg_addr = (addr_t)&(gprs->rsp);
326             }
327             break;
328         case 5:
329             if (reg_size == REG8) {
330                 reg_addr = (addr_t)&(gprs->rcx) + 1;
331             } else {
332                 reg_addr = (addr_t)&(gprs->rbp);
333             }
334             break;
335         case 6:
336             if (reg_size == REG8) {
337                 reg_addr = (addr_t)&(gprs->rdx) + 1;
338             } else {
339                 reg_addr = (addr_t)&(gprs->rsi);
340             }
341             break;
342         case 7:
343             if (reg_size == REG8) {
344                 reg_addr = (addr_t)&(gprs->rbx) + 1;
345             } else {
346                 reg_addr = (addr_t)&(gprs->rdi);
347             }
348             break;
349         default:
350             reg_addr = 0;
351             break;
352     }
353
354     return reg_addr;
355 }
356
357
358
359 static inline v3_operand_type_t decode_operands16(struct v3_gprs * gprs, // input/output
360                                                   char * modrm_instr,       // input
361                                                   int * offset,             // output
362                                                   addr_t * first_operand,   // output
363                                                   addr_t * second_operand,  // output
364                                                   reg_size_t reg_size) {    // input
365   
366     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
367     addr_t base_addr = 0;
368     modrm_mode_t mod_mode = 0;
369     v3_operand_type_t addr_type = INVALID_OPERAND;
370     char * instr_cursor = modrm_instr;
371
372     //  PrintDebug("ModRM mod=%d\n", modrm->mod);
373
374     instr_cursor += 1;
375
376     if (modrm->mod == 3) {
377         mod_mode = REG;
378         addr_type = REG_OPERAND;
379         //PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
380
381         *first_operand = decode_register(gprs, modrm->rm, reg_size);
382
383     } else {
384
385         addr_type = MEM_OPERAND;
386
387         if (modrm->mod == 0) {
388             mod_mode = DISP0;
389         } else if (modrm->mod == 1) {
390             mod_mode = DISP8;
391         } else if (modrm->mod == 2) {
392             mod_mode = DISP16;
393         }
394
395         switch (modrm->rm) {
396             case 0:
397                 base_addr = gprs->rbx + gprs->rsi;
398                 break;
399             case 1:
400                 base_addr = gprs->rbx + gprs->rdi;
401                 break;
402             case 2:
403                 base_addr = gprs->rbp + gprs->rsi;
404                 break;
405             case 3:
406                 base_addr = gprs->rbp + gprs->rdi;
407                 break;
408             case 4:
409                 base_addr = gprs->rsi;
410                 break;
411             case 5:
412                 base_addr = gprs->rdi;
413                 break;
414             case 6:
415                 if (modrm->mod == 0) {
416                     base_addr = 0;
417                     mod_mode = DISP16;
418                 } else {
419                     base_addr = gprs->rbp;
420                 }
421                 break;
422             case 7:
423                 base_addr = gprs->rbx;
424                 break;
425         }
426
427
428
429         if (mod_mode == DISP8) {
430             base_addr += (uchar_t)*(instr_cursor);
431             instr_cursor += 1;
432         } else if (mod_mode == DISP16) {
433             base_addr += (ushort_t)*(instr_cursor);
434             instr_cursor += 2;
435         }
436     
437         *first_operand = base_addr;
438     }
439
440     *offset +=  (instr_cursor - modrm_instr);
441     *second_operand = decode_register(gprs, modrm->reg, reg_size);
442
443     return addr_type;
444 }
445
446
447
448 static inline v3_operand_type_t decode_operands32(struct v3_gprs * gprs, // input/output
449                                                   uchar_t * modrm_instr,       // input
450                                                   int * offset,             // output
451                                                   addr_t * first_operand,   // output
452                                                   addr_t * second_operand,  // output
453                                                   reg_size_t reg_size) {    // input
454   
455     uchar_t * instr_cursor = modrm_instr;
456     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
457     addr_t base_addr = 0;
458     modrm_mode_t mod_mode = 0;
459     uint_t has_sib_byte = 0;
460     v3_operand_type_t addr_type = INVALID_OPERAND;
461
462
463
464     instr_cursor += 1;
465
466     if (modrm->mod == 3) {
467         mod_mode = REG;
468         addr_type = REG_OPERAND;
469     
470         //    PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
471
472         *first_operand = decode_register(gprs, modrm->rm, reg_size);
473
474     } else {
475
476         addr_type = MEM_OPERAND;
477
478         if (modrm->mod == 0) {
479             mod_mode = DISP0;
480         } else if (modrm->mod == 1) {
481             mod_mode = DISP8;
482         } else if (modrm->mod == 2) {
483             mod_mode = DISP32;
484         }
485     
486         switch (modrm->rm) {
487             case 0:
488                 base_addr = gprs->rax;
489                 break;
490             case 1:
491                 base_addr = gprs->rcx;
492                 break;
493             case 2:
494                 base_addr = gprs->rdx;
495                 break;
496             case 3:
497                 base_addr = gprs->rbx;
498                 break;
499             case 4:
500                 has_sib_byte = 1;
501                 break;
502             case 5:
503                 if (modrm->mod == 0) {
504                     base_addr = 0;
505                     mod_mode = DISP32;
506                 } else {
507                     base_addr = gprs->rbp;
508                 }
509                 break;
510             case 6:
511                 base_addr = gprs->rsi;
512                 break;
513             case 7:
514                 base_addr = gprs->rdi;
515                 break;
516         }
517
518         if (has_sib_byte) {
519             instr_cursor += 1;
520             struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
521             int scale = 1;
522
523             instr_cursor += 1;
524
525
526             if (sib->scale == 1) {
527                 scale = 2;
528             } else if (sib->scale == 2) {
529                 scale = 4;
530             } else if (sib->scale == 3) {
531                 scale = 8;
532             }
533
534
535             switch (sib->index) {
536                 case 0:
537                     base_addr = gprs->rax;
538                     break;
539                 case 1:
540                     base_addr = gprs->rcx;
541                     break;
542                 case 2:
543                     base_addr = gprs->rdx;
544                     break;
545                 case 3:
546                     base_addr = gprs->rbx;
547                     break;
548                 case 4:
549                     base_addr = 0;
550                     break;
551                 case 5:
552                     base_addr = gprs->rbp;
553                     break;
554                 case 6:
555                     base_addr = gprs->rsi;
556                     break;
557                 case 7:
558                     base_addr = gprs->rdi;
559                     break;
560             }
561
562             base_addr *= scale;
563
564
565             switch (sib->base) {
566                 case 0:
567                     base_addr += gprs->rax;
568                     break;
569                 case 1:
570                     base_addr += gprs->rcx;
571                     break;
572                 case 2:
573                     base_addr += gprs->rdx;
574                     break;
575                 case 3:
576                     base_addr += gprs->rbx;
577                     break;
578                 case 4:
579                     base_addr += gprs->rsp;
580                     break;
581                 case 5:
582                     if (modrm->mod != 0) {
583                         base_addr += gprs->rbp;
584                     }
585                     break;
586                 case 6:
587                     base_addr += gprs->rsi;
588                     break;
589                 case 7:
590                     base_addr += gprs->rdi;
591                     break;
592             }
593
594         } 
595
596
597         if (mod_mode == DISP8) {
598             base_addr += (uchar_t)*(instr_cursor);
599             instr_cursor += 1;
600         } else if (mod_mode == DISP32) {
601             base_addr += (uint_t)*(instr_cursor);
602             instr_cursor += 4;
603         }
604     
605
606         *first_operand = base_addr;
607     }
608
609     *offset += (instr_cursor - modrm_instr);
610
611     *second_operand = decode_register(gprs, modrm->reg, reg_size);
612
613     return addr_type;
614 }
615
616
617
618 #endif // !__V3VEE__
619
620
621 #endif