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.


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