aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kvm/x86_emulate.c66
1 files changed, 23 insertions, 43 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c
index 8f60ace13874..5f87d3e59195 100644
--- a/arch/x86/kvm/x86_emulate.c
+++ b/arch/x86/kvm/x86_emulate.c
@@ -359,6 +359,12 @@ static u16 group2_table[] = {
359 "andl %"_msk",%"_LO32 _tmp"; " \ 359 "andl %"_msk",%"_LO32 _tmp"; " \
360 "orl %"_LO32 _tmp",%"_sav"; " 360 "orl %"_LO32 _tmp",%"_sav"; "
361 361
362#ifdef CONFIG_X86_64
363#define ON64(x) x
364#else
365#define ON64(x)
366#endif
367
362/* Raw emulation: instruction has two explicit operands. */ 368/* Raw emulation: instruction has two explicit operands. */
363#define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy) \ 369#define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy) \
364 do { \ 370 do { \
@@ -425,42 +431,27 @@ static u16 group2_table[] = {
425 __emulate_2op_nobyte(_op, _src, _dst, _eflags, \ 431 __emulate_2op_nobyte(_op, _src, _dst, _eflags, \
426 "w", "r", _LO32, "r", "", "r") 432 "w", "r", _LO32, "r", "", "r")
427 433
428/* Instruction has only one explicit operand (no source operand). */ 434#define __emulate_1op(_op, _dst, _eflags, _suffix) \
429#define emulate_1op(_op, _dst, _eflags) \
430 do { \ 435 do { \
431 unsigned long _tmp; \ 436 unsigned long _tmp; \
432 \ 437 \
438 __asm__ __volatile__ ( \
439 _PRE_EFLAGS("0", "3", "2") \
440 _op _suffix " %1; " \
441 _POST_EFLAGS("0", "3", "2") \
442 : "=m" (_eflags), "+m" ((_dst).val), \
443 "=&r" (_tmp) \
444 : "i" (EFLAGS_MASK)); \
445 } while (0)
446
447/* Instruction has only one explicit operand (no source operand). */
448#define emulate_1op(_op, _dst, _eflags) \
449 do { \
433 switch ((_dst).bytes) { \ 450 switch ((_dst).bytes) { \
434 case 1: \ 451 case 1: __emulate_1op(_op, _dst, _eflags, "b"); break; \
435 __asm__ __volatile__ ( \ 452 case 2: __emulate_1op(_op, _dst, _eflags, "w"); break; \
436 _PRE_EFLAGS("0", "3", "2") \ 453 case 4: __emulate_1op(_op, _dst, _eflags, "l"); break; \
437 _op"b %1; " \ 454 case 8: ON64(__emulate_1op(_op, _dst, _eflags, "q")); break; \
438 _POST_EFLAGS("0", "3", "2") \
439 : "=m" (_eflags), "=m" ((_dst).val), \
440 "=&r" (_tmp) \
441 : "i" (EFLAGS_MASK)); \
442 break; \
443 case 2: \
444 __asm__ __volatile__ ( \
445 _PRE_EFLAGS("0", "3", "2") \
446 _op"w %1; " \
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 } \ 455 } \
465 } while (0) 456 } while (0)
466 457
@@ -476,19 +467,8 @@ static u16 group2_table[] = {
476 : _qy ((_src).val), "i" (EFLAGS_MASK)); \ 467 : _qy ((_src).val), "i" (EFLAGS_MASK)); \
477 } while (0) 468 } while (0)
478 469
479#define __emulate_1op_8byte(_op, _dst, _eflags) \
480 do { \
481 __asm__ __volatile__ ( \
482 _PRE_EFLAGS("0", "3", "2") \
483 _op"q %1; " \
484 _POST_EFLAGS("0", "3", "2") \
485 : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \
486 : "i" (EFLAGS_MASK)); \
487 } while (0)
488
489#elif defined(__i386__) 470#elif defined(__i386__)
490#define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy) 471#define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy)
491#define __emulate_1op_8byte(_op, _dst, _eflags)
492#endif /* __i386__ */ 472#endif /* __i386__ */
493 473
494/* Fetch next part of the instruction being emulated. */ 474/* Fetch next part of the instruction being emulated. */