Received: by 2002:a05:6a10:9afc:0:0:0:0 with SMTP id t28csp2238915pxm; Fri, 4 Mar 2022 12:05:39 -0800 (PST) X-Google-Smtp-Source: ABdhPJxuRpbJgQeEWlo4vt+XeKHvLm8W1xPsCgMCZmwP7w9e1L1H2lrCNVB4x5sAMusTGFQWp2Y+ X-Received: by 2002:a17:907:1c83:b0:6da:7ac5:4ad5 with SMTP id nb3-20020a1709071c8300b006da7ac54ad5mr371520ejc.258.1646424339239; Fri, 04 Mar 2022 12:05:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1646424339; cv=none; d=google.com; s=arc-20160816; b=mX2gIylbVjkvzjy5nmTfC596uxQ8dzdQtGP+gBD2fQppDzXbq88mN+eeBJXJLaX/CG dXoHZfhJHhBszqzer+jyAom/oK8UDquIXu1WHOmds4NR1V/ZPWAryyBsvA4Yxh3amYQJ I6KPifAkJ4c/E1PbDB4l6h1y4eF+uPTiPuvPwCsyDXEYLUZ+5XLVS3+SAJhyWfI4P3Ku CBW9vbUSC484upPrk3yCAUiTKROSuboe/ddlgmpc3kFILe5Dk3S9nHkAzPEswjIrN6OA iQam+pMpCfJC9T8s9ia7H2NawrzEDrQjZbujH5tGXQfIqLf0adF6KfJgJWI0z4w3Iydp SdCg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=6UJbAa4uUFW8H2rnDd7v9bZ8iCO07t1P2czt5G8s/aE=; b=hLE/Er95hsaKosIjPIvMTEPcAj7DZvVPwZgamp5ouFoYK7vmFAAh7x8GHwcuokyg5z R2Tz/lcP+lLeNd5TmQ98LyY0DPthUydm7KCKTRz7SZletY+XMSYhUdaSjitdzmji0uom Io2wK1waWXt9V1uIm41d4KfPKbXtu3ht+VRBdsO3rlFEbh2vpSuTdU2BtqopehhQx5WW X1m5/bk3tzLkh4+niKUBabOlv71PofKOxcQwxX/fy8OB1l3CUoPYE4hlj3cL1efk8MFg tkimiZyK3mdrG5g/jFJhOmSxDe1T6WJpit5Cb9gp6ZB/tLCIu2Hyb5ocoJaW62PePysP U6VQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=VdHlkU1s; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id sg20-20020a170907a41400b006dad7cb420fsi1335322ejc.949.2022.03.04.12.05.14; Fri, 04 Mar 2022 12:05:39 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=VdHlkU1s; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229787AbiCDUFg (ORCPT + 99 others); Fri, 4 Mar 2022 15:05:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52780 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230124AbiCDUFO (ORCPT ); Fri, 4 Mar 2022 15:05:14 -0500 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B4046182D92; Fri, 4 Mar 2022 12:00:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1646424031; x=1677960031; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=fb2KvTRU7rIHvCP5yebX8Jhd5QOb8UuSL1UU7dgcIuc=; b=VdHlkU1s0hZrkyCASkbqF2HLmho3dRJu0gkyRuNAdH6qUKnq1QAE1Ai5 g3NzQLDEYnNubGvtqumk5pEY9bhIYhFu8tPAx0DxZSfFLRqWBgKeIeRpn jUMe5rhzS8tK4gPhMfXCKFVLON1CHTSJDwUP034DXrSjNSbieXb6YosC9 6I+x5ngbo7dFO3m0EpORUZolmLq8G+hbToifsppc/4uWCve+Q1go+mkza vbIyZ7uyFwDzKWbPJw7pAW+W86V/VawtKFmCBGrIkkpreXgR/Cm0sVMce ZG4kgxyEEpc4WHICArBRsM6oDxeokREi8ZohCZWf/iVCz5bRmh/WeplwG g==; X-IronPort-AV: E=McAfee;i="6200,9189,10276"; a="253983293" X-IronPort-AV: E=Sophos;i="5.90,156,1643702400"; d="scan'208";a="253983293" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Mar 2022 11:50:04 -0800 X-IronPort-AV: E=Sophos;i="5.90,156,1643702400"; d="scan'208";a="552344081" Received: from ls.sc.intel.com (HELO localhost) ([143.183.96.54]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Mar 2022 11:50:03 -0800 From: isaku.yamahata@intel.com To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: isaku.yamahata@intel.com, isaku.yamahata@gmail.com, Paolo Bonzini , Jim Mattson , erdemaktas@google.com, Connor Kuehl , Sean Christopherson Subject: [RFC PATCH v5 005/104] KVM: x86: Refactor KVM VMX module init/exit functions Date: Fri, 4 Mar 2022 11:48:21 -0800 Message-Id: <8a8ec76f1700114d739623b2860630eacd277ab6.1646422845.git.isaku.yamahata@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-4.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Isaku Yamahata Currently, KVM VMX module initialization/exit functions are a single function each. Refactor KVM VMX module initialization functions into KVM common part and VMX part so that TDX specific part can be added cleanly. Opportunistically refactor module exit function as well. The current module initialization flow is, 1.) calculate the sizes of VMX kvm structure and VMX vcpu structure, 2.) report those sizes to the KVM common layer and KVM common initialization, and 3.) VMX specific system-wide initialization. Refactor the KVM VMX module initialization function into functions with a wrapper function to separate VMX logic in vmx.c from a file, main.c, common among VMX and TDX. We have a wrapper function, "vt_init() {vmx_pre_kvm_init(); kvm_init(); vmx_init(); }" in main.c, and vmx_pre_kvm_init() and vmx_init() in vmx.c. vmx_pre_kvm_init() calculates the sizes of VMX kvm structure and KVM vcpu structure, kvm_init() does system-wide initialization of the KVM common layer, and vmx_init() does system-wide VMX initialization. The KVM architecture common layer allocates struct kvm with reported size for architecture-specific code. The KVM VMX module defines its structure as struct vmx_kvm { struct kvm; VMX specific members;} and uses it as struct vmx kvm. Similar for vcpu structure. TDX KVM patches will define TDX specific kvm and vcpu structures, add tdx_pre_kvm_init() to report the sizes of them to the KVM common layer. The current module exit function is also a single function, a combination of VMX specific logic and common KVM logic. Refactor it into VMX specific logic and KVM common logic. This is just refactoring to keep the VMX specific logic in vmx.c from main.c. Signed-off-by: Isaku Yamahata --- arch/x86/kvm/vmx/main.c | 33 +++++++++++++ arch/x86/kvm/vmx/vmx.c | 97 +++++++++++++++++++------------------- arch/x86/kvm/vmx/x86_ops.h | 5 +- 3 files changed, 86 insertions(+), 49 deletions(-) diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c index b79fcc8d81dd..8ff13c7881f2 100644 --- a/arch/x86/kvm/vmx/main.c +++ b/arch/x86/kvm/vmx/main.c @@ -165,3 +165,36 @@ struct kvm_x86_init_ops vt_init_ops __initdata = { .runtime_ops = &vt_x86_ops, }; + +static int __init vt_init(void) +{ + unsigned int vcpu_size = 0, vcpu_align = 0; + int r; + + vmx_pre_kvm_init(&vcpu_size, &vcpu_align); + + r = kvm_init(&vt_init_ops, vcpu_size, vcpu_align, THIS_MODULE); + if (r) + goto err_vmx_post_exit; + + r = vmx_init(); + if (r) + goto err_kvm_exit; + + return 0; + +err_kvm_exit: + kvm_exit(); +err_vmx_post_exit: + vmx_post_kvm_exit(); + return r; +} +module_init(vt_init); + +static void vt_exit(void) +{ + vmx_exit(); + kvm_exit(); + vmx_post_kvm_exit(); +} +module_exit(vt_exit); diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index f6f5d0dac579..7838cd177f0e 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7929,47 +7929,12 @@ static void vmx_cleanup_l1d_flush(void) l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_AUTO; } -static void vmx_exit(void) +void __init vmx_pre_kvm_init(unsigned int *vcpu_size, unsigned int *vcpu_align) { -#ifdef CONFIG_KEXEC_CORE - RCU_INIT_POINTER(crash_vmclear_loaded_vmcss, NULL); - synchronize_rcu(); -#endif - - kvm_exit(); - -#if IS_ENABLED(CONFIG_HYPERV) - if (static_branch_unlikely(&enable_evmcs)) { - int cpu; - struct hv_vp_assist_page *vp_ap; - /* - * Reset everything to support using non-enlightened VMCS - * access later (e.g. when we reload the module with - * enlightened_vmcs=0) - */ - for_each_online_cpu(cpu) { - vp_ap = hv_get_vp_assist_page(cpu); - - if (!vp_ap) - continue; - - vp_ap->nested_control.features.directhypercall = 0; - vp_ap->current_nested_vmcs = 0; - vp_ap->enlighten_vmentry = 0; - } - - static_branch_disable(&enable_evmcs); - } -#endif - vmx_cleanup_l1d_flush(); - - allow_smaller_maxphyaddr = false; -} -module_exit(vmx_exit); - -static int __init vmx_init(void) -{ - int r, cpu; + if (sizeof(struct vcpu_vmx) > *vcpu_size) + *vcpu_size = sizeof(struct vcpu_vmx); + if (__alignof__(struct vcpu_vmx) > *vcpu_align) + *vcpu_align = __alignof__(struct vcpu_vmx); #if IS_ENABLED(CONFIG_HYPERV) /* @@ -8004,11 +7969,38 @@ static int __init vmx_init(void) enlightened_vmcs = false; } #endif +} - r = kvm_init(&vt_init_ops, sizeof(struct vcpu_vmx), - __alignof__(struct vcpu_vmx), THIS_MODULE); - if (r) - return r; +void vmx_post_kvm_exit(void) +{ +#if IS_ENABLED(CONFIG_HYPERV) + if (static_branch_unlikely(&enable_evmcs)) { + int cpu; + struct hv_vp_assist_page *vp_ap; + /* + * Reset everything to support using non-enlightened VMCS + * access later (e.g. when we reload the module with + * enlightened_vmcs=0) + */ + for_each_online_cpu(cpu) { + vp_ap = hv_get_vp_assist_page(cpu); + + if (!vp_ap) + continue; + + vp_ap->nested_control.features.directhypercall = 0; + vp_ap->current_nested_vmcs = 0; + vp_ap->enlighten_vmentry = 0; + } + + static_branch_disable(&enable_evmcs); + } +#endif +} + +int __init vmx_init(void) +{ + int r, cpu; /* * Must be called after kvm_init() so enable_ept is properly set @@ -8018,10 +8010,8 @@ static int __init vmx_init(void) * mitigation mode. */ r = vmx_setup_l1d_flush(vmentry_l1d_flush_param); - if (r) { - vmx_exit(); + if (r) return r; - } for_each_possible_cpu(cpu) { INIT_LIST_HEAD(&per_cpu(loaded_vmcss_on_cpu, cpu)); @@ -8045,4 +8035,15 @@ static int __init vmx_init(void) return 0; } -module_init(vmx_init); + +void vmx_exit(void) +{ +#ifdef CONFIG_KEXEC_CORE + RCU_INIT_POINTER(crash_vmclear_loaded_vmcss, NULL); + synchronize_rcu(); +#endif + + vmx_cleanup_l1d_flush(); + + allow_smaller_maxphyaddr = false; +} diff --git a/arch/x86/kvm/vmx/x86_ops.h b/arch/x86/kvm/vmx/x86_ops.h index ccf98e79d8c3..7da541e1c468 100644 --- a/arch/x86/kvm/vmx/x86_ops.h +++ b/arch/x86/kvm/vmx/x86_ops.h @@ -8,7 +8,10 @@ #include "x86.h" -extern struct kvm_x86_init_ops vt_init_ops __initdata; +void __init vmx_pre_kvm_init(unsigned int *vcpu_size, unsigned int *vcpu_align); +int __init vmx_init(void); +void vmx_exit(void); +void vmx_post_kvm_exit(void); __init int vmx_cpu_has_kvm_support(void); __init int vmx_disabled_by_bios(void); -- 2.25.1