5.15.55-rc1 review
Subsystems (3)
Greg Kroah-Hartman
maintainercover 5.15.55-rc1 review
This is the start of the stable review cycle for the 5.15.55 release. There are 78 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 14 Jul 2022 18:32:19 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.55-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 5.15.55-rc1
Thomas Gleixner <[email protected]>
x86/static_call: Serialize __static_call_fixup() properly
Pawan Gupta <[email protected]>
x86/speculation: Disable RRSBA behavior
Konrad Rzeszutek Wilk <[email protected]>
x86/kexec: Disable RET on kexec
Thadeu Lima de Souza Cascardo <[email protected]>
x86/bugs: Do not enable IBPB-on-entry when IBPB is not supported
Peter Zijlstra <[email protected]>
x86/entry: Move PUSH_AND_CLEAR_REGS() back into error_entry
Pawan Gupta <[email protected]>
x86/bugs: Add Cannon lake to RETBleed affected CPU list
Peter Zijlstra <[email protected]>
x86/retbleed: Add fine grained Kconfig knobs
Andrew Cooper <[email protected]>
x86/cpu/amd: Enumerate BTC_NO
Peter Zijlstra <[email protected]>
x86/common: Stamp out the stepping madness
Josh Poimboeuf <[email protected]>
x86/speculation: Fill RSB on vmexit for IBRS
Josh Poimboeuf <[email protected]>
KVM: VMX: Fix IBRS handling after vmexit
Josh Poimboeuf <[email protected]>
KVM: VMX: Prevent guest RSB poisoning attacks with eIBRS
Josh Poimboeuf <[email protected]>
KVM: VMX: Convert launched argument to flags
Josh Poimboeuf <[email protected]>
KVM: VMX: Flatten __vmx_vcpu_run()
Josh Poimboeuf <[email protected]>
objtool: Re-add UNWIND_HINT_{SAVE_RESTORE}Josh Poimboeuf <[email protected]>
x86/speculation: Remove x86_spec_ctrl_mask
Josh Poimboeuf <[email protected]>
x86/speculation: Use cached host SPEC_CTRL value for guest entry/exit
Josh Poimboeuf <[email protected]>
x86/speculation: Fix SPEC_CTRL write on SMT state change
Josh Poimboeuf <[email protected]>
x86/speculation: Fix firmware entry SPEC_CTRL handling
Josh Poimboeuf <[email protected]>
x86/speculation: Fix RSB filling with CONFIG_RETPOLINE=n
Peter Zijlstra <[email protected]>
x86/cpu/amd: Add Spectral Chicken
Peter Zijlstra <[email protected]>
objtool: Add entry UNRET validation
Josh Poimboeuf <[email protected]>
x86/bugs: Do IBPB fallback check only once
Peter Zijlstra <[email protected]>
x86/bugs: Add retbleed=ibpb
Peter Zijlstra <[email protected]>
x86/xen: Add UNTRAIN_RET
Peter Zijlstra <[email protected]>
x86/xen: Rename SYS* entry points
Peter Zijlstra <[email protected]>
objtool: Update Retpoline validation
Peter Zijlstra <[email protected]>
intel_idle: Disable IBRS during long idle
Peter Zijlstra <[email protected]>
x86/bugs: Report Intel retbleed vulnerability
Peter Zijlstra <[email protected]>
x86/bugs: Split spectre_v2_select_mitigation() and spectre_v2_user_select_mitigation()
Pawan Gupta <[email protected]>
x86/speculation: Add spectre_v2=ibrs option to support Kernel IBRS
Peter Zijlstra <[email protected]>
x86/bugs: Optimize SPEC_CTRL MSR writes
Thadeu Lima de Souza Cascardo <[email protected]>
x86/entry: Add kernel IBRS implementation
Peter Zijlstra <[email protected]>
x86/bugs: Keep a per-CPU IA32_SPEC_CTRL value
Kim Phillips <[email protected]>
x86/bugs: Enable STIBP for JMP2RET
Alexandre Chartre <[email protected]>
x86/bugs: Add AMD retbleed= boot parameter
Alexandre Chartre <[email protected]>
x86/bugs: Report AMD retbleed vulnerability
Peter Zijlstra <[email protected]>
x86: Add magic AMD return-thunk
Peter Zijlstra <[email protected]>
objtool: Treat .text.__x86.* as noinstr
Peter Zijlstra <[email protected]>
x86/entry: Avoid very early RET
Peter Zijlstra <[email protected]>
x86: Use return-thunk in asm code
Kim Phillips <[email protected]>
x86/sev: Avoid using __x86_return_thunk
Peter Zijlstra <[email protected]>
x86/vsyscall_emu/64: Don't use RET in vsyscall emulation
Peter Zijlstra <[email protected]>
x86/kvm: Fix SETcc emulation for return thunks
Peter Zijlstra <[email protected]>
x86/bpf: Use alternative RET encoding
Peter Zijlstra <[email protected]>
x86/ftrace: Use alternative RET encoding
Peter Zijlstra <[email protected]>
x86,static_call: Use alternative RET encoding
Thadeu Lima de Souza Cascardo <[email protected]>
objtool: skip non-text sections when adding return-thunk sites
Peter Zijlstra <[email protected]>
x86,objtool: Create .return_sites
Peter Zijlstra <[email protected]>
x86: Undo return-thunk damage
Peter Zijlstra <[email protected]>
x86/retpoline: Use -mfunction-return
Peter Zijlstra <[email protected]>
x86/retpoline: Swizzle retpoline thunk
Peter Zijlstra <[email protected]>
x86/retpoline: Cleanup some #ifdefery
Peter Zijlstra <[email protected]>
x86/cpufeatures: Move RETPOLINE flags to word 11
Peter Zijlstra <[email protected]>
x86/kvm/vmx: Make noinstr clean
Thadeu Lima de Souza Cascardo <[email protected]>
x86/realmode: build with -D__DISABLE_EXPORTS
Peter Zijlstra <[email protected]>
x86/entry: Remove skip_r11rcx
Peter Zijlstra <[email protected]>
objtool: Default ignore INT3 for unreachable
Peter Zijlstra <[email protected]>
bpf,x86: Respect X86_FEATURE_RETPOLINE*
Peter Zijlstra <[email protected]>
bpf,x86: Simplify computing label offsets
Peter Zijlstra <[email protected]>
x86/alternative: Add debug prints to apply_retpolines()
Peter Zijlstra <[email protected]>
x86/alternative: Try inline spectre_v2=retpoline,amd
Peter Zijlstra <[email protected]>
x86/alternative: Handle Jcc __x86_indirect_thunk_\reg
Peter Zijlstra <[email protected]>
x86/alternative: Implement .retpoline_sites support
Peter Zijlstra <[email protected]>
x86/retpoline: Create a retpoline thunk array
Peter Zijlstra <[email protected]>
x86/retpoline: Move the retpoline thunk declarations to nospec-branch.h
Peter Zijlstra <[email protected]>
x86/asm: Fixup odd GEN-for-each-reg.h usage
Peter Zijlstra <[email protected]>
x86/asm: Fix register order
Peter Zijlstra <[email protected]>
x86/retpoline: Remove unused replacement symbols
Peter Zijlstra <[email protected]>
objtool: Introduce CFI hash
Peter Zijlstra <[email protected]>
objtool,x86: Replace alternatives with .retpoline_sites
Peter Zijlstra <[email protected]>
objtool: Shrink struct instruction
Peter Zijlstra <[email protected]>
objtool: Explicitly avoid self modifying code in .altinstr_replacement
Peter Zijlstra <[email protected]>
objtool: Classify symbols
Lai Jiangshan <[email protected]>
x86/entry: Don't call error_entry() for XENPV
Lai Jiangshan <[email protected]>
x86/entry: Move PUSH_AND_CLEAR_REGS out of error_entry()
Lai Jiangshan <[email protected]>
x86/entry: Switch the stack after error_entry() returns
Lai Jiangshan <[email protected]>
x86/traps: Use pt_regs directly in fixup_bad_iret()
-------------
Diffstat:
Documentation/admin-guide/kernel-parameters.txt | 25 + Makefile | 10 +- arch/um/kernel/um_arch.c | 4 + arch/x86/Kconfig | 103 +++- arch/x86/Makefile | 2 +- arch/x86/entry/Makefile | 2 +- arch/x86/entry/calling.h | 72 ++- arch/x86/entry/entry.S | 22 + arch/x86/entry/entry_32.S | 2 - arch/x86/entry/entry_64.S | 88 ++- arch/x86/entry/entry_64_compat.S | 21 +- arch/x86/entry/vdso/Makefile | 1 + arch/x86/entry/vsyscall/vsyscall_emu_64.S | 9 +- arch/x86/include/asm/GEN-for-each-reg.h | 14 +- arch/x86/include/asm/alternative.h | 2 + arch/x86/include/asm/asm-prototypes.h | 18 - arch/x86/include/asm/cpufeatures.h | 12 +- arch/x86/include/asm/disabled-features.h | 21 +- arch/x86/include/asm/linkage.h | 8 + arch/x86/include/asm/msr-index.h | 13 + arch/x86/include/asm/nospec-branch.h | 133 ++--- arch/x86/include/asm/static_call.h | 17 + arch/x86/include/asm/traps.h | 2 +- arch/x86/include/asm/unwind_hints.h | 14 +- arch/x86/kernel/alternative.c | 260 ++++++++- arch/x86/kernel/cpu/amd.c | 46 +- arch/x86/kernel/cpu/bugs.c | 475 +++++++++++++--- arch/x86/kernel/cpu/common.c | 61 ++- arch/x86/kernel/cpu/cpu.h | 2 + arch/x86/kernel/cpu/hygon.c | 6 + arch/x86/kernel/cpu/scattered.c | 1 + arch/x86/kernel/ftrace.c | 7 +- arch/x86/kernel/head_64.S | 5 + arch/x86/kernel/module.c | 15 +- arch/x86/kernel/process.c | 2 +- arch/x86/kernel/relocate_kernel_32.S | 25 +- arch/x86/kernel/relocate_kernel_64.S | 23 +- arch/x86/kernel/static_call.c | 49 +- arch/x86/kernel/traps.c | 19 +- arch/x86/kernel/vmlinux.lds.S | 23 +- arch/x86/kvm/emulate.c | 26 +- arch/x86/kvm/svm/vmenter.S | 18 + arch/x86/kvm/vmx/nested.c | 2 +- arch/x86/kvm/vmx/run_flags.h | 8 + arch/x86/kvm/vmx/vmenter.S | 164 +++--- arch/x86/kvm/vmx/vmx.c | 76 ++- arch/x86/kvm/vmx/vmx.h | 6 +- arch/x86/kvm/x86.c | 4 +- arch/x86/lib/memmove_64.S | 7 +- arch/x86/lib/retpoline.S | 133 +++-- arch/x86/mm/mem_encrypt_boot.S | 10 +- arch/x86/net/bpf_jit_comp.c | 179 +++--- arch/x86/net/bpf_jit_comp32.c | 22 +- arch/x86/xen/setup.c | 6 +- arch/x86/xen/xen-asm.S | 30 +- arch/x86/xen/xen-head.S | 1 + arch/x86/xen/xen-ops.h | 6 +- drivers/base/cpu.c | 8 + drivers/idle/intel_idle.c | 43 +- include/linux/cpu.h | 2 + include/linux/kvm_host.h | 2 +- include/linux/objtool.h | 9 +- scripts/Makefile.build | 1 + scripts/link-vmlinux.sh | 3 + security/Kconfig | 11 - tools/arch/x86/include/asm/msr-index.h | 9 + tools/include/linux/objtool.h | 9 +- tools/objtool/arch/x86/decode.c | 145 +---- tools/objtool/builtin-check.c | 4 +- tools/objtool/check.c | 701 ++++++++++++++++++++---- tools/objtool/elf.c | 84 --- tools/objtool/include/objtool/arch.h | 3 +- tools/objtool/include/objtool/builtin.h | 2 +- tools/objtool/include/objtool/cfi.h | 2 + tools/objtool/include/objtool/check.h | 10 +- tools/objtool/include/objtool/elf.h | 9 +- tools/objtool/include/objtool/objtool.h | 1 + tools/objtool/objtool.c | 1 + tools/objtool/orc_gen.c | 15 +- tools/objtool/special.c | 8 - 80 files changed, 2470 insertions(+), 944 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/78 x86/traps: Use pt_regs directly in fixup_bad_iret()
From: Lai Jiangshan <[email protected]>
commit 0aca53c6b522f8d6e2681ca875acbbe105f5fdcf upstream.
Always stash the address error_entry() is going to return to, in %r12 and get rid of the void *error_entry_ret; slot in struct bad_iret_stack which was supposed to account for it and pt_regs pushed on the stack.
After this, both fixup_bad_iret() and sync_regs() can work on a struct pt_regs pointer directly.
[ bp: Rewrite commit message, touch ups. ]
--- arch/x86/entry/entry_64.S | 5 ++++- arch/x86/include/asm/traps.h | 2 +- arch/x86/kernel/traps.c | 19 +++++++------------ 3 files changed, 12 insertions(+), 14 deletions(-)
arch/x86/entry/entry_64.S +4 -1
@@ -1041,9 +1041,12 @@ SYM_CODE_START_LOCAL(error_entry) * Pretend that the exception came from user mode: set up pt_regs * as if we faulted immediately after IRET. */ - mov %rsp, %rdi + popq %r12 /* save return addr in %12 */ + movq %rsp, %rdi /* arg0 = pt_regs pointer */ call fixup_bad_iret mov %rax, %rsp + ENCODE_FRAME_POINTER + pushq %r12 jmp .Lerror_entry_from_usermode_after_swapgs SYM_CODE_END(error_entry)
arch/x86/include/asm/traps.h +1 -1
@@ -13,7 +13,7 @@#ifdef CONFIG_X86_64 asmlinkage __visible notrace struct pt_regs *sync_regs(struct pt_regs *eregs); asmlinkage __visible notrace -struct bad_iret_stack *fixup_bad_iret (struct bad_iret_stack *s); +struct pt_regs *fixup_bad_iret (struct pt_regs *bad_regs);void __init trap_init (void ); asmlinkage __visible noinstr struct pt_regs *vc_switch_off_ist(struct pt_regs *eregs);#endif
arch/x86/kernel/traps.c +7 -12
@@ -762,14 +762,10 @@ sync: }#endif -struct bad_iret_stack { -void *error_entry_ret; -struct pt_regs regs; -}; - -asmlinkage __visible noinstr -struct bad_iret_stack *fixup_bad_iret (struct bad_iret_stack *s) +asmlinkage __visible noinstr struct pt_regs *fixup_bad_iret(struct pt_regs *bad_regs) { +struct pt_regs tmp, *new_stack; +/* * This is called from entry_64.S early in handling a fault * caused by a bad iret to user mode. To handle the fault
@@ -778,19 +774,18 @@ struct bad_iret_stack *fixup_bad_iret(st* just below the IRET frame) and we want to pretend that the * exception came from the IRET target. */ -struct bad_iret_stack tmp, *new_stack = - (struct bad_iret_stack *)__this_cpu_read (cpu_tss_rw.x86_tss.sp0) -1 ; + new_stack = (struct pt_regs *)__this_cpu_read (cpu_tss_rw.x86_tss.sp0) -1 ;/* Copy the IRET target to the temporary storage. */ -__memcpy (&tmp.regs.ip, (void *)s->regs.sp,5 *8 ); +__memcpy (&tmp.ip, (void *)bad_regs->sp,5 *8 );/* Copy the remainder of the stack from the current stack. */ - __memcpy(&tmp, s, offsetof(struct bad_iret_stack, regs.ip)); +__memcpy (&tmp, bad_regs, offsetof(struct pt_regs , ip));/* Update the entry stack */ __memcpy (new_stack, &tmp,sizeof (tmp)); -BUG_ON (!user_mode (&new_stack->regs)); +BUG_ON (!user_mode (new_stack)); return new_stack; }#endif
Greg Kroah-Hartman
maintainerPATCH 2/78 x86/entry: Switch the stack after error_entry() returns
In reply to Greg Kroah-HartmanFrom: Lai Jiangshan <[email protected]>
commit 520a7e80c96d655fbe4650d9cc985bd9d0443389 upstream.
error_entry() calls fixup_bad_iret() before sync_regs() if it is a fault from a bad IRET, to copy pt_regs to the kernel stack. It switches to the kernel stack directly after sync_regs().
But error_entry() itself is also a function call, so it has to stash the address it is going to return to, in %r12 which is unnecessarily complicated.
Move the stack switching after error_entry() and get rid of the need to handle the return address.
[ bp: Massage commit message. ]
--- arch/x86/entry/entry_64.S | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-)
arch/x86/entry/entry_64.S +6 -10
@@ -323,6 +323,8 @@ SYM_CODE_END(ret_from_fork) .macro idtentry_body cfunc has_error_code:req call error_entry + movq %rax, %rsp /* switch to the task stack if from userspace */ + ENCODE_FRAME_POINTER UNWIND_HINT_REGS movq %rsp, %rdi /* pt_regs pointer into 1st argument*/
@@ -982,14 +984,10 @@ SYM_CODE_START_LOCAL(error_entry) /* We have user CR3. Change to kernel CR3. */ SWITCH_TO_KERNEL_CR3 scratch_reg=%rax + leaq 8(%rsp), %rdi /* arg0 = pt_regs pointer */ .Lerror_entry_from_usermode_after_swapgs: /* Put us onto the real thread stack. */ - popq %r12 /* save return addr in %12 */ - movq %rsp, %rdi /* arg0 = pt_regs pointer */ call sync_regs - movq %rax, %rsp /* switch stack */ - ENCODE_FRAME_POINTER - pushq %r12 RET /*
@@ -1021,6 +1019,7 @@ SYM_CODE_START_LOCAL(error_entry) */ .Lerror_entry_done_lfence: FENCE_SWAPGS_KERNEL_ENTRY + leaq 8(%rsp), %rax /* return pt_regs pointer */ RET .Lbstep_iret:
@@ -1041,12 +1040,9 @@ SYM_CODE_START_LOCAL(error_entry) * Pretend that the exception came from user mode: set up pt_regs * as if we faulted immediately after IRET. */ - popq %r12 /* save return addr in %12 */ - movq %rsp, %rdi /* arg0 = pt_regs pointer */ + leaq 8(%rsp), %rdi /* arg0 = pt_regs pointer */ call fixup_bad_iret - mov %rax, %rsp - ENCODE_FRAME_POINTER - pushq %r12 + mov %rax, %rdi jmp .Lerror_entry_from_usermode_after_swapgs SYM_CODE_END(error_entry)
Greg Kroah-Hartman
maintainerPATCH 3/78 x86/entry: Move PUSH_AND_CLEAR_REGS out of error_entry()
In reply to Greg Kroah-HartmanFrom: Lai Jiangshan <[email protected]>
commit ee774dac0da1543376a69fd90840af6aa86879b3 upstream.
The macro idtentry() (through idtentry_body()) calls error_entry() unconditionally even on XENPV. But XENPV needs to only push and clear regs.
PUSH_AND_CLEAR_REGS in error_entry() makes the stack not return to its original place when the function returns, which means it is not possible to convert it to a C function.
Carve out PUSH_AND_CLEAR_REGS out of error_entry() and into a separate function and call it before error_entry() in order to avoid calling error_entry() on XENPV.
It will also allow for error_entry() to be converted to C code that can use inlined sync_regs() and save a function call.
[ bp: Massage commit message. ]
--- arch/x86/entry/entry_64.S | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
arch/x86/entry/entry_64.S +12 -3
@@ -315,6 +315,14 @@ SYM_CODE_END(ret_from_fork) #endif .endm +/* Save all registers in pt_regs */ +SYM_CODE_START_LOCAL(push_and_clear_regs) + UNWIND_HINT_FUNC + PUSH_AND_CLEAR_REGS save_ret=1 + ENCODE_FRAME_POINTER 8 + RET +SYM_CODE_END(push_and_clear_regs) + /** * idtentry_body - Macro to emit code calling the C function * @cfunc: C function to be called
@@ -322,6 +330,9 @@ SYM_CODE_END(ret_from_fork) */ .macro idtentry_body cfunc has_error_code:req + call push_and_clear_regs + UNWIND_HINT_REGS + call error_entry movq %rax, %rsp /* switch to the task stack if from userspace */ ENCODE_FRAME_POINTER
@@ -965,13 +976,11 @@ SYM_CODE_START_LOCAL(paranoid_exit) SYM_CODE_END(paranoid_exit) /* - * Save all registers in pt_regs, and switch GS if needed. + * Switch GS and CR3 if needed. */ SYM_CODE_START_LOCAL(error_entry) UNWIND_HINT_FUNC cld - PUSH_AND_CLEAR_REGS save_ret=1 - ENCODE_FRAME_POINTER 8 testb $3, CS+8(%rsp) jz .Lerror_kernelspace
Greg Kroah-Hartman
maintainerPATCH 4/78 x86/entry: Dont call error_entry() for XENPV
In reply to Greg Kroah-HartmanFrom: Lai Jiangshan <[email protected]>
commit 64cbd0acb58203fb769ed2f4eab526d43e243847 upstream.
XENPV guests enter already on the task stack and they can't fault for native_iret() nor native_load_gs_index() since they use their own pvop for IRET and load_gs_index(). A CR3 switch is not needed either.
So there is no reason to call error_entry() in XENPV.
[ bp: Massage commit message. ]
--- arch/x86/entry/entry_64.S | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
arch/x86/entry/entry_64.S +11 -2
@@ -333,8 +333,17 @@ SYM_CODE_END(push_and_clear_regs) call push_and_clear_regs UNWIND_HINT_REGS - call error_entry - movq %rax, %rsp /* switch to the task stack if from userspace */ + /* + * Call error_entry() and switch to the task stack if from userspace. + * + * When in XENPV, it is already in the task stack, and it can't fault + * for native_iret() nor native_load_gs_index() since XENPV uses its + * own pvops for IRET and load_gs_index(). And it doesn't need to + * switch the CR3. So it can skip invoking error_entry(). + */ + ALTERNATIVE "call error_entry; movq %rax, %rsp", \ + "", X86_FEATURE_XENPV + ENCODE_FRAME_POINTER UNWIND_HINT_REGS
Greg Kroah-Hartman
maintainerPATCH 5/78 objtool: Classify symbols
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 1739c66eb7bd5f27f1b69a5a26e10e8327d1e136 upstream.
In order to avoid calling str*cmp() on symbol names, over and over, do them all once upfront and store the result.
[cascardo: no pv_target on struct symbol, because of missing
db2b0c5d7b6f19b3c2cab08c531b65342eb5252b]
--- tools/objtool/check.c | 34 ++++++++++++++++++++++------------ tools/objtool/include/objtool/elf.h | 7 +++++-- 2 files changed, 27 insertions(+), 14 deletions(-)
tools/objtool/check.c +22 -12
@@ -859,8 +859,7 @@ static void add_call_dest(struct objtool* so they need a little help, NOP out any KCOV calls from noinstr * text. */ -if (insn->sec->noinstr && - !strncmp (insn->call_dest->name,"__sanitizer_cov_" ,16 )) { +if (insn->sec->noinstr && insn->call_dest->kcov) {if (reloc) { reloc->type =R_NONE ;elf_write_reloc (file->elf, reloc);
@@ -884,7 +883,7 @@ static void add_call_dest(struct objtool } } -if (mcount && !strcmp (insn->call_dest->name,"__fentry__" )) { +if (mcount && insn->call_dest->fentry) {if (sibling)WARN_FUNC ("Tail call to __fentry__ !?!?" , insn->sec, insn->offset);
@@ -934,7 +933,7 @@ static int add_jump_destinations(struct }else if (reloc->sym->type ==STT_SECTION ) { dest_sec = reloc->sym->sec; dest_off =arch_dest_reloc_offset (reloc->addend); - }else if (arch_is_retpoline (reloc->sym)) { + }else if (reloc->sym->retpoline_thunk) {/* * Retpoline jumps are really dynamic jumps in * disguise, so convert them accordingly.
@@ -1075,7 +1074,7 @@ static int add_call_destinations(structadd_call_dest (file, insn, dest, false); - }else if (arch_is_retpoline (reloc->sym)) { + }else if (reloc->sym->retpoline_thunk) {/* * Retpoline calls are really dynamic calls in * disguise, so convert them accordingly.
@@ -1759,17 +1758,28 @@ static int read_intra_function_calls(strreturn 0 ; } -static int read_static_call_tramps (struct objtool_file *file) +static int classify_symbols (struct objtool_file *file) {struct section *sec;struct symbol *func;for_each_sec (file, sec) {list_for_each_entry (func, &sec->symbol_list, list) { -if (func->bind ==STB_GLOBAL && - !strncmp (func->name,STATIC_CALL_TRAMP_PREFIX_STR , +if (func->bind !=STB_GLOBAL ) +continue ; + +if (!strncmp (func->name,STATIC_CALL_TRAMP_PREFIX_STR ,strlen (STATIC_CALL_TRAMP_PREFIX_STR ))) func->static_call_tramp = true; + +if (arch_is_retpoline (func)) + func->retpoline_thunk = true; + +if (!strcmp (func->name,"__fentry__" )) + func->fentry = true; + +if (!strncmp (func->name,"__sanitizer_cov_" ,16 )) + func->kcov = true; } }
@@ -1831,7 +1841,7 @@ static int decode_sections(struct objtoo/* * Must be before add_{jump_call}_destination. */ - ret =read_static_call_tramps (file); + ret =classify_symbols (file);if (ret)return ret;
@@ -1889,9 +1899,9 @@ static int decode_sections(struct objtoostatic bool is_fentry_call (struct instruction *insn) { -if (insn->type ==INSN_CALL && insn->call_dest && - insn->call_dest->type ==STT_NOTYPE && - !strcmp (insn->call_dest->name,"__fentry__" )) +if (insn->type ==INSN_CALL && + insn->call_dest && + insn->call_dest->fentry)return true;return false;
tools/objtool/include/objtool/elf.h +5 -2
@@ -54,8 +54,11 @@ struct symbol {unsigned long offset;unsigned int len;struct symbol *pfunc, *cfunc, *alias; -bool uaccess_safe; -bool static_call_tramp; + u8 uaccess_safe : 1; + u8 static_call_tramp : 1; + u8 retpoline_thunk : 1; + u8 fentry : 1; + u8 kcov : 1; };struct reloc {
Greg Kroah-Hartman
maintainerPATCH 6/78 objtool: Explicitly avoid self modifying code in .altinstr_replacement
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit dd003edeffa3cb87bc9862582004f405d77d7670 upstream.
Assume ALTERNATIVE()s know what they're doing and do not change, or cause to change, instructions in .altinstr_replacement sections.
--- tools/objtool/check.c | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-)
tools/objtool/check.c +32 -11
@@ -840,18 +840,27 @@ static void remove_insn_ops(struct instr } } -static void add_call_dest (struct objtool_file *file,struct instruction *insn, -struct symbol *dest,bool sibling) +static void annotate_call_site (struct objtool_file *file, +struct instruction *insn,bool sibling) {struct reloc *reloc =insn_reloc (file, insn); +struct symbol *sym = insn->call_dest; - insn->call_dest = dest; -if (!dest) +if (!sym) + sym = reloc->sym; + +/* +* Alternative replacement code is just template code which is +* sometimes copied to the original instruction. For now, don't +* annotate it. (In the future we might consider annotating the +* original instruction if/when it ever makes sense to do so.) +*/ +if (!strcmp (insn->sec->name,".altinstr_replacement" ))return ; -if (insn->call_dest->static_call_tramp) { -list_add_tail (&insn->call_node, - &file->static_call_list); +if (sym->static_call_tramp) { +list_add_tail (&insn->call_node, &file->static_call_list); +return ; }/*
@@ -859,7 +868,7 @@ static void add_call_dest(struct objtool* so they need a little help, NOP out any KCOV calls from noinstr * text. */ -if (insn->sec->noinstr && insn->call_dest->kcov) { +if (insn->sec->noinstr && sym->kcov) {if (reloc) { reloc->type =R_NONE ;elf_write_reloc (file->elf, reloc);
@@ -881,9 +890,11 @@ static void add_call_dest(struct objtool*/ insn->retpoline_safe = true; } + +return ; } -if (mcount && insn->call_dest->fentry) { +if (mcount && sym->fentry) {if (sibling)WARN_FUNC ("Tail call to __fentry__ !?!?" , insn->sec, insn->offset);
@@ -898,9 +909,17 @@ static void add_call_dest(struct objtool insn->type =INSN_NOP ; -list_add_tail (&insn->mcount_loc_node, - &file->mcount_loc_list); +list_add_tail (&insn->mcount_loc_node, &file->mcount_loc_list); +return ; } +} + +static void add_call_dest (struct objtool_file *file,struct instruction *insn, +struct symbol *dest,bool sibling) +{ + insn->call_dest = dest; +if (!dest) +return ;/* * Whatever stack impact regular CALLs have, should be undone
@@ -910,6 +929,8 @@ static void add_call_dest(struct objtool* are converted to JUMP, see read_intra_function_calls(). */ remove_insn_ops (insn); + +annotate_call_site (file, insn, sibling); }/*
Greg Kroah-Hartman
maintainerPATCH 7/78 objtool: Shrink struct instruction
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit c509331b41b7365e17396c246e8c5797bccc8074 upstream.
Any one instruction can only ever call a single function, therefore insn->mcount_loc_node is superfluous and can use insn->call_node.
This shrinks struct instruction, which is by far the most numerous structure objtool creates.
--- tools/objtool/check.c | 6 +++--- tools/objtool/include/objtool/check.h | 1 - 2 files changed, 3 insertions(+), 4 deletions(-)
tools/objtool/check.c +3 -3
@@ -551,7 +551,7 @@ static int create_mcount_loc_sections(streturn 0 ; idx =0 ; -list_for_each_entry (insn, &file->mcount_loc_list, mcount_loc_node) +list_for_each_entry (insn, &file->mcount_loc_list, call_node) idx++; sec =elf_create_section (file->elf,"__mcount_loc" ,0 ,sizeof (unsigned long ), idx);
@@ -559,7 +559,7 @@ static int create_mcount_loc_sections(streturn -1 ; idx =0 ; -list_for_each_entry (insn, &file->mcount_loc_list, mcount_loc_node) { +list_for_each_entry (insn, &file->mcount_loc_list, call_node) { loc = (unsigned long *)sec->data->d_buf + idx;memset (loc,0 ,sizeof (unsigned long ));
@@ -909,7 +909,7 @@ static void annotate_call_site(struct ob insn->type =INSN_NOP ; -list_add_tail (&insn->mcount_loc_node, &file->mcount_loc_list); +list_add_tail (&insn->call_node, &file->mcount_loc_list);return ; } }
tools/objtool/include/objtool/check.h +0 -1
@@ -40,7 +40,6 @@ struct instruction {struct list_head list;struct hlist_node hash;struct list_head call_node; -struct list_head mcount_loc_node;struct section *sec;unsigned long offset;unsigned int len;
Greg Kroah-Hartman
maintainerPATCH 8/78 objtool,x86: Replace alternatives with .retpoline_sites
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 134ab5bd1883312d7a4b3033b05c6b5a1bb8889b upstream.
Instead of writing complete alternatives, simply provide a list of all the retpoline thunk calls. Then the kernel is free to do with them as it pleases. Simpler code all-round.
[cascardo: fixed conflict because of missing
8b946cc38e063f0f7bb67789478c38f6d7d457c9]
--- arch/x86/kernel/vmlinux.lds.S | 14 +++ tools/objtool/arch/x86/decode.c | 120 -------------------------------- tools/objtool/check.c | 132 +++++++++++++++++++++++++----------- tools/objtool/elf.c | 84 ---------------------- tools/objtool/include/objtool/elf.h | 1 tools/objtool/special.c | 8 -- 6 files changed, 107 insertions(+), 252 deletions(-)
arch/x86/kernel/vmlinux.lds.S +14 -0
@@ -272,6 +272,20 @@ SECTIONS __parainstructions_end = .; } +#ifdef CONFIG_RETPOLINE + /* + * List of instructions that call/jmp/jcc to retpoline thunks + * __x86_indirect_thunk_*(). These instructions can be patched along + * with alternatives, after which the section can be freed. + */ + . = ALIGN(8); + .retpoline_sites : AT(ADDR(.retpoline_sites) - LOAD_OFFSET) { + __retpoline_sites = .; + *(.retpoline_sites) + __retpoline_sites_end = .; + } +#endif + /* * struct alt_inst entries. From the header (alternative.h): * "Alternative instructions for different CPU types or capabilities"
tools/objtool/arch/x86/decode.c +0 -120
126 lines not on this page · raw message
tools/objtool/check.c +93 -39
180 lines not on this page · raw message
tools/objtool/elf.c +0 -84
90 lines not on this page · raw message
tools/objtool/include/objtool/elf.h +0 -1
@@ -143,7 +143,6 @@ int elf_write_insn(struct elf *elf, stru unsigned long offset, unsigned int len, const char *insn);int elf_write_reloc (struct elf *elf,struct reloc *reloc); -struct symbol *elf_create_undef_symbol (struct elf *elf,const char *name);int elf_write (struct elf *elf);void elf_close (struct elf *elf);
tools/objtool/special.c +0 -8
@@ -109,14 +109,6 @@ static int get_alt_entry(struct elf *elfreturn -1 ; } -/* -* Skip retpoline .altinstr_replacement... we already rewrite the -* instructions for retpolines anyway, see arch_is_retpoline() -* usage in add_{call,jump}_destinations(). -*/ -if (arch_is_retpoline (new_reloc->sym)) -return 1 ; -reloc_to_sec_off (new_reloc, &alt->new_sec, &alt->new_off);/* _ASM_EXTABLE_EX hack */
Greg Kroah-Hartman
maintainerPATCH 9/78 objtool: Introduce CFI hash
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 8b946cc38e063f0f7bb67789478c38f6d7d457c9 upstream.
Andi reported that objtool on vmlinux.o consumes more memory than his system has, leading to horrific performance.
This is in part because we keep a struct instruction for every instruction in the file in-memory. Shrink struct instruction by removing the CFI state (which includes full register state) from it and demand allocating it.
Given most instructions don't actually change CFI state, there's lots of repetition there, so add a hash table to find previous CFI instances.
Reduces memory consumption (and runtime) for processing an x86_64-allyesconfig:
pre: 4:40.84 real, 143.99 user, 44.18 sys, 30624988 mem post: 2:14.61 real, 108.58 user, 25.04 sys, 16396184 mem
--- tools/objtool/arch/x86/decode.c | 20 +--- tools/objtool/check.c | 154 ++++++++++++++++++++++++++++++---- tools/objtool/include/objtool/arch.h | 2 tools/objtool/include/objtool/cfi.h | 2 tools/objtool/include/objtool/check.h | 2 tools/objtool/orc_gen.c | 15 ++- 6 files changed, 160 insertions(+), 35 deletions(-)
tools/objtool/arch/x86/decode.c +9 -11
@@ -684,34 +684,32 @@ const char *arch_ret_insn(int len)return ret[len-1 ]; } -int arch_decode_hint_reg (struct instruction *insn,u8 sp_reg) +int arch_decode_hint_reg (u8 sp_reg,int *base) { -struct cfi_reg *cfa = &insn->cfi.cfa; -switch (sp_reg) {case ORC_REG_UNDEFINED : - cfa->base =CFI_UNDEFINED ; + *base =CFI_UNDEFINED ;break ;case ORC_REG_SP : - cfa->base =CFI_SP ; + *base =CFI_SP ;break ;case ORC_REG_BP : - cfa->base =CFI_BP ; + *base =CFI_BP ;break ;case ORC_REG_SP_INDIRECT : - cfa->base =CFI_SP_INDIRECT ; + *base =CFI_SP_INDIRECT ;break ;case ORC_REG_R10 : - cfa->base =CFI_R10 ; + *base =CFI_R10 ;break ;case ORC_REG_R13 : - cfa->base =CFI_R13 ; + *base =CFI_R13 ;break ;case ORC_REG_DI : - cfa->base =CFI_DI ; + *base =CFI_DI ;break ;case ORC_REG_DX : - cfa->base =CFI_DX ; + *base =CFI_DX ;break ;default :return -1 ;
tools/objtool/check.c +136 -18
271 lines not on this page · raw message
tools/objtool/include/objtool/arch.h +1 -1
@@ -85,7 +85,7 @@ unsigned long arch_dest_reloc_offset(intconst char *arch_nop_insn (int len);const char *arch_ret_insn (int len); -int arch_decode_hint_reg (struct instruction *insn,u8 sp_reg); +int arch_decode_hint_reg (u8 sp_reg,int *base);bool arch_is_retpoline (struct symbol *sym);
tools/objtool/include/objtool/cfi.h +2 -0
@@ -7,6 +7,7 @@#define _OBJTOOL_CFI_H#include <arch/cfi_regs.h> +#include <linux/list.h> #define CFI_UNDEFINED -1#define CFI_CFA -2
@@ -24,6 +25,7 @@ struct cfi_init_state { };struct cfi_state { +struct hlist_node hash;/* must be first, cficmp() */ struct cfi_reg regs[CFI_NUM_REGS ];struct cfi_reg vals[CFI_NUM_REGS ];struct cfi_reg cfa;
tools/objtool/include/objtool/check.h +1 -1
@@ -59,7 +59,7 @@ struct instruction {struct list_head alts;struct symbol *func;struct list_head stack_ops; -struct cfi_state cfi; +struct cfi_state *cfi; };static inline bool is_static_jump (struct instruction *insn)
tools/objtool/orc_gen.c +11 -4
@@ -13,13 +13,19 @@#include <objtool/warn.h> #include <objtool/endianness.h> -static int init_orc_entry (struct orc_entry *orc,struct cfi_state *cfi) +static int init_orc_entry (struct orc_entry *orc,struct cfi_state *cfi, +struct instruction *insn) { - struct instruction *insn = container_of(cfi, struct instruction, cfi);struct cfi_reg *bp = &cfi->regs[CFI_BP ];memset (orc,0 ,sizeof (*orc)); +if (!cfi) { + orc->end =0 ; + orc->sp_reg =ORC_REG_UNDEFINED ; +return 0 ; + } + orc->end = cfi->end;if (cfi->cfa.base ==CFI_UNDEFINED ) {
@@ -162,7 +168,7 @@ int orc_create(struct objtool_file *fileint i;if (!alt_group) { -if (init_orc_entry (&orc, &insn->cfi)) +if (init_orc_entry (&orc, insn->cfi, insn))return -1 ;if (!memcmp (&prev_orc, &orc,sizeof (orc)))continue ;
@@ -186,7 +192,8 @@ int orc_create(struct objtool_file *filestruct cfi_state *cfi = alt_group->cfi[i];if (!cfi)continue ; -if (init_orc_entry (&orc, cfi)) +/* errors are reported on the original insn */ +if (init_orc_entry (&orc, cfi, insn))return -1 ;if (!memcmp (&prev_orc, &orc,sizeof (orc)))continue ;
Greg Kroah-Hartman
maintainerPATCH 10/78 x86/retpoline: Remove unused replacement symbols
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 4fe79e710d9574a14993f8b4e16b7252da72d5e8 upstream.
Now that objtool no longer creates alternatives, these replacement symbols are no longer needed, remove them.
--- arch/x86/include/asm/asm-prototypes.h | 10 -------- arch/x86/lib/retpoline.S | 42 ---------------------------------- 2 files changed, 52 deletions(-)
arch/x86/include/asm/asm-prototypes.h +0 -10
@@ -24,14 +24,4 @@ extern void cmpxchg8b_emu(void); extern asmlinkage void __x86_indirect_thunk_ ## reg (void);#include <asm/GEN-for-each-reg.h> -#undef GEN -#define GEN (reg) \ - extern asmlinkage void __x86_indirect_alt_call_ ## reg (void); -#include <asm/GEN-for-each-reg.h> - -#undef GEN -#define GEN (reg) \ - extern asmlinkage void __x86_indirect_alt_jmp_ ## reg (void); -#include <asm/GEN-for-each-reg.h> -#endif /* CONFIG_RETPOLINE */
arch/x86/lib/retpoline.S +0 -42
51 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 11/78 x86/asm: Fix register order
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit a92ede2d584a2e070def59c7e47e6b6f6341c55c upstream.
Ensure the register order is correct; this allows for easy translation between register number and trampoline and vice-versa.
--- arch/x86/include/asm/GEN-for-each-reg.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
arch/x86/include/asm/GEN-for-each-reg.h +10 -4
@@ -1,11 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* +* These are in machine order; things rely on that. +*/ #ifdef CONFIG_64BIT GEN(rax) -GEN(rbx) GEN(rcx) GEN(rdx) +GEN(rbx) +GEN(rsp) +GEN(rbp) GEN(rsi) GEN(rdi) -GEN(rbp) GEN(r8) GEN(r9) GEN(r10)
@@ -16,10 +21,11 @@ GEN(r14) GEN(r15) #else GEN(eax) -GEN(ebx) GEN(ecx) GEN(edx) +GEN(ebx) +GEN(esp) +GEN(ebp) GEN(esi) GEN(edi) -GEN(ebp)#endif
Greg Kroah-Hartman
maintainerPATCH 12/78 x86/asm: Fixup odd GEN-for-each-reg.h usage
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit b6d3d9944bd7c9e8c06994ead3c9952f673f2a66 upstream.
Currently GEN-for-each-reg.h usage leaves GEN defined, relying on any subsequent usage to start with #undef, which is rude.
--- arch/x86/include/asm/asm-prototypes.h | 2 +- arch/x86/lib/retpoline.S | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
arch/x86/include/asm/asm-prototypes.h +1 -1
@@ -19,9 +19,9 @@ extern void cmpxchg8b_emu(void);#ifdef CONFIG_RETPOLINE -#undef GEN#define GEN (reg) \ extern asmlinkage void __x86_indirect_thunk_ ## reg (void);#include <asm/GEN-for-each-reg.h> +#undef GEN#endif /* CONFIG_RETPOLINE */
arch/x86/lib/retpoline.S +2 -2
@@ -55,10 +55,10 @@ SYM_FUNC_END(__x86_indirect_thunk_\reg) #define __EXPORT_THUNK(sym) _ASM_NOKPROBE(sym); EXPORT_SYMBOL(sym) #define EXPORT_THUNK(reg) __EXPORT_THUNK(__x86_indirect_thunk_ ## reg) -#undef GEN #define GEN(reg) THUNK reg #include <asm/GEN-for-each-reg.h> - #undef GEN + #define GEN(reg) EXPORT_THUNK(reg) #include <asm/GEN-for-each-reg.h> +#undef GEN
Greg Kroah-Hartman
maintainerPATCH 13/78 x86/retpoline: Move the retpoline thunk declarations to nospec-branch.h
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 6fda8a38865607db739be3e567a2387376222dbd upstream.
Because it makes no sense to split the retpoline gunk over multiple headers.
--- arch/x86/include/asm/asm-prototypes.h | 8 -------- arch/x86/include/asm/nospec-branch.h | 7 +++++++ arch/x86/net/bpf_jit_comp.c | 1 - 3 files changed, 7 insertions(+), 9 deletions(-)
arch/x86/include/asm/asm-prototypes.h +0 -8
@@ -17,11 +17,3 @@extern void cmpxchg8b_emu (void );#endif -#ifdef CONFIG_RETPOLINE - -#define GEN (reg) \ - extern asmlinkage void __x86_indirect_thunk_ ## reg (void); -#include <asm/GEN-for-each-reg.h> -#undef GEN - -#endif /* CONFIG_RETPOLINE */
arch/x86/include/asm/nospec-branch.h +7 -0
@@ -5,6 +5,7 @@#include <linux/static_key.h> #include <linux/objtool.h> +#include <linux/linkage.h> #include <asm/alternative.h> #include <asm/cpufeatures.h>
@@ -118,6 +119,12 @@ ".popsection\n\t"#ifdef CONFIG_RETPOLINE + +#define GEN (reg) \ + extern asmlinkage void __x86_indirect_thunk_ ## reg (void); +#include <asm/GEN-for-each-reg.h> +#undef GEN +#ifdef CONFIG_X86_64 /*
arch/x86/net/bpf_jit_comp.c +0 -1
@@ -15,7 +15,6 @@#include <asm/set_memory.h> #include <asm/nospec-branch.h> #include <asm/text-patching.h> -#include <asm/asm-prototypes.h> static u8 *emit_code (u8 *ptr,u32 bytes,unsigned int len) {
Greg Kroah-Hartman
maintainerPATCH 14/78 x86/retpoline: Create a retpoline thunk array
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 1a6f74429c42a3854980359a758e222005712aee upstream.
Stick all the retpolines in a single symbol and have the individual thunks as inner labels, this should guarantee thunk order and layout.
Previously there were 16 (or rather 15 without rsp) separate symbols and a toolchain might reasonably expect it could displace them however it liked, with disregard for their relative position.
However, now they're part of a larger symbol. Any change to their relative position would disrupt this larger _array symbol and thus not be sound.
This is the same reasoning used for data symbols. On their own there is no guarantee about their relative position wrt to one aonther, but we're still able to do arrays because an array as a whole is a single larger symbol.
--- arch/x86/include/asm/nospec-branch.h | 8 +++++++- arch/x86/lib/retpoline.S | 14 +++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-)
arch/x86/include/asm/nospec-branch.h +7 -1
@@ -12,6 +12,8 @@#include <asm/msr-index.h> #include <asm/unwind_hints.h> +#define RETPOLINE_THUNK_SIZE 32 +/* * Fill the CPU return stack buffer. *
@@ -120,11 +122,15 @@#ifdef CONFIG_RETPOLINE +typedef u8 retpoline_thunk_t [RETPOLINE_THUNK_SIZE ]; +#define GEN (reg) \ - extern asmlinkage void __x86_indirect_thunk_ ## reg (void); + extern retpoline_thunk_t __x86_indirect_thunk_ ## reg;#include <asm/GEN-for-each-reg.h> #undef GEN +extern retpoline_thunk_t __x86_indirect_thunk_array[]; +#ifdef CONFIG_X86_64 /*
arch/x86/lib/retpoline.S +9 -5
@@ -28,16 +28,14 @@ .macro THUNK reg - .align 32 - -SYM_FUNC_START(__x86_indirect_thunk_\reg) + .align RETPOLINE_THUNK_SIZE +SYM_INNER_LABEL(__x86_indirect_thunk_\reg, SYM_L_GLOBAL) + UNWIND_HINT_EMPTY ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \ __stringify(RETPOLINE \reg), X86_FEATURE_RETPOLINE, \ __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg; int3), X86_FEATURE_RETPOLINE_LFENCE -SYM_FUNC_END(__x86_indirect_thunk_\reg) - .endm /*
@@ -55,10 +53,16 @@ SYM_FUNC_END(__x86_indirect_thunk_\reg) #define __EXPORT_THUNK(sym) _ASM_NOKPROBE(sym); EXPORT_SYMBOL(sym) #define EXPORT_THUNK(reg) __EXPORT_THUNK(__x86_indirect_thunk_ ## reg) + .align RETPOLINE_THUNK_SIZE +SYM_CODE_START(__x86_indirect_thunk_array) + #define GEN(reg) THUNK reg #include <asm/GEN-for-each-reg.h> #undef GEN + .align RETPOLINE_THUNK_SIZE +SYM_CODE_END(__x86_indirect_thunk_array) + #define GEN(reg) EXPORT_THUNK(reg) #include <asm/GEN-for-each-reg.h> #undef GEN
Greg Kroah-Hartman
maintainerPATCH 15/78 x86/alternative: Implement .retpoline_sites support
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 7508500900814d14e2e085cdc4e28142721abbdf upstream.
Rewrite retpoline thunk call sites to be indirect calls for spectre_v2=off. This ensures spectre_v2=off is as near to a RETPOLINE=n build as possible.
This is the replacement for objtool writing alternative entries to ensure the same and achieves feature-parity with the previous approach.
One noteworthy feature is that it relies on the thunks to be in machine order to compute the register index.
Specifically, this does not yet address the Jcc __x86_indirect_thunk_* calls generated by clang, a future patch will add this.
--- arch/um/kernel/um_arch.c | 4 + arch/x86/include/asm/alternative.h | 1 arch/x86/kernel/alternative.c | 141 +++++++++++++++++++++++++++++++++++-- arch/x86/kernel/module.c | 9 ++ 4 files changed, 150 insertions(+), 5 deletions(-)
arch/um/kernel/um_arch.c +4 -0
@@ -421,6 +421,10 @@ void __init check_bugs(void)os_check_bugs (); } +void apply_retpolines (s32 *start,s32 *end) +{ +} +void apply_alternatives (struct alt_instr *start,struct alt_instr *end) { }
arch/x86/include/asm/alternative.h +1 -0
@@ -75,6 +75,7 @@ extern int alternatives_patched;extern void alternative_instructions (void );extern void apply_alternatives (struct alt_instr *start,struct alt_instr *end); +extern void apply_retpolines (s32 *start,s32 *end);struct module ;
arch/x86/kernel/alternative.c +137 -4
183 lines not on this page · raw message
arch/x86/kernel/module.c +8 -1
@@ -252,7 +252,8 @@ int module_finalize(const Elf_Ehdr *hdr, struct module *me) {const Elf_Shdr *s, *text =NULL , *alt =NULL , *locks =NULL , - *para =NULL , *orc =NULL , *orc_ip =NULL ; + *para =NULL , *orc =NULL , *orc_ip =NULL , + *retpolines =NULL ;char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
@@ -268,6 +269,8 @@ int module_finalize(const Elf_Ehdr *hdr, orc = s;if (!strcmp (".orc_unwind_ip" , secstrings + s->sh_name)) orc_ip = s; +if (!strcmp (".retpoline_sites" , secstrings + s->sh_name)) + retpolines = s; }/*
@@ -278,6 +281,10 @@ int module_finalize(const Elf_Ehdr *hdr,void *pseg = (void *)para->sh_addr;apply_paravirt (pseg, pseg + para->sh_size); } +if (retpolines) { +void *rseg = (void *)retpolines->sh_addr; +apply_retpolines (rseg, rseg + retpolines->sh_size); + }if (alt) {/* patch .altinstructions */ void *aseg = (void *)alt->sh_addr;
Greg Kroah-Hartman
maintainerPATCH 16/78 x86/alternative: Handle Jcc __x86_indirect_thunk_\reg
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 2f0cbb2a8e5bbf101e9de118fc0eb168111a5e1e upstream.
Handle the rare cases where the compiler (clang) does an indirect conditional tail-call using:
Jcc __x86_indirect_thunk_\reg
For the !RETPOLINE case this can be rewritten to fit the original (6 byte) instruction like:
Jncc.d8 1f
JMP *%\reg
NOP
1:
--- arch/x86/kernel/alternative.c | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-)
arch/x86/kernel/alternative.c +36 -4
@@ -393,7 +393,8 @@ static int emit_indirect(int op, int regstatic int patch_retpoline (void *addr,struct insn *insn,u8 *bytes) {retpoline_thunk_t *target; -int reg, i =0 ; +int reg, ret, i =0 ; +u8 op, cc; target = addr + insn->length + insn->immediate.value; reg = target - __x86_indirect_thunk_array;
@@ -407,9 +408,36 @@ static int patch_retpoline(void *addr, sif (cpu_feature_enabled (X86_FEATURE_RETPOLINE ))return -1 ; - i =emit_indirect (insn->opcode.bytes[0 ], reg, bytes); -if (i <0 ) -return i; + op = insn->opcode.bytes[0 ]; + +/* +* Convert: +* +* Jcc.d32 __x86_indirect_thunk_\reg +* +* into: +* +* Jncc.d8 1f +* JMP *%\reg +* NOP +* 1: +*/ +/* Jcc.d32 second opcode byte is in the range: 0x80-0x8f */ +if (op ==0x0f && (insn->opcode.bytes[1 ] &0xf0 ) ==0x80 ) { + cc = insn->opcode.bytes[1 ] &0xf ; + cc ^=1 ;/* invert condition */ + + bytes[i++] =0x70 + cc;/* Jcc.d8 */ + bytes[i++] = insn->length -2 ;/* sizeof(Jcc.d8) == 2 */ + +/* Continue as if: JMP.d32 __x86_indirect_thunk_\reg */ + op =JMP32_INSN_OPCODE ; + } + + ret =emit_indirect (op, reg, bytes + i); +if (ret <0 ) +return ret; + i += ret;for (; i < insn->length;) bytes[i++] =BYTES_NOP1 ;
@@ -443,6 +471,10 @@ void __init_or_module noinline apply_retcase JMP32_INSN_OPCODE :break ; +case 0x0f :/* escape */ +if (op2 >=0x80 && op2 <=0x8f ) +break ; + fallthrough;default :WARN_ON_ONCE (1 );continue ;
Greg Kroah-Hartman
maintainerPATCH 17/78 x86/alternative: Try inline spectre_v2=retpoline,amd
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit bbe2df3f6b6da7848398d55b1311d58a16ec21e4 upstream.
Try and replace retpoline thunk calls with:
LFENCE
CALL *%\reg
for spectre_v2=retpoline,amd.
Specifically, the sequence above is 5 bytes for the low 8 registers, but 6 bytes for the high 8 registers. This means that unless the compilers prefix stuff the call with higher registers this replacement will fail.
Luckily GCC strongly favours RAX for the indirect calls and most (95%+ for defconfig-x86_64) will be converted. OTOH clang strongly favours R11 and almost nothing gets converted.
Note: it will also generate a correct replacement for the Jcc.d32 case, except unless the compilers start to prefix stuff that, it'll never fit. Specifically:
Jncc.d8 1f
LFENCE
JMP *%\reg
1:
is 7-8 bytes long, where the original instruction in unpadded form is only 6 bytes.
--- arch/x86/kernel/alternative.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
arch/x86/kernel/alternative.c +14 -2
@@ -389,6 +389,7 @@ static int emit_indirect(int op, int reg* * CALL *%\reg * +* It also tries to inline spectre_v2=retpoline,amd when size permits. */ static int patch_retpoline (void *addr,struct insn *insn,u8 *bytes) {
@@ -405,7 +406,8 @@ static int patch_retpoline(void *addr, s/* If anyone ever does: CALL/JMP *%rsp, we're in deep trouble. */ BUG_ON (reg ==4 ); -if (cpu_feature_enabled (X86_FEATURE_RETPOLINE )) +if (cpu_feature_enabled (X86_FEATURE_RETPOLINE ) && + !cpu_feature_enabled (X86_FEATURE_RETPOLINE_LFENCE ))return -1 ; op = insn->opcode.bytes[0 ];
@@ -418,8 +420,9 @@ static int patch_retpoline(void *addr, s* into: * * Jncc.d8 1f +* [ LFENCE ] * JMP *%\reg -* NOP +* [ NOP ] * 1: */ /* Jcc.d32 second opcode byte is in the range: 0x80-0x8f */
@@ -434,6 +437,15 @@ static int patch_retpoline(void *addr, s op =JMP32_INSN_OPCODE ; } +/* +* For RETPOLINE_AMD: prepend the indirect CALL/JMP with an LFENCE. +*/ +if (cpu_feature_enabled (X86_FEATURE_RETPOLINE_LFENCE )) { + bytes[i++] =0x0f ; + bytes[i++] =0xae ; + bytes[i++] =0xe8 ;/* LFENCE */ + } + ret =emit_indirect (op, reg, bytes + i);if (ret <0 )return ret;
Greg Kroah-Hartman
maintainerPATCH 18/78 x86/alternative: Add debug prints to apply_retpolines()
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit d4b5a5c993009ffeb5febe3b701da3faab6adb96 upstream.
Make sure we can see the text changes when booting with 'debug-alternative'.
Example output:
[ ] SMP alternatives: retpoline at: __traceiter_initcall_level+0x1f/0x30 (ffffffff8100066f) len: 5 to: __x86_indirect_thunk_rax+0x0/0x20 [ ] SMP alternatives: ffffffff82603e58: [2:5) optimized NOPs: ff d0 0f 1f 00
[ ] SMP alternatives: ffffffff8100066f: orig: e8 cc 30 00 01
[ ] SMP alternatives: ffffffff8100066f: repl: ff d0 0f 1f 00
--- arch/x86/kernel/alternative.c | 6 ++++++ 1 file changed, 6 insertions(+)
arch/x86/kernel/alternative.c +6 -0
@@ -492,9 +492,15 @@ void __init_or_module noinline apply_retcontinue ; } +DPRINTK ("retpoline at: %pS (%px) len: %d to: %pS" , + addr, addr, insn.length, + addr + insn.length + insn.immediate.value); + len =patch_retpoline (addr, &insn, bytes);if (len == insn.length) {optimize_nops (bytes, len); +DUMP_BYTES (((u8 *)addr), len,"%px: orig: " , addr); +DUMP_BYTES (((u8 *)bytes), len,"%px: repl: " , addr);text_poke_early (addr, bytes, len); } }
Greg Kroah-Hartman
maintainerPATCH 19/78 bpf,x86: Simplify computing label offsets
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit dceba0817ca329868a15e2e1dd46eb6340b69206 upstream.
Take an idea from the 32bit JIT, which uses the multi-pass nature of the JIT to compute the instruction offsets on a prior pass in order to compute the relative jump offsets on a later pass.
Application to the x86_64 JIT is slightly more involved because the offsets depend on program variables (such as callee_regs_used and stack_depth) and hence the computed offsets need to be kept in the context of the JIT.
This removes, IMO quite fragile, code that hard-codes the offsets and tries to compute the length of variable parts of it.
Convert both emit_bpf_tail_call_*() functions which have an out: label at the end. Additionally emit_bpt_tail_call_direct() also has a poke table entry, for which it computes the offset from the end (and thus already relies on the previous pass to have computed addrs[i]), also convert this to be a forward based offset.
--- arch/x86/net/bpf_jit_comp.c | 123 +++++++++++++++----------------------------- 1 file changed, 42 insertions(+), 81 deletions(-)
arch/x86/net/bpf_jit_comp.c +42 -81
@@ -224,6 +224,14 @@ static void jit_fill_hole(void *area, unstruct jit_context {int cleanup_addr;/* Epilogue code offset */ + +/* +* Program specific offsets of labels in the code; these rely on the +* JIT doing at least 2 passes, recording the position on the first +* pass, only to generate the correct offset on the second pass. +*/ +int tail_call_direct_label; +int tail_call_indirect_label; };/* Maximum number of bytes emitted while JITing one eBPF insn */
@@ -379,22 +387,6 @@ int bpf_arch_text_poke(void *ip, enum bpreturn __bpf_arch_text_poke (ip, t, old_addr, new_addr, true); } -static int get_pop_bytes (bool *callee_regs_used) -{ -int bytes =0 ; - -if (callee_regs_used[3 ]) - bytes +=2 ; -if (callee_regs_used[2 ]) - bytes +=2 ; -if (callee_regs_used[1 ]) - bytes +=2 ; -if (callee_regs_used[0 ]) - bytes +=1 ; - -return bytes; -} -/* * Generate the following code: *
@@ -410,29 +402,12 @@ static int get_pop_bytes(bool *callee_re* out: */ static void emit_bpf_tail_call_indirect (u8 **pprog,bool *callee_regs_used, -u32 stack_depth) +u32 stack_depth,u8 *ip, +struct jit_context *ctx) {int tcc_off =-4 -round_up (stack_depth,8 ); -u8 *prog = *pprog; -int pop_bytes =0 ; -int off1 =42 ; -int off2 =31 ; -int off3 =9 ; - -/* count the additional bytes used for popping callee regs from stack -* that need to be taken into account for each of the offsets that -* are used for bailing out of the tail call -*/ - pop_bytes =get_pop_bytes (callee_regs_used); - off1 += pop_bytes; - off2 += pop_bytes; - off3 += pop_bytes; - -if (stack_depth) { - off1 +=7 ; - off2 +=7 ; - off3 +=7 ; - } +u8 *prog = *pprog, *start = *pprog; +int offset;/* * rdi - pointer to ctx
@@ -447,8 +422,9 @@ static void emit_bpf_tail_call_indirect(EMIT2 (0x89 ,0xD2 );/* mov edx, edx */ EMIT3 (0x39 ,0x56 ,/* cmp dword ptr [rsi + 16], edx */ offsetof(struct bpf_array, map.max_entries)); -#define OFFSET1 (off1 + RETPOLINE_RCX_BPF_JIT_SIZE)/* Number of bytes to jump */ -EMIT2 (X86_JBE ,OFFSET1 );/* jbe out */ + + offset = ctx->tail_call_indirect_label - (prog +2 - start); +EMIT2 (X86_JBE , offset);/* jbe out */ /* * if (tail_call_cnt > MAX_TAIL_CALL_CNT)
@@ -456,8 +432,9 @@ static void emit_bpf_tail_call_indirect(*/ EMIT2_off32 (0x8B ,0x85 , tcc_off);/* mov eax, dword ptr [rbp - tcc_off] */ EMIT3 (0x83 ,0xF8 ,MAX_TAIL_CALL_CNT );/* cmp eax, MAX_TAIL_CALL_CNT */ -#define OFFSET2 (off2 + RETPOLINE_RCX_BPF_JIT_SIZE) -EMIT2 (X86_JA ,OFFSET2 );/* ja out */ + + offset = ctx->tail_call_indirect_label - (prog +2 - start); +EMIT2 (X86_JA , offset);/* ja out */ EMIT3 (0x83 ,0xC0 ,0x01 );/* add eax, 1 */ EMIT2_off32 (0x89 ,0x85 , tcc_off);/* mov dword ptr [rbp - tcc_off], eax */
@@ -470,12 +447,11 @@ static void emit_bpf_tail_call_indirect(* goto out; */ EMIT3 (0x48 ,0x85 ,0xC9 );/* test rcx,rcx */ -#define OFFSET3 (off3 + RETPOLINE_RCX_BPF_JIT_SIZE) -EMIT2 (X86_JE ,OFFSET3 );/* je out */ - *pprog = prog; -pop_callee_regs (pprog, callee_regs_used); - prog = *pprog; + offset = ctx->tail_call_indirect_label - (prog +2 - start); +EMIT2 (X86_JE , offset);/* je out */ + +pop_callee_regs (&prog, callee_regs_used);EMIT1 (0x58 );/* pop rax */ if (stack_depth)
@@ -495,38 +471,18 @@ static void emit_bpf_tail_call_indirect(RETPOLINE_RCX_BPF_JIT ();/* out: */ + ctx->tail_call_indirect_label = prog - start; *pprog = prog; }static void emit_bpf_tail_call_direct (struct bpf_jit_poke_descriptor *poke, -u8 **pprog,int addr,u8 *image, -bool *callee_regs_used,u32 stack_depth) +u8 **pprog,u8 *ip, +bool *callee_regs_used,u32 stack_depth, +struct jit_context *ctx) {int tcc_off =-4 -round_up (stack_depth,8 ); -u8 *prog = *pprog; -int pop_bytes =0 ; -int off1 =20 ; -int poke_off; - -/* count the additional bytes used for popping callee regs to stack -* that need to be taken into account for jump offset that is used for -* bailing out from of the tail call when limit is reached -*/ - pop_bytes =get_pop_bytes (callee_regs_used); - off1 += pop_bytes; - -/* -* total bytes for: -* - nop5/ jmpq $off -* - pop callee regs -* - sub rsp, $val if depth > 0 -* - pop rax -*/ - poke_off =X86_PATCH_SIZE + pop_bytes +1 ; -if (stack_depth) { - poke_off +=7 ; - off1 +=7 ; - } +u8 *prog = *pprog, *start = *pprog; +int offset;/* * if (tail_call_cnt > MAX_TAIL_CALL_CNT)
@@ -534,28 +490,30 @@ static void emit_bpf_tail_call_direct(st*/ EMIT2_off32 (0x8B ,0x85 , tcc_off);/* mov eax, dword ptr [rbp - tcc_off] */ EMIT3 (0x83 ,0xF8 ,MAX_TAIL_CALL_CNT );/* cmp eax, MAX_TAIL_CALL_CNT */ -EMIT2 (X86_JA , off1);/* ja out */ + + offset = ctx->tail_call_direct_label - (prog +2 - start); +EMIT2 (X86_JA , offset);/* ja out */ EMIT3 (0x83 ,0xC0 ,0x01 );/* add eax, 1 */ EMIT2_off32 (0x89 ,0x85 , tcc_off);/* mov dword ptr [rbp - tcc_off], eax */ - poke->tailcall_bypass = image + (addr - poke_off -X86_PATCH_SIZE ); + poke->tailcall_bypass = ip + (prog - start); poke->adj_off =X86_TAIL_CALL_OFFSET ; - poke->tailcall_target = image + (addr -X86_PATCH_SIZE ); + poke->tailcall_target = ip + ctx->tail_call_direct_label -X86_PATCH_SIZE ; poke->bypass_addr = (u8 *)poke->tailcall_target +X86_PATCH_SIZE ;emit_jump (&prog, (u8 *)poke->tailcall_target +X86_PATCH_SIZE , poke->tailcall_bypass); - *pprog = prog; -pop_callee_regs (pprog, callee_regs_used); - prog = *pprog; +pop_callee_regs (&prog, callee_regs_used);EMIT1 (0x58 );/* pop rax */ if (stack_depth)EMIT3_off32 (0x48 ,0x81 ,0xC4 ,round_up (stack_depth,8 ));memcpy (prog, x86_nops[5 ],X86_PATCH_SIZE ); prog +=X86_PATCH_SIZE ; +/* out: */ + ctx->tail_call_direct_label = prog - start; *pprog = prog; }
@@ -1453,13 +1411,16 @@ st: if (is_imm8(insn->off))case BPF_JMP |BPF_TAIL_CALL :if (imm32)emit_bpf_tail_call_direct (&bpf_prog->aux->poke_tab[imm32 -1 ], - &prog, addrs[i], image, + &prog, image + addrs[i -1 ], callee_regs_used, - bpf_prog->aux->stack_depth); + bpf_prog->aux->stack_depth, + ctx);else emit_bpf_tail_call_indirect (&prog, callee_regs_used, - bpf_prog->aux->stack_depth); + bpf_prog->aux->stack_depth, + image + addrs[i -1 ], + ctx);break ;/* cond jump */
Greg Kroah-Hartman
maintainerPATCH 20/78 bpf,x86: Respect X86_FEATURE_RETPOLINE*
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 87c87ecd00c54ecd677798cb49ef27329e0fab41 upstream.
Current BPF codegen doesn't respect X86_FEATURE_RETPOLINE* flags and unconditionally emits a thunk call, this is sub-optimal and doesn't match the regular, compiler generated, code.
Update the i386 JIT to emit code equal to what the compiler emits for the regular kernel text (IOW. a plain THUNK call).
Update the x86_64 JIT to emit code similar to the result of compiler and kernel rewrites as according to X86_FEATURE_RETPOLINE* flags. Inlining RETPOLINE_AMD (lfence; jmp *%reg) and !RETPOLINE (jmp *%reg), while doing a THUNK call for RETPOLINE.
This removes the hard-coded retpoline thunks and shrinks the generated code. Leaving a single retpoline thunk definition in the kernel.
--- arch/x86/include/asm/nospec-branch.h | 59 ----------------------------------- arch/x86/net/bpf_jit_comp.c | 46 +++++++++++++-------------- arch/x86/net/bpf_jit_comp32.c | 22 +++++++++++-- 3 files changed, 41 insertions(+), 86 deletions(-)
arch/x86/include/asm/nospec-branch.h +0 -59
@@ -320,63 +320,4 @@ static inline void mds_idle_clear_cpu_bu#endif /* __ASSEMBLY__ */ -/* -* Below is used in the eBPF JIT compiler and emits the byte sequence -* for the following assembly: -* -* With retpolines configured: -* -* callq do_rop -* spec_trap: -* pause -* lfence -* jmp spec_trap -* do_rop: -* mov %rcx,(%rsp) for x86_64 -* mov %edx,(%esp) for x86_32 -* retq -* -* Without retpolines configured: -* -* jmp *%rcx for x86_64 -* jmp *%edx for x86_32 -*/ -#ifdef CONFIG_RETPOLINE -# ifdef CONFIG_X86_64 -# define RETPOLINE_RCX_BPF_JIT_SIZE 17 -# define RETPOLINE_RCX_BPF_JIT () \ -do { \ - EMIT1_off32(0xE8, 7);/* callq do_rop */ \ -/* spec_trap: */ \ -EMIT2 (0xF3 ,0x90 );/* pause */ \ -EMIT3 (0x0F ,0xAE ,0xE8 );/* lfence */ \ -EMIT2 (0xEB ,0xF9 );/* jmp spec_trap */ \ -/* do_rop: */ \ -EMIT4 (0x48 ,0x89 ,0x0C ,0x24 );/* mov %rcx,(%rsp) */ \ -EMIT1 (0xC3 );/* retq */ \ -} while (0) -# else /* !CONFIG_X86_64 */ -# define RETPOLINE_EDX_BPF_JIT () \ -do { \ - EMIT1_off32(0xE8, 7);/* call do_rop */ \ -/* spec_trap: */ \ -EMIT2 (0xF3 ,0x90 );/* pause */ \ -EMIT3 (0x0F ,0xAE ,0xE8 );/* lfence */ \ -EMIT2 (0xEB ,0xF9 );/* jmp spec_trap */ \ -/* do_rop: */ \ -EMIT3 (0x89 ,0x14 ,0x24 );/* mov %edx,(%esp) */ \ -EMIT1 (0xC3 );/* ret */ \ -} while (0) -# endif -#else /* !CONFIG_RETPOLINE */ -# ifdef CONFIG_X86_64 -# define RETPOLINE_RCX_BPF_JIT_SIZE 2 -# define RETPOLINE_RCX_BPF_JIT () \ - EMIT2(0xFF, 0xE1);/* jmp *%rcx */ -# else /* !CONFIG_X86_64 */ -# define RETPOLINE_EDX_BPF_JIT () \ - EMIT2(0xFF, 0xE2)/* jmp *%edx */ -# endif -#endif -#endif /* _ASM_X86_NOSPEC_BRANCH_H_ */
arch/x86/net/bpf_jit_comp.c +22 -24
76 lines not on this page · raw message
arch/x86/net/bpf_jit_comp32.c +19 -3
@@ -15,6 +15,7 @@#include <asm/cacheflush.h> #include <asm/set_memory.h> #include <asm/nospec-branch.h> +#include <asm/asm-prototypes.h> #include <linux/bpf.h> /*
@@ -1267,6 +1268,21 @@ static void emit_epilogue(u8 **pprog, u3 *pprog = prog; } +static int emit_jmp_edx (u8 **pprog,u8 *ip) +{ +u8 *prog = *pprog; +int cnt =0 ; + +#ifdef CONFIG_RETPOLINE +EMIT1_off32 (0xE9 , (u8 *)__x86_indirect_thunk_edx - (ip +5 )); +#else +EMIT2 (0xFF ,0xE2 ); +#endif + *pprog = prog; + +return cnt; +} +/* * Generate the following code: * ... bpf_tail_call(void *ctx, struct bpf_array *array, u64 index) ...
@@ -1280,7 +1296,7 @@ static void emit_epilogue(u8 **pprog, u3* goto *(prog->bpf_func + prologue_size); * out: */ -static void emit_bpf_tail_call (u8 **pprog) +static void emit_bpf_tail_call (u8 **pprog,u8 *ip) {u8 *prog = *pprog;int cnt =0 ;
@@ -1362,7 +1378,7 @@ static void emit_bpf_tail_call(u8 **ppro* eax == ctx (1st arg) * edx == prog->bpf_func + prologue_size */ -RETPOLINE_EDX_BPF_JIT (); + cnt +=emit_jmp_edx (&prog, ip + cnt);if (jmp_label1 ==-1 ) jmp_label1 = cnt;
@@ -2122,7 +2138,7 @@ static int do_jit(struct bpf_prog *bpf_pbreak ; }case BPF_JMP |BPF_TAIL_CALL : -emit_bpf_tail_call (&prog); +emit_bpf_tail_call (&prog, image + addrs[i -1 ]);break ;/* cond jump */
Greg Kroah-Hartman
maintainerPATCH 21/78 objtool: Default ignore INT3 for unreachable
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 1ffbe4e935f9b7308615c75be990aec07464d1e7 upstream.
Ignore all INT3 instructions for unreachable code warnings, similar to NOP. This allows using INT3 for various paddings instead of NOPs.
--- tools/objtool/check.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
tools/objtool/check.c +5 -7
@@ -2965,9 +2965,8 @@ static int validate_branch(struct objtooswitch (insn->type) {case INSN_RETURN : -if (next_insn && next_insn->type ==INSN_TRAP ) { - next_insn->ignore = true; - }else if (sls && !insn->retpoline_safe) { +if (sls && !insn->retpoline_safe && + next_insn && next_insn->type !=INSN_TRAP ) {WARN_FUNC ("missing int3 after ret" , insn->sec, insn->offset); }
@@ -3014,9 +3013,8 @@ static int validate_branch(struct objtoobreak ;case INSN_JUMP_DYNAMIC : -if (next_insn && next_insn->type ==INSN_TRAP ) { - next_insn->ignore = true; - }else if (sls && !insn->retpoline_safe) { +if (sls && !insn->retpoline_safe && + next_insn && next_insn->type !=INSN_TRAP ) {WARN_FUNC ("missing int3 after indirect jump" , insn->sec, insn->offset); }
@@ -3187,7 +3185,7 @@ static bool ignore_unreachable_insn(struint i;struct instruction *prev_insn; -if (insn->ignore || insn->type ==INSN_NOP ) +if (insn->ignore || insn->type ==INSN_NOP || insn->type ==INSN_TRAP )return true;/*
Greg Kroah-Hartman
maintainerPATCH 22/78 x86/entry: Remove skip_r11rcx
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 1b331eeea7b8676fc5dbdf80d0a07e41be226177 upstream.
Yes, r11 and rcx have been restored previously, but since they're being popped anyway (into rsi) might as well pop them into their own regs -- setting them to the value they already are.
Less magical code.
--- arch/x86/entry/calling.h | 10 +--------- arch/x86/entry/entry_64.S | 3 +-- 2 files changed, 2 insertions(+), 11 deletions(-)
arch/x86/entry/calling.h +1 -9
@@ -119,27 +119,19 @@ For 32-bit we have the following conventCLEAR_REGS .endm -.macro POP_REGS pop_rdi=1 skip_r11rcx=0 +.macro POP_REGS pop_rdi=1 popq %r15 popq %r14 popq %r13 popq %r12 popq %rbp popq %rbx - .if \skip_r11rcx - popq %rsi - .else popq %r11 - .endif popq %r10 popq %r9 popq %r8 popq %rax - .if \skip_r11rcx - popq %rsi - .else popq %rcx - .endif popq %rdx popq %rsi .if \pop_rdi
arch/x86/entry/entry_64.S +1 -2
@@ -189,8 +189,7 @@ SYM_INNER_LABEL(entry_SYSCALL_64_after_h * perf profiles. Nothing jumps here. */ syscall_return_via_sysret: - /* rcx and r11 are already restored (see code above) */ - POP_REGS pop_rdi=0 skip_r11rcx=1 + POP_REGS pop_rdi=0 /* * Now all regs are restored except RSP and RDI.
Greg Kroah-Hartman
maintainerPATCH 23/78 x86/realmode: build with -D__DISABLE_EXPORTS
In reply to Greg Kroah-HartmanFrom: Thadeu Lima de Souza Cascardo <[email protected]>
Commit 156ff4a544ae ("x86/ibt: Base IBT bits") added this option when building realmode in order to disable IBT there. This is also needed in order to disable return thunks.
--- arch/x86/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/Makefile +1 -1
@@ -24,7 +24,7 @@ endif # How to compile the 16-bit code. Note we always compile for -march=i386; # that way we can complain to the user if the CPU is insufficient. -REALMODE_CFLAGS := -m16 -g -Os -DDISABLE_BRANCH_PROFILING \ +REALMODE_CFLAGS := -m16 -g -Os -DDISABLE_BRANCH_PROFILING -D__DISABLE_EXPORTS \ -Wall -Wstrict-prototypes -march=i386 -mregparm=3 \ -fno-strict-aliasing -fomit-frame-pointer -fno-pic \ -mno-mmx -mno-sse $(call cc-option,-fcf-protection=none)
Greg Kroah-Hartman
maintainerPATCH 24/78 x86/kvm/vmx: Make noinstr clean
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 742ab6df974ae8384a2dd213db1a3a06cf6d8936 upstream.
The recent mmio_stale_data fixes broke the noinstr constraints:
vmlinux.o: warning: objtool: vmx_vcpu_enter_exit+0x15b: call to wrmsrl.constprop.0() leaves .noinstr.text section vmlinux.o: warning: objtool: vmx_vcpu_enter_exit+0x1bf: call to kvm_arch_has_assigned_device() leaves .noinstr.text section
make it all happy again.
--- arch/x86/kvm/vmx/vmx.c | 6 +++--- arch/x86/kvm/x86.c | 4 ++-- include/linux/kvm_host.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-)
arch/x86/kvm/vmx/vmx.c +3 -3
@@ -380,9 +380,9 @@ static __always_inline void vmx_disable_if (!vmx->disable_fb_clear)return ; -rdmsrl (MSR_IA32_MCU_OPT_CTRL , msr); + msr =__rdmsr (MSR_IA32_MCU_OPT_CTRL ); msr |=FB_CLEAR_DIS ; -wrmsrl (MSR_IA32_MCU_OPT_CTRL , msr); +native_wrmsrl (MSR_IA32_MCU_OPT_CTRL , msr);/* Cache the MSR value to avoid reading it later */ vmx->msr_ia32_mcu_opt_ctrl = msr; }
@@ -393,7 +393,7 @@ static __always_inline void vmx_enable_freturn ; vmx->msr_ia32_mcu_opt_ctrl &= ~FB_CLEAR_DIS ; -wrmsrl (MSR_IA32_MCU_OPT_CTRL , vmx->msr_ia32_mcu_opt_ctrl); +native_wrmsrl (MSR_IA32_MCU_OPT_CTRL , vmx->msr_ia32_mcu_opt_ctrl); }static void vmx_update_fb_clear_dis (struct kvm_vcpu *vcpu,struct vcpu_vmx *vmx)
arch/x86/kvm/x86.c +2 -2
@@ -12177,9 +12177,9 @@ void kvm_arch_end_assignment(struct kvm }EXPORT_SYMBOL_GPL (kvm_arch_end_assignment); -bool kvm_arch_has_assigned_device (struct kvm *kvm) +bool noinstr kvm_arch_has_assigned_device(struct kvm *kvm) { -return atomic_read (&kvm->arch.assigned_device_count); +return arch_atomic_read (&kvm->arch.assigned_device_count); }EXPORT_SYMBOL_GPL (kvm_arch_has_assigned_device);
include/linux/kvm_host.h +1 -1
@@ -1233,7 +1233,7 @@ static inline void kvm_arch_end_assignme { } -static inline bool kvm_arch_has_assigned_device (struct kvm *kvm) +static __always_inline bool kvm_arch_has_assigned_device(struct kvm *kvm) {return false; }
Greg Kroah-Hartman
maintainerPATCH 25/78 x86/cpufeatures: Move RETPOLINE flags to word 11
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit a883d624aed463c84c22596006e5a96f5b44db31 upstream.
In order to extend the RETPOLINE features to 4, move them to word 11 where there is still room. This mostly keeps DISABLE_RETPOLINE simple.
--- arch/x86/include/asm/cpufeatures.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
arch/x86/include/asm/cpufeatures.h +6 -2
@@ -203,8 +203,8 @@#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9)/* AMD ProcFeedbackInterface */ /* FREE! ( 7*32+10) */ #define X86_FEATURE_PTI ( 7*32+11)/* Kernel Page Table Isolation enabled */ -#define X86_FEATURE_RETPOLINE ( 7*32+12)/* "" Generic Retpoline mitigation for Spectre variant 2 */ -#define X86_FEATURE_RETPOLINE_LFENCE ( 7*32+13)/* "" Use LFENCE for Spectre variant 2 */ +/* FREE! ( 7*32+12) */ +/* FREE! ( 7*32+13) */ #define X86_FEATURE_INTEL_PPIN ( 7*32+14)/* Intel Processor Inventory Number */ #define X86_FEATURE_CDP_L2 ( 7*32+15)/* Code and Data Prioritization L2 */ #define X86_FEATURE_MSR_SPEC_CTRL ( 7*32+16)/* "" MSR SPEC_CTRL is implemented */
@@ -294,6 +294,10 @@#define X86_FEATURE_PER_THREAD_MBA (11*32+ 7)/* "" Per-thread Memory Bandwidth Allocation */ #define X86_FEATURE_SGX1 (11*32+ 8)/* "" Basic SGX */ #define X86_FEATURE_SGX2 (11*32+ 9)/* "" SGX Enclave Dynamic Memory Management (EDMM) */ +/* FREE! (11*32+10) */ +/* FREE! (11*32+11) */ +#define X86_FEATURE_RETPOLINE (11*32+12)/* "" Generic Retpoline mitigation for Spectre variant 2 */ +#define X86_FEATURE_RETPOLINE_LFENCE (11*32+13)/* "" Use LFENCE for Spectre variant 2 */ /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ #define X86_FEATURE_AVX_VNNI (12*32+ 4)/* AVX VNNI instructions */
Greg Kroah-Hartman
maintainerPATCH 26/78 x86/retpoline: Cleanup some #ifdefery
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 369ae6ffc41a3c1137cab697635a84d0cc7cdcea upstream.
On it's own not much of a cleanup but it prepares for more/similar code.
--- arch/x86/include/asm/disabled-features.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
arch/x86/include/asm/disabled-features.h +8 -1
@@ -56,6 +56,13 @@# define DISABLE_PTI (1 << (X86_FEATURE_PTI & 31))#endif +#ifdef CONFIG_RETPOLINE +# define DISABLE_RETPOLINE 0 +#else +# define DISABLE_RETPOLINE ((1 << (X86_FEATURE_RETPOLINE & 31)) | \ + (1 << (X86_FEATURE_RETPOLINE_LFENCE & 31))) +#endif +/* Force disable because it's broken beyond repair */ #define DISABLE_ENQCMD (1 << (X86_FEATURE_ENQCMD & 31))
@@ -79,7 +86,7 @@#define DISABLED_MASK8 0#define DISABLED_MASK9 (DISABLE_SMAP|DISABLE_SGX)#define DISABLED_MASK10 0 -#define DISABLED_MASK11 0 +#define DISABLED_MASK11 (DISABLE_RETPOLINE)#define DISABLED_MASK12 0#define DISABLED_MASK13 0#define DISABLED_MASK14 0
Greg Kroah-Hartman
maintainerPATCH 27/78 x86/retpoline: Swizzle retpoline thunk
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 00e1533325fd1fb5459229fe37f235462649f668 upstream.
Put the actual retpoline thunk as the original code so that it can become more complicated. Specifically, it allows RET to be a JMP, which can't be .altinstr_replacement since that doesn't do relocations (except for the very first instruction).
--- arch/x86/lib/retpoline.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/lib/retpoline.S +3 -3
@@ -32,9 +32,9 @@ SYM_INNER_LABEL(__x86_indirect_thunk_\reg, SYM_L_GLOBAL) UNWIND_HINT_EMPTY - ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \ - __stringify(RETPOLINE \reg), X86_FEATURE_RETPOLINE, \ - __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg; int3), X86_FEATURE_RETPOLINE_LFENCE + ALTERNATIVE_2 __stringify(RETPOLINE \reg), \ + __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg; int3), X86_FEATURE_RETPOLINE_LFENCE, \ + __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), ALT_NOT(X86_FEATURE_RETPOLINE) .endm
Greg Kroah-Hartman
maintainerPATCH 28/78 x86/retpoline: Use -mfunction-return
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 0b53c374b9eff2255a386f1f1cfb9a928e52a5ae upstream.
Utilize -mfunction-return=thunk-extern when available to have the compiler replace RET instructions with direct JMPs to the symbol __x86_return_thunk. This does not affect assembler (.S) sources, only C sources.
-mfunction-return=thunk-extern has been available since gcc 7.3 and clang 15.
--- Makefile | 2 ++ arch/x86/include/asm/nospec-branch.h | 2 ++ arch/x86/lib/retpoline.S | 12 ++++++++++++ 3 files changed, 16 insertions(+)
Makefile +2 -0
@@ -687,11 +687,13 @@ endif ifdef CONFIG_CC_IS_GCC RETPOLINE_CFLAGS := $(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register) +RETPOLINE_CFLAGS += $(call cc-option,-mfunction-return=thunk-extern) RETPOLINE_VDSO_CFLAGS := $(call cc-option,-mindirect-branch=thunk-inline -mindirect-branch-register) endif ifdef CONFIG_CC_IS_CLANG RETPOLINE_CFLAGS := -mretpoline-external-thunk RETPOLINE_VDSO_CFLAGS := -mretpoline +RETPOLINE_CFLAGS += $(call cc-option,-mfunction-return=thunk-extern) endif export RETPOLINE_CFLAGS export RETPOLINE_VDSO_CFLAGS
arch/x86/include/asm/nospec-branch.h +2 -0
@@ -120,6 +120,8 @@ _ASM_PTR" 999b\n\t" \".popsection\n\t" +extern void __x86_return_thunk(void); +#ifdef CONFIG_RETPOLINE typedef u8 retpoline_thunk_t [RETPOLINE_THUNK_SIZE ];
arch/x86/lib/retpoline.S +12 -0
@@ -66,3 +66,15 @@ SYM_CODE_END(__x86_indirect_thunk_array) #define GEN(reg) EXPORT_THUNK(reg) #include <asm/GEN-for-each-reg.h> #undef GEN + +/* + * This function name is magical and is used by -mfunction-return=thunk-extern + * for the compiler to generate JMPs to it. + */ +SYM_CODE_START(__x86_return_thunk) + UNWIND_HINT_EMPTY + ret + int3 +SYM_CODE_END(__x86_return_thunk) + +__EXPORT_THUNK(__x86_return_thunk)
Greg Kroah-Hartman
maintainerPATCH 29/78 x86: Undo return-thunk damage
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 15e67227c49a57837108acfe1c80570e1bd9f962 upstream.
Introduce X86_FEATURE_RETHUNK for those afflicted with needing this.
[ bp: Do only INT3 padding - simpler. ]
--- arch/x86/include/asm/alternative.h | 1 arch/x86/include/asm/cpufeatures.h | 1 arch/x86/include/asm/disabled-features.h | 3 + arch/x86/kernel/alternative.c | 60 +++++++++++++++++++++++++++++++ arch/x86/kernel/module.c | 8 +++- arch/x86/kernel/vmlinux.lds.S | 7 +++ 6 files changed, 78 insertions(+), 2 deletions(-)
arch/x86/include/asm/alternative.h +1 -0
@@ -76,6 +76,7 @@ extern int alternatives_patched;extern void alternative_instructions (void );extern void apply_alternatives (struct alt_instr *start,struct alt_instr *end);extern void apply_retpolines (s32 *start,s32 *end); +extern void apply_returns (s32 *start,s32 *end);struct module ;
arch/x86/include/asm/cpufeatures.h +1 -0
@@ -298,6 +298,7 @@/* FREE! (11*32+11) */ #define X86_FEATURE_RETPOLINE (11*32+12)/* "" Generic Retpoline mitigation for Spectre variant 2 */ #define X86_FEATURE_RETPOLINE_LFENCE (11*32+13)/* "" Use LFENCE for Spectre variant 2 */ +#define X86_FEATURE_RETHUNK (11*32+14)/* "" Use REturn THUNK */ /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ #define X86_FEATURE_AVX_VNNI (12*32+ 4)/* AVX VNNI instructions */
arch/x86/include/asm/disabled-features.h +2 -1
@@ -60,7 +60,8 @@# define DISABLE_RETPOLINE 0#else # define DISABLE_RETPOLINE ((1 << (X86_FEATURE_RETPOLINE & 31)) | \ - (1 << (X86_FEATURE_RETPOLINE_LFENCE & 31))) + (1 << (X86_FEATURE_RETPOLINE_LFENCE & 31)) | \ + (1 << (X86_FEATURE_RETHUNK & 31)))#endif /* Force disable because it's broken beyond repair */
arch/x86/kernel/alternative.c +60 -0
81 lines not on this page · raw message
arch/x86/kernel/module.c +7 -1
@@ -253,7 +253,7 @@ int module_finalize(const Elf_Ehdr *hdr, {const Elf_Shdr *s, *text =NULL , *alt =NULL , *locks =NULL , *para =NULL , *orc =NULL , *orc_ip =NULL , - *retpolines =NULL ; + *retpolines =NULL , *returns =NULL ;char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
@@ -271,6 +271,8 @@ int module_finalize(const Elf_Ehdr *hdr, orc_ip = s;if (!strcmp (".retpoline_sites" , secstrings + s->sh_name)) retpolines = s; +if (!strcmp (".return_sites" , secstrings + s->sh_name)) + returns = s; }/*
@@ -285,6 +287,10 @@ int module_finalize(const Elf_Ehdr *hdr,void *rseg = (void *)retpolines->sh_addr;apply_retpolines (rseg, rseg + retpolines->sh_size); } +if (returns) { +void *rseg = (void *)returns->sh_addr; +apply_returns (rseg, rseg + returns->sh_size); + }if (alt) {/* patch .altinstructions */ void *aseg = (void *)alt->sh_addr;
arch/x86/kernel/vmlinux.lds.S +7 -0
@@ -284,6 +284,13 @@ SECTIONS *(.retpoline_sites) __retpoline_sites_end = .; } + + . = ALIGN(8); + .return_sites : AT(ADDR(.return_sites) - LOAD_OFFSET) { + __return_sites = .; + *(.return_sites) + __return_sites_end = .; + } #endif /*
Greg Kroah-Hartman
maintainerPATCH 30/78 x86,objtool: Create .return_sites
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit d9e9d2300681d68a775c28de6aa6e5290ae17796 upstream.
Find all the return-thunk sites and record them in a .return_sites section such that the kernel can undo this.
--- tools/objtool/arch/x86/decode.c | 5 ++ tools/objtool/check.c | 75 ++++++++++++++++++++++++++++++++ tools/objtool/include/objtool/arch.h | 1 tools/objtool/include/objtool/elf.h | 1 tools/objtool/include/objtool/objtool.h | 1 tools/objtool/objtool.c | 1 6 files changed, 84 insertions(+)
tools/objtool/arch/x86/decode.c +5 -0
@@ -722,3 +722,8 @@ bool arch_is_retpoline(struct symbol *sy {return !strncmp (sym->name,"__x86_indirect_" ,15 ); } + +bool arch_is_rethunk (struct symbol *sym) +{ +return !strcmp (sym->name,"__x86_return_thunk" ); +}
tools/objtool/check.c +75 -0
111 lines not on this page · raw message
tools/objtool/include/objtool/arch.h +1 -0
@@ -88,6 +88,7 @@ const char *arch_ret_insn(int len);int arch_decode_hint_reg (u8 sp_reg,int *base);bool arch_is_retpoline (struct symbol *sym); +bool arch_is_rethunk (struct symbol *sym);int arch_rewrite_retpolines (struct objtool_file *file);
tools/objtool/include/objtool/elf.h +1 -0
@@ -57,6 +57,7 @@ struct symbol { u8 uaccess_safe : 1; u8 static_call_tramp : 1; u8 retpoline_thunk : 1; + u8 return_thunk : 1; u8 fentry : 1; u8 kcov : 1; };
tools/objtool/include/objtool/objtool.h +1 -0
@@ -19,6 +19,7 @@ struct objtool_file {struct list_head insn_list;DECLARE_HASHTABLE (insn_hash,20 );struct list_head retpoline_call_list; +struct list_head return_thunk_list;struct list_head static_call_list;struct list_head mcount_loc_list;bool ignore_unreachables, c_file, hints, rodata;
tools/objtool/objtool.c +1 -0
@@ -126,6 +126,7 @@ struct objtool_file *objtool_open_read(cINIT_LIST_HEAD (&file.insn_list);hash_init (file.insn_hash);INIT_LIST_HEAD (&file.retpoline_call_list); +INIT_LIST_HEAD (&file.return_thunk_list);INIT_LIST_HEAD (&file.static_call_list);INIT_LIST_HEAD (&file.mcount_loc_list); file.c_file = !vmlinux &&find_section_by_name (file.elf,".comment" );
Greg Kroah-Hartman
maintainerPATCH 31/78 objtool: skip non-text sections when adding return-thunk sites
In reply to Greg Kroah-HartmanFrom: Thadeu Lima de Souza Cascardo <[email protected]>
The .discard.text section is added in order to reserve BRK, with a temporary function just so it can give it a size. This adds a relocation to the return thunk, which objtool will add to the .return_sites section. Linking will then fail as there are references to the .discard.text section.
Do not add instructions from non-text sections to the list of return thunk calls, avoiding the reference to .discard.text.
--- tools/objtool/check.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
tools/objtool/check.c +3 -1
@@ -1153,7 +1153,9 @@ static void add_return_call(struct objto insn->type =INSN_RETURN ; insn->retpoline_safe = true; -list_add_tail (&insn->call_node, &file->return_thunk_list); +/* Skip the non-text sections, specially .discard ones */ +if (insn->sec->text) +list_add_tail (&insn->call_node, &file->return_thunk_list); }/*
Greg Kroah-Hartman
maintainerPATCH 32/78 x86,static_call: Use alternative RET encoding
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit ee88d363d15617ff50ac24fab0ffec11113b2aeb upstream.
In addition to teaching static_call about the new way to spell 'RET', there is an added complication in that static_call() is allowed to rewrite text before it is known which particular spelling is required.
In order to deal with this; have a static_call specific fixup in the apply_return() 'alternative' patching routine that will rewrite the static_call trampoline to match the definite sequence.
This in turn creates the problem of uniquely identifying static call trampolines. Currently trampolines are 8 bytes, the first 5 being the jmp.d32/ret sequence and the final 3 a byte sequence that spells out 'SCT'.
This sequence is used in __static_call_validate() to ensure it is patching a trampoline and not a random other jmp.d32. That is, false-positives shouldn't be plenty, but aren't a big concern.
OTOH the new __static_call_fixup() must not have false-positives, and 'SCT' decodes to the somewhat weird but semi plausible sequence:
push %rbx
rex.XB push %r12
Additionally, there are SLS concerns with immediate jumps. Combined it seems like a good moment to change the signature to a single 3 byte trap instruction that is unique to this usage and will not ever get generated by accident.
As such, change the signature to: '0x0f, 0xb9, 0xcc', which decodes to:
ud1 %esp, %ecx
--- arch/x86/include/asm/static_call.h | 17 ++++++++++++++++ arch/x86/kernel/alternative.c | 12 +++++++---- arch/x86/kernel/static_call.c | 38 ++++++++++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 5 deletions(-)
arch/x86/include/asm/static_call.h +17 -0
@@ -21,6 +21,16 @@* relative displacement across sections. */ +/* +* The trampoline is 8 bytes and of the general form: +* +* jmp.d32 \func +* ud1 %esp, %ecx +* +* That trailing #UD provides both a speculation stop and serves as a unique +* 3 byte signature identifying static call trampolines. Also see tramp_ud[] +* and __static_call_fixup(). +*/ #define __ARCH_DEFINE_STATIC_CALL_TRAMP (name, insns) \ asm(".pushsection .static_call.text, \"ax\" \n" \ ".align 4 \n" \
@@ -34,8 +44,13 @@#define ARCH_DEFINE_STATIC_CALL_TRAMP (name, func) \ __ARCH_DEFINE_STATIC_CALL_TRAMP(name, ".byte 0xe9; .long " #func " - (. + 4)") +#ifdef CONFIG_RETPOLINE +#define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP (name) \ + __ARCH_DEFINE_STATIC_CALL_TRAMP(name, "jmp __x86_return_thunk") +#else #define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP (name) \ __ARCH_DEFINE_STATIC_CALL_TRAMP(name, "ret; int3; nop; nop; nop") +#endif #define ARCH_ADD_TRAMP_KEY (name) \
@@ -44,4 +59,6 @@ ".long " STATIC_CALL_KEY_STR(name) " - . \n" \ ".popsection \n") +extern bool __static_call_fixup (void *tramp,u8 op,void *dest); +#endif /* _ASM_STATIC_CALL_H */
arch/x86/kernel/alternative.c +8 -4
@@ -538,18 +538,22 @@ void __init_or_module noinline apply_rets32 *s;for (s = start; s < end; s++) { -void *addr = (void *)s + *s; +void *dest =NULL , *addr = (void *)s + *s;struct insn insn;int len, ret;u8 bytes[16 ]; -u8 op1; +u8 op; ret =insn_decode_kernel (&insn, addr);if (WARN_ON_ONCE (ret <0 ))continue ; - op1 = insn.opcode.bytes[0 ]; -if (WARN_ON_ONCE (op1 !=JMP32_INSN_OPCODE )) + op = insn.opcode.bytes[0 ]; +if (op ==JMP32_INSN_OPCODE ) + dest = addr + insn.length + insn.immediate.value; + +if (__static_call_fixup (addr, op, dest) || +WARN_ON_ONCE (dest != &__x86_return_thunk))continue ; DPRINTK("return thunk at: %pS (%px) len: %d to: %pS",
arch/x86/kernel/static_call.c +37 -1
@@ -12,6 +12,13 @@ enum insn_type { };/* +* ud1 %esp, %ecx - a 3 byte #UD that is unique to trampolines, chosen such +* that there is no false-positive trampoline identification while also being a +* speculation stop. +*/ +static const u8 tramp_ud[] = {0x0f ,0xb9 ,0xcc }; + +/* * cs cs cs xorl %eax, %eax - a single 5 byte instruction that clears %[er]ax */ static const u8 xor5rax[] = {0x2e ,0x2e ,0x2e ,0x31 ,0xc0 };
@@ -43,7 +50,10 @@ static void __ref __static_call_transforbreak ;case RET : - code = &retinsn; +if (cpu_feature_enabled (X86_FEATURE_RETHUNK )) + code =text_gen_insn (JMP32_INSN_OPCODE , insn, &__x86_return_thunk); +else + code = &retinsn;break ; }
@@ -109,3 +119,29 @@ void arch_static_call_transform(void *simutex_unlock (&text_mutex); }EXPORT_SYMBOL_GPL (arch_static_call_transform); + +#ifdef CONFIG_RETPOLINE +/* +* This is called by apply_returns() to fix up static call trampolines, +* specifically ARCH_DEFINE_STATIC_CALL_NULL_TRAMP which is recorded as +* having a return trampoline. +* +* The problem is that static_call() is available before determining +* X86_FEATURE_RETHUNK and, by implication, running alternatives. +* +* This means that __static_call_transform() above can have overwritten the +* return trampoline and we now need to fix things up to be consistent. +*/ +bool __static_call_fixup (void *tramp,u8 op,void *dest) +{ +if (memcmp (tramp+5 , tramp_ud,3 )) { +/* Not a trampoline site, not our problem. */ +return false; + } + +if (op ==RET_INSN_OPCODE || dest == &__x86_return_thunk) +__static_call_transform (tramp,RET ,NULL ); + +return true; +} +#endif
Greg Kroah-Hartman
maintainerPATCH 33/78 x86/ftrace: Use alternative RET encoding
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 1f001e9da6bbf482311e45e48f53c2bd2179e59c upstream.
Use the return thunk in ftrace trampolines, if needed.
--- arch/x86/kernel/ftrace.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
arch/x86/kernel/ftrace.c +5 -2
@@ -308,7 +308,7 @@ union ftrace_op_code_union { } __attribute__((packed)); }; -#define RET_SIZE 1 + IS_ENABLED(CONFIG_SLS) +#define RET_SIZE (IS_ENABLED(CONFIG_RETPOLINE) ? 5 : 1 + IS_ENABLED(CONFIG_SLS))static unsigned long create_trampoline (struct ftrace_ops *ops,unsigned int *tramp_size)
@@ -367,7 +367,10 @@ create_trampoline(struct ftrace_ops *ops/* The trampoline ends with ret(q) */ retq = (unsigned long )ftrace_stub; - ret =copy_from_kernel_nofault (ip, (void *)retq,RET_SIZE ); +if (cpu_feature_enabled (X86_FEATURE_RETHUNK )) +memcpy (ip,text_gen_insn (JMP32_INSN_OPCODE , ip, &__x86_return_thunk),JMP32_INSN_SIZE ); +else + ret =copy_from_kernel_nofault (ip, (void *)retq,RET_SIZE );if (WARN_ON (ret <0 )) goto fail;
Greg Kroah-Hartman
maintainerPATCH 34/78 x86/bpf: Use alternative RET encoding
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit d77cfe594ad50e0bf95d457e02ccd578791b2a15 upstream.
Use the return thunk in eBPF generated code, if needed.
--- arch/x86/net/bpf_jit_comp.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
arch/x86/net/bpf_jit_comp.c +17 -2
@@ -406,6 +406,21 @@ static void emit_indirect_jump(u8 **ppro *pprog = prog; } +static void emit_return (u8 **pprog,u8 *ip) +{ +u8 *prog = *pprog; + +if (cpu_feature_enabled (X86_FEATURE_RETHUNK )) { +emit_jump (&prog, &__x86_return_thunk, ip); + }else { +EMIT1 (0xC3 );/* ret */ +if (IS_ENABLED (CONFIG_SLS )) +EMIT1 (0xCC );/* int3 */ + } + + *pprog = prog; +} +/* * Generate the following code: *
@@ -1681,7 +1696,7 @@ emit_jmp: ctx->cleanup_addr = proglen;pop_callee_regs (&prog, callee_regs_used);EMIT1 (0xC9 );/* leave */ -EMIT1 (0xC3 );/* ret */ +emit_return (&prog, image + addrs[i -1 ] + (prog - temp));break ;default :
@@ -2127,7 +2142,7 @@ int arch_prepare_bpf_trampoline(struct bif (flags &BPF_TRAMP_F_SKIP_FRAME )/* skip our return address and return to parent */ EMIT4 (0x48 ,0x83 ,0xC4 ,8 );/* add rsp, 8 */ -EMIT1 (0xC3 );/* ret */ +emit_return (&prog, prog);/* Make sure the trampoline generation logic doesn't overflow */ if (WARN_ON_ONCE (prog > (u8 *)image_end -BPF_INSN_SAFETY )) { ret = -EFAULT ;
Greg Kroah-Hartman
maintainerPATCH 35/78 x86/kvm: Fix SETcc emulation for return thunks
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit af2e140f34208a5dfb6b7a8ad2d56bda88f0524d upstream.
Prepare the SETcc fastop stuff for when RET can be larger still.
The tricky bit here is that the expressions should not only be constant C expressions, but also absolute GAS expressions. This means no ?: and 'true' is ~0.
Also ensure em_setcc() has the same alignment as the actual FOP_SETCC() ops, this ensures there cannot be an alignment hole between em_setcc() and the first op.
Additionally, add a .skip directive to the FOP_SETCC() macro to fill any remaining space with INT3 traps; however the primary purpose of this directive is to generate AS warnings when the remaining space goes negative. Which is a very good indication the alignment magic went side-ways.
--- arch/x86/kvm/emulate.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-)
arch/x86/kvm/emulate.c +14 -12
@@ -321,13 +321,15 @@ static int fastop(struct x86_emulate_ctx#define FOP_RET (name) \ __FOP_RET(#name) -#define FOP_START (op) \ +#define __FOP_START (op, align) \ extern void em_##op(struct fastop *fake); \ asm(".pushsection .text, \"ax\" \n\t" \ ".global em_" #op " \n\t" \ - ".align " __stringify(FASTOP_SIZE) " \n\t" \ + ".align " __stringify(align) " \n\t" \ "em_" #op ":\n\t" +#define FOP_START (op) __FOP_START(op, FASTOP_SIZE) +#define FOP_END \ ".popsection")
@@ -431,15 +433,14 @@ static int fastop(struct x86_emulate_ctx/* * Depending on .config the SETcc functions look like: * -* SETcc %al [3 bytes] -* RET [1 byte] -* INT3 [1 byte; CONFIG_SLS] -* -* Which gives possible sizes 4 or 5. When rounded up to the -* next power-of-two alignment they become 4 or 8. +* SETcc %al [3 bytes] +* RET | JMP __x86_return_thunk [1,5 bytes; CONFIG_RETPOLINE] +* INT3 [1 byte; CONFIG_SLS] */ -#define SETCC_LENGTH (4 + IS_ENABLED(CONFIG_SLS)) -#define SETCC_ALIGN (4 << IS_ENABLED(CONFIG_SLS)) +#define RET_LENGTH (1 + (4 * IS_ENABLED(CONFIG_RETPOLINE)) + \ + IS_ENABLED(CONFIG_SLS)) +#define SETCC_LENGTH (3 + RET_LENGTH) +#define SETCC_ALIGN (4 << ((SETCC_LENGTH > 4) & 1) << ((SETCC_LENGTH > 8) & 1))static_assert (SETCC_LENGTH <=SETCC_ALIGN );#define FOP_SETCC (op) \
@@ -447,13 +448,14 @@ static_assert(SETCC_LENGTH <= SETCC_ALIG ".type " #op ", @function \n\t" \ #op ": \n\t" \ #op " %al \n\t" \ - __FOP_RET(#op) + __FOP_RET(#op) \ + ".skip " __stringify(SETCC_ALIGN) " - (.-" #op "), 0xcc \n\t" asm(".pushsection .fixup, \"ax\"\n" "kvm_fastop_exception: xor %esi, %esi; " ASM_RET ".popsection" ); -FOP_START(setcc) +__FOP_START(setcc, SETCC_ALIGN) FOP_SETCC(seto) FOP_SETCC(setno) FOP_SETCC(setc)
Greg Kroah-Hartman
maintainerPATCH 36/78 x86/vsyscall_emu/64: Dont use RET in vsyscall emulation
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 15583e514eb16744b80be85dea0774ece153177d upstream.
This is userspace code and doesn't play by the normal kernel rules.
--- arch/x86/entry/vsyscall/vsyscall_emu_64.S | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
arch/x86/entry/vsyscall/vsyscall_emu_64.S +6 -3
@@ -19,17 +19,20 @@ __vsyscall_page: mov $__NR_gettimeofday, %rax syscall - RET + ret + int3 .balign 1024, 0xcc mov $__NR_time, %rax syscall - RET + ret + int3 .balign 1024, 0xcc mov $__NR_getcpu, %rax syscall - RET + ret + int3 .balign 4096, 0xcc
Greg Kroah-Hartman
maintainerPATCH 37/78 x86/sev: Avoid using __x86_return_thunk
In reply to Greg Kroah-HartmanFrom: Kim Phillips <[email protected]>
commit 0ee9073000e8791f8b134a8ded31bcc767f7f232 upstream.
Specifically, it's because __enc_copy() encrypts the kernel after being relocated outside the kernel in sme_encrypt_execute(), and the RET macro's jmp offset isn't amended prior to execution.
--- arch/x86/mm/mem_encrypt_boot.S | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
arch/x86/mm/mem_encrypt_boot.S +6 -2
@@ -65,7 +65,9 @@ SYM_FUNC_START(sme_encrypt_execute) movq %rbp, %rsp /* Restore original stack pointer */ pop %rbp - RET + /* Offset to __x86_return_thunk would be wrong here */ + ret + int3 SYM_FUNC_END(sme_encrypt_execute) SYM_FUNC_START(__enc_copy)
@@ -151,6 +153,8 @@ SYM_FUNC_START(__enc_copy) pop %r12 pop %r15 - RET + /* Offset to __x86_return_thunk would be wrong here */ + ret + int3 .L__enc_copy_end: SYM_FUNC_END(__enc_copy)
Greg Kroah-Hartman
maintainerPATCH 38/78 x86: Use return-thunk in asm code
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit aa3d480315ba6c3025a60958e1981072ea37c3df upstream.
Use the return thunk in asm code. If the thunk isn't needed, it will get patched into a RET instruction during boot by apply_returns().
Since alternatives can't handle relocations outside of the first instruction, putting a 'jmp __x86_return_thunk' in one is not valid, therefore carve out the memmove ERMS path into a separate label and jump to it.
--- arch/x86/entry/vdso/Makefile | 1 + arch/x86/include/asm/linkage.h | 8 ++++++++ arch/x86/lib/memmove_64.S | 7 ++++++- 3 files changed, 15 insertions(+), 1 deletion(-)
arch/x86/entry/vdso/Makefile +1 -0
@@ -92,6 +92,7 @@ endif endif $(vobjs): KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO) $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS)) $(CFL) +$(vobjs): KBUILD_AFLAGS += -DBUILD_VDSO # # vDSO code runs in userspace and -pg doesn't help with profiling anyway.
arch/x86/include/asm/linkage.h +8 -0
@@ -18,19 +18,27 @@#define __ALIGN_STR __stringify(__ALIGN)#endif +#if defined(CONFIG_RETPOLINE ) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO ) +#define RET jmp __x86_return_thunk +#else /* CONFIG_RETPOLINE */ #ifdef CONFIG_SLS #define RET ret; int3#else #define RET ret#endif +#endif /* CONFIG_RETPOLINE */ #else /* __ASSEMBLY__ */ +#if defined(CONFIG_RETPOLINE ) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO ) +#define ASM_RET "jmp __x86_return_thunk\n\t" +#else /* CONFIG_RETPOLINE */ #ifdef CONFIG_SLS #define ASM_RET "ret; int3\n\t"#else #define ASM_RET "ret\n\t"#endif +#endif /* CONFIG_RETPOLINE */ #endif /* __ASSEMBLY__ */
arch/x86/lib/memmove_64.S +6 -1
@@ -40,7 +40,7 @@ SYM_FUNC_START(__memmove) /* FSRM implies ERMS => no length checks, do the copy directly */ .Lmemmove_begin_forward: ALTERNATIVE "cmp $0x20, %rdx; jb 1f", "", X86_FEATURE_FSRM - ALTERNATIVE "", __stringify(movq %rdx, %rcx; rep movsb; RET), X86_FEATURE_ERMS + ALTERNATIVE "", "jmp .Lmemmove_erms", X86_FEATURE_ERMS /* * movsq instruction have many startup latency
@@ -206,6 +206,11 @@ SYM_FUNC_START(__memmove) movb %r11b, (%rdi) 13: RET + +.Lmemmove_erms: + movq %rdx, %rcx + rep movsb + RET SYM_FUNC_END(__memmove) SYM_FUNC_END_ALIAS(memmove) EXPORT_SYMBOL(__memmove)
Greg Kroah-Hartman
maintainerPATCH 39/78 x86/entry: Avoid very early RET
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 7c81c0c9210c9bfab2bae76aab2999de5bad27db upstream.
Commit
ee774dac0da1 ("x86/entry: Move PUSH_AND_CLEAR_REGS out of error_entry()")
manages to introduce a CALL/RET pair that is before SWITCH_TO_KERNEL_CR3, which means it is before RETBleed can be mitigated.
Revert to an earlier version of the commit in Fixes. Down side is that this will bloat .text size somewhat. The alternative is fully reverting it.
The purpose of this patch was to allow migrating error_entry() to C, including the whole of kPTI. Much care needs to be taken moving that forward to not re-introduce this problem of early RETs.
--- arch/x86/entry/entry_64.S | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-)
arch/x86/entry/entry_64.S +2 -10
@@ -314,14 +314,6 @@ SYM_CODE_END(ret_from_fork) #endif .endm -/* Save all registers in pt_regs */ -SYM_CODE_START_LOCAL(push_and_clear_regs) - UNWIND_HINT_FUNC - PUSH_AND_CLEAR_REGS save_ret=1 - ENCODE_FRAME_POINTER 8 - RET -SYM_CODE_END(push_and_clear_regs) - /** * idtentry_body - Macro to emit code calling the C function * @cfunc: C function to be called
@@ -329,8 +321,8 @@ SYM_CODE_END(push_and_clear_regs) */ .macro idtentry_body cfunc has_error_code:req - call push_and_clear_regs - UNWIND_HINT_REGS + PUSH_AND_CLEAR_REGS + ENCODE_FRAME_POINTER /* * Call error_entry() and switch to the task stack if from userspace.
Greg Kroah-Hartman
maintainerPATCH 40/78 objtool: Treat .text.__x86.* as noinstr
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 951ddecf435659553ed15a9214e153a3af43a9a1 upstream.
Needed because zen_untrain_ret() will be called from noinstr code.
Also makes sense since the thunks MUST NOT contain instrumentation nor be poked with dynamic instrumentation.
--- tools/objtool/check.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/objtool/check.c +2 -1
@@ -367,7 +367,8 @@ static int decode_instructions(struct ob sec->text = true;if (!strcmp (sec->name,".noinstr.text" ) || - !strcmp (sec->name,".entry.text" )) + !strcmp (sec->name,".entry.text" ) || + !strncmp (sec->name,".text.__x86." ,12 )) sec->noinstr = true;for (offset =0 ; offset < sec->sh.sh_size; offset += insn->len) {
Greg Kroah-Hartman
maintainerPATCH 41/78 x86: Add magic AMD return-thunk
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit a149180fbcf336e97ce4eb2cdc13672727feb94d upstream.
Note: needs to be in a section distinct from Retpolines such that the Retpoline RET substitution cannot possibly use immediate jumps.
ORC unwinding for zen_untrain_ret() and __x86_return_thunk() is a little tricky but works due to the fact that zen_untrain_ret() doesn't have any stack ops and as such will emit a single ORC entry at the start (+0x3f).
Meanwhile, unwinding an IP, including the __x86_return_thunk() one (+0x40) will search for the largest ORC entry smaller or equal to the IP, these will find the one ORC entry (+0x3f) and all works.
[ Alexandre: SVM part. ]
[ bp: Build fix, massages. ]
--- arch/x86/entry/entry_64.S | 6 ++ arch/x86/entry/entry_64_compat.S | 4 + arch/x86/include/asm/cpufeatures.h | 1 arch/x86/include/asm/disabled-features.h | 3 - arch/x86/include/asm/nospec-branch.h | 17 ++++++++ arch/x86/kernel/vmlinux.lds.S | 2 arch/x86/kvm/svm/vmenter.S | 18 ++++++++ arch/x86/lib/retpoline.S | 63 +++++++++++++++++++++++++++++-- tools/objtool/check.c | 20 ++++++++- 9 files changed, 126 insertions(+), 8 deletions(-)
arch/x86/entry/entry_64.S +6 -0
@@ -94,6 +94,7 @@ SYM_CODE_START(entry_SYSCALL_64) movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp SYM_INNER_LABEL(entry_SYSCALL_64_safe_stack, SYM_L_GLOBAL) + UNTRAIN_RET /* Construct struct pt_regs on stack */ pushq $__USER_DS /* pt_regs->ss */
@@ -688,6 +689,7 @@ native_irq_return_ldt: pushq %rdi /* Stash user RDI */ swapgs /* to kernel GS */ SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi /* to kernel CR3 */ + UNTRAIN_RET movq PER_CPU_VAR(espfix_waddr), %rdi movq %rax, (0*8)(%rdi) /* user RAX */
@@ -882,6 +884,7 @@ SYM_CODE_START_LOCAL(paranoid_entry) * be retrieved from a kernel internal table. */ SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg=%rax save_reg=%r14 + UNTRAIN_RET /* * Handling GSBASE depends on the availability of FSGSBASE.
@@ -992,6 +995,7 @@ SYM_CODE_START_LOCAL(error_entry) FENCE_SWAPGS_USER_ENTRY /* We have user CR3. Change to kernel CR3. */ SWITCH_TO_KERNEL_CR3 scratch_reg=%rax + UNTRAIN_RET leaq 8(%rsp), %rdi /* arg0 = pt_regs pointer */ .Lerror_entry_from_usermode_after_swapgs:
@@ -1044,6 +1048,7 @@ SYM_CODE_START_LOCAL(error_entry) SWAPGS FENCE_SWAPGS_USER_ENTRY SWITCH_TO_KERNEL_CR3 scratch_reg=%rax + UNTRAIN_RET /* * Pretend that the exception came from user mode: set up pt_regs
@@ -1138,6 +1143,7 @@ SYM_CODE_START(asm_exc_nmi) movq %rsp, %rdx movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp UNWIND_HINT_IRET_REGS base=%rdx offset=8 + UNTRAIN_RET pushq 5*8(%rdx) /* pt_regs->ss */ pushq 4*8(%rdx) /* pt_regs->rsp */ pushq 3*8(%rdx) /* pt_regs->flags */
arch/x86/entry/entry_64_compat.S +4 -0
@@ -14,6 +14,7 @@ #include <asm/irqflags.h> #include <asm/asm.h> #include <asm/smap.h> +#include <asm/nospec-branch.h> #include <linux/linkage.h> #include <linux/err.h>
@@ -71,6 +72,7 @@ SYM_CODE_START(entry_SYSENTER_compat) pushq $__USER32_CS /* pt_regs->cs */ pushq $0 /* pt_regs->ip = 0 (placeholder) */ SYM_INNER_LABEL(entry_SYSENTER_compat_after_hwframe, SYM_L_GLOBAL) + UNTRAIN_RET /* * User tracing code (ptrace or signal handlers) might assume that
@@ -211,6 +213,7 @@ SYM_CODE_START(entry_SYSCALL_compat) movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp SYM_INNER_LABEL(entry_SYSCALL_compat_safe_stack, SYM_L_GLOBAL) + UNTRAIN_RET /* Construct struct pt_regs on stack */ pushq $__USER32_DS /* pt_regs->ss */
@@ -377,6 +380,7 @@ SYM_CODE_START(entry_INT80_compat) pushq (%rdi) /* pt_regs->di */ .Lint80_keep_stack: + UNTRAIN_RET pushq %rsi /* pt_regs->si */ xorl %esi, %esi /* nospec si */ pushq %rdx /* pt_regs->dx */
arch/x86/include/asm/cpufeatures.h +1 -0
@@ -299,6 +299,7 @@#define X86_FEATURE_RETPOLINE (11*32+12)/* "" Generic Retpoline mitigation for Spectre variant 2 */ #define X86_FEATURE_RETPOLINE_LFENCE (11*32+13)/* "" Use LFENCE for Spectre variant 2 */ #define X86_FEATURE_RETHUNK (11*32+14)/* "" Use REturn THUNK */ +#define X86_FEATURE_UNRET (11*32+15)/* "" AMD BTB untrain return */ /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ #define X86_FEATURE_AVX_VNNI (12*32+ 4)/* AVX VNNI instructions */
arch/x86/include/asm/disabled-features.h +2 -1
@@ -61,7 +61,8 @@#else # define DISABLE_RETPOLINE ((1 << (X86_FEATURE_RETPOLINE & 31)) | \ (1 << (X86_FEATURE_RETPOLINE_LFENCE & 31)) | \ - (1 << (X86_FEATURE_RETHUNK & 31))) + (1 << (X86_FEATURE_RETHUNK & 31)) | \ + (1 << (X86_FEATURE_UNRET & 31)))#endif /* Force disable because it's broken beyond repair */
arch/x86/include/asm/nospec-branch.h +17 -0
@@ -112,6 +112,22 @@#endif .endm +/* + * Mitigate RETBleed for AMD/Hygon Zen uarch. Requires KERNEL CR3 because the + * return thunk isn't mapped into the userspace tables (then again, AMD + * typically has NO_MELTDOWN). + * + * Doesn't clobber any registers but does require a stable stack. + * + * As such, this must be placed after every *SWITCH_TO_KERNEL_CR3 at a point + * where we have a stack but before any RET instruction. + */ +.macro UNTRAIN_RET +#ifdef CONFIG_RETPOLINE +ALTERNATIVE "" ,"call zen_untrain_ret" ,X86_FEATURE_UNRET +#endif +.endm +#else /* __ASSEMBLY__ */ #define ANNOTATE_RETPOLINE_SAFE \
@@ -121,6 +137,7 @@".popsection\n\t" extern void __x86_return_thunk(void); +extern void zen_untrain_ret (void );#ifdef CONFIG_RETPOLINE
arch/x86/kernel/vmlinux.lds.S +1 -1
@@ -142,7 +142,7 @@ SECTIONS #ifdef CONFIG_RETPOLINE __indirect_thunk_start = .; - *(.text.__x86.indirect_thunk) + *(.text.__x86.*) __indirect_thunk_end = .; #endif } :text =0xcccc
arch/x86/kvm/svm/vmenter.S +18 -0
@@ -111,6 +111,15 @@ SYM_FUNC_START(__svm_vcpu_run) #endif /* + * Mitigate RETBleed for AMD/Hygon Zen uarch. RET should be + * untrained as soon as we exit the VM and are back to the + * kernel. This should be done before re-enabling interrupts + * because interrupt handlers won't sanitize 'ret' if the return is + * from the kernel. + */ + UNTRAIN_RET + + /* * Clear all general purpose registers except RSP and RAX to prevent * speculative use of the guest's values, even those that are reloaded * via the stack. In theory, an L1 cache miss when restoring registers
@@ -190,6 +199,15 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run) FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE #endif + /* + * Mitigate RETBleed for AMD/Hygon Zen uarch. RET should be + * untrained as soon as we exit the VM and are back to the + * kernel. This should be done before re-enabling interrupts + * because interrupt handlers won't sanitize RET if the return is + * from the kernel. + */ + UNTRAIN_RET + pop %_ASM_BX #ifdef CONFIG_X86_64
arch/x86/lib/retpoline.S +60 -3
70 lines not on this page · raw message
tools/objtool/check.c +17 -3
@@ -1145,7 +1145,7 @@ static void add_retpoline_call(struct obannotate_call_site (file, insn, false); } -static void add_return_call (struct objtool_file *file,struct instruction *insn) +static void add_return_call (struct objtool_file *file,struct instruction *insn,bool add) {/* * Return thunk tail calls are really just returns in disguise,
@@ -1155,7 +1155,7 @@ static void add_return_call(struct objto insn->retpoline_safe = true;/* Skip the non-text sections, specially .discard ones */ -if (insn->sec->text) +if (add && insn->sec->text)list_add_tail (&insn->call_node, &file->return_thunk_list); }
@@ -1184,7 +1184,7 @@ static int add_jump_destinations(structadd_retpoline_call (file, insn);continue ; }else if (reloc->sym->return_thunk) { -add_return_call (file, insn); +add_return_call (file, insn, true);continue ; }else if (insn->func) {/* internal or external sibling call (with reloc) */
@@ -1201,6 +1201,7 @@ static int add_jump_destinations(struct insn->jump_dest =find_insn (file, dest_sec, dest_off);if (!insn->jump_dest) { +struct symbol *sym =find_symbol_by_offset (dest_sec, dest_off);/* * This is a special case where an alt instruction
@@ -1210,6 +1211,19 @@ static int add_jump_destinations(structif (!strcmp (insn->sec->name,".altinstr_replacement" ))continue ; +/* +* This is a special case for zen_untrain_ret(). +* It jumps to __x86_return_thunk(), but objtool +* can't find the thunk's starting RET +* instruction, because the RET is also in the +* middle of another instruction. Objtool only +* knows about the outer instruction. +*/ +if (sym && sym->return_thunk) { +add_return_call (file, insn, false); +continue ; + } +WARN_FUNC ("can't find jump dest instruction at %s+0x%lx" , insn->sec, insn->offset, dest_sec->name, dest_off);
Greg Kroah-Hartman
maintainerPATCH 42/78 x86/bugs: Report AMD retbleed vulnerability
In reply to Greg Kroah-HartmanFrom: Alexandre Chartre <[email protected]>
commit 6b80b59b3555706508008f1f127b5412c89c7fd8 upstream.
Report that AMD x86 CPUs are vulnerable to the RETBleed (Arbitrary Speculative Code Execution with Return Instructions) attack.
[peterz: add hygon]
[kim: invert parity; fam15h]
--- arch/x86/include/asm/cpufeatures.h | 1 + arch/x86/kernel/cpu/bugs.c | 13 +++++++++++++ arch/x86/kernel/cpu/common.c | 19 +++++++++++++++++++ drivers/base/cpu.c | 8 ++++++++ include/linux/cpu.h | 2 ++ 5 files changed, 43 insertions(+)
arch/x86/include/asm/cpufeatures.h +1 -0
@@ -443,5 +443,6 @@#define X86_BUG_ITLB_MULTIHIT X86_BUG(23)/* CPU may incur MCE during certain page attribute changes */ #define X86_BUG_SRBDS X86_BUG(24)/* CPU may leak RNG bits if not mitigated */ #define X86_BUG_MMIO_STALE_DATA X86_BUG(25)/* CPU is affected by Processor MMIO Stale Data vulnerabilities */ +#define X86_BUG_RETBLEED X86_BUG(26)/* CPU is affected by RETBleed */ #endif /* _ASM_X86_CPUFEATURES_H */
arch/x86/kernel/cpu/bugs.c +13 -0
@@ -1987,6 +1987,11 @@ static ssize_t srbds_show_state(char *bureturn sprintf (buf,"%s\n" , srbds_strings[srbds_mitigation]); } +static ssize_t retbleed_show_state (char *buf) +{ +return sprintf (buf,"Vulnerable\n" ); +} +static ssize_t cpu_show_common (struct device *dev,struct device_attribute *attr,char *buf,unsigned int bug) {
@@ -2032,6 +2037,9 @@ static ssize_t cpu_show_common(struct decase X86_BUG_MMIO_STALE_DATA :return mmio_stale_data_show_state (buf); +case X86_BUG_RETBLEED : +return retbleed_show_state (buf); +default :break ; }
@@ -2088,4 +2096,9 @@ ssize_t cpu_show_mmio_stale_data(struct {return cpu_show_common (dev, attr, buf,X86_BUG_MMIO_STALE_DATA ); } + +ssize_t cpu_show_retbleed (struct device *dev,struct device_attribute *attr,char *buf) +{ +return cpu_show_common (dev, attr, buf,X86_BUG_RETBLEED ); +}#endif
arch/x86/kernel/cpu/common.c +19 -0
@@ -1095,16 +1095,27 @@ static const __initconst struct x86_cpu_ {} }; +#define VULNBL (vendor, family, model, blacklist) \ + X86_MATCH_VENDOR_FAM_MODEL(vendor, family, model, blacklist) +#define VULNBL_INTEL_STEPPINGS (model, steppings, issues) \ X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(INTEL, 6, \ INTEL_FAM6_##model, steppings, \ X86_FEATURE_ANY, issues) +#define VULNBL_AMD (family, blacklist) \ + VULNBL(AMD, family, X86_MODEL_ANY, blacklist) + +#define VULNBL_HYGON (family, blacklist) \ + VULNBL(HYGON, family, X86_MODEL_ANY, blacklist) +#define SRBDS BIT(0)/* CPU is affected by X86_BUG_MMIO_STALE_DATA */ #define MMIO BIT(1)/* CPU is affected by Shared Buffers Data Sampling (SBDS), a variant of X86_BUG_MMIO_STALE_DATA */ #define MMIO_SBDS BIT(2) +/* CPU is affected by RETbleed, speculating where you would not expect it */ +#define RETBLEED BIT(3)static const struct x86_cpu_id cpu_vuln_blacklist[]__initconst = {VULNBL_INTEL_STEPPINGS (IVYBRIDGE ,X86_STEPPING_ANY ,SRBDS ),
@@ -1137,6 +1148,11 @@ static const struct x86_cpu_id cpu_vuln_VULNBL_INTEL_STEPPINGS (ATOM_TREMONT ,X86_STEPPINGS (0x1 ,0x1 ),MMIO |MMIO_SBDS ),VULNBL_INTEL_STEPPINGS (ATOM_TREMONT_D ,X86_STEPPING_ANY ,MMIO ),VULNBL_INTEL_STEPPINGS (ATOM_TREMONT_L ,X86_STEPPINGS (0x0 ,0x0 ),MMIO |MMIO_SBDS ), + +VULNBL_AMD (0x15 ,RETBLEED ), +VULNBL_AMD (0x16 ,RETBLEED ), +VULNBL_AMD (0x17 ,RETBLEED ), + VULNBL_HYGON(0x18, RETBLEED), {} };
@@ -1238,6 +1254,9 @@ static void __init cpu_set_bug_bits(stru !arch_cap_mmio_immune(ia32_cap))setup_force_cpu_bug (X86_BUG_MMIO_STALE_DATA ); +if (cpu_matches (cpu_vuln_blacklist,RETBLEED )) +setup_force_cpu_bug (X86_BUG_RETBLEED ); +if (cpu_matches (cpu_vuln_whitelist,NO_MELTDOWN ))return ;
drivers/base/cpu.c +8 -0
@@ -570,6 +570,12 @@ ssize_t __weak cpu_show_mmio_stale_data(return sysfs_emit (buf,"Not affected\n" ); } +ssize_t __weak cpu_show_retbleed (struct device *dev, +struct device_attribute *attr,char *buf) +{ +return sysfs_emit (buf,"Not affected\n" ); +} + static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL);
@@ -580,6 +586,7 @@ static DEVICE_ATTR(tsx_async_abort, 0444 static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL); static DEVICE_ATTR(srbds, 0444, cpu_show_srbds, NULL); static DEVICE_ATTR(mmio_stale_data, 0444, cpu_show_mmio_stale_data, NULL); +static DEVICE_ATTR(retbleed, 0444, cpu_show_retbleed, NULL);static struct attribute *cpu_root_vulnerabilities_attrs[] = { &dev_attr_meltdown.attr,
@@ -592,6 +599,7 @@ static struct attribute *cpu_root_vulner &dev_attr_itlb_multihit.attr, &dev_attr_srbds.attr, &dev_attr_mmio_stale_data.attr, + &dev_attr_retbleed.attr, NULL };
include/linux/cpu.h +2 -0
@@ -68,6 +68,8 @@ extern ssize_t cpu_show_srbds(struct devextern ssize_t cpu_show_mmio_stale_data (struct device *dev,struct device_attribute *attr,char *buf); +extern ssize_t cpu_show_retbleed (struct device *dev, +struct device_attribute *attr,char *buf); extern __printf(4, 5) struct device *cpu_device_create(struct device *parent, void *drvdata,
Greg Kroah-Hartman
maintainerPATCH 43/78 x86/bugs: Add AMD retbleed= boot parameter
In reply to Greg Kroah-HartmanFrom: Alexandre Chartre <[email protected]>
commit 7fbf47c7ce50b38a64576b150e7011ae73d54669 upstream.
Add the "retbleed=<value>" boot parameter to select a mitigation for RETBleed. Possible values are "off", "auto" and "unret" (JMP2RET mitigation). The default value is "auto".
Currently, "retbleed=auto" will select the unret mitigation on AMD and Hygon and no mitigation on Intel (JMP2RET is not effective on Intel).
[peterz: rebase; add hygon]
[jpoimboe: cleanups]
--- Documentation/admin-guide/kernel-parameters.txt | 15 +++ arch/x86/Kconfig | 3 arch/x86/kernel/cpu/bugs.c | 108 +++++++++++++++++++++++- 3 files changed, 125 insertions(+), 1 deletion(-)
Documentation/admin-guide/kernel-parameters.txt +15 -0
@@ -4968,6 +4968,21 @@ retain_initrd [RAM] Keep initrd memory after extraction + retbleed= [X86] Control mitigation of RETBleed (Arbitrary + Speculative Code Execution with Return Instructions) + vulnerability. + + off - unconditionally disable + auto - automatically select a migitation + unret - force enable untrained return thunks, + only effective on AMD Zen {1,2} + based systems. + + Selecting 'auto' will choose a mitigation method at run + time according to the CPU. + + Not specifying this option is equivalent to retbleed=auto. + rfkill.default_state= 0 "airplane mode". All wifi, bluetooth, wimax, gps, fm, etc. communication is blocked by default.
arch/x86/Kconfig +3 -0
@@ -471,6 +471,9 @@ config RETPOLINE config CC_HAS_SLS def_bool $(cc-option,-mharden-sls=all) +config CC_HAS_RETURN_THUNK + def_bool $(cc-option,-mfunction-return=thunk-extern) + config SLS bool "Mitigate Straight-Line-Speculation" depends on CC_HAS_SLS && X86_64
arch/x86/kernel/cpu/bugs.c +107 -1
132 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 44/78 x86/bugs: Enable STIBP for JMP2RET
In reply to Greg Kroah-HartmanFrom: Kim Phillips <[email protected]>
commit e8ec1b6e08a2102d8755ccb06fa26d540f26a2fa upstream.
For untrained return thunks to be fully effective, STIBP must be enabled or SMT disabled.
--- Documentation/admin-guide/kernel-parameters.txt | 16 ++++-- arch/x86/kernel/cpu/bugs.c | 58 +++++++++++++++++++----- 2 files changed, 57 insertions(+), 17 deletions(-)
Documentation/admin-guide/kernel-parameters.txt +11 -5
@@ -4972,11 +4972,17 @@ Speculative Code Execution with Return Instructions) vulnerability. - off - unconditionally disable - auto - automatically select a migitation - unret - force enable untrained return thunks, - only effective on AMD Zen {1,2} - based systems. + off - no mitigation + auto - automatically select a migitation + auto,nosmt - automatically select a mitigation, + disabling SMT if necessary for + the full mitigation (only on Zen1 + and older without STIBP). + unret - force enable untrained return thunks, + only effective on AMD f15h-f17h + based systems. + unret,nosmt - like unret, will disable SMT when STIBP + is not available. Selecting 'auto' will choose a mitigation method at run time according to the CPU.
arch/x86/kernel/cpu/bugs.c +46 -12
87 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 45/78 x86/bugs: Keep a per-CPU IA32_SPEC_CTRL value
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit caa0ff24d5d0e02abce5e65c3d2b7f20a6617be5 upstream.
Due to TIF_SSBD and TIF_SPEC_IB the actual IA32_SPEC_CTRL value can differ from x86_spec_ctrl_base. As such, keep a per-CPU value reflecting the current task's MSR content.
[jpoimboe: rename]
--- arch/x86/include/asm/nospec-branch.h | 1 + arch/x86/kernel/cpu/bugs.c | 28 +++++++++++++++++++++++----- arch/x86/kernel/process.c | 2 +- 3 files changed, 25 insertions(+), 6 deletions(-)
arch/x86/include/asm/nospec-branch.h +1 -0
@@ -254,6 +254,7 @@ static inline void indirect_branch_predi/* The Intel SPEC CTRL MSR base value cache */ extern u64 x86_spec_ctrl_base; +extern void write_spec_ctrl_current (u64 val);/* * With retpoline, we must use IBRS to restrict branch prediction
arch/x86/kernel/cpu/bugs.c +23 -5
@@ -49,12 +49,30 @@ static void __init mmio_select_mitigatiostatic void __init srbds_select_mitigation (void );static void __init l1d_flush_select_mitigation (void ); -/* The base value of the SPEC_CTRL MSR that always has to be preserved. */ +/* The base value of the SPEC_CTRL MSR without task-specific bits set */ u64 x86_spec_ctrl_base;EXPORT_SYMBOL_GPL (x86_spec_ctrl_base); + +/* The current value of the SPEC_CTRL MSR with task-specific bits set */ +DEFINE_PER_CPU (u64, x86_spec_ctrl_current); +EXPORT_SYMBOL_GPL (x86_spec_ctrl_current); +static DEFINE_MUTEX (spec_ctrl_mutex);/* +* Keep track of the SPEC_CTRL MSR value for the current task, which may differ +* from x86_spec_ctrl_base due to STIBP/SSB in __speculation_ctrl_update(). +*/ +void write_spec_ctrl_current (u64 val) +{ +if (this_cpu_read (x86_spec_ctrl_current) == val) +return ; + +this_cpu_write (x86_spec_ctrl_current, val); +wrmsrl (MSR_IA32_SPEC_CTRL , val); +} + +/* * The vendor and possibly platform specific bits which can be modified in * x86_spec_ctrl_base. */
@@ -1272,7 +1290,7 @@ static void __init spectre_v2_select_mitif (spectre_v2_in_eibrs_mode (mode)) {/* Force it so VMEXIT will restore correctly */ x86_spec_ctrl_base |=SPEC_CTRL_IBRS ; -wrmsrl (MSR_IA32_SPEC_CTRL , x86_spec_ctrl_base); +write_spec_ctrl_current (x86_spec_ctrl_base); }switch (mode) {
@@ -1327,7 +1345,7 @@ static void __init spectre_v2_select_mitstatic void update_stibp_msr (void * __unused) { -wrmsrl (MSR_IA32_SPEC_CTRL , x86_spec_ctrl_base); +write_spec_ctrl_current (x86_spec_ctrl_base); }/* Update x86_spec_ctrl_base in case SMT state changed. */
@@ -1570,7 +1588,7 @@ static enum ssb_mitigation __init __ssb_x86_amd_ssb_disable (); }else { x86_spec_ctrl_base |=SPEC_CTRL_SSBD ; -wrmsrl (MSR_IA32_SPEC_CTRL , x86_spec_ctrl_base); +write_spec_ctrl_current (x86_spec_ctrl_base); } }
@@ -1821,7 +1839,7 @@ int arch_prctl_spec_ctrl_get(struct taskvoid x86_spec_ctrl_setup_ap (void ) {if (boot_cpu_has (X86_FEATURE_MSR_SPEC_CTRL )) -wrmsrl (MSR_IA32_SPEC_CTRL , x86_spec_ctrl_base); +write_spec_ctrl_current (x86_spec_ctrl_base);if (ssb_mode ==SPEC_STORE_BYPASS_DISABLE )x86_amd_ssb_disable ();
arch/x86/kernel/process.c +1 -1
@@ -584,7 +584,7 @@ static __always_inline void __speculatio }if (updmsr) -wrmsrl (MSR_IA32_SPEC_CTRL , msr); +write_spec_ctrl_current (msr); }static unsigned long speculation_ctrl_update_tif (struct task_struct *tsk)
Greg Kroah-Hartman
maintainerPATCH 46/78 x86/entry: Add kernel IBRS implementation
In reply to Greg Kroah-HartmanFrom: Thadeu Lima de Souza Cascardo <[email protected]>
commit 2dbb887e875b1de3ca8f40ddf26bcfe55798c609 upstream.
Implement Kernel IBRS - currently the only known option to mitigate RSB underflow speculation issues on Skylake hardware.
Note: since IBRS_ENTER requires fuller context established than UNTRAIN_RET, it must be placed after it. However, since UNTRAIN_RET itself implies a RET, it must come after IBRS_ENTER. This means IBRS_ENTER needs to also move UNTRAIN_RET.
Note 2: KERNEL_IBRS is sub-optimal for XenPV.
--- arch/x86/entry/calling.h | 58 +++++++++++++++++++++++++++++++++++++ arch/x86/entry/entry_64.S | 44 ++++++++++++++++++++++++---- arch/x86/entry/entry_64_compat.S | 17 ++++++++-- arch/x86/include/asm/cpufeatures.h | 2 - 4 files changed, 111 insertions(+), 10 deletions(-)
arch/x86/entry/calling.h +58 -0
@@ -7,6 +7,8 @@#include <asm/asm-offsets.h> #include <asm/processor-flags.h> #include <asm/ptrace-abi.h> +#include <asm/msr.h> +#include <asm/nospec-branch.h> /*
@@ -282,6 +284,62 @@ For 32-bit we have the following convent#endif /* +* IBRS kernel mitigation for Spectre_v2. +* +* Assumes full context is established (PUSH_REGS, CR3 and GS) and it clobbers +* the regs it uses (AX, CX, DX). Must be called before the first RET +* instruction (NOTE! UNTRAIN_RET includes a RET instruction) +* +* The optional argument is used to save/restore the current value, +* which is used on the paranoid paths. +* +* Assumes x86_spec_ctrl_{base,current} to have SPEC_CTRL_IBRS set. +*/ +.macro IBRS_ENTER save_reg + ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_KERNEL_IBRS + movl $MSR_IA32_SPEC_CTRL, %ecx + +.ifnb \save_reg + rdmsr + shl $32, %rdx + or %rdx, %rax + mov %rax, \save_reg + test $SPEC_CTRL_IBRS, %eax + jz .Ldo_wrmsr_\@ + lfence + jmp .Lend_\@ +.Ldo_wrmsr_\@: +.endif + + movq PER_CPU_VAR(x86_spec_ctrl_current), %rdx + movl %edx, %eax + shr $32, %rdx + wrmsr +.Lend_\@: +.endm + +/* + * Similar to IBRS_ENTER, requires KERNEL GS,CR3 and clobbers (AX, CX, DX) + * regs. Must be called after the last RET. + */ +.macro IBRS_EXIT save_reg + ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_KERNEL_IBRS + movl $MSR_IA32_SPEC_CTRL, %ecx + +.ifnb \save_reg + mov \save_reg, %rdx +.else + movq PER_CPU_VAR(x86_spec_ctrl_current), %rdx + andl $(~SPEC_CTRL_IBRS), %edx +.endif + + movl %edx, %eax + shr $32, %rdx + wrmsr +.Lend_\@: +.endm + +/* * Mitigate Spectre v1 for conditional swapgs code paths. * * FENCE_SWAPGS_USER_ENTRY is used in the user entry swapgs code path, to
arch/x86/entry/entry_64.S +39 -5
136 lines not on this page · raw message
arch/x86/entry/entry_64_compat.S +13 -4
@@ -4,7 +4,6 @@ * * Copyright 2000-2002 Andi Kleen, SuSE Labs. */ -#include "calling.h" #include <asm/asm-offsets.h> #include <asm/current.h> #include <asm/errno.h>
@@ -18,6 +17,8 @@ #include <linux/linkage.h> #include <linux/err.h> +#include "calling.h" + .section .entry.text, "ax" /*
@@ -72,7 +73,6 @@ SYM_CODE_START(entry_SYSENTER_compat) pushq $__USER32_CS /* pt_regs->cs */ pushq $0 /* pt_regs->ip = 0 (placeholder) */ SYM_INNER_LABEL(entry_SYSENTER_compat_after_hwframe, SYM_L_GLOBAL) - UNTRAIN_RET /* * User tracing code (ptrace or signal handlers) might assume that
@@ -114,6 +114,9 @@ SYM_INNER_LABEL(entry_SYSENTER_compat_af cld + IBRS_ENTER + UNTRAIN_RET + /* * SYSENTER doesn't filter flags, so we need to clear NT and AC * ourselves. To save a few cycles, we can check whether
@@ -213,7 +216,6 @@ SYM_CODE_START(entry_SYSCALL_compat) movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp SYM_INNER_LABEL(entry_SYSCALL_compat_safe_stack, SYM_L_GLOBAL) - UNTRAIN_RET /* Construct struct pt_regs on stack */ pushq $__USER32_DS /* pt_regs->ss */
@@ -255,6 +257,9 @@ SYM_INNER_LABEL(entry_SYSCALL_compat_aft UNWIND_HINT_REGS + IBRS_ENTER + UNTRAIN_RET + movq %rsp, %rdi call do_fast_syscall_32 /* XEN PV guests always use IRET path */
@@ -269,6 +274,8 @@ sysret32_from_system_call: */ STACKLEAK_ERASE + IBRS_EXIT + movq RBX(%rsp), %rbx /* pt_regs->rbx */ movq RBP(%rsp), %rbp /* pt_regs->rbp */ movq EFLAGS(%rsp), %r11 /* pt_regs->flags (in r11) */
@@ -380,7 +387,6 @@ SYM_CODE_START(entry_INT80_compat) pushq (%rdi) /* pt_regs->di */ .Lint80_keep_stack: - UNTRAIN_RET pushq %rsi /* pt_regs->si */ xorl %esi, %esi /* nospec si */ pushq %rdx /* pt_regs->dx */
@@ -413,6 +419,9 @@ SYM_CODE_START(entry_INT80_compat) cld + IBRS_ENTER + UNTRAIN_RET + movq %rsp, %rdi call do_int80_syscall_32 jmp swapgs_restore_regs_and_return_to_usermode
arch/x86/include/asm/cpufeatures.h +1 -1
@@ -203,7 +203,7 @@#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9)/* AMD ProcFeedbackInterface */ /* FREE! ( 7*32+10) */ #define X86_FEATURE_PTI ( 7*32+11)/* Kernel Page Table Isolation enabled */ -/* FREE! ( 7*32+12) */ +#define X86_FEATURE_KERNEL_IBRS ( 7*32+12)/* "" Set/clear IBRS on kernel entry/exit */ /* FREE! ( 7*32+13) */ #define X86_FEATURE_INTEL_PPIN ( 7*32+14)/* Intel Processor Inventory Number */ #define X86_FEATURE_CDP_L2 ( 7*32+15)/* Code and Data Prioritization L2 */
Greg Kroah-Hartman
maintainerPATCH 47/78 x86/bugs: Optimize SPEC_CTRL MSR writes
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit c779bc1a9002fa474175b80e72b85c9bf628abb0 upstream.
When changing SPEC_CTRL for user control, the WRMSR can be delayed until return-to-user when KERNEL_IBRS has been enabled.
This avoids an MSR write during context switch.
--- arch/x86/include/asm/nospec-branch.h | 2 +- arch/x86/kernel/cpu/bugs.c | 18 ++++++++++++------ arch/x86/kernel/process.c | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-)
arch/x86/include/asm/nospec-branch.h +1 -1
@@ -254,7 +254,7 @@ static inline void indirect_branch_predi/* The Intel SPEC CTRL MSR base value cache */ extern u64 x86_spec_ctrl_base; -extern void write_spec_ctrl_current (u64 val); +extern void write_spec_ctrl_current (u64 val,bool force);/* * With retpoline, we must use IBRS to restrict branch prediction
arch/x86/kernel/cpu/bugs.c +12 -6
@@ -63,13 +63,19 @@ static DEFINE_MUTEX(spec_ctrl_mutex);* Keep track of the SPEC_CTRL MSR value for the current task, which may differ * from x86_spec_ctrl_base due to STIBP/SSB in __speculation_ctrl_update(). */ -void write_spec_ctrl_current (u64 val) +void write_spec_ctrl_current (u64 val,bool force) {if (this_cpu_read (x86_spec_ctrl_current) == val)return ;this_cpu_write (x86_spec_ctrl_current, val); -wrmsrl (MSR_IA32_SPEC_CTRL , val); + +/* +* When KERNEL_IBRS this MSR is written on return-to-user, unless +* forced the update can be delayed until that time. +*/ +if (force || !cpu_feature_enabled (X86_FEATURE_KERNEL_IBRS )) +wrmsrl (MSR_IA32_SPEC_CTRL , val); }/*
@@ -1290,7 +1296,7 @@ static void __init spectre_v2_select_mitif (spectre_v2_in_eibrs_mode (mode)) {/* Force it so VMEXIT will restore correctly */ x86_spec_ctrl_base |=SPEC_CTRL_IBRS ; -write_spec_ctrl_current (x86_spec_ctrl_base); +write_spec_ctrl_current (x86_spec_ctrl_base, true); }switch (mode) {
@@ -1345,7 +1351,7 @@ static void __init spectre_v2_select_mitstatic void update_stibp_msr (void * __unused) { -write_spec_ctrl_current (x86_spec_ctrl_base); +write_spec_ctrl_current (x86_spec_ctrl_base, true); }/* Update x86_spec_ctrl_base in case SMT state changed. */
@@ -1588,7 +1594,7 @@ static enum ssb_mitigation __init __ssb_x86_amd_ssb_disable (); }else { x86_spec_ctrl_base |=SPEC_CTRL_SSBD ; -write_spec_ctrl_current (x86_spec_ctrl_base); +write_spec_ctrl_current (x86_spec_ctrl_base, true); } }
@@ -1839,7 +1845,7 @@ int arch_prctl_spec_ctrl_get(struct taskvoid x86_spec_ctrl_setup_ap (void ) {if (boot_cpu_has (X86_FEATURE_MSR_SPEC_CTRL )) -write_spec_ctrl_current (x86_spec_ctrl_base); +write_spec_ctrl_current (x86_spec_ctrl_base, true);if (ssb_mode ==SPEC_STORE_BYPASS_DISABLE )x86_amd_ssb_disable ();
arch/x86/kernel/process.c +1 -1
@@ -584,7 +584,7 @@ static __always_inline void __speculatio }if (updmsr) -write_spec_ctrl_current (msr); +write_spec_ctrl_current (msr, false); }static unsigned long speculation_ctrl_update_tif (struct task_struct *tsk)
Greg Kroah-Hartman
maintainerPATCH 48/78 x86/speculation: Add spectre_v2=ibrs option to support Kernel IBRS
In reply to Greg Kroah-HartmanFrom: Pawan Gupta <[email protected]>
commit 7c693f54c873691a4b7da05c7e0f74e67745d144 upstream.
Extend spectre_v2= boot option with Kernel IBRS.
[jpoimboe: no STIBP with IBRS]
--- Documentation/admin-guide/kernel-parameters.txt | 1 arch/x86/include/asm/nospec-branch.h | 1 arch/x86/kernel/cpu/bugs.c | 66 ++++++++++++++++++------ 3 files changed, 54 insertions(+), 14 deletions(-)
Documentation/admin-guide/kernel-parameters.txt +1 -0
@@ -5335,6 +5335,7 @@ eibrs - enhanced IBRS eibrs,retpoline - enhanced IBRS + Retpolines eibrs,lfence - enhanced IBRS + LFENCE + ibrs - use IBRS to protect kernel Not specifying this option is equivalent to spectre_v2=auto.
arch/x86/include/asm/nospec-branch.h +1 -0
@@ -212,6 +212,7 @@ enum spectre_v2_mitigation {SPECTRE_V2_EIBRS ,SPECTRE_V2_EIBRS_RETPOLINE ,SPECTRE_V2_EIBRS_LFENCE , + SPECTRE_V2_IBRS, };/* The indirect branch speculation control variants */
arch/x86/kernel/cpu/bugs.c +52 -14
148 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 49/78 x86/bugs: Split spectre_v2_select_mitigation() and spectre_v2_user_select_mitigation()
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 166115c08a9b0b846b783088808a27d739be6e8d upstream.
retbleed will depend on spectre_v2, while spectre_v2_user depends on retbleed. Break this cycle.
--- arch/x86/kernel/cpu/bugs.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-)
arch/x86/kernel/cpu/bugs.c +17 -8
@@ -37,8 +37,9 @@#include "cpu.h" static void __init spectre_v1_select_mitigation (void ); -static void __init retbleed_select_mitigation (void );static void __init spectre_v2_select_mitigation (void ); +static void __init retbleed_select_mitigation (void ); +static void __init spectre_v2_user_select_mitigation (void );static void __init ssb_select_mitigation (void );static void __init l1tf_select_mitigation (void );static void __init mds_select_mitigation (void );
@@ -145,13 +146,19 @@ void __init check_bugs(void)/* Select the proper CPU mitigations before patching alternatives: */ spectre_v1_select_mitigation (); +spectre_v2_select_mitigation (); +/* +* retbleed_select_mitigation() relies on the state set by +* spectre_v2_select_mitigation(); specifically it wants to know about +* spectre_v2=ibrs. +*/ retbleed_select_mitigation ();/* -* spectre_v2_select_mitigation() relies on the state set by +* spectre_v2_user_select_mitigation() relies on the state set by * retbleed_select_mitigation(); specifically the STIBP selection is * forced for UNRET. */ -spectre_v2_select_mitigation (); +spectre_v2_user_select_mitigation ();ssb_select_mitigation ();l1tf_select_mitigation ();md_clear_select_mitigation ();
@@ -1006,13 +1013,15 @@ static void __init spec_v2_user_print_copr_info ("spectre_v2_user=%s forced on command line.\n" , reason); } +static __ro_after_init enum spectre_v2_mitigation_cmd spectre_v2_cmd; +static enum spectre_v2_user_cmd __init -spectre_v2_parse_user_cmdline (enum spectre_v2_mitigation_cmd v2_cmd) +spectre_v2_parse_user_cmdline (void ) {char arg[20 ];int ret, i; -switch (v2_cmd) { +switch (spectre_v2_cmd) {case SPECTRE_V2_CMD_NONE :return SPECTRE_V2_USER_CMD_NONE ;case SPECTRE_V2_CMD_FORCE :
@@ -1047,7 +1056,7 @@ static inline bool spectre_v2_in_ibrs_mo }static void __init -spectre_v2_user_select_mitigation (enum spectre_v2_mitigation_cmd v2_cmd) +spectre_v2_user_select_mitigation (void ) {enum spectre_v2_user_mitigation mode =SPECTRE_V2_USER_NONE ;bool smt_possible =IS_ENABLED (CONFIG_SMP );
@@ -1060,7 +1069,7 @@ spectre_v2_user_select_mitigation(enum s cpu_smt_control == CPU_SMT_NOT_SUPPORTED) smt_possible = false; - cmd =spectre_v2_parse_user_cmdline (v2_cmd); + cmd =spectre_v2_parse_user_cmdline ();switch (cmd) {case SPECTRE_V2_USER_CMD_NONE : goto set_mode;
@@ -1384,7 +1393,7 @@ static void __init spectre_v2_select_mit }/* Set up IBPB and STIBP depending on the general spectre V2 command */ -spectre_v2_user_select_mitigation (cmd); + spectre_v2_cmd = cmd; }static void update_stibp_msr (void * __unused)
Greg Kroah-Hartman
maintainerPATCH 50/78 x86/bugs: Report Intel retbleed vulnerability
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 6ad0ad2bf8a67e27d1f9d006a1dabb0e1c360cc3 upstream.
Skylake suffers from RSB underflow speculation issues; report this vulnerability and it's mitigation (spectre_v2=ibrs).
[jpoimboe: cleanups, eibrs]
--- arch/x86/include/asm/msr-index.h | 1 + arch/x86/kernel/cpu/bugs.c | 39 +++++++++++++++++++++++++++++++++------ arch/x86/kernel/cpu/common.c | 24 ++++++++++++------------ 3 files changed, 46 insertions(+), 18 deletions(-)
arch/x86/include/asm/msr-index.h +1 -0
@@ -91,6 +91,7 @@#define MSR_IA32_ARCH_CAPABILITIES 0x0000010a#define ARCH_CAP_RDCL_NO BIT(0)/* Not susceptible to Meltdown */ #define ARCH_CAP_IBRS_ALL BIT(1)/* Enhanced IBRS support */ +#define ARCH_CAP_RSBA BIT(2)/* RET may use alternative branch predictors */ #define ARCH_CAP_SKIP_VMENTRY_L1DFLUSH BIT(3)/* Skip L1D flush on vmentry */ #define ARCH_CAP_SSB_NO BIT(4)/* * Not susceptible to Speculative Store Bypass
arch/x86/kernel/cpu/bugs.c +33 -6
@@ -783,12 +783,17 @@ static int __init nospectre_v1_cmdline(c }early_param ("nospectre_v1" , nospectre_v1_cmdline); +static enum spectre_v2_mitigation spectre_v2_enabled__ro_after_init = +SPECTRE_V2_NONE ; +#undef pr_fmt#define pr_fmt (fmt) "RETBleed: " fmtenum retbleed_mitigation {RETBLEED_MITIGATION_NONE ,RETBLEED_MITIGATION_UNRET , +RETBLEED_MITIGATION_IBRS , +RETBLEED_MITIGATION_EIBRS , };enum retbleed_mitigation_cmd {
@@ -800,6 +805,8 @@ enum retbleed_mitigation_cmd {const char *const retbleed_strings[] = { [RETBLEED_MITIGATION_NONE ] ="Vulnerable" , [RETBLEED_MITIGATION_UNRET ] ="Mitigation: untrained return thunk" , + [RETBLEED_MITIGATION_IBRS ] ="Mitigation: IBRS" , + [RETBLEED_MITIGATION_EIBRS ] ="Mitigation: Enhanced IBRS" , }; static enum retbleed_mitigation retbleed_mitigation __ro_after_init =
@@ -842,6 +849,7 @@ early_param("retbleed", retbleed_parse_c#define RETBLEED_UNTRAIN_MSG "WARNING: BTB untrained return thunk mitigation is only effective on AMD/Hygon!\n"#define RETBLEED_COMPILER_MSG "WARNING: kernel not compiled with RETPOLINE or -mfunction-return capable compiler!\n" +#define RETBLEED_INTEL_MSG "WARNING: Spectre v2 mitigation leaves CPU vulnerable to RETBleed attacks, data leaks possible!\n"static void __init retbleed_select_mitigation (void ) {
@@ -858,12 +866,15 @@ static void __init retbleed_select_mitigcase RETBLEED_CMD_AUTO :default : -if (!boot_cpu_has_bug (X86_BUG_RETBLEED )) -break ; -if (boot_cpu_data.x86_vendor ==X86_VENDOR_AMD || boot_cpu_data.x86_vendor ==X86_VENDOR_HYGON ) retbleed_mitigation =RETBLEED_MITIGATION_UNRET ; + +/* +* The Intel mitigation (IBRS) was already selected in +* spectre_v2_select_mitigation(). +*/ +break ; }
@@ -893,15 +904,31 @@ static void __init retbleed_select_mitigbreak ; } +/* +* Let IBRS trump all on Intel without affecting the effects of the +* retbleed= cmdline option. +*/ +if (boot_cpu_data.x86_vendor ==X86_VENDOR_INTEL ) { +switch (spectre_v2_enabled) { +case SPECTRE_V2_IBRS : + retbleed_mitigation =RETBLEED_MITIGATION_IBRS ; +break ; +case SPECTRE_V2_EIBRS : +case SPECTRE_V2_EIBRS_RETPOLINE : +case SPECTRE_V2_EIBRS_LFENCE : + retbleed_mitigation =RETBLEED_MITIGATION_EIBRS ; +break ; +default : +pr_err (RETBLEED_INTEL_MSG ); + } + } +pr_info ("%s\n" , retbleed_strings[retbleed_mitigation]); }#undef pr_fmt#define pr_fmt (fmt) "Spectre V2 : " fmt -static enum spectre_v2_mitigation spectre_v2_enabled__ro_after_init = -SPECTRE_V2_NONE ; -static enum spectre_v2_user_mitigation spectre_v2_user_stibp__ro_after_init =SPECTRE_V2_USER_NONE ; static enum spectre_v2_user_mitigation spectre_v2_user_ibpb __ro_after_init =
arch/x86/kernel/cpu/common.c +12 -12
@@ -1127,24 +1127,24 @@ static const struct x86_cpu_id cpu_vuln_VULNBL_INTEL_STEPPINGS (BROADWELL_G ,X86_STEPPING_ANY ,SRBDS ),VULNBL_INTEL_STEPPINGS (BROADWELL_X ,X86_STEPPING_ANY ,MMIO ),VULNBL_INTEL_STEPPINGS (BROADWELL ,X86_STEPPING_ANY ,SRBDS ), -VULNBL_INTEL_STEPPINGS (SKYLAKE_L ,X86_STEPPINGS (0x3 ,0x3 ),SRBDS |MMIO ), +VULNBL_INTEL_STEPPINGS (SKYLAKE_L ,X86_STEPPINGS (0x3 ,0x3 ),SRBDS |MMIO |RETBLEED ),VULNBL_INTEL_STEPPINGS (SKYLAKE_L ,X86_STEPPING_ANY ,SRBDS ),VULNBL_INTEL_STEPPINGS (SKYLAKE_X ,BIT (3 ) |BIT (4 ) |BIT (6 ) | -BIT (7 ) |BIT (0xB ),MMIO ), -VULNBL_INTEL_STEPPINGS (SKYLAKE ,X86_STEPPINGS (0x3 ,0x3 ),SRBDS |MMIO ), +BIT (7 ) |BIT (0xB ),MMIO |RETBLEED ), +VULNBL_INTEL_STEPPINGS (SKYLAKE ,X86_STEPPINGS (0x3 ,0x3 ),SRBDS |MMIO |RETBLEED ),VULNBL_INTEL_STEPPINGS (SKYLAKE ,X86_STEPPING_ANY ,SRBDS ), -VULNBL_INTEL_STEPPINGS (KABYLAKE_L ,X86_STEPPINGS (0x9 ,0xC ),SRBDS |MMIO ), +VULNBL_INTEL_STEPPINGS (KABYLAKE_L ,X86_STEPPINGS (0x9 ,0xC ),SRBDS |MMIO |RETBLEED ),VULNBL_INTEL_STEPPINGS (KABYLAKE_L ,X86_STEPPINGS (0x0 ,0x8 ),SRBDS ), -VULNBL_INTEL_STEPPINGS (KABYLAKE ,X86_STEPPINGS (0x9 ,0xD ),SRBDS |MMIO ), +VULNBL_INTEL_STEPPINGS (KABYLAKE ,X86_STEPPINGS (0x9 ,0xD ),SRBDS |MMIO |RETBLEED ),VULNBL_INTEL_STEPPINGS (KABYLAKE ,X86_STEPPINGS (0x0 ,0x8 ),SRBDS ), -VULNBL_INTEL_STEPPINGS (ICELAKE_L ,X86_STEPPINGS (0x5 ,0x5 ),MMIO |MMIO_SBDS ), +VULNBL_INTEL_STEPPINGS (ICELAKE_L ,X86_STEPPINGS (0x5 ,0x5 ),MMIO |MMIO_SBDS |RETBLEED ),VULNBL_INTEL_STEPPINGS (ICELAKE_D ,X86_STEPPINGS (0x1 ,0x1 ),MMIO ),VULNBL_INTEL_STEPPINGS (ICELAKE_X ,X86_STEPPINGS (0x4 ,0x6 ),MMIO ), -VULNBL_INTEL_STEPPINGS (COMETLAKE ,BIT (2 ) |BIT (3 ) |BIT (5 ),MMIO |MMIO_SBDS ), -VULNBL_INTEL_STEPPINGS (COMETLAKE_L ,X86_STEPPINGS (0x1 ,0x1 ),MMIO |MMIO_SBDS ), -VULNBL_INTEL_STEPPINGS (COMETLAKE_L ,X86_STEPPINGS (0x0 ,0x0 ),MMIO ), -VULNBL_INTEL_STEPPINGS (LAKEFIELD ,X86_STEPPINGS (0x1 ,0x1 ),MMIO |MMIO_SBDS ), -VULNBL_INTEL_STEPPINGS (ROCKETLAKE ,X86_STEPPINGS (0x1 ,0x1 ),MMIO ), +VULNBL_INTEL_STEPPINGS (COMETLAKE ,BIT (2 ) |BIT (3 ) |BIT (5 ),MMIO |MMIO_SBDS |RETBLEED ), +VULNBL_INTEL_STEPPINGS (COMETLAKE_L ,X86_STEPPINGS (0x1 ,0x1 ),MMIO |MMIO_SBDS |RETBLEED ), +VULNBL_INTEL_STEPPINGS (COMETLAKE_L ,X86_STEPPINGS (0x0 ,0x0 ),MMIO |RETBLEED ), +VULNBL_INTEL_STEPPINGS (LAKEFIELD ,X86_STEPPINGS (0x1 ,0x1 ),MMIO |MMIO_SBDS |RETBLEED ), +VULNBL_INTEL_STEPPINGS (ROCKETLAKE ,X86_STEPPINGS (0x1 ,0x1 ),MMIO |RETBLEED ),VULNBL_INTEL_STEPPINGS (ATOM_TREMONT ,X86_STEPPINGS (0x1 ,0x1 ),MMIO |MMIO_SBDS ),VULNBL_INTEL_STEPPINGS (ATOM_TREMONT_D ,X86_STEPPING_ANY ,MMIO ), VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L, X86_STEPPINGS(0x0, 0x0), MMIO | MMIO_SBDS),
@@ -1254,7 +1254,7 @@ static void __init cpu_set_bug_bits(stru !arch_cap_mmio_immune(ia32_cap))setup_force_cpu_bug (X86_BUG_MMIO_STALE_DATA ); -if (cpu_matches (cpu_vuln_blacklist,RETBLEED )) +if ((cpu_matches (cpu_vuln_blacklist,RETBLEED ) || (ia32_cap &ARCH_CAP_RSBA )))setup_force_cpu_bug (X86_BUG_RETBLEED );if (cpu_matches (cpu_vuln_whitelist,NO_MELTDOWN ))
Greg Kroah-Hartman
maintainerPATCH 51/78 intel_idle: Disable IBRS during long idle
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit bf5835bcdb9635c97f85120dba9bfa21e111130f upstream.
Having IBRS enabled while the SMT sibling is idle unnecessarily slows down the running sibling. OTOH, disabling IBRS around idle takes two MSR writes, which will increase the idle latency.
Therefore, only disable IBRS around deeper idle states. Shallow idle states are bounded by the tick in duration, since NOHZ is not allowed for them by virtue of their short target residency.
Only do this for mwait-driven idle, since that keeps interrupts disabled across idle, which makes disabling IBRS vs IRQ-entry a non-issue.
Note: C6 is a random threshold, most importantly C1 probably shouldn't disable IBRS, benchmarking needed.
--- arch/x86/include/asm/nospec-branch.h | 1 arch/x86/kernel/cpu/bugs.c | 6 ++++ drivers/idle/intel_idle.c | 43 ++++++++++++++++++++++++++++++----- 3 files changed, 44 insertions(+), 6 deletions(-)
arch/x86/include/asm/nospec-branch.h +1 -0
@@ -256,6 +256,7 @@ static inline void indirect_branch_predi/* The Intel SPEC CTRL MSR base value cache */ extern u64 x86_spec_ctrl_base;extern void write_spec_ctrl_current (u64 val,bool force); +extern u64 spec_ctrl_current (void );/* * With retpoline, we must use IBRS to restrict branch prediction
arch/x86/kernel/cpu/bugs.c +6 -0
@@ -79,6 +79,12 @@ void write_spec_ctrl_current(u64 val, bowrmsrl (MSR_IA32_SPEC_CTRL , val); } +u64 spec_ctrl_current (void ) +{ +return this_cpu_read (x86_spec_ctrl_current); +} +EXPORT_SYMBOL_GPL (spec_ctrl_current); +/* * The vendor and possibly platform specific bits which can be modified in * x86_spec_ctrl_base.
drivers/idle/intel_idle.c +37 -6
108 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 52/78 objtool: Update Retpoline validation
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 9bb2ec608a209018080ca262f771e6a9ff203b6f upstream.
Update retpoline validation with the new CONFIG_RETPOLINE requirement of not having bare naked RET instructions.
--- arch/x86/include/asm/nospec-branch.h | 6 ++++++ arch/x86/mm/mem_encrypt_boot.S | 2 ++ arch/x86/xen/xen-head.S | 1 + tools/objtool/check.c | 19 +++++++++++++------ 4 files changed, 22 insertions(+), 6 deletions(-)
arch/x86/include/asm/nospec-branch.h +6 -0
@@ -76,6 +76,12 @@ .endm/* +* (ab)use RETPOLINE_SAFE on RET to annotate away 'bare' RET instructions +* vs RETBleed validation. +*/ +#define ANNOTATE_UNRET_SAFE ANNOTATE_RETPOLINE_SAFE + +/* * JMP_NOSPEC and CALL_NOSPEC macros can be used instead of a simple * indirect jmp/call which may be susceptible to the Spectre variant 2 * attack.
arch/x86/mm/mem_encrypt_boot.S +2 -0
@@ -66,6 +66,7 @@ SYM_FUNC_START(sme_encrypt_execute) pop %rbp /* Offset to __x86_return_thunk would be wrong here */ + ANNOTATE_UNRET_SAFE ret int3 SYM_FUNC_END(sme_encrypt_execute)
@@ -154,6 +155,7 @@ SYM_FUNC_START(__enc_copy) pop %r15 /* Offset to __x86_return_thunk would be wrong here */ + ANNOTATE_UNRET_SAFE ret int3 .L__enc_copy_end:
arch/x86/xen/xen-head.S +1 -0
@@ -70,6 +70,7 @@ SYM_CODE_START(hypercall_page) .rept (PAGE_SIZE / 32) UNWIND_HINT_FUNC .skip 31, 0x90 + ANNOTATE_UNRET_SAFE RET .endr
tools/objtool/check.c +13 -6
@@ -1894,8 +1894,9 @@ static int read_retpoline_hints(struct o }if (insn->type !=INSN_JUMP_DYNAMIC && - insn->type !=INSN_CALL_DYNAMIC ) { -WARN_FUNC ("retpoline_safe hint not an indirect jump/call" , + insn->type !=INSN_CALL_DYNAMIC && + insn->type !=INSN_RETURN ) { +WARN_FUNC ("retpoline_safe hint not an indirect jump/call/ret" , insn->sec, insn->offset);return -1 ; }
@@ -3229,7 +3230,8 @@ static int validate_retpoline(struct objfor_each_insn (file, insn) {if (insn->type !=INSN_JUMP_DYNAMIC && - insn->type !=INSN_CALL_DYNAMIC ) + insn->type !=INSN_CALL_DYNAMIC && + insn->type !=INSN_RETURN )continue ;if (insn->retpoline_safe)
@@ -3244,9 +3246,14 @@ static int validate_retpoline(struct objif (!strcmp (insn->sec->name,".init.text" ) && !module)continue ; -WARN_FUNC ("indirect %s found in RETPOLINE build" , - insn->sec, insn->offset, - insn->type ==INSN_JUMP_DYNAMIC ?"jump" :"call" ); +if (insn->type ==INSN_RETURN ) { +WARN_FUNC ("'naked' return found in RETPOLINE build" , + insn->sec, insn->offset); + }else { +WARN_FUNC ("indirect %s found in RETPOLINE build" , + insn->sec, insn->offset, + insn->type ==INSN_JUMP_DYNAMIC ?"jump" :"call" ); + } warnings++; }
Greg Kroah-Hartman
maintainerPATCH 53/78 x86/xen: Rename SYS* entry points
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit b75b7f8ef1148be1b9321ffc2f6c19238904b438 upstream.
Native SYS{CALL,ENTER} entry points are called entry_SYS{CALL,ENTER}_{64,compat}, make sure the Xen versions are named consistently.
--- arch/x86/xen/setup.c | 6 +++--- arch/x86/xen/xen-asm.S | 20 ++++++++++---------- arch/x86/xen/xen-ops.h | 6 +++--- 3 files changed, 16 insertions(+), 16 deletions(-)
arch/x86/xen/setup.c +3 -3
@@ -922,7 +922,7 @@ void xen_enable_sysenter(void)if (!boot_cpu_has (sysenter_feature))return ; - ret =register_callback (CALLBACKTYPE_sysenter, xen_sysenter_target); + ret =register_callback (CALLBACKTYPE_sysenter, xen_entry_SYSENTER_compat);if (ret !=0 )setup_clear_cpu_cap (sysenter_feature); }
@@ -931,7 +931,7 @@ void xen_enable_syscall(void) {int ret; - ret =register_callback (CALLBACKTYPE_syscall, xen_syscall_target); + ret =register_callback (CALLBACKTYPE_syscall, xen_entry_SYSCALL_64);if (ret !=0 ) {printk (KERN_ERR "Failed to set syscall callback: %d\n" , ret);/* Pretty fatal; 64-bit userspace has no other
@@ -940,7 +940,7 @@ void xen_enable_syscall(void)if (boot_cpu_has (X86_FEATURE_SYSCALL32 )) { ret =register_callback (CALLBACKTYPE_syscall32, - xen_syscall32_target); + xen_entry_SYSCALL_compat);if (ret !=0 )setup_clear_cpu_cap (X86_FEATURE_SYSCALL32 ); }
arch/x86/xen/xen-asm.S +10 -10
@@ -227,7 +227,7 @@ SYM_CODE_END(xenpv_restore_regs_and_retu */ /* Normal 64-bit system call target */ -SYM_CODE_START(xen_syscall_target) +SYM_CODE_START(xen_entry_SYSCALL_64) UNWIND_HINT_EMPTY popq %rcx popq %r11
@@ -241,12 +241,12 @@ SYM_CODE_START(xen_syscall_target) movq $__USER_CS, 1*8(%rsp) jmp entry_SYSCALL_64_after_hwframe -SYM_CODE_END(xen_syscall_target) +SYM_CODE_END(xen_entry_SYSCALL_64) #ifdef CONFIG_IA32_EMULATION /* 32-bit compat syscall target */ -SYM_CODE_START(xen_syscall32_target) +SYM_CODE_START(xen_entry_SYSCALL_compat) UNWIND_HINT_EMPTY popq %rcx popq %r11
@@ -260,10 +260,10 @@ SYM_CODE_START(xen_syscall32_target) movq $__USER32_CS, 1*8(%rsp) jmp entry_SYSCALL_compat_after_hwframe -SYM_CODE_END(xen_syscall32_target) +SYM_CODE_END(xen_entry_SYSCALL_compat) /* 32-bit compat sysenter target */ -SYM_CODE_START(xen_sysenter_target) +SYM_CODE_START(xen_entry_SYSENTER_compat) UNWIND_HINT_EMPTY /* * NB: Xen is polite and clears TF from EFLAGS for us. This means
@@ -281,18 +281,18 @@ SYM_CODE_START(xen_sysenter_target) movq $__USER32_CS, 1*8(%rsp) jmp entry_SYSENTER_compat_after_hwframe -SYM_CODE_END(xen_sysenter_target) +SYM_CODE_END(xen_entry_SYSENTER_compat) #else /* !CONFIG_IA32_EMULATION */ -SYM_CODE_START(xen_syscall32_target) -SYM_CODE_START(xen_sysenter_target) +SYM_CODE_START(xen_entry_SYSCALL_compat) +SYM_CODE_START(xen_entry_SYSENTER_compat) UNWIND_HINT_EMPTY lea 16(%rsp), %rsp /* strip %rcx, %r11 */ mov $-ENOSYS, %rax pushq $0 jmp hypercall_iret -SYM_CODE_END(xen_sysenter_target) -SYM_CODE_END(xen_syscall32_target) +SYM_CODE_END(xen_entry_SYSENTER_compat) +SYM_CODE_END(xen_entry_SYSCALL_compat) #endif /* CONFIG_IA32_EMULATION */
arch/x86/xen/xen-ops.h +3 -3
@@ -10,10 +10,10 @@/* These are code, but not functions. Defined in entry.S */ extern const char xen_failsafe_callback[]; -void xen_sysenter_target (void ); +void xen_entry_SYSENTER_compat (void );#ifdef CONFIG_X86_64 -void xen_syscall_target (void ); -void xen_syscall32_target (void ); +void xen_entry_SYSCALL_64 (void ); +void xen_entry_SYSCALL_compat (void );#endif extern void *xen_initial_gdt;
Greg Kroah-Hartman
maintainerPATCH 54/78 x86/xen: Add UNTRAIN_RET
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit d147553b64bad34d2f92cb7d8ba454ae95c3baac upstream.
Ensure the Xen entry also passes through UNTRAIN_RET.
--- arch/x86/entry/entry_64.S | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
arch/x86/entry/entry_64.S +7 -1
@@ -320,6 +320,12 @@ SYM_CODE_END(ret_from_fork) #endif .endm +SYM_CODE_START_LOCAL(xen_error_entry) + UNWIND_HINT_FUNC + UNTRAIN_RET + RET +SYM_CODE_END(xen_error_entry) + /** * idtentry_body - Macro to emit code calling the C function * @cfunc: C function to be called
@@ -339,7 +345,7 @@ SYM_CODE_END(ret_from_fork) * switch the CR3. So it can skip invoking error_entry(). */ ALTERNATIVE "call error_entry; movq %rax, %rsp", \ - "", X86_FEATURE_XENPV + "call xen_error_entry", X86_FEATURE_XENPV ENCODE_FRAME_POINTER UNWIND_HINT_REGS
Greg Kroah-Hartman
maintainerPATCH 55/78 x86/bugs: Add retbleed=ibpb
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 3ebc170068885b6fc7bedda6c667bb2c4d533159 upstream.
jmp2ret mitigates the easy-to-attack case at relatively low overhead. It mitigates the long speculation windows after a mispredicted RET, but it does not mitigate the short speculation window from arbitrary instruction boundaries.
On Zen2, there is a chicken bit which needs setting, which mitigates "arbitrary instruction boundaries" down to just "basic block boundaries".
But there is no fix for the short speculation window on basic block boundaries, other than to flush the entire BTB to evict all attacker predictions.
On the spectrum of "fast & blurry" -> "safe", there is (on top of STIBP or no-SMT):
1) Nothing System wide open
2) jmp2ret May stop a script kiddy
3) jmp2ret+chickenbit Raises the bar rather further
4) IBPB Only thing which can count as "safe".
Tentative numbers put IBPB-on-entry at a 2.5x hit on Zen2, and a 10x hit on Zen1 according to lmbench.
[ bp: Fixup feature bit comments, document option, 32-bit build fix. ]
--- Documentation/admin-guide/kernel-parameters.txt | 3 + arch/x86/entry/Makefile | 2 - arch/x86/entry/entry.S | 22 ++++++++++++ arch/x86/include/asm/cpufeatures.h | 2 - arch/x86/include/asm/nospec-branch.h | 8 +++- arch/x86/kernel/cpu/bugs.c | 43 ++++++++++++++++++------ 6 files changed, 67 insertions(+), 13 deletions(-) create mode 100644 arch/x86/entry/entry.S
Documentation/admin-guide/kernel-parameters.txt +3 -0
@@ -4978,6 +4978,9 @@ disabling SMT if necessary for the full mitigation (only on Zen1 and older without STIBP). + ibpb - mitigate short speculation windows on + basic block boundaries too. Safe, highest + perf impact. unret - force enable untrained return thunks, only effective on AMD f15h-f17h based systems.
arch/x86/entry/Makefile +1 -1
@@ -11,7 +11,7 @@ CFLAGS_REMOVE_common.o = $(CC_FLAGS_FTR CFLAGS_common.o += -fno-stack-protector -obj-y := entry_$(BITS).o thunk_$(BITS).o syscall_$(BITS).o +obj-y := entry.o entry_$(BITS).o thunk_$(BITS).o syscall_$(BITS).o obj-y += common.o obj-y += vdso/
arch/x86/entry/entry.S new file +22 -0
@@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Common place for both 32- and 64-bit entry routines. + */ + +#include <linux/linkage.h> +#include <asm/export.h> +#include <asm/msr-index.h> + +.pushsection .noinstr.text, "ax" + +SYM_FUNC_START(entry_ibpb) + movl $MSR_IA32_PRED_CMD, %ecx + movl $PRED_CMD_IBPB, %eax + xorl %edx, %edx + wrmsr + RET +SYM_FUNC_END(entry_ibpb) +/* For KVM */ +EXPORT_SYMBOL_GPL(entry_ibpb); + +.popsection
arch/x86/include/asm/cpufeatures.h +1 -1
@@ -294,7 +294,7 @@#define X86_FEATURE_PER_THREAD_MBA (11*32+ 7)/* "" Per-thread Memory Bandwidth Allocation */ #define X86_FEATURE_SGX1 (11*32+ 8)/* "" Basic SGX */ #define X86_FEATURE_SGX2 (11*32+ 9)/* "" SGX Enclave Dynamic Memory Management (EDMM) */ -/* FREE! (11*32+10) */ +#define X86_FEATURE_ENTRY_IBPB (11*32+10)/* "" Issue an IBPB on kernel entry */ /* FREE! (11*32+11) */ #define X86_FEATURE_RETPOLINE (11*32+12)/* "" Generic Retpoline mitigation for Spectre variant 2 */ #define X86_FEATURE_RETPOLINE_LFENCE (11*32+13)/* "" Use LFENCE for Spectre variant 2 */
arch/x86/include/asm/nospec-branch.h +6 -2
@@ -123,14 +123,17 @@* return thunk isn't mapped into the userspace tables (then again, AMD * typically has NO_MELTDOWN). * -* Doesn't clobber any registers but does require a stable stack. +* While zen_untrain_ret() doesn't clobber anything but requires stack, +* entry_ibpb() will clobber AX, CX, DX. * * As such, this must be placed after every *SWITCH_TO_KERNEL_CR3 at a point * where we have a stack but before any RET instruction. */ .macro UNTRAIN_RET#ifdef CONFIG_RETPOLINE -ALTERNATIVE "" ,"call zen_untrain_ret" ,X86_FEATURE_UNRET +ALTERNATIVE_2 "" , \ +"call zen_untrain_ret" ,X86_FEATURE_UNRET , \ +"call entry_ibpb" ,X86_FEATURE_ENTRY_IBPB #endif .endm
@@ -144,6 +147,7 @@extern void __x86_return_thunk (void );extern void zen_untrain_ret (void ); +extern void entry_ibpb (void );#ifdef CONFIG_RETPOLINE
arch/x86/kernel/cpu/bugs.c +34 -9
105 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 56/78 x86/bugs: Do IBPB fallback check only once
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit 0fe4aeea9c01baabecc8c3afc7889c809d939bc2 upstream.
When booting with retbleed=auto, if the kernel wasn't built with CONFIG_CC_HAS_RETURN_THUNK, the mitigation falls back to IBPB. Make sure a warning is printed in that case. The IBPB fallback check is done twice, but it really only needs to be done once.
--- arch/x86/kernel/cpu/bugs.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-)
arch/x86/kernel/cpu/bugs.c +5 -10
@@ -884,18 +884,13 @@ static void __init retbleed_select_mitigcase RETBLEED_CMD_AUTO :default :if (boot_cpu_data.x86_vendor ==X86_VENDOR_AMD || - boot_cpu_data.x86_vendor ==X86_VENDOR_HYGON ) { - -if (IS_ENABLED (CONFIG_RETPOLINE ) && -IS_ENABLED (CONFIG_CC_HAS_RETURN_THUNK )) - retbleed_mitigation =RETBLEED_MITIGATION_UNRET ; -else - retbleed_mitigation =RETBLEED_MITIGATION_IBPB ; - } + boot_cpu_data.x86_vendor ==X86_VENDOR_HYGON ) + retbleed_mitigation =RETBLEED_MITIGATION_UNRET ;/* -* The Intel mitigation (IBRS) was already selected in -* spectre_v2_select_mitigation(). +* The Intel mitigation (IBRS or eIBRS) was already selected in +* spectre_v2_select_mitigation(). 'retbleed_mitigation' will +* be set accordingly below. */ break ;
Greg Kroah-Hartman
maintainerPATCH 57/78 objtool: Add entry UNRET validation
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit a09a6e2399ba0595c3042b3164f3ca68a3cff33e upstream.
Since entry asm is tricky, add a validation pass that ensures the retbleed mitigation has been done before the first actual RET instruction.
Entry points are those that either have UNWIND_HINT_ENTRY, which acts as UNWIND_HINT_EMPTY but marks the instruction as an entry point, or those that have UWIND_HINT_IRET_REGS at +0.
This is basically a variant of validate_branch() that is intra-function and it will simply follow all branches from marked entry points and ensures that all paths lead to ANNOTATE_UNRET_END.
If a path hits RET or an indirection the path is a fail and will be reported.
There are 3 ANNOTATE_UNRET_END instances:
- UNTRAIN_RET itself
- exception from-kernel; this path doesn't need UNTRAIN_RET
- all early exceptions; these also don't need UNTRAIN_RET
--- arch/x86/entry/entry_64.S | 3 arch/x86/entry/entry_64_compat.S | 6 - arch/x86/include/asm/nospec-branch.h | 12 ++ arch/x86/include/asm/unwind_hints.h | 4 arch/x86/kernel/head_64.S | 5 arch/x86/xen/xen-asm.S | 10 - include/linux/objtool.h | 3 scripts/link-vmlinux.sh | 3 tools/include/linux/objtool.h | 3 tools/objtool/builtin-check.c | 3 tools/objtool/check.c | 172 +++++++++++++++++++++++++++++++- tools/objtool/include/objtool/builtin.h | 2 tools/objtool/include/objtool/check.h | 6 + 13 files changed, 217 insertions(+), 15 deletions(-)
arch/x86/entry/entry_64.S +2 -1
@@ -85,7 +85,7 @@ */ SYM_CODE_START(entry_SYSCALL_64) - UNWIND_HINT_EMPTY + UNWIND_HINT_ENTRY swapgs /* tss.sp2 is scratch space. */
@@ -1067,6 +1067,7 @@ SYM_CODE_START_LOCAL(error_entry) .Lerror_entry_done_lfence: FENCE_SWAPGS_KERNEL_ENTRY leaq 8(%rsp), %rax /* return pt_regs pointer */ + ANNOTATE_UNRET_END RET .Lbstep_iret:
arch/x86/entry/entry_64_compat.S +3 -3
@@ -49,7 +49,7 @@ * 0(%ebp) arg6 */ SYM_CODE_START(entry_SYSENTER_compat) - UNWIND_HINT_EMPTY + UNWIND_HINT_ENTRY /* Interrupts are off on entry. */ SWAPGS
@@ -202,7 +202,7 @@ SYM_CODE_END(entry_SYSENTER_compat) * 0(%esp) arg6 */ SYM_CODE_START(entry_SYSCALL_compat) - UNWIND_HINT_EMPTY + UNWIND_HINT_ENTRY /* Interrupts are off on entry. */ swapgs
@@ -349,7 +349,7 @@ SYM_CODE_END(entry_SYSCALL_compat) * ebp arg6 */ SYM_CODE_START(entry_INT80_compat) - UNWIND_HINT_EMPTY + UNWIND_HINT_ENTRY /* * Interrupts are off on entry. */
arch/x86/include/asm/nospec-branch.h +12 -0
@@ -82,6 +82,17 @@#define ANNOTATE_UNRET_SAFE ANNOTATE_RETPOLINE_SAFE/* +* Abuse ANNOTATE_RETPOLINE_SAFE on a NOP to indicate UNRET_END, should +* eventually turn into it's own annotation. +*/ +.macro ANNOTATE_UNRET_END +#ifdef CONFIG_DEBUG_ENTRY +ANNOTATE_RETPOLINE_SAFE + nop +#endif +.endm + +/* * JMP_NOSPEC and CALL_NOSPEC macros can be used instead of a simple * indirect jmp/call which may be susceptible to the Spectre variant 2 * attack.
@@ -131,6 +142,7 @@*/ .macro UNTRAIN_RET#ifdef CONFIG_RETPOLINE +ANNOTATE_UNRET_END ALTERNATIVE_2 "", \"call zen_untrain_ret" ,X86_FEATURE_UNRET , \"call entry_ibpb" ,X86_FEATURE_ENTRY_IBPB
arch/x86/include/asm/unwind_hints.h +4 -0
@@ -11,6 +11,10 @@ UNWIND_HINT sp_reg=ORC_REG_UNDEFINED type=UNWIND_HINT_TYPE_CALL end=1 .endm +.macro UNWIND_HINT_ENTRY + UNWIND_HINT sp_reg=ORC_REG_UNDEFINED type=UNWIND_HINT_TYPE_ENTRY end=1 +.endm + .macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0 .if \base == %rsp .if \indirect
arch/x86/kernel/head_64.S +5 -0
@@ -312,6 +312,8 @@ SYM_CODE_END(start_cpu0) SYM_CODE_START_NOALIGN(vc_boot_ghcb) UNWIND_HINT_IRET_REGS offset=8 + ANNOTATE_UNRET_END + /* Build pt_regs */ PUSH_AND_CLEAR_REGS
@@ -369,6 +371,7 @@ SYM_CODE_START(early_idt_handler_array) SYM_CODE_END(early_idt_handler_array) SYM_CODE_START_LOCAL(early_idt_handler_common) + ANNOTATE_UNRET_END /* * The stack is the hardware frame, an error code or zero, and the * vector number.
@@ -415,6 +418,8 @@ SYM_CODE_END(early_idt_handler_common) SYM_CODE_START_NOALIGN(vc_no_ghcb) UNWIND_HINT_IRET_REGS offset=8 + ANNOTATE_UNRET_END + /* Build pt_regs */ PUSH_AND_CLEAR_REGS
arch/x86/xen/xen-asm.S +5 -5
@@ -120,7 +120,7 @@ SYM_FUNC_END(xen_read_cr2_direct); .macro xen_pv_trap name SYM_CODE_START(xen_\name) - UNWIND_HINT_EMPTY + UNWIND_HINT_ENTRY pop %rcx pop %r11 jmp \name
@@ -228,7 +228,7 @@ SYM_CODE_END(xenpv_restore_regs_and_retu /* Normal 64-bit system call target */ SYM_CODE_START(xen_entry_SYSCALL_64) - UNWIND_HINT_EMPTY + UNWIND_HINT_ENTRY popq %rcx popq %r11
@@ -247,7 +247,7 @@ SYM_CODE_END(xen_entry_SYSCALL_64) /* 32-bit compat syscall target */ SYM_CODE_START(xen_entry_SYSCALL_compat) - UNWIND_HINT_EMPTY + UNWIND_HINT_ENTRY popq %rcx popq %r11
@@ -264,7 +264,7 @@ SYM_CODE_END(xen_entry_SYSCALL_compat) /* 32-bit compat sysenter target */ SYM_CODE_START(xen_entry_SYSENTER_compat) - UNWIND_HINT_EMPTY + UNWIND_HINT_ENTRY /* * NB: Xen is polite and clears TF from EFLAGS for us. This means * that we don't need to guard against single step exceptions here.
@@ -287,7 +287,7 @@ SYM_CODE_END(xen_entry_SYSENTER_compat) SYM_CODE_START(xen_entry_SYSCALL_compat) SYM_CODE_START(xen_entry_SYSENTER_compat) - UNWIND_HINT_EMPTY + UNWIND_HINT_ENTRY lea 16(%rsp), %rsp /* strip %rcx, %r11 */ mov $-ENOSYS, %rax pushq $0
include/linux/objtool.h +3 -0
@@ -32,11 +32,14 @@ struct unwind_hint {* * UNWIND_HINT_FUNC: Generate the unwind metadata of a callable function. * Useful for code which doesn't have an ELF function annotation. +* +* UNWIND_HINT_ENTRY: machine entry without stack, SYSCALL/SYSENTER etc. */ #define UNWIND_HINT_TYPE_CALL 0#define UNWIND_HINT_TYPE_REGS 1#define UNWIND_HINT_TYPE_REGS_PARTIAL 2#define UNWIND_HINT_TYPE_FUNC 3 +#define UNWIND_HINT_TYPE_ENTRY 4#ifdef CONFIG_STACK_VALIDATION
scripts/link-vmlinux.sh +3 -0
@@ -120,6 +120,9 @@ objtool_link() if [ -n "${CONFIG_VMLINUX_VALIDATION}" ]; then objtoolopt="${objtoolopt} --noinstr" + if is_enabled CONFIG_RETPOLINE; then + objtoolopt="${objtoolopt} --unret" + fi fi if [ -n "${objtoolopt}" ]; then
tools/include/linux/objtool.h +3 -0
@@ -32,11 +32,14 @@ struct unwind_hint {* * UNWIND_HINT_FUNC: Generate the unwind metadata of a callable function. * Useful for code which doesn't have an ELF function annotation. +* +* UNWIND_HINT_ENTRY: machine entry without stack, SYSCALL/SYSENTER etc. */ #define UNWIND_HINT_TYPE_CALL 0#define UNWIND_HINT_TYPE_REGS 1#define UNWIND_HINT_TYPE_REGS_PARTIAL 2#define UNWIND_HINT_TYPE_FUNC 3 +#define UNWIND_HINT_TYPE_ENTRY 4#ifdef CONFIG_STACK_VALIDATION
tools/objtool/builtin-check.c +2 -1
@@ -20,7 +20,7 @@#include <objtool/objtool.h> bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, - validate_dup, vmlinux, mcount, noinstr, backup, sls; + validate_dup, vmlinux, mcount, noinstr, backup, sls, unret;static const char *const check_usage[] = {"objtool check [<options>] file.o" ,
@@ -36,6 +36,7 @@ const struct option check_options[] = {OPT_BOOLEAN ('f' ,"no-fp" , &no_fp,"Skip frame pointer validation" ),OPT_BOOLEAN ('u' ,"no-unreachable" , &no_unreachable,"Skip 'unreachable instruction' warnings" ),OPT_BOOLEAN ('r' ,"retpoline" , &retpoline,"Validate retpoline assumptions" ), +OPT_BOOLEAN (0 ,"unret" , &unret,"validate entry unret placement" ),OPT_BOOLEAN ('m' ,"module" , &module,"Indicates the object will be part of a kernel module" ),OPT_BOOLEAN ('b' ,"backtrace" , &backtrace,"unwind on error" ), OPT_BOOLEAN('a', "uaccess", &uaccess, "enable uaccess checking"),
tools/objtool/check.c +168 -4
202 lines not on this page · raw message
tools/objtool/include/objtool/builtin.h +1 -1
@@ -9,7 +9,7 @@extern const struct option check_options[];extern bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, - validate_dup, vmlinux, mcount, noinstr, backup, sls; + validate_dup, vmlinux, mcount, noinstr, backup, sls, unret;extern int cmd_parse_options (int argc,const char **argv,const char *const usage[]);
tools/objtool/include/objtool/check.h +6 -0
@@ -48,6 +48,7 @@ struct instruction {bool dead_end, ignore, ignore_alts;bool hint;bool retpoline_safe; +bool entry;s8 instr;u8 visited;struct alt_group *alt_group;
@@ -62,6 +63,11 @@ struct instruction {struct cfi_state *cfi; }; +#define VISITED_BRANCH 0x01 +#define VISITED_BRANCH_UACCESS 0x02 +#define VISITED_BRANCH_MASK 0x03 +#define VISITED_ENTRY 0x04 +static inline bool is_static_jump (struct instruction *insn) { return insn->type == INSN_JUMP_CONDITIONAL ||
Greg Kroah-Hartman
maintainerPATCH 58/78 x86/cpu/amd: Add Spectral Chicken
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit d7caac991feeef1b871ee6988fd2c9725df09039 upstream.
Zen2 uarchs have an undocumented, unnamed, MSR that contains a chicken bit for some speculation behaviour. It needs setting.
Note: very belatedly AMD released naming; it's now officially called
MSR_AMD64_DE_CFG2 and MSR_AMD64_DE_CFG2_SUPPRESS_NOBR_PRED_BIT but shall remain the SPECTRAL CHICKEN.
--- arch/x86/include/asm/msr-index.h | 3 +++ arch/x86/kernel/cpu/amd.c | 23 ++++++++++++++++++++++- arch/x86/kernel/cpu/cpu.h | 2 ++ arch/x86/kernel/cpu/hygon.c | 6 ++++++ 4 files changed, 33 insertions(+), 1 deletion(-)
arch/x86/include/asm/msr-index.h +3 -0
@@ -515,6 +515,9 @@/* Fam 17h MSRs */ #define MSR_F17H_IRPERF 0xc00000e9 +#define MSR_ZEN2_SPECTRAL_CHICKEN 0xc00110e3 +#define MSR_ZEN2_SPECTRAL_CHICKEN_BIT BIT_ULL(1) +/* Fam 16h MSRs */ #define MSR_F16H_L2I_PERF_CTL 0xc0010230#define MSR_F16H_L2I_PERF_CTR 0xc0010231
arch/x86/kernel/cpu/amd.c +22 -1
@@ -886,6 +886,26 @@ static void init_amd_bd(struct cpuinfo_xclear_rdrand_cpuid_bit (c); } +void init_spectral_chicken (struct cpuinfo_x86 *c) +{ +u64 value; + +/* +* On Zen2 we offer this chicken (bit) on the altar of Speculation. +* +* This suppresses speculation from the middle of a basic block, i.e. it +* suppresses non-branch predictions. +* +* We use STIBP as a heuristic to filter out Zen2 from the rest of F17H +*/ +if (!cpu_has (c,X86_FEATURE_HYPERVISOR ) &&cpu_has (c,X86_FEATURE_AMD_STIBP )) { +if (!rdmsrl_safe (MSR_ZEN2_SPECTRAL_CHICKEN , &value)) { + value |=MSR_ZEN2_SPECTRAL_CHICKEN_BIT ; +wrmsrl_safe (MSR_ZEN2_SPECTRAL_CHICKEN , value); + } + } +} +static void init_amd_zn (struct cpuinfo_x86 *c) {set_cpu_cap (c,X86_FEATURE_ZEN );
@@ -931,7 +951,8 @@ static void init_amd(struct cpuinfo_x86case 0x12 :init_amd_ln (c);break ;case 0x15 :init_amd_bd (c);break ;case 0x16 :init_amd_jg (c);break ; -case 0x17 : fallthrough; +case 0x17 :init_spectral_chicken (c); + fallthrough;case 0x19 :init_amd_zn (c);break ; }
arch/x86/kernel/cpu/cpu.h +2 -0
@@ -61,6 +61,8 @@ static inline void tsx_init(void) { }static inline void tsx_ap_init (void ) { }#endif /* CONFIG_CPU_SUP_INTEL */ +extern void init_spectral_chicken (struct cpuinfo_x86 *c); +extern void get_cpu_cap (struct cpuinfo_x86 *c);extern void get_cpu_address_sizes (struct cpuinfo_x86 *c);extern void cpu_detect_cache_sizes (struct cpuinfo_x86 *c);
arch/x86/kernel/cpu/hygon.c +6 -0
@@ -302,6 +302,12 @@ static void init_hygon(struct cpuinfo_x8/* get apicid instead of initial apic id from cpuid */ c->apicid =hard_smp_processor_id (); +/* +* XXX someone from Hygon needs to confirm this DTRT +* +init_spectral_chicken(c); +*/ +set_cpu_cap (c,X86_FEATURE_ZEN );set_cpu_cap (c,X86_FEATURE_CPB );
Greg Kroah-Hartman
maintainerPATCH 59/78 x86/speculation: Fix RSB filling with CONFIG_RETPOLINE=n
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit b2620facef4889fefcbf2e87284f34dcd4189bce upstream.
If a kernel is built with CONFIG_RETPOLINE=n, but the user still wants to mitigate Spectre v2 using IBRS or eIBRS, the RSB filling will be silently disabled.
There's nothing retpoline-specific about RSB buffer filling. Remove the CONFIG_RETPOLINE guards around it.
--- arch/x86/entry/entry_32.S | 2 -- arch/x86/entry/entry_64.S | 2 -- arch/x86/include/asm/nospec-branch.h | 2 -- 3 files changed, 6 deletions(-)
arch/x86/entry/entry_32.S +0 -2
@@ -701,7 +701,6 @@ SYM_CODE_START(__switch_to_asm) movl %ebx, PER_CPU_VAR(__stack_chk_guard) #endif -#ifdef CONFIG_RETPOLINE /* * When switching from a shallower to a deeper call stack * the RSB may either underflow or use entries populated
@@ -710,7 +709,6 @@ SYM_CODE_START(__switch_to_asm) * speculative execution to prevent attack. */ FILL_RETURN_BUFFER %ebx, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_CTXSW -#endif /* Restore flags or the incoming task to restore AC state. */ popfl
arch/x86/entry/entry_64.S +0 -2
@@ -248,7 +248,6 @@ SYM_FUNC_START(__switch_to_asm) movq %rbx, PER_CPU_VAR(fixed_percpu_data) + stack_canary_offset #endif -#ifdef CONFIG_RETPOLINE /* * When switching from a shallower to a deeper call stack * the RSB may either underflow or use entries populated
@@ -257,7 +256,6 @@ SYM_FUNC_START(__switch_to_asm) * speculative execution to prevent attack. */ FILL_RETURN_BUFFER %r12, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_CTXSW -#endif /* restore callee-saved registers */ popq %r15
arch/x86/include/asm/nospec-branch.h +0 -2
@@ -122,11 +122,9 @@* monstrosity above, manually. */ .macro FILL_RETURN_BUFFER reg:req nr:req ftr:req -#ifdef CONFIG_RETPOLINE ALTERNATIVE "jmp .Lskip_rsb_\@", "", \ftr __FILL_RETURN_BUFFER(\reg,\nr,%_ASM_SP) .Lskip_rsb_\@: -#endif .endm/*
Greg Kroah-Hartman
maintainerPATCH 60/78 x86/speculation: Fix firmware entry SPEC_CTRL handling
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit e6aa13622ea8283cc699cac5d018cc40a2ba2010 upstream.
The firmware entry code may accidentally clear STIBP or SSBD. Fix that.
--- arch/x86/include/asm/nospec-branch.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
arch/x86/include/asm/nospec-branch.h +4 -6
@@ -286,18 +286,16 @@ extern u64 spec_ctrl_current(void);*/ #define firmware_restrict_branch_speculation_start () \ do { \ - u64 val = x86_spec_ctrl_base | SPEC_CTRL_IBRS; \ - \ preempt_disable(); \ - alternative_msr_write(MSR_IA32_SPEC_CTRL, val, \ + alternative_msr_write(MSR_IA32_SPEC_CTRL, \ + spec_ctrl_current() | SPEC_CTRL_IBRS, \ X86_FEATURE_USE_IBRS_FW); \ } while (0)#define firmware_restrict_branch_speculation_end () \ do { \ - u64 val = x86_spec_ctrl_base; \ - \ - alternative_msr_write(MSR_IA32_SPEC_CTRL, val, \ + alternative_msr_write(MSR_IA32_SPEC_CTRL, \ + spec_ctrl_current(), \ X86_FEATURE_USE_IBRS_FW); \ preempt_enable(); \ } while (0)
Greg Kroah-Hartman
maintainerPATCH 61/78 x86/speculation: Fix SPEC_CTRL write on SMT state change
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit 56aa4d221f1ee2c3a49b45b800778ec6e0ab73c5 upstream.
If the SMT state changes, SSBD might get accidentally disabled. Fix that.
--- arch/x86/kernel/cpu/bugs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/x86/kernel/cpu/bugs.c +2 -1
@@ -1451,7 +1451,8 @@ static void __init spectre_v2_select_mitstatic void update_stibp_msr (void * __unused) { -write_spec_ctrl_current (x86_spec_ctrl_base, true); +u64 val =spec_ctrl_current () | (x86_spec_ctrl_base &SPEC_CTRL_STIBP ); +write_spec_ctrl_current (val, true); }/* Update x86_spec_ctrl_base in case SMT state changed. */
Greg Kroah-Hartman
maintainerPATCH 62/78 x86/speculation: Use cached host SPEC_CTRL value for guest entry/exit
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit bbb69e8bee1bd882784947095ffb2bfe0f7c9470 upstream.
There's no need to recalculate the host value for every entry/exit. Just use the cached value in spec_ctrl_current().
--- arch/x86/kernel/cpu/bugs.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
arch/x86/kernel/cpu/bugs.c +1 -11
@@ -208,7 +208,7 @@ void __init check_bugs(void)void x86_virt_spec_ctrl (u64 guest_spec_ctrl,u64 guest_virt_spec_ctrl,bool setguest) { -u64 msrval, guestval, hostval = x86_spec_ctrl_base; +u64 msrval, guestval, hostval =spec_ctrl_current ();struct thread_info *ti =current_thread_info ();/* Is MSR_SPEC_CTRL implemented ? */
@@ -221,15 +221,6 @@ x86_virt_spec_ctrl(u64 guest_spec_ctrl, guestval = hostval & ~x86_spec_ctrl_mask; guestval |= guest_spec_ctrl & x86_spec_ctrl_mask; -/* SSBD controlled in MSR_SPEC_CTRL */ -if (static_cpu_has (X86_FEATURE_SPEC_CTRL_SSBD ) || -static_cpu_has (X86_FEATURE_AMD_SSBD )) - hostval |=ssbd_tif_to_spec_ctrl (ti->flags); - -/* Conditional STIBP enabled? */ -if (static_branch_unlikely (&switch_to_cond_stibp)) - hostval |=stibp_tif_to_spec_ctrl (ti->flags); -if (hostval != guestval) { msrval = setguest ? guestval : hostval;wrmsrl (MSR_IA32_SPEC_CTRL , msrval);
@@ -1390,7 +1381,6 @@ static void __init spectre_v2_select_mitpr_err (SPECTRE_V2_EIBRS_EBPF_MSG );if (spectre_v2_in_ibrs_mode (mode)) { -/* Force it so VMEXIT will restore correctly */ x86_spec_ctrl_base |=SPEC_CTRL_IBRS ;write_spec_ctrl_current (x86_spec_ctrl_base, true); }
Greg Kroah-Hartman
maintainerPATCH 63/78 x86/speculation: Remove x86_spec_ctrl_mask
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit acac5e98ef8d638a411cfa2ee676c87e1973f126 upstream.
This mask has been made redundant by kvm_spec_ctrl_test_value(). And it doesn't even work when MSR interception is disabled, as the guest can just write to SPEC_CTRL directly.
--- arch/x86/kernel/cpu/bugs.c | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-)
arch/x86/kernel/cpu/bugs.c +1 -30
@@ -86,12 +86,6 @@ u64 spec_ctrl_current(void)EXPORT_SYMBOL_GPL (spec_ctrl_current);/* -* The vendor and possibly platform specific bits which can be modified in -* x86_spec_ctrl_base. -*/ -static u64 __ro_after_init x86_spec_ctrl_mask =SPEC_CTRL_IBRS ; - -/* * AMD specific MSR info for Speculative Store Bypass control. * x86_amd_ls_cfg_ssbd_mask is initialized in identify_boot_cpu(). */
@@ -146,10 +140,6 @@ void __init check_bugs(void)if (boot_cpu_has (X86_FEATURE_MSR_SPEC_CTRL ))rdmsrl (MSR_IA32_SPEC_CTRL , x86_spec_ctrl_base); -/* Allow STIBP in MSR_SPEC_CTRL if supported */ -if (boot_cpu_has (X86_FEATURE_STIBP )) - x86_spec_ctrl_mask |=SPEC_CTRL_STIBP ; -/* Select the proper CPU mitigations before patching alternatives: */ spectre_v1_select_mitigation ();spectre_v2_select_mitigation ();
@@ -208,19 +198,10 @@ void __init check_bugs(void)void x86_virt_spec_ctrl (u64 guest_spec_ctrl,u64 guest_virt_spec_ctrl,bool setguest) { -u64 msrval, guestval, hostval =spec_ctrl_current (); +u64 msrval, guestval = guest_spec_ctrl, hostval =spec_ctrl_current ();struct thread_info *ti =current_thread_info (); -/* Is MSR_SPEC_CTRL implemented ? */ if (static_cpu_has (X86_FEATURE_MSR_SPEC_CTRL )) { -/* -* Restrict guest_spec_ctrl to supported values. Clear the -* modifiable bits in the host base value and or the -* modifiable bits from the guest value. -*/ - guestval = hostval & ~x86_spec_ctrl_mask; - guestval |= guest_spec_ctrl & x86_spec_ctrl_mask; -if (hostval != guestval) { msrval = setguest ? guestval : hostval;wrmsrl (MSR_IA32_SPEC_CTRL , msrval);
@@ -1659,16 +1640,6 @@ static enum ssb_mitigation __init __ssb_ }/* -* If SSBD is controlled by the SPEC_CTRL MSR, then set the proper -* bit in the mask to allow guests to use the mitigation even in the -* case where the host does not enable it. -*/ -if (static_cpu_has (X86_FEATURE_SPEC_CTRL_SSBD ) || -static_cpu_has (X86_FEATURE_AMD_SSBD )) { - x86_spec_ctrl_mask |=SPEC_CTRL_SSBD ; - } - -/* * We have three CPU feature flags that are in play here: * - X86_BUG_SPEC_STORE_BYPASS - CPU is susceptible. * - X86_FEATURE_SSBD - CPU is able to turn off speculative store bypass
Greg Kroah-Hartman
maintainerPATCH 64/78 objtool: Re-add UNWIND_HINT_{SAVE_RESTORE}
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit 8faea26e611189e933ea2281975ff4dc7c1106b6 upstream.
Commit
c536ed2fffd5 ("objtool: Remove SAVE/RESTORE hints")
removed the save/restore unwind hints because they were no longer needed. Now they're going to be needed again so re-add them.
--- arch/x86/include/asm/unwind_hints.h | 12 ++++++++-- include/linux/objtool.h | 6 +++-- tools/include/linux/objtool.h | 6 +++-- tools/objtool/check.c | 40 ++++++++++++++++++++++++++++++++++ tools/objtool/include/objtool/check.h | 1 5 files changed, 59 insertions(+), 6 deletions(-)
arch/x86/include/asm/unwind_hints.h +10 -2
@@ -8,11 +8,11 @@#ifdef __ASSEMBLY__ .macro UNWIND_HINT_EMPTY - UNWIND_HINT sp_reg=ORC_REG_UNDEFINED type=UNWIND_HINT_TYPE_CALL end=1 + UNWIND_HINT type=UNWIND_HINT_TYPE_CALL end=1 .endm .macro UNWIND_HINT_ENTRY - UNWIND_HINT sp_reg=ORC_REG_UNDEFINED type=UNWIND_HINT_TYPE_ENTRY end=1 + UNWIND_HINT type=UNWIND_HINT_TYPE_ENTRY end=1 .endm .macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0
@@ -56,6 +56,14 @@ UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=8 type=UNWIND_HINT_TYPE_FUNC .endm +.macro UNWIND_HINT_SAVE + UNWIND_HINT type=UNWIND_HINT_TYPE_SAVE +.endm + +.macro UNWIND_HINT_RESTORE + UNWIND_HINT type=UNWIND_HINT_TYPE_RESTORE +.endm +#endif /* __ASSEMBLY__ */ #endif /* _ASM_X86_UNWIND_HINTS_H */
include/linux/objtool.h +4 -2
@@ -40,6 +40,8 @@ struct unwind_hint {#define UNWIND_HINT_TYPE_REGS_PARTIAL 2#define UNWIND_HINT_TYPE_FUNC 3#define UNWIND_HINT_TYPE_ENTRY 4 +#define UNWIND_HINT_TYPE_SAVE 5 +#define UNWIND_HINT_TYPE_RESTORE 6#ifdef CONFIG_STACK_VALIDATION
@@ -102,7 +104,7 @@ struct unwind_hint {* the debuginfo as necessary. It will also warn if it sees any * inconsistencies. */ -.macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0 +.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0 .Lunwind_hint_ip_\@: .pushsection .discard.unwind_hints/* struct unwind_hint */
@@ -132,7 +134,7 @@ struct unwind_hint {#define STACK_FRAME_NON_STANDARD (func)#else #define ANNOTATE_INTRA_FUNCTION_CALL -.macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0 +.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0 .endm .macro STACK_FRAME_NON_STANDARD func:req .endm
tools/include/linux/objtool.h +4 -2
@@ -40,6 +40,8 @@ struct unwind_hint {#define UNWIND_HINT_TYPE_REGS_PARTIAL 2#define UNWIND_HINT_TYPE_FUNC 3#define UNWIND_HINT_TYPE_ENTRY 4 +#define UNWIND_HINT_TYPE_SAVE 5 +#define UNWIND_HINT_TYPE_RESTORE 6#ifdef CONFIG_STACK_VALIDATION
@@ -102,7 +104,7 @@ struct unwind_hint {* the debuginfo as necessary. It will also warn if it sees any * inconsistencies. */ -.macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0 +.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0 .Lunwind_hint_ip_\@: .pushsection .discard.unwind_hints/* struct unwind_hint */
@@ -132,7 +134,7 @@ struct unwind_hint {#define STACK_FRAME_NON_STANDARD (func)#else #define ANNOTATE_INTRA_FUNCTION_CALL -.macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0 +.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0 .endm .macro STACK_FRAME_NON_STANDARD func:req .endm
tools/objtool/check.c +40 -0
@@ -1847,6 +1847,17 @@ static int read_unwind_hints(struct objt insn->hint = true; +if (hint->type ==UNWIND_HINT_TYPE_SAVE ) { + insn->hint = false; + insn->save = true; +continue ; + } + +if (hint->type ==UNWIND_HINT_TYPE_RESTORE ) { + insn->restore = true; +continue ; + } +if (hint->type ==UNWIND_HINT_TYPE_REGS_PARTIAL ) {struct symbol *sym =find_symbol_by_offset (insn->sec, insn->offset);
@@ -3025,6 +3036,35 @@ static int validate_branch(struct objtoo state.instr += insn->instr;if (insn->hint) { +if (insn->restore) { +struct instruction *save_insn, *i; + + i = insn; + save_insn =NULL ; + +sym_for_each_insn_continue_reverse (file, func, i) { +if (i->save) { + save_insn = i; +break ; + } + } + +if (!save_insn) { +WARN_FUNC ("no corresponding CFI save for CFI restore" , + sec, insn->offset); +return 1 ; + } + +if (!save_insn->visited) { +WARN_FUNC ("objtool isn't smart enough to handle this CFI save/restore combo" , + sec, insn->offset); +return 1 ; + } + + insn->cfi = save_insn->cfi; + nr_cfi_reused++; + } + state.cfi = *insn->cfi; }else {/* XXX track if we actually changed state.cfi */
tools/objtool/include/objtool/check.h +1 -0
@@ -47,6 +47,7 @@ struct instruction {unsigned long immediate;bool dead_end, ignore, ignore_alts;bool hint; +bool save, restore;bool retpoline_safe;bool entry;s8 instr;
Greg Kroah-Hartman
maintainerPATCH 65/78 KVM: VMX: Flatten __vmx_vcpu_run()
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit 8bd200d23ec42d66ccd517a72dd0b9cc6132d2fd upstream.
Move the vmx_vm{enter,exit}() functionality into __vmx_vcpu_run(). This will make it easier to do the spec_ctrl handling before the first RET.
--- arch/x86/kvm/vmx/vmenter.S | 118 +++++++++++++++++---------------------------- 1 file changed, 45 insertions(+), 73 deletions(-)
arch/x86/kvm/vmx/vmenter.S +45 -73
@@ -31,68 +31,6 @@ .section .noinstr.text, "ax" /** - * vmx_vmenter - VM-Enter the current loaded VMCS - * - * %RFLAGS.ZF: !VMCS.LAUNCHED, i.e. controls VMLAUNCH vs. VMRESUME - * - * Returns: - * %RFLAGS.CF is set on VM-Fail Invalid - * %RFLAGS.ZF is set on VM-Fail Valid - * %RFLAGS.{CF,ZF} are cleared on VM-Success, i.e. VM-Exit - * - * Note that VMRESUME/VMLAUNCH fall-through and return directly if - * they VM-Fail, whereas a successful VM-Enter + VM-Exit will jump - * to vmx_vmexit. - */ -SYM_FUNC_START_LOCAL(vmx_vmenter) - /* EFLAGS.ZF is set if VMCS.LAUNCHED == 0 */ - je 2f - -1: vmresume - RET - -2: vmlaunch - RET - -3: cmpb $0, kvm_rebooting - je 4f - RET -4: ud2 - - _ASM_EXTABLE(1b, 3b) - _ASM_EXTABLE(2b, 3b) - -SYM_FUNC_END(vmx_vmenter) - -/** - * vmx_vmexit - Handle a VMX VM-Exit - * - * Returns: - * %RFLAGS.{CF,ZF} are cleared on VM-Success, i.e. VM-Exit - * - * This is vmx_vmenter's partner in crime. On a VM-Exit, control will jump - * here after hardware loads the host's state, i.e. this is the destination - * referred to by VMCS.HOST_RIP. - */ -SYM_FUNC_START(vmx_vmexit) -#ifdef CONFIG_RETPOLINE - ALTERNATIVE "jmp .Lvmexit_skip_rsb", "", X86_FEATURE_RETPOLINE - /* Preserve guest's RAX, it's used to stuff the RSB. */ - push %_ASM_AX - - /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */ - FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE - - /* Clear RFLAGS.CF and RFLAGS.ZF to preserve VM-Exit, i.e. !VM-Fail. */ - or $1, %_ASM_AX - - pop %_ASM_AX -.Lvmexit_skip_rsb: -#endif - RET -SYM_FUNC_END(vmx_vmexit) - -/** * __vmx_vcpu_run - Run a vCPU via a transition to VMX guest mode * @vmx: struct vcpu_vmx * (forwarded to vmx_update_host_rsp) * @regs: unsigned long * (to guest registers)
@@ -124,8 +62,7 @@ SYM_FUNC_START(__vmx_vcpu_run) /* Copy @launched to BL, _ASM_ARG3 is volatile. */ mov %_ASM_ARG3B, %bl - /* Adjust RSP to account for the CALL to vmx_vmenter(). */ - lea -WORD_SIZE(%_ASM_SP), %_ASM_ARG2 + lea (%_ASM_SP), %_ASM_ARG2 call vmx_update_host_rsp /* Load @regs to RAX. */
@@ -154,11 +91,36 @@ SYM_FUNC_START(__vmx_vcpu_run) /* Load guest RAX. This kills the @regs pointer! */ mov VCPU_RAX(%_ASM_AX), %_ASM_AX - /* Enter guest mode */ - call vmx_vmenter + /* Check EFLAGS.ZF from 'testb' above */ + je .Lvmlaunch - /* Jump on VM-Fail. */ - jbe 2f + /* + * After a successful VMRESUME/VMLAUNCH, control flow "magically" + * resumes below at 'vmx_vmexit' due to the VMCS HOST_RIP setting. + * So this isn't a typical function and objtool needs to be told to + * save the unwind state here and restore it below. + */ + UNWIND_HINT_SAVE + +/* + * If VMRESUME/VMLAUNCH and corresponding vmexit succeed, execution resumes at + * the 'vmx_vmexit' label below. + */ +.Lvmresume: + vmresume + jmp .Lvmfail + +.Lvmlaunch: + vmlaunch + jmp .Lvmfail + + _ASM_EXTABLE(.Lvmresume, .Lfixup) + _ASM_EXTABLE(.Lvmlaunch, .Lfixup) + +SYM_INNER_LABEL(vmx_vmexit, SYM_L_GLOBAL) + + /* Restore unwind state from before the VMRESUME/VMLAUNCH. */ + UNWIND_HINT_RESTORE /* Temporarily save guest's RAX. */ push %_ASM_AX
@@ -185,9 +147,13 @@ SYM_FUNC_START(__vmx_vcpu_run) mov %r15, VCPU_R15(%_ASM_AX) #endif + /* IMPORTANT: RSB must be stuffed before the first return. */ + FILL_RETURN_BUFFER %_ASM_BX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE + /* Clear RAX to indicate VM-Exit (as opposed to VM-Fail). */ xor %eax, %eax +.Lclear_regs: /* * Clear all general purpose registers except RSP and RAX to prevent * speculative use of the guest's values, even those that are reloaded
@@ -197,7 +163,7 @@ SYM_FUNC_START(__vmx_vcpu_run) * free. RSP and RAX are exempt as RSP is restored by hardware during * VM-Exit and RAX is explicitly loaded with 0 or 1 to return VM-Fail. */ -1: xor %ecx, %ecx + xor %ecx, %ecx xor %edx, %edx xor %ebx, %ebx xor %ebp, %ebp
@@ -216,8 +182,8 @@ SYM_FUNC_START(__vmx_vcpu_run) /* "POP" @regs. */ add $WORD_SIZE, %_ASM_SP - pop %_ASM_BX + pop %_ASM_BX #ifdef CONFIG_X86_64 pop %r12 pop %r13
@@ -230,9 +196,15 @@ SYM_FUNC_START(__vmx_vcpu_run) pop %_ASM_BP RET - /* VM-Fail. Out-of-line to avoid a taken Jcc after VM-Exit. */ -2: mov $1, %eax - jmp 1b +.Lfixup: + cmpb $0, kvm_rebooting + jne .Lvmfail + ud2 +.Lvmfail: + /* VM-Fail: set return value to 1 */ + mov $1, %eax + jmp .Lclear_regs + SYM_FUNC_END(__vmx_vcpu_run)
Greg Kroah-Hartman
maintainerPATCH 66/78 KVM: VMX: Convert launched argument to flags
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit bb06650634d3552c0f8557e9d16aa1a408040e28 upstream.
Convert __vmx_vcpu_run()'s 'launched' argument to 'flags', in preparation for doing SPEC_CTRL handling immediately after vmexit, which will need another flag.
This is much easier than adding a fourth argument, because this code supports both 32-bit and 64-bit, and the fourth argument on 32-bit would have to be pushed on the stack.
Note that __vmx_vcpu_run_flags() is called outside of the noinstr critical section because it will soon start calling potentially traceable functions.
--- arch/x86/kvm/vmx/nested.c | 2 +- arch/x86/kvm/vmx/run_flags.h | 7 +++++++ arch/x86/kvm/vmx/vmenter.S | 9 +++++---- arch/x86/kvm/vmx/vmx.c | 17 ++++++++++++++--- arch/x86/kvm/vmx/vmx.h | 5 ++++- 5 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 arch/x86/kvm/vmx/run_flags.h
arch/x86/kvm/vmx/nested.c +1 -1
@@ -3077,7 +3077,7 @@ static int nested_vmx_check_vmentry_hw(s } vm_fail =__vmx_vcpu_run (vmx, (unsigned long *)&vcpu->arch.regs, - vmx->loaded_vmcs->launched); +__vmx_vcpu_run_flags (vmx));if (vmx->msr_autoload.host.nr)vmcs_write32 (VM_EXIT_MSR_LOAD_COUNT , vmx->msr_autoload.host.nr);
arch/x86/kvm/vmx/run_flags.h new file +7 -0
@@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __KVM_X86_VMX_RUN_FLAGS_H +#define __KVM_X86_VMX_RUN_FLAGS_H + +#define VMX_RUN_VMRESUME (1 << 0) + +#endif /* __KVM_X86_VMX_RUN_FLAGS_H */
arch/x86/kvm/vmx/vmenter.S +5 -4
@@ -5,6 +5,7 @@ #include <asm/kvm_vcpu_regs.h> #include <asm/nospec-branch.h> #include <asm/segment.h> +#include "run_flags.h" #define WORD_SIZE (BITS_PER_LONG / 8)
@@ -34,7 +35,7 @@ * __vmx_vcpu_run - Run a vCPU via a transition to VMX guest mode * @vmx: struct vcpu_vmx * (forwarded to vmx_update_host_rsp) * @regs: unsigned long * (to guest registers) - * @launched: %true if the VMCS has been launched + * @flags: VMX_RUN_VMRESUME: use VMRESUME instead of VMLAUNCH * * Returns: * 0 on VM-Exit, 1 on VM-Fail
@@ -59,7 +60,7 @@ SYM_FUNC_START(__vmx_vcpu_run) */ push %_ASM_ARG2 - /* Copy @launched to BL, _ASM_ARG3 is volatile. */ + /* Copy @flags to BL, _ASM_ARG3 is volatile. */ mov %_ASM_ARG3B, %bl lea (%_ASM_SP), %_ASM_ARG2
@@ -69,7 +70,7 @@ SYM_FUNC_START(__vmx_vcpu_run) mov (%_ASM_SP), %_ASM_AX /* Check if vmlaunch or vmresume is needed */ - testb %bl, %bl + testb $VMX_RUN_VMRESUME, %bl /* Load guest registers. Don't clobber flags. */ mov VCPU_RCX(%_ASM_AX), %_ASM_CX
@@ -92,7 +93,7 @@ SYM_FUNC_START(__vmx_vcpu_run) mov VCPU_RAX(%_ASM_AX), %_ASM_AX /* Check EFLAGS.ZF from 'testb' above */ - je .Lvmlaunch + jz .Lvmlaunch /* * After a successful VMRESUME/VMLAUNCH, control flow "magically"
arch/x86/kvm/vmx/vmx.c +14 -3
@@ -835,6 +835,16 @@ static bool msr_write_intercepted(struct MSR_IA32_SPEC_CTRL); } +unsigned int __vmx_vcpu_run_flags (struct vcpu_vmx *vmx) +{ +unsigned int flags =0 ; + +if (vmx->loaded_vmcs->launched) + flags |=VMX_RUN_VMRESUME ; + +return flags; +} +static void clear_atomic_switch_msr_special (struct vcpu_vmx *vmx,unsigned long entry,unsigned long exit) {
@@ -6667,7 +6677,8 @@ static fastpath_t vmx_exit_handlers_fast } static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu, -struct vcpu_vmx *vmx) +struct vcpu_vmx *vmx, +unsigned long flags) {kvm_guest_enter_irqoff ();
@@ -6686,7 +6697,7 @@ static noinstr void vmx_vcpu_enter_exit(native_write_cr2 (vcpu->arch.cr2); vmx->fail =__vmx_vcpu_run (vmx, (unsigned long *)&vcpu->arch.regs, - vmx->loaded_vmcs->launched); + flags); vcpu->arch.cr2 =native_read_cr2 ();
@@ -6786,7 +6797,7 @@ static fastpath_t vmx_vcpu_run(struct kvx86_spec_ctrl_set_guest (vmx->spec_ctrl,0 );/* The actual VMENTER/EXIT is in the .noinstr.text section. */ -vmx_vcpu_enter_exit (vcpu, vmx); +vmx_vcpu_enter_exit (vcpu, vmx,__vmx_vcpu_run_flags (vmx));/* * We do not use IBRS in the kernel. If this vCPU has used the
arch/x86/kvm/vmx/vmx.h +4 -1
@@ -13,6 +13,7 @@#include "vmcs.h" #include "vmx_ops.h" #include "cpuid.h" +#include "run_flags.h" #define MSR_TYPE_R 1#define MSR_TYPE_W 2
@@ -382,7 +383,9 @@ void vmx_set_virtual_apic_mode(struct kvstruct vmx_uret_msr *vmx_find_uret_msr (struct vcpu_vmx *vmx,u32 msr);void pt_update_intercept_for_msr (struct kvm_vcpu *vcpu);void vmx_update_host_rsp (struct vcpu_vmx *vmx,unsigned long host_rsp); -bool __vmx_vcpu_run (struct vcpu_vmx *vmx,unsigned long *regs,bool launched); +unsigned int __vmx_vcpu_run_flags (struct vcpu_vmx *vmx); +bool __vmx_vcpu_run (struct vcpu_vmx *vmx,unsigned long *regs, +unsigned int flags);int vmx_find_loadstore_msr_slot (struct vmx_msrs *m,u32 msr);void vmx_ept_load_pdptrs (struct kvm_vcpu *vcpu);
Greg Kroah-Hartman
maintainerPATCH 67/78 KVM: VMX: Prevent guest RSB poisoning attacks with eIBRS
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit fc02735b14fff8c6678b521d324ade27b1a3d4cf upstream.
On eIBRS systems, the returns in the vmexit return path from __vmx_vcpu_run() to vmx_vcpu_run() are exposed to RSB poisoning attacks.
Fix that by moving the post-vmexit spec_ctrl handling to immediately after the vmexit.
--- arch/x86/include/asm/nospec-branch.h | 1 arch/x86/kernel/cpu/bugs.c | 4 ++ arch/x86/kvm/vmx/run_flags.h | 1 arch/x86/kvm/vmx/vmenter.S | 49 +++++++++++++++++++++++++++-------- arch/x86/kvm/vmx/vmx.c | 48 ++++++++++++++++++++-------------- arch/x86/kvm/vmx/vmx.h | 1 6 files changed, 73 insertions(+), 31 deletions(-)
arch/x86/include/asm/nospec-branch.h +1 -0
@@ -275,6 +275,7 @@ static inline void indirect_branch_predi/* The Intel SPEC CTRL MSR base value cache */ extern u64 x86_spec_ctrl_base; +extern u64 x86_spec_ctrl_current;extern void write_spec_ctrl_current (u64 val,bool force);extern u64 spec_ctrl_current (void );
arch/x86/kernel/cpu/bugs.c +4 -0
@@ -195,6 +195,10 @@ void __init check_bugs(void)#endif } +/* +* NOTE: For VMX, this function is not called in the vmexit path. +* It uses vmx_spec_ctrl_restore_host() instead. +*/ void x86_virt_spec_ctrl (u64 guest_spec_ctrl,u64 guest_virt_spec_ctrl,bool setguest) {
arch/x86/kvm/vmx/run_flags.h +1 -0
@@ -3,5 +3,6 @@#define __KVM_X86_VMX_RUN_FLAGS_H#define VMX_RUN_VMRESUME (1 << 0) +#define VMX_RUN_SAVE_SPEC_CTRL (1 << 1)#endif /* __KVM_X86_VMX_RUN_FLAGS_H */
arch/x86/kvm/vmx/vmenter.S +38 -11
91 lines not on this page · raw message
arch/x86/kvm/vmx/vmx.c +28 -20
66 lines not on this page · raw message
arch/x86/kvm/vmx/vmx.h +1 -0
@@ -383,6 +383,7 @@ void vmx_set_virtual_apic_mode(struct kvstruct vmx_uret_msr *vmx_find_uret_msr (struct vcpu_vmx *vmx,u32 msr);void pt_update_intercept_for_msr (struct kvm_vcpu *vcpu);void vmx_update_host_rsp (struct vcpu_vmx *vmx,unsigned long host_rsp); +void vmx_spec_ctrl_restore_host (struct vcpu_vmx *vmx,unsigned int flags);unsigned int __vmx_vcpu_run_flags (struct vcpu_vmx *vmx);bool __vmx_vcpu_run (struct vcpu_vmx *vmx,unsigned long *regs,unsigned int flags);
Greg Kroah-Hartman
maintainerPATCH 68/78 KVM: VMX: Fix IBRS handling after vmexit
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit bea7e31a5caccb6fe8ed989c065072354f0ecb52 upstream.
For legacy IBRS to work, the IBRS bit needs to be always re-written after vmexit, even if it's already on.
--- arch/x86/kvm/vmx/vmx.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
arch/x86/kvm/vmx/vmx.c +6 -1
@@ -6685,8 +6685,13 @@ void noinstr vmx_spec_ctrl_restore_host(/* * If the guest/host SPEC_CTRL values differ, restore the host value. +* +* For legacy IBRS, the IBRS bit always needs to be written after +* transitioning from a less privileged predictor mode, regardless of +* whether the guest/host values differ. */ -if (vmx->spec_ctrl != hostval) +if (cpu_feature_enabled (X86_FEATURE_KERNEL_IBRS ) || + vmx->spec_ctrl != hostval)native_wrmsrl (MSR_IA32_SPEC_CTRL , hostval);barrier_nospec ();
Greg Kroah-Hartman
maintainerPATCH 69/78 x86/speculation: Fill RSB on vmexit for IBRS
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit 9756bba28470722dacb79ffce554336dd1f6a6cd upstream.
Prevent RSB underflow/poisoning attacks with RSB. While at it, add a bunch of comments to attempt to document the current state of tribal knowledge about RSB attacks and what exactly is being mitigated.
--- arch/x86/include/asm/cpufeatures.h | 2 - arch/x86/kernel/cpu/bugs.c | 63 ++++++++++++++++++++++++++++++++++--- arch/x86/kvm/vmx/vmenter.S | 6 +-- 3 files changed, 62 insertions(+), 9 deletions(-)
arch/x86/include/asm/cpufeatures.h +1 -1
@@ -204,7 +204,7 @@/* FREE! ( 7*32+10) */ #define X86_FEATURE_PTI ( 7*32+11)/* Kernel Page Table Isolation enabled */ #define X86_FEATURE_KERNEL_IBRS ( 7*32+12)/* "" Set/clear IBRS on kernel entry/exit */ -/* FREE! ( 7*32+13) */ +#define X86_FEATURE_RSB_VMEXIT ( 7*32+13)/* "" Fill RSB on VM-Exit */ #define X86_FEATURE_INTEL_PPIN ( 7*32+14)/* Intel Processor Inventory Number */ #define X86_FEATURE_CDP_L2 ( 7*32+15)/* Code and Data Prioritization L2 */ #define X86_FEATURE_MSR_SPEC_CTRL ( 7*32+16)/* "" MSR SPEC_CTRL is implemented */
arch/x86/kernel/cpu/bugs.c +58 -5
75 lines not on this page · raw message
arch/x86/kvm/vmx/vmenter.S +3 -3
@@ -193,15 +193,15 @@ SYM_INNER_LABEL(vmx_vmexit, SYM_L_GLOBAL * IMPORTANT: RSB filling and SPEC_CTRL handling must be done before * the first unbalanced RET after vmexit! * - * For retpoline, RSB filling is needed to prevent poisoned RSB entries - * and (in some cases) RSB underflow. + * For retpoline or IBRS, RSB filling is needed to prevent poisoned RSB + * entries and (in some cases) RSB underflow. * * eIBRS has its own protection against poisoned RSB, so it doesn't * need the RSB filling sequence. But it does need to be enabled * before the first unbalanced RET. */ - FILL_RETURN_BUFFER %_ASM_CX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE + FILL_RETURN_BUFFER %_ASM_CX, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_VMEXIT pop %_ASM_ARG2 /* @flags */ pop %_ASM_ARG1 /* @vmx */
Greg Kroah-Hartman
maintainerPATCH 70/78 x86/common: Stamp out the stepping madness
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 7a05bc95ed1c5a59e47aaade9fb4083c27de9e62 upstream.
The whole MMIO/RETBLEED enumeration went overboard on steppings. Get rid of all that and simply use ANY.
If a future stepping of these models would not be affected, it had better set the relevant ARCH_CAP_$FOO_NO bit in IA32_ARCH_CAPABILITIES.
--- arch/x86/kernel/cpu/common.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-)
arch/x86/kernel/cpu/common.c +16 -21
@@ -1122,32 +1122,27 @@ static const struct x86_cpu_id cpu_vuln_VULNBL_INTEL_STEPPINGS (HASWELL ,X86_STEPPING_ANY ,SRBDS ),VULNBL_INTEL_STEPPINGS (HASWELL_L ,X86_STEPPING_ANY ,SRBDS ),VULNBL_INTEL_STEPPINGS (HASWELL_G ,X86_STEPPING_ANY ,SRBDS ), -VULNBL_INTEL_STEPPINGS (HASWELL_X ,BIT (2 ) |BIT (4 ),MMIO ), -VULNBL_INTEL_STEPPINGS (BROADWELL_D ,X86_STEPPINGS (0x3 ,0x5 ),MMIO ), +VULNBL_INTEL_STEPPINGS (HASWELL_X ,X86_STEPPING_ANY ,MMIO ), +VULNBL_INTEL_STEPPINGS (BROADWELL_D ,X86_STEPPING_ANY ,MMIO ),VULNBL_INTEL_STEPPINGS (BROADWELL_G ,X86_STEPPING_ANY ,SRBDS ),VULNBL_INTEL_STEPPINGS (BROADWELL_X ,X86_STEPPING_ANY ,MMIO ),VULNBL_INTEL_STEPPINGS (BROADWELL ,X86_STEPPING_ANY ,SRBDS ), -VULNBL_INTEL_STEPPINGS (SKYLAKE_L ,X86_STEPPINGS (0x3 ,0x3 ),SRBDS |MMIO |RETBLEED ), -VULNBL_INTEL_STEPPINGS (SKYLAKE_L ,X86_STEPPING_ANY ,SRBDS ), -VULNBL_INTEL_STEPPINGS (SKYLAKE_X ,BIT (3 ) |BIT (4 ) |BIT (6 ) | -BIT (7 ) |BIT (0xB ),MMIO |RETBLEED ), -VULNBL_INTEL_STEPPINGS (SKYLAKE ,X86_STEPPINGS (0x3 ,0x3 ),SRBDS |MMIO |RETBLEED ), -VULNBL_INTEL_STEPPINGS (SKYLAKE ,X86_STEPPING_ANY ,SRBDS ), -VULNBL_INTEL_STEPPINGS (KABYLAKE_L ,X86_STEPPINGS (0x9 ,0xC ),SRBDS |MMIO |RETBLEED ), -VULNBL_INTEL_STEPPINGS (KABYLAKE_L ,X86_STEPPINGS (0x0 ,0x8 ),SRBDS ), -VULNBL_INTEL_STEPPINGS (KABYLAKE ,X86_STEPPINGS (0x9 ,0xD ),SRBDS |MMIO |RETBLEED ), -VULNBL_INTEL_STEPPINGS (KABYLAKE ,X86_STEPPINGS (0x0 ,0x8 ),SRBDS ), -VULNBL_INTEL_STEPPINGS (ICELAKE_L ,X86_STEPPINGS (0x5 ,0x5 ),MMIO |MMIO_SBDS |RETBLEED ), -VULNBL_INTEL_STEPPINGS (ICELAKE_D ,X86_STEPPINGS (0x1 ,0x1 ),MMIO ), -VULNBL_INTEL_STEPPINGS (ICELAKE_X ,X86_STEPPINGS (0x4 ,0x6 ),MMIO ), -VULNBL_INTEL_STEPPINGS (COMETLAKE ,BIT (2 ) |BIT (3 ) |BIT (5 ),MMIO |MMIO_SBDS |RETBLEED ), -VULNBL_INTEL_STEPPINGS (COMETLAKE_L ,X86_STEPPINGS (0x1 ,0x1 ),MMIO |MMIO_SBDS |RETBLEED ), +VULNBL_INTEL_STEPPINGS (SKYLAKE_L ,X86_STEPPING_ANY ,SRBDS |MMIO |RETBLEED ), +VULNBL_INTEL_STEPPINGS (SKYLAKE_X ,X86_STEPPING_ANY ,MMIO |RETBLEED ), +VULNBL_INTEL_STEPPINGS (SKYLAKE ,X86_STEPPING_ANY ,SRBDS |MMIO |RETBLEED ), +VULNBL_INTEL_STEPPINGS (KABYLAKE_L ,X86_STEPPING_ANY ,SRBDS |MMIO |RETBLEED ), +VULNBL_INTEL_STEPPINGS (KABYLAKE ,X86_STEPPING_ANY ,SRBDS |MMIO |RETBLEED ), +VULNBL_INTEL_STEPPINGS (ICELAKE_L ,X86_STEPPING_ANY ,MMIO |MMIO_SBDS |RETBLEED ), +VULNBL_INTEL_STEPPINGS (ICELAKE_D ,X86_STEPPING_ANY ,MMIO ), +VULNBL_INTEL_STEPPINGS (ICELAKE_X ,X86_STEPPING_ANY ,MMIO ), +VULNBL_INTEL_STEPPINGS (COMETLAKE ,X86_STEPPING_ANY ,MMIO |MMIO_SBDS |RETBLEED ),VULNBL_INTEL_STEPPINGS (COMETLAKE_L ,X86_STEPPINGS (0x0 ,0x0 ),MMIO |RETBLEED ), -VULNBL_INTEL_STEPPINGS (LAKEFIELD ,X86_STEPPINGS (0x1 ,0x1 ),MMIO |MMIO_SBDS |RETBLEED ), -VULNBL_INTEL_STEPPINGS (ROCKETLAKE ,X86_STEPPINGS (0x1 ,0x1 ),MMIO |RETBLEED ), -VULNBL_INTEL_STEPPINGS (ATOM_TREMONT ,X86_STEPPINGS (0x1 ,0x1 ),MMIO |MMIO_SBDS ), +VULNBL_INTEL_STEPPINGS (COMETLAKE_L ,X86_STEPPING_ANY ,MMIO |MMIO_SBDS |RETBLEED ), +VULNBL_INTEL_STEPPINGS (LAKEFIELD ,X86_STEPPING_ANY ,MMIO |MMIO_SBDS |RETBLEED ), +VULNBL_INTEL_STEPPINGS (ROCKETLAKE ,X86_STEPPING_ANY ,MMIO |RETBLEED ), +VULNBL_INTEL_STEPPINGS (ATOM_TREMONT ,X86_STEPPING_ANY ,MMIO |MMIO_SBDS ),VULNBL_INTEL_STEPPINGS (ATOM_TREMONT_D ,X86_STEPPING_ANY ,MMIO ), -VULNBL_INTEL_STEPPINGS (ATOM_TREMONT_L ,X86_STEPPINGS (0x0 ,0x0 ),MMIO |MMIO_SBDS ), +VULNBL_INTEL_STEPPINGS (ATOM_TREMONT_L ,X86_STEPPING_ANY ,MMIO |MMIO_SBDS ),VULNBL_AMD (0x15 ,RETBLEED ), VULNBL_AMD(0x16, RETBLEED),
Greg Kroah-Hartman
maintainerPATCH 71/78 x86/cpu/amd: Enumerate BTC_NO
In reply to Greg Kroah-HartmanFrom: Andrew Cooper <[email protected]>
commit 26aae8ccbc1972233afd08fb3f368947c0314265 upstream.
BTC_NO indicates that hardware is not susceptible to Branch Type Confusion.
Zen3 CPUs don't suffer BTC.
Hypervisors are expected to synthesise BTC_NO when it is appropriate given the migration pool, to prevent kernels using heuristics.
[ bp: Massage. ]
--- arch/x86/include/asm/cpufeatures.h | 1 + arch/x86/kernel/cpu/amd.c | 21 +++++++++++++++------ arch/x86/kernel/cpu/common.c | 6 ++++-- 3 files changed, 20 insertions(+), 8 deletions(-)
arch/x86/include/asm/cpufeatures.h +1 -0
@@ -319,6 +319,7 @@#define X86_FEATURE_AMD_SSBD (13*32+24)/* "" Speculative Store Bypass Disable */ #define X86_FEATURE_VIRT_SSBD (13*32+25)/* Virtualized Speculative Store Bypass Disable */ #define X86_FEATURE_AMD_SSB_NO (13*32+26)/* "" Speculative Store Bypass is fixed in hardware. */ +#define X86_FEATURE_BTC_NO (13*32+29)/* "" Not vulnerable to Branch Type Confusion */ /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ #define X86_FEATURE_DTHERM (14*32+ 0)/* Digital Thermal Sensor */
arch/x86/kernel/cpu/amd.c +15 -6
@@ -914,12 +914,21 @@ static void init_amd_zn(struct cpuinfo_x node_reclaim_distance =32 ;#endif -/* -* Fix erratum 1076: CPB feature bit not being set in CPUID. -* Always set it, except when running under a hypervisor. -*/ -if (!cpu_has (c,X86_FEATURE_HYPERVISOR ) && !cpu_has (c,X86_FEATURE_CPB )) -set_cpu_cap (c,X86_FEATURE_CPB ); +/* Fix up CPUID bits, but only if not virtualised. */ +if (!cpu_has (c,X86_FEATURE_HYPERVISOR )) { + +/* Erratum 1076: CPB feature bit not being set in CPUID. */ +if (!cpu_has (c,X86_FEATURE_CPB )) +set_cpu_cap (c,X86_FEATURE_CPB ); + +/* +* Zen3 (Fam19 model < 0x10) parts are not susceptible to +* Branch Type Confusion, but predate the allocation of the +* BTC_NO bit. +*/ +if (c->x86 ==0x19 && !cpu_has (c,X86_FEATURE_BTC_NO )) +set_cpu_cap (c,X86_FEATURE_BTC_NO ); + } }static void init_amd (struct cpuinfo_x86 *c)
arch/x86/kernel/cpu/common.c +4 -2
@@ -1249,8 +1249,10 @@ static void __init cpu_set_bug_bits(stru !arch_cap_mmio_immune(ia32_cap))setup_force_cpu_bug (X86_BUG_MMIO_STALE_DATA ); -if ((cpu_matches (cpu_vuln_blacklist,RETBLEED ) || (ia32_cap &ARCH_CAP_RSBA ))) -setup_force_cpu_bug (X86_BUG_RETBLEED ); +if (!cpu_has (c,X86_FEATURE_BTC_NO )) { +if (cpu_matches (cpu_vuln_blacklist,RETBLEED ) || (ia32_cap &ARCH_CAP_RSBA )) +setup_force_cpu_bug (X86_BUG_RETBLEED ); + }if (cpu_matches (cpu_vuln_whitelist,NO_MELTDOWN ))return ;
Greg Kroah-Hartman
maintainerPATCH 72/78 x86/retbleed: Add fine grained Kconfig knobs
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit f43b9876e857c739d407bc56df288b0ebe1a9164 upstream.
Do fine-grained Kconfig for all the various retbleed parts.
NOTE: if your compiler doesn't support return thunks this will silently 'upgrade' your mitigation to IBPB, you might not like this.
--- Makefile | 8 +- arch/x86/Kconfig | 106 +++++++++++++++++++++++-------- arch/x86/entry/calling.h | 4 + arch/x86/include/asm/disabled-features.h | 18 ++++- arch/x86/include/asm/linkage.h | 4 - arch/x86/include/asm/nospec-branch.h | 10 ++ arch/x86/include/asm/static_call.h | 2 arch/x86/kernel/alternative.c | 5 + arch/x86/kernel/cpu/amd.c | 2 arch/x86/kernel/cpu/bugs.c | 42 +++++++----- arch/x86/kernel/static_call.c | 2 arch/x86/kvm/emulate.c | 4 - arch/x86/lib/retpoline.S | 4 + scripts/Makefile.build | 1 scripts/link-vmlinux.sh | 2 security/Kconfig | 11 --- tools/objtool/builtin-check.c | 3 tools/objtool/check.c | 9 ++ tools/objtool/include/objtool/builtin.h | 2 19 files changed, 170 insertions(+), 69 deletions(-)
Makefile +6 -2
@@ -687,14 +687,18 @@ endif ifdef CONFIG_CC_IS_GCC RETPOLINE_CFLAGS := $(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register) -RETPOLINE_CFLAGS += $(call cc-option,-mfunction-return=thunk-extern) RETPOLINE_VDSO_CFLAGS := $(call cc-option,-mindirect-branch=thunk-inline -mindirect-branch-register) endif ifdef CONFIG_CC_IS_CLANG RETPOLINE_CFLAGS := -mretpoline-external-thunk RETPOLINE_VDSO_CFLAGS := -mretpoline -RETPOLINE_CFLAGS += $(call cc-option,-mfunction-return=thunk-extern) endif + +ifdef CONFIG_RETHUNK +RETHUNK_CFLAGS := -mfunction-return=thunk-extern +RETPOLINE_CFLAGS += $(RETHUNK_CFLAGS) +endif + export RETPOLINE_CFLAGS export RETPOLINE_VDSO_CFLAGS
arch/x86/Kconfig +82 -24
118 lines not on this page · raw message
arch/x86/entry/calling.h +4 -0
@@ -296,6 +296,7 @@ For 32-bit we have the following convent* Assumes x86_spec_ctrl_{base,current} to have SPEC_CTRL_IBRS set. */ .macro IBRS_ENTER save_reg +#ifdef CONFIG_CPU_IBRS_ENTRY ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_KERNEL_IBRS movl $MSR_IA32_SPEC_CTRL, %ecx
@@ -316,6 +317,7 @@ For 32-bit we have the following convent shr $32, %rdx wrmsr .Lend_\@: +#endif .endm/*
@@ -323,6 +325,7 @@ For 32-bit we have the following convent* regs. Must be called after the last RET. */ .macro IBRS_EXIT save_reg +#ifdef CONFIG_CPU_IBRS_ENTRY ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_KERNEL_IBRS movl $MSR_IA32_SPEC_CTRL, %ecx
@@ -337,6 +340,7 @@ For 32-bit we have the following convent shr $32, %rdx wrmsr .Lend_\@: +#endif .endm/*
arch/x86/include/asm/disabled-features.h +14 -4
@@ -60,9 +60,19 @@# define DISABLE_RETPOLINE 0#else # define DISABLE_RETPOLINE ((1 << (X86_FEATURE_RETPOLINE & 31)) | \ - (1 << (X86_FEATURE_RETPOLINE_LFENCE & 31)) | \ - (1 << (X86_FEATURE_RETHUNK & 31)) | \ - (1 << (X86_FEATURE_UNRET & 31))) + (1 << (X86_FEATURE_RETPOLINE_LFENCE & 31))) +#endif + +#ifdef CONFIG_RETHUNK +# define DISABLE_RETHUNK 0 +#else +# define DISABLE_RETHUNK (1 << (X86_FEATURE_RETHUNK & 31)) +#endif + +#ifdef CONFIG_CPU_UNRET_ENTRY +# define DISABLE_UNRET 0 +#else +# define DISABLE_UNRET (1 << (X86_FEATURE_UNRET & 31))#endif /* Force disable because it's broken beyond repair */
@@ -88,7 +98,7 @@#define DISABLED_MASK8 0#define DISABLED_MASK9 (DISABLE_SMAP|DISABLE_SGX)#define DISABLED_MASK10 0 -#define DISABLED_MASK11 (DISABLE_RETPOLINE) +#define DISABLED_MASK11 (DISABLE_RETPOLINE|DISABLE_RETHUNK|DISABLE_UNRET)#define DISABLED_MASK12 0#define DISABLED_MASK13 0#define DISABLED_MASK14 0
arch/x86/include/asm/linkage.h +2 -2
@@ -18,7 +18,7 @@#define __ALIGN_STR __stringify(__ALIGN)#endif -#if defined(CONFIG_RETPOLINE ) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO ) +#if defined(CONFIG_RETHUNK ) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO )#define RET jmp __x86_return_thunk#else /* CONFIG_RETPOLINE */ #ifdef CONFIG_SLS
@@ -30,7 +30,7 @@#else /* __ASSEMBLY__ */ -#if defined(CONFIG_RETPOLINE ) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO ) +#if defined(CONFIG_RETHUNK ) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO )#define ASM_RET "jmp __x86_return_thunk\n\t"#else /* CONFIG_RETPOLINE */ #ifdef CONFIG_SLS
arch/x86/include/asm/nospec-branch.h +8 -2
@@ -127,6 +127,12 @@ .Lskip_rsb_\@: .endm +#ifdef CONFIG_CPU_UNRET_ENTRY +#define CALL_ZEN_UNTRAIN_RET "call zen_untrain_ret" +#else +#define CALL_ZEN_UNTRAIN_RET "" +#endif +/* * Mitigate RETBleed for AMD/Hygon Zen uarch. Requires KERNEL CR3 because the * return thunk isn't mapped into the userspace tables (then again, AMD
@@ -139,10 +145,10 @@* where we have a stack but before any RET instruction. */ .macro UNTRAIN_RET -#ifdef CONFIG_RETPOLINE +#if defined(CONFIG_CPU_UNRET_ENTRY ) || defined(CONFIG_CPU_IBPB_ENTRY )ANNOTATE_UNRET_END ALTERNATIVE_2 "", \ -"call zen_untrain_ret" ,X86_FEATURE_UNRET , \ +CALL_ZEN_UNTRAIN_RET ,X86_FEATURE_UNRET , \"call entry_ibpb" ,X86_FEATURE_ENTRY_IBPB #endif .endm
arch/x86/include/asm/static_call.h +1 -1
@@ -44,7 +44,7 @@#define ARCH_DEFINE_STATIC_CALL_TRAMP (name, func) \ __ARCH_DEFINE_STATIC_CALL_TRAMP(name, ".byte 0xe9; .long " #func " - (. + 4)") -#ifdef CONFIG_RETPOLINE +#ifdef CONFIG_RETHUNK #define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP (name) \ __ARCH_DEFINE_STATIC_CALL_TRAMP(name, "jmp __x86_return_thunk")#else
arch/x86/kernel/alternative.c +5 -0
@@ -507,6 +507,7 @@ void __init_or_module noinline apply_ret } } +#ifdef CONFIG_RETHUNK /* * Rewrite the compiler generated return thunk tail-calls. *
@@ -568,6 +569,10 @@ void __init_or_module noinline apply_ret } } } +#else +void __init_or_module noinline apply_returns(s32 *start, s32 *end) { } +#endif /* CONFIG_RETHUNK */ +#else /* !RETPOLINES || !CONFIG_STACK_VALIDATION */ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end) { }
arch/x86/kernel/cpu/amd.c +2 -0
@@ -888,6 +888,7 @@ static void init_amd_bd(struct cpuinfo_xvoid init_spectral_chicken (struct cpuinfo_x86 *c) { +#ifdef CONFIG_CPU_UNRET_ENTRY u64 value;/*
@@ -904,6 +905,7 @@ void init_spectral_chicken(struct cpuinf wrmsrl_safe(MSR_ZEN2_SPECTRAL_CHICKEN, value); } } +#endif }static void init_amd_zn (struct cpuinfo_x86 *c)
arch/x86/kernel/cpu/bugs.c +27 -15
86 lines not on this page · raw message
arch/x86/kernel/static_call.c +1 -1
@@ -120,7 +120,7 @@ void arch_static_call_transform(void *si }EXPORT_SYMBOL_GPL (arch_static_call_transform); -#ifdef CONFIG_RETPOLINE +#ifdef CONFIG_RETHUNK /* * This is called by apply_returns() to fix up static call trampolines, * specifically ARCH_DEFINE_STATIC_CALL_NULL_TRAMP which is recorded as
arch/x86/kvm/emulate.c +2 -2
@@ -434,10 +434,10 @@ static int fastop(struct x86_emulate_ctx* Depending on .config the SETcc functions look like: * * SETcc %al [3 bytes] -* RET | JMP __x86_return_thunk [1,5 bytes; CONFIG_RETPOLINE] +* RET | JMP __x86_return_thunk [1,5 bytes; CONFIG_RETHUNK] * INT3 [1 byte; CONFIG_SLS] */ -#define RET_LENGTH (1 + (4 * IS_ENABLED(CONFIG_RETPOLINE)) + \ +#define RET_LENGTH (1 + (4 * IS_ENABLED(CONFIG_RETHUNK)) + \ IS_ENABLED(CONFIG_SLS))#define SETCC_LENGTH (3 + RET_LENGTH)#define SETCC_ALIGN (4 << ((SETCC_LENGTH > 4) & 1) << ((SETCC_LENGTH > 8) & 1))
arch/x86/lib/retpoline.S +4 -0
@@ -71,6 +71,8 @@ SYM_CODE_END(__x86_indirect_thunk_array) * This function name is magical and is used by -mfunction-return=thunk-extern * for the compiler to generate JMPs to it. */ +#ifdef CONFIG_RETHUNK + .section .text.__x86.return_thunk /*
@@ -135,3 +137,5 @@ SYM_FUNC_END(zen_untrain_ret) __EXPORT_THUNK(zen_untrain_ret) EXPORT_SYMBOL(__x86_return_thunk) + +#endif /* CONFIG_RETHUNK */
scripts/Makefile.build +1 -0
@@ -231,6 +231,7 @@ objtool_args = \ $(if $(CONFIG_FRAME_POINTER),, --no-fp) \ $(if $(CONFIG_GCOV_KERNEL)$(CONFIG_LTO_CLANG), --no-unreachable)\ $(if $(CONFIG_RETPOLINE), --retpoline) \ + $(if $(CONFIG_RETHUNK), --rethunk) \ $(if $(CONFIG_X86_SMAP), --uaccess) \ $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \ $(if $(CONFIG_SLS), --sls)
scripts/link-vmlinux.sh +1 -1
@@ -120,7 +120,7 @@ objtool_link() if [ -n "${CONFIG_VMLINUX_VALIDATION}" ]; then objtoolopt="${objtoolopt} --noinstr" - if is_enabled CONFIG_RETPOLINE; then + if is_enabled CONFIG_CPU_UNRET_ENTRY; then objtoolopt="${objtoolopt} --unret" fi fi
security/Kconfig +0 -11
@@ -54,17 +54,6 @@ config SECURITY_NETWORK implement socket and networking access controls. If you are unsure how to answer this question, answer N. -config PAGE_TABLE_ISOLATION - bool "Remove the kernel mapping in user mode" - default y - depends on (X86_64 || X86_PAE) && !UML - help - This feature reduces the number of hardware side channels by - ensuring that the majority of kernel addresses are not mapped - into userspace. - - See Documentation/x86/pti.rst for more details. - config SECURITY_INFINIBAND bool "Infiniband Security Hooks" depends on SECURITY && INFINIBAND
tools/objtool/builtin-check.c +2 -1
@@ -20,7 +20,7 @@#include <objtool/objtool.h> bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, - validate_dup, vmlinux, mcount, noinstr, backup, sls, unret; + validate_dup, vmlinux, mcount, noinstr, backup, sls, unret, rethunk;static const char *const check_usage[] = {"objtool check [<options>] file.o" ,
@@ -36,6 +36,7 @@ const struct option check_options[] = {OPT_BOOLEAN ('f' ,"no-fp" , &no_fp,"Skip frame pointer validation" ),OPT_BOOLEAN ('u' ,"no-unreachable" , &no_unreachable,"Skip 'unreachable instruction' warnings" ),OPT_BOOLEAN ('r' ,"retpoline" , &retpoline,"Validate retpoline assumptions" ), +OPT_BOOLEAN (0 ,"rethunk" , &rethunk,"validate and annotate rethunk usage" ),OPT_BOOLEAN (0 ,"unret" , &unret,"validate entry unret placement" ),OPT_BOOLEAN ('m' ,"module" , &module,"Indicates the object will be part of a kernel module" ), OPT_BOOLEAN('b', "backtrace", &backtrace, "unwind on error"),
tools/objtool/check.c +7 -2
@@ -3440,8 +3440,11 @@ static int validate_retpoline(struct objcontinue ;if (insn->type ==INSN_RETURN ) { -WARN_FUNC ("'naked' return found in RETPOLINE build" , - insn->sec, insn->offset); +if (rethunk) { +WARN_FUNC ("'naked' return found in RETHUNK build" , + insn->sec, insn->offset); + }else +continue ; }else { WARN_FUNC("indirect %s found in RETPOLINE build", insn->sec, insn->offset,
@@ -3711,7 +3714,9 @@ int check(struct objtool_file *file)if (ret <0 ) goto out; warnings += ret; + } +if (rethunk) { ret =create_return_sites_sections (file);if (ret <0 ) goto out;
tools/objtool/include/objtool/builtin.h +1 -1
@@ -9,7 +9,7 @@extern const struct option check_options[];extern bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, - validate_dup, vmlinux, mcount, noinstr, backup, sls, unret; + validate_dup, vmlinux, mcount, noinstr, backup, sls, unret, rethunk;extern int cmd_parse_options (int argc,const char **argv,const char *const usage[]);
Greg Kroah-Hartman
maintainerPATCH 73/78 x86/bugs: Add Cannon lake to RETBleed affected CPU list
In reply to Greg Kroah-HartmanFrom: Pawan Gupta <[email protected]>
commit f54d45372c6ac9c993451de5e51312485f7d10bc upstream.
Cannon lake is also affected by RETBleed, add it to the list.
--- arch/x86/kernel/cpu/common.c | 1 + 1 file changed, 1 insertion(+)
arch/x86/kernel/cpu/common.c +1 -0
@@ -1132,6 +1132,7 @@ static const struct x86_cpu_id cpu_vuln_VULNBL_INTEL_STEPPINGS (SKYLAKE ,X86_STEPPING_ANY ,SRBDS |MMIO |RETBLEED ),VULNBL_INTEL_STEPPINGS (KABYLAKE_L ,X86_STEPPING_ANY ,SRBDS |MMIO |RETBLEED ),VULNBL_INTEL_STEPPINGS (KABYLAKE ,X86_STEPPING_ANY ,SRBDS |MMIO |RETBLEED ), +VULNBL_INTEL_STEPPINGS (CANNONLAKE_L ,X86_STEPPING_ANY ,RETBLEED ),VULNBL_INTEL_STEPPINGS (ICELAKE_L ,X86_STEPPING_ANY ,MMIO |MMIO_SBDS |RETBLEED ),VULNBL_INTEL_STEPPINGS (ICELAKE_D ,X86_STEPPING_ANY ,MMIO ), VULNBL_INTEL_STEPPINGS(ICELAKE_X, X86_STEPPING_ANY, MMIO),
Greg Kroah-Hartman
maintainerPATCH 74/78 x86/entry: Move PUSH_AND_CLEAR_REGS() back into error_entry
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 2c08b9b38f5b0f4a6c2d29be22b695e4ec4a556b upstream.
Commit
ee774dac0da1 ("x86/entry: Move PUSH_AND_CLEAR_REGS out of error_entry()")
moved PUSH_AND_CLEAR_REGS out of error_entry, into its own function, in part to avoid calling error_entry() for XenPV.
However, commit
7c81c0c9210c ("x86/entry: Avoid very early RET")
had to change that because the 'ret' was too early and moved it into idtentry, bloating the text size, since idtentry is expanded for every exception vector.
However, with the advent of xen_error_entry() in commit
d147553b64bad ("x86/xen: Add UNTRAIN_RET")
it became possible to remove PUSH_AND_CLEAR_REGS from idtentry, back into *error_entry().
--- arch/x86/entry/entry_64.S | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
arch/x86/entry/entry_64.S +6 -3
@@ -320,6 +320,8 @@ SYM_CODE_END(ret_from_fork) SYM_CODE_START_LOCAL(xen_error_entry) UNWIND_HINT_FUNC + PUSH_AND_CLEAR_REGS save_ret=1 + ENCODE_FRAME_POINTER 8 UNTRAIN_RET RET SYM_CODE_END(xen_error_entry)
@@ -331,9 +333,6 @@ SYM_CODE_END(xen_error_entry) */ .macro idtentry_body cfunc has_error_code:req - PUSH_AND_CLEAR_REGS - ENCODE_FRAME_POINTER - /* * Call error_entry() and switch to the task stack if from userspace. *
@@ -1014,6 +1013,10 @@ SYM_CODE_END(paranoid_exit) SYM_CODE_START_LOCAL(error_entry) UNWIND_HINT_FUNC cld + + PUSH_AND_CLEAR_REGS save_ret=1 + ENCODE_FRAME_POINTER 8 + testb $3, CS+8(%rsp) jz .Lerror_kernelspace
Greg Kroah-Hartman
maintainerPATCH 75/78 x86/bugs: Do not enable IBPB-on-entry when IBPB is not supported
In reply to Greg Kroah-HartmanFrom: Thadeu Lima de Souza Cascardo <[email protected]>
commit 2259da159fbe5dba8ac00b560cf00b6a6537fa18 upstream.
There are some VM configurations which have Skylake model but do not support IBPB. In those cases, when using retbleed=ibpb, userspace is going to be killed and kernel is going to panic.
If the CPU does not support IBPB, warn and proceed with the auto option. Also, do not fallback to IBPB on AMD/Hygon systems if it is not supported.
--- arch/x86/kernel/cpu/bugs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
arch/x86/kernel/cpu/bugs.c +5 -2
@@ -858,7 +858,10 @@ static void __init retbleed_select_mitigbreak ;case RETBLEED_CMD_IBPB : -if (IS_ENABLED (CONFIG_CPU_IBPB_ENTRY )) { +if (!boot_cpu_has (X86_FEATURE_IBPB )) { +pr_err ("WARNING: CPU does not support IBPB.\n" ); + goto do_cmd_auto; + }else if (IS_ENABLED (CONFIG_CPU_IBPB_ENTRY )) { retbleed_mitigation =RETBLEED_MITIGATION_IBPB ; }else {pr_err ("WARNING: kernel not compiled with CPU_IBPB_ENTRY.\n" );
@@ -873,7 +876,7 @@ do_cmd_auto: boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {if (IS_ENABLED (CONFIG_CPU_UNRET_ENTRY )) retbleed_mitigation =RETBLEED_MITIGATION_UNRET ; -else if (IS_ENABLED (CONFIG_CPU_IBPB_ENTRY )) +else if (IS_ENABLED (CONFIG_CPU_IBPB_ENTRY ) &&boot_cpu_has (X86_FEATURE_IBPB )) retbleed_mitigation =RETBLEED_MITIGATION_IBPB ; }
Greg Kroah-Hartman
maintainerPATCH 76/78 x86/kexec: Disable RET on kexec
In reply to Greg Kroah-HartmanFrom: Konrad Rzeszutek Wilk <[email protected]>
commit 697977d8415d61f3acbc4ee6d564c9dcf0309507 upstream.
All the invocations unroll to __x86_return_thunk and this file must be PIC independent.
This fixes kexec on 64-bit AMD boxes.
[ bp: Fix 32-bit build. ]
--- arch/x86/kernel/relocate_kernel_32.S | 25 +++++++++++++++++++------ arch/x86/kernel/relocate_kernel_64.S | 23 +++++++++++++++++------ 2 files changed, 36 insertions(+), 12 deletions(-)
arch/x86/kernel/relocate_kernel_32.S +19 -6
@@ -7,10 +7,12 @@ #include <linux/linkage.h> #include <asm/page_types.h> #include <asm/kexec.h> +#include <asm/nospec-branch.h> #include <asm/processor-flags.h> /* - * Must be relocatable PIC code callable as a C function + * Must be relocatable PIC code callable as a C function, in particular + * there must be a plain RET and not jump to return thunk. */ #define PTR(x) (x << 2)
@@ -91,7 +93,9 @@ SYM_CODE_START_NOALIGN(relocate_kernel) movl %edi, %eax addl $(identity_mapped - relocate_kernel), %eax pushl %eax - RET + ANNOTATE_UNRET_SAFE + ret + int3 SYM_CODE_END(relocate_kernel) SYM_CODE_START_LOCAL_NOALIGN(identity_mapped)
@@ -159,12 +163,15 @@ SYM_CODE_START_LOCAL_NOALIGN(identity_ma xorl %edx, %edx xorl %esi, %esi xorl %ebp, %ebp - RET + ANNOTATE_UNRET_SAFE + ret + int3 1: popl %edx movl CP_PA_SWAP_PAGE(%edi), %esp addl $PAGE_SIZE, %esp 2: + ANNOTATE_RETPOLINE_SAFE call *%edx /* get the re-entry point of the peer system */
@@ -190,7 +197,9 @@ SYM_CODE_START_LOCAL_NOALIGN(identity_ma movl %edi, %eax addl $(virtual_mapped - relocate_kernel), %eax pushl %eax - RET + ANNOTATE_UNRET_SAFE + ret + int3 SYM_CODE_END(identity_mapped) SYM_CODE_START_LOCAL_NOALIGN(virtual_mapped)
@@ -208,7 +217,9 @@ SYM_CODE_START_LOCAL_NOALIGN(virtual_map popl %edi popl %esi popl %ebx - RET + ANNOTATE_UNRET_SAFE + ret + int3 SYM_CODE_END(virtual_mapped) /* Do the copies */
@@ -271,7 +282,9 @@ SYM_CODE_START_LOCAL_NOALIGN(swap_pages) popl %edi popl %ebx popl %ebp - RET + ANNOTATE_UNRET_SAFE + ret + int3 SYM_CODE_END(swap_pages) .globl kexec_control_code_size
arch/x86/kernel/relocate_kernel_64.S +17 -6
@@ -13,7 +13,8 @@ #include <asm/unwind_hints.h> /* - * Must be relocatable PIC code callable as a C function + * Must be relocatable PIC code callable as a C function, in particular + * there must be a plain RET and not jump to return thunk. */ #define PTR(x) (x << 3)
@@ -104,7 +105,9 @@ SYM_CODE_START_NOALIGN(relocate_kernel) /* jump to identity mapped page */ addq $(identity_mapped - relocate_kernel), %r8 pushq %r8 - RET + ANNOTATE_UNRET_SAFE + ret + int3 SYM_CODE_END(relocate_kernel) SYM_CODE_START_LOCAL_NOALIGN(identity_mapped)
@@ -191,7 +194,9 @@ SYM_CODE_START_LOCAL_NOALIGN(identity_ma xorl %r14d, %r14d xorl %r15d, %r15d - RET + ANNOTATE_UNRET_SAFE + ret + int3 1: popq %rdx
@@ -210,7 +215,9 @@ SYM_CODE_START_LOCAL_NOALIGN(identity_ma call swap_pages movq $virtual_mapped, %rax pushq %rax - RET + ANNOTATE_UNRET_SAFE + ret + int3 SYM_CODE_END(identity_mapped) SYM_CODE_START_LOCAL_NOALIGN(virtual_mapped)
@@ -231,7 +238,9 @@ SYM_CODE_START_LOCAL_NOALIGN(virtual_map popq %r12 popq %rbp popq %rbx - RET + ANNOTATE_UNRET_SAFE + ret + int3 SYM_CODE_END(virtual_mapped) /* Do the copies */
@@ -288,7 +297,9 @@ SYM_CODE_START_LOCAL_NOALIGN(swap_pages) lea PAGE_SIZE(%rax), %rsi jmp 0b 3: - RET + ANNOTATE_UNRET_SAFE + ret + int3 SYM_CODE_END(swap_pages) .globl kexec_control_code_size
Greg Kroah-Hartman
maintainerPATCH 77/78 x86/speculation: Disable RRSBA behavior
In reply to Greg Kroah-HartmanFrom: Pawan Gupta <[email protected]>
commit 4ad3278df6fe2b0852b00d5757fc2ccd8e92c26e upstream.
Some Intel processors may use alternate predictors for RETs on RSB-underflow. This condition may be vulnerable to Branch History Injection (BHI) and intramode-BTI.
Kernel earlier added spectre_v2 mitigation modes (eIBRS+Retpolines, eIBRS+LFENCE, Retpolines) which protect indirect CALLs and JMPs against such attacks. However, on RSB-underflow, RET target prediction may fallback to alternate predictors. As a result, RET's predicted target may get influenced by branch history.
A new MSR_IA32_SPEC_CTRL bit (RRSBA_DIS_S) controls this fallback behavior when in kernel mode. When set, RETs will not take predictions from alternate predictors, hence mitigating RETs as well. Support for this is enumerated by CPUID.7.2.EDX[RRSBA_CTRL] (bit2).
For spectre v2 mitigation, when a user selects a mitigation that protects indirect CALLs and JMPs against BHI and intramode-BTI, set RRSBA_DIS_S also to protect RETs for RSB-underflow case.
--- arch/x86/include/asm/cpufeatures.h | 2 +- arch/x86/include/asm/msr-index.h | 9 +++++++++ arch/x86/kernel/cpu/bugs.c | 26 ++++++++++++++++++++++++++ arch/x86/kernel/cpu/scattered.c | 1 + tools/arch/x86/include/asm/msr-index.h | 9 +++++++++ 5 files changed, 46 insertions(+), 1 deletion(-)
arch/x86/include/asm/cpufeatures.h +1 -1
@@ -295,7 +295,7 @@#define X86_FEATURE_SGX1 (11*32+ 8)/* "" Basic SGX */ #define X86_FEATURE_SGX2 (11*32+ 9)/* "" SGX Enclave Dynamic Memory Management (EDMM) */ #define X86_FEATURE_ENTRY_IBPB (11*32+10)/* "" Issue an IBPB on kernel entry */ -/* FREE! (11*32+11) */ +#define X86_FEATURE_RRSBA_CTRL (11*32+11)/* "" RET prediction control */ #define X86_FEATURE_RETPOLINE (11*32+12)/* "" Generic Retpoline mitigation for Spectre variant 2 */ #define X86_FEATURE_RETPOLINE_LFENCE (11*32+13)/* "" Use LFENCE for Spectre variant 2 */ #define X86_FEATURE_RETHUNK (11*32+14)/* "" Use REturn THUNK */
arch/x86/include/asm/msr-index.h +9 -0
@@ -51,6 +51,8 @@#define SPEC_CTRL_STIBP BIT(SPEC_CTRL_STIBP_SHIFT)/* STIBP mask */ #define SPEC_CTRL_SSBD_SHIFT 2/* Speculative Store Bypass Disable bit */ #define SPEC_CTRL_SSBD BIT(SPEC_CTRL_SSBD_SHIFT)/* Speculative Store Bypass Disable */ +#define SPEC_CTRL_RRSBA_DIS_S_SHIFT 6/* Disable RRSBA behavior */ +#define SPEC_CTRL_RRSBA_DIS_S BIT(SPEC_CTRL_RRSBA_DIS_S_SHIFT)#define MSR_IA32_PRED_CMD 0x00000049/* Prediction Command */ #define PRED_CMD_IBPB BIT(0)/* Indirect Branch Prediction Barrier */
@@ -139,6 +141,13 @@* bit available to control VERW * behavior. */ +#define ARCH_CAP_RRSBA BIT(19)/* +* Indicates RET may use predictors +* other than the RSB. With eIBRS +* enabled predictions in kernel mode +* are restricted to targets in +* kernel. +*/ #define MSR_IA32_FLUSH_CMD 0x0000010b#define L1D_FLUSH BIT(0)/*
arch/x86/kernel/cpu/bugs.c +26 -0
@@ -1311,6 +1311,22 @@ static enum spectre_v2_mitigation __initreturn SPECTRE_V2_RETPOLINE ; } +/* Disable in-kernel use of non-RSB RET predictors */ +static void __init spec_ctrl_disable_kernel_rrsba (void ) +{ +u64 ia32_cap; + +if (!boot_cpu_has (X86_FEATURE_RRSBA_CTRL )) +return ; + + ia32_cap =x86_read_arch_cap_msr (); + +if (ia32_cap &ARCH_CAP_RRSBA ) { + x86_spec_ctrl_base |=SPEC_CTRL_RRSBA_DIS_S ; +write_spec_ctrl_current (x86_spec_ctrl_base, true); + } +} +static void __init spectre_v2_select_mitigation (void ) {enum spectre_v2_mitigation_cmd cmd =spectre_v2_parse_cmdline ();
@@ -1405,6 +1421,16 @@ static void __init spectre_v2_select_mitbreak ; } +/* +* Disable alternate RSB predictions in kernel when indirect CALLs and +* JMPs gets protection against BHI and Intramode-BTI, but RET +* prediction from a non-RSB predictor is still a risk. +*/ +if (mode ==SPECTRE_V2_EIBRS_LFENCE || + mode ==SPECTRE_V2_EIBRS_RETPOLINE || + mode ==SPECTRE_V2_RETPOLINE ) +spec_ctrl_disable_kernel_rrsba (); + spectre_v2_enabled = mode;pr_info ("%s\n" , spectre_v2_strings[mode]);
arch/x86/kernel/cpu/scattered.c +1 -0
@@ -26,6 +26,7 @@ struct cpuid_bit {static const struct cpuid_bit cpuid_bits[] = { {X86_FEATURE_APERFMPERF ,CPUID_ECX ,0 ,0x00000006 ,0 }, {X86_FEATURE_EPB ,CPUID_ECX ,3 ,0x00000006 ,0 }, + {X86_FEATURE_RRSBA_CTRL ,CPUID_EDX ,2 ,0x00000007 ,2 }, {X86_FEATURE_CQM_LLC ,CPUID_EDX ,1 ,0x0000000f ,0 }, {X86_FEATURE_CQM_OCCUP_LLC ,CPUID_EDX ,0 ,0x0000000f ,1 }, {X86_FEATURE_CQM_MBM_TOTAL ,CPUID_EDX ,1 ,0x0000000f ,1 },
tools/arch/x86/include/asm/msr-index.h +9 -0
@@ -51,6 +51,8 @@#define SPEC_CTRL_STIBP BIT(SPEC_CTRL_STIBP_SHIFT)/* STIBP mask */ #define SPEC_CTRL_SSBD_SHIFT 2/* Speculative Store Bypass Disable bit */ #define SPEC_CTRL_SSBD BIT(SPEC_CTRL_SSBD_SHIFT)/* Speculative Store Bypass Disable */ +#define SPEC_CTRL_RRSBA_DIS_S_SHIFT 6/* Disable RRSBA behavior */ +#define SPEC_CTRL_RRSBA_DIS_S BIT(SPEC_CTRL_RRSBA_DIS_S_SHIFT)#define MSR_IA32_PRED_CMD 0x00000049/* Prediction Command */ #define PRED_CMD_IBPB BIT(0)/* Indirect Branch Prediction Barrier */
@@ -138,6 +140,13 @@* bit available to control VERW * behavior. */ +#define ARCH_CAP_RRSBA BIT(19)/* +* Indicates RET may use predictors +* other than the RSB. With eIBRS +* enabled predictions in kernel mode +* are restricted to targets in +* kernel. +*/ #define MSR_IA32_FLUSH_CMD 0x0000010b#define L1D_FLUSH BIT(0)/*
Greg Kroah-Hartman
maintainerPATCH 78/78 x86/static_call: Serialize __static_call_fixup() properly
In reply to Greg Kroah-HartmanFrom: Thomas Gleixner <[email protected]>
commit c27c753ea6fd1237f4f96abf8b623d7bab505513 upstream.
__static_call_fixup() invokes __static_call_transform() without holding text_mutex, which causes lockdep to complain in text_poke_bp().
Adding the proper locking cures that, but as this is either used during early boot or during module finalizing, it's not required to use text_poke_bp(). Add an argument to __static_call_transform() which tells it to use text_poke_early() for it.
--- arch/x86/kernel/static_call.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
arch/x86/kernel/static_call.c +8 -5
@@ -25,7 +25,8 @@ static const u8 xor5rax[] = { 0x2e, 0x2estatic const u8 retinsn[] = {RET_INSN_OPCODE ,0xcc ,0xcc ,0xcc ,0xcc }; -static void __ref __static_call_transform (void *insn,enum insn_type type,void *func) +static void __ref __static_call_transform (void *insn,enum insn_type type, +void *func,bool modinit) {const void *emulate =NULL ;int size =CALL_INSN_SIZE ;
@@ -60,7 +61,7 @@ static void __ref __static_call_transforif (memcmp (insn, code, size) ==0 )return ; -if (unlikely (system_state ==SYSTEM_BOOTING )) +if (system_state ==SYSTEM_BOOTING || modinit)return text_poke_early (insn, code, size);text_poke_bp (insn, code, size, emulate);
@@ -108,12 +109,12 @@ void arch_static_call_transform(void *siif (tramp) {__static_call_validate (tramp, true); -__static_call_transform (tramp,__sc_insn (!func, true), func); +__static_call_transform (tramp,__sc_insn (!func, true), func, false); }if (IS_ENABLED (CONFIG_HAVE_STATIC_CALL_INLINE ) && site) {__static_call_validate (site, tail); -__static_call_transform (site,__sc_insn (!func, tail), func); +__static_call_transform (site,__sc_insn (!func, tail), func, false); }mutex_unlock (&text_mutex);
@@ -139,8 +140,10 @@ bool __static_call_fixup(void *tramp, u8return false; } +mutex_lock (&text_mutex);if (op ==RET_INSN_OPCODE || dest == &__x86_return_thunk) -__static_call_transform (tramp,RET ,NULL ); +__static_call_transform (tramp,RET ,NULL , true); +mutex_unlock (&text_mutex);return true; }
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.55 release. There are 78 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 14 Jul 2022 18:32:19 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.55-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels:
Signature · 1 line
Florian
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.55 release. There are 78 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 14 Jul 2022 18:32:19 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.55-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Quoted 5 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.55 release. There are 78 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Successfully cross-compiled for arm64 (bcm2711_defconfig, GCC 10.2.0) and powerpc (ps3_defconfig, GCC 12.1.0).
Signature · 1 line
An old man doll... just what I always wanted! - Clara
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.55 release. There are 78 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 14 Jul 2022 18:32:19 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.55-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.15:
10 builds: 10 pass, 0 fail
28 boots: 28 pass, 0 fail
114 tests: 114 pass, 0 failLinux version: 5.15.55-rc1-g0fe4fdf9b1da
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra194-p3509-0000+p3668-0000,
tegra20-ventana, tegra210-p2371-2180,
tegra210-p3450-0000, tegra30-cardhu-a04Jon
Hi Greg,
Quoted 7 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.55 release. There are 78 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 14 Jul 2022 18:32:19 +0000. Anything received after that time might be too late.
Build test (gcc version 11.3.1 20220706):
mips: 62 configs -> no failure
arm: 99 configs -> no failure
arm64: 3 configs -> no failurex86_64: 4 configs -> no failure
alpha allmodconfig -> no failure
csky allmodconfig -> no failure
powerpc allmodconfig -> no failure
riscv allmodconfig -> no failure
s390 allmodconfig -> no failure
xtensa allmodconfig -> no failure
Boot test:x86_64: Booted on my test laptop. No regression.x86_64: Booted on qemu. No regression. [1]
arm64: Booted on rpi4b (4GB model). No regression. [2]
mips: Booted on ci20 board. No regression. [3]
[1]. https://openqa.qa.codethink.co.uk/tests/1508
[2]. https://openqa.qa.codethink.co.uk/tests/1511
[3]. https://openqa.qa.codethink.co.uk/tests/1514
--
Regards
Sudip
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.55 release. There are 78 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 14 Jul 2022 18:32:19 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.55-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
Regressions on x86_64.
1) Kernel panic noticed on device x86_6 while running kvm-unit-tests.
- APIC base relocation is unsupported by KVM
2) while booting qemu-x86_64 the following warning noticed.
- WARNING: CPU: 0 PID: 0 at arch/x86/kernel/alternative.c:557apply_returns+0x19c/0x1d0
kernel panic log:
- https://lkft.validation.linaro.org/scheduler/job/5278112#L1703
TESTNAME=emulator TIMEOUT=90s ACCEL= ./x86/run x86/emulator.flat -smp 1
[ 67.774572] APIC base relocation is unsupported by KVM [ 105.643057] kvm: emulating exchange as write [ 105.653717] int3: 0000 [#1] SMP PTI [ 105.653720] CPU: 3 PID: 3747 Comm: qemu-system-x86 Not tainted 5.15.55-rc1 #1 [ 105.653721] Hardware name: Supermicro SYS-5019S-ML/X11SSH-F, BIOS 2.0b 07/27/2017 [ 105.653722] RIP: 0010:xaddw_ax_dx+0x9/0x10 [ 105.653727] Code: 00 0f bb d0 c3 cc cc cc cc 48 0f bb d0 c3 cc cc cc cc 0f 1f 80 00 00 00 00 0f c0 d0 c3 cc cc cc cc 66 0f c1 d0 c3 cc cc cc cc <0f> 1f 80 00 00 00 00 0f c1 d0 c3 cc cc cc cc 48 0f c1 d0 c3 cc cc [ 105.653728] RSP: 0018:ffffb98bc5157ce8 EFLAGS: 00000206 [ 105.653729] RAX: 0000000089abcdef RBX: 0000000000000001 RCX: 0000000000000000 [ 105.653730] RDX: 0000000076543210 RSI: ffffffff8ea56000 RDI: 0000000000000204 [ 105.653731] RBP: ffffb98bc5157cf0 R08: ffffa306c6cf5df0 R09: 0000000000000002 [ 105.653732] R10: ffffa306c6cf5df0 R11: 0000000000000000 R12: ffffa306c6cf5df0 [ 105.653733] R13: ffffffff900090c0 R14: 0000000000000000 R15: 0000000000000000 [ 105.653734] FS: 00007f30ab0df700(0000) GS:ffffa30a1fd80000(0000) knlGS:0000000000000000 [ 105.653735] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 105.653736] CR2: 0000000000000000 CR3: 000000014e0d0003 CR4: 00000000003726e0 [ 105.653736] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 105.653737] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 105.653738] Call Trace: [ 105.653738] <TASK> [ 105.653739] ? fastop+0x5d/0xa0 [ 105.653741] x86_emulate_insn+0x7c9/0xf20 [ 105.653743] x86_emulate_instruction+0x2e3/0x790 [ 105.653746] complete_emulated_mmio+0x238/0x310 [ 105.653748] kvm_arch_vcpu_ioctl_run+0x11ba/0x1a70 [ 105.653750] ? vfs_writev+0xcb/0x140 [ 105.653753] kvm_vcpu_ioctl+0x281/0x6b0 [ 105.653755] ? clockevents_program_event+0x98/0x100 [ 105.653757] ? selinux_file_ioctl+0xae/0x140 [ 105.653760] ? selinux_file_ioctl+0xae/0x140 [ 105.653762] __x64_sys_ioctl+0x95/0xd0 [ 105.653764] do_syscall_64+0x3b/0x90 [ 105.653767] entry_SYSCALL_64_after_hwframe+0x61/0xcb [ 105.653769] RIP: 0033:0x7f30aca698f7 [ 105.653770] Code: b3 66 90 48 8b 05 a1 35 2c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 71 35 2c 00 f7 d8 64 89 01 48 [ 105.653771] RSP: 002b:00007f30ab0dea28 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [ 105.653772] RAX: ffffffffffffffda RBX: 000000000000ae80 RCX: 00007f30aca698f7 [ 105.653773] RDX: 0000000000000000 RSI: 000000000000ae80 RDI: 000000000000000f [ 105.653774] RBP: 000055fb7fb6faf0 R08: 000055fb7d67c450 R09: 00000000ffffffff [ 105.653775] R10: 00000000000216a8 R11: 0000000000000246 R12: 0000000000000000 [ 105.653775] R13: 00007f30aed99000 R14: 0000000000000006 R15: 000055fb7fb6faf0 [ 105.653776] </TASK> [ 105.653777] Modules linked in: x86_pkg_temp_thermal [ 105.902123] ---[ end trace cec99cae36bcbfd7 ]--- [ 105.902124] RIP: 0010:xaddw_ax_dx+0x9/0x10 [ 105.902126] Code: 00 0f bb d0 c3 cc cc cc cc 48 0f bb d0 c3 cc cc cc cc 0f 1f 80 00 00 00 00 0f c0 d0 c3 cc cc cc cc 66 0f c1 d0 c3 cc cc cc cc <0f> 1f 80 00 00 00 00 0f c1 d0 c3 cc cc cc cc 48 0f c1 d0 c3 cc cc [ 105.902127] RSP: 0018:ffffb98bc5157ce8 EFLAGS: 00000206 [ 105.902127] RAX: 0000000089abcdef RBX: 0000000000000001 RCX: 0000000000000000 [ 105.902128] RDX: 0000000076543210 RSI: ffffffff8ea56000 RDI: 0000000000000204 [ 105.902129] RBP: ffffb98bc5157cf0 R08: ffffa306c6cf5df0 R09: 0000000000000002 [ 105.902129] R10: ffffa306c6cf5df0 R11: 0000000000000000 R12: ffffa306c6cf5df0 [ 105.902130] R13: ffffffff900090c0 R14: 0000000000000000 R15: 0000000000000000 [ 105.902130] FS: 00007f30ab0df700(0000) GS:ffffa30a1fd80000(0000) knlGS:0000000000000000 [ 105.902131] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 105.902132] CR2: 0000000000000000 CR3: 000000014e0d0003 CR4: 00000000003726e0 [ 105.902133] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 105.902133] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 105.902134] Kernel panic - not syncing: Fatal exception in interrupt [ 105.902170] Kernel Offset: 0xda00000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) [ 106.022663] ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]--- [ 106.030224] ------------[ cut here ]------------ [ 106.030224] sched: Unexpected reschedule of offline CPU#0! [ 106.030226] WARNING: CPU: 3 PID: 3747 at arch/x86/kernel/apic/ipi.c:68 native_smp_send_reschedule+0x3e/0x50 [ 106.030229] Modules linked in: x86_pkg_temp_thermal [ 106.030230] CPU: 3 PID: 3747 Comm: qemu-system-x86 Tainted: G D 5.15.55-rc1 #1 [ 106.030231] Hardware name: Supermicro SYS-5019S-ML/X11SSH-F, BIOS 2.0b 07/27/2017 [ 106.030232] RIP: 0010:native_smp_send_reschedule+0x3e/0x50 [ 106.030234] Code: 1b 48 8b 05 d4 70 a6 01 be fd 00 00 00 48 8b 40 30 e8 66 dc 31 01 5d c3 cc cc cc cc 89 fe 48 c7 c7 a0 e9 41 90 e8 1e c3 ea 00 <0f> 0b 5d c3 cc cc cc cc 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 [ 106.030234] RSP: 0018:ffffb98bc0160c60 EFLAGS: 00010086 [ 106.030235] RAX: 0000000000000000 RBX: ffffa30a1fc29b00 RCX: 0000000000000027 [ 106.030236] RDX: ffffa30a1fd9b4b8 RSI: 0000000000000001 RDI: ffffa30a1fd9b4b0 [ 106.030237] RBP: ffffb98bc0160c60 R08: ffffffff90b65665 R09: 0000000000000000 [ 106.030237] R10: 0000000000000030 R11: ffffffff90b65665 R12: ffffa306c097c100 [ 106.030238] R13: ffffb98bc0160d00 R14: ffffb98bc0160d00 R15: 0000000000000009 [ 106.030239] FS: 00007f30ab0df700(0000) GS:ffffa30a1fd80000(0000) knlGS:0000000000000000 [ 106.030239] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 106.030240] CR2: 0000000000000000 CR3: 000000014e0d0003 CR4: 00000000003726e0 [ 106.030241] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 106.030241] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 106.030242] Call Trace: [ 106.030242] <IRQ> [ 106.030243] resched_curr+0x52/0xb0 [ 106.030245] check_preempt_curr+0x3b/0x70 [ 106.030247] ttwu_do_wakeup+0x1c/0x160 [ 106.030249] ttwu_do_activate+0x94/0x190 [ 106.030251] try_to_wake_up+0x1c4/0x480 [ 106.030253] default_wake_function+0x1a/0x40 [ 106.030254] autoremove_wake_function+0x12/0x40 [ 106.030256] __wake_up_common+0x7d/0x140 [ 106.030258] __wake_up_common_lock+0x7c/0xc0 [ 106.030261] __wake_up+0x13/0x20 [ 106.030263] wake_up_klogd_work_func+0x7b/0x90 [ 106.030265] irq_work_single+0x46/0x80 [ 106.030267] irq_work_run_list+0x2a/0x40 [ 106.030269] irq_work_tick+0x3b/0x50 [ 106.030270] update_process_times+0xba/0xd0 [ 106.030272] tick_sched_handle+0x38/0x50 [ 106.030274] tick_sched_timer+0x8c/0xc0 [ 106.030276] ? can_stop_idle_tick+0xa0/0xa0 [ 106.030278] __hrtimer_run_queues+0xa6/0x2b0 [ 106.030280] hrtimer_interrupt+0x101/0x220 [ 106.030281] __sysvec_apic_timer_interrupt+0x61/0xe0 [ 106.030283] sysvec_apic_timer_interrupt+0x7b/0x90 [ 106.030285] </IRQ> [ 106.030285] <TASK> [ 106.030286] asm_sysvec_apic_timer_interrupt+0x1a/0x20 [ 106.030288] RIP: 0010:panic+0x277/0x2b6 [ 106.030290] Code: e8 65 ac 25 ff 48 c7 c6 80 04 b5 90 48 c7 c7 80 3f 42 90 e8 6a 58 00 00 c7 05 cc 8e f5 00 01 00 00 00 e8 d3 80 33 ff fb 31 db <4c> 39 eb 7c 1d 41 83 f4 01 48 8b 05 a0 d2 1b 01 44 89 e7 e8 18 16 [ 106.030291] RSP: 0018:ffffb98bc5157b10 EFLAGS: 00000246 [ 106.030292] RAX: ffffb98bc5157b80 RBX: 0000000000000000 RCX: 0000000000000027 [ 106.030292] RDX: 0000000000000000 RSI: ffffffff8f98de8f RDI: ffffffff8f99314d [ 106.030293] RBP: ffffb98bc5157b80 R08: ffffffff90b655fa R09: 0000000090b655d6 [ 106.030293] R10: ffffffffffffffff R11: ffffffffffffffff R12: 0000000000000000 [ 106.030294] R13: 0000000000000000 R14: ffffffff904131e0 R15: 0000000000000000 [ 106.030295] ? oops_end.cold+0xc/0x18 [ 106.030297] ? panic+0x274/0x2b6 [ 106.030299] oops_end.cold+0xc/0x18 [ 106.030300] die+0x43/0x60 [ 106.030302] exc_int3+0x137/0x160 [ 106.030303] asm_exc_int3+0x39/0x40 [ 106.030305] RIP: 0010:xaddw_ax_dx+0x9/0x10 [ 106.030307] Code: 00 0f bb d0 c3 cc cc cc cc 48 0f bb d0 c3 cc cc cc cc 0f 1f 80 00 00 00 00 0f c0 d0 c3 cc cc cc cc 66 0f c1 d0 c3 cc cc cc cc <0f> 1f 80 00 00 00 00 0f c1 d0 c3 cc cc cc cc 48 0f c1 d0 c3 cc cc [ 106.030308] RSP: 0018:ffffb98bc5157ce8 EFLAGS: 00000206 [ 106.030308] RAX: 0000000089abcdef RBX: 0000000000000001 RCX: 0000000000000000 [ 106.030309] RDX: 0000000076543210 RSI: ffffffff8ea56000 RDI: 0000000000000204 [ 106.030310] RBP: ffffb98bc5157cf0 R08: ffffa306c6cf5df0 R09: 0000000000000002 [ 106.030310] R10: ffffa306c6cf5df0 R11: 0000000000000000 R12: ffffa306c6cf5df0 [ 106.030311] R13: ffffffff900090c0 R14: 0000000000000000 R15: 0000000000000000 [ 106.030312] ? xaddw_ax_dx+0x8/0x10 [ 106.030314] ? xaddw_ax_dx+0x9/0x10 [ 106.030315] ? xaddw_ax_dx+0x8/0x10 [ 106.030317] ? fastop+0x5d/0xa0 [ 106.030319] x86_emulate_insn+0x7c9/0xf20 [ 106.030321] x86_emulate_instruction+0x2e3/0x790 [ 106.030323] complete_emulated_mmio+0x238/0x310 [ 106.030325] kvm_arch_vcpu_ioctl_run+0x11ba/0x1a70 [ 106.030327] ? vfs_writev+0xcb/0x140 [ 106.030330] kvm_vcpu_ioctl+0x281/0x6b0 [ 106.030331] ? clockevents_program_event+0x98/0x100 [ 106.030333] ? selinux_file_ioctl+0xae/0x140 [ 106.030335] ? selinux_file_ioctl+0xae/0x140 [ 106.030337] __x64_sys_ioctl+0x95/0xd0 [ 106.030339] do_syscall_64+0x3b/0x90 [ 106.030340] entry_SYSCALL_64_after_hwframe+0x61/0xcb [ 106.030342] RIP: 0033:0x7f30aca698f7 [ 106.030343] Code: b3 66 90 48 8b 05 a1 35 2c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 71 35 2c 00 f7 d8 64 89 01 48 [ 106.030343] RSP: 002b:00007f30ab0dea28 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [ 106.030344] RAX: ffffffffffffffda RBX: 000000000000ae80 RCX: 00007f30aca698f7 [ 106.030345] RDX: 0000000000000000 RSI: 000000000000ae80 RDI: 000000000000000f [ 106.030346] RBP: 000055fb7fb6faf0 R08: 000055fb7d67c450 R09: 00000000ffffffff [ 106.030346] R10: 00000000000216a8 R11: 0000000000000246 R12: 0000000000000000 [ 106.030347] R13: 00007f30aed99000 R14: 0000000000000006 R15: 000055fb7fb6faf0 [ 106.030348] </TASK> [ 106.030348] ---[ end trace cec99cae36bcbfd8 ]--- [ 106.030350] ------------[ cut here ]------------ [ 106.030350] sched: Unexpected reschedule of offline CPU#2! [ 106.030351] WARNING: CPU: 3 PID: 3747 at arch/x86/kernel/apic/ipi.c:68 native_smp_send_reschedule+0x3e/0x50 [ 106.030354] Modules linked in: x86_pkg_temp_thermal [ 106.030354] CPU: 3 PID: 3747 Comm: qemu-system-x86 Tainted: G D W 5.15.55-rc1 #1 [ 106.030355] Hardware name: Supermicro SYS-5019S-ML/X11SSH-F, BIOS 2.0b 07/27/2017 [ 106.030356] RIP: 0010:native_smp_send_reschedule+0x3e/0x50 [ 106.030357] Code: 1b 48 8b 05 d4 70 a6 01 be fd 00 00 00 48 8b 40 30 e8 66 dc 31 01 5d c3 cc cc cc cc 89 fe 48 c7 c7 a0 e9 41 90 e8 1e c3 ea 00 <0f> 0b 5d c3 cc cc cc cc 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 [ 106.030358] RSP: 0018:ffffb98bc0160b40 EFLAGS: 00010086 [ 106.030359] RAX: 0000000000000000 RBX: ffffa30a1fd29b00 RCX: 0000000000000027 [ 106.030360] RDX: ffffa30a1fd9b4b8 RSI: 0000000000000001 RDI: ffffa30a1fd9b4b0 [ 106.030360] RBP: ffffb98bc0160b40 R08: ffffffff90b66d1d R09: 0000000000000000 [ 106.030361] R10: 0000000000000030 R11: ffffffff90b66d1d R12: ffffa306c2216180 [ 106.030361] R13: ffffb98bc0160be0 R14: ffffb98bc0160be0 R15: 0000000000000009 [ 106.030362] FS: 00007f30ab0df700(0000) GS:ffffa30a1fd80000(0000) knlGS:0000000000000000 [ 106.030363] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 106.030364] CR2: 0000000000000000 CR3: 000000014e0d0003 CR4: 00000000003726e0 [ 106.030364] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 106.030365] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 106.030365] Call Trace: [ 106.030366] <IRQ> [ 106.030366] resched_curr+0x52/0xb0 [ 106.030368] check_preempt_curr+0x3b/0x70 [ 106.030369] ttwu_do_wakeup+0x1c/0x160 [ 106.030371] ttwu_do_activate+0x94/0x190 [ 106.030373] try_to_wake_up+0x1c4/0x480 [ 106.030375] default_wake_function+0x1a/0x40 [ 106.030377] autoremove_wake_function+0x12/0x40 [ 106.030378] __wake_up_common+0x7d/0x140 [ 106.030380] __wake_up_common_lock+0x7c/0xc0 [ 106.030382] __wake_up+0x13/0x20 [ 106.030384] ep_poll_callback+0x10e/0x290 [ 106.030386] __wake_up_common+0x7d/0x140 [ 106.030389] __wake_up_common_lock+0x7c/0xc0 [ 106.030391] __wake_up+0x13/0x20 [ 106.030393] wake_up_klogd_work_func+0x7b/0x90 [ 106.030395] irq_work_single+0x46/0x80 [ 106.030397] irq_work_run_list+0x2a/0x40 [ 106.030398] irq_work_tick+0x3b/0x50 [ 106.030400] update_process_times+0xba/0xd0 [ 106.030401] tick_sched_handle+0x38/0x50 [ 106.030403] tick_sched_timer+0x8c/0xc0 [ 106.030405] ? can_stop_idle_tick+0xa0/0xa0 [ 106.030407] __hrtimer_run_queues+0xa6/0x2b0 [ 106.030408] hrtimer_interrupt+0x101/0x220 [ 106.030410] __sysvec_apic_timer_interrupt+0x61/0xe0 [ 106.030411] sysvec_apic_timer_interrupt+0x7b/0x90 [ 106.030413] </IRQ> [ 106.030413] <TASK> [ 106.030414] asm_sysvec_apic_timer_interrupt+0x1a/0x20 [ 106.030416] RIP: 0010:panic+0x277/0x2b6 [ 106.030417] Code: e8 65 ac 25 ff 48 c7 c6 80 04 b5 90 48 c7 c7 80 3f 42 90 e8 6a 58 00 00 c7 05 cc 8e f5 00 01 00 00 00 e8 d3 80 33 ff fb 31 db <4c> 39 eb 7c 1d 41 83 f4 01 48 8b 05 a0 d2 1b 01 44 89 e7 e8 18 16 [ 106.030418] RSP: 0018:ffffb98bc5157b10 EFLAGS: 00000246 [ 106.030419] RAX: ffffb98bc5157b80 RBX: 0000000000000000 RCX: 0000000000000027 [ 106.030419] RDX: 0000000000000000 RSI: ffffffff8f98de8f RDI: ffffffff8f99314d [ 106.030420] RBP: ffffb98bc5157b80 R08: ffffffff90b655fa R09: 0000000090b655d6 [ 106.030420] R10: ffffffffffffffff R11: ffffffffffffffff R12: 0000000000000000 [ 106.030421] R13: 0000000000000000 R14: ffffffff904131e0 R15: 0000000000000000 [ 106.030422] ? oops_end.cold+0xc/0x18 [ 106.030423] ? panic+0x274/0x2b6 [ 106.030425] oops_end.cold+0xc/0x18 [ 106.030427] die+0x43/0x60 [ 106.030428] exc_int3+0x137/0x160 [ 106.030430] asm_exc_int3+0x39/0x40 [ 106.030431] RIP: 0010:xaddw_ax_dx+0x9/0x10 [ 106.030433] Code: 00 0f bb d0 c3 cc cc cc cc 48 0f bb d0 c3 cc cc cc cc 0f 1f 80 00 00 00 00 0f c0 d0 c3 cc cc cc cc 66 0f c1 d0 c3 cc cc cc cc <0f> 1f 80 00 00 00 00 0f c1 d0 c3 cc cc cc cc 48 0f c1 d0 c3 cc cc [ 106.030434] RSP: 0018:ffffb98bc5157ce8 EFLAGS: 00000206 [ 106.030434] RAX: 0000000089abcdef RBX: 0000000000000001 RCX: 0000000000000000 [ 106.030435] RDX: 0000000076543210 RSI: ffffffff8ea56000 RDI: 0000000000000204 [ 106.030436] RBP: ffffb98bc5157cf0 R08: ffffa306c6cf5df0 R09: 0000000000000002 [ 106.030436] R10: ffffa306c6cf5df0 R11: 0000000000000000 R12: ffffa306c6cf5df0 [ 106.030437] R13: ffffffff900090c0 R14: 0000000000000000 R15: 0000000000000000 [ 106.030437] ? xaddw_ax_dx+0x8/0x10 [ 106.030439] ? xaddw_ax_dx+0x9/0x10 [ 106.030441] ? xaddw_ax_dx+0x8/0x10 [ 106.030443] ? fastop+0x5d/0xa0 [ 106.030445] x86_emulate_insn+0x7c9/0xf20 [ 106.030446] x86_emulate_instruction+0x2e3/0x790 [ 106.030449] complete_emulated_mmio+0x238/0x310 [ 106.030450] kvm_arch_vcpu_ioctl_run+0x11ba/0x1a70 [ 106.030453] ? vfs_writev+0xcb/0x140 [ 106.030455] kvm_vcpu_ioctl+0x281/0x6b0 [ 106.030456] ? clockevents_program_event+0x98/0x100 [ 106.030458] ? selinux_file_ioctl+0xae/0x140 [ 106.030460] ? selinux_file_ioctl+0xae/0x140 [ 106.030462] __x64_sys_ioctl+0x95/0xd0 [ 106.030464] do_syscall_64+0x3b/0x90 [ 106.030465] entry_SYSCALL_64_after_hwframe+0x61/0xcb [ 106.030467] RIP: 0033:0x7f30aca698f7 [ 106.030468] Code: b3 66 90 48 8b 05 a1 35 2c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 71 35 2c 00 f7 d8 64 89 01 48 [ 106.030468] RSP: 002b:00007f30ab0dea28 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [ 106.030469] RAX: ffffffffffffffda RBX: 000000000000ae80 RCX: 00007f30aca698f7 [ 106.030470] RDX: 0000000000000000 RSI: 000000000000ae80 RDI: 000000000000000f [ 106.030470] RBP: 000055fb7fb6faf0 R08: 000055fb7d67c450 R09: 00000000ffffffff [ 106.030471] R10: 00000000000216a8 R11: 0000000000000246 R12: 0000000000000000 [ 106.030472] R13: 00007f30aed99000 R14: 0000000000000006 R15: 000055fb7fb6faf0 [ 106.030473] </TASK> [ 106.030473] ---[ end trace cec99cae36bcbfd9 ]---
2. Kernel warning
- https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.15.y/build/v5.15.54-79-g0fe4fdf9b1da/testrun/10799646/suite/log-parser-test/tests/
<6>[ 0.571674] Speculative Store Bypass: Vulnerable <6>[ 0.573329] MDS: Vulnerable: Clear CPU buffers attempted, no microcode <4>[ 0.942716] ------------[ cut here ]------------ <4>[ 0.944263] WARNING: CPU: 0 PID: 0 at arch/x86/kernel/alternative.c:557 apply_returns+0x19c/0x1d0 <4>[ 0.945106] Modules linked in: <4>[ 0.946322] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.15.55-rc1 #1 <4>[ 0.947052] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.14.0-2 04/01/2014 <4>[ 0.947844] RIP: 0010:apply_returns+0x19c/0x1d0 <4>[ 0.948453] Code: 8d 7d c8 4c 89 75 c1 4c 89 74 08 f8 48 29 f8 8d 0c 02 4c 89 f0 c1 e9 03 f3 48 ab 8b 05 9d ba 52 02 85 c0 74 a0 e9 45 32 1a 01 <0f> 0b 48 83 c3 04 49 39 dd 0f 87 96 fe ff ff e9 0f ff ff ff c7 45 <4>[ 0.950059] RSP: 0000:ffffffff89803d78 EFLAGS: 00000206 <4>[ 0.950484] RAX: 0000000000000000 RBX: ffffffff89dbb174 RCX: 0000000000000000 <4>[ 0.951033] RDX: ffffffff891011b5 RSI: 00000000000000e9 RDI: ffffffff891011b0 <4>[ 0.951488] RBP: ffffffff89803e40 R08: 0000000000000000 R09: 0000000000000001 <4>[ 0.952032] R10: 0000000000000029 R11: 0000000000000000 R12: ffffffff891011b0 <4>[ 0.952488] R13: ffffffff89ddb184 R14: cccccccccccccccc R15: ffffffff891011b5 <4>[ 0.953125] FS: 0000000000000000(0000) GS:ffff90f63fc00000(0000) knlGS:0000000000000000 <4>[ 0.953634] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 <4>[ 0.954031] CR2: ffff90f63fa01000 CR3: 000000003e826000 CR4: 00000000000006f0 <4>[ 0.954669] Call Trace: <4>[ 0.955846] <TASK> <4>[ 0.957183] alternative_instructions+0x7d/0x146 <4>[ 0.957673] check_bugs+0xf16/0xf57 <4>[ 0.958114] start_kernel+0x6b6/0x6ef <4>[ 0.958446] x86_64_start_reservations+0x24/0x2a <4>[ 0.958764] x86_64_start_kernel+0x8d/0x95 <4>[ 0.959035] secondary_startup_64_no_verify+0xc2/0xcb <4>[ 0.959591] </TASK> <4>[ 0.960146] irq event stamp: 121171 <4>[ 0.960419] hardirqs last enabled at (121179): [<ffffffff87a7247c>] __up_console_sem+0x5c/0x70 <4>[ 0.961036] hardirqs last disabled at (121188): [<ffffffff87a72461>] __up_console_sem+0x41/0x70 <4>[ 0.961577] softirqs last enabled at (1484): [<ffffffff87ad3f20>] cgroup_idr_alloc.constprop.0+0x60/0xe0 <4>[ 0.962031] softirqs last disabled at (1482): [<ffffffff87ad3ef3>] cgroup_idr_alloc.constprop.0+0x33/0xe0 <4>[ 0.963358] ---[ end trace 7af0f35d34a8be8b ]--- <6>[ 1.100332] Freeing SMP alternatives memory: 52K <6>[ 1.233988] smpboot: CPU0: Intel Core i7 9xx (Nehalem Class Core i7) (family: 0x6, model: 0x1a, stepping: 0x3) <6>[ 1.266761] Running RCU-tasks wait API self tests <6>[ 1.271070] Performance Events: unsupported p6 CPU model 26 no PMU driver, software events only. <6>[ 1.276776] rcu: Hierarchical SRCU implementation. <6>[ 1.281153] Callback from call_rcu_ta# sks_trace() invoked. <6>[ 1.308215] smp: Bringing up secondary CPUs ... <6>[ 1.322732] x86: Booting SMP configuration: <6>[ 1.323121] .... node #0, CPUs: #1 <6>[ 1.361239] smp: Brought up 1 node, 2 CPUs
## Build
* kernel: 5.15.55-rc1
* git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc
* git branch: linux-5.15.y
* git commit: 0fe4fdf9b1dac90e23465eefeff45e529adcf3c6
* git describe: v5.15.54-79-g0fe4fdf9b1da
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.15.y/build/v5.15.54-79-g0fe4fdf9b1da
## Test Regressions (compared to v5.15.53-227-g71721f5974f2) kernel crash regression found.
## Metric Regressions (compared to v5.15.53-227-g71721f5974f2) No metric regressions found.
## Test Fixes (compared to v5.15.53-227-g71721f5974f2) No test fixes found.
## Metric Fixes (compared to v5.15.53-227-g71721f5974f2) No metric fixes found.
## Test result summary
total: 137556, pass: 124337, fail: 404, skip: 12121, xfail: 694
## Build Summary
* arc: 10 total, 10 passed, 0 failed
* arm: 308 total, 308 passed, 0 failed
* arm64: 62 total, 62 passed, 0 failed
* i386: 52 total, 49 passed, 3 failed
* mips: 48 total, 48 passed, 0 failed
* parisc: 12 total, 12 passed, 0 failed
* powerpc: 54 total, 52 passed, 2 failed
* riscv: 22 total, 22 passed, 0 failed
* s390: 21 total, 21 passed, 0 failed
* sh: 24 total, 24 passed, 0 failed
* sparc: 12 total, 12 passed, 0 failed
* x86_64: 56 total, 55 passed, 1 failed
## Test suites summary
* fwts
* kunit
* kvm-unit-tests
* libgpiod
* libhugetlbfs
* log-parser-boot
* log-parser-test
* ltp-cap_bounds
* ltp-commands
* ltp-containers
* ltp-controllers
* ltp-cpuhotplug
* ltp-crypto
* ltp-cve
* ltp-dio
* ltp-fcntl-locktests
* ltp-filecaps
* ltp-fs
* ltp-fs_bind
* ltp-fs_perms_simple
* ltp-fsx
* ltp-hugetlb
* ltp-io
* ltp-ipc
* ltp-math
* ltp-mm
* ltp-nptl
* ltp-open-posix-tests
* ltp-pty
* ltp-sched
* ltp-securebits
* ltp-smoke
* ltp-syscalls
* ltp-tracing
* network-basic-tests
* packetdrill
* perf
* perf/Zstd-perf.data-compression
* rcutorture
* ssuite
* v4l2-compliance
* vdso
--
Linaro LKFT
https://lkft.linaro.org
Quoted 21 lines · Naresh Kamboju
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.55 release. There are 78 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 14 Jul 2022 18:32:19 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.55-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
Quoted 8 lines
Results from Linaro’s test farm.
Regressions onx86_64.1) Kernel panic noticed on device
x86_6while running kvm-unit-tests.
- APIC base relocation is unsupported by KVM
Looking into the log, I don't think that message is related to the crash.
[ 67.774572] APIC base relocation is unsupported by KVM [ 105.643057] kvm: emulating exchange as write <--- warning [ 105.653717] int3: 0000 [#1] SMP PTI [ 105.653720] CPU: 3 PID: 3747 Comm: qemu-system-x86 Not tainted 5.15.55-rc1 #1 [ 105.653721] Hardware name: Supermicro SYS-5019S-ML/X11SSH-F, BIOS 2.0b 07/27/2017 [ 105.653722] RIP: 0010:xaddw_ax_dx+0x9/0x10 ... [ 105.653777] Modules linked in: x86_pkg_temp_thermal [ 105.902123] ---[ end trace cec99cae36bcbfd7 ]--- [ 105.902124] RIP: 0010:xaddw_ax_dx+0x9/0x10 <--- crash [ 105.902126] Code: 00 0f bb d0 c3 cc cc cc cc 48 0f bb d0 c3 cc cc
Guenter
Quoted 8 lines · Guenter Roeck
Looking into the log, I don't think that message is related to the crash.
...
[ 105.653777] Modules linked in: x86_pkg_temp_thermal [ 105.902123] ---[ end trace cec99cae36bcbfd7 ]--- [ 105.902124] RIP: 0010:xaddw_ax_dx+0x9/0x10 <--- crash [ 105.902126] Code: 00 0f bb d0 c3 cc cc cc cc 48 0f bb d0 c3 cc cc
Yeah, the code you snipped, shows
20: 66 0f c1 d0 xadd %dx,%ax
24: c3 ret 25: cc int3 26: cc int3 27: cc int3 28: cc int3 29:* 0f 1f 80 00 00 00 00 nopl 0x0(%rax) <-- trapping instruction 30: 0f c1 d0 xadd %edx,%eax 33: c3 ret 34: cc int3 35: cc int3 36: cc int3 37: cc int3
38: 48 0f c1 d0 xadd %rdx,%rax
3c: c3 ret
3d: cc int3
and that's a bit odd.
It says "xaddw_ax_dx+0x9/0x10", but I think somebody jumped to "xaddw_ax_dx+8", hit the 'int3', and the RIP points to the next instruction (because that's how int3 works).
And the fastop code says:
* fastop functions have a special calling convention:
...
* Moreover, they are all exactly FASTOP_SIZE bytes long,
but that is clearly *NOT* the case for xaddw_ax_dx, because it's 16 bytes in size, and the other ones are 8 bytes. That's where the "nopl" comes from: it's the alignment instruction to the next fastop function.
Compare that to the word-sized 'xaddl' case rigth afterwards: that one *is* just 8 bytes in size, so the 64-byte 'xaddq' comes 8 bytes aftrer it, and there's no 7-byte padding nop-instruction.
So I think that that is where the "xaddw_ax_dx+8" comes from: some code assumes that FASTOP_SIZE is 8, but that xaddw_ax_dx case was actually 9 bytes and thus got that "int3 + padding" in the next 8 bytes.
The whole kvm x86 emulation thiing is quite complicated and has lots of instruction size #defines and magic.
I'm not familiar enough with it to go "Ahh, it's obviously XYZ", but I'm sure PeterZ and Borislav know exactly what's going on.
Linus
Quoted 11 lines · Linus Torvalds
So I think that that is where the "xaddw_ax_dx+8" comes from: some code assumes that
FASTOP_SIZEis 8, but thatxaddw_ax_dxcase was actually 9 bytes and thus got that "int3 + padding" in the next 8 bytes.The whole kvm x86 emulation thing is quite complicated and has lots of instruction size #defines and magic.
I'm not familiar enough with it to go "Ahh, it's obviously XYZ", but I'm sure PeterZ and Borislav know exactly what's going on.
And I see that Thadeau already figured it out:
https://lore.kernel.org/all/[email protected]/
So presumably we need that patch everywhere.
Linus
Quoted 5 lines · Linus Torvalds
And I see that Thadeau already figured it out:
https://lore.kernel.org/all/[email protected]/
So presumably we need that patch everywhere.
Right, I've queued it along with other fallout fixes. Will do some testing before I send them to you on Sunday.
I'm guessing you're thinking of cutting an -rc7 so that people can test the whole retbleed mitigation disaster an additional week?
Thx.
Signature · 4 lines
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquettePaolo Bonzini
maintainerQuoted 11 lines · Borislav Petkov
Quoted 5 lines · Linus Torvalds
And I see that Thadeau already figured it out:
https://lore.kernel.org/all/[email protected]/So presumably we need that patch everywhere.
Right, I've queued it along with other fallout fixes. Will do some testing before I send them to you on Sunday.
I'm guessing you're thinking of cutting an -rc7 so that people can test the whole retbleed mitigation disaster an additional week?
Please leave that one out as Peter suggested a better fix and I have that queued for Linus.
(If you don't no big deal, the conflict will be very clear, but it will be a bit more work for everyone).
Paolo
Quoted 1 line · Paolo Bonzini
Please leave that one out as Peter suggested a better fix and I have that queued for Linus.
Already zapped.
Thx.
Signature · 1 line
Sent from a small device: formatting sux and brevity is inevitable.
Quoted 5 lines · Boris Petkov
Quoted 1 line · Paolo Bonzini
Please leave that one out as Peter suggested a better fix and I have that queued for Linus.
Already zapped.
I like Peter's more obvious use of FASTYOP_LENGTH, but this is just disgusting:
#define FASTOP_SIZE (8 << ((FASTOP_LENGTH > 8) & 1) <<
((FASTOP_LENGTH > 16) & 1))
I mean, I understand what it's doing, but just two lines above it the code has a "ilog2()" use that already depends on the fact that you can use ilog2() as a constant compile-time expression.
And guess what? The code could just use roundup_pow_of_two(), which is designed exactly like ilog2() to be used for compile-time constant values.
So the code should just use
#define FASTOP_SIZE roundup_pow_of_two(FASTOP_LENGTH)
and be a lot more legible, wouldn't it?
Because I don't think there is anything magical about the length "8/16/32". It's purely "aligned and big enough to contain FASTOP_LENGTH".
And then the point of that
static_assert(FASTOP_LENGTH <= FASTOP_SIZE);
just goes away, because there are no subtle math issues there any more.
In fact, the remaining question is just "where did the 7 come from" in
#define FASTOP_LENGTH (7 + ENDBR_INSN_SIZE + RET_LENGTH)
because other than that it all looks fairly straightforward.
Linus
Paolo Bonzini
maintainerQuoted 6 lines · Linus Torvalds
And guess what? The code could just use
roundup_pow_of_two(), which is designed exactly likeilog2()to be used for compile-time constant values.So the code should just use
Quoted 7 lines
#define FASTOP_SIZE roundup_pow_of_two(FASTOP_LENGTH)and be a lot more legible, wouldn't it?
Because I don't think there is anything magical about the length "8/16/32". It's purely "aligned and big enough to contain
FASTOP_LENGTH".
roundup_pow_of_two unfortunately is not enough for stringizing FASTOP_SIZE into an asm statement. :(
#define __FOP_FUNC(name) \ ".align " __stringify(FASTOP_SIZE) " \n\t" \ ".type " name ", @function \n\t" \ name ":\n\t" \ ASM_ENDBR
The shifts are what we came up with for the SETCC thunks when ENDBR and SLS made them grew beyond 4 bytes; Peter's patch is reusing the trick for the fastop thunks.
Quoted 3 lines
Because I don't think there is anything magical about the length "8/16/32". It's purely "aligned and big enough to contain
FASTOP_LENGTH".
I agree with that, it's only limited to 8/16/32 to keep the macro to a decent size.
Quoted 9 lines
And then the point of that
static_assert(FASTOP_LENGTH <= FASTOP_SIZE);just goes away, because there are no subtle math issues there any more.
In fact, the remaining question is just "where did the 7 come from" in
#define FASTOP_LENGTH (7 + ENDBR_INSN_SIZE + RET_LENGTH)
The 7 is an upper limit to the length of the code between endbr and ret.
There's no particular reason to limit to 7, but it allows using an alignment of 8 in the smallest case (no thunks, no SLS, no endbr) where you just have ".align 8; ...; ret".
Paolo
Quoted 5 lines · Linus Torvalds
I like Peter's more obvious use of
FASTYOP_LENGTH, but this is just disgusting:#define FASTOP_SIZE (8 << ((FASTOP_LENGTH > 8) & 1) <<((
FASTOP_LENGTH> 16) & 1))
Quoted 7 lines
I mean, I understand what it's doing, but just two lines above it the code has a "
ilog2()" use that already depends on the fact that you can useilog2()as a constant compile-time expression.And guess what? The code could just use
roundup_pow_of_two(), which is designed exactly likeilog2()to be used for compile-time constant values.
But NR_FASTOP isn't used in ASM.
Quoted 5 lines
So the code should just use
#define FASTOP_SIZE roundup_pow_of_two(FASTOP_LENGTH)and be a lot more legible, wouldn't it?
If only :/ FASTOP_SIZE is used in ASM, which means we've got to play by GNU-as rules, and them are aweful.
Quoted 3 lines · Peter Zijlstra
If only :/
FASTOP_SIZEis used in ASM, which means we've got to play by GNU-as rules, and they are awful.
Oh Gods. Yes they are.
Linus
Oh, btw, how bad would it be to just do
#define FASTOP_SIZE 16
static_assert(FASTOP_SIZE >= FASTOP_LENGTH)
and leave it at that?
Afaik both gcc and clang default to -falign-functions=16 *anyway*, and while on 32-bit x86 we have options to minimize alignment, we don't do that on x86-64 afaik.
In fact, we have an option to force *bigger* alignment (DEBUG_FORCE_FUNCTION_ALIGN_64B) but not any way to make it less.
And we use
.p2align 4
in most of our asm, aling with
#define __ALIGN .p2align 4, 0x90
So all the *normal* functions already get 16-byte alignment anyway.
So yeah, it would be less dense, but do we care? Wouldn't the "this is really simple" be a nice thing? It's not like there are a ton of those fastop functions anyway. 128 of them? Plus 16 of the "setCC" ones?
Linus
Quoted 3 lines · Linus Torvalds
So yeah, it would be less dense, but do we care? Wouldn't the "this is really simple" be a nice thing? It's not like there are a ton of those fastop functions anyway. 128 of them? Plus 16 of the "setCC" ones?
I definitely like simple.
Along with a comment why we have this magic 16 there.
Signature · 1 line
Sent from a small device: formatting sux and brevity is inevitable.
Paolo Bonzini
maintainerQuoted 4 lines · Linus Torvalds
Oh, btw, how bad would it be to just do
#define
FASTOP_SIZE16
static_assert(FASTOP_SIZE >= FASTOP_LENGTH)
Yeah, for 32 I might have some (probably irrational) qualms, but 16 is not worth the trouble.
Given 3 bytes for ENDBR, 5 for the return thunk and 1 for the straight line speculation INT3, there are 7 bytes left and only 4 are currently used (for instructions encoded as "66 0f xx xx"). So FASTOP_SIZE at SETCC_ALIGN can indeed be 16 unconditionally.
Paolo
Quoted 3 lines · Borislav Petkov
I'm guessing you're thinking of cutting an -rc7 so that people can test the whole retbleed mitigation disaster an additional week?
Oh, absolutely. Doing an -rc7 is normal.
Right now the question isn't whether an rc7 happens, but whether we'll need an rc8. We'll see.
Oh, I do hate the hw-embargoed stuff that doesn't get all the usual testing in all our automation.
Linus
Quoted 1 line · Linus Torvalds
Oh, absolutely. Doing an -rc7 is normal.
Good. I'm gathering all the fallout fixes and will send them to you on Sunday, if nothing unexpected happens.
Quoted 2 lines
Right now the question isn't whether an rc7 happens, but whether we'll need an rc8. We'll see.
Right, we'll see what additional fallout happens next week. I'll try to Cc you on such reports so that you're aware.
Quoted 2 lines
Oh, I do hate the hw-embargoed stuff that doesn't get all the usual testing in all our automation.
Tell me about it.
Thx.
Signature · 4 lines
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquetteQuoted 6 lines · Borislav Petkov
Quoted 1 line · Linus Torvalds
Oh, absolutely. Doing an -rc7 is normal.
Good. I'm gathering all the fallout fixes and will send them to you on Sunday, if nothing unexpected happens.
Btw, I assume that includes the clang fix for thex86_spec_ctrl_current section attribute.
That's kind of personally embarrassing that it slipped through: I do all my normal test builds that I actually *boot* with clang.
But since I kept all of the embargoed stuff outside my normal trees, it also meant that the test builds I did didn't have my "this is my clang tree" stuff in it.
And so I - like apparently everybody else - only did those builds with gcc.
And gcc for some reason doesn't care about this whole "you redeclared that variable with a different attribute" thing.
And sadly, our percpu accessor functions don't verify these things either, so you can write code like this:
unsigned long myvariable;
unsigned long test_fn(void)
{
return this_cpu_read(myvariable);
}and the compiler will not complain about anything at all, and happily generate completely nonsensical code like
movq %gs:myvariable(%rip), %rax
for it, which will do entirely the wrong thing because 'myvariable' wasn't allocated in the percpu section.
In the 'x86_spec_ctrl_current' case, that nonsensical code _worked_ (with gcc), because despite the declaration being for a regular variable, the actual definition was in the proper segment.
But that 'myvariable' thing above does end up being another example of how we are clearly missing some type checkng in this area.
I'm not sure if there's any way to get that section mismatch at compile-time at all. For the static declarations, we could just make DECLARE_PER_CPU() add some prefix/postfix to the name (and obviously then do it at use time too).
We have that '__pcpu_scope_##name' thing to make sure of globally unique naming due to the whole weak type thing. I wonder if we could do something similar to verify that "yes, this has been declared as a percpu variable" at use time?
Linus
Quoted 10 lines · Linus Torvalds
Quoted 6 lines · Borislav Petkov
Quoted 1 line · Linus Torvalds
Oh, absolutely. Doing an -rc7 is normal.
Good. I'm gathering all the fallout fixes and will send them to you on Sunday, if nothing unexpected happens.
Btw, I assume that includes the clang fix for the
x86_spec_ctrl_currentsection attribute.
Yap. Here's the current lineup:
https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/log/?h=x86/urgent
Quoted 11 lines
That's kind of personally embarrassing that it slipped through: I do all my normal test builds that I actually *boot* with clang.
But since I kept all of the embargoed stuff outside my normal trees, it also meant that the test builds I did didn't have my "this is my clang tree" stuff in it.
And so I - like apparently everybody else - only did those builds with gcc.
And gcc for some reason doesn't care about this whole "you redeclared that variable with a different attribute" thing.
... so why does clang care? Or, why doesn't gcc care?
I guess I need to talk to gcc folks again.
Quoted 3 lines
In the '
x86_spec_ctrl_current' case, that nonsensical code _worked_ (with gcc), because despite the declaration being for a regular variable, the actual definition was in the proper segment.
I'm guessing this is the reason why gcc doesn't fail - it probably looks at the declaration but doesn't care too much about it. And it is the definition that matters.
While clang goes, uh, ah, declaration and definition mismatch, I better warn.
Quoted 5 lines
But that 'myvariable' thing above does end up being another example of how we are clearly missing some type checkng in this area.
I'm not sure if there's any way to get that section mismatch at compile-time at all.
Well, apparently, clang can:
arch/x86/kernel/cpu/bugs.c:58:21: error: section attribute is specified on redeclared variable [-Werror,-Wsection]
so there's a -Wsection warning which gcc could implement too.
Quoted 8 lines
For the static declarations, we could just make
DECLARE_PER_CPU()add some prefix/postfix to the name (and obviously then do it at use time too).We have that '__pcpu_scope_##name' thing to make sure of globally unique naming due to the whole weak type thing. I wonder if we could do something similar to verify that "yes, this has been declared as a percpu variable" at use time?
But how?
We need to save the info how a var has been declared and then use that info at access time.
Yeah, lemme bother compiler guys a bit...
Signature · 4 lines
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquetteQuoted 21 lines · Naresh Kamboju
Quoted 15 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.55 release. There are 78 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 14 Jul 2022 18:32:19 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.55-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y and the diffstat can be found below.Quoted 3 lines
thanks,
greg k-h
Quoted 7 lines
Results from Linaro’s test farm.
Regressions onx86_64.1) Kernel panic noticed on device
x86_6while running kvm-unit-tests.
- APIC base relocation is unsupported by KVM
My 0.2 cent:
APIC base relocation warning is harmless, and I removed it 5.19 kernel:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v5.19-rc6&id=3743c2f0251743b8ae968329708bbbeefff244cf
The 'emulating exchange as write' is also something that KVM unit tests trigger
normally although this warning recently did signal a real and very nasty bug, which I fixed in this commit:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v5.19-rc6&id=33fbe6befa622c082f7d417896832856814bdde0
FYI, Another 'pr_info_ratelimited' message from KVM that you will see when running the unit tests is this "kvm: vcpu 0: requested 2000 ns lapic timer period limited to 200000 ns"
It is also harmless, but I do wonder how much value it adds.
And the panic I guess was already figured out.
BTW, there is a script in the kernel source, called decode_stacktrace (./scripts/decode_stacktrace.sh)
It is very useful to figure out, on which source line the panic/oops was triggered, you might want to consider using it in the report.
(I do wish the kernel had a debug option, of 'I don't care about kernel addresses/info leaks', please print all the info you can in the stacktrace).
Best regards,
Maxim Levitsky
Quoted 462 lines
2) while booting qemu-x86_64 the following warning noticed.
- WARNING: CPU: 0 PID: 0 atarch/x86/kernel/alternative.c:557apply_returns+0x19c/0x1d0kernel panic log:
- https://lkft.validation.linaro.org/scheduler/job/5278112#L1703
TESTNAME=emulator TIMEOUT=90s ACCEL= ./x86/run x86/emulator.flat -smp 1 [ 67.774572] APIC base relocation is unsupported by KVM
[ 105.643057] kvm: emulating exchange as write
[ 105.653717] int3: 0000 [#1] SMP PTI
[ 105.653720] CPU: 3 PID: 3747 Comm: qemu-system-x86 Not tainted 5.15.55-rc1 #1 [ 105.653721] Hardware name: Supermicro SYS-5019S-ML/X11SSH-F, BIOS 2.0b 07/27/2017
[ 105.653722] RIP: 0010:xaddw_ax_dx+0x9/0x10
[ 105.653727] Code: 00 0f bb d0 c3 cc cc cc cc 48 0f bb d0 c3 cc cc cc cc 0f 1f 80 00 00 00 00 0f c0 d0 c3 cc cc cc cc 66 0f c1 d0 c3 cc cc cc cc <0f> 1f 80 00 00 00 00 0f c1 d0 c3 cc cc cc cc 48 0f c1 d0 c3 cc cc
[ 105.653728] RSP: 0018:ffffb98bc5157ce8 EFLAGS: 00000206
[ 105.653729] RAX:0000000089abcdefRBX: 0000000000000001 RCX: 0000000000000000 [ 105.653730] RDX: 0000000076543210 RSI:ffffffff8ea56000RDI: 0000000000000204 [ 105.653731] RBP:ffffb98bc5157cf0R08:ffffa306c6cf5df0R09: 0000000000000002 [ 105.653732] R10:ffffa306c6cf5df0R11: 0000000000000000 R12:ffffa306c6cf5df0[ 105.653733] R13:ffffffff900090c0R14: 0000000000000000 R15: 0000000000000000 [ 105.653734] FS: 00007f30ab0df700(0000) GS:ffffa30a1fd80000(0000) knlGS:0000000000000000
[ 105.653735] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 105.653736] CR2: 0000000000000000 CR3:000000014e0d0003CR4:00000000003726e0[ 105.653736] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 105.653737] DR3: 0000000000000000 DR6:00000000fffe0ff0DR7: 0000000000000400 [ 105.653738] Call Trace:
[ 105.653738] <TASK>
[ 105.653739] ?fastop+0x5d/0xa0
[ 105.653741]x86_emulate_insn+0x7c9/0xf20
[ 105.653743]x86_emulate_instruction+0x2e3/0x790
[ 105.653746]complete_emulated_mmio+0x238/0x310
[ 105.653748]kvm_arch_vcpu_ioctl_run+0x11ba/0x1a70
[ 105.653750] ?vfs_writev+0xcb/0x140
[ 105.653753]kvm_vcpu_ioctl+0x281/0x6b0
[ 105.653755] ?clockevents_program_event+0x98/0x100
[ 105.653757] ?selinux_file_ioctl+0xae/0x140
[ 105.653760] ?selinux_file_ioctl+0xae/0x140
[ 105.653762]__x64_sys_ioctl+0x95/0xd0
[ 105.653764]do_syscall_64+0x3b/0x90
[ 105.653767]entry_SYSCALL_64_after_hwframe+0x61/0xcb
[ 105.653769] RIP: 0033:0x7f30aca698f7
[ 105.653770] Code: b3 66 90 48 8b 05 a1 35 2c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 71 35 2c 00 f7 d8 64 89 01 48
[ 105.653771] RSP: 002b:00007f30ab0dea28 EFLAGS: 00000246ORIG_RAX:
0000000000000010
[ 105.653772] RAX: ffffffffffffffda RBX:000000000000ae80RCX:00007f30aca698f7[ 105.653773] RDX: 0000000000000000 RSI:000000000000ae80RDI:000000000000000f[ 105.653774] RBP:000055fb7fb6faf0R08:000055fb7d67c450R09:00000000ffffffff[ 105.653775] R10:00000000000216a8R11: 0000000000000246 R12: 0000000000000000 [ 105.653775] R13:00007f30aed99000R14: 0000000000000006 R15:000055fb7fb6faf0[ 105.653776] </TASK>
[ 105.653777] Modules linked in:x86_pkg_temp_thermal
[ 105.902123] ---[ end tracecec99cae36bcbfd7]---
[ 105.902124] RIP: 0010:xaddw_ax_dx+0x9/0x10
[ 105.902126] Code: 00 0f bb d0 c3 cc cc cc cc 48 0f bb d0 c3 cc cc cc cc 0f 1f 80 00 00 00 00 0f c0 d0 c3 cc cc cc cc 66 0f c1 d0 c3 cc cc cc cc <0f> 1f 80 00 00 00 00 0f c1 d0 c3 cc cc cc cc 48 0f c1 d0 c3 cc cc
[ 105.902127] RSP: 0018:ffffb98bc5157ce8 EFLAGS: 00000206
[ 105.902127] RAX:0000000089abcdefRBX: 0000000000000001 RCX: 0000000000000000 [ 105.902128] RDX: 0000000076543210 RSI:ffffffff8ea56000RDI: 0000000000000204 [ 105.902129] RBP:ffffb98bc5157cf0R08:ffffa306c6cf5df0R09: 0000000000000002 [ 105.902129] R10:ffffa306c6cf5df0R11: 0000000000000000 R12:ffffa306c6cf5df0[ 105.902130] R13:ffffffff900090c0R14: 0000000000000000 R15: 0000000000000000 [ 105.902130] FS: 00007f30ab0df700(0000) GS:ffffa30a1fd80000(0000) knlGS:0000000000000000
[ 105.902131] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 105.902132] CR2: 0000000000000000 CR3:000000014e0d0003CR4:00000000003726e0[ 105.902133] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 105.902133] DR3: 0000000000000000 DR6:00000000fffe0ff0DR7: 0000000000000400 [ 105.902134] Kernel panic - not syncing: Fatal exception in interrupt [ 105.902170] Kernel Offset:0xda00000from0xffffffff81000000(relocation range: 0xffffffff80000000-0xffffffffbfffffff)
[ 106.022663] ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]---
[ 106.030224] ------------[ cut here ]------------
[ 106.030224] sched: Unexpected reschedule of offline CPU#0!
[ 106.030226] WARNING: CPU: 3 PID: 3747 atarch/x86/kernel/apic/ipi.c:68native_smp_send_reschedule+0x3e/0x50[ 106.030229] Modules linked in:x86_pkg_temp_thermal
[ 106.030230] CPU: 3 PID: 3747 Comm: qemu-system-x86 Tainted: G
D 5.15.55-rc1 #1
[ 106.030231] Hardware name: Supermicro SYS-5019S-ML/X11SSH-F, BIOS 2.0b 07/27/2017
[ 106.030232] RIP: 0010:native_smp_send_reschedule+0x3e/0x50
[ 106.030234] Code: 1b 48 8b 05 d4 70 a6 01 be fd 00 00 00 48 8b 40 30 e8 66 dc 31 01 5d c3 cc cc cc cc 89 fe 48 c7 c7 a0 e9 41 90 e8 1e c3 ea 00 <0f> 0b 5d c3 cc cc cc cc 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00
[ 106.030234] RSP: 0018:ffffb98bc0160c60 EFLAGS: 00010086
[ 106.030235] RAX: 0000000000000000 RBX:ffffa30a1fc29b00RCX: 0000000000000027 [ 106.030236] RDX:ffffa30a1fd9b4b8RSI: 0000000000000001 RDI:ffffa30a1fd9b4b0[ 106.030237] RBP:ffffb98bc0160c60R08:ffffffff90b65665R09: 0000000000000000 [ 106.030237] R10: 0000000000000030 R11:ffffffff90b65665R12:ffffa306c097c100[ 106.030238] R13:ffffb98bc0160d00R14:ffffb98bc0160d00R15: 0000000000000009 [ 106.030239] FS: 00007f30ab0df700(0000) GS:ffffa30a1fd80000(0000) knlGS:0000000000000000
[ 106.030239] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 106.030240] CR2: 0000000000000000 CR3:000000014e0d0003CR4:00000000003726e0[ 106.030241] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 106.030241] DR3: 0000000000000000 DR6:00000000fffe0ff0DR7: 0000000000000400 [ 106.030242] Call Trace:
[ 106.030242] <IRQ>
[ 106.030243]resched_curr+0x52/0xb0
[ 106.030245]check_preempt_curr+0x3b/0x70
[ 106.030247]ttwu_do_wakeup+0x1c/0x160
[ 106.030249]ttwu_do_activate+0x94/0x190
[ 106.030251]try_to_wake_up+0x1c4/0x480
[ 106.030253]default_wake_function+0x1a/0x40
[ 106.030254]autoremove_wake_function+0x12/0x40
[ 106.030256]__wake_up_common+0x7d/0x140
[ 106.030258]__wake_up_common_lock+0x7c/0xc0
[ 106.030261]__wake_up+0x13/0x20
[ 106.030263]wake_up_klogd_work_func+0x7b/0x90
[ 106.030265]irq_work_single+0x46/0x80
[ 106.030267]irq_work_run_list+0x2a/0x40
[ 106.030269]irq_work_tick+0x3b/0x50
[ 106.030270]update_process_times+0xba/0xd0
[ 106.030272]tick_sched_handle+0x38/0x50
[ 106.030274]tick_sched_timer+0x8c/0xc0
[ 106.030276] ?can_stop_idle_tick+0xa0/0xa0
[ 106.030278]__hrtimer_run_queues+0xa6/0x2b0
[ 106.030280]hrtimer_interrupt+0x101/0x220
[ 106.030281]__sysvec_apic_timer_interrupt+0x61/0xe0
[ 106.030283]sysvec_apic_timer_interrupt+0x7b/0x90
[ 106.030285] </IRQ>
[ 106.030285] <TASK>
[ 106.030286]asm_sysvec_apic_timer_interrupt+0x1a/0x20
[ 106.030288] RIP: 0010:panic+0x277/0x2b6
[ 106.030290] Code: e8 65 ac 25 ff 48 c7 c6 80 04 b5 90 48 c7 c7 80 3f 42 90 e8 6a 58 00 00 c7 05 cc 8e f5 00 01 00 00 00 e8 d3 80 33 ff fb 31 db <4c> 39 eb 7c 1d 41 83 f4 01 48 8b 05 a0 d2 1b 01 44 89 e7 e8 18 16
[ 106.030291] RSP: 0018:ffffb98bc5157b10 EFLAGS: 00000246
[ 106.030292] RAX:ffffb98bc5157b80RBX: 0000000000000000 RCX: 0000000000000027 [ 106.030292] RDX: 0000000000000000 RSI:ffffffff8f98de8fRDI:ffffffff8f99314d[ 106.030293] RBP:ffffb98bc5157b80R08:ffffffff90b655faR09:0000000090b655d6[ 106.030293] R10: ffffffffffffffff R11: ffffffffffffffff R12: 0000000000000000 [ 106.030294] R13: 0000000000000000 R14:ffffffff904131e0R15: 0000000000000000 [ 106.030295] ?oops_end.cold+0xc/0x18
[ 106.030297] ?panic+0x274/0x2b6
[ 106.030299]oops_end.cold+0xc/0x18
[ 106.030300]die+0x43/0x60
[ 106.030302]exc_int3+0x137/0x160
[ 106.030303]asm_exc_int3+0x39/0x40
[ 106.030305] RIP: 0010:xaddw_ax_dx+0x9/0x10
[ 106.030307] Code: 00 0f bb d0 c3 cc cc cc cc 48 0f bb d0 c3 cc cc cc cc 0f 1f 80 00 00 00 00 0f c0 d0 c3 cc cc cc cc 66 0f c1 d0 c3 cc cc cc cc <0f> 1f 80 00 00 00 00 0f c1 d0 c3 cc cc cc cc 48 0f c1 d0 c3 cc cc
[ 106.030308] RSP: 0018:ffffb98bc5157ce8 EFLAGS: 00000206
[ 106.030308] RAX:0000000089abcdefRBX: 0000000000000001 RCX: 0000000000000000 [ 106.030309] RDX: 0000000076543210 RSI:ffffffff8ea56000RDI: 0000000000000204 [ 106.030310] RBP:ffffb98bc5157cf0R08:ffffa306c6cf5df0R09: 0000000000000002 [ 106.030310] R10:ffffa306c6cf5df0R11: 0000000000000000 R12:ffffa306c6cf5df0[ 106.030311] R13:ffffffff900090c0R14: 0000000000000000 R15: 0000000000000000 [ 106.030312] ?xaddw_ax_dx+0x8/0x10
[ 106.030314] ?xaddw_ax_dx+0x9/0x10
[ 106.030315] ?xaddw_ax_dx+0x8/0x10
[ 106.030317] ?fastop+0x5d/0xa0
[ 106.030319]x86_emulate_insn+0x7c9/0xf20
[ 106.030321]x86_emulate_instruction+0x2e3/0x790
[ 106.030323]complete_emulated_mmio+0x238/0x310
[ 106.030325]kvm_arch_vcpu_ioctl_run+0x11ba/0x1a70
[ 106.030327] ?vfs_writev+0xcb/0x140
[ 106.030330]kvm_vcpu_ioctl+0x281/0x6b0
[ 106.030331] ?clockevents_program_event+0x98/0x100
[ 106.030333] ?selinux_file_ioctl+0xae/0x140
[ 106.030335] ?selinux_file_ioctl+0xae/0x140
[ 106.030337]__x64_sys_ioctl+0x95/0xd0
[ 106.030339]do_syscall_64+0x3b/0x90
[ 106.030340]entry_SYSCALL_64_after_hwframe+0x61/0xcb
[ 106.030342] RIP: 0033:0x7f30aca698f7
[ 106.030343] Code: b3 66 90 48 8b 05 a1 35 2c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 71 35 2c 00 f7 d8 64 89 01 48
[ 106.030343] RSP: 002b:00007f30ab0dea28 EFLAGS: 00000246ORIG_RAX:
0000000000000010
[ 106.030344] RAX: ffffffffffffffda RBX:000000000000ae80RCX:00007f30aca698f7[ 106.030345] RDX: 0000000000000000 RSI:000000000000ae80RDI:000000000000000f[ 106.030346] RBP:000055fb7fb6faf0R08:000055fb7d67c450R09:00000000ffffffff[ 106.030346] R10:00000000000216a8R11: 0000000000000246 R12: 0000000000000000 [ 106.030347] R13:00007f30aed99000R14: 0000000000000006 R15:000055fb7fb6faf0[ 106.030348] </TASK>
[ 106.030348] ---[ end tracecec99cae36bcbfd8]---
[ 106.030350] ------------[ cut here ]------------
[ 106.030350] sched: Unexpected reschedule of offline CPU#2!
[ 106.030351] WARNING: CPU: 3 PID: 3747 atarch/x86/kernel/apic/ipi.c:68native_smp_send_reschedule+0x3e/0x50[ 106.030354] Modules linked in:x86_pkg_temp_thermal
[ 106.030354] CPU: 3 PID: 3747 Comm: qemu-system-x86 Tainted: G
D W 5.15.55-rc1 #1
[ 106.030355] Hardware name: Supermicro SYS-5019S-ML/X11SSH-F, BIOS 2.0b 07/27/2017
[ 106.030356] RIP: 0010:native_smp_send_reschedule+0x3e/0x50
[ 106.030357] Code: 1b 48 8b 05 d4 70 a6 01 be fd 00 00 00 48 8b 40 30 e8 66 dc 31 01 5d c3 cc cc cc cc 89 fe 48 c7 c7 a0 e9 41 90 e8 1e c3 ea 00 <0f> 0b 5d c3 cc cc cc cc 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00
[ 106.030358] RSP: 0018:ffffb98bc0160b40 EFLAGS: 00010086
[ 106.030359] RAX: 0000000000000000 RBX:ffffa30a1fd29b00RCX: 0000000000000027 [ 106.030360] RDX:ffffa30a1fd9b4b8RSI: 0000000000000001 RDI:ffffa30a1fd9b4b0[ 106.030360] RBP:ffffb98bc0160b40R08:ffffffff90b66d1dR09: 0000000000000000 [ 106.030361] R10: 0000000000000030 R11:ffffffff90b66d1dR12:ffffa306c2216180[ 106.030361] R13:ffffb98bc0160be0R14:ffffb98bc0160be0R15: 0000000000000009 [ 106.030362] FS: 00007f30ab0df700(0000) GS:ffffa30a1fd80000(0000) knlGS:0000000000000000
[ 106.030363] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 106.030364] CR2: 0000000000000000 CR3:000000014e0d0003CR4:00000000003726e0[ 106.030364] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 106.030365] DR3: 0000000000000000 DR6:00000000fffe0ff0DR7: 0000000000000400 [ 106.030365] Call Trace:
[ 106.030366] <IRQ>
[ 106.030366]resched_curr+0x52/0xb0
[ 106.030368]check_preempt_curr+0x3b/0x70
[ 106.030369]ttwu_do_wakeup+0x1c/0x160
[ 106.030371]ttwu_do_activate+0x94/0x190
[ 106.030373]try_to_wake_up+0x1c4/0x480
[ 106.030375]default_wake_function+0x1a/0x40
[ 106.030377]autoremove_wake_function+0x12/0x40
[ 106.030378]__wake_up_common+0x7d/0x140
[ 106.030380]__wake_up_common_lock+0x7c/0xc0
[ 106.030382]__wake_up+0x13/0x20
[ 106.030384]ep_poll_callback+0x10e/0x290
[ 106.030386]__wake_up_common+0x7d/0x140
[ 106.030389]__wake_up_common_lock+0x7c/0xc0
[ 106.030391]__wake_up+0x13/0x20
[ 106.030393]wake_up_klogd_work_func+0x7b/0x90
[ 106.030395]irq_work_single+0x46/0x80
[ 106.030397]irq_work_run_list+0x2a/0x40
[ 106.030398]irq_work_tick+0x3b/0x50
[ 106.030400]update_process_times+0xba/0xd0
[ 106.030401]tick_sched_handle+0x38/0x50
[ 106.030403]tick_sched_timer+0x8c/0xc0
[ 106.030405] ?can_stop_idle_tick+0xa0/0xa0
[ 106.030407]__hrtimer_run_queues+0xa6/0x2b0
[ 106.030408]hrtimer_interrupt+0x101/0x220
[ 106.030410]__sysvec_apic_timer_interrupt+0x61/0xe0
[ 106.030411]sysvec_apic_timer_interrupt+0x7b/0x90
[ 106.030413] </IRQ>
[ 106.030413] <TASK>
[ 106.030414]asm_sysvec_apic_timer_interrupt+0x1a/0x20
[ 106.030416] RIP: 0010:panic+0x277/0x2b6
[ 106.030417] Code: e8 65 ac 25 ff 48 c7 c6 80 04 b5 90 48 c7 c7 80 3f 42 90 e8 6a 58 00 00 c7 05 cc 8e f5 00 01 00 00 00 e8 d3 80 33 ff fb 31 db <4c> 39 eb 7c 1d 41 83 f4 01 48 8b 05 a0 d2 1b 01 44 89 e7 e8 18 16
[ 106.030418] RSP: 0018:ffffb98bc5157b10 EFLAGS: 00000246
[ 106.030419] RAX:ffffb98bc5157b80RBX: 0000000000000000 RCX: 0000000000000027 [ 106.030419] RDX: 0000000000000000 RSI:ffffffff8f98de8fRDI:ffffffff8f99314d[ 106.030420] RBP:ffffb98bc5157b80R08:ffffffff90b655faR09:0000000090b655d6[ 106.030420] R10: ffffffffffffffff R11: ffffffffffffffff R12: 0000000000000000 [ 106.030421] R13: 0000000000000000 R14:ffffffff904131e0R15: 0000000000000000 [ 106.030422] ?oops_end.cold+0xc/0x18
[ 106.030423] ?panic+0x274/0x2b6
[ 106.030425]oops_end.cold+0xc/0x18
[ 106.030427]die+0x43/0x60
[ 106.030428]exc_int3+0x137/0x160
[ 106.030430]asm_exc_int3+0x39/0x40
[ 106.030431] RIP: 0010:xaddw_ax_dx+0x9/0x10
[ 106.030433] Code: 00 0f bb d0 c3 cc cc cc cc 48 0f bb d0 c3 cc cc cc cc 0f 1f 80 00 00 00 00 0f c0 d0 c3 cc cc cc cc 66 0f c1 d0 c3 cc cc cc cc <0f> 1f 80 00 00 00 00 0f c1 d0 c3 cc cc cc cc 48 0f c1 d0 c3 cc cc
[ 106.030434] RSP: 0018:ffffb98bc5157ce8 EFLAGS: 00000206
[ 106.030434] RAX:0000000089abcdefRBX: 0000000000000001 RCX: 0000000000000000 [ 106.030435] RDX: 0000000076543210 RSI:ffffffff8ea56000RDI: 0000000000000204 [ 106.030436] RBP:ffffb98bc5157cf0R08:ffffa306c6cf5df0R09: 0000000000000002 [ 106.030436] R10:ffffa306c6cf5df0R11: 0000000000000000 R12:ffffa306c6cf5df0[ 106.030437] R13:ffffffff900090c0R14: 0000000000000000 R15: 0000000000000000 [ 106.030437] ?xaddw_ax_dx+0x8/0x10
[ 106.030439] ?xaddw_ax_dx+0x9/0x10
[ 106.030441] ?xaddw_ax_dx+0x8/0x10
[ 106.030443] ?fastop+0x5d/0xa0
[ 106.030445]x86_emulate_insn+0x7c9/0xf20
[ 106.030446]x86_emulate_instruction+0x2e3/0x790
[ 106.030449]complete_emulated_mmio+0x238/0x310
[ 106.030450]kvm_arch_vcpu_ioctl_run+0x11ba/0x1a70
[ 106.030453] ?vfs_writev+0xcb/0x140
[ 106.030455]kvm_vcpu_ioctl+0x281/0x6b0
[ 106.030456] ?clockevents_program_event+0x98/0x100
[ 106.030458] ?selinux_file_ioctl+0xae/0x140
[ 106.030460] ?selinux_file_ioctl+0xae/0x140
[ 106.030462]__x64_sys_ioctl+0x95/0xd0
[ 106.030464]do_syscall_64+0x3b/0x90
[ 106.030465]entry_SYSCALL_64_after_hwframe+0x61/0xcb
[ 106.030467] RIP: 0033:0x7f30aca698f7
[ 106.030468] Code: b3 66 90 48 8b 05 a1 35 2c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 71 35 2c 00 f7 d8 64 89 01 48
[ 106.030468] RSP: 002b:00007f30ab0dea28 EFLAGS: 00000246ORIG_RAX:
0000000000000010
[ 106.030469] RAX: ffffffffffffffda RBX:000000000000ae80RCX:00007f30aca698f7[ 106.030470] RDX: 0000000000000000 RSI:000000000000ae80RDI:000000000000000f[ 106.030470] RBP:000055fb7fb6faf0R08:000055fb7d67c450R09:00000000ffffffff[ 106.030471] R10:00000000000216a8R11: 0000000000000246 R12: 0000000000000000 [ 106.030472] R13:00007f30aed99000R14: 0000000000000006 R15:000055fb7fb6faf0[ 106.030473] </TASK>
[ 106.030473] ---[ end tracecec99cae36bcbfd9]---2. Kernel warning
- https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.15.y/build/v5.15.54-79-g0fe4fdf9b1da/testrun/10799646/suite/log-parser-test/tests/
<6>[ 0.571674] Speculative Store Bypass: Vulnerable
<6>[ 0.573329] MDS: Vulnerable: Clear CPU buffers attempted, no microcode
<4>[ 0.942716] ------------[ cut here ]------------
<4>[ 0.944263] WARNING: CPU: 0 PID: 0 atarch/x86/kernel/alternative.c:557apply_returns+0x19c/0x1d0
<4>[ 0.945106] Modules linked in:
<4>[ 0.946322] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.15.55-rc1 #1
<4>[ 0.947052] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009),
BIOS 1.14.0-2 04/01/2014
<4>[ 0.947844] RIP: 0010:apply_returns+0x19c/0x1d0
<4>[ 0.948453] Code: 8d 7d c8 4c 89 75 c1 4c 89 74 08 f8 48 29 f8
8d 0c 02 4c 89 f0 c1 e9 03 f3 48 ab 8b 05 9d ba 52 02 85 c0 74 a0 e9
45 32 1a 01 <0f> 0b 48 83 c3 04 49 39 dd 0f 87 96 fe ff ff e9 0f ff ff
ff c7 45
<4>[ 0.950059] RSP: 0000:ffffffff89803d78 EFLAGS: 00000206
<4>[ 0.950484] RAX: 0000000000000000 RBX:ffffffff89dbb174RCX:
0000000000000000
<4>[ 0.951033] RDX:ffffffff891011b5RSI:00000000000000e9RDI:ffffffff891011b0
<4>[ 0.951488] RBP:ffffffff89803e40R08: 0000000000000000 R09:
0000000000000001
<4>[ 0.952032] R10: 0000000000000029 R11: 0000000000000000 R12:ffffffff891011b0
<4>[ 0.952488] R13:ffffffff89ddb184R14: cccccccccccccccc R15:ffffffff891011b5
<4>[ 0.953125] FS: 0000000000000000(0000)
GS:ffff90f63fc00000(0000) knlGS:0000000000000000
<4>[ 0.953634] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
<4>[ 0.954031] CR2:ffff90f63fa01000CR3:000000003e826000CR4:00000000000006f0
<4>[ 0.954669] Call Trace:
<4>[ 0.955846] <TASK>
<4>[ 0.957183]alternative_instructions+0x7d/0x146
<4>[ 0.957673]check_bugs+0xf16/0xf57
<4>[ 0.958114]start_kernel+0x6b6/0x6ef
<4>[ 0.958446]x86_64_start_reservations+0x24/0x2a
<4>[ 0.958764]x86_64_start_kernel+0x8d/0x95
<4>[ 0.959035]secondary_startup_64_no_verify+0xc2/0xcb
<4>[ 0.959591] </TASK>
<4>[ 0.960146] irq event stamp: 121171
<4>[ 0.960419] hardirqs last enabled at (121179):
[<ffffffff87a7247c>]__up_console_sem+0x5c/0x70
<4>[ 0.961036] hardirqs last disabled at (121188):
[<ffffffff87a72461>]__up_console_sem+0x41/0x70
<4>[ 0.961577] softirqs last enabled at (1484):
[<ffffffff87ad3f20>] cgroup_idr_alloc.constprop.0+0x60/0xe0
<4>[ 0.962031] softirqs last disabled at (1482):
[<ffffffff87ad3ef3>] cgroup_idr_alloc.constprop.0+0x33/0xe0
<4>[ 0.963358] ---[ end trace7af0f35d34a8be8b]---
<6>[ 1.100332] Freeing SMP alternatives memory: 52K
<6>[ 1.233988] smpboot: CPU0: Intel Core i7 9xx (Nehalem Class Core
i7) (family:0x6, model:0x1a, stepping:0x3)
<6>[ 1.266761] Running RCU-tasks wait API self tests
<6>[ 1.271070] Performance Events: unsupported p6 CPU model 26 no
PMU driver, software events only.
<6>[ 1.276776] rcu: Hierarchical SRCU implementation.
<6>[ 1.281153] Callback from call_rcu_ta#sks_trace()invoked.
<6>[ 1.308215] smp: Bringing up secondary CPUs ...
<6>[ 1.322732] x86: Booting SMP configuration:
<6>[ 1.323121] .... node #0, CPUs: #1
<6>[ 1.361239] smp: Brought up 1 node, 2 CPUs## Build
* kernel: 5.15.55-rc1
* git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc
* git branch: linux-5.15.y
* git commit:0fe4fdf9b1dac90e23465eefeff45e529adcf3c6
* git describe: v5.15.54-79-g0fe4fdf9b1da
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.15.y/build/v5.15.54-79-g0fe4fdf9b1da## Test Regressions (compared to v5.15.53-227-g71721f5974f2) kernel crash regression found.
## Metric Regressions (compared to v5.15.53-227-g71721f5974f2) No metric regressions found.
## Test Fixes (compared to v5.15.53-227-g71721f5974f2) No test fixes found.
## Metric Fixes (compared to v5.15.53-227-g71721f5974f2) No metric fixes found.
## Test result summary
total: 137556, pass: 124337, fail: 404, skip: 12121, xfail: 694## Build Summary
* arc: 10 total, 10 passed, 0 failed
* arm: 308 total, 308 passed, 0 failed
* arm64: 62 total, 62 passed, 0 failed
* i386: 52 total, 49 passed, 3 failed
* mips: 48 total, 48 passed, 0 failed
* parisc: 12 total, 12 passed, 0 failed
* powerpc: 54 total, 52 passed, 2 failed
* riscv: 22 total, 22 passed, 0 failed
* s390: 21 total, 21 passed, 0 failed
* sh: 24 total, 24 passed, 0 failed
* sparc: 12 total, 12 passed, 0 failed
*x86_64: 56 total, 55 passed, 1 failed## Test suites summary
* fwts
* kunit
* kvm-unit-tests
* libgpiod
* libhugetlbfs
* log-parser-boot
* log-parser-test
* ltp-cap_bounds
* ltp-commands
* ltp-containers
* ltp-controllers
* ltp-cpuhotplug
* ltp-crypto
* ltp-cve
* ltp-dio
* ltp-fcntl-locktests
* ltp-filecaps
* ltp-fs
* ltp-fs_bind
* ltp-fs_perms_simple
* ltp-fsx
* ltp-hugetlb
* ltp-io
* ltp-ipc
* ltp-math
* ltp-mm
* ltp-nptl
* ltp-open-posix-tests
* ltp-pty
* ltp-sched
* ltp-securebits
* ltp-smoke
* ltp-syscalls
* ltp-tracing
* network-basic-tests
* packetdrill
* perf
* perf/Zstd-perf.data-compression
* rcutorture
* ssuite
* v4l2-compliance
* vdso--
Linaro LKFT
https://lkft.linaro.org
Greg Kroah-Hartman
maintainerQuoted 27 lines · Maxim Levitsky
Quoted 26 lines · Naresh Kamboju
Quoted 15 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.55 release. There are 78 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 14 Jul 2022 18:32:19 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.55-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y and the diffstat can be found below.Quoted 3 lines
thanks,
greg k-h
Results from Linaro’s test farm.
Regressions onx86_64.
Quoted 7 lines
Quoted 2 lines
1) Kernel panic noticed on device
x86_6while running kvm-unit-tests.
- APIC base relocation is unsupported by KVMMy 0.2 cent:
APIC base relocation warning is harmless, and I removed it 5.19 kernel:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v5.19-rc6&id=3743c2f0251743b8ae968329708bbbeefff244cf
Nice, but doesn't look relevant for stable trees.
Quoted 3 lines
The 'emulating exchange as write' is also something that KVM unit tests trigger
normally although this warning recently did signal a real and very nasty bug, which I fixed in this commit:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v5.19-rc6&id=33fbe6befa622c082f7d417896832856814bdde0
Already in the 5.18.2 release, doesn't look all that relevant for 5.15, odd that it is showing up on 5.15.
thanks,
greg k-h
Quoted 36 lines · Greg Kroah-Hartman
Quoted 27 lines · Maxim Levitsky
Quoted 26 lines · Naresh Kamboju
Quoted 15 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.55 release. There are 78 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 14 Jul 2022 18:32:19 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.55-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y and the diffstat can be found below.Quoted 3 lines
thanks,
greg k-h
Results from Linaro’s test farm.
Regressions onx86_64.Quoted 7 lines
Quoted 2 lines
1) Kernel panic noticed on device
x86_6while running kvm-unit-tests.
- APIC base relocation is unsupported by KVMMy 0.2 cent:
APIC base relocation warning is harmless, and I removed it 5.19 kernel:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v5.19-rc6&id=3743c2f0251743b8ae968329708bbbeefff244cf
Quoted 8 lines
Nice, but doesn't look relevant for stable trees.
Quoted 3 lines
The 'emulating exchange as write' is also something that KVM unit tests trigger
normally although this warning recently did signal a real and very nasty bug, which I fixed in this commit:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v5.19-rc6&id=33fbe6befa622c082f7d417896832856814bdde0Already in the 5.18.2 release, doesn't look all that relevant for 5.15, odd that it is showing up on 5.15.
Yep, I also think so - I just wanted to point out the source of these warnings.
Best regards,
Maxim Levitsky
Quoted 5 lines
thanks,
greg k-h
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.55 release. There are 78 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 14 Jul 2022 18:32:19 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.55-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.55 release. There are 78 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 14 Jul 2022 18:32:19 +0000. Anything received after that time might be too late.
Build results:
total: 159 pass: 158 fail: 1 Failed builds: um:defconfig Qemu test results: total: 488 pass: 480 fail: 8 Failed tests: x86_64:q35:SandyBridge:defconfig:smp4:net,ne2k_pci:efi32:mem1G:usb:hd x86_64:q35:Conroe:defconfig:smp4:net,tulip:efi32:mem256:scsi[DC395]:hd x86_64:q35:Skylake-Server:defconfig:smp4:net,e1000-82544gc:efi32:mem2G:scsi[53C895A]:hd x86_64:q35:Opteron_G5:defconfig:smp4:net,i82559c:efi32:mem256:scsi[MEGASAS2]:hd x86_64:pc:Opteron_G2:defconfig:smp:net,usb:efi32:mem2G:scsi[virtio-pci]:hd x86_64:q35:Nehalem:defconfig:smp2:net,i82558a:efi32:mem1G:virtio:hd x86_64:q35:Skylake-Client-IBRS:defconfig:preempt:smp2:net,i82558b:efi32:mem1G:sdhci:mmc:hd x86_64:q35:Haswell-noTSX-IBRS:defconfig:nosmp:net,pcnet:efi32:mem2G:ata:hd
Guenter