diff options
author | Nadav Amit <namit@cs.technion.ac.il> | 2014-06-15 09:12:57 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-06-19 06:52:08 -0400 |
commit | 7dec5603b6b8dc4c3e1c65d318bd2a5a8c62a424 (patch) | |
tree | 2a331fa1dfa9396bfec002c5fa839294adbe664d | |
parent | bc39c4db7110f88f338cbbabe53d3e43c7400a59 (diff) |
KVM: x86: bit-ops emulation ignores offset on 64-bit
The current emulation of bit operations ignores the offset from the destination
on 64-bit target memory operands. This patch fixes this behavior.
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | arch/x86/kvm/emulate.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 8a1796b1eef2..439a3286406a 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -1220,12 +1220,14 @@ static void fetch_bit_operand(struct x86_emulate_ctxt *ctxt) | |||
1220 | long sv = 0, mask; | 1220 | long sv = 0, mask; |
1221 | 1221 | ||
1222 | if (ctxt->dst.type == OP_MEM && ctxt->src.type == OP_REG) { | 1222 | if (ctxt->dst.type == OP_MEM && ctxt->src.type == OP_REG) { |
1223 | mask = ~(ctxt->dst.bytes * 8 - 1); | 1223 | mask = ~((long)ctxt->dst.bytes * 8 - 1); |
1224 | 1224 | ||
1225 | if (ctxt->src.bytes == 2) | 1225 | if (ctxt->src.bytes == 2) |
1226 | sv = (s16)ctxt->src.val & (s16)mask; | 1226 | sv = (s16)ctxt->src.val & (s16)mask; |
1227 | else if (ctxt->src.bytes == 4) | 1227 | else if (ctxt->src.bytes == 4) |
1228 | sv = (s32)ctxt->src.val & (s32)mask; | 1228 | sv = (s32)ctxt->src.val & (s32)mask; |
1229 | else | ||
1230 | sv = (s64)ctxt->src.val & (s64)mask; | ||
1229 | 1231 | ||
1230 | ctxt->dst.addr.mem.ea += (sv >> 3); | 1232 | ctxt->dst.addr.mem.ea += (sv >> 3); |
1231 | } | 1233 | } |