From patchwork Tue Oct 20 07:50:40 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Lalancette X-Patchwork-Id: 54899 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n9K7oi3v025552 for ; Tue, 20 Oct 2009 07:50:44 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751062AbZJTHui (ORCPT ); Tue, 20 Oct 2009 03:50:38 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751067AbZJTHui (ORCPT ); Tue, 20 Oct 2009 03:50:38 -0400 Received: from mx1.redhat.com ([209.132.183.28]:17733 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751036AbZJTHuh (ORCPT ); Tue, 20 Oct 2009 03:50:37 -0400 Received: from int-mx05.intmail.prod.int.phx2.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.18]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n9K7ogYw007795 for ; Tue, 20 Oct 2009 03:50:42 -0400 Received: from localhost.localdomain (vpn-12-49.rdu.redhat.com [10.11.12.49]) by int-mx05.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id n9K7oeU5023566; Tue, 20 Oct 2009 03:50:41 -0400 From: Chris Lalancette To: kvm@vger.kernel.org Cc: Chris Lalancette Subject: [PATCH] Fix up vmx_set_segment for booting older guests. Date: Tue, 20 Oct 2009 09:50:40 +0200 Message-Id: <1256025040-4941-1-git-send-email-clalance@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.18 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 364263a..311afd4 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1846,7 +1846,22 @@ static void vmx_set_segment(struct kvm_vcpu *vcpu, vmx->rmode.tr.ar = vmx_segment_access_rights(var); return; } - vmcs_writel(sf->base, var->base); + + /* Intel 64 and IA-32 Architecture Software Developer's Manual Vol. 3b, + * section 22.3.1.2 states that VMENTRY will fail if bits 63:32 of the + * base address for CS, SS, DS, ES are not 0 and the register is usable. + * + * If var->base happens to have bit 31 set, then it will get sign + * extended on the vmcs_writel(), causing this check to fail. Make + * sure to use the 32-bit version where appropriate. + */ + if (sf->base == GUEST_CS_BASE || + ((~sf->ar_bytes & 0x00010000) && (sf->base == GUEST_SS_BASE || + sf->base == GUEST_DS_BASE || + sf->base == GUEST_ES_BASE))) + vmcs_write32(sf->base, var->base); + else + vmcs_writel(sf->base, var->base); vmcs_write32(sf->limit, var->limit); vmcs_write16(sf->selector, var->selector); if (vmx->rmode.vm86_active && var->s) {