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:
"The biggest diffstat comes from self-test updates, plus there's entry
code fixes, 5-level paging related fixes, console debug output fixes,
and misc fixes"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/mm: Clean up the printk()s in show_fault_oops()
x86/mm: Drop unneeded __always_inline for p4d page table helpers
x86/efi: Fix efi_call_phys_epilog() with CONFIG_X86_5LEVEL=y
selftests/x86/sigreturn: Do minor cleanups
selftests/x86/sigreturn/64: Fix spurious failures on AMD CPUs
x86/entry/64/compat: Fix "x86/entry/64/compat: Preserve r8-r11 in int $0x80"
x86/mm: Don't free P4D table when it is folded at runtime
x86/entry/32: Add explicit 'l' instruction suffix
x86/mm: Get rid of KERN_CONT in show_fault_oops()

+60 -51
+1 -1
arch/x86/entry/entry_32.S
··· 477 477 * whereas POPF does not.) 478 478 */ 479 479 addl $PT_EFLAGS-PT_DS, %esp /* point esp at pt_regs->flags */ 480 - btr $X86_EFLAGS_IF_BIT, (%esp) 480 + btrl $X86_EFLAGS_IF_BIT, (%esp) 481 481 popfl 482 482 483 483 /*
+8 -8
arch/x86/entry/entry_64_compat.S
··· 84 84 pushq %rdx /* pt_regs->dx */ 85 85 pushq %rcx /* pt_regs->cx */ 86 86 pushq $-ENOSYS /* pt_regs->ax */ 87 - pushq %r8 /* pt_regs->r8 */ 87 + pushq $0 /* pt_regs->r8 = 0 */ 88 88 xorl %r8d, %r8d /* nospec r8 */ 89 - pushq %r9 /* pt_regs->r9 */ 89 + pushq $0 /* pt_regs->r9 = 0 */ 90 90 xorl %r9d, %r9d /* nospec r9 */ 91 - pushq %r10 /* pt_regs->r10 */ 91 + pushq $0 /* pt_regs->r10 = 0 */ 92 92 xorl %r10d, %r10d /* nospec r10 */ 93 - pushq %r11 /* pt_regs->r11 */ 93 + pushq $0 /* pt_regs->r11 = 0 */ 94 94 xorl %r11d, %r11d /* nospec r11 */ 95 95 pushq %rbx /* pt_regs->rbx */ 96 96 xorl %ebx, %ebx /* nospec rbx */ ··· 374 374 pushq %rcx /* pt_regs->cx */ 375 375 xorl %ecx, %ecx /* nospec cx */ 376 376 pushq $-ENOSYS /* pt_regs->ax */ 377 - pushq $0 /* pt_regs->r8 = 0 */ 377 + pushq %r8 /* pt_regs->r8 */ 378 378 xorl %r8d, %r8d /* nospec r8 */ 379 - pushq $0 /* pt_regs->r9 = 0 */ 379 + pushq %r9 /* pt_regs->r9 */ 380 380 xorl %r9d, %r9d /* nospec r9 */ 381 - pushq $0 /* pt_regs->r10 = 0 */ 381 + pushq %r10 /* pt_regs->r10*/ 382 382 xorl %r10d, %r10d /* nospec r10 */ 383 - pushq $0 /* pt_regs->r11 = 0 */ 383 + pushq %r11 /* pt_regs->r11 */ 384 384 xorl %r11d, %r11d /* nospec r11 */ 385 385 pushq %rbx /* pt_regs->rbx */ 386 386 xorl %ebx, %ebx /* nospec rbx */
+3
arch/x86/include/asm/pgalloc.h
··· 184 184 185 185 static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d) 186 186 { 187 + if (!pgtable_l5_enabled()) 188 + return; 189 + 187 190 BUG_ON((unsigned long)p4d & (PAGE_SIZE-1)); 188 191 free_page((unsigned long)p4d); 189 192 }
+1 -1
arch/x86/include/asm/pgtable.h
··· 898 898 #define pgd_page(pgd) pfn_to_page(pgd_pfn(pgd)) 899 899 900 900 /* to find an entry in a page-table-directory. */ 901 - static __always_inline p4d_t *p4d_offset(pgd_t *pgd, unsigned long address) 901 + static inline p4d_t *p4d_offset(pgd_t *pgd, unsigned long address) 902 902 { 903 903 if (!pgtable_l5_enabled()) 904 904 return (p4d_t *)pgd;
+2 -2
arch/x86/include/asm/pgtable_64.h
··· 216 216 } 217 217 #endif 218 218 219 - static __always_inline void native_set_p4d(p4d_t *p4dp, p4d_t p4d) 219 + static inline void native_set_p4d(p4d_t *p4dp, p4d_t p4d) 220 220 { 221 221 pgd_t pgd; 222 222 ··· 230 230 *p4dp = native_make_p4d(native_pgd_val(pgd)); 231 231 } 232 232 233 - static __always_inline void native_p4d_clear(p4d_t *p4d) 233 + static inline void native_p4d_clear(p4d_t *p4d) 234 234 { 235 235 native_set_p4d(p4d, native_make_p4d(0)); 236 236 }
+7 -14
arch/x86/mm/fault.c
··· 641 641 return 0; 642 642 } 643 643 644 - static const char nx_warning[] = KERN_CRIT 645 - "kernel tried to execute NX-protected page - exploit attempt? (uid: %d)\n"; 646 - static const char smep_warning[] = KERN_CRIT 647 - "unable to execute userspace code (SMEP?) (uid: %d)\n"; 648 - 649 644 static void 650 645 show_fault_oops(struct pt_regs *regs, unsigned long error_code, 651 646 unsigned long address) ··· 659 664 pte = lookup_address_in_pgd(pgd, address, &level); 660 665 661 666 if (pte && pte_present(*pte) && !pte_exec(*pte)) 662 - printk(nx_warning, from_kuid(&init_user_ns, current_uid())); 667 + pr_crit("kernel tried to execute NX-protected page - exploit attempt? (uid: %d)\n", 668 + from_kuid(&init_user_ns, current_uid())); 663 669 if (pte && pte_present(*pte) && pte_exec(*pte) && 664 670 (pgd_flags(*pgd) & _PAGE_USER) && 665 671 (__read_cr4() & X86_CR4_SMEP)) 666 - printk(smep_warning, from_kuid(&init_user_ns, current_uid())); 672 + pr_crit("unable to execute userspace code (SMEP?) (uid: %d)\n", 673 + from_kuid(&init_user_ns, current_uid())); 667 674 } 668 675 669 - printk(KERN_ALERT "BUG: unable to handle kernel "); 670 - if (address < PAGE_SIZE) 671 - printk(KERN_CONT "NULL pointer dereference"); 672 - else 673 - printk(KERN_CONT "paging request"); 674 - 675 - printk(KERN_CONT " at %px\n", (void *) address); 676 + pr_alert("BUG: unable to handle kernel %s at %px\n", 677 + address < PAGE_SIZE ? "NULL pointer dereference" : "paging request", 678 + (void *)address); 676 679 677 680 dump_pagetable(address); 678 681 }
+2 -2
arch/x86/platform/efi/efi_64.c
··· 166 166 pgd = pgd_offset_k(pgd_idx * PGDIR_SIZE); 167 167 set_pgd(pgd_offset_k(pgd_idx * PGDIR_SIZE), save_pgd[pgd_idx]); 168 168 169 - if (!(pgd_val(*pgd) & _PAGE_PRESENT)) 169 + if (!pgd_present(*pgd)) 170 170 continue; 171 171 172 172 for (i = 0; i < PTRS_PER_P4D; i++) { 173 173 p4d = p4d_offset(pgd, 174 174 pgd_idx * PGDIR_SIZE + i * P4D_SIZE); 175 175 176 - if (!(p4d_val(*p4d) & _PAGE_PRESENT)) 176 + if (!p4d_present(*p4d)) 177 177 continue; 178 178 179 179 pud = (pud_t *)p4d_page_vaddr(*p4d);
+36 -23
tools/testing/selftests/x86/sigreturn.c
··· 610 610 */ 611 611 for (int i = 0; i < NGREG; i++) { 612 612 greg_t req = requested_regs[i], res = resulting_regs[i]; 613 + 613 614 if (i == REG_TRAPNO || i == REG_IP) 614 615 continue; /* don't care */ 615 - if (i == REG_SP) { 616 - printf("\tSP: %llx -> %llx\n", (unsigned long long)req, 617 - (unsigned long long)res); 618 616 617 + if (i == REG_SP) { 619 618 /* 620 - * In many circumstances, the high 32 bits of rsp 621 - * are zeroed. For example, we could be a real 622 - * 32-bit program, or we could hit any of a number 623 - * of poorly-documented IRET or segmented ESP 624 - * oddities. If this happens, it's okay. 619 + * If we were using a 16-bit stack segment, then 620 + * the kernel is a bit stuck: IRET only restores 621 + * the low 16 bits of ESP/RSP if SS is 16-bit. 622 + * The kernel uses a hack to restore bits 31:16, 623 + * but that hack doesn't help with bits 63:32. 624 + * On Intel CPUs, bits 63:32 end up zeroed, and, on 625 + * AMD CPUs, they leak the high bits of the kernel 626 + * espfix64 stack pointer. There's very little that 627 + * the kernel can do about it. 628 + * 629 + * Similarly, if we are returning to a 32-bit context, 630 + * the CPU will often lose the high 32 bits of RSP. 625 631 */ 626 - if (res == (req & 0xFFFFFFFF)) 627 - continue; /* OK; not expected to work */ 632 + 633 + if (res == req) 634 + continue; 635 + 636 + if (cs_bits != 64 && ((res ^ req) & 0xFFFFFFFF) == 0) { 637 + printf("[NOTE]\tSP: %llx -> %llx\n", 638 + (unsigned long long)req, 639 + (unsigned long long)res); 640 + continue; 641 + } 642 + 643 + printf("[FAIL]\tSP mismatch: requested 0x%llx; got 0x%llx\n", 644 + (unsigned long long)requested_regs[i], 645 + (unsigned long long)resulting_regs[i]); 646 + nerrs++; 647 + continue; 628 648 } 629 649 630 650 bool ignore_reg = false; ··· 674 654 #endif 675 655 676 656 /* Sanity check on the kernel */ 677 - if (i == REG_CX && requested_regs[i] != resulting_regs[i]) { 657 + if (i == REG_CX && req != res) { 678 658 printf("[FAIL]\tCX (saved SP) mismatch: requested 0x%llx; got 0x%llx\n", 679 - (unsigned long long)requested_regs[i], 680 - (unsigned long long)resulting_regs[i]); 659 + (unsigned long long)req, 660 + (unsigned long long)res); 681 661 nerrs++; 682 662 continue; 683 663 } 684 664 685 - if (requested_regs[i] != resulting_regs[i] && !ignore_reg) { 686 - /* 687 - * SP is particularly interesting here. The 688 - * usual cause of failures is that we hit the 689 - * nasty IRET case of returning to a 16-bit SS, 690 - * in which case bits 16:31 of the *kernel* 691 - * stack pointer persist in ESP. 692 - */ 665 + if (req != res && !ignore_reg) { 693 666 printf("[FAIL]\tReg %d mismatch: requested 0x%llx; got 0x%llx\n", 694 - i, (unsigned long long)requested_regs[i], 695 - (unsigned long long)resulting_regs[i]); 667 + i, (unsigned long long)req, 668 + (unsigned long long)res); 696 669 nerrs++; 697 670 } 698 671 }