diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-06-02 11:53:42 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-06-02 11:53:42 -0400 |
| commit | f2a025defd804be938f8acffe62e4801a3ed1601 (patch) | |
| tree | 95aca7ea234389743b7c148961647c84da1bcfff | |
| parent | f56f88ee3fa1c3080f6ba122a597e75f0d5ab969 (diff) | |
| parent | c08d517480ea342cc43acdacc5cf4a795e18151d (diff) | |
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Ingo Molnar:
"Misc fixes:
- revert a broken PAT commit that broke a number of systems
- fix two preemptability warnings/bugs that can trigger under certain
circumstances, in the debug code and in the microcode loader"
* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
Revert "x86/PAT: Fix Xorg regression on CPUs that don't support PAT"
x86/debug/32: Convert a smp_processor_id() call to raw to avoid DEBUG_PREEMPT warning
x86/microcode/AMD: Change load_microcode_amd()'s param to bool to fix preemptibility bug
| -rw-r--r-- | arch/x86/kernel/cpu/microcode/amd.c | 16 | ||||
| -rw-r--r-- | arch/x86/kernel/process_32.c | 2 | ||||
| -rw-r--r-- | arch/x86/mm/pat.c | 9 |
3 files changed, 12 insertions, 15 deletions
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 45db4d2ebd01..e9f4d762aa5b 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c | |||
| @@ -320,7 +320,7 @@ void load_ucode_amd_ap(unsigned int cpuid_1_eax) | |||
| 320 | } | 320 | } |
| 321 | 321 | ||
| 322 | static enum ucode_state | 322 | static enum ucode_state |
| 323 | load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size); | 323 | load_microcode_amd(bool save, u8 family, const u8 *data, size_t size); |
| 324 | 324 | ||
| 325 | int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax) | 325 | int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax) |
| 326 | { | 326 | { |
| @@ -338,8 +338,7 @@ int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax) | |||
| 338 | if (!desc.mc) | 338 | if (!desc.mc) |
| 339 | return -EINVAL; | 339 | return -EINVAL; |
| 340 | 340 | ||
| 341 | ret = load_microcode_amd(smp_processor_id(), x86_family(cpuid_1_eax), | 341 | ret = load_microcode_amd(true, x86_family(cpuid_1_eax), desc.data, desc.size); |
| 342 | desc.data, desc.size); | ||
| 343 | if (ret != UCODE_OK) | 342 | if (ret != UCODE_OK) |
| 344 | return -EINVAL; | 343 | return -EINVAL; |
| 345 | 344 | ||
| @@ -675,7 +674,7 @@ static enum ucode_state __load_microcode_amd(u8 family, const u8 *data, | |||
| 675 | } | 674 | } |
| 676 | 675 | ||
| 677 | static enum ucode_state | 676 | static enum ucode_state |
| 678 | load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size) | 677 | load_microcode_amd(bool save, u8 family, const u8 *data, size_t size) |
| 679 | { | 678 | { |
| 680 | enum ucode_state ret; | 679 | enum ucode_state ret; |
| 681 | 680 | ||
| @@ -689,8 +688,8 @@ load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size) | |||
| 689 | 688 | ||
| 690 | #ifdef CONFIG_X86_32 | 689 | #ifdef CONFIG_X86_32 |
| 691 | /* save BSP's matching patch for early load */ | 690 | /* save BSP's matching patch for early load */ |
| 692 | if (cpu_data(cpu).cpu_index == boot_cpu_data.cpu_index) { | 691 | if (save) { |
| 693 | struct ucode_patch *p = find_patch(cpu); | 692 | struct ucode_patch *p = find_patch(0); |
| 694 | if (p) { | 693 | if (p) { |
| 695 | memset(amd_ucode_patch, 0, PATCH_MAX_SIZE); | 694 | memset(amd_ucode_patch, 0, PATCH_MAX_SIZE); |
| 696 | memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data), | 695 | memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data), |
| @@ -722,11 +721,12 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device, | |||
| 722 | { | 721 | { |
| 723 | char fw_name[36] = "amd-ucode/microcode_amd.bin"; | 722 | char fw_name[36] = "amd-ucode/microcode_amd.bin"; |
| 724 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 723 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
| 724 | bool bsp = c->cpu_index == boot_cpu_data.cpu_index; | ||
| 725 | enum ucode_state ret = UCODE_NFOUND; | 725 | enum ucode_state ret = UCODE_NFOUND; |
| 726 | const struct firmware *fw; | 726 | const struct firmware *fw; |
| 727 | 727 | ||
| 728 | /* reload ucode container only on the boot cpu */ | 728 | /* reload ucode container only on the boot cpu */ |
| 729 | if (!refresh_fw || c->cpu_index != boot_cpu_data.cpu_index) | 729 | if (!refresh_fw || !bsp) |
| 730 | return UCODE_OK; | 730 | return UCODE_OK; |
| 731 | 731 | ||
| 732 | if (c->x86 >= 0x15) | 732 | if (c->x86 >= 0x15) |
| @@ -743,7 +743,7 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device, | |||
| 743 | goto fw_release; | 743 | goto fw_release; |
| 744 | } | 744 | } |
| 745 | 745 | ||
| 746 | ret = load_microcode_amd(cpu, c->x86, fw->data, fw->size); | 746 | ret = load_microcode_amd(bsp, c->x86, fw->data, fw->size); |
| 747 | 747 | ||
| 748 | fw_release: | 748 | fw_release: |
| 749 | release_firmware(fw); | 749 | release_firmware(fw); |
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index ff40e74c9181..ffeae818aa7a 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
| @@ -78,7 +78,7 @@ void __show_regs(struct pt_regs *regs, int all) | |||
| 78 | 78 | ||
| 79 | printk(KERN_DEFAULT "EIP: %pS\n", (void *)regs->ip); | 79 | printk(KERN_DEFAULT "EIP: %pS\n", (void *)regs->ip); |
| 80 | printk(KERN_DEFAULT "EFLAGS: %08lx CPU: %d\n", regs->flags, | 80 | printk(KERN_DEFAULT "EFLAGS: %08lx CPU: %d\n", regs->flags, |
| 81 | smp_processor_id()); | 81 | raw_smp_processor_id()); |
| 82 | 82 | ||
| 83 | printk(KERN_DEFAULT "EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", | 83 | printk(KERN_DEFAULT "EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", |
| 84 | regs->ax, regs->bx, regs->cx, regs->dx); | 84 | regs->ax, regs->bx, regs->cx, regs->dx); |
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 83a59a67757a..9b78685b66e6 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
| @@ -65,11 +65,9 @@ static int __init nopat(char *str) | |||
| 65 | } | 65 | } |
| 66 | early_param("nopat", nopat); | 66 | early_param("nopat", nopat); |
| 67 | 67 | ||
| 68 | static bool __read_mostly __pat_initialized = false; | ||
| 69 | |||
| 70 | bool pat_enabled(void) | 68 | bool pat_enabled(void) |
| 71 | { | 69 | { |
| 72 | return __pat_initialized; | 70 | return !!__pat_enabled; |
| 73 | } | 71 | } |
| 74 | EXPORT_SYMBOL_GPL(pat_enabled); | 72 | EXPORT_SYMBOL_GPL(pat_enabled); |
| 75 | 73 | ||
| @@ -227,14 +225,13 @@ static void pat_bsp_init(u64 pat) | |||
| 227 | } | 225 | } |
| 228 | 226 | ||
| 229 | wrmsrl(MSR_IA32_CR_PAT, pat); | 227 | wrmsrl(MSR_IA32_CR_PAT, pat); |
| 230 | __pat_initialized = true; | ||
| 231 | 228 | ||
| 232 | __init_cache_modes(pat); | 229 | __init_cache_modes(pat); |
| 233 | } | 230 | } |
| 234 | 231 | ||
| 235 | static void pat_ap_init(u64 pat) | 232 | static void pat_ap_init(u64 pat) |
| 236 | { | 233 | { |
| 237 | if (!this_cpu_has(X86_FEATURE_PAT)) { | 234 | if (!boot_cpu_has(X86_FEATURE_PAT)) { |
| 238 | /* | 235 | /* |
| 239 | * If this happens we are on a secondary CPU, but switched to | 236 | * If this happens we are on a secondary CPU, but switched to |
| 240 | * PAT on the boot CPU. We have no way to undo PAT. | 237 | * PAT on the boot CPU. We have no way to undo PAT. |
| @@ -309,7 +306,7 @@ void pat_init(void) | |||
| 309 | u64 pat; | 306 | u64 pat; |
| 310 | struct cpuinfo_x86 *c = &boot_cpu_data; | 307 | struct cpuinfo_x86 *c = &boot_cpu_data; |
| 311 | 308 | ||
| 312 | if (!__pat_enabled) { | 309 | if (!pat_enabled()) { |
| 313 | init_cache_modes(); | 310 | init_cache_modes(); |
| 314 | return; | 311 | return; |
| 315 | } | 312 | } |
