forked from clearlinux-pkgs/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path0124-x86-microcode-Force-update-a-uCode-even-if-the-rev-i.patch
143 lines (128 loc) · 4.23 KB
/
0124-x86-microcode-Force-update-a-uCode-even-if-the-rev-i.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ashok Raj <[email protected]>
Date: Sat, 20 Jul 2019 14:14:47 +0000
Subject: [PATCH] x86/microcode: Force update a uCode even if the rev is the
same
Signed-off-by: Ashok Raj <[email protected]>
---
arch/x86/kernel/cpu/microcode/core.c | 1 +
arch/x86/kernel/cpu/microcode/intel.c | 57 +++++++++++++++++++++++++--
2 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index 6a6318e9590c..fae61bd63ecf 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -604,6 +604,7 @@ static int microcode_reload_late(void)
atomic_set(&late_cpus_in, 0);
atomic_set(&late_cpus_out, 0);
+ printk ("Going to do stop_machine\n");
ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask);
if (ret == 0)
microcode_check();
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 7e8e07bddd5f..faaa56c05a64 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -30,6 +30,7 @@
#include <linux/uio.h>
#include <linux/mm.h>
+#include <asm/cmdline.h>
#include <asm/microcode_intel.h>
#include <asm/intel-family.h>
#include <asm/processor.h>
@@ -38,6 +39,7 @@
#include <asm/msr.h>
static const char ucode_path[] = "kernel/x86/microcode/GenuineIntel.bin";
+static bool force_ucode_load = false;
/* Current microcode patch used in early patching on the APs. */
static struct microcode_intel *intel_ucode_patch;
@@ -94,8 +96,18 @@ static int has_newer_microcode(void *mc, unsigned int csig, int cpf, int new_rev
{
struct microcode_header_intel *mc_hdr = mc;
- if (mc_hdr->rev <= new_rev)
+ //if (mc_hdr->rev <= new_rev)
+ if (mc_hdr->rev < new_rev) {
+ printk ("Returning NO_NEW old = 0x%x new = 0x%x\n",
+ mc_hdr->rev, new_rev);
return 0;
+ }
+ if ((mc_hdr->rev == new_rev) && !force_ucode_load) {
+ printk ("SAME REV: no_force Returning NO_NEW old = 0x%x new = 0x%x\n",
+ mc_hdr->rev, new_rev);
+ return 0;
+ }
+ printk ("ucode: force loading same rev\n");
return find_matching_signature(mc, csig, cpf);
}
@@ -550,11 +562,20 @@ static int apply_microcode_early(struct ucode_cpu_info *uci, bool early)
* already.
*/
rev = intel_get_microcode_revision();
- if (rev >= mc->hdr.rev) {
+ if (rev > mc->hdr.rev) {
uci->cpu_sig.rev = rev;
return UCODE_OK;
}
+ if (rev == mc->hdr.rev) {
+ if (!force_ucode_load) {
+ printk ("Matching ucode rev, no update\n");
+ return UCODE_OK;
+ } else {
+ printk ("Matching ucode rev.. force updating\n");
+ }
+ }
+
/*
* Writeback and invalidate caches before updating microcode to avoid
* internal issues depending on what the microcode is updating.
@@ -606,6 +627,29 @@ int __init save_microcode_in_initrd_intel(void)
return 0;
}
+static bool check_force_ucode_bsp(void)
+{
+ static const char *__force_ucode_str = "force_ucode_load";
+
+#ifdef CONFIG_X86_32
+ const char *cmdline = (const char *)__pa_nodebug(boot_command_line);
+ const char *option = (const char *)__pa_nodebug(__force_ucode_str);
+ bool *res = (bool *)__pa_nodebug(&force_ucode_load);
+
+#else /* CONFIG_X86_64 */
+ const char *cmdline = boot_command_line;
+ const char *option = __force_ucode_str;
+ bool *res = &force_ucode_load;
+#endif
+
+ if (cmdline_find_option_bool(cmdline, option)) {
+ printk("cmdline forcing ucode update for same rev\n");
+ *res = true;
+ }
+
+ return *res;
+}
+
/*
* @res_patch, output: a pointer to the patch we found.
*/
@@ -639,6 +683,9 @@ void __init load_ucode_intel_bsp(void)
{
struct microcode_intel *patch;
struct ucode_cpu_info uci;
+ bool force_bsp;
+
+ force_bsp = check_force_ucode_bsp();
patch = __load_ucode_intel(&uci);
if (!patch)
@@ -687,8 +734,12 @@ static struct microcode_intel *find_patch(struct ucode_cpu_info *uci)
phdr = (struct microcode_header_intel *)iter->data;
- if (phdr->rev <= uci->cpu_sig.rev)
+ if (phdr->rev < uci->cpu_sig.rev)
continue;
+ if (phdr->rev == uci->cpu_sig.rev && !force_ucode_load)
+ continue;
+ else
+ printk ("same rev forcing ucode\n");
if (!find_matching_signature(phdr,
uci->cpu_sig.sig,
--
https://clearlinux.org