Commit 41061cdb authored by Bandan Das's avatar Bandan Das Committed by Paolo Bonzini

KVM: emulate: do not initialize memopp

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: default avatarBandan Das <bsd@redhat.com>
[Fix immediate operands with rip-relative addressing. - Paolo]
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 573e80fe
...@@ -295,6 +295,11 @@ struct x86_emulate_ctxt { ...@@ -295,6 +295,11 @@ struct x86_emulate_ctxt {
struct operand dst; struct operand dst;
int (*execute)(struct x86_emulate_ctxt *ctxt); int (*execute)(struct x86_emulate_ctxt *ctxt);
int (*check_perm)(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; bool rip_relative;
u8 rex_prefix; u8 rex_prefix;
u8 lock_prefix; u8 lock_prefix;
......
...@@ -1177,6 +1177,9 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, ...@@ -1177,6 +1177,9 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
} }
} }
op->addr.mem.ea = modrm_ea; op->addr.mem.ea = modrm_ea;
if (ctxt->ad_bytes != 8)
ctxt->memop.addr.mem.ea = (u32)ctxt->memop.addr.mem.ea;
done: done:
return rc; return rc;
} }
...@@ -4425,9 +4428,6 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) ...@@ -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; 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 * Decode and fetch the source operand: register, memory
* or immediate. * or immediate.
...@@ -4448,7 +4448,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) ...@@ -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); rc = decode_operand(ctxt, &ctxt->dst, (ctxt->d >> DstShift) & OpMask);
done: done:
if (ctxt->memopp && ctxt->memopp->type == OP_MEM && ctxt->rip_relative) if (ctxt->rip_relative)
ctxt->memopp->addr.mem.ea += ctxt->_eip; ctxt->memopp->addr.mem.ea += ctxt->_eip;
return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK; return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment