linux/arch/x86
Rafael J. Wysocki 406f992e4a x86 / hibernate: Use hlt_play_dead() when resuming from hibernation
On Intel hardware, native_play_dead() uses mwait_play_dead() by
default and only falls back to the other methods if that fails.
That also happens during resume from hibernation, when the restore
(boot) kernel runs disable_nonboot_cpus() to take all of the CPUs
except for the boot one offline.

However, that is problematic, because the address passed to
__monitor() in mwait_play_dead() is likely to be written to in the
last phase of hibernate image restoration and that causes the "dead"
CPU to start executing instructions again.  Unfortunately, the page
containing the address in that CPU's instruction pointer may not be
valid any more at that point.

First, that page may have been overwritten with image kernel memory
contents already, so the instructions the CPU attempts to execute may
simply be invalid.  Second, the page tables previously used by that
CPU may have been overwritten by image kernel memory contents, so the
address in its instruction pointer is impossible to resolve then.

A report from Varun Koyyalagunta and investigation carried out by
Chen Yu show that the latter sometimes happens in practice.

To prevent it from happening, temporarily change the smp_ops.play_dead
pointer during resume from hibernation so that it points to a special
"play dead" routine which uses hlt_play_dead() and avoids the
inadvertent "revivals" of "dead" CPUs this way.

A slightly unpleasant consequence of this change is that if the
system is hibernated with one or more CPUs offline, it will generally
draw more power after resume than it did before hibernation, because
the physical state entered by CPUs via hlt_play_dead() is higher-power
than the mwait_play_dead() one in the majority of cases.  It is
possible to work around this, but it is unclear how much of a problem
that's going to be in practice, so the workaround will be implemented
later if it turns out to be necessary.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=106371
Reported-by: Varun Koyyalagunta <cpudebug@centtech.com>
Original-by: Chen Yu <yu.c.chen@intel.com>
Tested-by: Chen Yu <yu.c.chen@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
2016-07-15 22:42:48 +02:00
..
boot x86, build: copy ldlinux.c32 to image.iso 2016-06-07 15:54:18 -07:00
configs arch/defconfig: remove CONFIG_RESOURCE_COUNTERS 2016-05-23 17:04:14 -07:00
crypto Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6 2016-05-20 10:25:16 -07:00
entry Merge branch 'kbuild' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild 2016-05-26 22:01:22 -07:00
events perf/x86/intel/uncore: Remove SBOX support for Broadwell server 2016-06-03 08:39:38 +02:00
ia32 mm: remove more IS_ERR_VALUE abuses 2016-05-27 15:57:31 -07:00
include x86 / hibernate: Use hlt_play_dead() when resuming from hibernation 2016-07-15 22:42:48 +02:00
kernel x86 / hibernate: Use hlt_play_dead() when resuming from hibernation 2016-07-15 22:42:48 +02:00
kvm kvm: vmx: check apicv is active before using VT-d posted interrupt 2016-06-16 09:38:24 +02:00
lguest x86/paravirt: Remove paravirt_enabled() 2016-04-22 10:29:07 +02:00
lib Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2016-05-16 15:15:17 -07:00
math-emu
mm x86: get rid of superfluous __GFP_REPEAT 2016-06-24 17:23:52 -07:00
net bpf, x86: add support for constant blinding 2016-05-16 13:49:32 -04:00
oprofile x86/cpufeature: Replace cpu_has_apic with boot_cpu_has() usage 2016-04-13 11:37:41 +02:00
pci xen: bug fixes for 4.7-rc0 2016-05-24 10:22:34 -07:00
platform x86/efi: get rid of superfluous __GFP_REPEAT 2016-06-24 17:23:52 -07:00
power x86 / hibernate: Use hlt_play_dead() when resuming from hibernation 2016-07-15 22:42:48 +02:00
purgatory kbuild: delete unnecessary "@:" 2016-04-20 10:36:57 +02:00
ras x86/RAS: Add SMCA support to AMD Error Injector 2016-05-12 09:08:23 +02:00
realmode kbuild: delete unnecessary "@:" 2016-04-20 10:36:57 +02:00
tools x86/KASLR: Clean up unused code from old 'run_size' and rename it to 'kernel_total_size' 2016-04-29 11:03:30 +02:00
um Merge branch 'for-linus-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml 2016-05-27 18:54:59 -07:00
video x86/video: Don't assume all FB devices are PCI devices 2016-03-15 11:08:26 +01:00
xen Merge branch 'akpm' (patches from Andrew) 2016-06-24 19:08:33 -07:00
.gitignore
Kbuild
Kconfig isa: Allow ISA-style drivers on modern systems 2016-06-17 20:21:12 -07:00
Kconfig.cpu
Kconfig.debug Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2016-03-15 09:32:27 -07:00
Makefile x86/init: Rename EBDA code file 2016-04-22 10:29:07 +02:00
Makefile_32.cpu
Makefile.um