hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/arch/x86/kernel/cpu/microcode/core.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * CPU Microcode Update Driver for Linux
34 *
....@@ -12,11 +13,6 @@
1213 * (C) 2015 Borislav Petkov <bp@alien8.de>
1314 *
1415 * This driver allows to upgrade microcode on x86 processors.
15
- *
16
- * This program is free software; you can redistribute it and/or
17
- * modify it under the terms of the GNU General Public License
18
- * as published by the Free Software Foundation; either version
19
- * 2 of the License, or (at your option) any later version.
2016 */
2117
2218 #define pr_fmt(fmt) "microcode: " fmt
....@@ -66,11 +62,6 @@
6662 * updated at any particular moment of time.
6763 */
6864 static DEFINE_MUTEX(microcode_mutex);
69
-
70
-/*
71
- * Serialize late loading so that CPUs get updated one-by-one.
72
- */
73
-static DEFINE_RAW_SPINLOCK(update_lock);
7465
7566 struct ucode_cpu_info ucode_cpu_info[NR_CPUS];
7667
....@@ -154,7 +145,6 @@
154145
155146 bool get_builtin_firmware(struct cpio_data *cd, const char *name)
156147 {
157
-#ifdef CONFIG_FW_LOADER
158148 struct builtin_fw *b_fw;
159149
160150 for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) {
....@@ -164,7 +154,6 @@
164154 return true;
165155 }
166156 }
167
-#endif
168157 return false;
169158 }
170159
....@@ -428,16 +417,17 @@
428417
429418 static int microcode_open(struct inode *inode, struct file *file)
430419 {
431
- return capable(CAP_SYS_RAWIO) ? nonseekable_open(inode, file) : -EPERM;
420
+ return capable(CAP_SYS_RAWIO) ? stream_open(inode, file) : -EPERM;
432421 }
433422
434423 static ssize_t microcode_write(struct file *file, const char __user *buf,
435424 size_t len, loff_t *ppos)
436425 {
437426 ssize_t ret = -EINVAL;
427
+ unsigned long nr_pages = totalram_pages();
438428
439
- if ((len >> PAGE_SHIFT) > totalram_pages) {
440
- pr_err("too much data (max %ld pages)\n", totalram_pages);
429
+ if ((len >> PAGE_SHIFT) > nr_pages) {
430
+ pr_err("too much data (max %ld pages)\n", nr_pages);
441431 return ret;
442432 }
443433
....@@ -553,8 +543,7 @@
553543 /*
554544 * Returns:
555545 * < 0 - on error
556
- * 0 - no update done
557
- * 1 - microcode was updated
546
+ * 0 - success (no update done or microcode was updated)
558547 */
559548 static int __reload_late(void *info)
560549 {
....@@ -569,26 +558,37 @@
569558 if (__wait_for_cpus(&late_cpus_in, NSEC_PER_SEC))
570559 return -1;
571560
572
- raw_spin_lock(&update_lock);
573
- apply_microcode_local(&err);
574
- raw_spin_unlock(&update_lock);
561
+ /*
562
+ * On an SMT system, it suffices to load the microcode on one sibling of
563
+ * the core because the microcode engine is shared between the threads.
564
+ * Synchronization still needs to take place so that no concurrent
565
+ * loading attempts happen on multiple threads of an SMT core. See
566
+ * below.
567
+ */
568
+ if (cpumask_first(topology_sibling_cpumask(cpu)) == cpu)
569
+ apply_microcode_local(&err);
570
+ else
571
+ goto wait_for_siblings;
575572
576
- /* siblings return UCODE_OK because their engine got updated already */
577
- if (err > UCODE_NFOUND) {
578
- pr_warn("Error reloading microcode on CPU %d\n", cpu);
573
+ if (err >= UCODE_NFOUND) {
574
+ if (err == UCODE_ERROR)
575
+ pr_warn("Error reloading microcode on CPU %d\n", cpu);
576
+
579577 ret = -1;
580
- } else if (err == UCODE_UPDATED || err == UCODE_OK) {
581
- ret = 1;
582578 }
583579
584
- /*
585
- * Increase the wait timeout to a safe value here since we're
586
- * serializing the microcode update and that could take a while on a
587
- * large number of CPUs. And that is fine as the *actual* timeout will
588
- * be determined by the last CPU finished updating and thus cut short.
589
- */
590
- if (__wait_for_cpus(&late_cpus_out, NSEC_PER_SEC * num_online_cpus()))
580
+wait_for_siblings:
581
+ if (__wait_for_cpus(&late_cpus_out, NSEC_PER_SEC))
591582 panic("Timeout during microcode update!\n");
583
+
584
+ /*
585
+ * At least one thread has completed update on each core.
586
+ * For others, simply call the update to make sure the
587
+ * per-cpu cpuinfo can be updated with right microcode
588
+ * revision.
589
+ */
590
+ if (cpumask_first(topology_sibling_cpumask(cpu)) != cpu)
591
+ apply_microcode_local(&err);
592592
593593 return ret;
594594 }
....@@ -605,8 +605,10 @@
605605 atomic_set(&late_cpus_out, 0);
606606
607607 ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask);
608
- if (ret > 0)
608
+ if (ret == 0)
609609 microcode_check();
610
+
611
+ pr_info("Reload completed, microcode revision: 0x%x\n", boot_cpu_data.microcode);
610612
611613 return ret;
612614 }
....@@ -644,7 +646,7 @@
644646 put:
645647 put_online_cpus();
646648
647
- if (ret >= 0)
649
+ if (ret == 0)
648650 ret = size;
649651
650652 return ret;
....@@ -667,8 +669,8 @@
667669 }
668670
669671 static DEVICE_ATTR_WO(reload);
670
-static DEVICE_ATTR(version, 0400, version_show, NULL);
671
-static DEVICE_ATTR(processor_flags, 0400, pf_show, NULL);
672
+static DEVICE_ATTR(version, 0444, version_show, NULL);
673
+static DEVICE_ATTR(processor_flags, 0444, pf_show, NULL);
672674
673675 static struct attribute *mc_default_attrs[] = {
674676 &dev_attr_version.attr,
....@@ -773,9 +775,9 @@
773775 };
774776
775777 /**
776
- * mc_bp_resume - Update boot CPU microcode during resume.
778
+ * microcode_bsp_resume - Update boot CPU microcode during resume.
777779 */
778
-static void mc_bp_resume(void)
780
+void microcode_bsp_resume(void)
779781 {
780782 int cpu = smp_processor_id();
781783 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
....@@ -787,7 +789,7 @@
787789 }
788790
789791 static struct syscore_ops mc_syscore_ops = {
790
- .resume = mc_bp_resume,
792
+ .resume = microcode_bsp_resume,
791793 };
792794
793795 static int mc_cpu_starting(unsigned int cpu)