forked from luck/tmp_suning_uos_patched
KVM: x86 emulator: fix %rip-relative addressing with immediate source operand
%rip-relative addressing is relative to the first byte of the next instruction, so we need to add %rip only after we've fetched any immediate bytes. Based on original patch by Li Xin <xin.li@intel.com>. Signed-off-by: Avi Kivity <avi@redhat.com> Acked-by: Li Xin <xin.li@intel.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
This commit is contained in:
parent
b0af8dfdd6
commit
cb16c34876
|
@ -3372,7 +3372,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
|
|||
int def_op_bytes, def_ad_bytes, goffset, simd_prefix;
|
||||
bool op_prefix = false;
|
||||
struct opcode opcode;
|
||||
struct operand memop = { .type = OP_NONE };
|
||||
struct operand memop = { .type = OP_NONE }, *memopp = NULL;
|
||||
|
||||
c->eip = ctxt->eip;
|
||||
c->fetch.start = c->eip;
|
||||
|
@ -3547,9 +3547,6 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
|
|||
if (memop.type == OP_MEM && c->ad_bytes != 8)
|
||||
memop.addr.mem.ea = (u32)memop.addr.mem.ea;
|
||||
|
||||
if (memop.type == OP_MEM && c->rip_relative)
|
||||
memop.addr.mem.ea += c->eip;
|
||||
|
||||
/*
|
||||
* Decode and fetch the source operand: register, memory
|
||||
* or immediate.
|
||||
|
@ -3571,6 +3568,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
|
|||
c->op_bytes;
|
||||
srcmem_common:
|
||||
c->src = memop;
|
||||
memopp = &c->src;
|
||||
break;
|
||||
case SrcImmU16:
|
||||
rc = decode_imm(ctxt, &c->src, 2, false);
|
||||
|
@ -3667,6 +3665,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
|
|||
case DstMem:
|
||||
case DstMem64:
|
||||
c->dst = memop;
|
||||
memopp = &c->dst;
|
||||
if ((c->d & DstMask) == DstMem64)
|
||||
c->dst.bytes = 8;
|
||||
else
|
||||
|
@ -3700,10 +3699,13 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
|
|||
/* Special instructions do their own operand decoding. */
|
||||
default:
|
||||
c->dst.type = OP_NONE; /* Disable writeback. */
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
if (memopp && memopp->type == OP_MEM && c->rip_relative)
|
||||
memopp->addr.mem.ea += c->eip;
|
||||
|
||||
return (rc == X86EMUL_UNHANDLEABLE) ? EMULATION_FAILED : EMULATION_OK;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user