Received: by 2002:a6b:500f:0:0:0:0:0 with SMTP id e15csp4763447iob; Mon, 9 May 2022 00:37:43 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxI12zlvkg8ExrnqPiE2cIAXG5CbQNCI1VsUNejWmIro4/Rbht5v+DeIkjaocm0cm3SoIRr X-Received: by 2002:a17:90b:380f:b0:1dc:d54b:1888 with SMTP id mq15-20020a17090b380f00b001dcd54b1888mr16781838pjb.228.1652081863522; Mon, 09 May 2022 00:37:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1652081863; cv=none; d=google.com; s=arc-20160816; b=R6Mky4ETfsKgau542NH9rshna0KWYgq4G+tVvhkq8OwLIwmWrjp/HtOeIlcJng4TwJ hlVSF4EddcnftwkvApQ1Y6znUT015tbdR6LiJp4eWc6D/ZA1CitPO3YgCslEkd2XMhWh I2inNQ5bLUDxj7IEomCEdMNW/XK5lI2P/P4OBNzoXa4F83y/89fWBo73uU49Ul2XKZYo Ez9Y6Apq59gMDU29ZPetio5x2QTy7qjn6buwfOoLGAktELhaCahSTkp2zWEbPp/0ftCi rzu06y/lkw10ju7yZ0XnduP/lrp/h+NjrTwcX1ZSvg0K8qLGvNaPNkKE8yp5/FM4/NH+ 5fqA== 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=MRI5LQaLZKUTp/cNbWBqhglGWPBqkbnFr/jZT/cZIQg=; b=Dr8MhIb8AWDJ6xpUHoUTYWjxr1HJ3IXR3LteDvhEU/u7zjzAlXE+lFaj1ZnP+CqcAP gBeLPNoszy35pTpePvk3sVOoN4LMLAUFoTyHf438IFWM3woD3okHN/VbkW/SB1tSD90J 8V9YEH+KfeQQwbwqHLWnpQJ9vvb4ux243oj3DSZn3Xuj2fRAJo4fqs4fSsqYlpViD8// p5Y9UGlRbZ3rmPFLscfmgO7YCoAXpuMDc/SYBu7A5k7Ewl9E5kRqOE4rrAtuAPEDYLt1 ntsI3e95BSz+O63Hdkvv9C1UuviYL0gG/WbzyV3g3iZ5M22UpibxJcHIIfwdqlDzmWIl XyhQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=U31hSxEz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 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 lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id n4-20020a170902d2c400b001588973b195si11514220plc.436.2022.05.09.00.37.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 May 2022 00:37:43 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) client-ip=2620:137:e000::1:18; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=U31hSxEz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 38DD3174917; Mon, 9 May 2022 00:32:43 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1383353AbiEESTt (ORCPT + 99 others); Thu, 5 May 2022 14:19:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36216 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1383069AbiEESTX (ORCPT ); Thu, 5 May 2022 14:19:23 -0400 Received: from mga06.intel.com (mga06b.intel.com [134.134.136.31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B4D411C33; Thu, 5 May 2022 11:15:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1651774543; x=1683310543; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=edji8pZckxmQsAtS6gc1oiKadfL+agtktzsETJQF6rs=; b=U31hSxEzzd3lv5ezjXk0F4OMMPQa225Wir6UDOadAQ6eC/ylp6vxtvEt DN0NCJkSVRCb6ZFywNh3KpQdp8KZ7SBbThJ0q4Ru2KiKTXsP8J3BqDQpn sXmdzDxwS8YFumHNJ4mm2ttCHgvhtQjAWmrg+hLEPDjH0zdO8fwjufvY5 xD34GHSuaW7ACY1hRhX0IM1Thh1XZidjnPgceyLOVO2arD7dHmTjukAQr 7pJNPIZfgett70zw6hTVH90kb+vJZ5KUailEt9g6i63ZMVHEtnKmsvvyZ hcywgqa+vdyvJar64RfUFnxM4GwlDY/NL9kdVFe6rqnkNa2JeXQATsIE7 Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10338"; a="328746228" X-IronPort-AV: E=Sophos;i="5.91,202,1647327600"; d="scan'208";a="328746228" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 May 2022 11:15:40 -0700 X-IronPort-AV: E=Sophos;i="5.91,202,1647327600"; d="scan'208";a="665083153" Received: from ls.sc.intel.com (HELO localhost) ([143.183.96.54]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 May 2022 11:15:40 -0700 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 , erdemaktas@google.com, Sean Christopherson , Sagi Shahar Subject: [RFC PATCH v6 008/104] KVM: x86: Refactor KVM VMX module init/exit functions Date: Thu, 5 May 2022 11:14:02 -0700 Message-Id: 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=-2.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable 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.) hyper-v specific initialization 3.) report those sizes to the KVM common layer and KVM common initialization, and 4.) 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 kvm/vcpu size calculation; hv_vp_assist_page_init(); kvm_init(); vmx_init(); }" in main.c, and hv_vp_assist_page_init() and vmx_init() in vmx.c. hv_vp_assist_page_init() initializes hyper-v specific assist pages, 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 | 38 +++++++++++++ arch/x86/kvm/vmx/vmx.c | 106 ++++++++++++++++++------------------- arch/x86/kvm/vmx/x86_ops.h | 6 +++ 3 files changed, 95 insertions(+), 55 deletions(-) diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c index fabf5f22c94f..371dad728166 100644 --- a/arch/x86/kvm/vmx/main.c +++ b/arch/x86/kvm/vmx/main.c @@ -169,3 +169,41 @@ struct kvm_x86_init_ops vt_init_ops __initdata = { .runtime_ops = &vt_x86_ops, .pmu_ops = &intel_pmu_ops, }; + +static int __init vt_init(void) +{ + unsigned int vcpu_size, vcpu_align; + int r; + + vt_x86_ops.vm_size = sizeof(struct kvm_vmx); + vcpu_size = sizeof(struct vcpu_vmx); + vcpu_align = __alignof__(struct vcpu_vmx); + + hv_vp_assist_page_init(); + vmx_init_early(); + + 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: + hv_vp_assist_page_exit(); + return r; +} +module_init(vt_init); + +static void vt_exit(void) +{ + vmx_exit(); + kvm_exit(); + hv_vp_assist_page_exit(); +} +module_exit(vt_exit); diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index e08be67352e0..b5846e0fc78f 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -8063,15 +8063,45 @@ static void vmx_cleanup_l1d_flush(void) l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_AUTO; } -static void vmx_exit(void) +void __init hv_vp_assist_page_init(void) { -#ifdef CONFIG_KEXEC_CORE - RCU_INIT_POINTER(crash_vmclear_loaded_vmcss, NULL); - synchronize_rcu(); -#endif +#if IS_ENABLED(CONFIG_HYPERV) + /* + * Enlightened VMCS usage should be recommended and the host needs + * to support eVMCS v1 or above. We can also disable eVMCS support + * with module parameter. + */ + if (enlightened_vmcs && + ms_hyperv.hints & HV_X64_ENLIGHTENED_VMCS_RECOMMENDED && + (ms_hyperv.nested_features & HV_X64_ENLIGHTENED_VMCS_VERSION) >= + KVM_EVMCS_VERSION) { + int cpu; + + /* Check that we have assist pages on all online CPUs */ + for_each_online_cpu(cpu) { + if (!hv_get_vp_assist_page(cpu)) { + enlightened_vmcs = false; + break; + } + } - kvm_exit(); + if (enlightened_vmcs) { + pr_info("KVM: vmx: using Hyper-V Enlightened VMCS\n"); + static_branch_enable(&enable_evmcs); + } + + if (ms_hyperv.nested_features & HV_X64_NESTED_DIRECT_FLUSH) + vt_x86_ops.enable_direct_tlbflush + = hv_enable_direct_tlbflush; + } else { + enlightened_vmcs = false; + } +#endif +} + +void hv_vp_assist_page_exit(void) +{ #if IS_ENABLED(CONFIG_HYPERV) if (static_branch_unlikely(&enable_evmcs)) { int cpu; @@ -8095,14 +8125,10 @@ static void vmx_exit(void) static_branch_disable(&enable_evmcs); } #endif - vmx_cleanup_l1d_flush(); - - allow_smaller_maxphyaddr = false; } -module_exit(vmx_exit); /* initialize before kvm_init() so that hardware_enable/disable() can work. */ -static void __init vmx_init_early(void) +void __init vmx_init_early(void) { int cpu; @@ -8110,49 +8136,10 @@ static void __init vmx_init_early(void) INIT_LIST_HEAD(&per_cpu(loaded_vmcss_on_cpu, cpu)); } -static int __init vmx_init(void) +int __init vmx_init(void) { int r, cpu; -#if IS_ENABLED(CONFIG_HYPERV) - /* - * Enlightened VMCS usage should be recommended and the host needs - * to support eVMCS v1 or above. We can also disable eVMCS support - * with module parameter. - */ - if (enlightened_vmcs && - ms_hyperv.hints & HV_X64_ENLIGHTENED_VMCS_RECOMMENDED && - (ms_hyperv.nested_features & HV_X64_ENLIGHTENED_VMCS_VERSION) >= - KVM_EVMCS_VERSION) { - - /* Check that we have assist pages on all online CPUs */ - for_each_online_cpu(cpu) { - if (!hv_get_vp_assist_page(cpu)) { - enlightened_vmcs = false; - break; - } - } - - if (enlightened_vmcs) { - pr_info("KVM: vmx: using Hyper-V Enlightened VMCS\n"); - static_branch_enable(&enable_evmcs); - } - - if (ms_hyperv.nested_features & HV_X64_NESTED_DIRECT_FLUSH) - vt_x86_ops.enable_direct_tlbflush - = hv_enable_direct_tlbflush; - - } else { - enlightened_vmcs = false; - } -#endif - - vmx_init_early(); - r = kvm_init(&vt_init_ops, sizeof(struct vcpu_vmx), - __alignof__(struct vcpu_vmx), THIS_MODULE); - if (r) - return r; - /* * Must be called after kvm_init() so enable_ept is properly set * up. Hand the parameter mitigation value in which was stored in @@ -8161,10 +8148,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) pi_init_cpu(cpu); @@ -8185,4 +8170,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 7a885dc84183..e28f4e0653b8 100644 --- a/arch/x86/kvm/vmx/x86_ops.h +++ b/arch/x86/kvm/vmx/x86_ops.h @@ -8,6 +8,12 @@ #include "x86.h" +void __init hv_vp_assist_page_init(void); +void hv_vp_assist_page_exit(void); +void __init vmx_init_early(void); +int __init vmx_init(void); +void vmx_exit(void); + __init int vmx_cpu_has_kvm_support(void); __init int vmx_disabled_by_bios(void); __init int vmx_hardware_setup(void); -- 2.25.1