samples: bpf: enable trace samples for s390x
authorMichael Holzheu <holzheu@linux.vnet.ibm.com>
Mon, 6 Jul 2015 14:20:07 +0000 (16:20 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 8 Jul 2015 22:17:45 +0000 (15:17 -0700)
The trace bpf samples do not compile on s390x because they use x86
specific fields from the "pt_regs" structure.

Fix this and access the fields via new PT_REGS macros.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
samples/bpf/bpf_helpers.h
samples/bpf/tracex1_kern.c
samples/bpf/tracex2_kern.c
samples/bpf/tracex3_kern.c
samples/bpf/tracex4_kern.c
samples/bpf/tracex5_kern.c

index bdf1c1607b808e9ac0d7ada164a25694c56b6965..c77c872fe8ee477c7cfabf5fd539824fc676b173 100644 (file)
@@ -60,4 +60,29 @@ static int (*bpf_l3_csum_replace)(void *ctx, int off, int from, int to, int flag
 static int (*bpf_l4_csum_replace)(void *ctx, int off, int from, int to, int flags) =
        (void *) BPF_FUNC_l4_csum_replace;
 
+#if defined(__x86_64__)
+
+#define PT_REGS_PARM1(x) ((x)->di)
+#define PT_REGS_PARM2(x) ((x)->si)
+#define PT_REGS_PARM3(x) ((x)->dx)
+#define PT_REGS_PARM4(x) ((x)->cx)
+#define PT_REGS_PARM5(x) ((x)->r8)
+#define PT_REGS_RET(x) ((x)->sp)
+#define PT_REGS_FP(x) ((x)->bp)
+#define PT_REGS_RC(x) ((x)->ax)
+#define PT_REGS_SP(x) ((x)->sp)
+
+#elif defined(__s390x__)
+
+#define PT_REGS_PARM1(x) ((x)->gprs[2])
+#define PT_REGS_PARM2(x) ((x)->gprs[3])
+#define PT_REGS_PARM3(x) ((x)->gprs[4])
+#define PT_REGS_PARM4(x) ((x)->gprs[5])
+#define PT_REGS_PARM5(x) ((x)->gprs[6])
+#define PT_REGS_RET(x) ((x)->gprs[14])
+#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])
+
+#endif
 #endif
index 31620463701a55edc0afc54d45a5cabaef890410..3f450a8fa1f3487b2cf2d9b261f63dc3d25f6599 100644 (file)
@@ -29,7 +29,7 @@ int bpf_prog1(struct pt_regs *ctx)
        int len;
 
        /* non-portable! works for the given kernel only */
-       skb = (struct sk_buff *) ctx->di;
+       skb = (struct sk_buff *) PT_REGS_PARM1(ctx);
 
        dev = _(skb->dev);
 
index dc50f4f2943f937d5c389e5384d39a0153d3f273..b32367cfbff4aff3020bb9c36c8faf6c981dd0f8 100644 (file)
@@ -27,10 +27,10 @@ int bpf_prog2(struct pt_regs *ctx)
        long init_val = 1;
        long *value;
 
-       /* x64 specific: read ip of kfree_skb caller.
+       /* x64/s390x specific: read ip of kfree_skb caller.
         * non-portable version of __builtin_return_address(0)
         */
-       bpf_probe_read(&loc, sizeof(loc), (void *)ctx->sp);
+       bpf_probe_read(&loc, sizeof(loc), (void *)PT_REGS_RET(ctx));
 
        value = bpf_map_lookup_elem(&my_map, &loc);
        if (value)
@@ -79,7 +79,7 @@ struct bpf_map_def SEC("maps") my_hist_map = {
 SEC("kprobe/sys_write")
 int bpf_prog3(struct pt_regs *ctx)
 {
-       long write_size = ctx->dx; /* arg3 */
+       long write_size = PT_REGS_PARM3(ctx);
        long init_val = 1;
        long *value;
        struct hist_key key = {};
index 255ff27923666a844e3cb2881e25661278c7c1d6..bf337fbb09472cbe32bfbaff2d4313b7cafb58c6 100644 (file)
@@ -23,7 +23,7 @@ struct bpf_map_def SEC("maps") my_map = {
 SEC("kprobe/blk_mq_start_request")
 int bpf_prog1(struct pt_regs *ctx)
 {
-       long rq = ctx->di;
+       long rq = PT_REGS_PARM1(ctx);
        u64 val = bpf_ktime_get_ns();
 
        bpf_map_update_elem(&my_map, &rq, &val, BPF_ANY);
@@ -51,7 +51,7 @@ struct bpf_map_def SEC("maps") lat_map = {
 SEC("kprobe/blk_update_request")
 int bpf_prog2(struct pt_regs *ctx)
 {
-       long rq = ctx->di;
+       long rq = PT_REGS_PARM1(ctx);
        u64 *value, l, base;
        u32 index;
 
index 126b80512228aa6493c8332e75933ab5852acab1..ac4671420cf15949c4087b8c2847c69978646650 100644 (file)
@@ -27,7 +27,7 @@ struct bpf_map_def SEC("maps") my_map = {
 SEC("kprobe/kmem_cache_free")
 int bpf_prog1(struct pt_regs *ctx)
 {
-       long ptr = ctx->si;
+       long ptr = PT_REGS_PARM2(ctx);
 
        bpf_map_delete_elem(&my_map, &ptr);
        return 0;
@@ -36,11 +36,11 @@ int bpf_prog1(struct pt_regs *ctx)
 SEC("kretprobe/kmem_cache_alloc_node")
 int bpf_prog2(struct pt_regs *ctx)
 {
-       long ptr = ctx->ax;
+       long ptr = PT_REGS_RC(ctx);
        long ip = 0;
 
        /* get ip address of kmem_cache_alloc_node() caller */
-       bpf_probe_read(&ip, sizeof(ip), (void *)(ctx->bp + sizeof(ip)));
+       bpf_probe_read(&ip, sizeof(ip), (void *)(PT_REGS_FP(ctx) + sizeof(ip)));
 
        struct pair v = {
                .val = bpf_ktime_get_ns(),
index b71fe07a7a7a4820a77e7cb0d5a112febdbaa49c..b3f4295bf288536c1f9ae7500b542a77cf8aaec1 100644 (file)
@@ -24,7 +24,7 @@ int bpf_prog1(struct pt_regs *ctx)
 {
        struct seccomp_data sd = {};
 
-       bpf_probe_read(&sd, sizeof(sd), (void *)ctx->di);
+       bpf_probe_read(&sd, sizeof(sd), (void *)PT_REGS_PARM1(ctx));
 
        /* dispatch into next BPF program depending on syscall number */
        bpf_tail_call(ctx, &progs, sd.nr);
@@ -42,7 +42,7 @@ PROG(__NR_write)(struct pt_regs *ctx)
 {
        struct seccomp_data sd = {};
 
-       bpf_probe_read(&sd, sizeof(sd), (void *)ctx->di);
+       bpf_probe_read(&sd, sizeof(sd), (void *)PT_REGS_PARM1(ctx));
        if (sd.args[2] == 512) {
                char fmt[] = "write(fd=%d, buf=%p, size=%d)\n";
                bpf_trace_printk(fmt, sizeof(fmt),
@@ -55,7 +55,7 @@ PROG(__NR_read)(struct pt_regs *ctx)
 {
        struct seccomp_data sd = {};
 
-       bpf_probe_read(&sd, sizeof(sd), (void *)ctx->di);
+       bpf_probe_read(&sd, sizeof(sd), (void *)PT_REGS_PARM1(ctx));
        if (sd.args[2] > 128 && sd.args[2] <= 1024) {
                char fmt[] = "read(fd=%d, buf=%p, size=%d)\n";
                bpf_trace_printk(fmt, sizeof(fmt),