> From: Mark Rutland <mark.rutland@xxxxxxx> > > Currently x86 and riscv open-code 4 instances of the same logic to > define a u32 variable with the KCFI typeid of a given function. > > Replace the duplicate logic with a common macro. > > Signed-off-by: Mark Rutland <mark.rutland@xxxxxxx> > Co-Developed-by: Maxwell Bland <mbland@xxxxxxxxxxxx> > Signed-off-by: Maxwell Bland <mbland@xxxxxxxxxxxx> > Co-Developed-by: Sami Tolvanen <samitolvanen@xxxxxxxxxx> > Signed-off-by: Sami Tolvanen <samitolvanen@xxxxxxxxxx> > --- > arch/riscv/kernel/cfi.c | 35 +++-------------------------------- > arch/x86/kernel/alternative.c | 35 +++-------------------------------- > include/linux/cfi_types.h | 23 +++++++++++++++++++++++ > 3 files changed, 29 insertions(+), 64 deletions(-) > > diff --git a/arch/riscv/kernel/cfi.c b/arch/riscv/kernel/cfi.c > index 64bdd3e1ab8c..e7aec5f36dd5 100644 > --- a/arch/riscv/kernel/cfi.c > +++ b/arch/riscv/kernel/cfi.c > @@ -4,6 +4,7 @@ > * > * Copyright (C) 2023 Google LLC > */ > +#include <linux/cfi_types.h> > #include <linux/cfi.h> > #include <asm/insn.h> > > @@ -82,41 +83,11 @@ struct bpf_insn; > /* Must match bpf_func_t / DEFINE_BPF_PROG_RUN() */ > extern unsigned int __bpf_prog_runX(const void *ctx, > const struct bpf_insn *insn); > - > -/* > - * Force a reference to the external symbol so the compiler generates > - * __kcfi_typid. > - */ > -__ADDRESSABLE(__bpf_prog_runX); > - > -/* u32 __ro_after_init cfi_bpf_hash = __kcfi_typeid___bpf_prog_runX; */ > -asm ( > -" .pushsection .data..ro_after_init,\"aw\",@progbits \n" > -" .type cfi_bpf_hash,@object \n" > -" .globl cfi_bpf_hash \n" > -" .p2align 2, 0x0 \n" > -"cfi_bpf_hash: \n" > -" .word __kcfi_typeid___bpf_prog_runX \n" > -" .size cfi_bpf_hash, 4 \n" > -" .popsection \n" > -); > +DEFINE_CFI_TYPE(cfi_bpf_hash, __bpf_prog_runX); > > /* Must match bpf_callback_t */ > extern u64 __bpf_callback_fn(u64, u64, u64, u64, u64); > - > -__ADDRESSABLE(__bpf_callback_fn); > - > -/* u32 __ro_after_init cfi_bpf_subprog_hash = __kcfi_typeid___bpf_callback_fn; */ > -asm ( > -" .pushsection .data..ro_after_init,\"aw\",@progbits \n" > -" .type cfi_bpf_subprog_hash,@object \n" > -" .globl cfi_bpf_subprog_hash \n" > -" .p2align 2, 0x0 \n" > -"cfi_bpf_subprog_hash: \n" > -" .word __kcfi_typeid___bpf_callback_fn \n" > -" .size cfi_bpf_subprog_hash, 4 \n" > -" .popsection \n" > -); > +DEFINE_CFI_TYPE(cfi_bpf_subprog_hash, __bpf_callback_fn); > > u32 cfi_get_func_hash(void *func) > { > diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c > index c71b575bf229..a9f415e873dd 100644 > --- a/arch/x86/kernel/alternative.c > +++ b/arch/x86/kernel/alternative.c > @@ -1,6 +1,7 @@ > // SPDX-License-Identifier: GPL-2.0-only > #define pr_fmt(fmt) "SMP alternatives: " fmt > > +#include <linux/cfi_types.h> > #include <linux/module.h> > #include <linux/sched.h> > #include <linux/perf_event.h> > @@ -934,41 +935,11 @@ struct bpf_insn; > /* Must match bpf_func_t / DEFINE_BPF_PROG_RUN() */ > extern unsigned int __bpf_prog_runX(const void *ctx, > const struct bpf_insn *insn); > - > -/* > - * Force a reference to the external symbol so the compiler generates > - * __kcfi_typid. > - */ > -__ADDRESSABLE(__bpf_prog_runX); > - > -/* u32 __ro_after_init cfi_bpf_hash = __kcfi_typeid___bpf_prog_runX; */ > -asm ( > -" .pushsection .data..ro_after_init,\"aw\",@progbits \n" > -" .type cfi_bpf_hash,@object \n" > -" .globl cfi_bpf_hash \n" > -" .p2align 2, 0x0 \n" > -"cfi_bpf_hash: \n" > -" .long __kcfi_typeid___bpf_prog_runX \n" > -" .size cfi_bpf_hash, 4 \n" > -" .popsection \n" > -); > +DEFINE_CFI_TYPE(cfi_bpf_hash, __bpf_prog_runX); > > /* Must match bpf_callback_t */ > extern u64 __bpf_callback_fn(u64, u64, u64, u64, u64); > - > -__ADDRESSABLE(__bpf_callback_fn); > - > -/* u32 __ro_after_init cfi_bpf_subprog_hash = __kcfi_typeid___bpf_callback_fn; */ > -asm ( > -" .pushsection .data..ro_after_init,\"aw\",@progbits \n" > -" .type cfi_bpf_subprog_hash,@object \n" > -" .globl cfi_bpf_subprog_hash \n" > -" .p2align 2, 0x0 \n" > -"cfi_bpf_subprog_hash: \n" > -" .long __kcfi_typeid___bpf_callback_fn \n" > -" .size cfi_bpf_subprog_hash, 4 \n" > -" .popsection \n" > -); > +DEFINE_CFI_TYPE(cfi_bpf_subprog_hash, __bpf_callback_fn); > > u32 cfi_get_func_hash(void *func) > { > diff --git a/include/linux/cfi_types.h b/include/linux/cfi_types.h > index 6b8713675765..209c8a16ac4e 100644 > --- a/include/linux/cfi_types.h > +++ b/include/linux/cfi_types.h > @@ -41,5 +41,28 @@ > SYM_TYPED_START(name, SYM_L_GLOBAL, SYM_A_ALIGN) > #endif > > +#else /* __ASSEMBLY__ */ > + > +#ifdef CONFIG_CFI_CLANG > +#define DEFINE_CFI_TYPE(name, func) \ > + /* \ > + * Force a reference to the function so the compiler generates \ > + * __kcfi_typeid_<func>. \ > + */ \ > + __ADDRESSABLE(func); \ > + /* u32 name = __kcfi_typeid_<func> */ \ > + extern u32 name; \ > + asm ( \ > + " .pushsection .data..ro_after_init,\"aw\",@progbits \n" \ > + " .type " #name ",@object \n" \ > + " .globl " #name " \n" \ > + " .p2align 2, 0x0 \n" \ > + #name ": \n" \ > + " .4byte __kcfi_typeid_" #func " \n" \ > + " .size " #name ", 4 \n" \ > + " .popsection \n" \ > + ); > +#endif > + > #endif /* __ASSEMBLY__ */ > #endif /* _LINUX_CFI_TYPES_H */ > -- > 2.49.0.rc0.332.g42c0ae87b1-goog we oppo team have tested this patch on Mediatek DX-5(arm64) with a kernel based on android-16(kernel-6.12). It has been running fine for a week on both machines.