From nobody Tue Jun 30 12:07:31 2026 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 0B1A7C433EF for ; Tue, 18 Jan 2022 06:49:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243595AbiARGtl (ORCPT ); Tue, 18 Jan 2022 01:49:41 -0500 Received: from mga06.intel.com ([134.134.136.31]:49404 "EHLO mga06.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243179AbiARGte (ORCPT ); Tue, 18 Jan 2022 01:49:34 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1642488574; x=1674024574; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=zeKFisLcTn3SYsHCdtM4J/tldathG8abND9ZUmvW4CI=; b=Ngs0frGhR/FVWz90tZ6EJcgVYUR9xoq53L2JxWf/oISgaQwR0J3GRjyl i9ruqN8daXpajqwbSndubuu8UGr5Lhdiq7URgBU0xt2zgs1IFcyklKtZF o5kMXXapI/uev78ge+0WwAwrNafmSH/AKWnLNFvLl0pNjzt6J8szUZguk 0AxfE0gC48URkKdF1ZaipIZYy5e0woytpXRyXtRLgOR+cu5HYoZnYYdyw XdP1WoQ2lGWMA5VkawtmwuhWjgeNCJ35Zpx+0oKPFlyor9xn1b2Gpucb8 ec5s0UKzlZpQmDfFOZpleDqSZQrqEI/rOLeYQhKlhOFT6qwMV4r7uAJeb A==; X-IronPort-AV: E=McAfee;i="6200,9189,10230"; a="305484651" X-IronPort-AV: E=Sophos;i="5.88,296,1635231600"; d="scan'208";a="305484651" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2022 22:49:34 -0800 X-IronPort-AV: E=Sophos;i="5.88,296,1635231600"; d="scan'208";a="531648568" Received: from hyperv-sh4.sh.intel.com ([10.239.48.22]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2022 22:49:30 -0800 From: Chao Gao To: kvm@vger.kernel.org, seanjc@google.com, 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 v2 1/4] KVM: x86: Move check_processor_compatibility from init ops to runtime ops Date: Tue, 18 Jan 2022 14:44:24 +0800 Message-Id: <20220118064430.3882337-2-chao.gao@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220118064430.3882337-1-chao.gao@intel.com> References: <20220118064430.3882337-1-chao.gao@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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(). Signed-off-by: Chao Gao --- 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 f658bb4dbb74..ab9b4eca56be 100644 --- a/arch/x86/include/asm/kvm-x86-ops.h +++ b/arch/x86/include/asm/kvm-x86-ops.h @@ -123,6 +123,7 @@ KVM_X86_OP_NULL(enable_direct_tlbflush) KVM_X86_OP_NULL(migrate_timers) KVM_X86_OP(msr_filter_changed) KVM_X86_OP_NULL(complete_emulated_msr) +KVM_X86_OP(check_processor_compatibility) =20 #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_hos= t.h index 89d1fdb39c46..a916b16edd89 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1314,6 +1314,7 @@ static inline u16 kvm_lapic_irq_dest_mode(bool dest_m= ode_logical) struct kvm_x86_ops { const char *name; =20 + int (*check_processor_compatibility)(void); int (*hardware_enable)(void); void (*hardware_disable)(void); void (*hardware_unsetup)(void); @@ -1526,7 +1527,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); =20 struct kvm_x86_ops *runtime_ops; diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index c3d9006478a4..5725fed5ced7 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4064,7 +4064,7 @@ svm_patch_hypercall(struct kvm_vcpu *vcpu, unsigned c= har *hypercall) hypercall[2] =3D 0xd9; } =20 -static int __init svm_check_processor_compat(void) +static int svm_check_processor_compat(void) { return 0; } @@ -4613,6 +4613,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata =3D { .name =3D "kvm_amd", =20 .hardware_unsetup =3D svm_hardware_teardown, + .check_processor_compatibility =3D svm_check_processor_compat, .hardware_enable =3D svm_hardware_enable, .hardware_disable =3D svm_hardware_disable, .cpu_has_accelerated_tpr =3D svm_cpu_has_accelerated_tpr, @@ -4746,7 +4747,6 @@ static struct kvm_x86_init_ops svm_init_ops __initdat= a =3D { .cpu_has_kvm_support =3D has_svm, .disabled_by_bios =3D is_disabled, .hardware_setup =3D svm_hardware_setup, - .check_processor_compatibility =3D svm_check_processor_compat, =20 .runtime_ops =3D &svm_x86_ops, }; diff --git a/arch/x86/kvm/vmx/evmcs.c b/arch/x86/kvm/vmx/evmcs.c index ba6f99f584ac..50f923e9917e 100644 --- a/arch/x86/kvm/vmx/evmcs.c +++ b/arch/x86/kvm/vmx/evmcs.c @@ -296,7 +296,7 @@ const struct evmcs_field vmcs_field_to_evmcs_1[] =3D { }; const unsigned int nr_evmcs_1_fields =3D ARRAY_SIZE(vmcs_field_to_evmcs_1); =20 -__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 &=3D ~EVMCS1_UNSUPPORTED_PINCTRL; vmcs_conf->cpu_based_2nd_exec_ctrl &=3D ~EVMCS1_UNSUPPORTED_2NDEXEC; diff --git a/arch/x86/kvm/vmx/evmcs.h b/arch/x86/kvm/vmx/evmcs.h index 16731d2cf231..17a7c956396b 100644 --- a/arch/x86/kvm/vmx/evmcs.h +++ b/arch/x86/kvm/vmx/evmcs.h @@ -181,7 +181,7 @@ static inline void evmcs_load(u64 phys_addr) vp_ap->enlighten_vmentry =3D 1; } =20 -__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 15e30602782b..364348e134df 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2402,8 +2402,8 @@ static bool cpu_has_sgx(void) return cpuid_eax(0) >=3D 0x12 && (cpuid_eax(0x12) & BIT(0)); } =20 -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 =3D ctl_min | ctl_opt; @@ -2421,8 +2421,8 @@ static __init int adjust_vmx_controls(u32 ctl_min, u3= 2 ctl_opt, return 0; } =20 -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; @@ -7051,7 +7051,7 @@ static int vmx_vm_init(struct kvm *kvm) return 0; } =20 -static int __init vmx_check_processor_compat(void) +static int vmx_check_processor_compat(void) { struct vmcs_config vmcs_conf; struct vmx_capability vmx_cap; @@ -7663,6 +7663,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata =3D { =20 .hardware_unsetup =3D hardware_unsetup, =20 + .check_processor_compatibility =3D vmx_check_processor_compat, .hardware_enable =3D hardware_enable, .hardware_disable =3D hardware_disable, .cpu_has_accelerated_tpr =3D report_flexpriority, @@ -7999,7 +8000,6 @@ static __init int hardware_setup(void) static struct kvm_x86_init_ops vmx_init_ops __initdata =3D { .cpu_has_kvm_support =3D cpu_has_kvm_support, .disabled_by_bios =3D vmx_disabled_by_bios, - .check_processor_compatibility =3D vmx_check_processor_compat, .hardware_setup =3D hardware_setup, =20 .runtime_ops =3D &vmx_x86_ops, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 60da2331ec32..f8bc1948a8b5 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -11473,7 +11473,6 @@ void kvm_arch_hardware_unsetup(void) int kvm_arch_check_processor_compat(void *opaque) { struct cpuinfo_x86 *c =3D &cpu_data(smp_processor_id()); - struct kvm_x86_init_ops *ops =3D opaque; =20 WARN_ON(!irqs_disabled()); =20 @@ -11481,7 +11480,7 @@ int kvm_arch_check_processor_compat(void *opaque) __cr4_reserved_bits(cpu_has, &boot_cpu_data)) return -EIO; =20 - return ops->check_processor_compatibility(); + return static_call(kvm_x86_check_processor_compatibility)(); } =20 bool kvm_vcpu_is_reset_bsp(struct kvm_vcpu *vcpu) --=20 2.25.1 From nobody Tue Jun 30 12:07:31 2026 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 0F156C433FE for ; Tue, 18 Jan 2022 06:49:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243875AbiARGts (ORCPT ); Tue, 18 Jan 2022 01:49:48 -0500 Received: from mga07.intel.com ([134.134.136.100]:32573 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243775AbiARGtq (ORCPT ); Tue, 18 Jan 2022 01:49:46 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1642488586; x=1674024586; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=osuXG+anjBv2tJZWB6/GHb9x1pC7y9dn5ivYyboeLSo=; b=OQPv49FnWbTk/L02sc2r1vsmVmqJ1ApP7tPv4wlrCfRwimimQ3A9GikJ JBgtsGBrQAx6HPSZdmcSav3EwHTKkFSDklXWebR3oVwXgSDBNDeUEqwJ1 gHPIvQWA7AF7mpip7Du480bjly3dLm93RTSzEIIfab4UMnbtfvK+hDSu6 W5SnkoCKmVlv8dj0ffaPu8RTwciDTNhk6LGU/mDXZe1vA1sY6ol2dyhba U/9lNamHg96jJpbxgmBf4WXVXNjssud+fW9fqzv9Ybi4qUSX53jSNEHkk T3/n+ycq7Q1eGIfMzH36m7RvPEv2Mi7ZyPdTcBzYmTh1+h13ZUt84nuRf Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10230"; a="308090438" X-IronPort-AV: E=Sophos;i="5.88,296,1635231600"; d="scan'208";a="308090438" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2022 22:49:46 -0800 X-IronPort-AV: E=Sophos;i="5.88,296,1635231600"; d="scan'208";a="531648627" Received: from hyperv-sh4.sh.intel.com ([10.239.48.22]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2022 22:49:35 -0800 From: Chao Gao To: kvm@vger.kernel.org, seanjc@google.com, pbonzini@redhat.com, kevin.tian@intel.com, tglx@linutronix.de Cc: Chao Gao , Marc Zyngier , 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 , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , "Maciej S. Szmigiero" , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Ravi Bangoria , Nicholas Piggin , Bharata B Rao , Nick Desaulniers , Fabiano Rosas , 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 v2 2/4] Partially revert "KVM: Pass kvm_init()'s opaque param to additional arch funcs" Date: Tue, 18 Jan 2022 14:44:25 +0800 Message-Id: <20220118064430.3882337-3-chao.gao@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220118064430.3882337-1-chao.gao@intel.com> References: <20220118064430.3882337-1-chao.gao@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 --- 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 868109cf96b4..92ab3d5516ce 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; } =20 -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 e59cb6246f76..c5dc4fe53bfc 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; } =20 -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; } =20 -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; } =20 -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 9c6d45d0d345..99c70d881cb6 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; } =20 -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 f8bc1948a8b5..6f3bf78afb29 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -11470,7 +11470,7 @@ void kvm_arch_hardware_unsetup(void) static_call(kvm_x86_hardware_unsetup)(); } =20 -int kvm_arch_check_processor_compat(void *opaque) +int kvm_arch_check_processor_compat(void) { struct cpuinfo_x86 *c =3D &cpu_data(smp_processor_id()); =20 diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 3c47b146851a..a51e9ab520fc 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1310,7 +1310,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 6e8e9d36f382..148f7169b431 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -5603,22 +5603,14 @@ struct kvm_vcpu * __percpu *kvm_get_running_vcpus(v= oid) return &kvm_running_vcpu; } =20 -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 =3D data; - - *c->ret =3D kvm_arch_check_processor_compat(c->opaque); + *(int *)rtn =3D kvm_arch_check_processor_compat(); } =20 int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, struct module *module) { - struct kvm_cpu_compat_check c; int r; int cpu; =20 @@ -5646,10 +5638,8 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsig= ned vcpu_align, if (r < 0) goto out_free_1; =20 - c.ret =3D &r; - c.opaque =3D 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; } --=20 2.25.1 From nobody Tue Jun 30 12:07:31 2026 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 404EFC433F5 for ; Tue, 18 Jan 2022 06:49:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243935AbiARGty (ORCPT ); Tue, 18 Jan 2022 01:49:54 -0500 Received: from mga07.intel.com ([134.134.136.100]:32573 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243178AbiARGtv (ORCPT ); Tue, 18 Jan 2022 01:49:51 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1642488590; x=1674024590; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=sukS5IeWozjhaGOQaV7YpNhdc/rV9F4bsauJImDN94o=; b=AV1LrNYOz7PARzX1SBU4+5FZ3Ing5SJIJfan5GC7yTf311/Pll9yJrWm t/7KExtcHmdS7Ht/14iuzRyzWQog53kyJunuSMRwF0G59YuDDq0oPDPG9 DlRglAIv33ekI5NuOpN9a4/KDFDh1OoBXMgx/kHgzLY6GYA7g6nxv+/y8 y8xipmfWLMvoAA2DflMgvUYTLyWPcwH5FcuHKuevX9gvHEWE/83K/0EXI PpYKJ2uMK1OOyrSpVjXVOAdFLRsUP28jhi0oRxAPEvTc2vcmVmwVK+77e 2y1m13p6KHyqMDndmjamrX+Za62yfNklDpB7FMG9EGyLaU7xqNcepzPYP Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10230"; a="308090444" X-IronPort-AV: E=Sophos;i="5.88,296,1635231600"; d="scan'208";a="308090444" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2022 22:49:50 -0800 X-IronPort-AV: E=Sophos;i="5.88,296,1635231600"; d="scan'208";a="531648655" Received: from hyperv-sh4.sh.intel.com ([10.239.48.22]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2022 22:49:47 -0800 From: Chao Gao To: kvm@vger.kernel.org, seanjc@google.com, pbonzini@redhat.com, kevin.tian@intel.com, tglx@linutronix.de Cc: Chao Gao , John Garry , Will Deacon , "Darrick J. Wong" , Shaokun Zhang , Thomas Richter , Tony Lindgren , linux-kernel@vger.kernel.org Subject: [PATCH v2 3/4] KVM: Rename and move CPUHP_AP_KVM_STARTING to ONLINE section Date: Tue, 18 Jan 2022 14:44:26 +0800 Message-Id: <20220118064430.3882337-4-chao.gao@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220118064430.3882337-1-chao.gao@intel.com> References: <20220118064430.3882337-1-chao.gao@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 | 28 ++++++++++++++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 773c83730906..14d354c8ce35 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, CPUHP_AP_KVM_ARM_VGIC_INIT_STARTING, CPUHP_AP_KVM_ARM_VGIC_STARTING, CPUHP_AP_KVM_ARM_TIMER_STARTING, @@ -200,6 +199,7 @@ enum cpuhp_state { =20 /* 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 148f7169b431..528741601122 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -4856,13 +4856,25 @@ static void hardware_enable_nolock(void *junk) } } =20 -static int kvm_starting_cpu(unsigned int cpu) +static int kvm_online_cpu(unsigned int cpu) { + int ret =3D 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) { hardware_enable_nolock(NULL); + if (atomic_read(&hardware_enable_failed)) { + ret =3D -EIO; + pr_warn("kvm: abort onlining CPU%d", cpu); + } + } raw_spin_unlock(&kvm_count_lock); - return 0; + return ret; } =20 static void hardware_disable_nolock(void *junk) @@ -4875,7 +4887,7 @@ static void hardware_disable_nolock(void *junk) kvm_arch_hardware_disable(); } =20 -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) @@ -5644,8 +5656,8 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsign= ed vcpu_align, goto out_free_2; } =20 - r =3D cpuhp_setup_state_nocalls(CPUHP_AP_KVM_STARTING, "kvm/cpu:starting", - kvm_starting_cpu, kvm_dying_cpu); + r =3D 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); @@ -5708,7 +5720,7 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsign= ed 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: @@ -5734,7 +5746,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(); --=20 2.25.1 From nobody Tue Jun 30 12:07:31 2026 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 78CD3C433F5 for ; Tue, 18 Jan 2022 06:49:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243178AbiARGt4 (ORCPT ); Tue, 18 Jan 2022 01:49:56 -0500 Received: from mga07.intel.com ([134.134.136.100]:32573 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243988AbiARGtz (ORCPT ); Tue, 18 Jan 2022 01:49:55 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1642488595; x=1674024595; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=MRlNCZ1rQT5dO9BKVcb4/9RCOl9rnCzSJkTuTsJPPF4=; b=PQVsXh2SIhAuVOxJ0TruaeSgXsh3Zwdmr+cITJW81QpVgw2FBfcpg1hV wBLpybfmMbr7/6jeQuMt2iVU9sHsWALbX0To1tQWmgmb3pevtQYZWzceT V7atTS9oN80joOgNRVrmQ98sCUp9J3siFaRSP0cQJFxpPVrtJ/E8JHWJ0 6IEPty0pGbjzofH1zX38wiyB2EH+MGxVo0XSkWfTTF05L2TE4lcxKEmNR ZeTqW0DI0rQc+T88wY5X7SE0Tpyl5jtq1bCKfuzt/MIdRG+CrimZkreOI SLDyIzuUiqZG3FqLsorobgs/PXlUGd4r33rl68AYZ4r5CYLeo/R6If9nf w==; X-IronPort-AV: E=McAfee;i="6200,9189,10230"; a="308090449" X-IronPort-AV: E=Sophos;i="5.88,296,1635231600"; d="scan'208";a="308090449" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2022 22:49:55 -0800 X-IronPort-AV: E=Sophos;i="5.88,296,1635231600"; d="scan'208";a="531648675" Received: from hyperv-sh4.sh.intel.com ([10.239.48.22]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2022 22:49:51 -0800 From: Chao Gao To: kvm@vger.kernel.org, seanjc@google.com, 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 v2 4/4] KVM: Do compatibility checks on hotplugged CPUs Date: Tue, 18 Jan 2022 14:44:27 +0800 Message-Id: <20220118064430.3882337-5-chao.gao@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220118064430.3882337-1-chao.gao@intel.com> References: <20220118064430.3882337-1-chao.gao@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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). Signed-off-by: Chao Gao --- arch/x86/kvm/x86.c | 11 +++++++++-- virt/kvm/kvm_main.c | 20 +++++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 6f3bf78afb29..21bdb5783f71 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -11472,9 +11472,16 @@ void kvm_arch_hardware_unsetup(void) =20 int kvm_arch_check_processor_compat(void) { - struct cpuinfo_x86 *c =3D &cpu_data(smp_processor_id()); + int cpu =3D smp_processor_id(); + struct cpuinfo_x86 *c =3D &cpu_data(cpu); =20 - 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)); =20 if (__cr4_reserved_bits(cpu_has, c) !=3D __cr4_reserved_bits(cpu_has, &boot_cpu_data)) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 528741601122..83f87fb1fa0a 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -4858,7 +4858,13 @@ static void hardware_enable_nolock(void *junk) =20 static int kvm_online_cpu(unsigned int cpu) { - int ret =3D 0; + int ret; + + ret =3D kvm_arch_check_processor_compat(); + if (ret) { + pr_warn("kvm: CPU%d is incompatible with online CPUs", cpu); + return ret; + } =20 raw_spin_lock(&kvm_count_lock); /* @@ -4916,6 +4922,17 @@ static int hardware_enable_all(void) { int r =3D 0; =20 + /* + * 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); =20 kvm_usage_count++; @@ -4930,6 +4947,7 @@ static int hardware_enable_all(void) } =20 raw_spin_unlock(&kvm_count_lock); + cpus_read_unlock(); =20 return r; } --=20 2.25.1