4141
4242#include "internal.h"
4343
44- static struct microcode_ops * microcode_ops ;
45- bool dis_ucode_ldr = true ;
44+ static struct microcode_ops * microcode_ops ;
45+ static bool dis_ucode_ldr = false ;
4646
4747bool force_minrev = IS_ENABLED (CONFIG_MICROCODE_LATE_FORCE_MINREV );
4848module_param (force_minrev , bool , S_IRUSR | S_IWUSR );
@@ -84,6 +84,9 @@ static bool amd_check_current_patch_level(void)
8484 u32 lvl , dummy , i ;
8585 u32 * levels ;
8686
87+ if (x86_cpuid_vendor () != X86_VENDOR_AMD )
88+ return false;
89+
8790 native_rdmsr (MSR_AMD64_PATCH_LEVEL , lvl , dummy );
8891
8992 levels = final_levels ;
@@ -95,27 +98,29 @@ static bool amd_check_current_patch_level(void)
9598 return false;
9699}
97100
98- static bool __init check_loader_disabled_bsp (void )
101+ bool __init microcode_loader_disabled (void )
99102{
100- static const char * __dis_opt_str = "dis_ucode_ldr" ;
101- const char * cmdline = boot_command_line ;
102- const char * option = __dis_opt_str ;
103+ if (dis_ucode_ldr )
104+ return true;
103105
104106 /*
105- * CPUID(1).ECX[31]: reserved for hypervisor use. This is still not
106- * completely accurate as xen pv guests don't see that CPUID bit set but
107- * that's good enough as they don't land on the BSP path anyway.
107+ * Disable when:
108+ *
109+ * 1) The CPU does not support CPUID.
110+ *
111+ * 2) Bit 31 in CPUID[1]:ECX is clear
112+ * The bit is reserved for hypervisor use. This is still not
113+ * completely accurate as XEN PV guests don't see that CPUID bit
114+ * set, but that's good enough as they don't land on the BSP
115+ * path anyway.
116+ *
117+ * 3) Certain AMD patch levels are not allowed to be
118+ * overwritten.
108119 */
109- if (native_cpuid_ecx (1 ) & BIT (31 ))
110- return true;
111-
112- if (x86_cpuid_vendor () == X86_VENDOR_AMD ) {
113- if (amd_check_current_patch_level ())
114- return true;
115- }
116-
117- if (cmdline_find_option_bool (cmdline , option ) <= 0 )
118- dis_ucode_ldr = false;
120+ if (!have_cpuid_p () ||
121+ native_cpuid_ecx (1 ) & BIT (31 ) ||
122+ amd_check_current_patch_level ())
123+ dis_ucode_ldr = true;
119124
120125 return dis_ucode_ldr ;
121126}
@@ -125,7 +130,10 @@ void __init load_ucode_bsp(void)
125130 unsigned int cpuid_1_eax ;
126131 bool intel = true;
127132
128- if (!have_cpuid_p ())
133+ if (cmdline_find_option_bool (boot_command_line , "dis_ucode_ldr" ) > 0 )
134+ dis_ucode_ldr = true;
135+
136+ if (microcode_loader_disabled ())
129137 return ;
130138
131139 cpuid_1_eax = native_cpuid_eax (1 );
@@ -146,9 +154,6 @@ void __init load_ucode_bsp(void)
146154 return ;
147155 }
148156
149- if (check_loader_disabled_bsp ())
150- return ;
151-
152157 if (intel )
153158 load_ucode_intel_bsp (& early_data );
154159 else
@@ -159,6 +164,11 @@ void load_ucode_ap(void)
159164{
160165 unsigned int cpuid_1_eax ;
161166
167+ /*
168+ * Can't use microcode_loader_disabled() here - .init section
169+ * hell. It doesn't have to either - the BSP variant must've
170+ * parsed cmdline already anyway.
171+ */
162172 if (dis_ucode_ldr )
163173 return ;
164174
@@ -810,7 +820,7 @@ static int __init microcode_init(void)
810820 struct cpuinfo_x86 * c = & boot_cpu_data ;
811821 int error ;
812822
813- if (dis_ucode_ldr )
823+ if (microcode_loader_disabled () )
814824 return - EINVAL ;
815825
816826 if (c -> x86_vendor == X86_VENDOR_INTEL )
0 commit comments