From mboxrd@z Thu Jan 1 00:00:00 1970 From: Avi Kivity Subject: [PATCH] KVM: x86 emulator: fix %rip-relative addressing with immediate source operand Date: Sun, 19 Jun 2011 19:21:11 +0300 Message-ID: <1308500471-6222-1-git-send-email-avi@redhat.com> Cc: To: Marcelo Tosatti , kvm@vger.kernel.org Return-path: Received: from mx1.redhat.com ([209.132.183.28]:26693 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750767Ab1FSQVP (ORCPT ); Sun, 19 Jun 2011 12:21:15 -0400 Sender: kvm-owner@vger.kernel.org List-ID: %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. Signed-off-by: Avi Kivity --- arch/x86/kvm/emulate.c | 12 +++++++----- 1 files changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 14891ad..6f08bc9 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -3342,7 +3342,7 @@ int 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; ctxt->_eip = ctxt->eip; ctxt->fetch.start = ctxt->_eip; @@ -3517,9 +3517,6 @@ done_prefixes: if (memop.type == OP_MEM && ctxt->ad_bytes != 8) memop.addr.mem.ea = (u32)memop.addr.mem.ea; - if (memop.type == OP_MEM && ctxt->rip_relative) - memop.addr.mem.ea += ctxt->_eip; - /* * Decode and fetch the source operand: register, memory * or immediate. @@ -3541,6 +3538,7 @@ done_prefixes: ctxt->op_bytes; srcmem_common: ctxt->src = memop; + memopp = &ctxt->src; break; case SrcImmU16: rc = decode_imm(ctxt, &ctxt->src, 2, false); @@ -3637,6 +3635,7 @@ done_prefixes: case DstMem: case DstMem64: ctxt->dst = memop; + memopp = &ctxt->dst; if ((ctxt->d & DstMask) == DstMem64) ctxt->dst.bytes = 8; else @@ -3670,10 +3669,13 @@ done_prefixes: /* Special instructions do their own operand decoding. */ default: ctxt->dst.type = OP_NONE; /* Disable writeback. */ - return 0; + break; } done: + if (memopp && memopp->type == OP_MEM && ctxt->rip_relative) + memopp->addr.mem.ea += ctxt->_eip; + return (rc == X86EMUL_UNHANDLEABLE) ? EMULATION_FAILED : EMULATION_OK; } -- 1.7.5.3