samples/bpf: Enable powerpc support
authorNaveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Mon, 4 Apr 2016 17:01:34 +0000 (22:31 +0530)
committerDavid S. Miller <davem@davemloft.net>
Wed, 6 Apr 2016 20:01:29 +0000 (16:01 -0400)
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 <ast@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
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>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
samples/bpf/bpf_helpers.h
samples/bpf/spintest_kern.c
samples/bpf/tracex2_kern.c
samples/bpf/tracex4_kern.c

index 9363500131a777f98cd7016a35b9cf9858dbf9a6..7904a2a493de43f69c0cf868d78c38d8509790af 100644 (file)
@@ -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
index 4b27619d91a46c680a01b91bf05ac6fd6b5ce1d7..ce0167d09cdc6f1432e687933bf38ebef59bad21 100644 (file)
@@ -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); \
index 09c1adc27d426ed4adec7408a6fbae9193c39bb0..6d6eefd0d4655ed3bdcebe6bf1956a7f43a70d27 100644 (file)
@@ -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)
index ac4671420cf15949c4087b8c2847c69978646650..6dd8e384de961b66269f5da840b5d4b22d057ea8 100644 (file)
@@ -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(),