Drop kvm_rebooting and all related uses. Virtualization is now disabled immediately before a CPU shuts down, eliminating any chance of executing virtualization instructions during reboot. Signed-off-by: Xin Li (Intel) --- arch/x86/kvm/svm/vmenter.S | 42 ++++++++++++-------------------------- arch/x86/kvm/vmx/tdx.c | 4 +--- arch/x86/kvm/vmx/vmenter.S | 2 -- arch/x86/kvm/x86.c | 8 ++------ include/linux/kvm_host.h | 1 - virt/kvm/kvm_main.c | 15 ++------------ 6 files changed, 18 insertions(+), 54 deletions(-) diff --git a/arch/x86/kvm/svm/vmenter.S b/arch/x86/kvm/svm/vmenter.S index 235c4af6b692..d530f62679b9 100644 --- a/arch/x86/kvm/svm/vmenter.S +++ b/arch/x86/kvm/svm/vmenter.S @@ -145,7 +145,6 @@ SYM_FUNC_START(__svm_vcpu_run) */ mov SVM_vmcb01_pa(%_ASM_DI), %_ASM_AX 1: vmload %_ASM_AX -2: /* Get svm->current_vmcb->pa into RAX. */ mov SVM_current_vmcb(%_ASM_DI), %_ASM_AX @@ -173,8 +172,8 @@ SYM_FUNC_START(__svm_vcpu_run) VM_CLEAR_CPU_BUFFERS /* Enter guest mode */ -3: vmrun %_ASM_AX -4: +2: vmrun %_ASM_AX + /* Pop @svm to RAX while it's the only available register. */ pop %_ASM_AX @@ -200,13 +199,11 @@ SYM_FUNC_START(__svm_vcpu_run) mov %_ASM_AX, %_ASM_DI mov SVM_vmcb01_pa(%_ASM_DI), %_ASM_AX -5: vmsave %_ASM_AX -6: +3: vmsave %_ASM_AX /* Restores GSBASE among other things, allowing access to percpu data. */ pop %_ASM_AX -7: vmload %_ASM_AX -8: +4: vmload %_ASM_AX /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */ FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_VMEXIT @@ -269,23 +266,12 @@ SYM_FUNC_START(__svm_vcpu_run) RESTORE_GUEST_SPEC_CTRL_BODY RESTORE_HOST_SPEC_CTRL_BODY (%_ASM_SP) -10: cmpb $0, _ASM_RIP(kvm_rebooting) - jne 2b - ud2 -30: cmpb $0, _ASM_RIP(kvm_rebooting) - jne 4b - ud2 -50: cmpb $0, _ASM_RIP(kvm_rebooting) - jne 6b - ud2 -70: cmpb $0, _ASM_RIP(kvm_rebooting) - jne 8b - ud2 - - _ASM_EXTABLE(1b, 10b) - _ASM_EXTABLE(3b, 30b) - _ASM_EXTABLE(5b, 50b) - _ASM_EXTABLE(7b, 70b) +5: ud2 + + _ASM_EXTABLE(1b, 5b) + _ASM_EXTABLE(2b, 5b) + _ASM_EXTABLE(3b, 5b) + _ASM_EXTABLE(4b, 5b) SYM_FUNC_END(__svm_vcpu_run) @@ -343,7 +329,7 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run) /* Enter guest mode */ 1: vmrun %rax -2: + /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */ FILL_RETURN_BUFFER %rax, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_VMEXIT @@ -365,11 +351,9 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run) RESTORE_GUEST_SPEC_CTRL_BODY RESTORE_HOST_SPEC_CTRL_BODY %sil -3: cmpb $0, kvm_rebooting(%rip) - jne 2b - ud2 +2: ud2 - _ASM_EXTABLE(1b, 3b) + _ASM_EXTABLE(1b, 2b) SYM_FUNC_END(__svm_sev_es_vcpu_run) #endif /* CONFIG_KVM_AMD_SEV */ diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index 66744f5768c8..cfe5f8b63973 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -2052,10 +2052,8 @@ int tdx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t fastpath) * Handle TDX SW errors, including TDX_SEAMCALL_UD, TDX_SEAMCALL_GP and * TDX_SEAMCALL_VMFAILINVALID. */ - if (unlikely((vp_enter_ret & TDX_SW_ERROR) == TDX_SW_ERROR)) { - KVM_BUG_ON(!kvm_rebooting, vcpu->kvm); + if (unlikely((vp_enter_ret & TDX_SW_ERROR) == TDX_SW_ERROR)) goto unhandled_exit; - } if (unlikely(tdx_failed_vmentry(vcpu))) { /* diff --git a/arch/x86/kvm/vmx/vmenter.S b/arch/x86/kvm/vmx/vmenter.S index 0a6cf5bff2aa..3457b5e1f856 100644 --- a/arch/x86/kvm/vmx/vmenter.S +++ b/arch/x86/kvm/vmx/vmenter.S @@ -293,8 +293,6 @@ SYM_INNER_LABEL_ALIGN(vmx_vmexit, SYM_L_GLOBAL) RET .Lfixup: - cmpb $0, _ASM_RIP(kvm_rebooting) - jne .Lvmfail ud2 .Lvmfail: /* VM-Fail: set return value to 1 */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 8b9f64770684..1abc4550fd76 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -687,15 +687,11 @@ static void drop_user_return_notifiers(void) /* * Handle a fault on a hardware virtualization (VMX or SVM) instruction. - * - * Hardware virtualization extension instructions may fault if a reboot turns - * off virtualization while processes are running. Usually after catching the - * fault we just panic; during reboot instead the instruction is ignored. */ noinstr void kvm_spurious_fault(void) { - /* Fault while not rebooting. We want the trace. */ - BUG_ON(!kvm_rebooting); + /* We want the trace. */ + BUG_ON(true); } EXPORT_SYMBOL_GPL(kvm_spurious_fault); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 151305b33bce..2d9c306db4f0 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -2276,7 +2276,6 @@ static inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu) #ifdef CONFIG_KVM_GENERIC_HARDWARE_ENABLING extern bool enable_virt_at_load; -extern bool kvm_rebooting; #endif extern unsigned int halt_poll_ns; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 6e86c6a45a71..0037761c1a51 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -5559,9 +5559,6 @@ bool enable_virt_at_load = true; module_param(enable_virt_at_load, bool, 0444); EXPORT_SYMBOL_GPL(enable_virt_at_load); -__visible bool kvm_rebooting; -EXPORT_SYMBOL_GPL(kvm_rebooting); - static DEFINE_PER_CPU(bool, virtualization_enabled); static DEFINE_MUTEX(kvm_usage_lock); static int kvm_usage_count; @@ -5610,18 +5607,10 @@ static int kvm_offline_cpu(unsigned int cpu) static void kvm_shutdown(void) { /* - * Disable hardware virtualization and set kvm_rebooting to indicate - * that KVM has asynchronously disabled hardware virtualization, i.e. - * that relevant errors and exceptions aren't entirely unexpected. - * Some flavors of hardware virtualization need to be disabled before - * transferring control to firmware (to perform shutdown/reboot), e.g. - * on x86, virtualization can block INIT interrupts, which are used by - * firmware to pull APs back under firmware control. Note, this path - * is used for both shutdown and reboot scenarios, i.e. neither name is - * 100% comprehensive. + * Note, this path is used for both shutdown and reboot scenarios, i.e. + * neither name is 100% comprehensive. */ pr_info("kvm: exiting hardware virtualization\n"); - kvm_rebooting = true; on_each_cpu(kvm_disable_virtualization_cpu, NULL, 1); } -- 2.51.0