diff options
Diffstat (limited to 'arch/x86/kvm/x86_emulate.c')
-rw-r--r-- | arch/x86/kvm/x86_emulate.c | 297 |
1 files changed, 174 insertions, 123 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index ea051173b0da..d174db7a3370 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #define SrcMem32 (4<<4) /* Memory operand (32-bit). */ | 58 | #define SrcMem32 (4<<4) /* Memory operand (32-bit). */ |
59 | #define SrcImm (5<<4) /* Immediate operand. */ | 59 | #define SrcImm (5<<4) /* Immediate operand. */ |
60 | #define SrcImmByte (6<<4) /* 8-bit sign-extended immediate operand. */ | 60 | #define SrcImmByte (6<<4) /* 8-bit sign-extended immediate operand. */ |
61 | #define SrcOne (7<<4) /* Implied '1' */ | ||
61 | #define SrcMask (7<<4) | 62 | #define SrcMask (7<<4) |
62 | /* Generic ModRM decode. */ | 63 | /* Generic ModRM decode. */ |
63 | #define ModRM (1<<7) | 64 | #define ModRM (1<<7) |
@@ -70,17 +71,23 @@ | |||
70 | #define Group (1<<14) /* Bits 3:5 of modrm byte extend opcode */ | 71 | #define Group (1<<14) /* Bits 3:5 of modrm byte extend opcode */ |
71 | #define GroupDual (1<<15) /* Alternate decoding of mod == 3 */ | 72 | #define GroupDual (1<<15) /* Alternate decoding of mod == 3 */ |
72 | #define GroupMask 0xff /* Group number stored in bits 0:7 */ | 73 | #define GroupMask 0xff /* Group number stored in bits 0:7 */ |
74 | /* Source 2 operand type */ | ||
75 | #define Src2None (0<<29) | ||
76 | #define Src2CL (1<<29) | ||
77 | #define Src2ImmByte (2<<29) | ||
78 | #define Src2One (3<<29) | ||
79 | #define Src2Mask (7<<29) | ||
73 | 80 | ||
74 | enum { | 81 | enum { |
75 | Group1_80, Group1_81, Group1_82, Group1_83, | 82 | Group1_80, Group1_81, Group1_82, Group1_83, |
76 | Group1A, Group3_Byte, Group3, Group4, Group5, Group7, | 83 | Group1A, Group3_Byte, Group3, Group4, Group5, Group7, |
77 | }; | 84 | }; |
78 | 85 | ||
79 | static u16 opcode_table[256] = { | 86 | static u32 opcode_table[256] = { |
80 | /* 0x00 - 0x07 */ | 87 | /* 0x00 - 0x07 */ |
81 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 88 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, |
82 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 89 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
83 | 0, 0, 0, 0, | 90 | ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 0, 0, |
84 | /* 0x08 - 0x0F */ | 91 | /* 0x08 - 0x0F */ |
85 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 92 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, |
86 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 93 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
@@ -195,7 +202,7 @@ static u16 opcode_table[256] = { | |||
195 | ImplicitOps, ImplicitOps, Group | Group4, Group | Group5, | 202 | ImplicitOps, ImplicitOps, Group | Group4, Group | Group5, |
196 | }; | 203 | }; |
197 | 204 | ||
198 | static u16 twobyte_table[256] = { | 205 | static u32 twobyte_table[256] = { |
199 | /* 0x00 - 0x0F */ | 206 | /* 0x00 - 0x0F */ |
200 | 0, Group | GroupDual | Group7, 0, 0, 0, 0, ImplicitOps, 0, | 207 | 0, Group | GroupDual | Group7, 0, 0, 0, 0, ImplicitOps, 0, |
201 | ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0, | 208 | ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0, |
@@ -230,9 +237,14 @@ static u16 twobyte_table[256] = { | |||
230 | /* 0x90 - 0x9F */ | 237 | /* 0x90 - 0x9F */ |
231 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 238 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
232 | /* 0xA0 - 0xA7 */ | 239 | /* 0xA0 - 0xA7 */ |
233 | 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, 0, 0, 0, 0, | 240 | 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, |
241 | DstMem | SrcReg | Src2ImmByte | ModRM, | ||
242 | DstMem | SrcReg | Src2CL | ModRM, 0, 0, | ||
234 | /* 0xA8 - 0xAF */ | 243 | /* 0xA8 - 0xAF */ |
235 | 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, 0, 0, ModRM, 0, | 244 | 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, |
245 | DstMem | SrcReg | Src2ImmByte | ModRM, | ||
246 | DstMem | SrcReg | Src2CL | ModRM, | ||
247 | ModRM, 0, | ||
236 | /* 0xB0 - 0xB7 */ | 248 | /* 0xB0 - 0xB7 */ |
237 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 0, | 249 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 0, |
238 | DstMem | SrcReg | ModRM | BitOp, | 250 | DstMem | SrcReg | ModRM | BitOp, |
@@ -253,7 +265,7 @@ static u16 twobyte_table[256] = { | |||
253 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | 265 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
254 | }; | 266 | }; |
255 | 267 | ||
256 | static u16 group_table[] = { | 268 | static u32 group_table[] = { |
257 | [Group1_80*8] = | 269 | [Group1_80*8] = |
258 | ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, | 270 | ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, |
259 | ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, | 271 | ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, |
@@ -297,9 +309,9 @@ static u16 group_table[] = { | |||
297 | SrcMem16 | ModRM | Mov, SrcMem | ModRM | ByteOp, | 309 | SrcMem16 | ModRM | Mov, SrcMem | ModRM | ByteOp, |
298 | }; | 310 | }; |
299 | 311 | ||
300 | static u16 group2_table[] = { | 312 | static u32 group2_table[] = { |
301 | [Group7*8] = | 313 | [Group7*8] = |
302 | SrcNone | ModRM, 0, 0, 0, | 314 | SrcNone | ModRM, 0, 0, SrcNone | ModRM, |
303 | SrcNone | ModRM | DstMem | Mov, 0, | 315 | SrcNone | ModRM | DstMem | Mov, 0, |
304 | SrcMem16 | ModRM | Mov, 0, | 316 | SrcMem16 | ModRM | Mov, 0, |
305 | }; | 317 | }; |
@@ -359,49 +371,48 @@ static u16 group2_table[] = { | |||
359 | "andl %"_msk",%"_LO32 _tmp"; " \ | 371 | "andl %"_msk",%"_LO32 _tmp"; " \ |
360 | "orl %"_LO32 _tmp",%"_sav"; " | 372 | "orl %"_LO32 _tmp",%"_sav"; " |
361 | 373 | ||
374 | #ifdef CONFIG_X86_64 | ||
375 | #define ON64(x) x | ||
376 | #else | ||
377 | #define ON64(x) | ||
378 | #endif | ||
379 | |||
380 | #define ____emulate_2op(_op, _src, _dst, _eflags, _x, _y, _suffix) \ | ||
381 | do { \ | ||
382 | __asm__ __volatile__ ( \ | ||
383 | _PRE_EFLAGS("0", "4", "2") \ | ||
384 | _op _suffix " %"_x"3,%1; " \ | ||
385 | _POST_EFLAGS("0", "4", "2") \ | ||
386 | : "=m" (_eflags), "=m" ((_dst).val), \ | ||
387 | "=&r" (_tmp) \ | ||
388 | : _y ((_src).val), "i" (EFLAGS_MASK)); \ | ||
389 | } while (0) | ||
390 | |||
391 | |||
362 | /* Raw emulation: instruction has two explicit operands. */ | 392 | /* Raw emulation: instruction has two explicit operands. */ |
363 | #define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy) \ | 393 | #define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy) \ |
364 | do { \ | 394 | do { \ |
365 | unsigned long _tmp; \ | 395 | unsigned long _tmp; \ |
366 | \ | 396 | \ |
367 | switch ((_dst).bytes) { \ | 397 | switch ((_dst).bytes) { \ |
368 | case 2: \ | 398 | case 2: \ |
369 | __asm__ __volatile__ ( \ | 399 | ____emulate_2op(_op,_src,_dst,_eflags,_wx,_wy,"w"); \ |
370 | _PRE_EFLAGS("0", "4", "2") \ | 400 | break; \ |
371 | _op"w %"_wx"3,%1; " \ | 401 | case 4: \ |
372 | _POST_EFLAGS("0", "4", "2") \ | 402 | ____emulate_2op(_op,_src,_dst,_eflags,_lx,_ly,"l"); \ |
373 | : "=m" (_eflags), "=m" ((_dst).val), \ | 403 | break; \ |
374 | "=&r" (_tmp) \ | 404 | case 8: \ |
375 | : _wy ((_src).val), "i" (EFLAGS_MASK)); \ | 405 | ON64(____emulate_2op(_op,_src,_dst,_eflags,_qx,_qy,"q")); \ |
376 | break; \ | 406 | break; \ |
377 | case 4: \ | 407 | } \ |
378 | __asm__ __volatile__ ( \ | ||
379 | _PRE_EFLAGS("0", "4", "2") \ | ||
380 | _op"l %"_lx"3,%1; " \ | ||
381 | _POST_EFLAGS("0", "4", "2") \ | ||
382 | : "=m" (_eflags), "=m" ((_dst).val), \ | ||
383 | "=&r" (_tmp) \ | ||
384 | : _ly ((_src).val), "i" (EFLAGS_MASK)); \ | ||
385 | break; \ | ||
386 | case 8: \ | ||
387 | __emulate_2op_8byte(_op, _src, _dst, \ | ||
388 | _eflags, _qx, _qy); \ | ||
389 | break; \ | ||
390 | } \ | ||
391 | } while (0) | 408 | } while (0) |
392 | 409 | ||
393 | #define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy) \ | 410 | #define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy) \ |
394 | do { \ | 411 | do { \ |
395 | unsigned long __tmp; \ | 412 | unsigned long _tmp; \ |
396 | switch ((_dst).bytes) { \ | 413 | switch ((_dst).bytes) { \ |
397 | case 1: \ | 414 | case 1: \ |
398 | __asm__ __volatile__ ( \ | 415 | ____emulate_2op(_op,_src,_dst,_eflags,_bx,_by,"b"); \ |
399 | _PRE_EFLAGS("0", "4", "2") \ | ||
400 | _op"b %"_bx"3,%1; " \ | ||
401 | _POST_EFLAGS("0", "4", "2") \ | ||
402 | : "=m" (_eflags), "=m" ((_dst).val), \ | ||
403 | "=&r" (__tmp) \ | ||
404 | : _by ((_src).val), "i" (EFLAGS_MASK)); \ | ||
405 | break; \ | 416 | break; \ |
406 | default: \ | 417 | default: \ |
407 | __emulate_2op_nobyte(_op, _src, _dst, _eflags, \ | 418 | __emulate_2op_nobyte(_op, _src, _dst, _eflags, \ |
@@ -425,71 +436,68 @@ static u16 group2_table[] = { | |||
425 | __emulate_2op_nobyte(_op, _src, _dst, _eflags, \ | 436 | __emulate_2op_nobyte(_op, _src, _dst, _eflags, \ |
426 | "w", "r", _LO32, "r", "", "r") | 437 | "w", "r", _LO32, "r", "", "r") |
427 | 438 | ||
428 | /* Instruction has only one explicit operand (no source operand). */ | 439 | /* Instruction has three operands and one operand is stored in ECX register */ |
429 | #define emulate_1op(_op, _dst, _eflags) \ | 440 | #define __emulate_2op_cl(_op, _cl, _src, _dst, _eflags, _suffix, _type) \ |
430 | do { \ | 441 | do { \ |
431 | unsigned long _tmp; \ | 442 | unsigned long _tmp; \ |
432 | \ | 443 | _type _clv = (_cl).val; \ |
433 | switch ((_dst).bytes) { \ | 444 | _type _srcv = (_src).val; \ |
434 | case 1: \ | 445 | _type _dstv = (_dst).val; \ |
435 | __asm__ __volatile__ ( \ | 446 | \ |
436 | _PRE_EFLAGS("0", "3", "2") \ | 447 | __asm__ __volatile__ ( \ |
437 | _op"b %1; " \ | 448 | _PRE_EFLAGS("0", "5", "2") \ |
438 | _POST_EFLAGS("0", "3", "2") \ | 449 | _op _suffix " %4,%1 \n" \ |
439 | : "=m" (_eflags), "=m" ((_dst).val), \ | 450 | _POST_EFLAGS("0", "5", "2") \ |
440 | "=&r" (_tmp) \ | 451 | : "=m" (_eflags), "+r" (_dstv), "=&r" (_tmp) \ |
441 | : "i" (EFLAGS_MASK)); \ | 452 | : "c" (_clv) , "r" (_srcv), "i" (EFLAGS_MASK) \ |
442 | break; \ | 453 | ); \ |
443 | case 2: \ | 454 | \ |
444 | __asm__ __volatile__ ( \ | 455 | (_cl).val = (unsigned long) _clv; \ |
445 | _PRE_EFLAGS("0", "3", "2") \ | 456 | (_src).val = (unsigned long) _srcv; \ |
446 | _op"w %1; " \ | 457 | (_dst).val = (unsigned long) _dstv; \ |
447 | _POST_EFLAGS("0", "3", "2") \ | ||
448 | : "=m" (_eflags), "=m" ((_dst).val), \ | ||
449 | "=&r" (_tmp) \ | ||
450 | : "i" (EFLAGS_MASK)); \ | ||
451 | break; \ | ||
452 | case 4: \ | ||
453 | __asm__ __volatile__ ( \ | ||
454 | _PRE_EFLAGS("0", "3", "2") \ | ||
455 | _op"l %1; " \ | ||
456 | _POST_EFLAGS("0", "3", "2") \ | ||
457 | : "=m" (_eflags), "=m" ((_dst).val), \ | ||
458 | "=&r" (_tmp) \ | ||
459 | : "i" (EFLAGS_MASK)); \ | ||
460 | break; \ | ||
461 | case 8: \ | ||
462 | __emulate_1op_8byte(_op, _dst, _eflags); \ | ||
463 | break; \ | ||
464 | } \ | ||
465 | } while (0) | 458 | } while (0) |
466 | 459 | ||
467 | /* Emulate an instruction with quadword operands (x86/64 only). */ | 460 | #define emulate_2op_cl(_op, _cl, _src, _dst, _eflags) \ |
468 | #if defined(CONFIG_X86_64) | 461 | do { \ |
469 | #define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy) \ | 462 | switch ((_dst).bytes) { \ |
470 | do { \ | 463 | case 2: \ |
471 | __asm__ __volatile__ ( \ | 464 | __emulate_2op_cl(_op, _cl, _src, _dst, _eflags, \ |
472 | _PRE_EFLAGS("0", "4", "2") \ | 465 | "w", unsigned short); \ |
473 | _op"q %"_qx"3,%1; " \ | 466 | break; \ |
474 | _POST_EFLAGS("0", "4", "2") \ | 467 | case 4: \ |
475 | : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \ | 468 | __emulate_2op_cl(_op, _cl, _src, _dst, _eflags, \ |
476 | : _qy ((_src).val), "i" (EFLAGS_MASK)); \ | 469 | "l", unsigned int); \ |
470 | break; \ | ||
471 | case 8: \ | ||
472 | ON64(__emulate_2op_cl(_op, _cl, _src, _dst, _eflags, \ | ||
473 | "q", unsigned long)); \ | ||
474 | break; \ | ||
475 | } \ | ||
477 | } while (0) | 476 | } while (0) |
478 | 477 | ||
479 | #define __emulate_1op_8byte(_op, _dst, _eflags) \ | 478 | #define __emulate_1op(_op, _dst, _eflags, _suffix) \ |
480 | do { \ | 479 | do { \ |
481 | __asm__ __volatile__ ( \ | 480 | unsigned long _tmp; \ |
482 | _PRE_EFLAGS("0", "3", "2") \ | 481 | \ |
483 | _op"q %1; " \ | 482 | __asm__ __volatile__ ( \ |
484 | _POST_EFLAGS("0", "3", "2") \ | 483 | _PRE_EFLAGS("0", "3", "2") \ |
485 | : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \ | 484 | _op _suffix " %1; " \ |
486 | : "i" (EFLAGS_MASK)); \ | 485 | _POST_EFLAGS("0", "3", "2") \ |
486 | : "=m" (_eflags), "+m" ((_dst).val), \ | ||
487 | "=&r" (_tmp) \ | ||
488 | : "i" (EFLAGS_MASK)); \ | ||
487 | } while (0) | 489 | } while (0) |
488 | 490 | ||
489 | #elif defined(__i386__) | 491 | /* Instruction has only one explicit operand (no source operand). */ |
490 | #define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy) | 492 | #define emulate_1op(_op, _dst, _eflags) \ |
491 | #define __emulate_1op_8byte(_op, _dst, _eflags) | 493 | do { \ |
492 | #endif /* __i386__ */ | 494 | switch ((_dst).bytes) { \ |
495 | case 1: __emulate_1op(_op, _dst, _eflags, "b"); break; \ | ||
496 | case 2: __emulate_1op(_op, _dst, _eflags, "w"); break; \ | ||
497 | case 4: __emulate_1op(_op, _dst, _eflags, "l"); break; \ | ||
498 | case 8: ON64(__emulate_1op(_op, _dst, _eflags, "q")); break; \ | ||
499 | } \ | ||
500 | } while (0) | ||
493 | 501 | ||
494 | /* Fetch next part of the instruction being emulated. */ | 502 | /* Fetch next part of the instruction being emulated. */ |
495 | #define insn_fetch(_type, _size, _eip) \ | 503 | #define insn_fetch(_type, _size, _eip) \ |
@@ -1041,6 +1049,33 @@ done_prefixes: | |||
1041 | c->src.bytes = 1; | 1049 | c->src.bytes = 1; |
1042 | c->src.val = insn_fetch(s8, 1, c->eip); | 1050 | c->src.val = insn_fetch(s8, 1, c->eip); |
1043 | break; | 1051 | break; |
1052 | case SrcOne: | ||
1053 | c->src.bytes = 1; | ||
1054 | c->src.val = 1; | ||
1055 | break; | ||
1056 | } | ||
1057 | |||
1058 | /* | ||
1059 | * Decode and fetch the second source operand: register, memory | ||
1060 | * or immediate. | ||
1061 | */ | ||
1062 | switch (c->d & Src2Mask) { | ||
1063 | case Src2None: | ||
1064 | break; | ||
1065 | case Src2CL: | ||
1066 | c->src2.bytes = 1; | ||
1067 | c->src2.val = c->regs[VCPU_REGS_RCX] & 0x8; | ||
1068 | break; | ||
1069 | case Src2ImmByte: | ||
1070 | c->src2.type = OP_IMM; | ||
1071 | c->src2.ptr = (unsigned long *)c->eip; | ||
1072 | c->src2.bytes = 1; | ||
1073 | c->src2.val = insn_fetch(u8, 1, c->eip); | ||
1074 | break; | ||
1075 | case Src2One: | ||
1076 | c->src2.bytes = 1; | ||
1077 | c->src2.val = 1; | ||
1078 | break; | ||
1044 | } | 1079 | } |
1045 | 1080 | ||
1046 | /* Decode and fetch the destination operand: register or memory. */ | 1081 | /* Decode and fetch the destination operand: register or memory. */ |
@@ -1100,20 +1135,33 @@ static inline void emulate_push(struct x86_emulate_ctxt *ctxt) | |||
1100 | c->regs[VCPU_REGS_RSP]); | 1135 | c->regs[VCPU_REGS_RSP]); |
1101 | } | 1136 | } |
1102 | 1137 | ||
1103 | static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt, | 1138 | static int emulate_pop(struct x86_emulate_ctxt *ctxt, |
1104 | struct x86_emulate_ops *ops) | 1139 | struct x86_emulate_ops *ops) |
1105 | { | 1140 | { |
1106 | struct decode_cache *c = &ctxt->decode; | 1141 | struct decode_cache *c = &ctxt->decode; |
1107 | int rc; | 1142 | int rc; |
1108 | 1143 | ||
1109 | rc = ops->read_std(register_address(c, ss_base(ctxt), | 1144 | rc = ops->read_emulated(register_address(c, ss_base(ctxt), |
1110 | c->regs[VCPU_REGS_RSP]), | 1145 | c->regs[VCPU_REGS_RSP]), |
1111 | &c->dst.val, c->dst.bytes, ctxt->vcpu); | 1146 | &c->src.val, c->src.bytes, ctxt->vcpu); |
1112 | if (rc != 0) | 1147 | if (rc != 0) |
1113 | return rc; | 1148 | return rc; |
1114 | 1149 | ||
1115 | register_address_increment(c, &c->regs[VCPU_REGS_RSP], c->dst.bytes); | 1150 | register_address_increment(c, &c->regs[VCPU_REGS_RSP], c->src.bytes); |
1151 | return rc; | ||
1152 | } | ||
1153 | |||
1154 | static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt, | ||
1155 | struct x86_emulate_ops *ops) | ||
1156 | { | ||
1157 | struct decode_cache *c = &ctxt->decode; | ||
1158 | int rc; | ||
1116 | 1159 | ||
1160 | c->src.bytes = c->dst.bytes; | ||
1161 | rc = emulate_pop(ctxt, ops); | ||
1162 | if (rc != 0) | ||
1163 | return rc; | ||
1164 | c->dst.val = c->src.val; | ||
1117 | return 0; | 1165 | return 0; |
1118 | } | 1166 | } |
1119 | 1167 | ||
@@ -1415,24 +1463,15 @@ special_insn: | |||
1415 | emulate_1op("dec", c->dst, ctxt->eflags); | 1463 | emulate_1op("dec", c->dst, ctxt->eflags); |
1416 | break; | 1464 | break; |
1417 | case 0x50 ... 0x57: /* push reg */ | 1465 | case 0x50 ... 0x57: /* push reg */ |
1418 | c->dst.type = OP_MEM; | 1466 | emulate_push(ctxt); |
1419 | c->dst.bytes = c->op_bytes; | ||
1420 | c->dst.val = c->src.val; | ||
1421 | register_address_increment(c, &c->regs[VCPU_REGS_RSP], | ||
1422 | -c->op_bytes); | ||
1423 | c->dst.ptr = (void *) register_address( | ||
1424 | c, ss_base(ctxt), c->regs[VCPU_REGS_RSP]); | ||
1425 | break; | 1467 | break; |
1426 | case 0x58 ... 0x5f: /* pop reg */ | 1468 | case 0x58 ... 0x5f: /* pop reg */ |
1427 | pop_instruction: | 1469 | pop_instruction: |
1428 | if ((rc = ops->read_std(register_address(c, ss_base(ctxt), | 1470 | c->src.bytes = c->op_bytes; |
1429 | c->regs[VCPU_REGS_RSP]), c->dst.ptr, | 1471 | rc = emulate_pop(ctxt, ops); |
1430 | c->op_bytes, ctxt->vcpu)) != 0) | 1472 | if (rc != 0) |
1431 | goto done; | 1473 | goto done; |
1432 | 1474 | c->dst.val = c->src.val; | |
1433 | register_address_increment(c, &c->regs[VCPU_REGS_RSP], | ||
1434 | c->op_bytes); | ||
1435 | c->dst.type = OP_NONE; /* Disable writeback. */ | ||
1436 | break; | 1475 | break; |
1437 | case 0x63: /* movsxd */ | 1476 | case 0x63: /* movsxd */ |
1438 | if (ctxt->mode != X86EMUL_MODE_PROT64) | 1477 | if (ctxt->mode != X86EMUL_MODE_PROT64) |
@@ -1591,7 +1630,9 @@ special_insn: | |||
1591 | emulate_push(ctxt); | 1630 | emulate_push(ctxt); |
1592 | break; | 1631 | break; |
1593 | case 0x9d: /* popf */ | 1632 | case 0x9d: /* popf */ |
1633 | c->dst.type = OP_REG; | ||
1594 | c->dst.ptr = (unsigned long *) &ctxt->eflags; | 1634 | c->dst.ptr = (unsigned long *) &ctxt->eflags; |
1635 | c->dst.bytes = c->op_bytes; | ||
1595 | goto pop_instruction; | 1636 | goto pop_instruction; |
1596 | case 0xa0 ... 0xa1: /* mov */ | 1637 | case 0xa0 ... 0xa1: /* mov */ |
1597 | c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; | 1638 | c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; |
@@ -1689,7 +1730,9 @@ special_insn: | |||
1689 | emulate_grp2(ctxt); | 1730 | emulate_grp2(ctxt); |
1690 | break; | 1731 | break; |
1691 | case 0xc3: /* ret */ | 1732 | case 0xc3: /* ret */ |
1733 | c->dst.type = OP_REG; | ||
1692 | c->dst.ptr = &c->eip; | 1734 | c->dst.ptr = &c->eip; |
1735 | c->dst.bytes = c->op_bytes; | ||
1693 | goto pop_instruction; | 1736 | goto pop_instruction; |
1694 | case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */ | 1737 | case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */ |
1695 | mov: | 1738 | mov: |
@@ -1778,7 +1821,7 @@ special_insn: | |||
1778 | c->eip = saved_eip; | 1821 | c->eip = saved_eip; |
1779 | goto cannot_emulate; | 1822 | goto cannot_emulate; |
1780 | } | 1823 | } |
1781 | return 0; | 1824 | break; |
1782 | case 0xf4: /* hlt */ | 1825 | case 0xf4: /* hlt */ |
1783 | ctxt->vcpu->arch.halt_request = 1; | 1826 | ctxt->vcpu->arch.halt_request = 1; |
1784 | break; | 1827 | break; |
@@ -1999,12 +2042,20 @@ twobyte_insn: | |||
1999 | c->src.val &= (c->dst.bytes << 3) - 1; | 2042 | c->src.val &= (c->dst.bytes << 3) - 1; |
2000 | emulate_2op_SrcV_nobyte("bt", c->src, c->dst, ctxt->eflags); | 2043 | emulate_2op_SrcV_nobyte("bt", c->src, c->dst, ctxt->eflags); |
2001 | break; | 2044 | break; |
2045 | case 0xa4: /* shld imm8, r, r/m */ | ||
2046 | case 0xa5: /* shld cl, r, r/m */ | ||
2047 | emulate_2op_cl("shld", c->src2, c->src, c->dst, ctxt->eflags); | ||
2048 | break; | ||
2002 | case 0xab: | 2049 | case 0xab: |
2003 | bts: /* bts */ | 2050 | bts: /* bts */ |
2004 | /* only subword offset */ | 2051 | /* only subword offset */ |
2005 | c->src.val &= (c->dst.bytes << 3) - 1; | 2052 | c->src.val &= (c->dst.bytes << 3) - 1; |
2006 | emulate_2op_SrcV_nobyte("bts", c->src, c->dst, ctxt->eflags); | 2053 | emulate_2op_SrcV_nobyte("bts", c->src, c->dst, ctxt->eflags); |
2007 | break; | 2054 | break; |
2055 | case 0xac: /* shrd imm8, r, r/m */ | ||
2056 | case 0xad: /* shrd cl, r, r/m */ | ||
2057 | emulate_2op_cl("shrd", c->src2, c->src, c->dst, ctxt->eflags); | ||
2058 | break; | ||
2008 | case 0xae: /* clflush */ | 2059 | case 0xae: /* clflush */ |
2009 | break; | 2060 | break; |
2010 | case 0xb0 ... 0xb1: /* cmpxchg */ | 2061 | case 0xb0 ... 0xb1: /* cmpxchg */ |