hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/arch/x86/power/hibernate_32.c
....@@ -1,22 +1,19 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Hibernation support specific for i386 - temporary page tables
3
- *
4
- * Distribute under GPLv2
54 *
65 * Copyright (c) 2006 Rafael J. Wysocki <rjw@sisk.pl>
76 */
87
98 #include <linux/gfp.h>
109 #include <linux/suspend.h>
11
-#include <linux/bootmem.h>
10
+#include <linux/memblock.h>
11
+#include <linux/pgtable.h>
1212
1313 #include <asm/page.h>
14
-#include <asm/pgtable.h>
1514 #include <asm/mmzone.h>
1615 #include <asm/sections.h>
17
-
18
-/* Defined in hibernate_asm_32.S */
19
-extern int restore_image(void);
16
+#include <asm/suspend.h>
2017
2118 /* Pointer to the temporary resume page tables */
2219 pgd_t *resume_pg_dir;
....@@ -145,6 +142,32 @@
145142 #endif
146143 }
147144
145
+static int set_up_temporary_text_mapping(pgd_t *pgd_base)
146
+{
147
+ pgd_t *pgd;
148
+ pmd_t *pmd;
149
+ pte_t *pte;
150
+
151
+ pgd = pgd_base + pgd_index(restore_jump_address);
152
+
153
+ pmd = resume_one_md_table_init(pgd);
154
+ if (!pmd)
155
+ return -ENOMEM;
156
+
157
+ if (boot_cpu_has(X86_FEATURE_PSE)) {
158
+ set_pmd(pmd + pmd_index(restore_jump_address),
159
+ __pmd((jump_address_phys & PMD_MASK) | pgprot_val(PAGE_KERNEL_LARGE_EXEC)));
160
+ } else {
161
+ pte = resume_one_page_table_init(pmd);
162
+ if (!pte)
163
+ return -ENOMEM;
164
+ set_pte(pte + pte_index(restore_jump_address),
165
+ __pte((jump_address_phys & PAGE_MASK) | pgprot_val(PAGE_KERNEL_EXEC)));
166
+ }
167
+
168
+ return 0;
169
+}
170
+
148171 asmlinkage int swsusp_arch_resume(void)
149172 {
150173 int error;
....@@ -154,22 +177,22 @@
154177 return -ENOMEM;
155178
156179 resume_init_first_level_page_table(resume_pg_dir);
180
+
181
+ error = set_up_temporary_text_mapping(resume_pg_dir);
182
+ if (error)
183
+ return error;
184
+
157185 error = resume_physical_mapping_init(resume_pg_dir);
186
+ if (error)
187
+ return error;
188
+
189
+ temp_pgt = __pa(resume_pg_dir);
190
+
191
+ error = relocate_restore_code();
158192 if (error)
159193 return error;
160194
161195 /* We have got enough memory and from now on we cannot recover */
162196 restore_image();
163197 return 0;
164
-}
165
-
166
-/*
167
- * pfn_is_nosave - check if given pfn is in the 'nosave' section
168
- */
169
-
170
-int pfn_is_nosave(unsigned long pfn)
171
-{
172
- unsigned long nosave_begin_pfn = __pa_symbol(&__nosave_begin) >> PAGE_SHIFT;
173
- unsigned long nosave_end_pfn = PAGE_ALIGN(__pa_symbol(&__nosave_end)) >> PAGE_SHIFT;
174
- return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
175198 }