9ae3a8
From c576ee9550d38273808c2055803f3a254655753e Mon Sep 17 00:00:00 2001
9ae3a8
From: Orit Wasserman <owasserm@redhat.com>
9ae3a8
Date: Wed, 9 Oct 2013 10:09:10 +0200
9ae3a8
Subject: [PATCH 15/25] Fix real mode guest migration
9ae3a8
9ae3a8
RH-Author: Orit Wasserman <owasserm@redhat.com>
9ae3a8
Message-id: <1381313355-15641-6-git-send-email-owasserm@redhat.com>
9ae3a8
Patchwork-id: 54801
9ae3a8
O-Subject: [RHEL7.0 qemu-kvm v2 05/10] Fix real mode guest migration
9ae3a8
Bugzilla: 921465
9ae3a8
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
RH-Acked-by: Juan Quintela <quintela@redhat.com>
9ae3a8
9ae3a8
Older KVM versions save CS dpl value to an invalid value for real mode guests
9ae3a8
(0x3). This patch detect this situation when loading CPU state and set all the
9ae3a8
segments dpl to zero.
9ae3a8
This will allow migration from older KVM on host without unrestricted guest
9ae3a8
to hosts with restricted guest support.
9ae3a8
For example migration from a Penryn host (with kernel 2.6.32) to
9ae3a8
a Westmere host (for real mode guest) will fail with "kvm: unhandled exit 80000021".
9ae3a8
9ae3a8
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
9ae3a8
Reviewed-by: Juan Quintela <quintela@redhat.com>
9ae3a8
Signed-off-by: Juan Quintela <quintela@redhat.com>
9ae3a8
(cherry picked from commit 444ba6797ef6ef331fe9fd34309b1ec59caaede3)
9ae3a8
---
9ae3a8
 target-i386/machine.c | 18 ++++++++++++++++++
9ae3a8
 1 file changed, 18 insertions(+)
9ae3a8
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 target-i386/machine.c |   18 ++++++++++++++++++
9ae3a8
 1 files changed, 18 insertions(+), 0 deletions(-)
9ae3a8
9ae3a8
diff --git a/target-i386/machine.c b/target-i386/machine.c
9ae3a8
index ecf1617..079a132 100644
9ae3a8
--- a/target-i386/machine.c
9ae3a8
+++ b/target-i386/machine.c
9ae3a8
@@ -260,6 +260,24 @@ static int cpu_post_load(void *opaque, int version_id)
9ae3a8
     CPUX86State *env = &cpu->env;
9ae3a8
     int i;
9ae3a8
 
9ae3a8
+    /*
9ae3a8
+     * Real mode guest segments register DPL should be zero.
9ae3a8
+     * Older KVM version were setting it wrongly.
9ae3a8
+     * Fixing it will allow live migration from such host that don't have
9ae3a8
+     * restricted guest support to a host with unrestricted guest support
9ae3a8
+     * (otherwise the migration will fail with invalid guest state
9ae3a8
+     * error).
9ae3a8
+     */
9ae3a8
+    if (!(env->cr[0] & CR0_PE_MASK) &&
9ae3a8
+        (env->segs[R_CS].flags >> DESC_DPL_SHIFT & 3) != 0) {
9ae3a8
+        env->segs[R_CS].flags &= ~(env->segs[R_CS].flags & DESC_DPL_MASK);
9ae3a8
+        env->segs[R_DS].flags &= ~(env->segs[R_DS].flags & DESC_DPL_MASK);
9ae3a8
+        env->segs[R_ES].flags &= ~(env->segs[R_ES].flags & DESC_DPL_MASK);
9ae3a8
+        env->segs[R_FS].flags &= ~(env->segs[R_FS].flags & DESC_DPL_MASK);
9ae3a8
+        env->segs[R_GS].flags &= ~(env->segs[R_GS].flags & DESC_DPL_MASK);
9ae3a8
+        env->segs[R_SS].flags &= ~(env->segs[R_SS].flags & DESC_DPL_MASK);
9ae3a8
+    }
9ae3a8
+
9ae3a8
     /* XXX: restore FPU round state */
9ae3a8
     env->fpstt = (env->fpus_vmstate >> 11) & 7;
9ae3a8
     env->fpus = env->fpus_vmstate & ~0x3800;
9ae3a8
-- 
9ae3a8
1.7.1
9ae3a8