From patchwork Sun May 19 04:52:25 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Nakajima, Jun" X-Patchwork-Id: 2589691 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 13C3E40276 for ; Sun, 19 May 2013 04:52:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751808Ab3ESEw4 (ORCPT ); Sun, 19 May 2013 00:52:56 -0400 Received: from mail-pd0-f176.google.com ([209.85.192.176]:55935 "EHLO mail-pd0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751371Ab3ESEwr (ORCPT ); Sun, 19 May 2013 00:52:47 -0400 Received: by mail-pd0-f176.google.com with SMTP id r11so1157071pdi.35 for ; Sat, 18 May 2013 21:52:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:x-gm-message-state; bh=IXkI+o1XS654jcsdLwD2c+1sTq0cxCd7dRD4AKtjILo=; b=VI3o/qR4OIhxHTeysXb5oopS6ZFd76sw0CJItGTYO+RS1dwEaS+kQozQfZN2yNK8Zf RhhzMqXyeC6Z+QZQ2Dk+Pviqr3+aIMLTmt8dhSMe/6YwLn7BvuXPNQqBz2uBhdrHqZPn jleudxJ14CNBKkVkBLQ/GfHcvB/wZs0x5RFOq+eO2NSEaQ4iQfEYSE8vJZ0gmPW8GLPU gHeCZjc+mKKxwSGoiqAGK3Stl8m2EHGfEsmDTTrF97JYvLMPQnSxNGdEV3oA1Oc7Qm+M 4ooxHhyJUQ9dScA0IWDo+dshORufVSJjvyy+ZV0BJMeClYg+destmvAg38Ik4Di8ruWS L5Kw== X-Received: by 10.68.135.231 with SMTP id pv7mr54356260pbb.108.1368939167214; Sat, 18 May 2013 21:52:47 -0700 (PDT) Received: from localhost (c-98-207-34-191.hsd1.ca.comcast.net. [98.207.34.191]) by mx.google.com with ESMTPSA id ea15sm19597478pad.16.2013.05.18.21.52.45 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Sat, 18 May 2013 21:52:46 -0700 (PDT) From: Jun Nakajima To: kvm@vger.kernel.org Cc: Gleb Natapov , Paolo Bonzini Subject: [PATCH v3 06/13] nEPT: Fix cr3 handling in nested exit and entry Date: Sat, 18 May 2013 21:52:25 -0700 Message-Id: <1368939152-11406-6-git-send-email-jun.nakajima@intel.com> X-Mailer: git-send-email 1.8.2.1.610.g562af5b In-Reply-To: <1368939152-11406-1-git-send-email-jun.nakajima@intel.com> References: <1368939152-11406-1-git-send-email-jun.nakajima@intel.com> X-Gm-Message-State: ALoCoQnZ8aeaNpipvpLr3EmWGxNXE72yKezGACNNU1icQCoZBceLDkbFoRYksV3XkSLxyDxMRvAg Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org From: Nadav Har'El The existing code for handling cr3 and related VMCS fields during nested exit and entry wasn't correct in all cases: If L2 is allowed to control cr3 (and this is indeed the case in nested EPT), during nested exit we must copy the modified cr3 from vmcs02 to vmcs12, and we forgot to do so. This patch adds this copy. If L0 isn't controlling cr3 when running L2 (i.e., L0 is using EPT), and whoever does control cr3 (L1 or L2) is using PAE, the processor might have saved PDPTEs and we should also save them in vmcs12 (and restore later). Signed-off-by: Nadav Har'El Signed-off-by: Jun Nakajima Signed-off-by: Xinhao Xu Reviewed-by: Paolo Bonzini --- arch/x86/kvm/vmx.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index a88432f..b79efd4 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -7608,6 +7608,17 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) kvm_set_cr3(vcpu, vmcs12->guest_cr3); kvm_mmu_reset_context(vcpu); + /* + * Additionally, except when L0 is using shadow page tables, L1 or + * L2 control guest_cr3 for L2, so they may also have saved PDPTEs + */ + if (enable_ept) { + vmcs_write64(GUEST_PDPTR0, vmcs12->guest_pdptr0); + vmcs_write64(GUEST_PDPTR1, vmcs12->guest_pdptr1); + vmcs_write64(GUEST_PDPTR2, vmcs12->guest_pdptr2); + vmcs_write64(GUEST_PDPTR3, vmcs12->guest_pdptr3); + } + kvm_register_write(vcpu, VCPU_REGS_RSP, vmcs12->guest_rsp); kvm_register_write(vcpu, VCPU_REGS_RIP, vmcs12->guest_rip); } @@ -7930,6 +7941,25 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) vmcs12->guest_pending_dbg_exceptions = vmcs_readl(GUEST_PENDING_DBG_EXCEPTIONS); + /* + * In some cases (usually, nested EPT), L2 is allowed to change its + * own CR3 without exiting. If it has changed it, we must keep it. + * Of course, if L0 is using shadow page tables, GUEST_CR3 was defined + * by L0, not L1 or L2, so we mustn't unconditionally copy it to vmcs12. + */ + if (enable_ept) + vmcs12->guest_cr3 = vmcs_read64(GUEST_CR3); + /* + * Additionally, except when L0 is using shadow page tables, L1 or + * L2 control guest_cr3 for L2, so save their PDPTEs + */ + if (enable_ept) { + vmcs12->guest_pdptr0 = vmcs_read64(GUEST_PDPTR0); + vmcs12->guest_pdptr1 = vmcs_read64(GUEST_PDPTR1); + vmcs12->guest_pdptr2 = vmcs_read64(GUEST_PDPTR2); + vmcs12->guest_pdptr3 = vmcs_read64(GUEST_PDPTR3); + } + vmcs12->vm_entry_controls = (vmcs12->vm_entry_controls & ~VM_ENTRY_IA32E_MODE) | (vmcs_read32(VM_ENTRY_CONTROLS) & VM_ENTRY_IA32E_MODE);