From 138d6153a139c318739f20e61309e5778427a73c Mon Sep 17 00:00:00 2001 From: "Naveen N. Rao" Date: Mon, 4 Apr 2016 22:31:34 +0530 Subject: samples/bpf: Enable powerpc support Add the necessary definitions for building bpf samples on ppc. Since ppc doesn't store function return address on the stack, modify how PT_REGS_RET() and PT_REGS_FP() work. Also, introduce PT_REGS_IP() to access the instruction pointer. Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: David S. Miller Cc: Ananth N Mavinakayanahalli Cc: Michael Ellerman Signed-off-by: Naveen N. Rao Acked-by: Alexei Starovoitov Signed-off-by: David S. Miller --- samples/bpf/bpf_helpers.h | 26 ++++++++++++++++++++++++++ samples/bpf/spintest_kern.c | 2 +- samples/bpf/tracex2_kern.c | 4 ++-- samples/bpf/tracex4_kern.c | 2 +- 4 files changed, 30 insertions(+), 4 deletions(-) (limited to 'samples/bpf') diff --git a/samples/bpf/bpf_helpers.h b/samples/bpf/bpf_helpers.h index 9363500131a7..7904a2a493de 100644 --- a/samples/bpf/bpf_helpers.h +++ b/samples/bpf/bpf_helpers.h @@ -82,6 +82,7 @@ static int (*bpf_l4_csum_replace)(void *ctx, int off, int from, int to, int flag #define PT_REGS_FP(x) ((x)->bp) #define PT_REGS_RC(x) ((x)->ax) #define PT_REGS_SP(x) ((x)->sp) +#define PT_REGS_IP(x) ((x)->ip) #elif defined(__s390x__) @@ -94,6 +95,7 @@ static int (*bpf_l4_csum_replace)(void *ctx, int off, int from, int to, int flag #define PT_REGS_FP(x) ((x)->gprs[11]) /* Works only with CONFIG_FRAME_POINTER */ #define PT_REGS_RC(x) ((x)->gprs[2]) #define PT_REGS_SP(x) ((x)->gprs[15]) +#define PT_REGS_IP(x) ((x)->ip) #elif defined(__aarch64__) @@ -106,6 +108,30 @@ static int (*bpf_l4_csum_replace)(void *ctx, int off, int from, int to, int flag #define PT_REGS_FP(x) ((x)->regs[29]) /* Works only with CONFIG_FRAME_POINTER */ #define PT_REGS_RC(x) ((x)->regs[0]) #define PT_REGS_SP(x) ((x)->sp) +#define PT_REGS_IP(x) ((x)->pc) + +#elif defined(__powerpc__) + +#define PT_REGS_PARM1(x) ((x)->gpr[3]) +#define PT_REGS_PARM2(x) ((x)->gpr[4]) +#define PT_REGS_PARM3(x) ((x)->gpr[5]) +#define PT_REGS_PARM4(x) ((x)->gpr[6]) +#define PT_REGS_PARM5(x) ((x)->gpr[7]) +#define PT_REGS_RC(x) ((x)->gpr[3]) +#define PT_REGS_SP(x) ((x)->sp) +#define PT_REGS_IP(x) ((x)->nip) #endif + +#ifdef __powerpc__ +#define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = (ctx)->link; }) +#define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP +#else +#define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ \ + bpf_probe_read(&(ip), sizeof(ip), (void *)PT_REGS_RET(ctx)); }) +#define BPF_KRETPROBE_READ_RET_IP(ip, ctx) ({ \ + bpf_probe_read(&(ip), sizeof(ip), \ + (void *)(PT_REGS_FP(ctx) + sizeof(ip))); }) +#endif + #endif diff --git a/samples/bpf/spintest_kern.c b/samples/bpf/spintest_kern.c index 4b27619d91a4..ce0167d09cdc 100644 --- a/samples/bpf/spintest_kern.c +++ b/samples/bpf/spintest_kern.c @@ -34,7 +34,7 @@ struct bpf_map_def SEC("maps") stackmap = { #define PROG(foo) \ int foo(struct pt_regs *ctx) \ { \ - long v = ctx->ip, *val; \ + long v = PT_REGS_IP(ctx), *val; \ \ val = bpf_map_lookup_elem(&my_map, &v); \ bpf_map_update_elem(&my_map, &v, &v, BPF_ANY); \ diff --git a/samples/bpf/tracex2_kern.c b/samples/bpf/tracex2_kern.c index 09c1adc27d42..6d6eefd0d465 100644 --- a/samples/bpf/tracex2_kern.c +++ b/samples/bpf/tracex2_kern.c @@ -27,10 +27,10 @@ int bpf_prog2(struct pt_regs *ctx) long init_val = 1; long *value; - /* x64/s390x specific: read ip of kfree_skb caller. + /* read ip of kfree_skb caller. * non-portable version of __builtin_return_address(0) */ - bpf_probe_read(&loc, sizeof(loc), (void *)PT_REGS_RET(ctx)); + BPF_KPROBE_READ_RET_IP(loc, ctx); value = bpf_map_lookup_elem(&my_map, &loc); if (value) diff --git a/samples/bpf/tracex4_kern.c b/samples/bpf/tracex4_kern.c index ac4671420cf1..6dd8e384de96 100644 --- a/samples/bpf/tracex4_kern.c +++ b/samples/bpf/tracex4_kern.c @@ -40,7 +40,7 @@ int bpf_prog2(struct pt_regs *ctx) long ip = 0; /* get ip address of kmem_cache_alloc_node() caller */ - bpf_probe_read(&ip, sizeof(ip), (void *)(PT_REGS_FP(ctx) + sizeof(ip))); + BPF_KRETPROBE_READ_RET_IP(ip, ctx); struct pair v = { .val = bpf_ktime_get_ns(), -- cgit v1.2.1