hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/arch/x86/power/hibernate_64.c
....@@ -1,7 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Hibernation support for x86-64
3
- *
4
- * Distribute under GPLv2
54 *
65 * Copyright (c) 2007 Rafael J. Wysocki <rjw@sisk.pl>
76 * Copyright (c) 2002 Pavel Machek <pavel@ucw.cz>
....@@ -13,7 +12,7 @@
1312 #include <linux/suspend.h>
1413 #include <linux/scatterlist.h>
1514 #include <linux/kdebug.h>
16
-#include <linux/cpu.h>
15
+#include <linux/pgtable.h>
1716
1817 #include <crypto/hash.h>
1918
....@@ -21,31 +20,10 @@
2120 #include <asm/init.h>
2221 #include <asm/proto.h>
2322 #include <asm/page.h>
24
-#include <asm/pgtable.h>
2523 #include <asm/mtrr.h>
2624 #include <asm/sections.h>
2725 #include <asm/suspend.h>
2826 #include <asm/tlbflush.h>
29
-
30
-/* Defined in hibernate_asm_64.S */
31
-extern asmlinkage __visible int restore_image(void);
32
-
33
-/*
34
- * Address to jump to in the last phase of restore in order to get to the image
35
- * kernel's text (this value is passed in the image header).
36
- */
37
-unsigned long restore_jump_address __visible;
38
-unsigned long jump_address_phys;
39
-
40
-/*
41
- * Value of the cr3 register from before the hibernation (this value is passed
42
- * in the image header).
43
- */
44
-unsigned long restore_cr3 __visible;
45
-
46
-unsigned long temp_level4_pgt __visible;
47
-
48
-unsigned long relocated_restore_code __visible;
4927
5028 static int set_up_temporary_text_mapping(pgd_t *pgd)
5129 {
....@@ -142,46 +120,7 @@
142120 return result;
143121 }
144122
145
- temp_level4_pgt = __pa(pgd);
146
- return 0;
147
-}
148
-
149
-static int relocate_restore_code(void)
150
-{
151
- pgd_t *pgd;
152
- p4d_t *p4d;
153
- pud_t *pud;
154
- pmd_t *pmd;
155
- pte_t *pte;
156
-
157
- relocated_restore_code = get_safe_page(GFP_ATOMIC);
158
- if (!relocated_restore_code)
159
- return -ENOMEM;
160
-
161
- memcpy((void *)relocated_restore_code, core_restore_code, PAGE_SIZE);
162
-
163
- /* Make the page containing the relocated code executable */
164
- pgd = (pgd_t *)__va(read_cr3_pa()) +
165
- pgd_index(relocated_restore_code);
166
- p4d = p4d_offset(pgd, relocated_restore_code);
167
- if (p4d_large(*p4d)) {
168
- set_p4d(p4d, __p4d(p4d_val(*p4d) & ~_PAGE_NX));
169
- goto out;
170
- }
171
- pud = pud_offset(p4d, relocated_restore_code);
172
- if (pud_large(*pud)) {
173
- set_pud(pud, __pud(pud_val(*pud) & ~_PAGE_NX));
174
- goto out;
175
- }
176
- pmd = pmd_offset(pud, relocated_restore_code);
177
- if (pmd_large(*pmd)) {
178
- set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_NX));
179
- goto out;
180
- }
181
- pte = pte_offset_kernel(pmd, relocated_restore_code);
182
- set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_NX));
183
-out:
184
- __flush_tlb_all();
123
+ temp_pgt = __pa(pgd);
185124 return 0;
186125 }
187126
....@@ -200,198 +139,4 @@
200139
201140 restore_image();
202141 return 0;
203
-}
204
-
205
-/*
206
- * pfn_is_nosave - check if given pfn is in the 'nosave' section
207
- */
208
-
209
-int pfn_is_nosave(unsigned long pfn)
210
-{
211
- unsigned long nosave_begin_pfn = __pa_symbol(&__nosave_begin) >> PAGE_SHIFT;
212
- unsigned long nosave_end_pfn = PAGE_ALIGN(__pa_symbol(&__nosave_end)) >> PAGE_SHIFT;
213
- return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
214
-}
215
-
216
-#define MD5_DIGEST_SIZE 16
217
-
218
-struct restore_data_record {
219
- unsigned long jump_address;
220
- unsigned long jump_address_phys;
221
- unsigned long cr3;
222
- unsigned long magic;
223
- u8 e820_digest[MD5_DIGEST_SIZE];
224
-};
225
-
226
-#define RESTORE_MAGIC 0x23456789ABCDEF01UL
227
-
228
-#if IS_BUILTIN(CONFIG_CRYPTO_MD5)
229
-/**
230
- * get_e820_md5 - calculate md5 according to given e820 table
231
- *
232
- * @table: the e820 table to be calculated
233
- * @buf: the md5 result to be stored to
234
- */
235
-static int get_e820_md5(struct e820_table *table, void *buf)
236
-{
237
- struct crypto_shash *tfm;
238
- struct shash_desc *desc;
239
- int size;
240
- int ret = 0;
241
-
242
- tfm = crypto_alloc_shash("md5", 0, 0);
243
- if (IS_ERR(tfm))
244
- return -ENOMEM;
245
-
246
- desc = kmalloc(sizeof(struct shash_desc) + crypto_shash_descsize(tfm),
247
- GFP_KERNEL);
248
- if (!desc) {
249
- ret = -ENOMEM;
250
- goto free_tfm;
251
- }
252
-
253
- desc->tfm = tfm;
254
- desc->flags = 0;
255
-
256
- size = offsetof(struct e820_table, entries) +
257
- sizeof(struct e820_entry) * table->nr_entries;
258
-
259
- if (crypto_shash_digest(desc, (u8 *)table, size, buf))
260
- ret = -EINVAL;
261
-
262
- kzfree(desc);
263
-
264
-free_tfm:
265
- crypto_free_shash(tfm);
266
- return ret;
267
-}
268
-
269
-static int hibernation_e820_save(void *buf)
270
-{
271
- return get_e820_md5(e820_table_firmware, buf);
272
-}
273
-
274
-static bool hibernation_e820_mismatch(void *buf)
275
-{
276
- int ret;
277
- u8 result[MD5_DIGEST_SIZE];
278
-
279
- memset(result, 0, MD5_DIGEST_SIZE);
280
- /* If there is no digest in suspend kernel, let it go. */
281
- if (!memcmp(result, buf, MD5_DIGEST_SIZE))
282
- return false;
283
-
284
- ret = get_e820_md5(e820_table_firmware, result);
285
- if (ret)
286
- return true;
287
-
288
- return memcmp(result, buf, MD5_DIGEST_SIZE) ? true : false;
289
-}
290
-#else
291
-static int hibernation_e820_save(void *buf)
292
-{
293
- return 0;
294
-}
295
-
296
-static bool hibernation_e820_mismatch(void *buf)
297
-{
298
- /* If md5 is not builtin for restore kernel, let it go. */
299
- return false;
300
-}
301
-#endif
302
-
303
-/**
304
- * arch_hibernation_header_save - populate the architecture specific part
305
- * of a hibernation image header
306
- * @addr: address to save the data at
307
- */
308
-int arch_hibernation_header_save(void *addr, unsigned int max_size)
309
-{
310
- struct restore_data_record *rdr = addr;
311
-
312
- if (max_size < sizeof(struct restore_data_record))
313
- return -EOVERFLOW;
314
- rdr->jump_address = (unsigned long)restore_registers;
315
- rdr->jump_address_phys = __pa_symbol(restore_registers);
316
-
317
- /*
318
- * The restore code fixes up CR3 and CR4 in the following sequence:
319
- *
320
- * [in hibernation asm]
321
- * 1. CR3 <= temporary page tables
322
- * 2. CR4 <= mmu_cr4_features (from the kernel that restores us)
323
- * 3. CR3 <= rdr->cr3
324
- * 4. CR4 <= mmu_cr4_features (from us, i.e. the image kernel)
325
- * [in restore_processor_state()]
326
- * 5. CR4 <= saved CR4
327
- * 6. CR3 <= saved CR3
328
- *
329
- * Our mmu_cr4_features has CR4.PCIDE=0, and toggling
330
- * CR4.PCIDE while CR3's PCID bits are nonzero is illegal, so
331
- * rdr->cr3 needs to point to valid page tables but must not
332
- * have any of the PCID bits set.
333
- */
334
- rdr->cr3 = restore_cr3 & ~CR3_PCID_MASK;
335
-
336
- rdr->magic = RESTORE_MAGIC;
337
-
338
- return hibernation_e820_save(rdr->e820_digest);
339
-}
340
-
341
-/**
342
- * arch_hibernation_header_restore - read the architecture specific data
343
- * from the hibernation image header
344
- * @addr: address to read the data from
345
- */
346
-int arch_hibernation_header_restore(void *addr)
347
-{
348
- struct restore_data_record *rdr = addr;
349
-
350
- restore_jump_address = rdr->jump_address;
351
- jump_address_phys = rdr->jump_address_phys;
352
- restore_cr3 = rdr->cr3;
353
-
354
- if (rdr->magic != RESTORE_MAGIC) {
355
- pr_crit("Unrecognized hibernate image header format!\n");
356
- return -EINVAL;
357
- }
358
-
359
- if (hibernation_e820_mismatch(rdr->e820_digest)) {
360
- pr_crit("Hibernate inconsistent memory map detected!\n");
361
- return -ENODEV;
362
- }
363
-
364
- return 0;
365
-}
366
-
367
-int arch_resume_nosmt(void)
368
-{
369
- int ret = 0;
370
- /*
371
- * We reached this while coming out of hibernation. This means
372
- * that SMT siblings are sleeping in hlt, as mwait is not safe
373
- * against control transition during resume (see comment in
374
- * hibernate_resume_nonboot_cpu_disable()).
375
- *
376
- * If the resumed kernel has SMT disabled, we have to take all the
377
- * SMT siblings out of hlt, and offline them again so that they
378
- * end up in mwait proper.
379
- *
380
- * Called with hotplug disabled.
381
- */
382
- cpu_hotplug_enable();
383
- if (cpu_smt_control == CPU_SMT_DISABLED ||
384
- cpu_smt_control == CPU_SMT_FORCE_DISABLED) {
385
- enum cpuhp_smt_control old = cpu_smt_control;
386
-
387
- ret = cpuhp_smt_enable();
388
- if (ret)
389
- goto out;
390
- ret = cpuhp_smt_disable(old);
391
- if (ret)
392
- goto out;
393
- }
394
-out:
395
- cpu_hotplug_disable();
396
- return ret;
397142 }