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 set of fixes for x86:

- Fix the bogus detection of 32bit user mode for uretprobes which
caused corruption of the user return address resulting in
application crashes. In the uprobes handler in_ia32_syscall() is
obviously always returning false on a 64bit kernel. Use
user_64bit_mode() instead which works correctly.

- Prevent large page splitting when ftrace flips RW/RO on the kernel
text which caused iTLB performance issues. Ftrace wants to be
converted to text_poke() which avoids the problem, but for now
allow large page preservation in the static protections check when
the change request spawns a full large page.

- Prevent arch_dynirq_lower_bound() from returning 0 when the IOAPIC
is configured via device tree. In the device tree case the GSI 1:1
mapping is meaningless therefore the lower bound which protects the
GSI range on ACPI machines is irrelevant. Return the lower bound
which the core hands to the function instead of blindly returning 0
which causes the core to allocate the invalid virtual interupt
number 0 which in turn prevents all drivers from allocating and
requesting an interrupt.

- Remove the bogus initialization of LDR and DFR in the 32bit bigsmp
APIC driver. That uses physical destination mode where LDR/DFR are
ignored, but the initialization and the missing clear of LDR caused
the APIC to be left in a inconsistent state on kexec/reboot.

- Clear LDR when clearing the APIC registers so the APIC is in a well
defined state.

- Initialize variables proper in the find_trampoline_placement()
code.

