mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-06 19:07:52 +00:00
Merge branch 'kvm-updates/3.0' of git://git.kernel.org/pub/scm/virt/kvm/kvm
* 'kvm-updates/3.0' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: x86 emulator: fix %rip-relative addressing with immediate source operand
This commit is contained in:
commit
c017d0d135
1 changed files with 7 additions and 5 deletions
|
@ -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;
|
int def_op_bytes, def_ad_bytes, goffset, simd_prefix;
|
||||||
bool op_prefix = false;
|
bool op_prefix = false;
|
||||||
struct opcode opcode;
|
struct opcode opcode;
|
||||||
struct operand memop = { .type = OP_NONE };
|
struct operand memop = { .type = OP_NONE }, *memopp = NULL;
|
||||||
|
|
||||||
c->eip = ctxt->eip;
|
c->eip = ctxt->eip;
|
||||||
c->fetch.start = c->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)
|
if (memop.type == OP_MEM && c->ad_bytes != 8)
|
||||||
memop.addr.mem.ea = (u32)memop.addr.mem.ea;
|
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
|
* Decode and fetch the source operand: register, memory
|
||||||
* or immediate.
|
* or immediate.
|
||||||
|
@ -3571,6 +3568,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
|
||||||
c->op_bytes;
|
c->op_bytes;
|
||||||
srcmem_common:
|
srcmem_common:
|
||||||
c->src = memop;
|
c->src = memop;
|
||||||
|
memopp = &c->src;
|
||||||
break;
|
break;
|
||||||
case SrcImmU16:
|
case SrcImmU16:
|
||||||
rc = decode_imm(ctxt, &c->src, 2, false);
|
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 DstMem:
|
||||||
case DstMem64:
|
case DstMem64:
|
||||||
c->dst = memop;
|
c->dst = memop;
|
||||||
|
memopp = &c->dst;
|
||||||
if ((c->d & DstMask) == DstMem64)
|
if ((c->d & DstMask) == DstMem64)
|
||||||
c->dst.bytes = 8;
|
c->dst.bytes = 8;
|
||||||
else
|
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. */
|
/* Special instructions do their own operand decoding. */
|
||||||
default:
|
default:
|
||||||
c->dst.type = OP_NONE; /* Disable writeback. */
|
c->dst.type = OP_NONE; /* Disable writeback. */
|
||||||
return 0;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
if (memopp && memopp->type == OP_MEM && c->rip_relative)
|
||||||
|
memopp->addr.mem.ea += c->eip;
|
||||||
|
|
||||||
return (rc == X86EMUL_UNHANDLEABLE) ? EMULATION_FAILED : EMULATION_OK;
|
return (rc == X86EMUL_UNHANDLEABLE) ? EMULATION_FAILED : EMULATION_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue