* [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 an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.