From patchwork Wed Feb 16 03:15:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Gao X-Patchwork-Id: 12747886 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 58AF8C433F5 for ; Wed, 16 Feb 2022 03:15:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344124AbiBPDQG (ORCPT ); Tue, 15 Feb 2022 22:16:06 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:58006 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344110AbiBPDQE (ORCPT ); Tue, 15 Feb 2022 22:16:04 -0500 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6CB8FDCE07; Tue, 15 Feb 2022 19:15:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1644981353; x=1676517353; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=DlL2v0Wh9Vt/N3ZHWaxB+6mMkKskQwZNeJemBveuQDU=; b=RE2NSGlhGXwKP5G/cKMA1C2M2F3N2iAVly+B7bqz3d8a+80nZfikfAHJ RqENGwqsHdaYOFGJmVFvWQDaKxq8jJ87GEKAq9zyKVgtlOVkS9at3gqSn AT/Exw0oS+FXPSrzA3oJDA8df6fI2Oxr6qE2N7fVNRzHvuTHqRxDqKOt1 lnB8RYffwsh2CPdDyEP03YwVlTcB6GELFMsga3j2P8KHeYlvVYyxsDga7 Y3gTqxIet0Kr3Y0aCaHv0sanWJuWuR28eVniA/OIg2NtBvA4ANOh6TJA4 7Ii/A1u7vXHUiOaxv65YwxC+XvHPNbYNkccH4u5giPkdefmKYXfMGvAvx A==; X-IronPort-AV: E=McAfee;i="6200,9189,10259"; a="250250418" X-IronPort-AV: E=Sophos;i="5.88,371,1635231600"; d="scan'208";a="250250418" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2022 19:15:53 -0800 X-IronPort-AV: E=Sophos;i="5.88,371,1635231600"; d="scan'208";a="773798154" Received: from hyperv-sh4.sh.intel.com ([10.239.48.22]) by fmsmga006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2022 19:15:49 -0800 From: Chao Gao To: seanjc@google.com, maz@kernel.org, kvm@vger.kernel.org, pbonzini@redhat.com, kevin.tian@intel.com, tglx@linutronix.de Cc: Chao Gao , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , linux-kernel@vger.kernel.org Subject: [PATCH v4 1/6] KVM: x86: Move check_processor_compatibility from init ops to runtime ops Date: Wed, 16 Feb 2022 11:15:16 +0800 Message-Id: <20220216031528.92558-2-chao.gao@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220216031528.92558-1-chao.gao@intel.com> References: <20220216031528.92558-1-chao.gao@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org so that KVM can do compatibility checks on hotplugged CPUs. Drop __init from check_processor_compatibility() and its callees. use a static_call() to invoke .check_processor_compatibility. Opportunistically rename {svm,vmx}_check_processor_compat to conform to the naming convention of fields of kvm_x86_ops. Signed-off-by: Chao Gao Reviewed-by: Sean Christopherson --- arch/x86/include/asm/kvm-x86-ops.h | 1 + arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/svm/svm.c | 4 ++-- arch/x86/kvm/vmx/evmcs.c | 2 +- arch/x86/kvm/vmx/evmcs.h | 2 +- arch/x86/kvm/vmx/vmx.c | 12 ++++++------ arch/x86/kvm/x86.c | 3 +-- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h index 9e37dc3d8863..08494f172e2e 100644 --- a/arch/x86/include/asm/kvm-x86-ops.h +++ b/arch/x86/include/asm/kvm-x86-ops.h @@ -125,6 +125,7 @@ KVM_X86_OP_NULL(migrate_timers) KVM_X86_OP(msr_filter_changed) KVM_X86_OP_NULL(complete_emulated_msr) KVM_X86_OP(vcpu_deliver_sipi_vector) +KVM_X86_OP(check_processor_compatibility) #undef KVM_X86_OP #undef KVM_X86_OP_NULL diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 10815b672a26..7ac393a8dd54 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1315,6 +1315,7 @@ static inline u16 kvm_lapic_irq_dest_mode(bool dest_mode_logical) struct kvm_x86_ops { const char *name; + int (*check_processor_compatibility)(void); int (*hardware_enable)(void); void (*hardware_disable)(void); void (*hardware_unsetup)(void); @@ -1519,7 +1520,6 @@ struct kvm_x86_nested_ops { struct kvm_x86_init_ops { int (*cpu_has_kvm_support)(void); int (*disabled_by_bios)(void); - int (*check_processor_compatibility)(void); int (*hardware_setup)(void); unsigned int (*handle_intel_pt_intr)(void); diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 4243bb355db0..6244f669f03e 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3907,7 +3907,7 @@ svm_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall) hypercall[2] = 0xd9; } -static int __init svm_check_processor_compat(void) +static int svm_check_processor_compatibility(void) { return 0; } @@ -4527,6 +4527,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata = { .name = "kvm_amd", .hardware_unsetup = svm_hardware_unsetup, + .check_processor_compatibility = svm_check_processor_compatibility, .hardware_enable = svm_hardware_enable, .hardware_disable = svm_hardware_disable, .cpu_has_accelerated_tpr = svm_cpu_has_accelerated_tpr, @@ -4899,7 +4900,6 @@ static struct kvm_x86_init_ops svm_init_ops __initdata = { .cpu_has_kvm_support = has_svm, .disabled_by_bios = is_disabled, .hardware_setup = svm_hardware_setup, - .check_processor_compatibility = svm_check_processor_compat, .runtime_ops = &svm_x86_ops, }; diff --git a/arch/x86/kvm/vmx/evmcs.c b/arch/x86/kvm/vmx/evmcs.c index 87e3dc10edf4..a2a4c87d0558 100644 --- a/arch/x86/kvm/vmx/evmcs.c +++ b/arch/x86/kvm/vmx/evmcs.c @@ -295,7 +295,7 @@ const struct evmcs_field vmcs_field_to_evmcs_1[] = { const unsigned int nr_evmcs_1_fields = ARRAY_SIZE(vmcs_field_to_evmcs_1); #if IS_ENABLED(CONFIG_HYPERV) -__init void evmcs_sanitize_exec_ctrls(struct vmcs_config *vmcs_conf) +void evmcs_sanitize_exec_ctrls(struct vmcs_config *vmcs_conf) { vmcs_conf->pin_based_exec_ctrl &= ~EVMCS1_UNSUPPORTED_PINCTRL; vmcs_conf->cpu_based_2nd_exec_ctrl &= ~EVMCS1_UNSUPPORTED_2NDEXEC; diff --git a/arch/x86/kvm/vmx/evmcs.h b/arch/x86/kvm/vmx/evmcs.h index 8d70f9aea94b..3fd4cc44d8ad 100644 --- a/arch/x86/kvm/vmx/evmcs.h +++ b/arch/x86/kvm/vmx/evmcs.h @@ -211,7 +211,7 @@ static inline void evmcs_load(u64 phys_addr) vp_ap->enlighten_vmentry = 1; } -__init void evmcs_sanitize_exec_ctrls(struct vmcs_config *vmcs_conf); +void evmcs_sanitize_exec_ctrls(struct vmcs_config *vmcs_conf); #else /* !IS_ENABLED(CONFIG_HYPERV) */ static __always_inline void evmcs_write64(unsigned long field, u64 value) {} static inline void evmcs_write32(unsigned long field, u32 value) {} diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 70e7f00362bc..5e1b40e5ad87 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2403,8 +2403,8 @@ static bool cpu_has_sgx(void) return cpuid_eax(0) >= 0x12 && (cpuid_eax(0x12) & BIT(0)); } -static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, - u32 msr, u32 *result) +static int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, + u32 msr, u32 *result) { u32 vmx_msr_low, vmx_msr_high; u32 ctl = ctl_min | ctl_opt; @@ -2422,8 +2422,8 @@ static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, return 0; } -static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf, - struct vmx_capability *vmx_cap) +static int setup_vmcs_config(struct vmcs_config *vmcs_conf, + struct vmx_capability *vmx_cap) { u32 vmx_msr_low, vmx_msr_high; u32 min, opt, min2, opt2; @@ -7118,7 +7118,7 @@ static int vmx_vm_init(struct kvm *kvm) return 0; } -static int __init vmx_check_processor_compat(void) +static int vmx_check_processor_compatibility(void) { struct vmcs_config vmcs_conf; struct vmx_capability vmx_cap; @@ -7712,6 +7712,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = { .hardware_unsetup = vmx_hardware_unsetup, + .check_processor_compatibility = vmx_check_processor_compatibility, .hardware_enable = vmx_hardware_enable, .hardware_disable = vmx_hardware_disable, .cpu_has_accelerated_tpr = vmx_cpu_has_accelerated_tpr, @@ -8066,7 +8067,6 @@ static __init int hardware_setup(void) static struct kvm_x86_init_ops vmx_init_ops __initdata = { .cpu_has_kvm_support = cpu_has_kvm_support, .disabled_by_bios = vmx_disabled_by_bios, - .check_processor_compatibility = vmx_check_processor_compat, .hardware_setup = hardware_setup, .handle_intel_pt_intr = NULL, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index eaa3b5b89c5e..9b484ed61f37 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -11512,7 +11512,6 @@ void kvm_arch_hardware_unsetup(void) int kvm_arch_check_processor_compat(void *opaque) { struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); - struct kvm_x86_init_ops *ops = opaque; WARN_ON(!irqs_disabled()); @@ -11520,7 +11519,7 @@ int kvm_arch_check_processor_compat(void *opaque) __cr4_reserved_bits(cpu_has, &boot_cpu_data)) return -EIO; - return ops->check_processor_compatibility(); + return static_call(kvm_x86_check_processor_compatibility)(); } bool kvm_vcpu_is_reset_bsp(struct kvm_vcpu *vcpu) From patchwork Wed Feb 16 03:15:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Gao X-Patchwork-Id: 12747887 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AAB42C4332F for ; Wed, 16 Feb 2022 03:16:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344130AbiBPDQR (ORCPT ); Tue, 15 Feb 2022 22:16:17 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:58094 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241101AbiBPDQQ (ORCPT ); Tue, 15 Feb 2022 22:16:16 -0500 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D2EE7DCE0D; Tue, 15 Feb 2022 19:16:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1644981364; x=1676517364; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=OL/CJpx3e1GRIpNB1pTJCWsC1hGcn+U6/rlTNg6FcmQ=; b=CLunqwH7BLPaZ1oQbBmQrX13uXAoTbppuSJEduZSamzC7arLYfuggNy5 oLWMi1fwM8s2nKVXx9Vpn9g3e+W++02/R+Yu9YVv6JSL/ju0rLiDdL4mX v9p0BJqRNnvt8r14iu53o4mXlM3CbS0EKYR3nJhRLxIOC34sYtGzZHWjt tVc8MYu8yOPY3p05MhypP3/42aN/2ju2JRKPzth1yoXW+UhozFoPmpPVU 6lNjaCEvJh+9SEfxJjxVH4msWBugl8OFJGePJRBB8T6DfYc5TtqTY3na0 e0sgmbQeiJ5XtOZOGFSPycQ5Maq2iEKp5W3W5PdP35YmOhXXkpJIzRFX5 Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10259"; a="248110834" X-IronPort-AV: E=Sophos;i="5.88,371,1635231600"; d="scan'208";a="248110834" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2022 19:16:04 -0800 X-IronPort-AV: E=Sophos;i="5.88,371,1635231600"; d="scan'208";a="773798219" Received: from hyperv-sh4.sh.intel.com ([10.239.48.22]) by fmsmga006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2022 19:15:54 -0800 From: Chao Gao To: seanjc@google.com, maz@kernel.org, kvm@vger.kernel.org, pbonzini@redhat.com, kevin.tian@intel.com, tglx@linutronix.de Cc: Chao Gao , James Morse , Alexandru Elisei , Suzuki K Poulose , Catalin Marinas , Will Deacon , Huacai Chen , Aleksandar Markovic , Thomas Bogendoerfer , Michael Ellerman , Benjamin Herrenschmidt , Paul Mackerras , Anup Patel , Atish Patra , Paul Walmsley , Palmer Dabbelt , Albert Ou , Christian Borntraeger , Janosch Frank , David Hildenbrand , Claudio Imbrenda , Heiko Carstens , Vasily Gorbik , Alexander Gordeev , Sven Schnelle , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , "Maciej S. Szmigiero" , Bharata B Rao , Nicholas Piggin , Nick Desaulniers , linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org, linux-mips@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, linux-s390@vger.kernel.org Subject: [PATCH v4 2/6] Partially revert "KVM: Pass kvm_init()'s opaque param to additional arch funcs" Date: Wed, 16 Feb 2022 11:15:17 +0800 Message-Id: <20220216031528.92558-3-chao.gao@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220216031528.92558-1-chao.gao@intel.com> References: <20220216031528.92558-1-chao.gao@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org This partially reverts commit b99040853738 ("KVM: Pass kvm_init()'s opaque param to additional arch funcs") remove opaque from kvm_arch_check_processor_compat because no one uses this opaque now. Address conflicts for ARM (due to file movement) and manually handle RISC-V which comes after the commit. And changes about kvm_arch_hardware_setup() in original commit are still needed so they are not reverted. Signed-off-by: Chao Gao Reviewed-by: Sean Christopherson Acked-by: Anup Patel Acked-by: Claudio Imbrenda Reviewed-by: Suzuki K Poulose --- arch/arm64/kvm/arm.c | 2 +- arch/mips/kvm/mips.c | 2 +- arch/powerpc/kvm/powerpc.c | 2 +- arch/riscv/kvm/main.c | 2 +- arch/s390/kvm/kvm-s390.c | 2 +- arch/x86/kvm/x86.c | 2 +- include/linux/kvm_host.h | 2 +- virt/kvm/kvm_main.c | 16 +++------------- 8 files changed, 10 insertions(+), 20 deletions(-) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index ecc5958e27fe..0165cf3aac3a 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -73,7 +73,7 @@ int kvm_arch_hardware_setup(void *opaque) return 0; } -int kvm_arch_check_processor_compat(void *opaque) +int kvm_arch_check_processor_compat(void) { return 0; } diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index a25e0b73ee70..092d09fb6a7e 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c @@ -140,7 +140,7 @@ int kvm_arch_hardware_setup(void *opaque) return 0; } -int kvm_arch_check_processor_compat(void *opaque) +int kvm_arch_check_processor_compat(void) { return 0; } diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 2ad0ccd202d5..30c817f3fa0c 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -423,7 +423,7 @@ int kvm_arch_hardware_setup(void *opaque) return 0; } -int kvm_arch_check_processor_compat(void *opaque) +int kvm_arch_check_processor_compat(void) { return kvmppc_core_check_processor_compat(); } diff --git a/arch/riscv/kvm/main.c b/arch/riscv/kvm/main.c index 2e5ca43c8c49..992877e78393 100644 --- a/arch/riscv/kvm/main.c +++ b/arch/riscv/kvm/main.c @@ -20,7 +20,7 @@ long kvm_arch_dev_ioctl(struct file *filp, return -EINVAL; } -int kvm_arch_check_processor_compat(void *opaque) +int kvm_arch_check_processor_compat(void) { return 0; } diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 577f1ead6a51..0053b81c6b02 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -252,7 +252,7 @@ int kvm_arch_hardware_enable(void) return 0; } -int kvm_arch_check_processor_compat(void *opaque) +int kvm_arch_check_processor_compat(void) { return 0; } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 9b484ed61f37..ffb88f0b7265 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -11509,7 +11509,7 @@ void kvm_arch_hardware_unsetup(void) static_call(kvm_x86_hardware_unsetup)(); } -int kvm_arch_check_processor_compat(void *opaque) +int kvm_arch_check_processor_compat(void) { struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index f11039944c08..2ad78e729bf7 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1413,7 +1413,7 @@ int kvm_arch_hardware_enable(void); void kvm_arch_hardware_disable(void); int kvm_arch_hardware_setup(void *opaque); void kvm_arch_hardware_unsetup(void); -int kvm_arch_check_processor_compat(void *opaque); +int kvm_arch_check_processor_compat(void); int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu); bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu); int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 83c57bcc6eb6..ee47d33d69e1 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -5643,22 +5643,14 @@ void kvm_unregister_perf_callbacks(void) } #endif -struct kvm_cpu_compat_check { - void *opaque; - int *ret; -}; - -static void check_processor_compat(void *data) +static void check_processor_compat(void *rtn) { - struct kvm_cpu_compat_check *c = data; - - *c->ret = kvm_arch_check_processor_compat(c->opaque); + *(int *)rtn = kvm_arch_check_processor_compat(); } int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, struct module *module) { - struct kvm_cpu_compat_check c; int r; int cpu; @@ -5686,10 +5678,8 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, if (r < 0) goto out_free_1; - c.ret = &r; - c.opaque = opaque; for_each_online_cpu(cpu) { - smp_call_function_single(cpu, check_processor_compat, &c, 1); + smp_call_function_single(cpu, check_processor_compat, &r, 1); if (r < 0) goto out_free_2; } From patchwork Wed Feb 16 03:15:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Gao X-Patchwork-Id: 12747888 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 545F3C433EF for ; Wed, 16 Feb 2022 03:16:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344141AbiBPDQV (ORCPT ); Tue, 15 Feb 2022 22:16:21 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:58106 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241101AbiBPDQR (ORCPT ); Tue, 15 Feb 2022 22:16:17 -0500 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1D7CCDCE07; Tue, 15 Feb 2022 19:16:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1644981367; x=1676517367; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=bpLgm/nN68Ff7pu3yaDbK15XDjBubHfH/fey+JeZkjo=; b=KjDAmG3ObJ7corAKuR4jNOezt5cVn2chDAS3PiANQEHUR/EPDl1DUqun iH5y/QLlzBJEitvDabCcWwRB8MlTQE1JZ5D/lGl9srNzM0V/iOOyDhwHp 34dNrZ+ST52kOBV5bcCMHhUaKdBMdIZ2qZ49YTuhhC0xIMI1C0DWwgE9c Ef0vd0H65fOPjwhx8wUrhA2gT3GSoCOsZigOS+6KCTD1T+aED0rMasaM7 1oaND8QjtUStT+PJWfnP2Rw29GvOoF1qa0t8MxOP08AR2FuniZi8NiskZ cddkokqaHr1PLxu3BcoFJsFahSQOHwv2CcR8g/BlXldCRZ9V2OV0r7pVF g==; X-IronPort-AV: E=McAfee;i="6200,9189,10259"; a="248110842" X-IronPort-AV: E=Sophos;i="5.88,371,1635231600"; d="scan'208";a="248110842" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2022 19:16:06 -0800 X-IronPort-AV: E=Sophos;i="5.88,371,1635231600"; d="scan'208";a="773798241" Received: from hyperv-sh4.sh.intel.com ([10.239.48.22]) by fmsmga006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2022 19:16:04 -0800 From: Chao Gao To: seanjc@google.com, maz@kernel.org, kvm@vger.kernel.org, pbonzini@redhat.com, kevin.tian@intel.com, tglx@linutronix.de Cc: Chao Gao , linux-kernel@vger.kernel.org Subject: [PATCH v4 3/6] KVM: Provide more information in kernel log if hardware enabling fails Date: Wed, 16 Feb 2022 11:15:18 +0800 Message-Id: <20220216031528.92558-4-chao.gao@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220216031528.92558-1-chao.gao@intel.com> References: <20220216031528.92558-1-chao.gao@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org From: Sean Christopherson Provide the name of the calling function to hardware_enable_nolock() and include it in the error message to provide additional information on exactly what path failed. Opportunistically bump the pr_info() to pr_warn(), failure to enable virtualization support is warn-worthy as _something_ is wrong with the system. Signed-off-by: Sean Christopherson Signed-off-by: Chao Gao --- virt/kvm/kvm_main.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index ee47d33d69e1..c7229f5c9f66 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -4833,7 +4833,7 @@ static struct miscdevice kvm_dev = { &kvm_chardev_ops, }; -static void hardware_enable_nolock(void *junk) +static void hardware_enable_nolock(void *caller_name) { int cpu = raw_smp_processor_id(); int r; @@ -4848,7 +4848,8 @@ static void hardware_enable_nolock(void *junk) if (r) { cpumask_clear_cpu(cpu, cpus_hardware_enabled); atomic_inc(&hardware_enable_failed); - pr_info("kvm: enabling virtualization on CPU%d failed\n", cpu); + pr_warn("kvm: enabling virtualization on CPU%d failed during %s()\n", + cpu, (const char *)caller_name); } } @@ -4856,7 +4857,7 @@ static int kvm_starting_cpu(unsigned int cpu) { raw_spin_lock(&kvm_count_lock); if (kvm_usage_count) - hardware_enable_nolock(NULL); + hardware_enable_nolock((void *)__func__); raw_spin_unlock(&kvm_count_lock); return 0; } @@ -4905,7 +4906,7 @@ static int hardware_enable_all(void) kvm_usage_count++; if (kvm_usage_count == 1) { atomic_set(&hardware_enable_failed, 0); - on_each_cpu(hardware_enable_nolock, NULL, 1); + on_each_cpu(hardware_enable_nolock, (void *)__func__, 1); if (atomic_read(&hardware_enable_failed)) { hardware_disable_all_nolock(); @@ -5530,7 +5531,7 @@ static void kvm_resume(void) #ifdef CONFIG_LOCKDEP WARN_ON(lockdep_is_held(&kvm_count_lock)); #endif - hardware_enable_nolock(NULL); + hardware_enable_nolock((void *)__func__); } } From patchwork Wed Feb 16 03:15:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Gao X-Patchwork-Id: 12747889 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3B790C433EF for ; Wed, 16 Feb 2022 03:16:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344148AbiBPDQ2 (ORCPT ); Tue, 15 Feb 2022 22:16:28 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:58158 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344145AbiBPDQZ (ORCPT ); Tue, 15 Feb 2022 22:16:25 -0500 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 84CA0E7F60; Tue, 15 Feb 2022 19:16:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1644981374; x=1676517374; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=FfUoAo4oDorQPqjCfrO87NTW/6QExAqQMSQCENI5GwQ=; b=IiX1mMQeYrfc/o4oOVKPCLFhiU+fVoDJ3kgwqGqyD72ErTQ+jObs8dDd foC+zUbL6gS3+AijAhlElJi7u/MuWsIDILuO1u8Eaqth5oVK10oc/+Ikt ADKrf9uuSajivuDngXyb2WMClV4VVpWheOPV/5octl1ESKQg+AiYwIf0/ d4Bi/Qx4wLklqwODXceKBw5gmd4qVFEmMA6JXq5I4Ny+yCwzG0RnHqR7F MzVnDMxodTBv3lUEB+ilbjP+jwkuF+3Nc5nwrroFQY7DsN2qVAkelUKo/ nGymjqQqKOBUQdmrzFDAjqjN5r9NVaTUM9Dsda0lPCdNblBG6MqDs2ALE g==; X-IronPort-AV: E=McAfee;i="6200,9189,10259"; a="249344539" X-IronPort-AV: E=Sophos;i="5.88,371,1635231600"; d="scan'208";a="249344539" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2022 19:16:14 -0800 X-IronPort-AV: E=Sophos;i="5.88,371,1635231600"; d="scan'208";a="773798287" Received: from hyperv-sh4.sh.intel.com ([10.239.48.22]) by fmsmga006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2022 19:16:09 -0800 From: Chao Gao To: seanjc@google.com, maz@kernel.org, kvm@vger.kernel.org, pbonzini@redhat.com, kevin.tian@intel.com, tglx@linutronix.de Cc: Chao Gao , James Morse , Alexandru Elisei , Suzuki K Poulose , Catalin Marinas , Will Deacon , Eric Auger , Oliver Upton , Jia He , John Garry , Shaokun Zhang , Qi Liu , Daniel Lezcano , Thomas Richter , linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org Subject: [PATCH v4 4/6] KVM: arm64: Simplify the CPUHP logic Date: Wed, 16 Feb 2022 11:15:19 +0800 Message-Id: <20220216031528.92558-5-chao.gao@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220216031528.92558-1-chao.gao@intel.com> References: <20220216031528.92558-1-chao.gao@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org From: Marc Zyngier For a number of historical reasons, the KVM/arm64 hotplug setup is pretty complicated, and we have two extra CPUHP notifiers for vGIC and timers. It looks pretty pointless, and gets in the way of further changes. So let's just expose some helpers that can be called from the core CPUHP callback, and get rid of everything else. This gives us the opportunity to drop a useless notifier entry, as well as tidy-up the timer enable/disable, which was a bit odd. Signed-off-by: Marc Zyngier Signed-off-by: Chao Gao Reviewed-by: Oliver Upton --- arch/arm64/kvm/arch_timer.c | 27 ++++++++++----------------- arch/arm64/kvm/arm.c | 4 ++++ arch/arm64/kvm/vgic/vgic-init.c | 19 ++----------------- include/kvm/arm_arch_timer.h | 4 ++++ include/kvm/arm_vgic.h | 4 ++++ include/linux/cpuhotplug.h | 3 --- 6 files changed, 24 insertions(+), 37 deletions(-) diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 6e542e2eae32..f9d14c6dc0b4 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -796,10 +796,18 @@ void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) ptimer->host_timer_irq_flags = host_ptimer_irq_flags; } -static void kvm_timer_init_interrupt(void *info) +void kvm_timer_cpu_up(void) { enable_percpu_irq(host_vtimer_irq, host_vtimer_irq_flags); - enable_percpu_irq(host_ptimer_irq, host_ptimer_irq_flags); + if (host_ptimer_irq) + enable_percpu_irq(host_ptimer_irq, host_ptimer_irq_flags); +} + +void kvm_timer_cpu_down(void) +{ + disable_percpu_irq(host_vtimer_irq); + if (host_ptimer_irq) + disable_percpu_irq(host_ptimer_irq); } int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value) @@ -961,18 +969,6 @@ void kvm_arm_timer_write_sysreg(struct kvm_vcpu *vcpu, preempt_enable(); } -static int kvm_timer_starting_cpu(unsigned int cpu) -{ - kvm_timer_init_interrupt(NULL); - return 0; -} - -static int kvm_timer_dying_cpu(unsigned int cpu) -{ - disable_percpu_irq(host_vtimer_irq); - return 0; -} - static int timer_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu) { if (vcpu) @@ -1170,9 +1166,6 @@ int kvm_timer_hyp_init(bool has_gic) goto out_free_irq; } - cpuhp_setup_state(CPUHP_AP_KVM_ARM_TIMER_STARTING, - "kvm/arm/timer:starting", kvm_timer_starting_cpu, - kvm_timer_dying_cpu); return 0; out_free_irq: free_percpu_irq(host_vtimer_irq, kvm_get_running_vcpus()); diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 0165cf3aac3a..31b049e48b19 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1658,6 +1658,8 @@ static void _kvm_arch_hardware_enable(void *discard) { if (!__this_cpu_read(kvm_arm_hardware_enabled)) { cpu_hyp_reinit(); + kvm_vgic_cpu_up(); + kvm_timer_cpu_up(); __this_cpu_write(kvm_arm_hardware_enabled, 1); } } @@ -1671,6 +1673,8 @@ int kvm_arch_hardware_enable(void) static void _kvm_arch_hardware_disable(void *discard) { if (__this_cpu_read(kvm_arm_hardware_enabled)) { + kvm_timer_cpu_down(); + kvm_vgic_cpu_down(); cpu_hyp_reset(); __this_cpu_write(kvm_arm_hardware_enabled, 0); } diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index fc00304fe7d8..60038a8516de 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -460,17 +460,15 @@ int kvm_vgic_map_resources(struct kvm *kvm) /* GENERIC PROBE */ -static int vgic_init_cpu_starting(unsigned int cpu) +void kvm_vgic_cpu_up(void) { enable_percpu_irq(kvm_vgic_global_state.maint_irq, 0); - return 0; } -static int vgic_init_cpu_dying(unsigned int cpu) +void kvm_vgic_cpu_down(void) { disable_percpu_irq(kvm_vgic_global_state.maint_irq); - return 0; } static irqreturn_t vgic_maintenance_handler(int irq, void *data) @@ -579,19 +577,6 @@ int kvm_vgic_hyp_init(void) return ret; } - ret = cpuhp_setup_state(CPUHP_AP_KVM_ARM_VGIC_INIT_STARTING, - "kvm/arm/vgic:starting", - vgic_init_cpu_starting, vgic_init_cpu_dying); - if (ret) { - kvm_err("Cannot register vgic CPU notifier\n"); - goto out_free_irq; - } - kvm_info("vgic interrupt IRQ%d\n", kvm_vgic_global_state.maint_irq); return 0; - -out_free_irq: - free_percpu_irq(kvm_vgic_global_state.maint_irq, - kvm_get_running_vcpus()); - return ret; } diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h index 51c19381108c..16a2f65fcfb4 100644 --- a/include/kvm/arm_arch_timer.h +++ b/include/kvm/arm_arch_timer.h @@ -106,4 +106,8 @@ void kvm_arm_timer_write_sysreg(struct kvm_vcpu *vcpu, u32 timer_get_ctl(struct arch_timer_context *ctxt); u64 timer_get_cval(struct arch_timer_context *ctxt); +/* CPU HP callbacks */ +void kvm_timer_cpu_up(void); +void kvm_timer_cpu_down(void); + #endif diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index bb30a6803d9f..a2a0cca05a73 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -427,4 +427,8 @@ int vgic_v4_load(struct kvm_vcpu *vcpu); void vgic_v4_commit(struct kvm_vcpu *vcpu); int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db); +/* CPU HP callbacks */ +void kvm_vgic_cpu_up(void); +void kvm_vgic_cpu_down(void); + #endif /* __KVM_ARM_VGIC_H */ diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 411a428ace4d..4345b8eafc03 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -183,9 +183,6 @@ enum cpuhp_state { CPUHP_AP_TI_GP_TIMER_STARTING, CPUHP_AP_HYPERV_TIMER_STARTING, CPUHP_AP_KVM_STARTING, - CPUHP_AP_KVM_ARM_VGIC_INIT_STARTING, - CPUHP_AP_KVM_ARM_VGIC_STARTING, - CPUHP_AP_KVM_ARM_TIMER_STARTING, /* Must be the last timer callback */ CPUHP_AP_DUMMY_TIMER_STARTING, CPUHP_AP_ARM_XEN_STARTING, From patchwork Wed Feb 16 03:15:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Gao X-Patchwork-Id: 12747890 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7C207C433F5 for ; Wed, 16 Feb 2022 03:16:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244524AbiBPDQp (ORCPT ); Tue, 15 Feb 2022 22:16:45 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:59018 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234910AbiBPDQo (ORCPT ); Tue, 15 Feb 2022 22:16:44 -0500 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 965AF6433; Tue, 15 Feb 2022 19:16: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=1644981392; x=1676517392; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=yrhdfFnt+IU2sldeSHzrHzJiU1+hSv0xsaODnQGVYi0=; b=VxCib6+aOWa/VHfeoKgey1Qo7THxmXufDmX4y21esClN2a41cq8N6WHr 1yYR+VBcD9L9YLutaaTXncDFR9JkJcT19Lxh8jwGX7Q8lY4YbuwF+y4Oo UFjUZ5LIn7S89y22VRQP1CHbBB4Xs6K7boBNWnEZqrc/EpqiAwTPgUobw 9pSgqUQWTmre99BQ26/e2I2lBgyvSzCrOr4Btzn35DEIX1505UXSQM/9R mOj3nosI3n9wDlV7G8CTSy6fxcJ7dThE66ubwiVGVMYtoS/cIN0n5QMS6 Ef/e5xI6OpLMSkg3A17jC9OUjB/hCeAm1w5yzP/UntTJgTS5QSXi4N/KQ Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10259"; a="249344572" X-IronPort-AV: E=Sophos;i="5.88,371,1635231600"; d="scan'208";a="249344572" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2022 19:16:31 -0800 X-IronPort-AV: E=Sophos;i="5.88,371,1635231600"; d="scan'208";a="773798316" Received: from hyperv-sh4.sh.intel.com ([10.239.48.22]) by fmsmga006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2022 19:16:15 -0800 From: Chao Gao To: seanjc@google.com, maz@kernel.org, kvm@vger.kernel.org, pbonzini@redhat.com, kevin.tian@intel.com, tglx@linutronix.de Cc: Chao Gao , John Garry , Will Deacon , Shaokun Zhang , Qi Liu , Sumanth Korikkar , Thomas Richter , Dave Chinner , linux-kernel@vger.kernel.org Subject: [PATCH v4 5/6] KVM: Rename and move CPUHP_AP_KVM_STARTING to ONLINE section Date: Wed, 16 Feb 2022 11:15:20 +0800 Message-Id: <20220216031528.92558-6-chao.gao@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220216031528.92558-1-chao.gao@intel.com> References: <20220216031528.92558-1-chao.gao@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The CPU STARTING section doesn't allow callbacks to fail. Move KVM's hotplug callback to ONLINE section so that it can abort onlining a CPU in certain cases to avoid potentially breaking VMs running on existing CPUs. For example, when kvm fails to enable hardware virtualization on the hotplugged CPU. Place KVM's hotplug state before CPUHP_AP_SCHED_WAIT_EMPTY as it ensures when offlining a CPU, all user tasks and non-pinned kernel tasks have left the CPU, i.e. there cannot be a vCPU task around. So, it is safe for KVM's CPU offline callback to disable hardware virtualization at that point. Likewise, KVM's online callback can enable hardware virtualization before any vCPU task gets a chance to run on hotplugged CPUs. KVM's CPU hotplug callbacks are renamed as well. Suggested-by: Thomas Gleixner Signed-off-by: Chao Gao --- include/linux/cpuhotplug.h | 2 +- virt/kvm/kvm_main.c | 30 ++++++++++++++++++++++-------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 4345b8eafc03..2c88770d3681 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -182,7 +182,6 @@ enum cpuhp_state { CPUHP_AP_CSKY_TIMER_STARTING, CPUHP_AP_TI_GP_TIMER_STARTING, CPUHP_AP_HYPERV_TIMER_STARTING, - CPUHP_AP_KVM_STARTING, /* Must be the last timer callback */ CPUHP_AP_DUMMY_TIMER_STARTING, CPUHP_AP_ARM_XEN_STARTING, @@ -197,6 +196,7 @@ enum cpuhp_state { /* Online section invoked on the hotplugged CPU from the hotplug thread */ CPUHP_AP_ONLINE_IDLE, + CPUHP_AP_KVM_ONLINE, CPUHP_AP_SCHED_WAIT_EMPTY, CPUHP_AP_SMPBOOT_THREADS, CPUHP_AP_X86_VDSO_VMA_ONLINE, diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index c7229f5c9f66..bd60f8278867 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -4853,13 +4853,27 @@ static void hardware_enable_nolock(void *caller_name) } } -static int kvm_starting_cpu(unsigned int cpu) +static int kvm_online_cpu(unsigned int cpu) { + int ret = 0; + raw_spin_lock(&kvm_count_lock); - if (kvm_usage_count) + /* + * Abort the CPU online process if hardware virtualization cannot + * be enabled. Otherwise running VMs would encounter unrecoverable + * errors when scheduled to this CPU. + */ + if (kvm_usage_count) { + WARN_ON_ONCE(atomic_read(&hardware_enable_failed)); + hardware_enable_nolock((void *)__func__); + if (atomic_read(&hardware_enable_failed)) { + atomic_set(&hardware_enable_failed, 0); + ret = -EIO; + } + } raw_spin_unlock(&kvm_count_lock); - return 0; + return ret; } static void hardware_disable_nolock(void *junk) @@ -4872,7 +4886,7 @@ static void hardware_disable_nolock(void *junk) kvm_arch_hardware_disable(); } -static int kvm_dying_cpu(unsigned int cpu) +static int kvm_offline_cpu(unsigned int cpu) { raw_spin_lock(&kvm_count_lock); if (kvm_usage_count) @@ -5685,8 +5699,8 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, goto out_free_2; } - r = cpuhp_setup_state_nocalls(CPUHP_AP_KVM_STARTING, "kvm/cpu:starting", - kvm_starting_cpu, kvm_dying_cpu); + r = cpuhp_setup_state_nocalls(CPUHP_AP_KVM_ONLINE, "kvm/cpu:online", + kvm_online_cpu, kvm_offline_cpu); if (r) goto out_free_2; register_reboot_notifier(&kvm_reboot_notifier); @@ -5749,7 +5763,7 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, kmem_cache_destroy(kvm_vcpu_cache); out_free_3: unregister_reboot_notifier(&kvm_reboot_notifier); - cpuhp_remove_state_nocalls(CPUHP_AP_KVM_STARTING); + cpuhp_remove_state_nocalls(CPUHP_AP_KVM_ONLINE); out_free_2: kvm_arch_hardware_unsetup(); out_free_1: @@ -5775,7 +5789,7 @@ void kvm_exit(void) kvm_async_pf_deinit(); unregister_syscore_ops(&kvm_syscore_ops); unregister_reboot_notifier(&kvm_reboot_notifier); - cpuhp_remove_state_nocalls(CPUHP_AP_KVM_STARTING); + cpuhp_remove_state_nocalls(CPUHP_AP_KVM_ONLINE); on_each_cpu(hardware_disable_nolock, NULL, 1); kvm_arch_hardware_unsetup(); kvm_arch_exit(); From patchwork Wed Feb 16 03:15:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Gao X-Patchwork-Id: 12747891 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0B1FFC433FE for ; Wed, 16 Feb 2022 03:16:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344161AbiBPDQr (ORCPT ); Tue, 15 Feb 2022 22:16:47 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:59104 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244696AbiBPDQp (ORCPT ); Tue, 15 Feb 2022 22:16:45 -0500 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CCFCDA185; Tue, 15 Feb 2022 19:16:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1644981393; x=1676517393; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=CXIRvtzJsiu2gcoHHl+uHSkuWDGrmc7HzH3aUUMVke4=; b=B1KzLwfZuCE8wqQWezao27+0XWS8eCZSUvLe15iXDwp0gaUp1uhMtx6x gjRKcgwJXwYKHAsoKO9DsQWKUbP0W1LR+kIao3vJiCNBHmGVRp+pX1hl7 1Z1n0d4z+1gavQpPc30O9M5SLsazni8xXixbQMAXtY9rab1h5rGV4wBcQ 13ZjaOs1Q5IMHhT625rFomeSvrmxXsNc/vRSvg8oa01zfONss97O4Ph01 XYddUtlZmHykcjs8g0pZjD3SdA8Yoel7u9HwXGRHotrJ018K26ZrgeDpx mms9sPN7m2quLh9gAAulpNy5Im/HSTLAyYU9s6HQWkYlw44T7kKTsrRHW A==; X-IronPort-AV: E=McAfee;i="6200,9189,10259"; a="249344574" X-IronPort-AV: E=Sophos;i="5.88,371,1635231600"; d="scan'208";a="249344574" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2022 19:16:31 -0800 X-IronPort-AV: E=Sophos;i="5.88,371,1635231600"; d="scan'208";a="773798338" Received: from hyperv-sh4.sh.intel.com ([10.239.48.22]) by fmsmga006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2022 19:16:21 -0800 From: Chao Gao To: seanjc@google.com, maz@kernel.org, kvm@vger.kernel.org, pbonzini@redhat.com, kevin.tian@intel.com, tglx@linutronix.de Cc: Chao Gao , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , linux-kernel@vger.kernel.org Subject: [PATCH v4 6/6] KVM: Do compatibility checks on hotplugged CPUs Date: Wed, 16 Feb 2022 11:15:21 +0800 Message-Id: <20220216031528.92558-7-chao.gao@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220216031528.92558-1-chao.gao@intel.com> References: <20220216031528.92558-1-chao.gao@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org At init time, KVM does compatibility checks to ensure that all online CPUs support hardware virtualization and a common set of features. But KVM uses hotplugged CPUs without such compatibility checks. On Intel CPUs, this leads to #GP if the hotplugged CPU doesn't support VMX or vmentry failure if the hotplugged CPU doesn't meet minimal feature requirements. Do compatibility checks when onlining a CPU and abort the online process if the hotplugged CPU is incompatible with online CPUs. CPU hotplug is disabled during hardware_enable_all() to prevent the corner case as shown below. A hotplugged CPU marks itself online in cpu_online_mask (1) and enables interrupt (2) before invoking callbacks registered in ONLINE section (3). So, if hardware_enable_all() is invoked on another CPU right after (2), then on_each_cpu() in hardware_enable_all() invokes hardware_enable_nolock() on the hotplugged CPU before kvm_online_cpu() is called. This makes the CPU escape from compatibility checks, which is risky. start_secondary { ... set_cpu_online(smp_processor_id(), true); <- 1 ... local_irq_enable(); <- 2 ... cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); <- 3 } Keep compatibility checks at KVM init time. It can help to find incompatibility issues earlier and refuse to load arch KVM module (e.g., kvm-intel). Loosen the WARN_ON in kvm_arch_check_processor_compat so that it can be invoked from KVM's CPU hotplug callback (i.e., kvm_online_cpu). Opportunistically, add a pr_err() for setup_vmcs_config() path in vmx_check_processor_compatibility() so that each possible error path has its own error message. Convert printk(KERN_ERR ... to pr_err to please checkpatch.pl Signed-off-by: Chao Gao Reviewed-by: Sean Christopherson --- arch/x86/kvm/vmx/vmx.c | 10 ++++++---- arch/x86/kvm/x86.c | 11 +++++++++-- virt/kvm/kvm_main.c | 18 +++++++++++++++++- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 5e1b40e5ad87..9eb7e5dab46d 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7122,20 +7122,22 @@ static int vmx_check_processor_compatibility(void) { struct vmcs_config vmcs_conf; struct vmx_capability vmx_cap; + int cpu = smp_processor_id(); if (!this_cpu_has(X86_FEATURE_MSR_IA32_FEAT_CTL) || !this_cpu_has(X86_FEATURE_VMX)) { - pr_err("kvm: VMX is disabled on CPU %d\n", smp_processor_id()); + pr_err("kvm: VMX is disabled on CPU %d\n", cpu); return -EIO; } - if (setup_vmcs_config(&vmcs_conf, &vmx_cap) < 0) + if (setup_vmcs_config(&vmcs_conf, &vmx_cap) < 0) { + pr_err("kvm: failed to setup vmcs config on CPU %d\n", cpu); return -EIO; + } if (nested) nested_vmx_setup_ctls_msrs(&vmcs_conf.nested, vmx_cap.ept); if (memcmp(&vmcs_config, &vmcs_conf, sizeof(struct vmcs_config)) != 0) { - printk(KERN_ERR "kvm: CPU %d feature inconsistency!\n", - smp_processor_id()); + pr_err("kvm: CPU %d feature inconsistency!\n", cpu); return -EIO; } return 0; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index ffb88f0b7265..c30e3cdb0a30 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -11511,9 +11511,16 @@ void kvm_arch_hardware_unsetup(void) int kvm_arch_check_processor_compat(void) { - struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); + int cpu = smp_processor_id(); + struct cpuinfo_x86 *c = &cpu_data(cpu); - WARN_ON(!irqs_disabled()); + /* + * Compatibility checks are done when loading KVM or in KVM's CPU + * hotplug callback. It ensures all online CPUs are compatible to run + * vCPUs. For other cases, compatibility checks are unnecessary or + * even problematic. Try to detect improper usages here. + */ + WARN_ON(!irqs_disabled() && cpu_active(cpu)); if (__cr4_reserved_bits(cpu_has, c) != __cr4_reserved_bits(cpu_has, &boot_cpu_data)) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index bd60f8278867..330a5a62f043 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -4855,7 +4855,11 @@ static void hardware_enable_nolock(void *caller_name) static int kvm_online_cpu(unsigned int cpu) { - int ret = 0; + int ret; + + ret = kvm_arch_check_processor_compat(); + if (ret) + return ret; raw_spin_lock(&kvm_count_lock); /* @@ -4915,6 +4919,17 @@ static int hardware_enable_all(void) { int r = 0; + /* + * During onlining a CPU, cpu_online_mask is set before kvm_online_cpu() + * is called. on_each_cpu() between them includes the CPU. As a result, + * hardware_enable_nolock() may get invoked before kvm_online_cpu(). + * This would enable hardware virtualization on that cpu without + * compatibility checks, which can potentially crash system or break + * running VMs. + * + * Disable CPU hotplug to prevent this case from happening. + */ + cpus_read_lock(); raw_spin_lock(&kvm_count_lock); kvm_usage_count++; @@ -4929,6 +4944,7 @@ static int hardware_enable_all(void) } raw_spin_unlock(&kvm_count_lock); + cpus_read_unlock(); return r; }