Skip to content

Commit

Permalink
KVM: emulate: do not initialize memopp
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
whitebrandy authored and bonzini committed Jul 11, 2014
1 parent 573e80f commit 41061cd
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 4 deletions.
5 changes: 5 additions & 0 deletions arch/x86/include/asm/kvm_emulate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 4 additions & 4 deletions arch/x86/kvm/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -4425,9 +4428,6 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)

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.
Expand All @@ -4448,7 +4448,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
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;
Expand Down

0 comments on commit 41061cd

Please sign in to comment.