x86, microcode: Add a disable chicken bit
Add a cmdline param which disables the microcode loader. This is useful mostly in debugging situations where we want to turn off microcode loading, both early from the initrd and late, as a means to be able to rule out its influence on the machine. Signed-off-by: Borislav Petkov <bp@suse.de> Link: http://lkml.kernel.org/r/1400525957-11525-3-git-send-email-bp@alien8.de Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
		
					parent
					
						
							
								1b1ded57a4
							
						
					
				
			
			
				commit
				
					
						65cef1311d
					
				
			
		
					 3 changed files with 44 additions and 0 deletions
				
			
		|  | @ -25,6 +25,7 @@ struct cpu_signature { | ||||||
| struct device; | struct device; | ||||||
| 
 | 
 | ||||||
| enum ucode_state { UCODE_ERROR, UCODE_OK, UCODE_NFOUND }; | enum ucode_state { UCODE_ERROR, UCODE_OK, UCODE_NFOUND }; | ||||||
|  | extern bool dis_ucode_ldr; | ||||||
| 
 | 
 | ||||||
| struct microcode_ops { | struct microcode_ops { | ||||||
| 	enum ucode_state (*request_microcode_user) (int cpu, | 	enum ucode_state (*request_microcode_user) (int cpu, | ||||||
|  |  | ||||||
|  | @ -97,6 +97,9 @@ MODULE_LICENSE("GPL"); | ||||||
| 
 | 
 | ||||||
| static struct microcode_ops	*microcode_ops; | static struct microcode_ops	*microcode_ops; | ||||||
| 
 | 
 | ||||||
|  | bool dis_ucode_ldr; | ||||||
|  | module_param(dis_ucode_ldr, bool, 0); | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Synchronization. |  * Synchronization. | ||||||
|  * |  * | ||||||
|  | @ -546,6 +549,9 @@ static int __init microcode_init(void) | ||||||
| 	struct cpuinfo_x86 *c = &cpu_data(0); | 	struct cpuinfo_x86 *c = &cpu_data(0); | ||||||
| 	int error; | 	int error; | ||||||
| 
 | 
 | ||||||
|  | 	if (dis_ucode_ldr) | ||||||
|  | 		return 0; | ||||||
|  | 
 | ||||||
| 	if (c->x86_vendor == X86_VENDOR_INTEL) | 	if (c->x86_vendor == X86_VENDOR_INTEL) | ||||||
| 		microcode_ops = init_intel_microcode(); | 		microcode_ops = init_intel_microcode(); | ||||||
| 	else if (c->x86_vendor == X86_VENDOR_AMD) | 	else if (c->x86_vendor == X86_VENDOR_AMD) | ||||||
|  |  | ||||||
|  | @ -17,9 +17,11 @@ | ||||||
|  *	2 of the License, or (at your option) any later version. |  *	2 of the License, or (at your option) any later version. | ||||||
|  */ |  */ | ||||||
| #include <linux/module.h> | #include <linux/module.h> | ||||||
|  | #include <asm/microcode.h> | ||||||
| #include <asm/microcode_intel.h> | #include <asm/microcode_intel.h> | ||||||
| #include <asm/microcode_amd.h> | #include <asm/microcode_amd.h> | ||||||
| #include <asm/processor.h> | #include <asm/processor.h> | ||||||
|  | #include <asm/cmdline.h> | ||||||
| 
 | 
 | ||||||
| #define QCHAR(a, b, c, d) ((a) + ((b) << 8) + ((c) << 16) + ((d) << 24)) | #define QCHAR(a, b, c, d) ((a) + ((b) << 8) + ((c) << 16) + ((d) << 24)) | ||||||
| #define CPUID_INTEL1 QCHAR('G', 'e', 'n', 'u') | #define CPUID_INTEL1 QCHAR('G', 'e', 'n', 'u') | ||||||
|  | @ -72,10 +74,33 @@ static int x86_family(void) | ||||||
| 	return x86; | 	return x86; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static bool __init check_loader_disabled_bsp(void) | ||||||
|  | { | ||||||
|  | #ifdef CONFIG_X86_32 | ||||||
|  | 	const char *cmdline = (const char *)__pa_nodebug(boot_command_line); | ||||||
|  | 	const char *opt	    = "dis_ucode_ldr"; | ||||||
|  | 	const char *option  = (const char *)__pa_nodebug(opt); | ||||||
|  | 	bool *res = (bool *)__pa_nodebug(&dis_ucode_ldr); | ||||||
|  | 
 | ||||||
|  | #else /* CONFIG_X86_64 */ | ||||||
|  | 	const char *cmdline = boot_command_line; | ||||||
|  | 	const char *option  = "dis_ucode_ldr"; | ||||||
|  | 	bool *res = &dis_ucode_ldr; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 	if (cmdline_find_option_bool(cmdline, option)) | ||||||
|  | 		*res = true; | ||||||
|  | 
 | ||||||
|  | 	return *res; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void __init load_ucode_bsp(void) | void __init load_ucode_bsp(void) | ||||||
| { | { | ||||||
| 	int vendor, x86; | 	int vendor, x86; | ||||||
| 
 | 
 | ||||||
|  | 	if (check_loader_disabled_bsp()) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
| 	if (!have_cpuid_p()) | 	if (!have_cpuid_p()) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
|  | @ -96,10 +121,22 @@ void __init load_ucode_bsp(void) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static bool check_loader_disabled_ap(void) | ||||||
|  | { | ||||||
|  | #ifdef CONFIG_X86_32 | ||||||
|  | 	return __pa_nodebug(dis_ucode_ldr); | ||||||
|  | #else | ||||||
|  | 	return dis_ucode_ldr; | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void load_ucode_ap(void) | void load_ucode_ap(void) | ||||||
| { | { | ||||||
| 	int vendor, x86; | 	int vendor, x86; | ||||||
| 
 | 
 | ||||||
|  | 	if (check_loader_disabled_ap()) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
| 	if (!have_cpuid_p()) | 	if (!have_cpuid_p()) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Borislav Petkov
				Borislav Petkov