x86/hibernate/64: Mask off CR3's PCID bits in the saved CR3

Jiri reported a resume-from-hibernation failure triggered by PCID.
The root cause appears to be rather odd. The hibernation asm
restores a CR3 value that comes from the image header. If the image
kernel has PCID on, it's entirely reasonable for this CR3 value to
have one of the low 12 bits set. The restore code restores it with
CR4.PCIDE=0, which means that those low 12 bits are accepted by the
CPU but are either ignored or interpreted as a caching mode. This
is odd, but still works. We blow up later when the image kernel
restores CR4, though, since changing CR4.PCIDE with CR3[11:0] != 0
is illegal. Boom!

FWIW, it's entirely unclear to me what's supposed to happen if a PAE
kernel restores a non-PAE image or vice versa. Ditto for LA57.

Reported-by: Jiri Kosina <jikos@kernel.org>
Tested-by: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bpetkov@suse.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Fixes: 660da7c9228f ("x86/mm: Enable CR4.PCIDE on supported systems")
Link: http://lkml.kernel.org/r/18ca57090651a6341e97083883f9e814c4f14684.1504847163.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Andy Lutomirski and committed by
Ingo Molnar
f34902c5 a376e7f9

+20 -1
+20 -1
arch/x86/power/hibernate_64.c
··· 295 295 return -EOVERFLOW; 296 296 rdr->jump_address = (unsigned long)restore_registers; 297 297 rdr->jump_address_phys = __pa_symbol(restore_registers); 298 - rdr->cr3 = restore_cr3; 298 + 299 + /* 300 + * The restore code fixes up CR3 and CR4 in the following sequence: 301 + * 302 + * [in hibernation asm] 303 + * 1. CR3 <= temporary page tables 304 + * 2. CR4 <= mmu_cr4_features (from the kernel that restores us) 305 + * 3. CR3 <= rdr->cr3 306 + * 4. CR4 <= mmu_cr4_features (from us, i.e. the image kernel) 307 + * [in restore_processor_state()] 308 + * 5. CR4 <= saved CR4 309 + * 6. CR3 <= saved CR3 310 + * 311 + * Our mmu_cr4_features has CR4.PCIDE=0, and toggling 312 + * CR4.PCIDE while CR3's PCID bits are nonzero is illegal, so 313 + * rdr->cr3 needs to point to valid page tables but must not 314 + * have any of the PCID bits set. 315 + */ 316 + rdr->cr3 = restore_cr3 & ~CR3_PCID_MASK; 317 + 299 318 rdr->magic = RESTORE_MAGIC; 300 319 301 320 hibernation_e820_save(rdr->e820_digest);