s390/bpf: correct broken uapi for BPF_PROG_TYPE_PERF_EVENT program type

To mitigate and correct the broken uapi for the BPF_PROG_TYPE_PERF_EVENT
program type, introduce a user_pt_regs structure (similar to arm64) that
exports parts from the beginnig of the pt_regs structure.

The export must start with the beginning of the pt_regs structure because
to correctly calculate BPF prologues for perf (regs_query_register_offset()).

For BPF_PROG_TYPE_PERF_EVENT program types, the BPF program is then passed
a user_pt_regs structure.

Note: Depending on future changes to the s390 pt_regs structure, consider
the user_pt_regs structure to be stable for a particular kernel version
only. (Of course, s390 tries to ensure keep it stable as much as possible.)

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: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
This commit is contained in:
Hendrik Brueckner 2017-12-04 10:56:45 +01:00 коммит произвёл Daniel Borkmann
Родитель c895f6f703
Коммит 466698e654
4 изменённых файлов: 29 добавлений и 3 удалений

Просмотреть файл

@ -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 {
*/ */
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;

Просмотреть файл

@ -0,0 +1,9 @@
/* 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__ */

Просмотреть файл

@ -290,6 +290,17 @@ typedef struct
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