1 #ifndef __VMM_EMULATE_H
2 #define __VMM_EMULATE_H
6 #include <palacios/vm_guest.h>
7 #include <palacios/vmm.h>
10 * This is where we do the hideous X86 instruction parsing among other things
11 * We can parse out the instruction prefixes, as well as decode the operands
18 typedef enum {INVALID_OPERAND, REG_OPERAND, MEM_OPERAND} operand_type_t;
26 struct x86_prefix_list {
27 uint_t lock : 1; // 0xF0
28 uint_t repne : 1; // 0xF2
29 uint_t repnz : 1; // 0xF2
30 uint_t rep : 1; // 0xF3
31 uint_t repe : 1; // 0xF3
32 uint_t repz : 1; // 0xF3
33 uint_t cs_override : 1; // 0x2E
34 uint_t ss_override : 1; // 0x36
35 uint_t ds_override : 1; // 0x3E
36 uint_t es_override : 1; // 0x26
37 uint_t fs_override : 1; // 0x64
38 uint_t gs_override : 1; // 0x65
39 uint_t br_not_taken : 1; // 0x2E
40 uint_t br_takend : 1; // 0x3E
41 uint_t op_size : 1; // 0x66
42 uint_t addr_size : 1; // 0x67
47 uint_t instr_length; // output
48 addr_t opcode; // output
49 uint_t opcode_length; // output
50 struct x86_prefix_list prefixes; // output
51 struct x86_operand src_operand; // output
52 struct x86_operand dst_operand; // output
53 struct x86_operand extra_operand;
57 /************************/
58 /* EXTERNAL DECODER API */
59 /************************/
61 This is an External API definition that must be implemented by a decoder
65 * Decodes an instruction
66 * All addresses in arguments are in the host address space
67 * instr_ptr is the host address of the instruction
68 * IMPORTANT: make sure the instr_ptr is in contiguous host memory
69 * ie. Copy it to a buffer before the call
71 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr);
74 * Encodes an instruction
75 * All addresses in arguments are in the host address space
76 * The instruction is encoded from the struct, and copied into a 15 byte host buffer
77 * referenced by instr_buf
78 * any unused bytes at the end of instr_buf will be filled with nops
79 * IMPORTANT: instr_buf must be allocated and 15 bytes long
81 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf);
92 * JRL: Some of this was taken from the Xen sources...
95 #define PACKED __attribute__((packed))
97 #define MODRM_MOD(x) ((x >> 6) & 0x3)
98 #define MODRM_REG(x) ((x >> 3) & 0x7)
99 #define MODRM_RM(x) (x & 0x7)
102 uint_t rm : 3 PACKED;
103 uint_t reg : 3 PACKED;
104 uint_t mod : 2 PACKED;
108 #define SIB_BASE(x) ((x >> 6) & 0x3)
109 #define SIB_INDEX(x) ((x >> 3) & 0x7)
110 #define SIB_SCALE(x) (x & 0x7)
113 uint_t base : 3 PACKED;
114 uint_t index : 3 PACKED;
115 uint_t scale : 2 PACKED;
120 #define MAKE_INSTR(nm, ...) static const uchar_t OPCODE_##nm[] = { __VA_ARGS__ }
123 * Here's how it works:
124 * First byte: Length.
125 * Following bytes: Opcode bytes.
126 * Special case: Last byte, if zero, doesn't need to match.
128 MAKE_INSTR(INVD, 2, 0x0f, 0x08);
129 MAKE_INSTR(CPUID, 2, 0x0f, 0xa2);
130 MAKE_INSTR(RDMSR, 2, 0x0f, 0x32);
131 MAKE_INSTR(WRMSR, 2, 0x0f, 0x30);
132 MAKE_INSTR(RDTSC, 2, 0x0f, 0x31);
133 MAKE_INSTR(RDTSCP, 3, 0x0f, 0x01, 0xf9);
134 MAKE_INSTR(CLI, 1, 0xfa);
135 MAKE_INSTR(STI, 1, 0xfb);
136 MAKE_INSTR(RDPMC, 2, 0x0f, 0x33);
137 MAKE_INSTR(CLGI, 3, 0x0f, 0x01, 0xdd);
138 MAKE_INSTR(STGI, 3, 0x0f, 0x01, 0xdc);
139 MAKE_INSTR(VMRUN, 3, 0x0f, 0x01, 0xd8);
140 MAKE_INSTR(VMLOAD, 3, 0x0f, 0x01, 0xda);
141 MAKE_INSTR(VMSAVE, 3, 0x0f, 0x01, 0xdb);
142 MAKE_INSTR(VMCALL, 3, 0x0f, 0x01, 0xd9);
143 MAKE_INSTR(PAUSE, 2, 0xf3, 0x90);
144 MAKE_INSTR(SKINIT, 3, 0x0f, 0x01, 0xde);
145 MAKE_INSTR(MOV2CR, 3, 0x0f, 0x22, 0x00);
146 MAKE_INSTR(MOVCR2, 3, 0x0f, 0x20, 0x00);
147 MAKE_INSTR(MOV2DR, 3, 0x0f, 0x23, 0x00);
148 MAKE_INSTR(MOVDR2, 3, 0x0f, 0x21, 0x00);
149 MAKE_INSTR(PUSHF, 1, 0x9c);
150 MAKE_INSTR(POPF, 1, 0x9d);
151 MAKE_INSTR(RSM, 2, 0x0f, 0xaa);
152 MAKE_INSTR(INVLPG, 3, 0x0f, 0x01, 0x00);
153 MAKE_INSTR(INVLPGA,3, 0x0f, 0x01, 0xdf);
154 MAKE_INSTR(HLT, 1, 0xf4);
155 MAKE_INSTR(CLTS, 2, 0x0f, 0x06);
156 MAKE_INSTR(LMSW, 3, 0x0f, 0x01, 0x00);
157 MAKE_INSTR(SMSW, 3, 0x0f, 0x01, 0x00);
160 #define PREFIX_LOCK 0xF0
161 #define PREFIX_REPNE 0xF2
162 #define PREFIX_REPNZ 0xF2
163 #define PREFIX_REP 0xF3
164 #define PREFIX_REPE 0xF3
165 #define PREFIX_REPZ 0xF3
166 #define PREFIX_CS_OVERRIDE 0x2E
167 #define PREFIX_SS_OVERRIDE 0x36
168 #define PREFIX_DS_OVERRIDE 0x3E
169 #define PREFIX_ES_OVERRIDE 0x26
170 #define PREFIX_FS_OVERRIDE 0x64
171 #define PREFIX_GS_OVERRIDE 0x65
172 #define PREFIX_BR_NOT_TAKEN 0x2E
173 #define PREFIX_BR_TAKEN 0x3E
174 #define PREFIX_OP_SIZE 0x66
175 #define PREFIX_ADDR_SIZE 0x67
177 static inline int is_prefix_byte(char byte) {
180 case 0xF2: // REPNE/REPNZ
181 case 0xF3: // REP or REPE/REPZ
182 case 0x2E: // CS override or Branch hint not taken (with Jcc instrs)
183 case 0x36: // SS override
184 case 0x3E: // DS override or Branch hint taken (with Jcc instrs)
185 case 0x26: // ES override
186 case 0x64: // FS override
187 case 0x65: // GS override
188 //case 0x2E: // branch not taken hint
189 // case 0x3E: // branch taken hint
190 case 0x66: // operand size override
191 case 0x67: // address size override
201 static inline v3_reg_t get_gpr_mask(struct guest_info * info) {
202 switch (info->cpu_mode) {
215 static inline addr_t get_addr_linear(struct guest_info * info, addr_t addr, struct v3_segment * seg) {
216 switch (info->cpu_mode) {
218 // It appears that the segment values are computed and cached in the vmcb structure
219 // We Need to check this for Intel
220 /* return addr + (seg->selector << 4);
224 return addr + seg->base;
233 typedef enum {INVALID_ADDR_TYPE, REG, DISP0, DISP8, DISP16, DISP32} modrm_mode_t;
234 typedef enum {INVALID_REG_SIZE, REG64, REG32, REG16, REG8} reg_size_t;
243 static inline addr_t decode_register(struct v3_gprs * gprs, char reg_code, reg_size_t reg_size) {
248 reg_addr = (addr_t)&(gprs->rax);
251 reg_addr = (addr_t)&(gprs->rcx);
254 reg_addr = (addr_t)&(gprs->rdx);
257 reg_addr = (addr_t)&(gprs->rbx);
260 if (reg_size == REG8) {
261 reg_addr = (addr_t)&(gprs->rax) + 1;
263 reg_addr = (addr_t)&(gprs->rsp);
267 if (reg_size == REG8) {
268 reg_addr = (addr_t)&(gprs->rcx) + 1;
270 reg_addr = (addr_t)&(gprs->rbp);
274 if (reg_size == REG8) {
275 reg_addr = (addr_t)&(gprs->rdx) + 1;
277 reg_addr = (addr_t)&(gprs->rsi);
281 if (reg_size == REG8) {
282 reg_addr = (addr_t)&(gprs->rbx) + 1;
284 reg_addr = (addr_t)&(gprs->rdi);
297 static inline operand_type_t decode_operands16(struct v3_gprs * gprs, // input/output
298 char * modrm_instr, // input
299 int * offset, // output
300 addr_t * first_operand, // output
301 addr_t * second_operand, // output
302 reg_size_t reg_size) { // input
304 struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
305 addr_t base_addr = 0;
306 modrm_mode_t mod_mode = 0;
307 operand_type_t addr_type = INVALID_OPERAND;
308 char * instr_cursor = modrm_instr;
310 // PrintDebug("ModRM mod=%d\n", modrm->mod);
314 if (modrm->mod == 3) {
316 addr_type = REG_OPERAND;
317 //PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
319 *first_operand = decode_register(gprs, modrm->rm, reg_size);
323 addr_type = MEM_OPERAND;
325 if (modrm->mod == 0) {
327 } else if (modrm->mod == 1) {
329 } else if (modrm->mod == 2) {
335 base_addr = gprs->rbx + gprs->rsi;
338 base_addr = gprs->rbx + gprs->rdi;
341 base_addr = gprs->rbp + gprs->rsi;
344 base_addr = gprs->rbp + gprs->rdi;
347 base_addr = gprs->rsi;
350 base_addr = gprs->rdi;
353 if (modrm->mod == 0) {
357 base_addr = gprs->rbp;
361 base_addr = gprs->rbx;
367 if (mod_mode == DISP8) {
368 base_addr += (uchar_t)*(instr_cursor);
370 } else if (mod_mode == DISP16) {
371 base_addr += (ushort_t)*(instr_cursor);
375 *first_operand = base_addr;
378 *offset += (instr_cursor - modrm_instr);
379 *second_operand = decode_register(gprs, modrm->reg, reg_size);
386 static inline operand_type_t decode_operands32(struct v3_gprs * gprs, // input/output
387 char * modrm_instr, // input
388 int * offset, // output
389 addr_t * first_operand, // output
390 addr_t * second_operand, // output
391 reg_size_t reg_size) { // input
393 char * instr_cursor = modrm_instr;
394 struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
395 addr_t base_addr = 0;
396 modrm_mode_t mod_mode = 0;
397 uint_t has_sib_byte = 0;
398 operand_type_t addr_type = INVALID_OPERAND;
404 if (modrm->mod == 3) {
406 addr_type = REG_OPERAND;
408 // PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
410 *first_operand = decode_register(gprs, modrm->rm, reg_size);
414 addr_type = MEM_OPERAND;
416 if (modrm->mod == 0) {
418 } else if (modrm->mod == 1) {
420 } else if (modrm->mod == 2) {
426 base_addr = gprs->rax;
429 base_addr = gprs->rcx;
432 base_addr = gprs->rdx;
435 base_addr = gprs->rbx;
441 if (modrm->mod == 0) {
445 base_addr = gprs->rbp;
449 base_addr = gprs->rsi;
452 base_addr = gprs->rdi;
458 struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
464 if (sib->scale == 1) {
466 } else if (sib->scale == 2) {
468 } else if (sib->scale == 3) {
473 switch (sib->index) {
475 base_addr = gprs->rax;
478 base_addr = gprs->rcx;
481 base_addr = gprs->rdx;
484 base_addr = gprs->rbx;
490 base_addr = gprs->rbp;
493 base_addr = gprs->rsi;
496 base_addr = gprs->rdi;
505 base_addr += gprs->rax;
508 base_addr += gprs->rcx;
511 base_addr += gprs->rdx;
514 base_addr += gprs->rbx;
517 base_addr += gprs->rsp;
520 if (modrm->mod != 0) {
521 base_addr += gprs->rbp;
525 base_addr += gprs->rsi;
528 base_addr += gprs->rdi;
535 if (mod_mode == DISP8) {
536 base_addr += (uchar_t)*(instr_cursor);
538 } else if (mod_mode == DISP32) {
539 base_addr += (uint_t)*(instr_cursor);
544 *first_operand = base_addr;
547 *offset += (instr_cursor - modrm_instr);
549 *second_operand = decode_register(gprs, modrm->reg, reg_size);