- Silence GCC( build warning for the real mode part of the build"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/mm/cpa: Prevent large page split when ftrace flips RW on kernel text
x86/build: Add -Wnoaddress-of-packed-member to REALMODE_CFLAGS, to silence GCC9 build warning
x86/boot/compressed/64: Fix missing initialization in find_trampoline_placement()
x86/apic: Include the LDR when clearing out APIC registers
x86/apic: Do not initialize LDR and DFR for bigsmp
uprobes/x86: Fix detection of 32-bit user mode
x86/apic: Fix arch_dynirq_lower_bound() bug for DT enabled machines

Changed files
+43 -39
arch
+1
arch/x86/Makefile
··· 38 38 39 39 REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -ffreestanding) 40 40 REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -fno-stack-protector) 41 + REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -Wno-address-of-packed-member) 41 42 REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align4)) 42 43 export REALMODE_CFLAGS 43 44
+1 -1
arch/x86/boot/compressed/pgtable_64.c
··· 72 72 73 73 /* Find the first usable memory region under bios_start. */ 74 74 for (i = boot_params->e820_entries - 1; i >= 0; i--) { 75 - unsigned long new; 75 + unsigned long new = bios_start; 76 76 77 77 entry = &boot_params->e820_table[i]; 78 78
+4
arch/x86/kernel/apic/apic.c
··· 1179 1179 apic_write(APIC_LVT0, v | APIC_LVT_MASKED); 1180 1180 v = apic_read(APIC_LVT1); 1181 1181 apic_write(APIC_LVT1, v | APIC_LVT_MASKED); 1182 + if (!x2apic_enabled()) { 1183 + v = apic_read(APIC_LDR) & ~APIC_LDR_MASK; 1184 + apic_write(APIC_LDR, v); 1185 + } 1182 1186 if (maxlvt >= 4) { 1183 1187 v = apic_read(APIC_LVTPC); 1184 1188 apic_write(APIC_LVTPC, v | APIC_LVT_MASKED);
+2 -22
arch/x86/kernel/apic/bigsmp_32.c
··· 38 38 return early_per_cpu(x86_cpu_to_apicid, cpu); 39 39 } 40 40 41 - static inline unsigned long calculate_ldr(int cpu) 42 - { 43 - unsigned long val, id; 44 - 45 - val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; 46 - id = per_cpu(x86_bios_cpu_apicid, cpu); 47 - val |= SET_APIC_LOGICAL_ID(id); 48 - 49 - return val; 50 - } 51 - 52 41 /* 53 - * Set up the logical destination ID. 54 - * 55 - * Intel recommends to set DFR, LDR and TPR before enabling 56 - * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel 57 - * document number 292116). So here it goes... 42 + * bigsmp enables physical destination mode 43 + * and doesn't use LDR and DFR 58 44 */ 59 45 static void bigsmp_init_apic_ldr(void) 60 46 { 61 - unsigned long val; 62 - int cpu = smp_processor_id(); 63 - 64 - apic_write(APIC_DFR, APIC_DFR_FLAT); 65 - val = calculate_ldr(cpu); 66 - apic_write(APIC_LDR, val); 67 47 } 68 48 69 49 static void bigsmp_setup_apic_routing(void)
+7 -1
arch/x86/kernel/apic/io_apic.c
··· 2438 2438 * dmar_alloc_hwirq() may be called before setup_IO_APIC(), so use 2439 2439 * gsi_top if ioapic_dynirq_base hasn't been initialized yet. 2440 2440 */ 2441 - return ioapic_initialized ? ioapic_dynirq_base : gsi_top; 2441 + if (!ioapic_initialized) 2442 + return gsi_top; 2443 + /* 2444 + * For DT enabled machines ioapic_dynirq_base is irrelevant and not 2445 + * updated. So simply return @from if ioapic_dynirq_base == 0. 2446 + */ 2447 + return ioapic_dynirq_base ? : from; 2442 2448 } 2443 2449 2444 2450 #ifdef CONFIG_X86_32
+10 -7
arch/x86/kernel/uprobes.c
··· 508 508 void (*abort)(struct arch_uprobe *, struct pt_regs *); 509 509 }; 510 510 511 - static inline int sizeof_long(void) 511 + static inline int sizeof_long(struct pt_regs *regs) 512 512 { 513 - return in_ia32_syscall() ? 4 : 8; 513 + /* 514 + * Check registers for mode as in_xxx_syscall() does not apply here. 515 + */ 516 + return user_64bit_mode(regs) ? 8 : 4; 514 517 } 515 518 516 519 static int default_pre_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs) ··· 524 521 525 522 static int emulate_push_stack(struct pt_regs *regs, unsigned long val) 526 523 { 527 - unsigned long new_sp = regs->sp - sizeof_long(); 524 + unsigned long new_sp = regs->sp - sizeof_long(regs); 528 525 529 - if (copy_to_user((void __user *)new_sp, &val, sizeof_long())) 526 + if (copy_to_user((void __user *)new_sp, &val, sizeof_long(regs))) 530 527 return -EFAULT; 531 528 532 529 regs->sp = new_sp; ··· 559 556 long correction = utask->vaddr - utask->xol_vaddr; 560 557 regs->ip += correction; 561 558 } else if (auprobe->defparam.fixups & UPROBE_FIX_CALL) { 562 - regs->sp += sizeof_long(); /* Pop incorrect return address */ 559 + regs->sp += sizeof_long(regs); /* Pop incorrect return address */ 563 560 if (emulate_push_stack(regs, utask->vaddr + auprobe->defparam.ilen)) 564 561 return -ERESTART; 565 562 } ··· 678 675 * "call" insn was executed out-of-line. Just restore ->sp and restart. 679 676 * We could also restore ->ip and try to call branch_emulate_op() again. 680 677 */ 681 - regs->sp += sizeof_long(); 678 + regs->sp += sizeof_long(regs); 682 679 return -ERESTART; 683 680 } 684 681 ··· 1059 1056 unsigned long 1060 1057 arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs) 1061 1058 { 1062 - int rasize = sizeof_long(), nleft; 1059 + int rasize = sizeof_long(regs), nleft; 1063 1060 unsigned long orig_ret_vaddr = 0; /* clear high bits for 32-bit apps */ 1064 1061 1065 1062 if (copy_from_user(&orig_ret_vaddr, (void __user *)regs->sp, rasize))
+18 -8
arch/x86/mm/pageattr.c
··· 516 516 */ 517 517 static inline pgprot_t static_protections(pgprot_t prot, unsigned long start, 518 518 unsigned long pfn, unsigned long npg, 519 - int warnlvl) 519 + unsigned long lpsize, int warnlvl) 520 520 { 521 521 pgprotval_t forbidden, res; 522 522 unsigned long end; ··· 535 535 check_conflict(warnlvl, prot, res, start, end, pfn, "Text NX"); 536 536 forbidden = res; 537 537 538 - res = protect_kernel_text_ro(start, end); 539 - check_conflict(warnlvl, prot, res, start, end, pfn, "Text RO"); 540 - forbidden |= res; 538 + /* 539 + * Special case to preserve a large page. If the change spawns the 540 + * full large page mapping then there is no point to split it 541 + * up. Happens with ftrace and is going to be removed once ftrace 542 + * switched to text_poke(). 543 + */ 544 + if (lpsize != (npg * PAGE_SIZE) || (start & (lpsize - 1))) { 545 + res = protect_kernel_text_ro(start, end); 546 + check_conflict(warnlvl, prot, res, start, end, pfn, "Text RO"); 547 + forbidden |= res; 548 + } 541 549 542 550 /* Check the PFN directly */ 543 551 res = protect_pci_bios(pfn, pfn + npg - 1); ··· 827 819 * extra conditional required here. 828 820 */ 829 821 chk_prot = static_protections(old_prot, lpaddr, old_pfn, numpages, 830 - CPA_CONFLICT); 822 + psize, CPA_CONFLICT); 831 823 832 824 if (WARN_ON_ONCE(pgprot_val(chk_prot) != pgprot_val(old_prot))) { 833 825 /* ··· 863 855 * protection requirement in the large page. 864 856 */ 865 857 new_prot = static_protections(req_prot, lpaddr, old_pfn, numpages, 866 - CPA_DETECT); 858 + psize, CPA_DETECT); 867 859 868 860 /* 869 861 * If there is a conflict, split the large page. ··· 914 906 if (!cpa->force_static_prot) 915 907 goto set; 916 908 917 - prot = static_protections(ref_prot, address, pfn, npg, CPA_PROTECT); 909 + /* Hand in lpsize = 0 to enforce the protection mechanism */ 910 + prot = static_protections(ref_prot, address, pfn, npg, 0, CPA_PROTECT); 918 911 919 912 if (pgprot_val(prot) == pgprot_val(ref_prot)) 920 913 goto set; ··· 1512 1503 pgprot_val(new_prot) |= pgprot_val(cpa->mask_set); 1513 1504 1514 1505 cpa_inc_4k_install(); 1515 - new_prot = static_protections(new_prot, address, pfn, 1, 1506 + /* Hand in lpsize = 0 to enforce the protection mechanism */ 1507 + new_prot = static_protections(new_prot, address, pfn, 1, 0, 1516 1508 CPA_PROTECT); 1517 1509 1518 1510 new_prot = pgprot_clear_protnone_bits(new_prot);