1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * This may not use any stack, nor any variable that is not "NoSave": 4 * 5 * Its rewriting one kernel image with another. What is stack in "old" 6 * image could very well be data page in "new" image, and overwriting 7 * your own stack under you is bad idea. 8 */ 9 10#include <linux/linkage.h> 11#include <asm/segment.h> 12#include <asm/page_types.h> 13#include <asm/asm-offsets.h> 14#include <asm/processor-flags.h> 15 16.text 17 18ENTRY(swsusp_arch_suspend) 19 movl %esp, saved_context_esp 20 movl %ebx, saved_context_ebx 21 movl %ebp, saved_context_ebp 22 movl %esi, saved_context_esi 23 movl %edi, saved_context_edi 24 pushfl 25 popl saved_context_eflags 26 27 call swsusp_save 28 ret 29 30ENTRY(restore_image) 31 movl mmu_cr4_features, %ecx 32 movl resume_pg_dir, %eax 33 subl $__PAGE_OFFSET, %eax 34 movl %eax, %cr3 35 36 jecxz 1f # cr4 Pentium and higher, skip if zero 37 andl $~(X86_CR4_PGE), %ecx 38 movl %ecx, %cr4; # turn off PGE 39 movl %cr3, %eax; # flush TLB 40 movl %eax, %cr3 411: 42 movl restore_pblist, %edx 43 .p2align 4,,7 44 45copy_loop: 46 testl %edx, %edx 47 jz done 48 49 movl pbe_address(%edx), %esi 50 movl pbe_orig_address(%edx), %edi 51 52 movl $1024, %ecx 53 rep 54 movsl 55 56 movl pbe_next(%edx), %edx 57 jmp copy_loop 58 .p2align 4,,7 59 60done: 61 /* go back to the original page tables */ 62 movl $swapper_pg_dir, %eax 63 subl $__PAGE_OFFSET, %eax 64 movl %eax, %cr3 65 movl mmu_cr4_features, %ecx 66 jecxz 1f # cr4 Pentium and higher, skip if zero 67 movl %ecx, %cr4; # turn PGE back on 681: 69 70 movl saved_context_esp, %esp 71 movl saved_context_ebp, %ebp 72 movl saved_context_ebx, %ebx 73 movl saved_context_esi, %esi 74 movl saved_context_edi, %edi 75 76 pushl saved_context_eflags 77 popfl 78 79 /* Saved in save_processor_state. */ 80 movl $saved_context, %eax 81 lgdt saved_context_gdt_desc(%eax) 82 83 xorl %eax, %eax 84 85 ret 86