hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/arch/x86/power/cpu.c
....@@ -1,7 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Suspend support specific for i386/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>
....@@ -14,8 +13,8 @@
1413 #include <linux/perf_event.h>
1514 #include <linux/tboot.h>
1615 #include <linux/dmi.h>
16
+#include <linux/pgtable.h>
1717
18
-#include <asm/pgtable.h>
1918 #include <asm/proto.h>
2019 #include <asm/mtrr.h>
2120 #include <asm/page.h>
....@@ -26,6 +25,7 @@
2625 #include <asm/cpu.h>
2726 #include <asm/mmu_context.h>
2827 #include <asm/cpu_device_id.h>
28
+#include <asm/microcode.h>
2929
3030 #ifdef CONFIG_X86_32
3131 __visible unsigned long saved_context_ebx;
....@@ -41,7 +41,8 @@
4141 struct saved_msr *end = msr + ctxt->saved_msrs.num;
4242
4343 while (msr < end) {
44
- msr->valid = !rdmsrl_safe(msr->info.msr_no, &msr->info.reg.q);
44
+ if (msr->valid)
45
+ rdmsrl(msr->info.msr_no, msr->info.reg.q);
4546 msr++;
4647 }
4748 }
....@@ -124,9 +125,6 @@
124125 ctxt->cr2 = read_cr2();
125126 ctxt->cr3 = __read_cr3();
126127 ctxt->cr4 = __read_cr4();
127
-#ifdef CONFIG_X86_64
128
- ctxt->cr8 = read_cr8();
129
-#endif
130128 ctxt->misc_enable_saved = !rdmsrl_safe(MSR_IA32_MISC_ENABLE,
131129 &ctxt->misc_enable);
132130 msr_save_context(ctxt);
....@@ -197,6 +195,8 @@
197195 */
198196 static void notrace __restore_processor_state(struct saved_context *ctxt)
199197 {
198
+ struct cpuinfo_x86 *c;
199
+
200200 if (ctxt->misc_enable_saved)
201201 wrmsrl(MSR_IA32_MISC_ENABLE, ctxt->misc_enable);
202202 /*
....@@ -209,7 +209,6 @@
209209 #else
210210 /* CONFIG X86_64 */
211211 wrmsrl(MSR_EFER, ctxt->efer);
212
- write_cr8(ctxt->cr8);
213212 __write_cr4(ctxt->cr4);
214213 #endif
215214 write_cr3(ctxt->cr3);
....@@ -267,12 +266,36 @@
267266 x86_platform.restore_sched_clock_state();
268267 mtrr_bp_restore();
269268 perf_restore_debug_store();
269
+
270
+ c = &cpu_data(smp_processor_id());
271
+ if (cpu_has(c, X86_FEATURE_MSR_IA32_FEAT_CTL))
272
+ init_ia32_feat_ctl(c);
273
+
274
+ microcode_bsp_resume();
275
+
276
+ /*
277
+ * This needs to happen after the microcode has been updated upon resume
278
+ * because some of the MSRs are "emulated" in microcode.
279
+ */
270280 msr_restore_context(ctxt);
271281 }
272282
273283 /* Needed by apm.c */
274284 void notrace restore_processor_state(void)
275285 {
286
+#ifdef __clang__
287
+ // The following code snippet is copied from __restore_processor_state.
288
+ // Its purpose is to prepare GS segment before the function is called.
289
+ // Since the function is compiled with SCS on, it will use GS at its
290
+ // entry.
291
+ // TODO: Hack to be removed later when compiler bug is fixed.
292
+#ifdef CONFIG_X86_64
293
+ wrmsrl(MSR_GS_BASE, saved_context.kernelmode_gs_base);
294
+#else
295
+ loadsegment(fs, __KERNEL_PERCPU);
296
+ loadsegment(gs, __KERNEL_STACK_CANARY);
297
+#endif
298
+#endif
276299 __restore_processor_state(&saved_context);
277300 }
278301 #ifdef CONFIG_X86_32
....@@ -312,7 +335,7 @@
312335 if (ret)
313336 return ret;
314337 smp_ops.play_dead = resume_play_dead;
315
- ret = disable_nonboot_cpus();
338
+ ret = freeze_secondary_cpus(0);
316339 smp_ops.play_dead = play_dead;
317340 return ret;
318341 }
....@@ -426,8 +449,10 @@
426449 }
427450
428451 for (i = saved_msrs->num, j = 0; i < total_num; i++, j++) {
452
+ u64 dummy;
453
+
429454 msr_array[i].info.msr_no = msr_id[j];
430
- msr_array[i].valid = false;
455
+ msr_array[i].valid = !rdmsrl_safe(msr_id[j], &dummy);
431456 msr_array[i].info.reg.q = 0;
432457 }
433458 saved_msrs->num = total_num;
....@@ -480,20 +505,8 @@
480505 }
481506
482507 static const struct x86_cpu_id msr_save_cpu_table[] = {
483
- {
484
- .vendor = X86_VENDOR_AMD,
485
- .family = 0x15,
486
- .model = X86_MODEL_ANY,
487
- .feature = X86_FEATURE_ANY,
488
- .driver_data = (kernel_ulong_t)msr_save_cpuid_features,
489
- },
490
- {
491
- .vendor = X86_VENDOR_AMD,
492
- .family = 0x16,
493
- .model = X86_MODEL_ANY,
494
- .feature = X86_FEATURE_ANY,
495
- .driver_data = (kernel_ulong_t)msr_save_cpuid_features,
496
- },
508
+ X86_MATCH_VENDOR_FAM(AMD, 0x15, &msr_save_cpuid_features),
509
+ X86_MATCH_VENDOR_FAM(AMD, 0x16, &msr_save_cpuid_features),
497510 {}
498511 };
499512
....@@ -514,10 +527,32 @@
514527 return ret;
515528 }
516529
530
+static void pm_save_spec_msr(void)
531
+{
532
+ struct msr_enumeration {
533
+ u32 msr_no;
534
+ u32 feature;
535
+ } msr_enum[] = {
536
+ { MSR_IA32_SPEC_CTRL, X86_FEATURE_MSR_SPEC_CTRL },
537
+ { MSR_IA32_TSX_CTRL, X86_FEATURE_MSR_TSX_CTRL },
538
+ { MSR_TSX_FORCE_ABORT, X86_FEATURE_TSX_FORCE_ABORT },
539
+ { MSR_IA32_MCU_OPT_CTRL, X86_FEATURE_SRBDS_CTRL },
540
+ { MSR_AMD64_LS_CFG, X86_FEATURE_LS_CFG_SSBD },
541
+ { MSR_AMD64_DE_CFG, X86_FEATURE_LFENCE_RDTSC },
542
+ };
543
+ int i;
544
+
545
+ for (i = 0; i < ARRAY_SIZE(msr_enum); i++) {
546
+ if (boot_cpu_has(msr_enum[i].feature))
547
+ msr_build_context(&msr_enum[i].msr_no, 1);
548
+ }
549
+}
550
+
517551 static int pm_check_save_msr(void)
518552 {
519553 dmi_check_system(msr_save_dmi_table);
520554 pm_cpu_check(msr_save_cpu_table);
555
+ pm_save_spec_msr();
521556
522557 return 0;
523558 }