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: Wei Yongjun <yjwei@cn.fujitsu.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
Wei Yongjun 2010-08-09 11:34:56 +08:00 committed by Avi Kivity
parent 8744aa9aad
commit 35c843c485

View file

@ -723,6 +723,22 @@ done:
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,
struct x86_emulate_ops *ops,
unsigned long addr, void *dest, unsigned size)
@ -2638,12 +2654,8 @@ done_prefixes:
c->dst.bytes = 8;
else
c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
if (c->dst.type == OP_MEM && (c->d & BitOp)) {
unsigned long mask = ~(c->dst.bytes * 8 - 1);
c->dst.addr.mem = c->dst.addr.mem +
(c->src.val & mask) / 8;
}
if (c->d & BitOp)
fetch_bit_operand(c);
c->dst.orig_val = c->dst.val;
break;
case DstAcc: