]>
Commit | Line | Data |
---|---|---|
ed963235 GKH |
1 | From a64c8ec1d075617579fdc09b28559c748bf0d660 Mon Sep 17 00:00:00 2001 |
2 | From: Avi Kivity <avi@redhat.com> | |
3 | Date: Thu, 26 Aug 2010 14:31:30 +0300 | |
4 | Subject: KVM: x86 emulator: fix regression with cmpxchg8b on i386 hosts | |
5 | ||
6 | From: Avi Kivity <avi@redhat.com> | |
7 | ||
8 | commit 16518d5ada690643453eb0aef3cc7841d3623c2d upstream. | |
9 | ||
10 | operand::val and operand::orig_val are 32-bit on i386, whereas cmpxchg8b | |
11 | operands are 64-bit. | |
12 | ||
13 | Fix by adding val64 and orig_val64 union members to struct operand, and | |
14 | using them where needed. | |
15 | ||
16 | Signed-off-by: Avi Kivity <avi@redhat.com> | |
17 | Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> | |
18 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
19 | ||
20 | --- | |
21 | arch/x86/include/asm/kvm_emulate.h | 10 +++++++++- | |
22 | arch/x86/kvm/emulate.c | 9 ++++----- | |
23 | 2 files changed, 13 insertions(+), 6 deletions(-) | |
24 | ||
25 | --- a/arch/x86/include/asm/kvm_emulate.h | |
26 | +++ b/arch/x86/include/asm/kvm_emulate.h | |
27 | @@ -143,7 +143,15 @@ struct x86_emulate_ops { | |
28 | struct operand { | |
29 | enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type; | |
30 | unsigned int bytes; | |
31 | - unsigned long val, orig_val, *ptr; | |
32 | + union { | |
33 | + unsigned long orig_val; | |
34 | + u64 orig_val64; | |
35 | + }; | |
36 | + unsigned long *ptr; | |
37 | + union { | |
38 | + unsigned long val; | |
39 | + u64 val64; | |
40 | + }; | |
41 | }; | |
42 | ||
43 | struct fetch_cache { | |
44 | --- a/arch/x86/kvm/emulate.c | |
45 | +++ b/arch/x86/kvm/emulate.c | |
46 | @@ -1712,17 +1712,16 @@ static inline int emulate_grp9(struct x8 | |
47 | struct x86_emulate_ops *ops) | |
48 | { | |
49 | struct decode_cache *c = &ctxt->decode; | |
50 | - u64 old = c->dst.orig_val; | |
51 | + u64 old = c->dst.orig_val64; | |
52 | ||
53 | if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) || | |
54 | ((u32) (old >> 32) != (u32) c->regs[VCPU_REGS_RDX])) { | |
55 | - | |
56 | c->regs[VCPU_REGS_RAX] = (u32) (old >> 0); | |
57 | c->regs[VCPU_REGS_RDX] = (u32) (old >> 32); | |
58 | ctxt->eflags &= ~EFLG_ZF; | |
59 | } else { | |
60 | - c->dst.val = ((u64)c->regs[VCPU_REGS_RCX] << 32) | | |
61 | - (u32) c->regs[VCPU_REGS_RBX]; | |
62 | + c->dst.val64 = ((u64)c->regs[VCPU_REGS_RCX] << 32) | | |
63 | + (u32) c->regs[VCPU_REGS_RBX]; | |
64 | ||
65 | ctxt->eflags |= EFLG_ZF; | |
66 | } | |
67 | @@ -2535,7 +2534,7 @@ x86_emulate_insn(struct x86_emulate_ctxt | |
68 | ctxt->vcpu); | |
69 | if (rc != X86EMUL_CONTINUE) | |
70 | goto done; | |
71 | - c->src.orig_val = c->src.val; | |
72 | + c->src.orig_val64 = c->src.val64; | |
73 | } | |
74 | ||
75 | if (c->src2.type == OP_MEM) { |