Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
c5759124 | 2 | /* |
1da177e4 LT |
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> | |
0341c14d | 12 | #include <asm/page_types.h> |
86feeaa8 | 13 | #include <asm/asm-offsets.h> |
c171f465 | 14 | #include <asm/processor-flags.h> |
8e5b2a3c | 15 | #include <asm/frame.h> |
1da177e4 | 16 | |
c171f465 | 17 | .text |
1da177e4 | 18 | |
6d685e53 | 19 | SYM_FUNC_START(swsusp_arch_suspend) |
1da177e4 LT |
20 | movl %esp, saved_context_esp |
21 | movl %ebx, saved_context_ebx | |
22 | movl %ebp, saved_context_ebp | |
23 | movl %esi, saved_context_esi | |
24 | movl %edi, saved_context_edi | |
c171f465 UB |
25 | pushfl |
26 | popl saved_context_eflags | |
1da177e4 | 27 | |
32aa2764 ZG |
28 | /* save cr3 */ |
29 | movl %cr3, %eax | |
30 | movl %eax, restore_cr3 | |
31 | ||
8e5b2a3c | 32 | FRAME_BEGIN |
1da177e4 | 33 | call swsusp_save |
8e5b2a3c | 34 | FRAME_END |
f94909ce | 35 | RET |
6d685e53 | 36 | SYM_FUNC_END(swsusp_arch_suspend) |
1da177e4 | 37 | |
78762b0e | 38 | SYM_CODE_START(restore_image) |
5331d2c7 ZG |
39 | /* prepare to jump to the image kernel */ |
40 | movl restore_jump_address, %ebx | |
32aa2764 ZG |
41 | movl restore_cr3, %ebp |
42 | ||
8ae06d22 | 43 | movl mmu_cr4_features, %ecx |
6bae499a ZG |
44 | |
45 | /* jump to relocated restore code */ | |
46 | movl relocated_restore_code, %eax | |
47 | jmpl *%eax | |
78762b0e | 48 | SYM_CODE_END(restore_image) |
6bae499a ZG |
49 | |
50 | /* code below has been relocated to a safe page */ | |
78762b0e | 51 | SYM_CODE_START(core_restore_code) |
7c0a9827 | 52 | movl temp_pgt, %eax |
e532c06f | 53 | movl %eax, %cr3 |
1da177e4 | 54 | |
8ae06d22 SL |
55 | jecxz 1f # cr4 Pentium and higher, skip if zero |
56 | andl $~(X86_CR4_PGE), %ecx | |
57 | movl %ecx, %cr4; # turn off PGE | |
58 | movl %cr3, %eax; # flush TLB | |
59 | movl %eax, %cr3 | |
60 | 1: | |
75534b50 | 61 | movl restore_pblist, %edx |
1da177e4 LT |
62 | .p2align 4,,7 |
63 | ||
64 | copy_loop: | |
65 | testl %edx, %edx | |
66 | jz done | |
67 | ||
68 | movl pbe_address(%edx), %esi | |
69 | movl pbe_orig_address(%edx), %edi | |
70 | ||
0b0a6b1f | 71 | movl $(PAGE_SIZE >> 2), %ecx |
1da177e4 LT |
72 | rep |
73 | movsl | |
74 | ||
75 | movl pbe_next(%edx), %edx | |
76 | jmp copy_loop | |
77 | .p2align 4,,7 | |
78 | ||
79 | done: | |
5331d2c7 | 80 | jmpl *%ebx |
78762b0e | 81 | SYM_CODE_END(core_restore_code) |
8e5b2a3c ZG |
82 | |
83 | /* code below belongs to the image kernel */ | |
84 | .align PAGE_SIZE | |
6d685e53 | 85 | SYM_FUNC_START(restore_registers) |
2d4a34c9 | 86 | /* go back to the original page tables */ |
32aa2764 | 87 | movl %ebp, %cr3 |
e532c06f DF |
88 | movl mmu_cr4_features, %ecx |
89 | jecxz 1f # cr4 Pentium and higher, skip if zero | |
e532c06f DF |
90 | movl %ecx, %cr4; # turn PGE back on |
91 | 1: | |
1da177e4 LT |
92 | |
93 | movl saved_context_esp, %esp | |
94 | movl saved_context_ebp, %ebp | |
95 | movl saved_context_ebx, %ebx | |
96 | movl saved_context_esi, %esi | |
97 | movl saved_context_edi, %edi | |
98 | ||
c171f465 UB |
99 | pushl saved_context_eflags |
100 | popfl | |
1da177e4 | 101 | |
cc456c4e KRW |
102 | /* Saved in save_processor_state. */ |
103 | movl $saved_context, %eax | |
104 | lgdt saved_context_gdt_desc(%eax) | |
105 | ||
1da177e4 LT |
106 | xorl %eax, %eax |
107 | ||
1fca4ba0 ZG |
108 | /* tell the hibernation core that we've just restored the memory */ |
109 | movl %eax, in_suspend | |
110 | ||
f94909ce | 111 | RET |
6d685e53 | 112 | SYM_FUNC_END(restore_registers) |