diff options
| author | Borislav Petkov <bp@suse.de> | 2014-05-19 14:59:17 -0400 |
|---|---|---|
| committer | H. Peter Anvin <hpa@zytor.com> | 2014-05-20 23:21:27 -0400 |
| commit | 65cef1311d5d212fd3d48a43678536dc878ca288 (patch) | |
| tree | 016bff3b97650be35dc3fac764116734a5d1d803 /arch/x86/kernel/cpu/microcode | |
| parent | 1b1ded57a4f2f4420b4de7c395d1b841d8b3c41a (diff) | |
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>
Diffstat (limited to 'arch/x86/kernel/cpu/microcode')
| -rw-r--r-- | arch/x86/kernel/cpu/microcode/core.c | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/microcode/core_early.c | 37 |
2 files changed, 43 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index 15c987698b0f..dd9d6190b08d 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c | |||
| @@ -97,6 +97,9 @@ MODULE_LICENSE("GPL"); | |||
| 97 | 97 | ||
| 98 | static struct microcode_ops *microcode_ops; | 98 | static struct microcode_ops *microcode_ops; |
| 99 | 99 | ||
| 100 | bool dis_ucode_ldr; | ||
| 101 | module_param(dis_ucode_ldr, bool, 0); | ||
| 102 | |||
| 100 | /* | 103 | /* |
| 101 | * Synchronization. | 104 | * Synchronization. |
| 102 | * | 105 | * |
| @@ -546,6 +549,9 @@ static int __init microcode_init(void) | |||
| 546 | struct cpuinfo_x86 *c = &cpu_data(0); | 549 | struct cpuinfo_x86 *c = &cpu_data(0); |
| 547 | int error; | 550 | int error; |
| 548 | 551 | ||
| 552 | if (dis_ucode_ldr) | ||
| 553 | return 0; | ||
| 554 | |||
| 549 | if (c->x86_vendor == X86_VENDOR_INTEL) | 555 | if (c->x86_vendor == X86_VENDOR_INTEL) |
| 550 | microcode_ops = init_intel_microcode(); | 556 | microcode_ops = init_intel_microcode(); |
| 551 | else if (c->x86_vendor == X86_VENDOR_AMD) | 557 | else if (c->x86_vendor == X86_VENDOR_AMD) |
diff --git a/arch/x86/kernel/cpu/microcode/core_early.c b/arch/x86/kernel/cpu/microcode/core_early.c index be7f8514f577..5f28a64e71ea 100644 --- a/arch/x86/kernel/cpu/microcode/core_early.c +++ b/arch/x86/kernel/cpu/microcode/core_early.c | |||
| @@ -17,9 +17,11 @@ | |||
| 17 | * 2 of the License, or (at your option) any later version. | 17 | * 2 of the License, or (at your option) any later version. |
| 18 | */ | 18 | */ |
| 19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
| 20 | #include <asm/microcode.h> | ||
| 20 | #include <asm/microcode_intel.h> | 21 | #include <asm/microcode_intel.h> |
| 21 | #include <asm/microcode_amd.h> | 22 | #include <asm/microcode_amd.h> |
| 22 | #include <asm/processor.h> | 23 | #include <asm/processor.h> |
| 24 | #include <asm/cmdline.h> | ||
| 23 | 25 | ||
| 24 | #define QCHAR(a, b, c, d) ((a) + ((b) << 8) + ((c) << 16) + ((d) << 24)) | 26 | #define QCHAR(a, b, c, d) ((a) + ((b) << 8) + ((c) << 16) + ((d) << 24)) |
| 25 | #define CPUID_INTEL1 QCHAR('G', 'e', 'n', 'u') | 27 | #define CPUID_INTEL1 QCHAR('G', 'e', 'n', 'u') |
| @@ -72,10 +74,33 @@ static int x86_family(void) | |||
| 72 | return x86; | 74 | return x86; |
| 73 | } | 75 | } |
| 74 | 76 | ||
| 77 | static bool __init check_loader_disabled_bsp(void) | ||
| 78 | { | ||
| 79 | #ifdef CONFIG_X86_32 | ||
| 80 | const char *cmdline = (const char *)__pa_nodebug(boot_command_line); | ||
| 81 | const char *opt = "dis_ucode_ldr"; | ||
| 82 | const char *option = (const char *)__pa_nodebug(opt); | ||
| 83 | bool *res = (bool *)__pa_nodebug(&dis_ucode_ldr); | ||
| 84 | |||
| 85 | #else /* CONFIG_X86_64 */ | ||
| 86 | const char *cmdline = boot_command_line; | ||
| 87 | const char *option = "dis_ucode_ldr"; | ||
| 88 | bool *res = &dis_ucode_ldr; | ||
| 89 | #endif | ||
| 90 | |||
| 91 | if (cmdline_find_option_bool(cmdline, option)) | ||
| 92 | *res = true; | ||
| 93 | |||
| 94 | return *res; | ||
| 95 | } | ||
| 96 | |||
| 75 | void __init load_ucode_bsp(void) | 97 | void __init load_ucode_bsp(void) |
| 76 | { | 98 | { |
| 77 | int vendor, x86; | 99 | int vendor, x86; |
| 78 | 100 | ||
| 101 | if (check_loader_disabled_bsp()) | ||
| 102 | return; | ||
| 103 | |||
| 79 | if (!have_cpuid_p()) | 104 | if (!have_cpuid_p()) |
| 80 | return; | 105 | return; |
| 81 | 106 | ||
| @@ -96,10 +121,22 @@ void __init load_ucode_bsp(void) | |||
| 96 | } | 121 | } |
| 97 | } | 122 | } |
| 98 | 123 | ||
| 124 | static bool check_loader_disabled_ap(void) | ||
| 125 | { | ||
| 126 | #ifdef CONFIG_X86_32 | ||
| 127 | return __pa_nodebug(dis_ucode_ldr); | ||
| 128 | #else | ||
| 129 | return dis_ucode_ldr; | ||
| 130 | #endif | ||
| 131 | } | ||
| 132 | |||
| 99 | void load_ucode_ap(void) | 133 | void load_ucode_ap(void) |
| 100 | { | 134 | { |
| 101 | int vendor, x86; | 135 | int vendor, x86; |
| 102 | 136 | ||
| 137 | if (check_loader_disabled_ap()) | ||
| 138 | return; | ||
| 139 | |||
| 103 | if (!have_cpuid_p()) | 140 | if (!have_cpuid_p()) |
| 104 | return; | 141 | return; |
| 105 | 142 | ||
