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

Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Thomas Gleixner:
"A collection of assorted fixes:

- Fix for the pinned cr0/4 fallout which escaped all testing efforts
because the kvm-intel module was never loaded when the kernel was
compiled with CONFIG_PARAVIRT=n. The cr0/4 accessors are moved out
of line and static key is now solely used in the core code and
therefore can stay in the RO after init section. So the kvm-intel
and other modules do not longer reference the (read only) static
key which the module loader tried to update.

- Prevent an infinite loop in arch_stack_walk_user() by breaking out
of the loop once the return address is detected to be 0.

- Prevent the int3_emulate_call() selftest from corrupting the stack
when KASAN is enabled. KASASN clobbers more registers than covered
by the emulated call implementation. Convert the int3_magic()
selftest to a ASM function so the compiler cannot KASANify it.

- Unbreak the build with old GCC versions and with the Gold linker by
reverting the 'Move of _etext to the actual end of .text'. In both
cases the build fails with 'Invalid absolute R_X86_64_32S
relocation: _etext'

- Initialize the context lock for init_mm, which was never an issue
until the alternatives code started to use a temporary mm for
patching.

- Fix a build warning vs. the LOWMEM_PAGES constant where clang
complains rightfully about a signed integer overflow in the shift
operation by converting the operand to an ULL.

- Adjust the misnamed ENDPROC() of common_spurious in the 32bit entry
code"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/stacktrace: Prevent infinite loop in arch_stack_walk_user()
x86/asm: Move native_write_cr0/4() out of line
x86/pgtable/32: Fix LOWMEM_PAGES constant
x86/alternatives: Fix int3_emulate_call() selftest stack corruption
x86/entry/32: Fix ENDPROC of common_spurious
Revert "x86/build: Move _etext to actual end of .text"
x86/ldt: Initialize the context lock for init_mm

