From patchwork Wed Nov 30 20:03:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Mattson X-Patchwork-Id: 9454795 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8DB6560756 for ; Wed, 30 Nov 2016 20:05:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8144F2849F for ; Wed, 30 Nov 2016 20:05:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 76504284A4; Wed, 30 Nov 2016 20:05:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0F3B4284A1 for ; Wed, 30 Nov 2016 20:05:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755164AbcK3UE7 (ORCPT ); Wed, 30 Nov 2016 15:04:59 -0500 Received: from mail-pg0-f47.google.com ([74.125.83.47]:34286 "EHLO mail-pg0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758126AbcK3UEp (ORCPT ); Wed, 30 Nov 2016 15:04:45 -0500 Received: by mail-pg0-f47.google.com with SMTP id x23so85531667pgx.1 for ; Wed, 30 Nov 2016 12:04:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=50K2Lz7aQXldH6g/RfZAVIL5QHKRCxPxMAG8oMkhE6c=; b=pUIYvYzpWY/jh1ac29wTZyRDhipZvuyhKT0SwxueOlDGCDT5030o6LNLJgQeDWrNSv JMIr1kNIpjI8t7GvC+oQ9dHxzA5TtiS+xLa8uZayn2EugUn90BZNeiy+qeWU4jHtJrlA OnPcTq5LsAD/4VBcRJq0eyvPvHwoV1wPw1goRHj1/QE2TBoOKRefMo1uqW/1sELk1K2b 4PW1JIw0mB2ldwBknWORtlETI4uDdRk1KGdo2wpIwIKe+DSs8vEMvSgznEHxgRrlCerX 5h+7o0L1yJnYxSZWgZD6XSoGB5t962KjOzHwfsuH8XYfvVCgP5KnVc/JTg5tIdOL7PHd nGjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=50K2Lz7aQXldH6g/RfZAVIL5QHKRCxPxMAG8oMkhE6c=; b=L7EV5nlwh7cMQ78Vu5IXYl12/LgZv1DkUDM6SS+zAroHtFLXsxFvEbpbGzMVEa7P3q kY17BnM0TWYZoFJz9yakP2ah45e3ef3eYjg4uhOXsUEtsz4LfwzAKYfZdgSrZsqj5w80 OSbPEh+FSTg0LZyb4aYa6g9+jOH5JOnJyoRQVTfS7EtqimZrOzhKUS9Rwfg+lCZF6YQ3 BcTl+Tr8v1Kj2g/DTqAMB3JrKv3Wjf4BxwKnnm8eunOdP74ZTaCn3Jl20Ve7WYzFcDZ9 8sZH97lMvGB4y71b+gPsklXR6GJNNacLCpqdg6/o8/6MtQ/6Htj6tTcQ1wtNmVyrP5Y7 ClZw== X-Gm-Message-State: AKaTC00yOaaW1K3IWJ14tldvV42INBcwo2lFgmYSUB2TuR6wBXC/3EwXC6JjLHeANF5RQUNF X-Received: by 10.99.125.65 with SMTP id m1mr63209958pgn.159.1480536282528; Wed, 30 Nov 2016 12:04:42 -0800 (PST) Received: from jmattson.sea.corp.google.com ([100.100.206.154]) by smtp.gmail.com with ESMTPSA id w24sm104811079pfa.9.2016.11.30.12.04.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 30 Nov 2016 12:04:41 -0800 (PST) From: Jim Mattson To: kvm@vger.kernel.org Cc: Jim Mattson Subject: [PATCH 6/8] kvm: nVMX: Refactor nested_vmx_run() Date: Wed, 30 Nov 2016 12:03:47 -0800 Message-Id: <1480536229-11754-7-git-send-email-jmattson@google.com> X-Mailer: git-send-email 2.8.0.rc3.226.g39d4020 In-Reply-To: <1480536229-11754-1-git-send-email-jmattson@google.com> References: <1480536229-11754-1-git-send-email-jmattson@google.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Nested_vmx_run is split into two parts: the part that handles the VMLAUNCH/VMRESUME instruction, and the part that modifies the vcpu state to transition from VMX root mode to VMX non-root mode. The latter will be used when restoring the checkpointed state of a vCPU that was in VMX operation when a snapshot was taken. Signed-off-by: Jim Mattson --- arch/x86/kvm/vmx.c | 98 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 43 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 8b12461..9f0c747 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -10237,6 +10237,58 @@ static int check_vmentry_postreqs(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, return 0; } +static int enter_vmx_non_root_mode(struct kvm_vcpu *vcpu) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + struct vmcs12 *vmcs12 = get_vmcs12(vcpu); + struct loaded_vmcs *vmcs02; + int cpu; + u32 msr_entry_idx; + + vmcs02 = nested_get_current_vmcs02(vmx); + if (!vmcs02) + return -ENOMEM; + + enter_guest_mode(vcpu); + + if (!(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS)) + vmx->nested.vmcs01_debugctl = vmcs_read64(GUEST_IA32_DEBUGCTL); + + cpu = get_cpu(); + vmx->loaded_vmcs = vmcs02; + vmx_vcpu_put(vcpu); + vmx_vcpu_load(vcpu, cpu); + vcpu->cpu = cpu; + put_cpu(); + + vmx_segment_cache_clear(vmx); + + prepare_vmcs02(vcpu, vmcs12); + + nested_get_vmcs12_pages(vcpu, vmcs12); + + msr_entry_idx = nested_vmx_load_msr(vcpu, + vmcs12->vm_entry_msr_load_addr, + vmcs12->vm_entry_msr_load_count); + if (msr_entry_idx) { + leave_guest_mode(vcpu); + vmx_load_vmcs01(vcpu); + nested_vmx_entry_failure(vcpu, vmcs12, + EXIT_REASON_MSR_LOAD_FAIL, msr_entry_idx); + return 1; + } + + vmcs12->launch_state = 1; + + /* + * Note no nested_vmx_succeed or nested_vmx_fail here. At this point + * we are no longer running L1, and VMLAUNCH/VMRESUME has not yet + * returned as far as L1 is concerned. It will only return (and set + * the success flag) when L2 exits (see nested_vmx_vmexit()). + */ + return 0; +} + /* * nested_vmx_run() handles a nested entry, i.e., a VMLAUNCH or VMRESUME on L1 * for running an L2 nested guest. @@ -10245,9 +10297,6 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) { struct vmcs12 *vmcs12; struct vcpu_vmx *vmx = to_vmx(vcpu); - int cpu; - struct loaded_vmcs *vmcs02; - u32 msr_entry_idx; u32 exit_qual; int ret; @@ -10296,54 +10345,17 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) * the nested entry. */ - vmcs02 = nested_get_current_vmcs02(vmx); - if (!vmcs02) - return -ENOMEM; - - enter_guest_mode(vcpu); - vmx->nested.nested_run_pending = 1; - if (!(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS)) - vmx->nested.vmcs01_debugctl = vmcs_read64(GUEST_IA32_DEBUGCTL); - - cpu = get_cpu(); - vmx->loaded_vmcs = vmcs02; - vmx_vcpu_put(vcpu); - vmx_vcpu_load(vcpu, cpu); - vcpu->cpu = cpu; - put_cpu(); - - vmx_segment_cache_clear(vmx); - - prepare_vmcs02(vcpu, vmcs12); - - nested_get_vmcs12_pages(vcpu, vmcs12); - - msr_entry_idx = nested_vmx_load_msr(vcpu, - vmcs12->vm_entry_msr_load_addr, - vmcs12->vm_entry_msr_load_count); - if (msr_entry_idx) { - leave_guest_mode(vcpu); - vmx_load_vmcs01(vcpu); - nested_vmx_entry_failure(vcpu, vmcs12, - EXIT_REASON_MSR_LOAD_FAIL, msr_entry_idx); - return 1; - } - - vmcs12->launch_state = 1; + ret = enter_vmx_non_root_mode(vcpu); + if (ret) + return ret; if (unlikely(vmcs12->guest_activity_state == GUEST_ACTIVITY_HLT)) { vmx->nested.nested_run_pending = 0; return kvm_vcpu_halt(vcpu); } - /* - * Note no nested_vmx_succeed or nested_vmx_fail here. At this point - * we are no longer running L1, and VMLAUNCH/VMRESUME has not yet - * returned as far as L1 is concerned. It will only return (and set - * the success flag) when L2 exits (see nested_vmx_vmexit()). - */ return 1; }