aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/emulate.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2010-08-18 08:11:24 -0400
committerAvi Kivity <avi@redhat.com>2010-10-24 04:51:12 -0400
commitb250e605895d02cede78922d034f7825af72a8b5 (patch)
treef9a5a70a3aac61362cb39f5bd2725bd0d4c6b861 /arch/x86/kvm/emulate.c
parent0ef753b8c323f5b8d75d7dc57ceef6b35982afdb (diff)
KVM: x86 emulator: add SrcImmU16 operand type
Used for RET NEAR instructions. Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r--arch/x86/kvm/emulate.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 313357793968..db80e28471da 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -72,6 +72,7 @@
72#define SrcImmFAddr (0xb<<4) /* Source is immediate far address */ 72#define SrcImmFAddr (0xb<<4) /* Source is immediate far address */
73#define SrcMemFAddr (0xc<<4) /* Source is far address in memory */ 73#define SrcMemFAddr (0xc<<4) /* Source is far address in memory */
74#define SrcAcc (0xd<<4) /* Source Accumulator */ 74#define SrcAcc (0xd<<4) /* Source Accumulator */
75#define SrcImmU16 (0xe<<4) /* Immediate operand, unsigned, 16 bits */
75#define SrcMask (0xf<<4) 76#define SrcMask (0xf<<4)
76/* Generic ModRM decode. */ 77/* Generic ModRM decode. */
77#define ModRM (1<<8) 78#define ModRM (1<<8)
@@ -2678,13 +2679,17 @@ done_prefixes:
2678 srcmem_common: 2679 srcmem_common:
2679 c->src = memop; 2680 c->src = memop;
2680 break; 2681 break;
2682 case SrcImmU16:
2683 c->src.bytes = 2;
2684 goto srcimm;
2681 case SrcImm: 2685 case SrcImm:
2682 case SrcImmU: 2686 case SrcImmU:
2683 c->src.type = OP_IMM;
2684 c->src.addr.mem = c->eip;
2685 c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; 2687 c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
2686 if (c->src.bytes == 8) 2688 if (c->src.bytes == 8)
2687 c->src.bytes = 4; 2689 c->src.bytes = 4;
2690 srcimm:
2691 c->src.type = OP_IMM;
2692 c->src.addr.mem = c->eip;
2688 /* NB. Immediates are sign-extended as necessary. */ 2693 /* NB. Immediates are sign-extended as necessary. */
2689 switch (c->src.bytes) { 2694 switch (c->src.bytes) {
2690 case 1: 2695 case 1:
@@ -2697,7 +2702,8 @@ done_prefixes:
2697 c->src.val = insn_fetch(s32, 4, c->eip); 2702 c->src.val = insn_fetch(s32, 4, c->eip);
2698 break; 2703 break;
2699 } 2704 }
2700 if ((c->d & SrcMask) == SrcImmU) { 2705 if ((c->d & SrcMask) == SrcImmU
2706 || (c->d & SrcMask) == SrcImmU16) {
2701 switch (c->src.bytes) { 2707 switch (c->src.bytes) {
2702 case 1: 2708 case 1:
2703 c->src.val &= 0xff; 2709 c->src.val &= 0xff;