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