Message ID | 28a3811d03f6e8f7dca989a4ade536bf9aa8c7ce.1459423412.git.naveen.n.rao@linux.vnet.ibm.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
On 3/31/16 4:25 AM, Naveen N. Rao wrote: > 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. I have > fixed this to work with x86_64 and arm64, but not s390. > > Cc: Alexei Starovoitov <ast@fb.com> > Cc: David S. Miller <davem@davemloft.net> > Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> > Cc: Michael Ellerman <mpe@ellerman.id.au> > Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> > --- ... > + > +#ifdef __powerpc__ > +#define BPF_KPROBE_READ_RET_IP(ip, ctx) { (ip) = (ctx)->link; } > +#define BPF_KRETPROBE_READ_RET_IP(ip, ctx) BPF_KPROBE_READ_RET_IP(ip, ctx) > +#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))) makes sense, but please use ({ }) gcc extension instead of {} and open call to make sure that macro body is scoped.
On 2016/03/31 10:52AM, Alexei Starovoitov wrote: > On 3/31/16 4:25 AM, Naveen N. Rao wrote: > ... > >+ > >+#ifdef __powerpc__ > >+#define BPF_KPROBE_READ_RET_IP(ip, ctx) { (ip) = (ctx)->link; } > >+#define BPF_KRETPROBE_READ_RET_IP(ip, ctx) BPF_KPROBE_READ_RET_IP(ip, ctx) > >+#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))) > > makes sense, but please use ({ }) gcc extension instead of {} and > open call to make sure that macro body is scoped. To be sure I understand this right, do you mean something like this? + +#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 + Thanks, Naveen
On 4/1/16 7:41 AM, Naveen N. Rao wrote: > On 2016/03/31 10:52AM, Alexei Starovoitov wrote: >> On 3/31/16 4:25 AM, Naveen N. Rao wrote: >> ... >>> + >>> +#ifdef __powerpc__ >>> +#define BPF_KPROBE_READ_RET_IP(ip, ctx) { (ip) = (ctx)->link; } >>> +#define BPF_KRETPROBE_READ_RET_IP(ip, ctx) BPF_KPROBE_READ_RET_IP(ip, ctx) >>> +#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))) >> >> makes sense, but please use ({ }) gcc extension instead of {} and >> open call to make sure that macro body is scoped. > > To be sure I understand this right, do you mean something like this? > > + > +#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 yes. Thanks!
diff --git a/samples/bpf/bpf_helpers.h b/samples/bpf/bpf_helpers.h index 9363500..343423c 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(ip, ctx) BPF_KPROBE_READ_RET_IP(ip, ctx) +#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 4b27619..ce0167d 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 09c1adc..6d6eefd 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 ac46714..6dd8e38 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(),
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. I have fixed this to work with x86_64 and arm64, but not s390. Cc: Alexei Starovoitov <ast@fb.com> Cc: David S. Miller <davem@davemloft.net> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> --- 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(-)