Pull x86 fixes from Borislav Petkov: - A fix to disable PCI/MSI[-X] masking for XEN_HVM guests as that is solely controlled by the hypervisor - A build fix to make the function prototype (__warn()) as visible as the definition itself - A bunch of objtool annotation fixes which have accumulated over time - An ORC unwinder fix to handle bad input gracefully - Well, we thought the microcode gets loaded in time in order to restore the microcode-emulated MSRs but we thought wrong. So there's a fix for that to have the ordering done properly - Add new Intel model numbers - A spelling fix * tag 'x86_urgent_for_v5.18_rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/pci/xen: Disable PCI/MSI[-X] masking for XEN_HVM guests bug: Have __warn() prototype defined unconditionally x86/Kconfig: fix the spelling of 'becoming' in X86_KERNEL_IBT config objtool: Use offstr() to print address of missing ENDBR objtool: Print data address for "!ENDBR" data warnings x86/xen: Add ANNOTATE_NOENDBR to startup_xen() x86/uaccess: Add ENDBR to __put_user_nocheck*() x86/retpoline: Add ANNOTATE_NOENDBR for retpolines x86/static_call: Add ANNOTATE_NOENDBR to static call trampoline objtool: Enable unreachable warnings for CLANG LTO x86,objtool: Explicitly mark idtentry_body()s tail REACHABLE x86,objtool: Mark cpu_startup_entry() __noreturn x86,xen,objtool: Add UNWIND hint lib/strn*,objtool: Enforce user_access_begin() rules MAINTAINERS: Add x86 unwinding entry x86/unwind/orc: Recheck address range after stack info was updated x86/cpu: Load microcode during restore_processor_state() x86/cpu: Add new Alderlake and Raptorlake CPU model numbers
Unified · Split
| @@ -21443,6 +21443,15 @@ F: arch/x86/include/asm/uv/ · 21442 unmodified lines | ||
| 21443 | 21443 | F: arch/x86/kernel/apic/x2apic_uv_x.c |
| 21444 | 21444 | F: arch/x86/platform/uv/ |
| 21445 | 21445 | |
| 21446 | +X86 STACK UNWINDING | |
| 21447 | +M: Josh Poimboeuf <jpoimboe@redhat.com> | |
| 21448 | +M: Peter Zijlstra <peterz@infradead.org> | |
| 21449 | +S: Supported | |
| 21450 | +F: arch/x86/include/asm/unwind*.h | |
| 21451 | +F: arch/x86/kernel/dumpstack.c | |
| 21452 | +F: arch/x86/kernel/stacktrace.c | |
| 21453 | +F: arch/x86/kernel/unwind_*.c | |
| 21454 | + | |
| 21446 | 21455 | X86 VDSO |
| 21447 | 21456 | M: Andy Lutomirski <luto@kernel.org> |
| 21448 | 21457 | L: linux-kernel@vger.kernel.org |
| @@ -1866,7 +1866,7 @@ config X86_KERNEL_IBT · 1865 unmodified lines | ||
| 1866 | 1866 | code with them to make this happen. |
| 1867 | 1867 | |
| 1868 | 1868 | In addition to building the kernel with IBT, seal all functions that |
| 1869 | − are not indirect call targets, avoiding them ever becomming one. | |
| 1869 | + are not indirect call targets, avoiding them ever becoming one. | |
| 1870 | 1870 | |
| 1871 | 1871 | This requires LTO like objtool runs and will slow down the build. It |
| 1872 | 1872 | does significantly reduce the number of ENDBR instructions in the |
| @@ -337,6 +337,9 @@ SYM_CODE_END(ret_from_fork) · 336 unmodified lines | ||
| 337 | 337 | |
| 338 | 338 | call \cfunc |
| 339 | 339 | |
| 340 | + /* For some configurations \cfunc ends up being a noreturn. */ | |
| 341 | + REACHABLE | |
| 342 | + | |
| 340 | 343 | jmp error_return |
| 341 | 344 | .endm |
| 342 | 345 | |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | * _G - parts with extra graphics on |
| 27 | 27 | * _X - regular server parts |
| 28 | 28 | * _D - micro server parts |
| 29 | + * _N,_P - other mobile parts | |
| 29 | 30 | * |
| 30 | 31 | * Historical OPTDIFFs: |
| 31 | 32 | * |
| @@ -107,8 +108,10 @@ · 75 unmodified lines | ||
| 107 | 108 | |
| 108 | 109 | #define INTEL_FAM6_ALDERLAKE 0x97 /* Golden Cove / Gracemont */ |
| 109 | 110 | #define INTEL_FAM6_ALDERLAKE_L 0x9A /* Golden Cove / Gracemont */ |
| 111 | +#define INTEL_FAM6_ALDERLAKE_N 0xBE | |
| 110 | 112 | |
| 111 | 113 | #define INTEL_FAM6_RAPTORLAKE 0xB7 |
| 114 | +#define INTEL_FAM6_RAPTORLAKE_P 0xBA | |
| 112 | 115 | |
| 113 | 116 | /* "Small Core" Processors (Atom) */ |
| 114 | 117 | |
| @@ -131,10 +131,12 @@ extern void __init load_ucode_bsp(void); · 130 unmodified lines | ||
| 131 | 131 | extern void load_ucode_ap(void); |
| 132 | 132 | void reload_early_microcode(void); |
| 133 | 133 | extern bool initrd_gone; |
| 134 | +void microcode_bsp_resume(void); | |
| 134 | 135 | #else |
| 135 | 136 | static inline void __init load_ucode_bsp(void) { } |
| 136 | 137 | static inline void load_ucode_ap(void) { } |
| 137 | 138 | static inline void reload_early_microcode(void) { } |
| 139 | +static inline void microcode_bsp_resume(void) { } | |
| 138 | 140 | #endif |
| 139 | 141 | |
| 140 | 142 | #endif /* _ASM_X86_MICROCODE_H */ |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | ".align 4 \n" \ |
| 27 | 27 | ".globl " STATIC_CALL_TRAMP_STR(name) " \n" \ |
| 28 | 28 | STATIC_CALL_TRAMP_STR(name) ": \n" \ |
| 29 | + ANNOTATE_NOENDBR \ | |
| 29 | 30 | insns " \n" \ |
| 30 | 31 | ".byte 0x53, 0x43, 0x54 \n" \ |
| 31 | 32 | ".type " STATIC_CALL_TRAMP_STR(name) ", @function \n" \ |
| @@ -758,9 +758,9 @@ static struct subsys_interface mc_cpu_interface = { · 757 unmodified lines | ||
| 758 | 758 | }; |
| 759 | 759 | |
| 760 | 760 | /** |
| 761 | − * mc_bp_resume - Update boot CPU microcode during resume. | |
| 761 | + * microcode_bsp_resume - Update boot CPU microcode during resume. | |
| 762 | 762 | */ |
| 763 | −static void mc_bp_resume(void) | |
| 763 | +void microcode_bsp_resume(void) | |
| 764 | 764 | { |
| 765 | 765 | int cpu = smp_processor_id(); |
| 766 | 766 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
| @@ -772,7 +772,7 @@ static void mc_bp_resume(void) · 5 unmodified lines | ||
| 772 | 772 | } |
| 773 | 773 | |
| 774 | 774 | static struct syscore_ops mc_syscore_ops = { |
| 775 | − .resume = mc_bp_resume, | |
| 775 | + .resume = microcode_bsp_resume, | |
| 776 | 776 | }; |
| 777 | 777 | |
| 778 | 778 | static int mc_cpu_starting(unsigned int cpu) |
| @@ -339,11 +339,11 @@ static bool stack_access_ok(struct unwind_state *state, unsigned long _addr, · 338 unmodified lines | ||
| 339 | 339 | struct stack_info *info = &state->stack_info; |
| 340 | 340 | void *addr = (void *)_addr; |
| 341 | 341 | |
| 342 | − if (!on_stack(info, addr, len) && | |
| 343 | − (get_stack_info(addr, state->task, info, &state->stack_mask))) | |
| 344 | − return false; | |
| 342 | + if (on_stack(info, addr, len)) | |
| 343 | + return true; | |
| 345 | 344 | |
| 346 | − return true; | |
| 345 | + return !get_stack_info(addr, state->task, info, &state->stack_mask) && | |
| 346 | + on_stack(info, addr, len); | |
| 347 | 347 | } |
| 348 | 348 | |
| 349 | 349 | static bool deref_stack_reg(struct unwind_state *state, unsigned long addr, |
| @@ -48,6 +48,7 @@ SYM_FUNC_START(__put_user_1) · 47 unmodified lines | ||
| 48 | 48 | cmp %_ASM_BX,%_ASM_CX |
| 49 | 49 | jae .Lbad_put_user |
| 50 | 50 | SYM_INNER_LABEL(__put_user_nocheck_1, SYM_L_GLOBAL) |
| 51 | + ENDBR | |
| 51 | 52 | ASM_STAC |
| 52 | 53 | 1: movb %al,(%_ASM_CX) |
| 53 | 54 | xor %ecx,%ecx |
| @@ -62,6 +63,7 @@ SYM_FUNC_START(__put_user_2) · 8 unmodified lines | ||
| 62 | 63 | cmp %_ASM_BX,%_ASM_CX |
| 63 | 64 | jae .Lbad_put_user |
| 64 | 65 | SYM_INNER_LABEL(__put_user_nocheck_2, SYM_L_GLOBAL) |
| 66 | + ENDBR | |
| 65 | 67 | ASM_STAC |
| 66 | 68 | 2: movw %ax,(%_ASM_CX) |
| 67 | 69 | xor %ecx,%ecx |
| @@ -76,6 +78,7 @@ SYM_FUNC_START(__put_user_4) · 8 unmodified lines | ||
| 76 | 78 | cmp %_ASM_BX,%_ASM_CX |
| 77 | 79 | jae .Lbad_put_user |
| 78 | 80 | SYM_INNER_LABEL(__put_user_nocheck_4, SYM_L_GLOBAL) |
| 81 | + ENDBR | |
| 79 | 82 | ASM_STAC |
| 80 | 83 | 3: movl %eax,(%_ASM_CX) |
| 81 | 84 | xor %ecx,%ecx |
| @@ -90,6 +93,7 @@ SYM_FUNC_START(__put_user_8) · 8 unmodified lines | ||
| 90 | 93 | cmp %_ASM_BX,%_ASM_CX |
| 91 | 94 | jae .Lbad_put_user |
| 92 | 95 | SYM_INNER_LABEL(__put_user_nocheck_8, SYM_L_GLOBAL) |
| 96 | + ENDBR | |
| 93 | 97 | ASM_STAC |
| 94 | 98 | 4: mov %_ASM_AX,(%_ASM_CX) |
| 95 | 99 | #ifdef CONFIG_X86_32 |
| @@ -31,6 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | .align RETPOLINE_THUNK_SIZE |
| 32 | 32 | SYM_INNER_LABEL(__x86_indirect_thunk_\reg, SYM_L_GLOBAL) |
| 33 | 33 | UNWIND_HINT_EMPTY |
| 34 | + ANNOTATE_NOENDBR | |
| 34 | 35 | |
| 35 | 36 | ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \ |
| 36 | 37 | __stringify(RETPOLINE \reg), X86_FEATURE_RETPOLINE, \ |
| @@ -55,7 +56,6 @@ SYM_INNER_LABEL(__x86_indirect_thunk_\reg, SYM_L_GLOBAL) · 18 unmodified lines | ||
| 55 | 56 | |
| 56 | 57 | .align RETPOLINE_THUNK_SIZE |
| 57 | 58 | SYM_CODE_START(__x86_indirect_thunk_array) |
| 58 | − ANNOTATE_NOENDBR // apply_retpolines | |
| 59 | 59 | |
| 60 | 60 | #define GEN(reg) THUNK reg |
| 61 | 61 | #include <asm/GEN-for-each-reg.h> |
| @@ -467,7 +467,6 @@ static __init void xen_setup_pci_msi(void) · 466 unmodified lines | ||
| 467 | 467 | else |
| 468 | 468 | xen_msi_ops.setup_msi_irqs = xen_setup_msi_irqs; |
| 469 | 469 | xen_msi_ops.teardown_msi_irqs = xen_pv_teardown_msi_irqs; |
| 470 | − pci_msi_ignore_mask = 1; | |
| 471 | 470 | } else if (xen_hvm_domain()) { |
| 472 | 471 | xen_msi_ops.setup_msi_irqs = xen_hvm_setup_msi_irqs; |
| 473 | 472 | xen_msi_ops.teardown_msi_irqs = xen_teardown_msi_irqs; |
| @@ -481,6 +480,11 @@ static __init void xen_setup_pci_msi(void) · 7 unmodified lines | ||
| 481 | 480 | * in allocating the native domain and never use it. |
| 482 | 481 | */ |
| 483 | 482 | x86_init.irqs.create_pci_msi_domain = xen_create_pci_msi_domain; |
| 483 | + /* | |
| 484 | + * With XEN PIRQ/Eventchannels in use PCI/MSI[-X] masking is solely | |
| 485 | + * controlled by the hypervisor. | |
| 486 | + */ | |
| 487 | + pci_msi_ignore_mask = 1; | |
| 484 | 488 | } |
| 485 | 489 | |
| 486 | 490 | #else /* CONFIG_PCI_MSI */ |
| @@ -50,6 +50,7 @@ · 49 unmodified lines | ||
| 50 | 50 | #define PVH_DS_SEL (PVH_GDT_ENTRY_DS * 8) |
| 51 | 51 | |
| 52 | 52 | SYM_CODE_START_LOCAL(pvh_start_xen) |
| 53 | + UNWIND_HINT_EMPTY | |
| 53 | 54 | cld |
| 54 | 55 | |
| 55 | 56 | lgdt (_pa(gdt)) |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <asm/cpu.h> |
| 26 | 26 | #include <asm/mmu_context.h> |
| 27 | 27 | #include <asm/cpu_device_id.h> |
| 28 | +#include <asm/microcode.h> | |
| 28 | 29 | |
| 29 | 30 | #ifdef CONFIG_X86_32 |
| 30 | 31 | __visible unsigned long saved_context_ebx; |
| @@ -262,11 +263,18 @@ static void notrace __restore_processor_state(struct saved_context *ctxt) · 231 unmodified lines | ||
| 262 | 263 | x86_platform.restore_sched_clock_state(); |
| 263 | 264 | mtrr_bp_restore(); |
| 264 | 265 | perf_restore_debug_store(); |
| 265 | − msr_restore_context(ctxt); | |
| 266 | 266 | |
| 267 | 267 | c = &cpu_data(smp_processor_id()); |
| 268 | 268 | if (cpu_has(c, X86_FEATURE_MSR_IA32_FEAT_CTL)) |
| 269 | 269 | init_ia32_feat_ctl(c); |
| 270 | + | |
| 271 | + microcode_bsp_resume(); | |
| 272 | + | |
| 273 | + /* | |
| 274 | + * This needs to happen after the microcode has been updated upon resume | |
| 275 | + * because some of the MSRs are "emulated" in microcode. | |
| 276 | + */ | |
| 277 | + msr_restore_context(ctxt); | |
| 270 | 278 | } |
| 271 | 279 | |
| 272 | 280 | /* Needed by apm.c */ |
| @@ -45,6 +45,7 @@ SYM_CODE_END(hypercall_page) · 44 unmodified lines | ||
| 45 | 45 | __INIT |
| 46 | 46 | SYM_CODE_START(startup_xen) |
| 47 | 47 | UNWIND_HINT_EMPTY |
| 48 | + ANNOTATE_NOENDBR | |
| 48 | 49 | cld |
| 49 | 50 | |
| 50 | 51 | /* Clear .bss */ |
| @@ -21,6 +21,12 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <linux/panic.h> |
| 22 | 22 | #include <linux/printk.h> |
| 23 | 23 | |
| 24 | +struct warn_args; | |
| 25 | +struct pt_regs; | |
| 26 | + | |
| 27 | +void __warn(const char *file, int line, void *caller, unsigned taint, | |
| 28 | + struct pt_regs *regs, struct warn_args *args); | |
| 29 | + | |
| 24 | 30 | #ifdef CONFIG_BUG |
| 25 | 31 | |
| 26 | 32 | #ifdef CONFIG_GENERIC_BUG |
| @@ -110,11 +116,6 @@ extern __printf(1, 2) void __warn_printk(const char *fmt, ...); · 83 unmodified lines | ||
| 110 | 116 | #endif |
| 111 | 117 | |
| 112 | 118 | /* used internally by panic.c */ |
| 113 | −struct warn_args; | |
| 114 | −struct pt_regs; | |
| 115 | − | |
| 116 | −void __warn(const char *file, int line, void *caller, unsigned taint, | |
| 117 | − struct pt_regs *regs, struct warn_args *args); | |
| 118 | 119 | |
| 119 | 120 | #ifndef WARN_ON |
| 120 | 121 | #define WARN_ON(condition) ({ \ |
| @@ -167,7 +167,7 @@ static inline int suspend_disable_secondary_cpus(void) { return 0; } · 166 unmodified lines | ||
| 167 | 167 | static inline void suspend_enable_secondary_cpus(void) { } |
| 168 | 168 | #endif /* !CONFIG_PM_SLEEP_SMP */ |
| 169 | 169 | |
| 170 | −void cpu_startup_entry(enum cpuhp_state state); | |
| 170 | +void __noreturn cpu_startup_entry(enum cpuhp_state state); | |
| 171 | 171 | |
| 172 | 172 | void cpu_idle_poll_ctrl(bool enable); |
| 173 | 173 | |
| @@ -25,7 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | * hit it), 'max' is the address space maximum (and we return |
| 26 | 26 | * -EFAULT if we hit it). |
| 27 | 27 | */ |
| 28 | −static inline long do_strncpy_from_user(char *dst, const char __user *src, | |
| 28 | +static __always_inline long do_strncpy_from_user(char *dst, const char __user *src, | |
| 29 | 29 | unsigned long count, unsigned long max) |
| 30 | 30 | { |
| 31 | 31 | const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; |
| @@ -20,7 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | * if it fits in a aligned 'long'. The caller needs to check |
| 21 | 21 | * the return value against "> max". |
| 22 | 22 | */ |
| 23 | −static inline long do_strnlen_user(const char __user *src, unsigned long count, unsigned long max) | |
| 23 | +static __always_inline long do_strnlen_user(const char __user *src, unsigned long count, unsigned long max) | |
| 24 | 24 | { |
| 25 | 25 | const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; |
| 26 | 26 | unsigned long align, res = 0; |
| @@ -231,7 +231,7 @@ objtool_args = \ · 230 unmodified lines | ||
| 231 | 231 | $(if $(part-of-module), --module) \ |
| 232 | 232 | $(if $(CONFIG_X86_KERNEL_IBT), --lto --ibt) \ |
| 233 | 233 | $(if $(CONFIG_FRAME_POINTER),, --no-fp) \ |
| 234 | − $(if $(CONFIG_GCOV_KERNEL)$(CONFIG_LTO_CLANG), --no-unreachable)\ | |
| 234 | + $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) \ | |
| 235 | 235 | $(if $(CONFIG_RETPOLINE), --retpoline) \ |
| 236 | 236 | $(if $(CONFIG_X86_SMAP), --uaccess) \ |
| 237 | 237 | $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \ |
| @@ -140,7 +140,7 @@ objtool_link() · 139 unmodified lines | ||
| 140 | 140 | if ! is_enabled CONFIG_FRAME_POINTER; then |
| 141 | 141 | objtoolopt="${objtoolopt} --no-fp" |
| 142 | 142 | fi |
| 143 | − if is_enabled CONFIG_GCOV_KERNEL || is_enabled CONFIG_LTO_CLANG; then | |
| 143 | + if is_enabled CONFIG_GCOV_KERNEL; then | |
| 144 | 144 | objtoolopt="${objtoolopt} --no-unreachable" |
| 145 | 145 | fi |
| 146 | 146 | if is_enabled CONFIG_RETPOLINE; then |
| @@ -184,6 +184,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func, · 183 unmodified lines | ||
| 184 | 184 | "do_group_exit", |
| 185 | 185 | "stop_this_cpu", |
| 186 | 186 | "__invalid_creds", |
| 187 | + "cpu_startup_entry", | |
| 187 | 188 | }; |
| 188 | 189 | |
| 189 | 190 | if (!func) |
| @@ -3217,9 +3218,8 @@ validate_ibt_reloc(struct objtool_file *file, struct reloc *reloc) · 3027 unmodified lines | ||
| 3217 | 3218 | static void warn_noendbr(const char *msg, struct section *sec, unsigned long offset, |
| 3218 | 3219 | struct instruction *dest) |
| 3219 | 3220 | { |
| 3220 | − WARN_FUNC("%srelocation to !ENDBR: %s+0x%lx", sec, offset, msg, | |
| 3221 | − dest->func ? dest->func->name : dest->sec->name, | |
| 3222 | − dest->func ? dest->offset - dest->func->offset : dest->offset); | |
| 3221 | + WARN_FUNC("%srelocation to !ENDBR: %s", sec, offset, msg, | |
| 3222 | + offstr(dest->sec, dest->offset)); | |
| 3223 | 3223 | } |
| 3224 | 3224 | |
| 3225 | 3225 | static void validate_ibt_dest(struct objtool_file *file, struct instruction *insn, |
| @@ -3823,11 +3823,8 @@ static int validate_ibt(struct objtool_file *file) · 597 unmodified lines | ||
| 3823 | 3823 | struct instruction *dest; |
| 3824 | 3824 | |
| 3825 | 3825 | dest = validate_ibt_reloc(file, reloc); |
| 3826 | − if (is_data && dest && !dest->noendbr) { | |
| 3827 | − warn_noendbr("data ", reloc->sym->sec, | |
| 3828 | − reloc->sym->offset + reloc->addend, | |
| 3829 | − dest); | |
| 3830 | − } | |
| 3826 | + if (is_data && dest && !dest->noendbr) | |
| 3827 | + warn_noendbr("data ", sec, reloc->offset, dest); | |
| 3831 | 3828 | } |
| 3832 | 3829 | } |
| 3833 | 3830 | |