Commit 037776e4 authored by Daniel Borkmann's avatar Daniel Borkmann

Merge branch 'bpf-fix-broken-uapi-for-pt-regs'

Hendrik Brueckner says:

====================
Perf tool bpf selftests revealed a broken uapi for s390 and arm64.
With the BPF_PROG_TYPE_PERF_EVENT program type the bpf_perf_event
structure exports the pt_regs structure for all architectures.

This fails for s390 and arm64 because pt_regs are not part of the
user api and kept in-kernel only.  To mitigate the broken uapi,
introduce a wrapper that exports pt_regs in an asm-generic way.
For arm64, export the exising user_pt_regs structure.  For s390,
introduce a user_pt_regs structure that exports the beginning of
pt_regs.

Note that user_pt_regs must export from the beginning of pt_regs
as BPF_PROG_TYPE_PERF_EVENT program type is not the only type for
running BPF programs.

Some more background:

  For the bpf_perf_event, there is a uapi definition that is
  passed to the BPF program.  For other "probe" points like
  trace points, kprobes, and uprobes, there is no uapi and the
  BPF program is always passed pt_regs (which is OK as the BPF
  program runs in the kernel context).  The perf tool can attach
  BPF programs to all of these "probe" points and, optionally,
  can create a BPF prologue to access particular arguments
  (passed as registers).  For this, it uses DWARF/CFI
  information to obtain the register and calls a perf-arch
  backend function, regs_query_register_offset().  This function
  returns the index into (user_)pt_regs for a particular
  register.  Then, perf creates a BPF prologue that accesses
  this register based on the passed stucture from the "probe"
  point.

Part of this series, are also updates to the testing and bpf selftest
to deal with asm-specifics.  To complete the bpf support in perf, the
the regs_query_register_offset function is added for s390 to support
BPF prologue creation.

Changelog v1 -> v2:
- Correct kbuild test bot issues by including
  asm-generic/bpf_perf_event.h for archictectures that do not have
  their own asm version.
