Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'x86-urgent-2025-05-11' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fix from Ingo Molnar:
"Fix a boot regression on very old x86 CPUs without CPUID support"

* tag 'x86-urgent-2025-05-11' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/microcode: Consolidate the loader enablement checking

+42 -33
+2
arch/x86/include/asm/microcode.h
··· 17 17 void load_ucode_bsp(void); 18 18 void load_ucode_ap(void); 19 19 void microcode_bsp_resume(void); 20 + bool __init microcode_loader_disabled(void); 20 21 #else 21 22 static inline void load_ucode_bsp(void) { } 22 23 static inline void load_ucode_ap(void) { } 23 24 static inline void microcode_bsp_resume(void) { } 25 + static inline bool __init microcode_loader_disabled(void) { return false; } 24 26 #endif 25 27 26 28 extern unsigned long initrd_start_early;
+4 -2
arch/x86/kernel/cpu/microcode/amd.c
··· 1098 1098 1099 1099 static int __init save_microcode_in_initrd(void) 1100 1100 { 1101 - unsigned int cpuid_1_eax = native_cpuid_eax(1); 1102 1101 struct cpuinfo_x86 *c = &boot_cpu_data; 1103 1102 struct cont_desc desc = { 0 }; 1103 + unsigned int cpuid_1_eax; 1104 1104 enum ucode_state ret; 1105 1105 struct cpio_data cp; 1106 1106 1107 - if (dis_ucode_ldr || c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) 1107 + if (microcode_loader_disabled() || c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) 1108 1108 return 0; 1109 + 1110 + cpuid_1_eax = native_cpuid_eax(1); 1109 1111 1110 1112 if (!find_blobs_in_containers(&cp)) 1111 1113 return -EINVAL;
+35 -25
arch/x86/kernel/cpu/microcode/core.c
··· 41 41 42 42 #include "internal.h" 43 43 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; 46 46 47 47 bool force_minrev = IS_ENABLED(CONFIG_MICROCODE_LATE_FORCE_MINREV); 48 48 module_param(force_minrev, bool, S_IRUSR | S_IWUSR); ··· 84 84 u32 lvl, dummy, i; 85 85 u32 *levels; 86 86 87 + if (x86_cpuid_vendor() != X86_VENDOR_AMD) 88 + return false; 89 + 87 90 native_rdmsr(MSR_AMD64_PATCH_LEVEL, lvl, dummy); 88 91 89 92 levels = final_levels; ··· 98 95 return false; 99 96 } 100 97 101 - static bool __init check_loader_disabled_bsp(void) 98 + bool __init microcode_loader_disabled(void) 102 99 { 103 - static const char *__dis_opt_str = "dis_ucode_ldr"; 104 - const char *cmdline = boot_command_line; 105 - const char *option = __dis_opt_str; 106 - 107 - /* 108 - * CPUID(1).ECX[31]: reserved for hypervisor use. This is still not 109 - * completely accurate as xen pv guests don't see that CPUID bit set but 110 - * that's good enough as they don't land on the BSP path anyway. 111 - */ 112 - if (native_cpuid_ecx(1) & BIT(31)) 100 + if (dis_ucode_ldr) 113 101 return true; 114 102 115 - if (x86_cpuid_vendor() == X86_VENDOR_AMD) { 116 - if (amd_check_current_patch_level()) 117 - return true; 118 - } 119 - 120 - if (cmdline_find_option_bool(cmdline, option) <= 0) 121 - dis_ucode_ldr = false; 103 + /* 104 + * Disable when: 105 + * 106 + * 1) The CPU does not support CPUID. 107 + * 108 + * 2) Bit 31 in CPUID[1]:ECX is clear 109 + * The bit is reserved for hypervisor use. This is still not 110 + * completely accurate as XEN PV guests don't see that CPUID bit 111 + * set, but that's good enough as they don't land on the BSP 112 + * path anyway. 113 + * 114 + * 3) Certain AMD patch levels are not allowed to be 115 + * overwritten. 116 + */ 117 + if (!have_cpuid_p() || 118 + native_cpuid_ecx(1) & BIT(31) || 119 + amd_check_current_patch_level()) 120 + dis_ucode_ldr = true; 122 121 123 122 return dis_ucode_ldr; 124 123 } ··· 130 125 unsigned int cpuid_1_eax; 131 126 bool intel = true; 132 127 133 - if (!have_cpuid_p()) 128 + if (cmdline_find_option_bool(boot_command_line, "dis_ucode_ldr") > 0) 129 + dis_ucode_ldr = true; 130 + 131 + if (microcode_loader_disabled()) 134 132 return; 135 133 136 134 cpuid_1_eax = native_cpuid_eax(1); ··· 154 146 return; 155 147 } 156 148 157 - if (check_loader_disabled_bsp()) 158 - return; 159 - 160 149 if (intel) 161 150 load_ucode_intel_bsp(&early_data); 162 151 else ··· 164 159 { 165 160 unsigned int cpuid_1_eax; 166 161 162 + /* 163 + * Can't use microcode_loader_disabled() here - .init section 164 + * hell. It doesn't have to either - the BSP variant must've 165 + * parsed cmdline already anyway. 166 + */ 167 167 if (dis_ucode_ldr) 168 168 return; 169 169 ··· 820 810 struct cpuinfo_x86 *c = &boot_cpu_data; 821 811 int error; 822 812 823 - if (dis_ucode_ldr) 813 + if (microcode_loader_disabled()) 824 814 return -EINVAL; 825 815 826 816 if (c->x86_vendor == X86_VENDOR_INTEL)
+1 -1
arch/x86/kernel/cpu/microcode/intel.c
··· 389 389 if (xchg(&ucode_patch_va, NULL) != UCODE_BSP_LOADED) 390 390 return 0; 391 391 392 - if (dis_ucode_ldr || boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) 392 + if (microcode_loader_disabled() || boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) 393 393 return 0; 394 394 395 395 uci.mc = get_microcode_blob(&uci, true);
-1
arch/x86/kernel/cpu/microcode/internal.h
··· 94 94 return x86_family(eax); 95 95 } 96 96 97 - extern bool dis_ucode_ldr; 98 97 extern bool force_minrev; 99 98 100 99 #ifdef CONFIG_CPU_SUP_AMD
-4
arch/x86/kernel/head32.c
··· 145 145 *ptr = (unsigned long)ptep + PAGE_OFFSET; 146 146 147 147 #ifdef CONFIG_MICROCODE_INITRD32 148 - /* Running on a hypervisor? */ 149 - if (native_cpuid_ecx(1) & BIT(31)) 150 - return; 151 - 152 148 params = (struct boot_params *)__pa_nodebug(&boot_params); 153 149 if (!params->hdr.ramdisk_size || !params->hdr.ramdisk_image) 154 150 return;