KVM: emulate: do not initialize memopp
authorBandan Das <bsd@redhat.com>
Wed, 16 Apr 2014 16:46:14 +0000 (12:46 -0400)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 11 Jul 2014 07:14:01 +0000 (09:14 +0200)
rip_relative is only set if decode_modrm runs, and if you have ModRM
you will also have a memopp.  We can then access memopp unconditionally.
Note that rip_relative cannot be hoisted up to decode_modrm, or you
break "mov $0, xyz(%rip)".

Also, move typecast on "out of range value" of mem.ea to decode_modrm.

Together, all these optimizations save about 50 cycles on each emulated
instructions (4-6%).

Signed-off-by: Bandan Das <bsd@redhat.com>
[Fix immediate operands with rip-relative addressing. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/include/asm/kvm_emulate.h
arch/x86/kvm/emulate.c

index 6c808408326fc1f5e99fed51e49b2f9d32b6881f..fcf58cd25ebda63501924945bd05d8f65317ba1a 100644 (file)
@@ -295,6 +295,11 @@ struct x86_emulate_ctxt {
        struct operand dst;
        int (*execute)(struct x86_emulate_ctxt *ctxt);
        int (*check_perm)(struct x86_emulate_ctxt *ctxt);
+       /*
+        * The following six fields are cleared together,
+        * the rest are initialized unconditionally in x86_decode_insn
+        * or elsewhere
+        */
        bool rip_relative;
        u8 rex_prefix;
        u8 lock_prefix;
index 08badf638fb0f34bb026de05dc691dd8fd78f3c6..390400a54a9c5c084fb6fa6114056f471ce23089 100644 (file)
@@ -1177,6 +1177,9 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
                }
        }
        op->addr.mem.ea = modrm_ea;
+       if (ctxt->ad_bytes != 8)
+               ctxt->memop.addr.mem.ea = (u32)ctxt->memop.addr.mem.ea;
+
 done:
        return rc;
 }
@@ -4425,9 +4428,6 @@ done_prefixes:
 
        ctxt->memop.addr.mem.seg = ctxt->seg_override;
 
-       if (ctxt->memop.type == OP_MEM && ctxt->ad_bytes != 8)
-               ctxt->memop.addr.mem.ea = (u32)ctxt->memop.addr.mem.ea;
-
        /*
         * Decode and fetch the source operand: register, memory
         * or immediate.
@@ -4448,7 +4448,7 @@ done_prefixes:
        rc = decode_operand(ctxt, &ctxt->dst, (ctxt->d >> DstShift) & OpMask);
 
 done:
-       if (ctxt->memopp && ctxt->memopp->type == OP_MEM && ctxt->rip_relative)
+       if (ctxt->rip_relative)
                ctxt->memopp->addr.mem.ea += ctxt->_eip;
 
        return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK;