diff mbox

[maverick] KVM: x86 emulator: fix regression with cmpxchg8b on i386 hosts

Message ID 20110107152008.GA12709@hallyn.com
State Accepted
Headers show

Commit Message

Serge Hallyn Jan. 7, 2011, 3:20 p.m. UTC
Hi,

the patch below addresses LP: #688085.  SRU justification follows first:


SRU Justification:
Impact: Users cannot boot KVM guests on i386 hosts
2. How bug addressed: The upstream commit at http://www.spinics.net/lists/kvm/msg40800.html fixed it
3. Patch: A kernel patch is attached to this bug.
4. How to reproduce:
  1. install Maversick x86 (not amd64)
  2. ensure you have kvm support in processor
  3. kvm -kernel /boot/initrd.img-2.6.35-24-generic-pae
  4. kvm -no-kvm -kernel /boot/initrd.img-2.6.35-24-generic-pae works OK.
5. Regression potential: since this is cherrypicking a commit from a future upstream which had already been changed, regression is possible. However if there is a regression, it should only affect users of KVM on i386 hosts, which currently fail anyway.

thanks,
-serge

From fa059f7ac6aecac94a2ce6be10713000be80df08 Mon Sep 17 00:00:00 2001
From: Serge E. Hallyn <serge.hallyn@canonical.com>
Date: Wed, 5 Jan 2011 15:02:28 +0000
Subject: [PATCH 1/1] UBUNTU: [Upstream] KVM: x86 emulator: fix regression with cmpxchg8b on i386 host

Buglink: https://bugs.launchpad.net/ubuntu/+source/qemu/+bug/688085

upstream commit: 16518d5ada690643453eb0aef3cc7841d3623c2d

KVM: x86 emulator: fix regression with cmpxchg8b on i386 hosts

operand::val and operand::orig_val are 32-bit on i386, whereas cmpxchg8b
operands are 64-bit.

Fix by adding val64 and orig_val64 union members to struct operand, and
using them where needed.

Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Serge E. Hallyn <serge.hallyn@canonical.com>
---
 arch/x86/include/asm/kvm_emulate.h |   10 +++++++++-
 arch/x86/kvm/emulate.c             |    6 +++---
 debian.master/changelog            |    9 +++++++++
 3 files changed, 21 insertions(+), 4 deletions(-)

Comments

Tim Gardner Jan. 12, 2011, 4:53 p.m. UTC | #1
On 01/07/2011 09:20 AM, Serge E. Hallyn wrote:
> Hi,
>
> the patch below addresses LP: #688085.  SRU justification follows first:
>
>
> SRU Justification:
> Impact: Users cannot boot KVM guests on i386 hosts
> 2. How bug addressed: The upstream commit at http://www.spinics.net/lists/kvm/msg40800.html fixed it
> 3. Patch: A kernel patch is attached to this bug.
> 4. How to reproduce:
>    1. install Maversick x86 (not amd64)
>    2. ensure you have kvm support in processor
>    3. kvm -kernel /boot/initrd.img-2.6.35-24-generic-pae
>    4. kvm -no-kvm -kernel /boot/initrd.img-2.6.35-24-generic-pae works OK.
> 5. Regression potential: since this is cherrypicking a commit from a future upstream which had already been changed, regression is possible. However if there is a regression, it should only affect users of KVM on i386 hosts, which currently fail anyway.
>
> thanks,
> -serge
>
>  From fa059f7ac6aecac94a2ce6be10713000be80df08 Mon Sep 17 00:00:00 2001
> From: Serge E. Hallyn<serge.hallyn@canonical.com>
> Date: Wed, 5 Jan 2011 15:02:28 +0000
> Subject: [PATCH 1/1] UBUNTU: [Upstream] KVM: x86 emulator: fix regression with cmpxchg8b on i386 host
>
> Buglink: https://bugs.launchpad.net/ubuntu/+source/qemu/+bug/688085
>
> upstream commit: 16518d5ada690643453eb0aef3cc7841d3623c2d
>
> KVM: x86 emulator: fix regression with cmpxchg8b on i386 hosts
>
> operand::val and operand::orig_val are 32-bit on i386, whereas cmpxchg8b
> operands are 64-bit.
>
> Fix by adding val64 and orig_val64 union members to struct operand, and
> using them where needed.
>
> Signed-off-by: Avi Kivity<avi@redhat.com>
> Signed-off-by: Marcelo Tosatti<mtosatti@redhat.com>
> Signed-off-by: Serge E. Hallyn<serge.hallyn@canonical.com>
> ---
>   arch/x86/include/asm/kvm_emulate.h |   10 +++++++++-
>   arch/x86/kvm/emulate.c             |    6 +++---
>   debian.master/changelog            |    9 +++++++++
>   3 files changed, 21 insertions(+), 4 deletions(-)
>
> diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
> index 0b2729b..2cd35d5 100644
> --- a/arch/x86/include/asm/kvm_emulate.h
> +++ b/arch/x86/include/asm/kvm_emulate.h
> @@ -143,7 +143,15 @@ struct x86_emulate_ops {
>   struct operand {
>   	enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type;
>   	unsigned int bytes;
> -	unsigned long val, orig_val, *ptr;
> +	unsigned long *ptr;
> +	union {
> +		unsigned long orig_val;
> +		u64 orig_val64;
> +	};
> +	union {
> +		unsigned long val;
> +		u64 val64;
> +	};
>   };
>
>   struct fetch_cache {
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index 715a7fa..abb677a 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -1712,7 +1712,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
>   			       struct x86_emulate_ops *ops)
>   {
>   	struct decode_cache *c =&ctxt->decode;
> -	u64 old = c->dst.orig_val;
> +	u64 old = c->dst.orig_val64;
>
>   	if (((u32) (old>>  0) != (u32) c->regs[VCPU_REGS_RAX]) ||
>   	    ((u32) (old>>  32) != (u32) c->regs[VCPU_REGS_RDX])) {
> @@ -1721,7 +1721,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
>   		c->regs[VCPU_REGS_RDX] = (u32) (old>>  32);
>   		ctxt->eflags&= ~EFLG_ZF;
>   	} else {
> -		c->dst.val = ((u64)c->regs[VCPU_REGS_RCX]<<  32) |
> +		c->dst.val64 = ((u64)c->regs[VCPU_REGS_RCX]<<  32) |
>   		       (u32) c->regs[VCPU_REGS_RBX];
>
>   		ctxt->eflags |= EFLG_ZF;
> @@ -2535,7 +2535,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
>   					ctxt->vcpu);
>   		if (rc != X86EMUL_CONTINUE)
>   			goto done;
> -		c->src.orig_val = c->src.val;
> +		c->src.orig_val64 = c->src.val64;
>   	}
>
>   	if (c->src2.type == OP_MEM) {
> diff --git a/debian.master/changelog b/debian.master/changelog
> index f8a29cc..2df896c 100644
> --- a/debian.master/changelog
> +++ b/debian.master/changelog
> @@ -1,3 +1,12 @@
> +linux (2.6.35-24.42qemui386) maverick-proposed; urgency=low
> +
> +  [ Avi Kivity ]
> +
> +  * [Upstream] KVM: x86 emulator: fix regression with cmpxchg8b on i386 hosts
> +    - LP: #688085
> +
> + -- Serge Hallyn<serge.hallyn@ubuntu.com>   Wed, 05 Jan 2011 15:06:07 +0000
> +
>   linux (2.6.35-24.42) maverick-proposed; urgency=low
>
>     [ Brad Figg ]

This already appears to have been committed to Maverick master-next via 
2.6.35.9 stable.

---
Tim Gardner tim.gardner@canonical.com
diff mbox

Patch

diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index 0b2729b..2cd35d5 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -143,7 +143,15 @@  struct x86_emulate_ops {
 struct operand {
 	enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type;
 	unsigned int bytes;
-	unsigned long val, orig_val, *ptr;
+	unsigned long *ptr;
+	union {
+		unsigned long orig_val;
+		u64 orig_val64;
+	};
+	union {
+		unsigned long val;
+		u64 val64;
+	};
 };
 
 struct fetch_cache {
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 715a7fa..abb677a 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1712,7 +1712,7 @@  static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
 			       struct x86_emulate_ops *ops)
 {
 	struct decode_cache *c = &ctxt->decode;
-	u64 old = c->dst.orig_val;
+	u64 old = c->dst.orig_val64;
 
 	if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) ||
 	    ((u32) (old >> 32) != (u32) c->regs[VCPU_REGS_RDX])) {
@@ -1721,7 +1721,7 @@  static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
 		c->regs[VCPU_REGS_RDX] = (u32) (old >> 32);
 		ctxt->eflags &= ~EFLG_ZF;
 	} else {
-		c->dst.val = ((u64)c->regs[VCPU_REGS_RCX] << 32) |
+		c->dst.val64 = ((u64)c->regs[VCPU_REGS_RCX] << 32) |
 		       (u32) c->regs[VCPU_REGS_RBX];
 
 		ctxt->eflags |= EFLG_ZF;
@@ -2535,7 +2535,7 @@  x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
 					ctxt->vcpu);
 		if (rc != X86EMUL_CONTINUE)
 			goto done;
-		c->src.orig_val = c->src.val;
+		c->src.orig_val64 = c->src.val64;
 	}
 
 	if (c->src2.type == OP_MEM) {
diff --git a/debian.master/changelog b/debian.master/changelog
index f8a29cc..2df896c 100644
--- a/debian.master/changelog
+++ b/debian.master/changelog
@@ -1,3 +1,12 @@ 
+linux (2.6.35-24.42qemui386) maverick-proposed; urgency=low
+
+  [ Avi Kivity ]
+
+  * [Upstream] KVM: x86 emulator: fix regression with cmpxchg8b on i386 hosts
+    - LP: #688085
+
+ -- Serge Hallyn <serge.hallyn@ubuntu.com>  Wed, 05 Jan 2011 15:06:07 +0000
+
 linux (2.6.35-24.42) maverick-proposed; urgency=low
 
   [ Brad Figg ]