x86/reboot: KVM: Disable SVM during reboot via virt/KVM reboot callback
authorSean Christopherson <seanjc@google.com>
Fri, 21 Jul 2023 20:18:44 +0000 (13:18 -0700)
committerSean Christopherson <seanjc@google.com>
Thu, 3 Aug 2023 22:37:14 +0000 (15:37 -0700)
Use the virt callback to disable SVM (and set GIF=1) during an emergency
instead of blindly attempting to disable SVM.  Like the VMX case, if a
hypervisor, i.e. KVM, isn't loaded/active, SVM can't be in use.

Acked-by: Kai Huang <kai.huang@intel.com>
Link: https://lore.kernel.org/r/20230721201859.2307736-5-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/include/asm/virtext.h
arch/x86/kernel/reboot.c
arch/x86/kvm/svm/svm.c

index 5bc29fab15da7d9d441a4cd0b1ddfe54cf8cd41f..aaed66249ccf3c3782057d0337be7899a43bb616 100644 (file)
@@ -133,12 +133,4 @@ fault:
        }
 }
 
-/** Makes sure SVM is disabled, if it is supported on the CPU
- */
-static inline void cpu_emergency_svm_disable(void)
-{
-       if (cpu_has_svm(NULL))
-               cpu_svm_disable();
-}
-
 #endif /* _ASM_X86_VIRTEX_H */
index d2d0f2672a64d48568edf29a023ba0d3f49ca8e4..48ad2d1ff83d56fa7ead07c7c82c7d5967d0ef66 100644 (file)
@@ -826,9 +826,6 @@ void cpu_emergency_disable_virtualization(void)
        if (callback)
                callback();
        rcu_read_unlock();
-
-       /* KVM_AMD doesn't yet utilize the common callback. */
-       cpu_emergency_svm_disable();
 }
 
 #if defined(CONFIG_SMP)
index d381ad4245542c2d30805433fe2a381f2f5cddf0..1ae9c2c7eacb3c870ffcc8cfefa9c891f604cc1e 100644 (file)
@@ -39,6 +39,7 @@
 #include <asm/spec-ctrl.h>
 #include <asm/cpu_device_id.h>
 #include <asm/traps.h>
+#include <asm/reboot.h>
 #include <asm/fpu/api.h>
 
 #include <asm/virtext.h>
@@ -563,6 +564,11 @@ out:
        preempt_enable();
 }
 
+static void svm_emergency_disable(void)
+{
+       cpu_svm_disable();
+}
+
 static void svm_hardware_disable(void)
 {
        /* Make sure we clean up behind us */
@@ -5209,6 +5215,13 @@ static struct kvm_x86_init_ops svm_init_ops __initdata = {
        .pmu_ops = &amd_pmu_ops,
 };
 
+static void __svm_exit(void)
+{
+       kvm_x86_vendor_exit();
+
+       cpu_emergency_unregister_virt_callback(svm_emergency_disable);
+}
+
 static int __init svm_init(void)
 {
        int r;
@@ -5222,6 +5235,8 @@ static int __init svm_init(void)
        if (r)
                return r;
 
+       cpu_emergency_register_virt_callback(svm_emergency_disable);
+
        /*
         * Common KVM initialization _must_ come last, after this, /dev/kvm is
         * exposed to userspace!
@@ -5234,14 +5249,14 @@ static int __init svm_init(void)
        return 0;
 
 err_kvm_init:
-       kvm_x86_vendor_exit();
+       __svm_exit();
        return r;
 }
 
 static void __exit svm_exit(void)
 {
        kvm_exit();
-       kvm_x86_vendor_exit();
+       __svm_exit();
 }
 
 module_init(svm_init)