* [PATCH 1/3] KVM: x86 emulator: fix negative bit offset BitOp instruction emulation
@ 2010-08-06 7:17 Wei Yongjun
2010-08-06 7:20 ` PATCH 2/3] KVM: x86 emulator: do not adjust the address for immediate source Wei Yongjun
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: Wei Yongjun @ 2010-08-06 7:17 UTC (permalink / raw)
To: Avi Kivity; +Cc: kvm
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>
---
arch/x86/kvm/emulate.c | 32 ++++++++++++++++++++++++++------
1 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 0e360c6..470c7eb 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -724,6 +724,30 @@ done:
return rc;
}
+static void fetch_bit_operand(struct decode_cache *c)
+{
+ unsigned long mask, byte_offset;
+
+ if (c->dst.type == OP_MEM) {
+ if (c->src.bytes == 2)
+ c->src.val = (s16)c->src.val;
+ else if (c->src.bytes == 4)
+ c->src.val = (s32)c->src.val;
+
+ mask = ~(c->dst.bytes * 8 - 1);
+
+ if ((long)c->src.val < 0) {
+ /* negative bit offset */
+ byte_offset = c->dst.bytes +
+ ((-c->src.val - 1) & mask) / 8;
+ c->dst.addr.mem -= byte_offset;
+ } else {
+ /* positive bit offset */
+ c->dst.addr.mem += (c->src.val & mask) / 8;
+ }
+ }
+}
+
static int read_emulated(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops,
unsigned long addr, void *dest, unsigned size)
@@ -2646,12 +2670,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:
--
1.7.0.4
^ permalink raw reply related [flat|nested] 10+ messages in thread* PATCH 2/3] KVM: x86 emulator: do not adjust the address for immediate source 2010-08-06 7:17 [PATCH 1/3] KVM: x86 emulator: fix negative bit offset BitOp instruction emulation Wei Yongjun @ 2010-08-06 7:20 ` Wei Yongjun 2010-08-06 7:26 ` [PATCH 2/3 v2] " Wei Yongjun 2010-08-06 7:21 ` [PATCH 3/3] KVM: x86 emulator: mask group 8 instruction as BitOp Wei Yongjun ` (2 subsequent siblings) 3 siblings, 1 reply; 10+ messages in thread From: Wei Yongjun @ 2010-08-06 7:20 UTC (permalink / raw) To: Avi Kivity; +Cc: kvm adjust the dst address for a register source but not adjust the address for an immediate source. Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> --- arch/x86/kvm/emulate.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 470c7eb..e7e3d2d 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -728,7 +728,7 @@ static void fetch_bit_operand(struct decode_cache *c) { unsigned long mask, byte_offset; - if (c->dst.type == OP_MEM) { + if (c->dst.type == OP_MEM && c->src.type == OP_REG) { if (c->src.bytes == 2) c->src.val = (s16)c->src.val; else if (c->src.bytes == 4) -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/3 v2] KVM: x86 emulator: do not adjust the address for immediate source 2010-08-06 7:20 ` PATCH 2/3] KVM: x86 emulator: do not adjust the address for immediate source Wei Yongjun @ 2010-08-06 7:26 ` Wei Yongjun 0 siblings, 0 replies; 10+ messages in thread From: Wei Yongjun @ 2010-08-06 7:26 UTC (permalink / raw) To: Avi Kivity; +Cc: kvm adjust the dst address for a register source but not adjust the address for an immediate source. Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> --- v1 -> v2 just fix the missing left bracket of mail title --- arch/x86/kvm/emulate.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 470c7eb..e7e3d2d 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -728,7 +728,7 @@ static void fetch_bit_operand(struct decode_cache *c) { unsigned long mask, byte_offset; - if (c->dst.type == OP_MEM) { + if (c->dst.type == OP_MEM && c->src.type == OP_REG) { if (c->src.bytes == 2) c->src.val = (s16)c->src.val; else if (c->src.bytes == 4) -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/3] KVM: x86 emulator: mask group 8 instruction as BitOp 2010-08-06 7:17 [PATCH 1/3] KVM: x86 emulator: fix negative bit offset BitOp instruction emulation Wei Yongjun 2010-08-06 7:20 ` PATCH 2/3] KVM: x86 emulator: do not adjust the address for immediate source Wei Yongjun @ 2010-08-06 7:21 ` Wei Yongjun 2010-08-06 8:10 ` [PATCH 1/3] KVM: x86 emulator: fix negative bit offset BitOp instruction emulation Paolo Bonzini 2010-08-08 20:28 ` Avi Kivity 3 siblings, 0 replies; 10+ messages in thread From: Wei Yongjun @ 2010-08-06 7:21 UTC (permalink / raw) To: Avi Kivity; +Cc: kvm Mask group 8 instruction as BitOp, so we can share the code for adjust the source operand. Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> --- arch/x86/kvm/emulate.c | 11 ++++------- 1 files changed, 4 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index e7e3d2d..dc6a74e 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -746,6 +746,9 @@ static void fetch_bit_operand(struct decode_cache *c) c->dst.addr.mem += (c->src.val & mask) / 8; } } + + /* only subword offset */ + c->src.val &= (c->dst.bytes << 3) - 1; } static int read_emulated(struct x86_emulate_ctxt *ctxt, @@ -2346,7 +2349,7 @@ static struct opcode twobyte_table[256] = { D(DstReg | SrcMem16 | ModRM | Mov), /* 0xB8 - 0xBF */ N, N, - G(0, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), + G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), /* 0xC0 - 0xCF */ @@ -3420,8 +3423,6 @@ twobyte_insn: break; case 0xab: bts: /* bts */ - /* only subword offset */ - c->src.val &= (c->dst.bytes << 3) - 1; emulate_2op_SrcV_nobyte("bts", c->src, c->dst, ctxt->eflags); break; case 0xac: /* shrd imm8, r, r/m */ @@ -3449,8 +3450,6 @@ twobyte_insn: break; case 0xb3: btr: /* btr */ - /* only subword offset */ - c->src.val &= (c->dst.bytes << 3) - 1; emulate_2op_SrcV_nobyte("btr", c->src, c->dst, ctxt->eflags); break; case 0xb6 ... 0xb7: /* movzx */ @@ -3472,8 +3471,6 @@ twobyte_insn: break; case 0xbb: btc: /* btc */ - /* only subword offset */ - c->src.val &= (c->dst.bytes << 3) - 1; emulate_2op_SrcV_nobyte("btc", c->src, c->dst, ctxt->eflags); break; case 0xbe ... 0xbf: /* movsx */ -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] KVM: x86 emulator: fix negative bit offset BitOp instruction emulation 2010-08-06 7:17 [PATCH 1/3] KVM: x86 emulator: fix negative bit offset BitOp instruction emulation Wei Yongjun 2010-08-06 7:20 ` PATCH 2/3] KVM: x86 emulator: do not adjust the address for immediate source Wei Yongjun 2010-08-06 7:21 ` [PATCH 3/3] KVM: x86 emulator: mask group 8 instruction as BitOp Wei Yongjun @ 2010-08-06 8:10 ` Paolo Bonzini 2010-08-08 20:28 ` Avi Kivity 3 siblings, 0 replies; 10+ messages in thread From: Paolo Bonzini @ 2010-08-06 8:10 UTC (permalink / raw) To: Wei Yongjun; +Cc: Avi Kivity, kvm On 08/06/2010 09:17 AM, Wei Yongjun wrote: > 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> > --- > arch/x86/kvm/emulate.c | 32 ++++++++++++++++++++++++++------ > 1 files changed, 26 insertions(+), 6 deletions(-) > > diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c > index 0e360c6..470c7eb 100644 > --- a/arch/x86/kvm/emulate.c > +++ b/arch/x86/kvm/emulate.c > @@ -724,6 +724,30 @@ done: > return rc; > } > > +static void fetch_bit_operand(struct decode_cache *c) > +{ > + unsigned long mask, byte_offset; > + > + if (c->dst.type == OP_MEM) { > + if (c->src.bytes == 2) > + c->src.val = (s16)c->src.val; > + else if (c->src.bytes == 4) > + c->src.val = (s32)c->src.val; > + > + mask = ~(c->dst.bytes * 8 - 1); > + > + if ((long)c->src.val< 0) { > + /* negative bit offset */ > + byte_offset = c->dst.bytes + > + ((-c->src.val - 1)& mask) / 8; > + c->dst.addr.mem -= byte_offset; > + } else { > + /* positive bit offset */ > + c->dst.addr.mem += (c->src.val& mask) / 8; > + } > + } > +} > + > static int read_emulated(struct x86_emulate_ctxt *ctxt, > struct x86_emulate_ops *ops, > unsigned long addr, void *dest, unsigned size) > @@ -2646,12 +2670,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: The whole series looks good now. Thanks! Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Paolo ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] KVM: x86 emulator: fix negative bit offset BitOp instruction emulation 2010-08-06 7:17 [PATCH 1/3] KVM: x86 emulator: fix negative bit offset BitOp instruction emulation Wei Yongjun ` (2 preceding siblings ...) 2010-08-06 8:10 ` [PATCH 1/3] KVM: x86 emulator: fix negative bit offset BitOp instruction emulation Paolo Bonzini @ 2010-08-08 20:28 ` Avi Kivity 2010-08-09 3:34 ` [PATCH 1/3 v2] " Wei Yongjun 3 siblings, 1 reply; 10+ messages in thread From: Avi Kivity @ 2010-08-08 20:28 UTC (permalink / raw) To: Wei Yongjun; +Cc: kvm On 08/06/2010 03:17 AM, Wei Yongjun wrote: > If bit offset operands is a negative number, BitOp instruction > will return wrong value. This patch fix it. > > +static void fetch_bit_operand(struct decode_cache *c) > +{ > + unsigned long mask, byte_offset; > + > + if (c->dst.type == OP_MEM) { > + if (c->src.bytes == 2) > + c->src.val = (s16)c->src.val; > + else if (c->src.bytes == 4) > + c->src.val = (s32)c->src.val; Better not to update in place, but instead use a local signed variable. > + > + mask = ~(c->dst.bytes * 8 - 1); > + > + if ((long)c->src.val < 0) { > + /* negative bit offset */ > + byte_offset = c->dst.bytes + > + ((-c->src.val - 1) & mask) / 8; > + c->dst.addr.mem -= byte_offset; > + } else { > + /* positive bit offset */ > + c->dst.addr.mem += (c->src.val & mask) / 8; > + } > + } Is the if () really necessary? If division translates to arithmetic shift right, it might not be needed. > +} > + -- I have a truly marvellous patch that fixes the bug which this signature is too narrow to contain. ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/3 v2] KVM: x86 emulator: fix negative bit offset BitOp instruction emulation 2010-08-08 20:28 ` Avi Kivity @ 2010-08-09 3:34 ` Wei Yongjun 2010-08-09 3:37 ` [PATCH 2/3 v2] KVM: x86 emulator: do not adjust the address for immediate source Wei Yongjun 2010-08-10 2:46 ` [PATCH 1/3 v2] KVM: x86 emulator: fix negative bit offset BitOp instruction emulation Avi Kivity 0 siblings, 2 replies; 10+ messages in thread From: Wei Yongjun @ 2010-08-09 3:34 UTC (permalink / raw) To: Avi Kivity; +Cc: kvm 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> --- arch/x86/kvm/emulate.c | 24 ++++++++++++++++++------ 1 files changed, 18 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 0e360c6..f48890d 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -724,6 +724,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) @@ -2646,12 +2662,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: -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/3 v2] KVM: x86 emulator: do not adjust the address for immediate source 2010-08-09 3:34 ` [PATCH 1/3 v2] " Wei Yongjun @ 2010-08-09 3:37 ` Wei Yongjun 2010-08-09 3:39 ` [PATCH 3/3 v2] KVM: x86 emulator: mask group 8 instruction as BitOp Wei Yongjun 2010-08-10 2:46 ` [PATCH 1/3 v2] KVM: x86 emulator: fix negative bit offset BitOp instruction emulation Avi Kivity 1 sibling, 1 reply; 10+ messages in thread From: Wei Yongjun @ 2010-08-09 3:37 UTC (permalink / raw) To: Avi Kivity; +Cc: kvm adjust the dst address for a register source but not adjust the address for an immediate source. Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> --- arch/x86/kvm/emulate.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index f48890d..161d361 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -728,7 +728,7 @@ static void fetch_bit_operand(struct decode_cache *c) { long sv, mask; - if (c->dst.type == OP_MEM) { + if (c->dst.type == OP_MEM && c->src.type == OP_REG) { mask = ~(c->dst.bytes * 8 - 1); if (c->src.bytes == 2) -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/3 v2] KVM: x86 emulator: mask group 8 instruction as BitOp 2010-08-09 3:37 ` [PATCH 2/3 v2] KVM: x86 emulator: do not adjust the address for immediate source Wei Yongjun @ 2010-08-09 3:39 ` Wei Yongjun 0 siblings, 0 replies; 10+ messages in thread From: Wei Yongjun @ 2010-08-09 3:39 UTC (permalink / raw) To: Avi Kivity; +Cc: kvm Mask group 8 instruction as BitOp, so we can share the code for adjust the source operand. Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> --- arch/x86/kvm/emulate.c | 11 ++++------- 1 files changed, 4 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 161d361..db19bcf 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -738,6 +738,9 @@ static void fetch_bit_operand(struct decode_cache *c) c->dst.addr.mem += (sv >> 3); } + + /* only subword offset */ + c->src.val &= (c->dst.bytes << 3) - 1; } static int read_emulated(struct x86_emulate_ctxt *ctxt, @@ -2338,7 +2341,7 @@ static struct opcode twobyte_table[256] = { D(DstReg | SrcMem16 | ModRM | Mov), /* 0xB8 - 0xBF */ N, N, - G(0, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), + G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), /* 0xC0 - 0xCF */ @@ -3412,8 +3415,6 @@ twobyte_insn: break; case 0xab: bts: /* bts */ - /* only subword offset */ - c->src.val &= (c->dst.bytes << 3) - 1; emulate_2op_SrcV_nobyte("bts", c->src, c->dst, ctxt->eflags); break; case 0xac: /* shrd imm8, r, r/m */ @@ -3441,8 +3442,6 @@ twobyte_insn: break; case 0xb3: btr: /* btr */ - /* only subword offset */ - c->src.val &= (c->dst.bytes << 3) - 1; emulate_2op_SrcV_nobyte("btr", c->src, c->dst, ctxt->eflags); break; case 0xb6 ... 0xb7: /* movzx */ @@ -3464,8 +3463,6 @@ twobyte_insn: break; case 0xbb: btc: /* btc */ - /* only subword offset */ - c->src.val &= (c->dst.bytes << 3) - 1; emulate_2op_SrcV_nobyte("btc", c->src, c->dst, ctxt->eflags); break; case 0xbe ... 0xbf: /* movsx */ -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3 v2] KVM: x86 emulator: fix negative bit offset BitOp instruction emulation 2010-08-09 3:34 ` [PATCH 1/3 v2] " Wei Yongjun 2010-08-09 3:37 ` [PATCH 2/3 v2] KVM: x86 emulator: do not adjust the address for immediate source Wei Yongjun @ 2010-08-10 2:46 ` Avi Kivity 1 sibling, 0 replies; 10+ messages in thread From: Avi Kivity @ 2010-08-10 2:46 UTC (permalink / raw) To: Wei Yongjun; +Cc: kvm On 08/08/2010 11:34 PM, Wei Yongjun wrote: > If bit offset operands is a negative number, BitOp instruction > will return wrong value. This patch fix it. > Thanks, applied all three patches. -- I have a truly marvellous patch that fixes the bug which this signature is too narrow to contain. ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2010-08-10 2:46 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-08-06 7:17 [PATCH 1/3] KVM: x86 emulator: fix negative bit offset BitOp instruction emulation Wei Yongjun 2010-08-06 7:20 ` PATCH 2/3] KVM: x86 emulator: do not adjust the address for immediate source Wei Yongjun 2010-08-06 7:26 ` [PATCH 2/3 v2] " Wei Yongjun 2010-08-06 7:21 ` [PATCH 3/3] KVM: x86 emulator: mask group 8 instruction as BitOp Wei Yongjun 2010-08-06 8:10 ` [PATCH 1/3] KVM: x86 emulator: fix negative bit offset BitOp instruction emulation Paolo Bonzini 2010-08-08 20:28 ` Avi Kivity 2010-08-09 3:34 ` [PATCH 1/3 v2] " Wei Yongjun 2010-08-09 3:37 ` [PATCH 2/3 v2] KVM: x86 emulator: do not adjust the address for immediate source Wei Yongjun 2010-08-09 3:39 ` [PATCH 3/3 v2] KVM: x86 emulator: mask group 8 instruction as BitOp Wei Yongjun 2010-08-10 2:46 ` [PATCH 1/3 v2] KVM: x86 emulator: fix negative bit offset BitOp instruction emulation Avi Kivity
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).