]> Pileus Git - ~andy/linux/commitdiff
KVM: x86 emulator: add SrcImmU16 operand type
authorAvi Kivity <avi@redhat.com>
Wed, 18 Aug 2010 12:11:24 +0000 (15:11 +0300)
committerAvi Kivity <avi@redhat.com>
Sun, 24 Oct 2010 08:51:12 +0000 (10:51 +0200)
Used for RET NEAR instructions.

Signed-off-by: Avi Kivity <avi@redhat.com>
arch/x86/kvm/emulate.c

index 31335779396887df6e565cae392e192b84923fc2..db80e28471da8fe0b7402769e27d38e02daff45a 100644 (file)
@@ -72,6 +72,7 @@
 #define SrcImmFAddr (0xb<<4)   /* Source is immediate far address */
 #define SrcMemFAddr (0xc<<4)   /* Source is far address in memory */
 #define SrcAcc      (0xd<<4)   /* Source Accumulator */
+#define SrcImmU16   (0xe<<4)    /* Immediate operand, unsigned, 16 bits */
 #define SrcMask     (0xf<<4)
 /* Generic ModRM decode. */
 #define ModRM       (1<<8)
@@ -2678,13 +2679,17 @@ done_prefixes:
        srcmem_common:
                c->src = memop;
                break;
+       case SrcImmU16:
+               c->src.bytes = 2;
+               goto srcimm;
        case SrcImm:
        case SrcImmU:
-               c->src.type = OP_IMM;
-               c->src.addr.mem = c->eip;
                c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
                if (c->src.bytes == 8)
                        c->src.bytes = 4;
+       srcimm:
+               c->src.type = OP_IMM;
+               c->src.addr.mem = c->eip;
                /* NB. Immediates are sign-extended as necessary. */
                switch (c->src.bytes) {
                case 1:
@@ -2697,7 +2702,8 @@ done_prefixes:
                        c->src.val = insn_fetch(s32, 4, c->eip);
                        break;
                }
-               if ((c->d & SrcMask) == SrcImmU) {
+               if ((c->d & SrcMask) == SrcImmU
+                   || (c->d & SrcMask) == SrcImmU16) {
                        switch (c->src.bytes) {
                        case 1:
                                c->src.val &= 0xff;