Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bpf: correct broken uapi for BPF_PROG_TYPE_PERF_EVENT program type

Commit 0515e5999a466dfe ("bpf: introduce BPF_PROG_TYPE_PERF_EVENT
program type") introduced the bpf_perf_event_data structure which
exports the pt_regs structure. This is OK for multiple architectures
but fail for s390 and arm64 which do not export pt_regs. Programs
using them, for example, the bpf selftest fail to compile on these
architectures.

For s390, exporting the pt_regs is not an option because s390 wants
to allow changes to it. For arm64, there is a user_pt_regs structure
that covers parts of the pt_regs structure for use by user space.

To solve the broken uapi for s390 and arm64, introduce an abstract
type for pt_regs and add an asm/bpf_perf_event.h file that concretes
the type. An asm-generic header file covers the architectures that
export pt_regs today.

The arch-specific enablement for s390 and arm64 follows in separate
commits.

Reported-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
Fixes: 0515e5999a466dfe ("bpf: introduce BPF_PROG_TYPE_PERF_EVENT program type")
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Reviewed-and-tested-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>

authored by

Hendrik Brueckner and committed by
Daniel Borkmann
c895f6f7 2391f0b4

+47 -5
+2
arch/alpha/include/uapi/asm/Kbuild
··· 1 1 # UAPI Header export list 2 2 include include/uapi/asm-generic/Kbuild.asm 3 + 4 + generic-y += bpf_perf_event.h
+1
arch/arc/include/uapi/asm/Kbuild
··· 3 3 4 4 generic-y += auxvec.h 5 5 generic-y += bitsperlong.h 6 + generic-y += bpf_perf_event.h 6 7 generic-y += errno.h 7 8 generic-y += fcntl.h 8 9 generic-y += ioctl.h
+1
arch/arm/include/uapi/asm/Kbuild
··· 7 7 generated-y += unistd-eabi.h 8 8 9 9 generic-y += bitsperlong.h 10 + generic-y += bpf_perf_event.h 10 11 generic-y += errno.h 11 12 generic-y += ioctl.h 12 13 generic-y += ipcbuf.h
+1
arch/blackfin/include/uapi/asm/Kbuild
··· 3 3 4 4 generic-y += auxvec.h 5 5 generic-y += bitsperlong.h 6 + generic-y += bpf_perf_event.h 6 7 generic-y += errno.h 7 8 generic-y += ioctl.h 8 9 generic-y += ipcbuf.h
+1
arch/c6x/include/uapi/asm/Kbuild
··· 3 3 4 4 generic-y += auxvec.h 5 5 generic-y += bitsperlong.h 6 + generic-y += bpf_perf_event.h 6 7 generic-y += errno.h 7 8 generic-y += fcntl.h 8 9 generic-y += ioctl.h
+1
arch/cris/include/uapi/asm/Kbuild
··· 3 3 4 4 generic-y += auxvec.h 5 5 generic-y += bitsperlong.h 6 + generic-y += bpf_perf_event.h 6 7 generic-y += errno.h 7 8 generic-y += fcntl.h 8 9 generic-y += ioctl.h
+2
arch/frv/include/uapi/asm/Kbuild
··· 1 1 # UAPI Header export list 2 2 include include/uapi/asm-generic/Kbuild.asm 3 + 4 + generic-y += bpf_perf_event.h
+1
arch/h8300/include/uapi/asm/Kbuild
··· 2 2 include include/uapi/asm-generic/Kbuild.asm 3 3 4 4 generic-y += auxvec.h 5 + generic-y += bpf_perf_event.h 5 6 generic-y += errno.h 6 7 generic-y += fcntl.h 7 8 generic-y += ioctl.h
+1
arch/hexagon/include/uapi/asm/Kbuild
··· 2 2 include include/uapi/asm-generic/Kbuild.asm 3 3 4 4 generic-y += auxvec.h 5 + generic-y += bpf_perf_event.h 5 6 generic-y += errno.h 6 7 generic-y += fcntl.h 7 8 generic-y += ioctl.h
+1
arch/ia64/include/uapi/asm/Kbuild
··· 1 1 # UAPI Header export list 2 2 include include/uapi/asm-generic/Kbuild.asm 3 3 4 + generic-y += bpf_perf_event.h 4 5 generic-y += kvm_para.h
+1
arch/m32r/include/uapi/asm/Kbuild
··· 1 1 # UAPI Header export list 2 2 include include/uapi/asm-generic/Kbuild.asm 3 3 4 + generic-y += bpf_perf_event.h 4 5 generic-y += kvm_para.h 5 6 generic-y += siginfo.h
+1
arch/m68k/include/uapi/asm/Kbuild
··· 3 3 4 4 generic-y += auxvec.h 5 5 generic-y += bitsperlong.h 6 + generic-y += bpf_perf_event.h 6 7 generic-y += errno.h 7 8 generic-y += ioctl.h 8 9 generic-y += ipcbuf.h
+1
arch/metag/include/uapi/asm/Kbuild
··· 3 3 4 4 generic-y += auxvec.h 5 5 generic-y += bitsperlong.h 6 + generic-y += bpf_perf_event.h 6 7 generic-y += errno.h 7 8 generic-y += fcntl.h 8 9 generic-y += ioctl.h
+1
arch/microblaze/include/uapi/asm/Kbuild
··· 2 2 include include/uapi/asm-generic/Kbuild.asm 3 3 4 4 generic-y += bitsperlong.h 5 + generic-y += bpf_perf_event.h 5 6 generic-y += errno.h 6 7 generic-y += fcntl.h 7 8 generic-y += ioctl.h
+1
arch/mips/include/uapi/asm/Kbuild
··· 1 1 # UAPI Header export list 2 2 include include/uapi/asm-generic/Kbuild.asm 3 3 4 + generic-y += bpf_perf_event.h 4 5 generic-y += ipcbuf.h
+1
arch/mn10300/include/uapi/asm/Kbuild
··· 1 1 # UAPI Header export list 2 2 include include/uapi/asm-generic/Kbuild.asm 3 3 4 + generic-y += bpf_perf_event.h 4 5 generic-y += siginfo.h
+1
arch/nios2/include/uapi/asm/Kbuild
··· 3 3 4 4 generic-y += auxvec.h 5 5 generic-y += bitsperlong.h 6 + generic-y += bpf_perf_event.h 6 7 generic-y += errno.h 7 8 generic-y += fcntl.h 8 9 generic-y += ioctl.h
+1
arch/openrisc/include/uapi/asm/Kbuild
··· 3 3 4 4 generic-y += auxvec.h 5 5 generic-y += bitsperlong.h 6 + generic-y += bpf_perf_event.h 6 7 generic-y += errno.h 7 8 generic-y += fcntl.h 8 9 generic-y += ioctl.h
+1
arch/parisc/include/uapi/asm/Kbuild
··· 2 2 include include/uapi/asm-generic/Kbuild.asm 3 3 4 4 generic-y += auxvec.h 5 + generic-y += bpf_perf_event.h 5 6 generic-y += kvm_para.h 6 7 generic-y += param.h 7 8 generic-y += poll.h
+1
arch/powerpc/include/uapi/asm/Kbuild
··· 1 1 # UAPI Header export list 2 2 include include/uapi/asm-generic/Kbuild.asm 3 3 4 + generic-y += bpf_perf_event.h 4 5 generic-y += param.h 5 6 generic-y += poll.h 6 7 generic-y += resource.h
+1
arch/riscv/include/uapi/asm/Kbuild
··· 3 3 4 4 generic-y += setup.h 5 5 generic-y += unistd.h 6 + generic-y += bpf_perf_event.h 6 7 generic-y += errno.h 7 8 generic-y += fcntl.h 8 9 generic-y += ioctl.h
+1
arch/score/include/uapi/asm/Kbuild
··· 1 1 # UAPI Header export list 2 2 include include/uapi/asm-generic/Kbuild.asm 3 3 4 + generic-y += bpf_perf_event.h 4 5 generic-y += siginfo.h
+1
arch/sh/include/uapi/asm/Kbuild
··· 2 2 include include/uapi/asm-generic/Kbuild.asm 3 3 4 4 generic-y += bitsperlong.h 5 + generic-y += bpf_perf_event.h 5 6 generic-y += errno.h 6 7 generic-y += fcntl.h 7 8 generic-y += ioctl.h
+1
arch/sparc/include/uapi/asm/Kbuild
··· 1 1 # UAPI Header export list 2 2 include include/uapi/asm-generic/Kbuild.asm 3 3 4 + generic-y += bpf_perf_event.h 4 5 generic-y += types.h
+1
arch/tile/include/uapi/asm/Kbuild
··· 1 1 # UAPI Header export list 2 2 include include/uapi/asm-generic/Kbuild.asm 3 3 4 + generic-y += bpf_perf_event.h 4 5 generic-y += errno.h 5 6 generic-y += fcntl.h 6 7 generic-y += ioctl.h
+1
arch/unicore32/include/uapi/asm/Kbuild
··· 3 3 4 4 generic-y += auxvec.h 5 5 generic-y += bitsperlong.h 6 + generic-y += bpf_perf_event.h 6 7 generic-y += errno.h 7 8 generic-y += fcntl.h 8 9 generic-y += ioctl.h
+1
arch/x86/include/uapi/asm/Kbuild
··· 1 1 # UAPI Header export list 2 2 include include/uapi/asm-generic/Kbuild.asm 3 3 4 + generic-y += bpf_perf_event.h 4 5 generated-y += unistd_32.h 5 6 generated-y += unistd_64.h 6 7 generated-y += unistd_x32.h
+1
arch/xtensa/include/uapi/asm/Kbuild
··· 2 2 include include/uapi/asm-generic/Kbuild.asm 3 3 4 4 generic-y += bitsperlong.h 5 + generic-y += bpf_perf_event.h 5 6 generic-y += errno.h 6 7 generic-y += fcntl.h 7 8 generic-y += ioctl.h
+5 -1
include/linux/perf_event.h
··· 15 15 #define _LINUX_PERF_EVENT_H 16 16 17 17 #include <uapi/linux/perf_event.h> 18 + #include <uapi/linux/bpf_perf_event.h> 18 19 19 20 /* 20 21 * Kernel-internal data types and definitions: ··· 788 787 }; 789 788 790 789 struct bpf_perf_event_data_kern { 791 - struct pt_regs *regs; 790 + bpf_user_pt_regs_t *regs; 792 791 struct perf_sample_data *data; 793 792 struct perf_event *event; 794 793 }; ··· 1177 1176 # define perf_misc_flags(regs) \ 1178 1177 (user_mode(regs) ? PERF_RECORD_MISC_USER : PERF_RECORD_MISC_KERNEL) 1179 1178 # define perf_instruction_pointer(regs) instruction_pointer(regs) 1179 + #endif 1180 + #ifndef perf_arch_bpf_user_pt_regs 1181 + # define perf_arch_bpf_user_pt_regs(regs) regs 1180 1182 #endif 1181 1183 1182 1184 static inline bool has_branch_stack(struct perf_event *event)
+9
include/uapi/asm-generic/bpf_perf_event.h
··· 1 + #ifndef _UAPI__ASM_GENERIC_BPF_PERF_EVENT_H__ 2 + #define _UAPI__ASM_GENERIC_BPF_PERF_EVENT_H__ 3 + 4 + #include <linux/ptrace.h> 5 + 6 + /* Export kernel pt_regs structure */ 7 + typedef struct pt_regs bpf_user_pt_regs_t; 8 + 9 + #endif /* _UAPI__ASM_GENERIC_BPF_PERF_EVENT_H__ */
+2 -3
include/uapi/linux/bpf_perf_event.h
··· 8 8 #ifndef _UAPI__LINUX_BPF_PERF_EVENT_H__ 9 9 #define _UAPI__LINUX_BPF_PERF_EVENT_H__ 10 10 11 - #include <linux/types.h> 12 - #include <linux/ptrace.h> 11 + #include <asm/bpf_perf_event.h> 13 12 14 13 struct bpf_perf_event_data { 15 - struct pt_regs regs; 14 + bpf_user_pt_regs_t regs; 16 15 __u64 sample_period; 17 16 }; 18 17
+1 -1
kernel/events/core.c
··· 7987 7987 { 7988 7988 struct bpf_perf_event_data_kern ctx = { 7989 7989 .data = data, 7990 - .regs = regs, 7991 7990 .event = event, 7992 7991 }; 7993 7992 int ret = 0; 7994 7993 7994 + ctx.regs = perf_arch_bpf_user_pt_regs(regs); 7995 7995 preempt_disable(); 7996 7996 if (unlikely(__this_cpu_inc_return(bpf_prog_active) != 1)) 7997 7997 goto out;