hc
2024-02-19 1c055e55a242a33e574e48be530e06770a210dcd
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
....@@ -59,18 +55,13 @@
5955 * All non cpu-hotplug-callback call sites use:
6056 *
6157 * - microcode_mutex to synchronize with each other;
62
- * - get/put_online_cpus() to synchronize with
58
+ * - cpus_read_lock/unlock() to synchronize with
6359 * the cpu-hotplug-callback call sites.
6460 *
6561 * We guarantee that only a single cpu is being
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
....@@ -326,7 +315,7 @@
326315 #endif
327316 }
328317
329
-void reload_early_microcode(void)
318
+void reload_early_microcode(unsigned int cpu)
330319 {
331320 int vendor, family;
332321
....@@ -340,7 +329,7 @@
340329 break;
341330 case X86_VENDOR_AMD:
342331 if (family >= 0x10)
343
- reload_ucode_amd();
332
+ reload_ucode_amd(cpu);
344333 break;
345334 default:
346335 break;
....@@ -401,100 +390,10 @@
401390 return ret;
402391 }
403392
404
-#ifdef CONFIG_MICROCODE_OLD_INTERFACE
405
-static int do_microcode_update(const void __user *buf, size_t size)
406
-{
407
- int error = 0;
408
- int cpu;
409
-
410
- for_each_online_cpu(cpu) {
411
- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
412
- enum ucode_state ustate;
413
-
414
- if (!uci->valid)
415
- continue;
416
-
417
- ustate = microcode_ops->request_microcode_user(cpu, buf, size);
418
- if (ustate == UCODE_ERROR) {
419
- error = -1;
420
- break;
421
- } else if (ustate == UCODE_NEW) {
422
- apply_microcode_on_target(cpu);
423
- }
424
- }
425
-
426
- return error;
427
-}
428
-
429
-static int microcode_open(struct inode *inode, struct file *file)
430
-{
431
- return capable(CAP_SYS_RAWIO) ? nonseekable_open(inode, file) : -EPERM;
432
-}
433
-
434
-static ssize_t microcode_write(struct file *file, const char __user *buf,
435
- size_t len, loff_t *ppos)
436
-{
437
- ssize_t ret = -EINVAL;
438
-
439
- if ((len >> PAGE_SHIFT) > totalram_pages) {
440
- pr_err("too much data (max %ld pages)\n", totalram_pages);
441
- return ret;
442
- }
443
-
444
- get_online_cpus();
445
- mutex_lock(&microcode_mutex);
446
-
447
- if (do_microcode_update(buf, len) == 0)
448
- ret = (ssize_t)len;
449
-
450
- if (ret > 0)
451
- perf_check_microcode();
452
-
453
- mutex_unlock(&microcode_mutex);
454
- put_online_cpus();
455
-
456
- return ret;
457
-}
458
-
459
-static const struct file_operations microcode_fops = {
460
- .owner = THIS_MODULE,
461
- .write = microcode_write,
462
- .open = microcode_open,
463
- .llseek = no_llseek,
464
-};
465
-
466
-static struct miscdevice microcode_dev = {
467
- .minor = MICROCODE_MINOR,
468
- .name = "microcode",
469
- .nodename = "cpu/microcode",
470
- .fops = &microcode_fops,
471
-};
472
-
473
-static int __init microcode_dev_init(void)
474
-{
475
- int error;
476
-
477
- error = misc_register(&microcode_dev);
478
- if (error) {
479
- pr_err("can't misc_register on minor=%d\n", MICROCODE_MINOR);
480
- return error;
481
- }
482
-
483
- return 0;
484
-}
485
-
486
-static void __exit microcode_dev_exit(void)
487
-{
488
- misc_deregister(&microcode_dev);
489
-}
490
-#else
491
-#define microcode_dev_init() 0
492
-#define microcode_dev_exit() do { } while (0)
493
-#endif
494
-
495393 /* fake device for request_firmware */
496394 static struct platform_device *microcode_pdev;
497395
396
+#ifdef CONFIG_MICROCODE_LATE_LOADING
498397 /*
499398 * Late loading dance. Why the heavy-handed stomp_machine effort?
500399 *
....@@ -553,8 +452,7 @@
553452 /*
554453 * Returns:
555454 * < 0 - on error
556
- * 0 - no update done
557
- * 1 - microcode was updated
455
+ * 0 - success (no update done or microcode was updated)
558456 */
559457 static int __reload_late(void *info)
560458 {
....@@ -569,26 +467,37 @@
569467 if (__wait_for_cpus(&late_cpus_in, NSEC_PER_SEC))
570468 return -1;
571469
572
- raw_spin_lock(&update_lock);
573
- apply_microcode_local(&err);
574
- raw_spin_unlock(&update_lock);
470
+ /*
471
+ * On an SMT system, it suffices to load the microcode on one sibling of
472
+ * the core because the microcode engine is shared between the threads.
473
+ * Synchronization still needs to take place so that no concurrent
474
+ * loading attempts happen on multiple threads of an SMT core. See
475
+ * below.
476
+ */
477
+ if (cpumask_first(topology_sibling_cpumask(cpu)) == cpu)
478
+ apply_microcode_local(&err);
479
+ else
480
+ goto wait_for_siblings;
575481
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);
482
+ if (err >= UCODE_NFOUND) {
483
+ if (err == UCODE_ERROR)
484
+ pr_warn("Error reloading microcode on CPU %d\n", cpu);
485
+
579486 ret = -1;
580
- } else if (err == UCODE_UPDATED || err == UCODE_OK) {
581
- ret = 1;
582487 }
583488
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()))
489
+wait_for_siblings:
490
+ if (__wait_for_cpus(&late_cpus_out, NSEC_PER_SEC))
591491 panic("Timeout during microcode update!\n");
492
+
493
+ /*
494
+ * At least one thread has completed update on each core.
495
+ * For others, simply call the update to make sure the
496
+ * per-cpu cpuinfo can be updated with right microcode
497
+ * revision.
498
+ */
499
+ if (cpumask_first(topology_sibling_cpumask(cpu)) != cpu)
500
+ apply_microcode_local(&err);
592501
593502 return ret;
594503 }
....@@ -599,14 +508,27 @@
599508 */
600509 static int microcode_reload_late(void)
601510 {
602
- int ret;
511
+ int old = boot_cpu_data.microcode, ret;
512
+ struct cpuinfo_x86 prev_info;
603513
604514 atomic_set(&late_cpus_in, 0);
605515 atomic_set(&late_cpus_out, 0);
606516
517
+ /*
518
+ * Take a snapshot before the microcode update in order to compare and
519
+ * check whether any bits changed after an update.
520
+ */
521
+ store_cpu_caps(&prev_info);
522
+
607523 ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask);
608
- if (ret > 0)
609
- microcode_check();
524
+ if (!ret) {
525
+ pr_info("Reload succeeded, microcode revision: 0x%x -> 0x%x\n",
526
+ old, boot_cpu_data.microcode);
527
+ microcode_check(&prev_info);
528
+ } else {
529
+ pr_info("Reload failed, current microcode revision: 0x%x\n",
530
+ boot_cpu_data.microcode);
531
+ }
610532
611533 return ret;
612534 }
....@@ -627,7 +549,7 @@
627549 if (val != 1)
628550 return size;
629551
630
- get_online_cpus();
552
+ cpus_read_lock();
631553
632554 ret = check_online_cpus();
633555 if (ret)
....@@ -642,13 +564,16 @@
642564 mutex_unlock(&microcode_mutex);
643565
644566 put:
645
- put_online_cpus();
567
+ cpus_read_unlock();
646568
647
- if (ret >= 0)
569
+ if (ret == 0)
648570 ret = size;
649571
650572 return ret;
651573 }
574
+
575
+static DEVICE_ATTR_WO(reload);
576
+#endif
652577
653578 static ssize_t version_show(struct device *dev,
654579 struct device_attribute *attr, char *buf)
....@@ -666,9 +591,8 @@
666591 return sprintf(buf, "0x%x\n", uci->cpu_sig.pf);
667592 }
668593
669
-static DEVICE_ATTR_WO(reload);
670
-static DEVICE_ATTR(version, 0400, version_show, NULL);
671
-static DEVICE_ATTR(processor_flags, 0400, pf_show, NULL);
594
+static DEVICE_ATTR(version, 0444, version_show, NULL);
595
+static DEVICE_ATTR(processor_flags, 0444, pf_show, NULL);
672596
673597 static struct attribute *mc_default_attrs[] = {
674598 &dev_attr_version.attr,
....@@ -773,9 +697,9 @@
773697 };
774698
775699 /**
776
- * mc_bp_resume - Update boot CPU microcode during resume.
700
+ * microcode_bsp_resume - Update boot CPU microcode during resume.
777701 */
778
-static void mc_bp_resume(void)
702
+void microcode_bsp_resume(void)
779703 {
780704 int cpu = smp_processor_id();
781705 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
....@@ -783,11 +707,11 @@
783707 if (uci->valid && uci->mc)
784708 microcode_ops->apply_microcode(cpu);
785709 else if (!uci->mc)
786
- reload_early_microcode();
710
+ reload_early_microcode(cpu);
787711 }
788712
789713 static struct syscore_ops mc_syscore_ops = {
790
- .resume = mc_bp_resume,
714
+ .resume = microcode_bsp_resume,
791715 };
792716
793717 static int mc_cpu_starting(unsigned int cpu)
....@@ -819,7 +743,9 @@
819743 }
820744
821745 static struct attribute *cpu_root_microcode_attrs[] = {
746
+#ifdef CONFIG_MICROCODE_LATE_LOADING
822747 &dev_attr_reload.attr,
748
+#endif
823749 NULL
824750 };
825751
....@@ -851,14 +777,14 @@
851777 if (IS_ERR(microcode_pdev))
852778 return PTR_ERR(microcode_pdev);
853779
854
- get_online_cpus();
780
+ cpus_read_lock();
855781 mutex_lock(&microcode_mutex);
856782
857783 error = subsys_interface_register(&mc_cpu_interface);
858784 if (!error)
859785 perf_check_microcode();
860786 mutex_unlock(&microcode_mutex);
861
- put_online_cpus();
787
+ cpus_read_unlock();
862788
863789 if (error)
864790 goto out_pdev;
....@@ -871,10 +797,6 @@
871797 goto out_driver;
872798 }
873799
874
- error = microcode_dev_init();
875
- if (error)
876
- goto out_ucode_group;
877
-
878800 register_syscore_ops(&mc_syscore_ops);
879801 cpuhp_setup_state_nocalls(CPUHP_AP_MICROCODE_LOADER, "x86/microcode:starting",
880802 mc_cpu_starting, NULL);
....@@ -885,18 +807,14 @@
885807
886808 return 0;
887809
888
- out_ucode_group:
889
- sysfs_remove_group(&cpu_subsys.dev_root->kobj,
890
- &cpu_root_microcode_group);
891
-
892810 out_driver:
893
- get_online_cpus();
811
+ cpus_read_lock();
894812 mutex_lock(&microcode_mutex);
895813
896814 subsys_interface_unregister(&mc_cpu_interface);
897815
898816 mutex_unlock(&microcode_mutex);
899
- put_online_cpus();
817
+ cpus_read_unlock();
900818
901819 out_pdev:
902820 platform_device_unregister(microcode_pdev);