bcc/tools: Introduce bpf_probe_read_user to the tools.

This is essential for architecture which do have overlapping address space.
- bpf_probe_read_kernel() shall be used for reading data from kernel space
to the bpf vm.
- bpf_probe_read_user() shall be used for reading data from user space
  to the bpf vm.

Signed-off-by: Sumanth Korikkar <[email protected]>
diff --git a/tools/bashreadline.py b/tools/bashreadline.py
index b7d9827..ad9cfdc 100755
--- a/tools/bashreadline.py
+++ b/tools/bashreadline.py
@@ -52,7 +52,7 @@
         return 0;
     pid = bpf_get_current_pid_tgid();
     data.pid = pid;
-    bpf_probe_read(&data.str, sizeof(data.str), (void *)PT_REGS_RC(ctx));
+    bpf_probe_read_user(&data.str, sizeof(data.str), (void *)PT_REGS_RC(ctx));
 
     bpf_get_current_comm(&comm, sizeof(comm));
     if (comm[0] == 'b' && comm[1] == 'a' && comm[2] == 's' && comm[3] == 'h' && comm[4] == 0 ) {
diff --git a/tools/biosnoop.lua b/tools/biosnoop.lua
index 705212e..21261d0 100755
--- a/tools/biosnoop.lua
+++ b/tools/biosnoop.lua
@@ -84,7 +84,8 @@
     valp = infobyreq.lookup(&req);
     if (valp == 0) {
         data.len = req->__data_len;
-        strcpy(data.name,"?");
+        data.name[0] = '?';
+        data.name[1] = 0;
     } else {
         data.pid = valp->pid;
         data.len = req->__data_len;
diff --git a/tools/biosnoop.py b/tools/biosnoop.py
index e6f708f..b550281 100755
--- a/tools/biosnoop.py
+++ b/tools/biosnoop.py
@@ -108,7 +108,8 @@
     valp = infobyreq.lookup(&req);
     if (valp == 0) {
         data.len = req->__data_len;
-        strcpy(data.name, "?");
+        data.name[0] = '?';
+        data.name[1] = 0;
     } else {
         if (##QUEUE##) {
             data.qdelta = *tsp - valp->ts;
diff --git a/tools/dbslower.py b/tools/dbslower.py
index 2f1b6a8..ffbb5e1 100755
--- a/tools/dbslower.py
+++ b/tools/dbslower.py
@@ -127,12 +127,12 @@
     tmp.timestamp = bpf_ktime_get_ns();
 
 #if defined(MYSQL56)
-    bpf_probe_read(&tmp.query, sizeof(tmp.query), (void*) PT_REGS_PARM3(ctx));
+    bpf_probe_read_user(&tmp.query, sizeof(tmp.query), (void*) PT_REGS_PARM3(ctx));
 #elif defined(MYSQL57)
     void* st = (void*) PT_REGS_PARM2(ctx);
     char* query;
-    bpf_probe_read(&query, sizeof(query), st);
-    bpf_probe_read(&tmp.query, sizeof(tmp.query), query);
+    bpf_probe_read_user(&query, sizeof(query), st);
+    bpf_probe_read_user(&tmp.query, sizeof(tmp.query), query);
 #else //USDT
     bpf_usdt_readarg(1, ctx, &tmp.query);
 #endif
@@ -157,7 +157,13 @@
         data.pid = pid >> 32;   // only process id
         data.timestamp = tempp->timestamp;
         data.duration = delta;
+#if defined(MYSQL56) || defined(MYSQL57)
+	// We already copied string to the bpf stack. Hence use bpf_probe_read()
         bpf_probe_read(&data.query, sizeof(data.query), tempp->query);
+#else
+	// USDT - we didnt copy string to the bpf stack before.
+        bpf_probe_read_user(&data.query, sizeof(data.query), tempp->query);
+#endif
         events.perf_submit(ctx, &data, sizeof(data));
 #ifdef THRESHOLD
     }
diff --git a/tools/execsnoop.py b/tools/execsnoop.py
index 26cbce6..9879d2c 100755
--- a/tools/execsnoop.py
+++ b/tools/execsnoop.py
@@ -120,7 +120,7 @@
 
 static int __submit_arg(struct pt_regs *ctx, void *ptr, struct data_t *data)
 {
-    bpf_probe_read(data->argv, sizeof(data->argv), ptr);
+    bpf_probe_read_user(data->argv, sizeof(data->argv), ptr);
     events.perf_submit(ctx, data, sizeof(struct data_t));
     return 1;
 }
@@ -128,7 +128,7 @@
 static int submit_arg(struct pt_regs *ctx, void *ptr, struct data_t *data)
 {
     const char *argp = NULL;
-    bpf_probe_read(&argp, sizeof(argp), ptr);
+    bpf_probe_read_user(&argp, sizeof(argp), ptr);
     if (argp) {
         return __submit_arg(ctx, (void *)(argp), data);
     }
diff --git a/tools/funcslower.py b/tools/funcslower.py
index bda6a84..9acd35d 100755
--- a/tools/funcslower.py
+++ b/tools/funcslower.py
@@ -82,7 +82,11 @@
     u64 id;
     u64 start_ns;
 #ifdef GRAB_ARGS
+#ifndef __s390x__
     u64 args[6];
+#else
+    u64 args[5];
+#endif
 #endif
 };
 
@@ -94,7 +98,11 @@
     u64 retval;
     char comm[TASK_COMM_LEN];
 #ifdef GRAB_ARGS
+#ifndef __s390x__
     u64 args[6];
+#else
+    u64 args[5];
+#endif
 #endif
 #ifdef USER_STACKS
     int user_stack_id;
@@ -130,8 +138,10 @@
     entry.args[2] = PT_REGS_PARM3(ctx);
     entry.args[3] = PT_REGS_PARM4(ctx);
     entry.args[4] = PT_REGS_PARM5(ctx);
+#ifndef __s390x__
     entry.args[5] = PT_REGS_PARM6(ctx);
 #endif
+#endif
 
     entryinfo.update(&tgid_pid, &entry);
 
diff --git a/tools/gethostlatency.py b/tools/gethostlatency.py
index f7506a8..a6b8080 100755
--- a/tools/gethostlatency.py
+++ b/tools/gethostlatency.py
@@ -64,7 +64,7 @@
     u32 pid = bpf_get_current_pid_tgid();
 
     if (bpf_get_current_comm(&val.comm, sizeof(val.comm)) == 0) {
-        bpf_probe_read(&val.host, sizeof(val.host),
+        bpf_probe_read_user(&val.host, sizeof(val.host),
                        (void *)PT_REGS_PARM1(ctx));
         val.pid = bpf_get_current_pid_tgid();
         val.ts = bpf_ktime_get_ns();
diff --git a/tools/lib/ucalls.py b/tools/lib/ucalls.py
index 307df25..396d56e 100755
--- a/tools/lib/ucalls.py
+++ b/tools/lib/ucalls.py
@@ -158,9 +158,9 @@
 #endif
     READ_CLASS
     READ_METHOD
-    bpf_probe_read(&data.method.clazz, sizeof(data.method.clazz),
+    bpf_probe_read_user(&data.method.clazz, sizeof(data.method.clazz),
                    (void *)clazz);
-    bpf_probe_read(&data.method.method, sizeof(data.method.method),
+    bpf_probe_read_user(&data.method.method, sizeof(data.method.method),
                    (void *)method);
 #ifndef LATENCY
     valp = counts.lookup_or_try_init(&data.method, &val);
@@ -182,9 +182,9 @@
     data.pid = bpf_get_current_pid_tgid();
     READ_CLASS
     READ_METHOD
-    bpf_probe_read(&data.method.clazz, sizeof(data.method.clazz),
+    bpf_probe_read_user(&data.method.clazz, sizeof(data.method.clazz),
                    (void *)clazz);
-    bpf_probe_read(&data.method.method, sizeof(data.method.method),
+    bpf_probe_read_user(&data.method.method, sizeof(data.method.method),
                    (void *)method);
     entry_timestamp = entry.lookup(&data);
     if (!entry_timestamp) {
diff --git a/tools/lib/uflow.py b/tools/lib/uflow.py
index 4779ba2..de3d7e2 100755
--- a/tools/lib/uflow.py
+++ b/tools/lib/uflow.py
@@ -81,8 +81,8 @@
 
     READ_CLASS
     READ_METHOD
-    bpf_probe_read(&data.clazz, sizeof(data.clazz), (void *)clazz);
-    bpf_probe_read(&data.method, sizeof(data.method), (void *)method);
+    bpf_probe_read_user(&data.clazz, sizeof(data.clazz), (void *)clazz);
+    bpf_probe_read_user(&data.method, sizeof(data.method), (void *)method);
 
     FILTER_CLASS
     FILTER_METHOD
diff --git a/tools/lib/ugc.py b/tools/lib/ugc.py
index 8841d5f..8f4c8de 100755
--- a/tools/lib/ugc.py
+++ b/tools/lib/ugc.py
@@ -140,8 +140,8 @@
     u64 manager = 0, pool = 0;
     bpf_usdt_readarg(1, ctx, &manager);        // ptr to manager name
     bpf_usdt_readarg(3, ctx, &pool);           // ptr to pool name
-    bpf_probe_read(&event.string1, sizeof(event.string1), (void *)manager);
-    bpf_probe_read(&event.string2, sizeof(event.string2), (void *)pool);
+    bpf_probe_read_user(&event.string1, sizeof(event.string1), (void *)manager);
+    bpf_probe_read_user(&event.string2, sizeof(event.string2), (void *)pool);
     """
 
     def formatter(e):
diff --git a/tools/lib/uobjnew.py b/tools/lib/uobjnew.py
index b8eed0f..f75ba04 100755
--- a/tools/lib/uobjnew.py
+++ b/tools/lib/uobjnew.py
@@ -98,7 +98,7 @@
     u64 classptr = 0, size = 0;
     bpf_usdt_readarg(2, ctx, &classptr);
     bpf_usdt_readarg(4, ctx, &size);
-    bpf_probe_read(&key.name, sizeof(key.name), (void *)classptr);
+    bpf_probe_read_user(&key.name, sizeof(key.name), (void *)classptr);
     valp = allocs.lookup_or_try_init(&key, &zero);
     if (valp) {
         valp->total_size += size;
@@ -132,7 +132,7 @@
     struct val_t *valp, zero = {};
     u64 classptr = 0;
     bpf_usdt_readarg(1, ctx, &classptr);
-    bpf_probe_read(&key.name, sizeof(key.name), (void *)classptr);
+    bpf_probe_read_user(&key.name, sizeof(key.name), (void *)classptr);
     valp = allocs.lookup_or_try_init(&key, &zero);
     if (valp) {
         valp->num_allocs += 1;  // We don't know the size, unfortunately
diff --git a/tools/lib/uthreads.py b/tools/lib/uthreads.py
index 90d0a74..9745b3d 100755
--- a/tools/lib/uthreads.py
+++ b/tools/lib/uthreads.py
@@ -80,7 +80,7 @@
     bpf_usdt_readarg(1, ctx, &nameptr);
     bpf_usdt_readarg(3, ctx, &id);
     bpf_usdt_readarg(4, ctx, &native_id);
-    bpf_probe_read(&te.name, sizeof(te.name), (void *)nameptr);
+    bpf_probe_read_user(&te.name, sizeof(te.name), (void *)nameptr);
     te.runtime_id = id;
     te.native_id = native_id;
     __builtin_memcpy(&te.type, type, sizeof(te.type));
diff --git a/tools/mountsnoop.py b/tools/mountsnoop.py
index 17a2edb..667ea35 100755
--- a/tools/mountsnoop.py
+++ b/tools/mountsnoop.py
@@ -109,22 +109,22 @@
 
     event.type = EVENT_MOUNT_SOURCE;
     __builtin_memset(event.str, 0, sizeof(event.str));
-    bpf_probe_read(event.str, sizeof(event.str), source);
+    bpf_probe_read_user(event.str, sizeof(event.str), source);
     events.perf_submit(ctx, &event, sizeof(event));
 
     event.type = EVENT_MOUNT_TARGET;
     __builtin_memset(event.str, 0, sizeof(event.str));
-    bpf_probe_read(event.str, sizeof(event.str), target);
+    bpf_probe_read_user(event.str, sizeof(event.str), target);
     events.perf_submit(ctx, &event, sizeof(event));
 
     event.type = EVENT_MOUNT_TYPE;
     __builtin_memset(event.str, 0, sizeof(event.str));
-    bpf_probe_read(event.str, sizeof(event.str), type);
+    bpf_probe_read_user(event.str, sizeof(event.str), type);
     events.perf_submit(ctx, &event, sizeof(event));
 
     event.type = EVENT_MOUNT_DATA;
     __builtin_memset(event.str, 0, sizeof(event.str));
-    bpf_probe_read(event.str, sizeof(event.str), data);
+    bpf_probe_read_user(event.str, sizeof(event.str), data);
     events.perf_submit(ctx, &event, sizeof(event));
 
     return 0;
@@ -164,7 +164,7 @@
 
     event.type = EVENT_UMOUNT_TARGET;
     __builtin_memset(event.str, 0, sizeof(event.str));
-    bpf_probe_read(event.str, sizeof(event.str), target);
+    bpf_probe_read_user(event.str, sizeof(event.str), target);
     events.perf_submit(ctx, &event, sizeof(event));
 
     return 0;
diff --git a/tools/mysqld_qslower.py b/tools/mysqld_qslower.py
index d867d70..33ea7dd 100755
--- a/tools/mysqld_qslower.py
+++ b/tools/mysqld_qslower.py
@@ -81,7 +81,7 @@
     if (delta >= """ + str(min_ns) + """) {
         // populate and emit data struct
         struct data_t data = {.pid = pid, .ts = sp->ts, .delta = delta};
-        bpf_probe_read(&data.query, sizeof(data.query), (void *)sp->query);
+        bpf_probe_read_user(&data.query, sizeof(data.query), (void *)sp->query);
         events.perf_submit(ctx, &data, sizeof(data));
     }
 
diff --git a/tools/opensnoop.py b/tools/opensnoop.py
index b28d7d5..995443e 100755
--- a/tools/opensnoop.py
+++ b/tools/opensnoop.py
@@ -152,7 +152,7 @@
         return 0;
     }
     bpf_probe_read(&data.comm, sizeof(data.comm), valp->comm);
-    bpf_probe_read(&data.fname, sizeof(data.fname), (void *)valp->fname);
+    bpf_probe_read_user(&data.fname, sizeof(data.fname), (void *)valp->fname);
     data.id = valp->id;
     data.ts = tsp / 1000;
     data.uid = bpf_get_current_uid_gid();
@@ -167,7 +167,7 @@
 """
 
 bpf_text_kfunc= """
-KRETFUNC_PROBE(do_sys_open, int dfd, const char *filename, int flags, int mode, int ret)
+KRETFUNC_PROBE(do_sys_open, int dfd, const char __user *filename, int flags, int mode, int ret)
 {
     u64 id = bpf_get_current_pid_tgid();
     u32 pid = id >> 32; // PID is higher part
@@ -189,7 +189,7 @@
 
     u64 tsp = bpf_ktime_get_ns();
 
-    bpf_probe_read(&data.fname, sizeof(data.fname), (void *)filename);
+    bpf_probe_read_user(&data.fname, sizeof(data.fname), (void *)filename);
     data.id    = id;
     data.ts    = tsp / 1000;
     data.uid   = bpf_get_current_uid_gid();
diff --git a/tools/sslsniff.py b/tools/sslsniff.py
index e48fbb4..8c027fe 100755
--- a/tools/sslsniff.py
+++ b/tools/sslsniff.py
@@ -72,7 +72,7 @@
         bpf_get_current_comm(&__data.comm, sizeof(__data.comm));
 
         if ( buf != 0) {
-                bpf_probe_read(&__data.v0, sizeof(__data.v0), buf);
+                bpf_probe_read_user(&__data.v0, sizeof(__data.v0), buf);
         }
 
         perf_SSL_write.perf_submit(ctx, &__data, sizeof(__data));
@@ -108,7 +108,7 @@
         bpf_get_current_comm(&__data.comm, sizeof(__data.comm));
 
         if (bufp != 0) {
-                bpf_probe_read(&__data.v0, sizeof(__data.v0), (char *)*bufp);
+                bpf_probe_read_user(&__data.v0, sizeof(__data.v0), (char *)*bufp);
         }
 
         bufs.delete(&pid);
diff --git a/tools/statsnoop.py b/tools/statsnoop.py
index 6cdff94..9c7df0b 100755
--- a/tools/statsnoop.py
+++ b/tools/statsnoop.py
@@ -84,7 +84,7 @@
     }
 
     struct data_t data = {.pid = pid};
-    bpf_probe_read(&data.fname, sizeof(data.fname), (void *)valp->fname);
+    bpf_probe_read_user(&data.fname, sizeof(data.fname), (void *)valp->fname);
     bpf_get_current_comm(&data.comm, sizeof(data.comm));
     data.ts_ns = bpf_ktime_get_ns();
     data.ret = PT_REGS_RC(ctx);