x86/power: Fix 'nosmt' vs hibernation triple fault during resume
[sfrench/cifs-2.6.git] / arch / x86 / power / hibernate.c
index 4845b8c7be7f428a5ca0f38a233ae472adff1a84..fc413717a45f727969e0bd0a9b93ee625cd9a462 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/suspend.h>
 #include <linux/scatterlist.h>
 #include <linux/kdebug.h>
+#include <linux/cpu.h>
 
 #include <crypto/hash.h>
 
@@ -245,3 +246,35 @@ out:
        __flush_tlb_all();
        return 0;
 }
+
+int arch_resume_nosmt(void)
+{
+       int ret = 0;
+       /*
+        * We reached this while coming out of hibernation. This means
+        * that SMT siblings are sleeping in hlt, as mwait is not safe
+        * against control transition during resume (see comment in
+        * hibernate_resume_nonboot_cpu_disable()).
+        *
+        * If the resumed kernel has SMT disabled, we have to take all the
+        * SMT siblings out of hlt, and offline them again so that they
+        * end up in mwait proper.
+        *
+        * Called with hotplug disabled.
+        */
+       cpu_hotplug_enable();
+       if (cpu_smt_control == CPU_SMT_DISABLED ||
+                       cpu_smt_control == CPU_SMT_FORCE_DISABLED) {
+               enum cpuhp_smt_control old = cpu_smt_control;
+
+               ret = cpuhp_smt_enable();
+               if (ret)
+                       goto out;
+               ret = cpuhp_smt_disable(old);
+               if (ret)
+                       goto out;
+       }
+out:
+       cpu_hotplug_disable();
+       return ret;
+}