+90 -83
+1 -1
arch/x86/entry/entry_32.S
··· 1189 1189 movl %esp, %eax 1190 1190 call smp_spurious_interrupt 1191 1191 jmp ret_from_intr 1192 - ENDPROC(common_interrupt) 1192 + ENDPROC(common_spurious) 1193 1193 #endif 1194 1194 1195 1195 /*
+1
arch/x86/include/asm/mmu.h
··· 59 59 #define INIT_MM_CONTEXT(mm) \ 60 60 .context = { \ 61 61 .ctx_id = 1, \ 62 + .lock = __MUTEX_INITIALIZER(mm.context.lock), \ 62 63 } 63 64 64 65 void leave_mm(int cpu);
+1 -1
arch/x86/include/asm/pgtable_32.h
··· 106 106 * with only a host target support using a 32-bit type for internal 107 107 * representation. 108 108 */ 109 - #define LOWMEM_PAGES ((((2<<31) - __PAGE_OFFSET) >> PAGE_SHIFT)) 109 + #define LOWMEM_PAGES ((((_ULL(2)<<31) - __PAGE_OFFSET) >> PAGE_SHIFT)) 110 110 111 111 #endif /* _ASM_X86_PGTABLE_32_H */
+1
arch/x86/include/asm/processor.h
··· 741 741 extern void load_fixmap_gdt(int); 742 742 extern void load_percpu_segment(int); 743 743 extern void cpu_init(void); 744 + extern void cr4_init(void); 744 745 745 746 static inline unsigned long get_debugctlmsr(void) 746 747 {
+2 -39
arch/x86/include/asm/special_insns.h
··· 18 18 */ 19 19 extern unsigned long __force_order; 20 20 21 - /* Starts false and gets enabled once CPU feature detection is done. */ 22 - DECLARE_STATIC_KEY_FALSE(cr_pinning); 23 - extern unsigned long cr4_pinned_bits; 21 + void native_write_cr0(unsigned long val); 24 22 25 23 static inline unsigned long native_read_cr0(void) 26 24 { 27 25 unsigned long val; 28 26 asm volatile("mov %%cr0,%0\n\t" : "=r" (val), "=m" (__force_order)); 29 27 return val; 30 - } 31 - 32 - static inline void native_write_cr0(unsigned long val) 33 - { 34 - unsigned long bits_missing = 0; 35 - 36 - set_register: 37 - asm volatile("mov %0,%%cr0": "+r" (val), "+m" (__force_order)); 38 - 39 - if (static_branch_likely(&cr_pinning)) { 40 - if (unlikely((val & X86_CR0_WP) != X86_CR0_WP)) { 41 - bits_missing = X86_CR0_WP; 42 - val |= bits_missing; 43 - goto set_register; 44 - } 45 - /* Warn after we've set the missing bits. */ 46 - WARN_ONCE(bits_missing, "CR0 WP bit went missing!?\n"); 47 - } 48 28 } 49 29 50 30 static inline unsigned long native_read_cr2(void) ··· 71 91 return val; 72 92 } 73 93 74 - static inline void native_write_cr4(unsigned long val) 75 - { 76 - unsigned long bits_missing = 0; 77 - 78 - set_register: 79 - asm volatile("mov %0,%%cr4": "+r" (val), "+m" (cr4_pinned_bits)); 80 - 81 - if (static_branch_likely(&cr_pinning)) { 82 - if (unlikely((val & cr4_pinned_bits) != cr4_pinned_bits)) { 83 - bits_missing = ~val & cr4_pinned_bits; 84 - val |= bits_missing; 85 - goto set_register; 86 - } 87 - /* Warn after we've set the missing bits. */ 88 - WARN_ONCE(bits_missing, "CR4 bits went missing: %lx!?\n", 89 - bits_missing); 90 - } 91 - } 94 + void native_write_cr4(unsigned long val); 92 95 93 96 #ifdef CONFIG_X86_64 94 97 static inline unsigned long native_read_cr8(void)
+20 -5
arch/x86/kernel/alternative.c
··· 625 625 * 626 626 * See entry_{32,64}.S for more details. 627 627 */ 628 - static void __init int3_magic(unsigned int *ptr) 629 - { 630 - *ptr = 1; 631 - } 628 + 629 + /* 630 + * We define the int3_magic() function in assembly to control the calling 631 + * convention such that we can 'call' it from assembly. 632 + */ 633 + 634 + extern void int3_magic(unsigned int *ptr); /* defined in asm */ 635 + 636 + asm ( 637 + " .pushsection .init.text, \"ax\", @progbits\n" 638 + " .type int3_magic, @function\n" 639 + "int3_magic:\n" 640 + " movl $1, (%" _ASM_ARG1 ")\n" 641 + " ret\n" 642 + " .size int3_magic, .-int3_magic\n" 643 + " .popsection\n" 644 + ); 632 645 633 646 extern __initdata unsigned long int3_selftest_ip; /* defined in asm below */ 634 647 ··· 689 676 "int3_selftest_ip:\n\t" 690 677 __ASM_SEL(.long, .quad) " 1b\n\t" 691 678 ".popsection\n\t" 692 - : : __ASM_SEL_RAW(a, D) (&val) : "memory"); 679 + : ASM_CALL_CONSTRAINT 680 + : __ASM_SEL_RAW(a, D) (&val) 681 + : "memory"); 693 682 694 683 BUG_ON(val != 1); 695 684
+56 -16
arch/x86/kernel/cpu/common.c
··· 366 366 cr4_clear_bits(X86_CR4_UMIP); 367 367 } 368 368 369 - DEFINE_STATIC_KEY_FALSE_RO(cr_pinning); 370 - EXPORT_SYMBOL(cr_pinning); 371 - unsigned long cr4_pinned_bits __ro_after_init; 372 - EXPORT_SYMBOL(cr4_pinned_bits); 369 + static DEFINE_STATIC_KEY_FALSE_RO(cr_pinning); 370 + static unsigned long cr4_pinned_bits __ro_after_init; 371 + 372 + void native_write_cr0(unsigned long val) 373 + { 374 + unsigned long bits_missing = 0; 375 + 376 + set_register: 377 + asm volatile("mov %0,%%cr0": "+r" (val), "+m" (__force_order)); 378 + 379 + if (static_branch_likely(&cr_pinning)) { 380 + if (unlikely((val & X86_CR0_WP) != X86_CR0_WP)) { 381 + bits_missing = X86_CR0_WP; 382 + val |= bits_missing; 383 + goto set_register; 384 + } 385 + /* Warn after we've set the missing bits. */ 386 + WARN_ONCE(bits_missing, "CR0 WP bit went missing!?\n"); 387 + } 388 + } 389 + EXPORT_SYMBOL(native_write_cr0); 390 + 391 + void native_write_cr4(unsigned long val) 392 + { 393 + unsigned long bits_missing = 0; 394 + 395 + set_register: 396 + asm volatile("mov %0,%%cr4": "+r" (val), "+m" (cr4_pinned_bits)); 397 + 398 + if (static_branch_likely(&cr_pinning)) { 399 + if (unlikely((val & cr4_pinned_bits) != cr4_pinned_bits)) { 400 + bits_missing = ~val & cr4_pinned_bits; 401 + val |= bits_missing; 402 + goto set_register; 403 + } 404 + /* Warn after we've set the missing bits. */ 405 + WARN_ONCE(bits_missing, "CR4 bits went missing: %lx!?\n", 406 + bits_missing); 407 + } 408 + } 409 + EXPORT_SYMBOL(native_write_cr4); 410 + 411 + void cr4_init(void) 412 + { 413 + unsigned long cr4 = __read_cr4(); 414 + 415 + if (boot_cpu_has(X86_FEATURE_PCID)) 416 + cr4 |= X86_CR4_PCIDE; 417 + if (static_branch_likely(&cr_pinning)) 418 + cr4 |= cr4_pinned_bits; 419 + 420 + __write_cr4(cr4); 421 + 422 + /* Initialize cr4 shadow for this CPU. */ 423 + this_cpu_write(cpu_tlbstate.cr4, cr4); 424 + } 373 425 374 426 /* 375 427 * Once CPU feature detection is finished (and boot params have been ··· 1775 1723 1776 1724 wait_for_master_cpu(cpu); 1777 1725 1778 - /* 1779 - * Initialize the CR4 shadow before doing anything that could 1780 - * try to read it. 1781 - */ 1782 - cr4_init_shadow(); 1783 - 1784 1726 if (cpu) 1785 1727 load_ucode_ap(); 1786 1728 ··· 1868 1822 struct tss_struct *t = &per_cpu(cpu_tss_rw, cpu); 1869 1823 1870 1824 wait_for_master_cpu(cpu); 1871 - 1872 - /* 1873 - * Initialize the CR4 shadow before doing anything that could 1874 - * try to read it. 1875 - */ 1876 - cr4_init_shadow(); 1877 1825 1878 1826 show_ucode_info_early(); 1879 1827
+1 -13
arch/x86/kernel/smpboot.c
··· 210 210 */ 211 211 static void notrace start_secondary(void *unused) 212 212 { 213 - unsigned long cr4 = __read_cr4(); 214 - 215 213 /* 216 214 * Don't put *anything* except direct CPU state initialization 217 215 * before cpu_init(), SMP booting is too fragile that we want to 218 216 * limit the things done here to the most necessary things. 219 217 */ 220 - if (boot_cpu_has(X86_FEATURE_PCID)) 221 - cr4 |= X86_CR4_PCIDE; 222 - if (static_branch_likely(&cr_pinning)) 223 - cr4 |= cr4_pinned_bits; 224 - 225 - __write_cr4(cr4); 218 + cr4_init(); 226 219 227 220 #ifdef CONFIG_X86_32 228 221 /* switch away from the initial page table */ 229 222 load_cr3(swapper_pg_dir); 230 - /* 231 - * Initialize the CR4 shadow before doing anything that could 232 - * try to read it. 233 - */ 234 - cr4_init_shadow(); 235 223 __flush_tlb_all(); 236 224 #endif 237 225 load_current_idt();
+3 -5
arch/x86/kernel/stacktrace.c
··· 129 129 break; 130 130 if ((unsigned long)fp < regs->sp) 131 131 break; 132 - if (frame.ret_addr) { 133 - if (!consume_entry(cookie, frame.ret_addr, false)) 134 - return; 135 - } 136 - if (fp == frame.next_fp) 132 + if (!frame.ret_addr) 133 + break; 134 + if (!consume_entry(cookie, frame.ret_addr, false)) 137 135 break; 138 136 fp = frame.next_fp; 139 137 }
+3 -3
arch/x86/kernel/vmlinux.lds.S
··· 141 141 *(.text.__x86.indirect_thunk) 142 142 __indirect_thunk_end = .; 143 143 #endif 144 - } :text = 0x9090 145 144 146 - /* End of text section */ 147 - _etext = .; 145 + /* End of text section */ 146 + _etext = .; 147 + } :text = 0x9090 148 148 149 149 NOTES :text :note 150 150
+1
arch/x86/xen/smp_pv.c
··· 58 58 { 59 59 int cpu; 60 60 61 + cr4_init(); 61 62 cpu_init(); 62 63 touch_softlockup_watchdog(); 63 64 preempt_disable();