summarylogtreecommitdiffstats
path: root/x86-hibernate-Use-hlt_play_dead-when-resuming-from-hibernation.patch
diff options
context:
space:
mode:
authordrrossum2016-08-03 08:07:51 -0500
committerdrrossum2016-08-03 08:07:51 -0500
commit6c4060b1a2cc0723c20932e1b81fa52bb80dd38c (patch)
tree888a1b29b52f58b5b651a5b99166f57ddceb04a5 /x86-hibernate-Use-hlt_play_dead-when-resuming-from-hibernation.patch
parent3c7c0c99fa7cf983b82326eab8e9c9dc6fde72d8 (diff)
downloadaur-6c4060b1a2cc0723c20932e1b81fa52bb80dd38c.tar.gz
update hibernation patches and bump to 4.6.5
Diffstat (limited to 'x86-hibernate-Use-hlt_play_dead-when-resuming-from-hibernation.patch')
-rw-r--r--x86-hibernate-Use-hlt_play_dead-when-resuming-from-hibernation.patch101
1 files changed, 101 insertions, 0 deletions
diff --git a/x86-hibernate-Use-hlt_play_dead-when-resuming-from-hibernation.patch b/x86-hibernate-Use-hlt_play_dead-when-resuming-from-hibernation.patch
new file mode 100644
index 000000000000..0517f9b6eca6
--- /dev/null
+++ b/x86-hibernate-Use-hlt_play_dead-when-resuming-from-hibernation.patch
@@ -0,0 +1,101 @@
+Index: linux-pm/kernel/power/hibernate.c
+===================================================================
+--- linux-pm.orig/kernel/power/hibernate.c
++++ linux-pm/kernel/power/hibernate.c
+@@ -409,6 +409,11 @@ int hibernation_snapshot(int platform_mo
+ goto Close;
+ }
+
++int __weak hibernate_resume_nonboot_cpu_disable(void)
++{
++ return disable_nonboot_cpus();
++}
++
+ /**
+ * resume_target_kernel - Restore system state from a hibernation image.
+ * @platform_mode: Whether or not to use the platform driver.
+@@ -433,7 +438,7 @@ static int resume_target_kernel(bool pla
+ if (error)
+ goto Cleanup;
+
+- error = disable_nonboot_cpus();
++ error = hibernate_resume_nonboot_cpu_disable();
+ if (error)
+ goto Enable_cpus;
+
+Index: linux-pm/kernel/power/power.h
+===================================================================
+--- linux-pm.orig/kernel/power/power.h
++++ linux-pm/kernel/power/power.h
+@@ -38,6 +38,8 @@ static inline char *check_image_kernel(s
+ }
+ #endif /* CONFIG_ARCH_HIBERNATION_HEADER */
+
++extern int hibernate_resume_nonboot_cpu_disable(void);
++
+ /*
+ * Keep some memory free so that I/O operations can succeed without paging
+ * [Might this be more than 4 MB?]
+Index: linux-pm/arch/x86/power/cpu.c
+===================================================================
+--- linux-pm.orig/arch/x86/power/cpu.c
++++ linux-pm/arch/x86/power/cpu.c
+@@ -266,6 +266,27 @@ void notrace restore_processor_state(voi
+ EXPORT_SYMBOL(restore_processor_state);
+ #endif
+
++#if defined(CONFIG_HIBERNATION) && defined(CONFIG_HOTPLUG_CPU)
++bool force_hlt_play_dead __read_mostly;
++
++int hibernate_resume_nonboot_cpu_disable(void)
++{
++ int ret;
++
++ /*
++ * Ensure that MONITOR/MWAIT will not be used in the "play dead" loop
++ * during hibernate image restoration, because it is likely that the
++ * monitored address will be actually written to at that time and then
++ * the "dead" CPU may start executing instructions from an image
++ * kernel's page (and that may not be the "play dead" loop any more).
++ */
++ force_hlt_play_dead = true;
++ ret = disable_nonboot_cpus();
++ force_hlt_play_dead = false;
++ return ret;
++}
++#endif
++
+ /*
+ * When bsp_check() is called in hibernate and suspend, cpu hotplug
+ * is disabled already. So it's unnessary to handle race condition between
+Index: linux-pm/arch/x86/kernel/smpboot.c
+===================================================================
+--- linux-pm.orig/arch/x86/kernel/smpboot.c
++++ linux-pm/arch/x86/kernel/smpboot.c
+@@ -1642,6 +1642,9 @@ void native_play_dead(void)
+ play_dead_common();
+ tboot_shutdown(TB_SHUTDOWN_WFS);
+
++ if (force_hlt_play_dead)
++ hlt_play_dead();
++
+ mwait_play_dead(); /* Only returns on failure */
+ if (cpuidle_play_dead())
+ hlt_play_dead();
+Index: linux-pm/arch/x86/include/asm/cpu.h
+===================================================================
+--- linux-pm.orig/arch/x86/include/asm/cpu.h
++++ linux-pm/arch/x86/include/asm/cpu.h
+@@ -26,6 +26,12 @@ struct x86_cpu {
+ };
+
+ #ifdef CONFIG_HOTPLUG_CPU
++#ifdef CONFIG_HIBERNATION
++extern bool force_hlt_play_dead;
++#else
++#define force_hlt_play_dead (false)
++#endif
++
+ extern int arch_register_cpu(int num);
+ extern void arch_unregister_cpu(int);
+ extern void start_cpu0(void);