Commit 5ccaeedb authored by Mark Rutland's avatar Mark Rutland Committed by Alexei Starovoitov
Browse files

cfi: add C CFI type macro



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: default avatarMark Rutland <mark.rutland@arm.com>
Co-developed-by: default avatarMaxwell Bland <mbland@motorola.com>
Signed-off-by: default avatarMaxwell Bland <mbland@motorola.com>
Co-developed-by: default avatarSami Tolvanen <samitolvanen@google.com>
Signed-off-by: default avatarSami Tolvanen <samitolvanen@google.com>
Tested-by: default avatarDao Huang <huangdao1@oppo.com>
Acked-by: default avatarWill Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20250801001004.1859976-6-samitolvanen@google.com


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 13cb7573
Loading
Loading
Loading
Loading
+3 −32
Original line number Diff line number Diff line
@@ -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)
{
+3 −28
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
#define pr_fmt(fmt) "SMP alternatives: " fmt

#include <linux/mmu_context.h>
#include <linux/cfi_types.h>
#include <linux/perf_event.h>
#include <linux/vmalloc.h>
#include <linux/memory.h>
@@ -1189,37 +1190,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);

KCFI_REFERENCE(__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);

KCFI_REFERENCE(__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)
{
+23 −0
Original line number Diff line number Diff line
@@ -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 __ro_after_init = __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 */