Commit 35c843c4 authored by Wei Yongjun's avatar Wei Yongjun Committed by Avi Kivity

KVM: x86 emulator: fix negative bit offset BitOp instruction emulation

If bit offset operands is a negative number, BitOp instruction
will return wrong value. This patch fix it.
Signed-off-by: default avatarWei Yongjun <yjwei@cn.fujitsu.com>
Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent 8744aa9a
...@@ -723,6 +723,22 @@ static int decode_abs(struct x86_emulate_ctxt *ctxt, ...@@ -723,6 +723,22 @@ static int decode_abs(struct x86_emulate_ctxt *ctxt,
return rc; return rc;
} }
static void fetch_bit_operand(struct decode_cache *c)
{
long sv, mask;
if (c->dst.type == OP_MEM) {
mask = ~(c->dst.bytes * 8 - 1);
if (c->src.bytes == 2)
sv = (s16)c->src.val & (s16)mask;
else if (c->src.bytes == 4)
sv = (s32)c->src.val & (s32)mask;
c->dst.addr.mem += (sv >> 3);
}
}
static int read_emulated(struct x86_emulate_ctxt *ctxt, static int read_emulated(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops, struct x86_emulate_ops *ops,
unsigned long addr, void *dest, unsigned size) unsigned long addr, void *dest, unsigned size)
...@@ -2638,12 +2654,8 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt) ...@@ -2638,12 +2654,8 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt)
c->dst.bytes = 8; c->dst.bytes = 8;
else else
c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
if (c->dst.type == OP_MEM && (c->d & BitOp)) { if (c->d & BitOp)
unsigned long mask = ~(c->dst.bytes * 8 - 1); fetch_bit_operand(c);
c->dst.addr.mem = c->dst.addr.mem +
(c->src.val & mask) / 8;
}
c->dst.orig_val = c->dst.val; c->dst.orig_val = c->dst.val;
break; break;
case DstAcc: case DstAcc:
......
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