From patchwork Mon Jul 22 17:29:41 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Orit Wasserman X-Patchwork-Id: 260773 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id DCCA52C007C for ; Tue, 23 Jul 2013 03:30:27 +1000 (EST) Received: from localhost ([::1]:48979 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V1JwH-0003dt-Bl for incoming@patchwork.ozlabs.org; Mon, 22 Jul 2013 13:30:25 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48813) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V1Juc-00016I-9N for qemu-devel@nongnu.org; Mon, 22 Jul 2013 13:28:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V1Jua-0001Rh-Qr for qemu-devel@nongnu.org; Mon, 22 Jul 2013 13:28:42 -0400 Received: from mx1.redhat.com ([209.132.183.28]:32821) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V1Jua-0001RZ-DP for qemu-devel@nongnu.org; Mon, 22 Jul 2013 13:28:40 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r6MHSdbI011319 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 22 Jul 2013 13:28:39 -0400 Received: from dhcp-1-120.tlv.redhat.com (vpn-201-41.tlv.redhat.com [10.35.201.41]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r6MHSWWG000983; Mon, 22 Jul 2013 13:28:36 -0400 From: Orit Wasserman To: qemu-devel@nongnu.org Date: Mon, 22 Jul 2013 20:29:41 +0300 Message-Id: <1374514182-24808-2-git-send-email-owasserm@redhat.com> In-Reply-To: <1374514182-24808-1-git-send-email-owasserm@redhat.com> References: <1374514182-24808-1-git-send-email-owasserm@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: aliguori@us.ibm.com, ehabkost@redhat.com, gleb@redhat.com, quintela@redhat.com, mtosatti@redhat.com, Orit Wasserman , pbonzini@redhat.com, afaerber@suse.de Subject: [Qemu-devel] [PATCH v3 1/2] Fix real mode guest migration X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Older KVM versions save CS dpl value to an invalid value for real mode guests (0x3). This patch detect this situation when loading CPU state and set all the segments dpl to zero. This will allow migration from older KVM on host without unrestricted guest to hosts with restricted guest support. For example migration from a Penryn host (with kernel 2.6.32) to a Westmere host (for real mode guest) will fail with "kvm: unhandled exit 80000021". Signed-off-by: Orit Wasserman Reviewed-by: Juan Quintela --- target-i386/machine.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/target-i386/machine.c b/target-i386/machine.c index 3659db9..af4c167 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -260,6 +260,24 @@ static int cpu_post_load(void *opaque, int version_id) CPUX86State *env = &cpu->env; int i; + /* + * Real mode guest segments register DPL should be zero. + * Older KVM version were setting it wrongly. + * Fixing it will allow live migration from such host that don't have + * restricted guest support to a host with unrestricted guest support + * (otherwise the migration will fail with invalid guest state + * error). + */ + if (!(env->cr[0] & CR0_PE_MASK) && + (env->segs[R_CS].flags >> DESC_DPL_SHIFT & 3) != 0) { + env->segs[R_CS].flags &= ~(env->segs[R_CS].flags & DESC_DPL_MASK); + env->segs[R_DS].flags &= ~(env->segs[R_DS].flags & DESC_DPL_MASK); + env->segs[R_ES].flags &= ~(env->segs[R_ES].flags & DESC_DPL_MASK); + env->segs[R_FS].flags &= ~(env->segs[R_FS].flags & DESC_DPL_MASK); + env->segs[R_GS].flags &= ~(env->segs[R_GS].flags & DESC_DPL_MASK); + env->segs[R_SS].flags &= ~(env->segs[R_SS].flags & DESC_DPL_MASK); + } + /* XXX: restore FPU round state */ env->fpstt = (env->fpus_vmstate >> 11) & 7; env->fpus = env->fpus_vmstate & ~0x3800;