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 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:

- two microcode loader fixes

- two FPU xstate handling fixes

- an MCE timer handling related crash fix"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/mce: Make timer handling more robust
x86/microcode: Do not access the initrd after it has been freed
x86/fpu/xstate: Fix xcomp_bv in XSAVES header
x86/fpu: Set the xcomp_bv when we fake up a XSAVES area
x86/microcode/intel: Drop stashed AP patch pointer optimization

+37 -35
+1
arch/x86/include/asm/microcode.h
··· 140 140 extern void load_ucode_ap(void); 141 141 void reload_early_microcode(void); 142 142 extern bool get_builtin_firmware(struct cpio_data *cd, const char *name); 143 + extern bool initrd_gone; 143 144 #else 144 145 static inline int __init microcode_init(void) { return 0; }; 145 146 static inline void __init load_ucode_bsp(void) { }
+12 -19
arch/x86/kernel/cpu/mcheck/mce.c
··· 1373 1373 1374 1374 static unsigned long (*mce_adjust_timer)(unsigned long interval) = mce_adjust_timer_default; 1375 1375 1376 - static void __restart_timer(struct timer_list *t, unsigned long interval) 1376 + static void __start_timer(struct timer_list *t, unsigned long interval) 1377 1377 { 1378 1378 unsigned long when = jiffies + interval; 1379 1379 unsigned long flags; 1380 1380 1381 1381 local_irq_save(flags); 1382 1382 1383 - if (timer_pending(t)) { 1384 - if (time_before(when, t->expires)) 1385 - mod_timer(t, when); 1386 - } else { 1387 - t->expires = round_jiffies(when); 1388 - add_timer_on(t, smp_processor_id()); 1389 - } 1383 + if (!timer_pending(t) || time_before(when, t->expires)) 1384 + mod_timer(t, round_jiffies(when)); 1390 1385 1391 1386 local_irq_restore(flags); 1392 1387 } ··· 1416 1421 1417 1422 done: 1418 1423 __this_cpu_write(mce_next_interval, iv); 1419 - __restart_timer(t, iv); 1424 + __start_timer(t, iv); 1420 1425 } 1421 1426 1422 1427 /* ··· 1427 1432 struct timer_list *t = this_cpu_ptr(&mce_timer); 1428 1433 unsigned long iv = __this_cpu_read(mce_next_interval); 1429 1434 1430 - __restart_timer(t, interval); 1435 + __start_timer(t, interval); 1431 1436 1432 1437 if (interval < iv) 1433 1438 __this_cpu_write(mce_next_interval, interval); ··· 1774 1779 } 1775 1780 } 1776 1781 1777 - static void mce_start_timer(unsigned int cpu, struct timer_list *t) 1782 + static void mce_start_timer(struct timer_list *t) 1778 1783 { 1779 1784 unsigned long iv = check_interval * HZ; 1780 1785 1781 1786 if (mca_cfg.ignore_ce || !iv) 1782 1787 return; 1783 1788 1784 - per_cpu(mce_next_interval, cpu) = iv; 1785 - 1786 - t->expires = round_jiffies(jiffies + iv); 1787 - add_timer_on(t, cpu); 1789 + this_cpu_write(mce_next_interval, iv); 1790 + __start_timer(t, iv); 1788 1791 } 1789 1792 1790 1793 static void __mcheck_cpu_setup_timer(void) ··· 1799 1806 unsigned int cpu = smp_processor_id(); 1800 1807 1801 1808 setup_pinned_timer(t, mce_timer_fn, cpu); 1802 - mce_start_timer(cpu, t); 1809 + mce_start_timer(t); 1803 1810 } 1804 1811 1805 1812 /* Handle unconfigured int18 (should never happen) */ ··· 2559 2566 2560 2567 static int mce_cpu_online(unsigned int cpu) 2561 2568 { 2562 - struct timer_list *t = &per_cpu(mce_timer, cpu); 2569 + struct timer_list *t = this_cpu_ptr(&mce_timer); 2563 2570 int ret; 2564 2571 2565 2572 mce_device_create(cpu); ··· 2570 2577 return ret; 2571 2578 } 2572 2579 mce_reenable_cpu(); 2573 - mce_start_timer(cpu, t); 2580 + mce_start_timer(t); 2574 2581 return 0; 2575 2582 } 2576 2583 2577 2584 static int mce_cpu_pre_down(unsigned int cpu) 2578 2585 { 2579 - struct timer_list *t = &per_cpu(mce_timer, cpu); 2586 + struct timer_list *t = this_cpu_ptr(&mce_timer); 2580 2587 2581 2588 mce_disable_cpu(); 2582 2589 del_timer_sync(t);
+3 -2
arch/x86/kernel/cpu/microcode/amd.c
··· 384 384 reget: 385 385 if (!get_builtin_microcode(&cp, family)) { 386 386 #ifdef CONFIG_BLK_DEV_INITRD 387 - cp = find_cpio_data(ucode_path, (void *)initrd_start, 388 - initrd_end - initrd_start, NULL); 387 + if (!initrd_gone) 388 + cp = find_cpio_data(ucode_path, (void *)initrd_start, 389 + initrd_end - initrd_start, NULL); 389 390 #endif 390 391 if (!(cp.data && cp.size)) { 391 392 /*
+17 -5
arch/x86/kernel/cpu/microcode/core.c
··· 46 46 static struct microcode_ops *microcode_ops; 47 47 static bool dis_ucode_ldr = true; 48 48 49 + bool initrd_gone; 50 + 49 51 LIST_HEAD(microcode_cache); 50 52 51 53 /* ··· 192 190 static int __init save_microcode_in_initrd(void) 193 191 { 194 192 struct cpuinfo_x86 *c = &boot_cpu_data; 193 + int ret = -EINVAL; 195 194 196 195 switch (c->x86_vendor) { 197 196 case X86_VENDOR_INTEL: 198 197 if (c->x86 >= 6) 199 - return save_microcode_in_initrd_intel(); 198 + ret = save_microcode_in_initrd_intel(); 200 199 break; 201 200 case X86_VENDOR_AMD: 202 201 if (c->x86 >= 0x10) 203 - return save_microcode_in_initrd_amd(c->x86); 202 + ret = save_microcode_in_initrd_amd(c->x86); 204 203 break; 205 204 default: 206 205 break; 207 206 } 208 207 209 - return -EINVAL; 208 + initrd_gone = true; 209 + 210 + return ret; 210 211 } 211 212 212 213 struct cpio_data find_microcode_in_initrd(const char *path, bool use_pa) ··· 252 247 * has the virtual address of the beginning of the initrd. It also 253 248 * possibly relocates the ramdisk. In either case, initrd_start contains 254 249 * the updated address so use that instead. 250 + * 251 + * initrd_gone is for the hotplug case where we've thrown out initrd 252 + * already. 255 253 */ 256 - if (!use_pa && initrd_start) 257 - start = initrd_start; 254 + if (!use_pa) { 255 + if (initrd_gone) 256 + return (struct cpio_data){ NULL, 0, "" }; 257 + if (initrd_start) 258 + start = initrd_start; 259 + } 258 260 259 261 return find_cpio_data(path, (void *)start, size, NULL); 260 262 #else /* !CONFIG_BLK_DEV_INITRD */
+1 -8
arch/x86/kernel/cpu/microcode/intel.c
··· 41 41 42 42 static const char ucode_path[] = "kernel/x86/microcode/GenuineIntel.bin"; 43 43 44 - /* Current microcode patch used in early patching */ 44 + /* Current microcode patch used in early patching on the APs. */ 45 45 struct microcode_intel *intel_ucode_patch; 46 46 47 47 static inline bool cpu_signatures_match(unsigned int s1, unsigned int p1, ··· 607 607 struct ucode_cpu_info uci; 608 608 struct cpio_data cp; 609 609 610 - /* 611 - * AP loading didn't find any microcode patch, no need to save anything. 612 - */ 613 - if (!intel_ucode_patch || IS_ERR(intel_ucode_patch)) 614 - return 0; 615 - 616 610 if (!load_builtin_intel_microcode(&cp)) 617 611 cp = find_microcode_in_initrd(ucode_path, false); 618 612 ··· 621 627 622 628 return 0; 623 629 } 624 - 625 630 626 631 /* 627 632 * @res_patch, output: a pointer to the patch we found.
+3 -1
arch/x86/kernel/fpu/core.c
··· 9 9 #include <asm/fpu/regset.h> 10 10 #include <asm/fpu/signal.h> 11 11 #include <asm/fpu/types.h> 12 + #include <asm/fpu/xstate.h> 12 13 #include <asm/traps.h> 13 14 14 15 #include <linux/hardirq.h> ··· 184 183 * it will #GP. Make sure it is replaced after the memset(). 185 184 */ 186 185 if (static_cpu_has(X86_FEATURE_XSAVES)) 187 - state->xsave.header.xcomp_bv = XCOMP_BV_COMPACTED_FORMAT; 186 + state->xsave.header.xcomp_bv = XCOMP_BV_COMPACTED_FORMAT | 187 + xfeatures_mask; 188 188 189 189 if (static_cpu_has(X86_FEATURE_FXSR)) 190 190 fpstate_init_fxstate(&state->fxsave);