Messages in this thread | | | Date | Tue, 1 Mar 2022 15:10:22 -0800 | From | Josh Poimboeuf <> | Subject | Re: [PATCH v2 00/39] x86: Kernel IBT |
| |
On Fri, Feb 25, 2022 at 04:28:32PM +0100, Peter Zijlstra wrote: > On Thu, Feb 24, 2022 at 12:26:02PM -0800, Josh Poimboeuf wrote: > > > Bricked my SPR: > > > > [ 21.602888] jump_label: Fatal kernel bug, unexpected op at sched_clock_stable+0x4/0x20 [0000000074a0db20] (eb 06 b8 01 00 != eb 0a 00 00 00)) size:2 type:0 > > > ffffffff81120a70 <sched_clock_stable>: > > ffffffff81120a70: f3 0f 1e fa endbr64 > > ffffffff81120a74: eb 06 jmp ffffffff81120a7c <sched_clock_stable+0xc> > > ffffffff81120a76: b8 01 00 00 00 mov $0x1,%eax > > ffffffff81120a7b: c3 retq > > ffffffff81120a7c: f3 0f 1e fa endbr64 > > ffffffff81120a80: 31 c0 xor %eax,%eax > > ffffffff81120a82: c3 retq > > ffffffff81120a83: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1) > > ffffffff81120a8a: 00 00 00 00 > > ffffffff81120a8e: 66 90 xchg %ax,%ax > > This is due to you having a very old (and arguably buggy) compiler :-( I > can reproduce with gcc-8.4 and gcc-9.4, my gcc-10.3 compiler no longer > generates daft code like that, nor do any later. > > That said, I can fix objtool to also re-write jumps to in-the-middle > ENDBR like this, but then I do get a bunch of: > > OBJTOOL vmlinux.o > vmlinux.o: warning: objtool: displacement doesn't fit > vmlinux.o: warning: objtool: ep_insert()+0xbc5: Direct IMM jump to ENDBR; cannot fix > vmlinux.o: warning: objtool: displacement doesn't fit > vmlinux.o: warning: objtool: configfs_depend_prep()+0x76: Direct IMM jump to ENDBR; cannot fix > vmlinux.o: warning: objtool: displacement doesn't fit > vmlinux.o: warning: objtool: request_key_and_link()+0x17b: Direct IMM jump to ENDBR; cannot fix > vmlinux.o: warning: objtool: displacement doesn't fit > vmlinux.o: warning: objtool: blk_mq_poll()+0x2e0: Direct IMM jump to ENDBR; cannot fix > > The alternative is only skipping endbr at +0 I suppose, lemme go try > that with the brand spanking new skip_endbr() function. > > Yep,.. that seems to cure things. It noaw boats when build with old > crappy compilers too. > > > --- a/arch/x86/include/asm/ibt.h > +++ b/arch/x86/include/asm/ibt.h > @@ -47,6 +47,8 @@ static inline bool is_endbr(unsigned int > return val == gen_endbr(); > } > > +extern void *skip_endbr(void *); > + > extern __noendbr u64 ibt_save(void); > extern __noendbr void ibt_restore(u64 save); > > @@ -71,6 +73,7 @@ extern __noendbr void ibt_restore(u64 sa > #define __noendbr > > static inline bool is_endbr(unsigned int val) { return false; } > +static inline void *skip_endbr(void *addr) { return addr; } > > static inline u64 ibt_save(void) { return 0; } > static inline void ibt_restore(u64 save) { } > --- a/arch/x86/include/asm/text-patching.h > +++ b/arch/x86/include/asm/text-patching.h > @@ -112,10 +112,7 @@ void __text_gen_insn(void *buf, u8 opcod > OPTIMIZER_HIDE_VAR(addr); > OPTIMIZER_HIDE_VAR(dest); > > -#ifdef CONFIG_X86_KERNEL_IBT > - if (is_endbr(*(u32 *)dest)) > - dest += 4; > -#endif > + dest = skip_endbr((void *)dest); > > insn->opcode = opcode; > > --- a/arch/x86/kernel/cpu/common.c > +++ b/arch/x86/kernel/cpu/common.c > @@ -620,6 +620,19 @@ __noendbr void ibt_restore(u64 save) > } > } > > + > +void *skip_endbr(void *addr) > +{ > + unsigned long size, offset; > + > + if (is_endbr(*(unsigned int *)addr) && > + kallsyms_lookup_size_offset((unsigned long)addr, &size, &offset) && > + !offset) > + addr += 4; > + > + return addr; > +} > + > #endif > > static __always_inline void setup_cet(struct cpuinfo_x86 *c) > @@ -636,7 +649,10 @@ static __always_inline void setup_cet(st > if (!ibt_selftest()) { > pr_err("IBT selftest: Failed!\n"); > setup_clear_cpu_cap(X86_FEATURE_IBT); > + return; > } > + > + pr_info("CET detected: Indirect Branch Tracking enabled\n");
This is a little excessive on my 192 CPUs :-)
It also messes with the pr_cont()s in announce_cpu():
[ 3.733446] x86: Booting SMP configuration: [ 3.734342] .... node #0, CPUs: #1 [ 3.534902] CET detected: Indirect Branch Tracking enabled [ 3.770955] #2 [ 3.534902] CET detected: Indirect Branch Tracking enabled [ 3.802979] #3 [ 3.534902] CET detected: Indirect Branch Tracking enabled [ 3.835459] #4 [ 3.534902] CET detected: Indirect Branch Tracking enabled [ 3.866826] #5 [ 3.534902] CET detected: Indirect Branch Tracking enabled [ 3.898690] #6 [ 3.534902] CET detected: Indirect Branch Tracking enabled [ 3.930355] #7 [ 3.534902] CET detected: Indirect Branch Tracking enabled [ 3.961493] #8 [ 3.534902] CET detected: Indirect Branch Tracking enabled [ 3.993500] #9 [ 3.534902] CET detected: Indirect Branch Tracking enabled [ 4.024952] #10 [ 3.534902] CET detected: Indirect Branch Tracking enabled [ 4.056491] #11 [ 3.534902] CET detected: Indirect Branch Tracking enabled [ 4.087493] #12 [ 3.534902] CET detected: Indirect Branch Tracking enabled [ 4.118907] #13 [ 3.534902] CET detected: Indirect Branch Tracking enabled [ 4.150494] #14 [ 3.534902] CET detected: Indirect Branch Tracking enabled [ 4.181425] #15
-- Josh
| |