- Added patch to clean-up whitespace and coding style issues in s390
  asm/ptrace.h (#4/6) as suggested by Alexei.
====================
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parents 2391f0b4 a81c4213
# UAPI Header export list # UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm include include/uapi/asm-generic/Kbuild.asm
generic-y += bpf_perf_event.h
...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm ...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm
generic-y += auxvec.h generic-y += auxvec.h
generic-y += bitsperlong.h generic-y += bitsperlong.h
generic-y += bpf_perf_event.h
generic-y += errno.h generic-y += errno.h
generic-y += fcntl.h generic-y += fcntl.h
generic-y += ioctl.h generic-y += ioctl.h
......
...@@ -7,6 +7,7 @@ generated-y += unistd-oabi.h ...@@ -7,6 +7,7 @@ generated-y += unistd-oabi.h
generated-y += unistd-eabi.h generated-y += unistd-eabi.h
generic-y += bitsperlong.h generic-y += bitsperlong.h
generic-y += bpf_perf_event.h
generic-y += errno.h generic-y += errno.h
generic-y += ioctl.h generic-y += ioctl.h
generic-y += ipcbuf.h generic-y += ipcbuf.h
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#define __ASM_PERF_EVENT_H #define __ASM_PERF_EVENT_H
#include <asm/stack_pointer.h> #include <asm/stack_pointer.h>
#include <asm/ptrace.h>
#define ARMV8_PMU_MAX_COUNTERS 32 #define ARMV8_PMU_MAX_COUNTERS 32
#define ARMV8_PMU_COUNTER_MASK (ARMV8_PMU_MAX_COUNTERS - 1) #define ARMV8_PMU_COUNTER_MASK (ARMV8_PMU_MAX_COUNTERS - 1)
...@@ -79,6 +80,7 @@ struct pt_regs; ...@@ -79,6 +80,7 @@ struct pt_regs;
extern unsigned long perf_instruction_pointer(struct pt_regs *regs); extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
extern unsigned long perf_misc_flags(struct pt_regs *regs); extern unsigned long perf_misc_flags(struct pt_regs *regs);
#define perf_misc_flags(regs) perf_misc_flags(regs) #define perf_misc_flags(regs) perf_misc_flags(regs)
#define perf_arch_bpf_user_pt_regs(regs) &regs->user_regs
#endif #endif
#define perf_arch_fetch_caller_regs(regs, __ip) { \ #define perf_arch_fetch_caller_regs(regs, __ip) { \
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _UAPI__ASM_BPF_PERF_EVENT_H__
#define _UAPI__ASM_BPF_PERF_EVENT_H__
#include <asm/ptrace.h>
typedef struct user_pt_regs bpf_user_pt_regs_t;
#endif /* _UAPI__ASM_BPF_PERF_EVENT_H__ */
...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm ...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm
generic-y += auxvec.h generic-y += auxvec.h
generic-y += bitsperlong.h generic-y += bitsperlong.h
generic-y += bpf_perf_event.h
generic-y += errno.h generic-y += errno.h
generic-y += ioctl.h generic-y += ioctl.h
generic-y += ipcbuf.h generic-y += ipcbuf.h
......
...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm ...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm
generic-y += auxvec.h generic-y += auxvec.h
generic-y += bitsperlong.h generic-y += bitsperlong.h
generic-y += bpf_perf_event.h
generic-y += errno.h generic-y += errno.h
generic-y += fcntl.h generic-y += fcntl.h
generic-y += ioctl.h generic-y += ioctl.h
......
...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm ...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm
generic-y += auxvec.h generic-y += auxvec.h
generic-y += bitsperlong.h generic-y += bitsperlong.h
generic-y += bpf_perf_event.h
generic-y += errno.h generic-y += errno.h
generic-y += fcntl.h generic-y += fcntl.h
generic-y += ioctl.h generic-y += ioctl.h
......
# UAPI Header export list # UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm include include/uapi/asm-generic/Kbuild.asm
generic-y += bpf_perf_event.h
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
include include/uapi/asm-generic/Kbuild.asm include include/uapi/asm-generic/Kbuild.asm
generic-y += auxvec.h generic-y += auxvec.h
generic-y += bpf_perf_event.h
generic-y += errno.h generic-y += errno.h
generic-y += fcntl.h generic-y += fcntl.h
generic-y += ioctl.h generic-y += ioctl.h
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
include include/uapi/asm-generic/Kbuild.asm include include/uapi/asm-generic/Kbuild.asm
generic-y += auxvec.h generic-y += auxvec.h
generic-y += bpf_perf_event.h
generic-y += errno.h generic-y += errno.h
generic-y += fcntl.h generic-y += fcntl.h
generic-y += ioctl.h generic-y += ioctl.h
......
# UAPI Header export list # UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm include include/uapi/asm-generic/Kbuild.asm
generic-y += bpf_perf_event.h
generic-y += kvm_para.h generic-y += kvm_para.h
# UAPI Header export list # UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm include include/uapi/asm-generic/Kbuild.asm
generic-y += bpf_perf_event.h
generic-y += kvm_para.h generic-y += kvm_para.h
generic-y += siginfo.h generic-y += siginfo.h
...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm ...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm
generic-y += auxvec.h generic-y += auxvec.h
generic-y += bitsperlong.h generic-y += bitsperlong.h
generic-y += bpf_perf_event.h
generic-y += errno.h generic-y += errno.h
generic-y += ioctl.h generic-y += ioctl.h
generic-y += ipcbuf.h generic-y += ipcbuf.h
......
...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm ...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm
generic-y += auxvec.h generic-y += auxvec.h
generic-y += bitsperlong.h generic-y += bitsperlong.h
generic-y += bpf_perf_event.h
generic-y += errno.h generic-y += errno.h
generic-y += fcntl.h generic-y += fcntl.h
generic-y += ioctl.h generic-y += ioctl.h
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
include include/uapi/asm-generic/Kbuild.asm include include/uapi/asm-generic/Kbuild.asm
generic-y += bitsperlong.h generic-y += bitsperlong.h
generic-y += bpf_perf_event.h
generic-y += errno.h generic-y += errno.h
generic-y += fcntl.h generic-y += fcntl.h
generic-y += ioctl.h generic-y += ioctl.h
......
# UAPI Header export list # UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm include include/uapi/asm-generic/Kbuild.asm
generic-y += bpf_perf_event.h
generic-y += ipcbuf.h generic-y += ipcbuf.h
# UAPI Header export list # UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm include include/uapi/asm-generic/Kbuild.asm
generic-y += bpf_perf_event.h
generic-y += siginfo.h generic-y += siginfo.h
...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm ...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm
generic-y += auxvec.h generic-y += auxvec.h
generic-y += bitsperlong.h generic-y += bitsperlong.h
generic-y += bpf_perf_event.h
generic-y += errno.h generic-y += errno.h
generic-y += fcntl.h generic-y += fcntl.h
generic-y += ioctl.h generic-y += ioctl.h
......
...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm ...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm
generic-y += auxvec.h generic-y += auxvec.h
generic-y += bitsperlong.h generic-y += bitsperlong.h
generic-y += bpf_perf_event.h
generic-y += errno.h generic-y += errno.h
generic-y += fcntl.h generic-y += fcntl.h
generic-y += ioctl.h generic-y += ioctl.h
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
include include/uapi/asm-generic/Kbuild.asm include include/uapi/asm-generic/Kbuild.asm
generic-y += auxvec.h generic-y += auxvec.h
generic-y += bpf_perf_event.h
generic-y += kvm_para.h generic-y += kvm_para.h
generic-y += param.h generic-y += param.h
generic-y += poll.h generic-y += poll.h
......
# UAPI Header export list # UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm include include/uapi/asm-generic/Kbuild.asm
generic-y += bpf_perf_event.h
generic-y += param.h generic-y += param.h
generic-y += poll.h generic-y += poll.h
generic-y += resource.h generic-y += resource.h
......
...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm ...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm
generic-y += setup.h generic-y += setup.h
generic-y += unistd.h generic-y += unistd.h
generic-y += bpf_perf_event.h
generic-y += errno.h generic-y += errno.h
generic-y += fcntl.h generic-y += fcntl.h
generic-y += ioctl.h generic-y += ioctl.h
......
...@@ -40,6 +40,7 @@ struct pt_regs; ...@@ -40,6 +40,7 @@ struct pt_regs;
extern unsigned long perf_instruction_pointer(struct pt_regs *regs); extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
extern unsigned long perf_misc_flags(struct pt_regs *regs); extern unsigned long perf_misc_flags(struct pt_regs *regs);
#define perf_misc_flags(regs) perf_misc_flags(regs) #define perf_misc_flags(regs) perf_misc_flags(regs)
#define perf_arch_bpf_user_pt_regs(regs) &regs->user_regs
/* Perf pt_regs extension for sample-data-entry indicators */ /* Perf pt_regs extension for sample-data-entry indicators */
struct perf_sf_sde_regs { struct perf_sf_sde_regs {
......
...@@ -74,9 +74,14 @@ enum { ...@@ -74,9 +74,14 @@ enum {
*/ */
struct pt_regs struct pt_regs
{ {
unsigned long args[1]; union {
psw_t psw; user_pt_regs user_regs;
unsigned long gprs[NUM_GPRS]; struct {
unsigned long args[1];
psw_t psw;
unsigned long gprs[NUM_GPRS];
};
};
unsigned long orig_gpr2; unsigned long orig_gpr2;
unsigned int int_code; unsigned int int_code;
unsigned int int_parm; unsigned int int_parm;
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _UAPI__ASM_BPF_PERF_EVENT_H__
#define _UAPI__ASM_BPF_PERF_EVENT_H__
#include <asm/ptrace.h>
typedef user_pt_regs bpf_user_pt_regs_t;
#endif /* _UAPI__ASM_BPF_PERF_EVENT_H__ */
...@@ -162,7 +162,7 @@ ...@@ -162,7 +162,7 @@
#define GPR_SIZE 8 #define GPR_SIZE 8
#define CR_SIZE 8 #define CR_SIZE 8
#define STACK_FRAME_OVERHEAD 160 /* size of minimum stack frame */ #define STACK_FRAME_OVERHEAD 160 /* size of minimum stack frame */
#endif /* __s390x__ */ #endif /* __s390x__ */
...@@ -179,17 +179,16 @@ ...@@ -179,17 +179,16 @@
#define ACR_SIZE 4 #define ACR_SIZE 4
#define PTRACE_OLDSETOPTIONS 21 #define PTRACE_OLDSETOPTIONS 21
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/types.h> #include <linux/types.h>
typedef union typedef union {
{ float f;
float f; double d;
double d; __u64 ui;
__u64 ui;
struct struct
{ {
__u32 hi; __u32 hi;
...@@ -197,23 +196,21 @@ typedef union ...@@ -197,23 +196,21 @@ typedef union
} fp; } fp;
} freg_t; } freg_t;
typedef struct typedef struct {
{ __u32 fpc;
__u32 fpc;
__u32 pad; __u32 pad;
freg_t fprs[NUM_FPRS]; freg_t fprs[NUM_FPRS];
} s390_fp_regs; } s390_fp_regs;
#define FPC_EXCEPTION_MASK 0xF8000000 #define FPC_EXCEPTION_MASK 0xF8000000
#define FPC_FLAGS_MASK 0x00F80000 #define FPC_FLAGS_MASK 0x00F80000
#define FPC_DXC_MASK 0x0000FF00 #define FPC_DXC_MASK 0x0000FF00
#define FPC_RM_MASK 0x00000003 #define FPC_RM_MASK 0x00000003
/* this typedef defines how a Program Status Word looks like */ /* this typedef defines how a Program Status Word looks like */
typedef struct typedef struct {
{ unsigned long mask;
unsigned long mask; unsigned long addr;
unsigned long addr;
} __attribute__ ((aligned(8))) psw_t; } __attribute__ ((aligned(8))) psw_t;
#ifndef __s390x__ #ifndef __s390x__
...@@ -282,33 +279,40 @@ typedef struct ...@@ -282,33 +279,40 @@ typedef struct
/* /*
* The s390_regs structure is used to define the elf_gregset_t. * The s390_regs structure is used to define the elf_gregset_t.
*/ */
typedef struct typedef struct {
{
psw_t psw; psw_t psw;
unsigned long gprs[NUM_GPRS]; unsigned long gprs[NUM_GPRS];
unsigned int acrs[NUM_ACRS]; unsigned int acrs[NUM_ACRS];
unsigned long orig_gpr2; unsigned long orig_gpr2;
} s390_regs; } s390_regs;
/*
* The user_pt_regs structure exports the beginning of
* the in-kernel pt_regs structure to user space.
*/
typedef struct {
unsigned long args[1];
psw_t psw;
unsigned long gprs[NUM_GPRS];
} user_pt_regs;
/* /*
* Now for the user space program event recording (trace) definitions. * Now for the user space program event recording (trace) definitions.
* The following structures are used only for the ptrace interface, don't * The following structures are used only for the ptrace interface, don't
* touch or even look at it if you don't want to modify the user-space * touch or even look at it if you don't want to modify the user-space
* ptrace interface. In particular stay away from it for in-kernel PER. * ptrace interface. In particular stay away from it for in-kernel PER.
*/ */
typedef struct typedef struct {
{
unsigned long cr[NUM_CR_WORDS]; unsigned long cr[NUM_CR_WORDS];
} per_cr_words; } per_cr_words;
#define PER_EM_MASK 0xE8000000UL #define PER_EM_MASK 0xE8000000UL
typedef struct typedef struct {
{
#ifdef __s390x__ #ifdef __s390x__
unsigned : 32; unsigned : 32;
#endif /* __s390x__ */ #endif /* __s390x__ */
unsigned em_branching : 1; unsigned em_branching : 1;
unsigned em_instruction_fetch : 1; unsigned em_instruction_fetch : 1;
/* /*
* Switching on storage alteration automatically fixes * Switching on storage alteration automatically fixes
...@@ -317,44 +321,41 @@ typedef struct ...@@ -317,44 +321,41 @@ typedef struct
unsigned em_storage_alteration : 1; unsigned em_storage_alteration : 1;
unsigned em_gpr_alt_unused : 1; unsigned em_gpr_alt_unused : 1;
unsigned em_store_real_address : 1; unsigned em_store_real_address : 1;
unsigned : 3; unsigned : 3;
unsigned branch_addr_ctl : 1; unsigned branch_addr_ctl : 1;
unsigned : 1; unsigned : 1;
unsigned storage_alt_space_ctl : 1; unsigned storage_alt_space_ctl : 1;
unsigned : 21; unsigned : 21;
unsigned long starting_addr; unsigned long starting_addr;
unsigned long ending_addr; unsigned long ending_addr;
} per_cr_bits; } per_cr_bits;
typedef struct typedef struct {
{
unsigned short perc_atmid; unsigned short perc_atmid;
unsigned long address; unsigned long address;
unsigned char access_id; unsigned char access_id;
} per_lowcore_words; } per_lowcore_words;
typedef struct typedef struct {
{ unsigned perc_branching : 1;
unsigned perc_branching : 1;
unsigned perc_instruction_fetch : 1; unsigned perc_instruction_fetch : 1;
unsigned perc_storage_alteration : 1; unsigned perc_storage_alteration : 1;
unsigned perc_gpr_alt_unused : 1; unsigned perc_gpr_alt_unused : 1;
unsigned perc_store_real_address : 1; unsigned perc_store_real_address : 1;
unsigned : 3; unsigned : 3;
unsigned atmid_psw_bit_31 : 1; unsigned atmid_psw_bit_31 : 1;
unsigned atmid_validity_bit : 1; unsigned atmid_validity_bit : 1;
unsigned atmid_psw_bit_32 : 1; unsigned atmid_psw_bit_32 : 1;
unsigned atmid_psw_bit_5 : 1; unsigned atmid_psw_bit_5 : 1;
unsigned atmid_psw_bit_16 : 1; unsigned atmid_psw_bit_16 : 1;
unsigned atmid_psw_bit_17 : 1; unsigned atmid_psw_bit_17 : 1;
unsigned si : 2; unsigned si : 2;
unsigned long address; unsigned long address;
unsigned : 4; unsigned : 4;
unsigned access_id : 4; unsigned access_id : 4;
} per_lowcore_bits; } per_lowcore_bits;
typedef struct typedef struct {
{
union { union {
per_cr_words words; per_cr_words words;
per_cr_bits bits; per_cr_bits bits;
...@@ -364,9 +365,9 @@ typedef struct ...@@ -364,9 +365,9 @@ typedef struct
* the kernel always sets them to zero. To enable single * the kernel always sets them to zero. To enable single
* stepping use ptrace(PTRACE_SINGLESTEP) instead. * stepping use ptrace(PTRACE_SINGLESTEP) instead.
*/ */
unsigned single_step : 1; unsigned single_step : 1;
unsigned instruction_fetch : 1; unsigned instruction_fetch : 1;
unsigned : 30; unsigned : 30;
/* /*
* These addresses are copied into cr10 & cr11 if single * These addresses are copied into cr10 & cr11 if single
* stepping is switched off * stepping is switched off
...@@ -376,11 +377,10 @@ typedef struct ...@@ -376,11 +377,10 @@ typedef struct
union { union {
per_lowcore_words words; per_lowcore_words words;
per_lowcore_bits bits; per_lowcore_bits bits;
} lowcore; } lowcore;
} per_struct; } per_struct;
typedef struct typedef struct {
{
unsigned int len; unsigned int len;
unsigned long kernel_addr; unsigned long kernel_addr;
unsigned long process_addr; unsigned long process_addr;
...@@ -390,12 +390,12 @@ typedef struct ...@@ -390,12 +390,12 @@ typedef struct
* S/390 specific non posix ptrace requests. I chose unusual values so * S/390 specific non posix ptrace requests. I chose unusual values so
* they are unlikely to clash with future ptrace definitions. * they are unlikely to clash with future ptrace definitions.
*/ */
#define PTRACE_PEEKUSR_AREA 0x5000 #define PTRACE_PEEKUSR_AREA 0x5000
#define PTRACE_POKEUSR_AREA 0x5001 #define PTRACE_POKEUSR_AREA 0x5001
#define PTRACE_PEEKTEXT_AREA 0x5002 #define PTRACE_PEEKTEXT_AREA 0x5002
#define PTRACE_PEEKDATA_AREA 0x5003 #define PTRACE_PEEKDATA_AREA 0x5003
#define PTRACE_POKETEXT_AREA 0x5004 #define PTRACE_POKETEXT_AREA 0x5004
#define PTRACE_POKEDATA_AREA 0x5005 #define PTRACE_POKEDATA_AREA 0x5005
#define PTRACE_GET_LAST_BREAK 0x5006 #define PTRACE_GET_LAST_BREAK 0x5006
#define PTRACE_PEEK_SYSTEM_CALL 0x5007 #define PTRACE_PEEK_SYSTEM_CALL 0x5007
#define PTRACE_POKE_SYSTEM_CALL 0x5008 #define PTRACE_POKE_SYSTEM_CALL 0x5008
...@@ -413,21 +413,19 @@ typedef struct ...@@ -413,21 +413,19 @@ typedef struct
* PT_PROT definition is loosely based on hppa bsd definition in * PT_PROT definition is loosely based on hppa bsd definition in
* gdb/hppab-nat.c * gdb/hppab-nat.c
*/ */
#define PTRACE_PROT 21 #define PTRACE_PROT 21
typedef enum typedef enum {
{
ptprot_set_access_watchpoint, ptprot_set_access_watchpoint,
ptprot_set_write_watchpoint, ptprot_set_write_watchpoint,
ptprot_disable_watchpoint ptprot_disable_watchpoint
} ptprot_flags; } ptprot_flags;
typedef struct typedef struct {
{
unsigned long lowaddr; unsigned long lowaddr;
unsigned long hiaddr; unsigned long hiaddr;
ptprot_flags prot; ptprot_flags prot;
} ptprot_area; } ptprot_area;
/* Sequence of bytes for breakpoint illegal instruction. */ /* Sequence of bytes for breakpoint illegal instruction. */
#define S390_BREAKPOINT {0x0,0x1} #define S390_BREAKPOINT {0x0,0x1}
...@@ -439,8 +437,7 @@ typedef struct ...@@ -439,8 +437,7 @@ typedef struct
* The user_regs_struct defines the way the user registers are * The user_regs_struct defines the way the user registers are
* store on the stack for signal handling. * store on the stack for signal handling.
*/ */
struct user_regs_struct struct user_regs_struct {
{
psw_t psw; psw_t psw;
unsigned long gprs[NUM_GPRS]; unsigned long gprs[NUM_GPRS];
unsigned int acrs[NUM_ACRS]; unsigned int acrs[NUM_ACRS];
......
# UAPI Header export list # UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm include include/uapi/asm-generic/Kbuild.asm
generic-y += bpf_perf_event.h
generic-y += siginfo.h generic-y += siginfo.h
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
include include/uapi/asm-generic/Kbuild.asm include include/uapi/asm-generic/Kbuild.asm
generic-y += bitsperlong.h generic-y += bitsperlong.h
generic-y += bpf_perf_event.h
generic-y += errno.h generic-y += errno.h
generic-y += fcntl.h generic-y += fcntl.h
generic-y += ioctl.h generic-y += ioctl.h
......
# UAPI Header export list # UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm include include/uapi/asm-generic/Kbuild.asm
generic-y += bpf_perf_event.h
generic-y += types.h generic-y += types.h
# UAPI Header export list # UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm include include/uapi/asm-generic/Kbuild.asm
generic-y += bpf_perf_event.h
generic-y += errno.h generic-y += errno.h
generic-y += fcntl.h generic-y += fcntl.h
generic-y += ioctl.h generic-y += ioctl.h
......
...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm ...@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm
generic-y += auxvec.h generic-y += auxvec.h
generic-y += bitsperlong.h generic-y += bitsperlong.h
generic-y += bpf_perf_event.h
generic-y += errno.h generic-y += errno.h
generic-y += fcntl.h generic-y += fcntl.h
generic-y += ioctl.h generic-y += ioctl.h
......
# UAPI Header export list # UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm include include/uapi/asm-generic/Kbuild.asm
generic-y += bpf_perf_event.h
generated-y += unistd_32.h generated-y += unistd_32.h
generated-y += unistd_64.h generated-y += unistd_64.h
generated-y += unistd_x32.h generated-y += unistd_x32.h
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
include include/uapi/asm-generic/Kbuild.asm include include/uapi/asm-generic/Kbuild.asm
generic-y += bitsperlong.h generic-y += bitsperlong.h
generic-y += bpf_perf_event.h
generic-y += errno.h generic-y += errno.h
generic-y += fcntl.h generic-y += fcntl.h
generic-y += ioctl.h generic-y += ioctl.h
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#define _LINUX_PERF_EVENT_H #define _LINUX_PERF_EVENT_H
#include <uapi/linux/perf_event.h> #include <uapi/linux/perf_event.h>
#include <uapi/linux/bpf_perf_event.h>
/* /*
* Kernel-internal data types and definitions: * Kernel-internal data types and definitions:
...@@ -787,7 +788,7 @@ struct perf_output_handle { ...@@ -787,7 +788,7 @@ struct perf_output_handle {
}; };
struct bpf_perf_event_data_kern { struct bpf_perf_event_data_kern {
struct pt_regs *regs; bpf_user_pt_regs_t *regs;
struct perf_sample_data *data; struct perf_sample_data *data;
struct perf_event *event; struct perf_event *event;
}; };
...@@ -1177,6 +1178,9 @@ extern void perf_bp_event(struct perf_event *event, void *data); ...@@ -1177,6 +1178,9 @@ extern void perf_bp_event(struct perf_event *event, void *data);
(user_mode(regs) ? PERF_RECORD_MISC_USER : PERF_RECORD_MISC_KERNEL) (user_mode(regs) ? PERF_RECORD_MISC_USER : PERF_RECORD_MISC_KERNEL)
# define perf_instruction_pointer(regs) instruction_pointer(regs) # define perf_instruction_pointer(regs) instruction_pointer(regs)
#endif #endif
#ifndef perf_arch_bpf_user_pt_regs
# define perf_arch_bpf_user_pt_regs(regs) regs
#endif
static inline bool has_branch_stack(struct perf_event *event) static inline bool has_branch_stack(struct perf_event *event)
{ {
......
#ifndef _UAPI__ASM_GENERIC_BPF_PERF_EVENT_H__
#define _UAPI__ASM_GENERIC_BPF_PERF_EVENT_H__
#include <linux/ptrace.h>
/* Export kernel pt_regs structure */
typedef struct pt_regs bpf_user_pt_regs_t;
#endif /* _UAPI__ASM_GENERIC_BPF_PERF_EVENT_H__ */
...@@ -8,11 +8,10 @@ ...@@ -8,11 +8,10 @@
#ifndef _UAPI__LINUX_BPF_PERF_EVENT_H__ #ifndef _UAPI__LINUX_BPF_PERF_EVENT_H__
#define _UAPI__LINUX_BPF_PERF_EVENT_H__ #define _UAPI__LINUX_BPF_PERF_EVENT_H__
#include <linux/types.h> #include <asm/bpf_perf_event.h>
#include <linux/ptrace.h>
struct bpf_perf_event_data { struct bpf_perf_event_data {
struct pt_regs regs; bpf_user_pt_regs_t regs;
__u64 sample_period; __u64 sample_period;
}; };
......
...@@ -7987,11 +7987,11 @@ static void bpf_overflow_handler(struct perf_event *event, ...@@ -7987,11 +7987,11 @@ static void bpf_overflow_handler(struct perf_event *event,
{ {
struct bpf_perf_event_data_kern ctx = { struct bpf_perf_event_data_kern ctx = {
.data = data, .data = data,
.regs = regs,
.event = event, .event = event,
}; };
int ret = 0; int ret = 0;
ctx.regs = perf_arch_bpf_user_pt_regs(regs);
preempt_disable(); preempt_disable();
if (unlikely(__this_cpu_inc_return(bpf_prog_active) != 1)) if (unlikely(__this_cpu_inc_return(bpf_prog_active) != 1))
goto out; goto out;
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _UAPI__ASM_BPF_PERF_EVENT_H__
#define _UAPI__ASM_BPF_PERF_EVENT_H__
#include <asm/ptrace.h>
typedef struct user_pt_regs bpf_user_pt_regs_t;
#endif /* _UAPI__ASM_BPF_PERF_EVENT_H__ */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _UAPI__ASM_BPF_PERF_EVENT_H__
#define _UAPI__ASM_BPF_PERF_EVENT_H__
#include <asm/ptrace.h>
typedef user_pt_regs bpf_user_pt_regs_t;
#endif /* _UAPI__ASM_BPF_PERF_EVENT_H__ */
This diff is collapsed.
#ifndef _UAPI__ASM_GENERIC_BPF_PERF_EVENT_H__
#define _UAPI__ASM_GENERIC_BPF_PERF_EVENT_H__
#include <linux/ptrace.h>
/* Export kernel pt_regs structure */
typedef struct pt_regs bpf_user_pt_regs_t;
#endif /* _UAPI__ASM_GENERIC_BPF_PERF_EVENT_H__ */
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/* Copyright (c) 2016 Facebook /* Copyright (c) 2016 Facebook
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -7,11 +8,10 @@ ...@@ -7,11 +8,10 @@
#ifndef _UAPI__LINUX_BPF_PERF_EVENT_H__ #ifndef _UAPI__LINUX_BPF_PERF_EVENT_H__
#define _UAPI__LINUX_BPF_PERF_EVENT_H__ #define _UAPI__LINUX_BPF_PERF_EVENT_H__
#include <linux/types.h> #include <asm/bpf_perf_event.h>
#include <linux/ptrace.h>
struct bpf_perf_event_data { struct bpf_perf_event_data {
struct pt_regs regs; bpf_user_pt_regs_t regs;
__u64 sample_period; __u64 sample_period;
}; };
......
...@@ -2,3 +2,4 @@ ifndef NO_DWARF ...@@ -2,3 +2,4 @@ ifndef NO_DWARF
PERF_HAVE_DWARF_REGS := 1 PERF_HAVE_DWARF_REGS := 1
endif endif
HAVE_KVM_STAT_SUPPORT := 1 HAVE_KVM_STAT_SUPPORT := 1
PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
...@@ -2,17 +2,43 @@ ...@@ -2,17 +2,43 @@
/* /*
* Mapping of DWARF debug register numbers into register names. * Mapping of DWARF debug register numbers into register names.
* *
* Copyright IBM Corp. 2010 * Copyright IBM Corp. 2010, 2017
* Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>, * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>,
* Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
* *
*/ */
#include <errno.h>
#include <stddef.h> #include <stddef.h>
#include <dwarf-regs.h> #include <stdlib.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <asm/ptrace.h>
#include <string.h>
#include <dwarf-regs.h>
#include "dwarf-regs-table.h" #include "dwarf-regs-table.h"
const char *get_arch_regstr(unsigned int n) const char *get_arch_regstr(unsigned int n)
{ {
return (n >= ARRAY_SIZE(s390_dwarf_regs)) ? NULL : s390_dwarf_regs[n]; return (n >= ARRAY_SIZE(s390_dwarf_regs)) ? NULL : s390_dwarf_regs[n];
} }
/*
* Convert the register name into an offset to struct pt_regs (kernel).
* This is required by the BPF prologue generator. The BPF
* program is called in the BPF overflow handler in the perf
* core.
*/
int regs_query_register_offset(const char *name)
{
unsigned long gpr;
if (!name || strncmp(name, "%r", 2))
return -EINVAL;
errno = 0;
gpr = strtoul(name + 2, NULL, 10);
if (errno || gpr >= 16)
return -EINVAL;
return offsetof(user_pt_regs, gprs) + 8 * gpr;
}
...@@ -30,6 +30,7 @@ arch/x86/include/uapi/asm/vmx.h ...@@ -30,6 +30,7 @@ arch/x86/include/uapi/asm/vmx.h
arch/powerpc/include/uapi/asm/kvm.h arch/powerpc/include/uapi/asm/kvm.h
arch/s390/include/uapi/asm/kvm.h arch/s390/include/uapi/asm/kvm.h
arch/s390/include/uapi/asm/kvm_perf.h arch/s390/include/uapi/asm/kvm_perf.h
arch/s390/include/uapi/asm/ptrace.h
arch/s390/include/uapi/asm/sie.h arch/s390/include/uapi/asm/sie.h
arch/arm/include/uapi/asm/kvm.h arch/arm/include/uapi/asm/kvm.h
arch/arm64/include/uapi/asm/kvm.h arch/arm64/include/uapi/asm/kvm.h
......
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
ifeq ($(srctree),)
srctree := $(patsubst %/,%,$(dir $(CURDIR)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
endif
include $(srctree)/tools/scripts/Makefile.arch
$(call detected_var,SRCARCH)
LIBDIR := ../../../lib LIBDIR := ../../../lib
BPFDIR := $(LIBDIR)/bpf BPFDIR := $(LIBDIR)/bpf
APIDIR := ../../../include/uapi APIDIR := ../../../include/uapi
ASMDIR:= ../../../arch/$(ARCH)/include/uapi
GENDIR := ../../../../include/generated GENDIR := ../../../../include/generated
GENHDR := $(GENDIR)/autoconf.h GENHDR := $(GENDIR)/autoconf.h
...@@ -9,7 +21,7 @@ ifneq ($(wildcard $(GENHDR)),) ...@@ -9,7 +21,7 @@ ifneq ($(wildcard $(GENHDR)),)
GENFLAGS := -DHAVE_GENHDR GENFLAGS := -DHAVE_GENHDR
endif endif
CFLAGS += -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(GENDIR) $(GENFLAGS) -I../../../include CFLAGS += -Wall -O2 -I$(APIDIR) -I$(ASMDIR) -I$(LIBDIR) -I$(GENDIR) $(GENFLAGS) -I../../../include
LDLIBS += -lcap -lelf LDLIBS += -lcap -lelf
TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment