@@ -160,6 +160,7 @@ int arch_hibernation_header_save(void *addr, unsigned int max_size)
#ifdef CONFIG_X86_64
rdr->jump_address = (unsigned long)restore_registers;
rdr->jump_address_phys = __pa_symbol(restore_registers);
+#endif
/*
* The restore code fixes up CR3 and CR4 in the following sequence:
@@ -179,7 +180,6 @@ int arch_hibernation_header_save(void *addr, unsigned int max_size)
* have any of the PCID bits set.
*/
rdr->cr3 = restore_cr3 & ~CR3_PCID_MASK;
-#endif
return hibernation_e820_save(rdr->e820_digest);
}
@@ -201,8 +201,8 @@ int arch_hibernation_header_restore(void *addr)
#ifdef CONFIG_X86_64
restore_jump_address = rdr->jump_address;
jump_address_phys = rdr->jump_address_phys;
- restore_cr3 = rdr->cr3;
#endif
+ restore_cr3 = rdr->cr3;
if (hibernation_e820_mismatch(rdr->e820_digest)) {
pr_crit("Hibernate inconsistent memory map detected!\n");
@@ -25,6 +25,10 @@ ENTRY(swsusp_arch_suspend)
pushfl
popl saved_context_eflags
+ /* save cr3 */
+ movl %cr3, %eax
+ movl %eax, restore_cr3
+
FRAME_BEGIN
call swsusp_save
FRAME_END
@@ -32,6 +36,8 @@ ENTRY(swsusp_arch_suspend)
ENDPROC(swsusp_arch_suspend)
ENTRY(restore_image)
+ movl restore_cr3, %ebp
+
movl mmu_cr4_features, %ecx
movl temp_pgt, %eax
movl %eax, %cr3
@@ -66,9 +72,7 @@ done:
.align PAGE_SIZE
ENTRY(restore_registers)
/* go back to the original page tables */
- movl $swapper_pg_dir, %eax
- subl $__PAGE_OFFSET, %eax
- movl %eax, %cr3
+ movl %ebp, %cr3
movl mmu_cr4_features, %ecx
jecxz 1f # cr4 Pentium and higher, skip if zero
movl %ecx, %cr4; # turn PGE back on