From: He Kuang <hekuang@huawei.com>
To: <wangnan0@huawei.com>, <paulus@samba.org>,
<a.p.zijlstra@chello.nl>, <mingo@redhat.com>, <acme@kernel.org>,
<namhyung@kernel.org>, <jolsa@kernel.org>, <ast@plumgrid.com>,
<masami.hiramatsu.pt@hitachi.com>, <dsahern@gmail.com>,
<brendan.d.gregg@gmail.com>, <daniel@iogearbox.net>
Cc: <lizefan@huawei.com>, <linux-kernel@vger.kernel.org>
Subject: [RFC PATCH v2 07/15] bpf tools: Convert arglist to bpf prologue
Date: Sun, 24 May 2015 08:28:03 +0000 [thread overview]
Message-ID: <1432456091-73384-8-git-send-email-hekuang@huawei.com> (raw)
In-Reply-To: <1432456091-73384-1-git-send-email-hekuang@huawei.com>
When all arguments in bpf config section are collected in register and
offset form, this patch will fetch them from bpf context register and
place them as bpf input parameters.
By bpf calling convention, we restrict the max fetched arg number to 4.
Bpf prologue is generated as the following steps:
1. alloc dst address in stack -> r1
2. set size -> r2
3. fetch base register and offset -> r3
4. call BPF_FUNC_probe_read
5. loop 1
6. save intermediate result and process next arg
7. restore intermediate result to arg2~5
Signed-off-by: He Kuang <hekuang@huawei.com>
---
tools/lib/bpf/Build | 2 +-
tools/lib/bpf/gen_prologue.c | 108 +++++++++++++++++++++++++++++++++++++++++++
tools/lib/bpf/libbpf.h | 10 ++++
3 files changed, 119 insertions(+), 1 deletion(-)
create mode 100644 tools/lib/bpf/gen_prologue.c
diff --git a/tools/lib/bpf/Build b/tools/lib/bpf/Build
index d874975..c910805 100644
--- a/tools/lib/bpf/Build
+++ b/tools/lib/bpf/Build
@@ -1 +1 @@
-libbpf-y := libbpf.o bpf.o
+libbpf-y := libbpf.o bpf.o gen_prologue.o
diff --git a/tools/lib/bpf/gen_prologue.c b/tools/lib/bpf/gen_prologue.c
new file mode 100644
index 0000000..ca8aa1c
--- /dev/null
+++ b/tools/lib/bpf/gen_prologue.c
@@ -0,0 +1,108 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <dwarf-regs.h>
+#include <debug.h>
+
+#include "libbpf.h"
+#include "bpf.h"
+
+#define BPF_REG_SIZE (8)
+
+unsigned int bpf_prologue_arg_deref(int offset, int stack_index, int depth,
+ char *new_prog, bool last)
+{
+ struct bpf_insn tmp_insns[6] = {};
+ struct bpf_insn *insn = tmp_insns;
+ unsigned int size;
+
+ if (!depth) {
+ /* base register */
+ if (offset < 0)
+ return 0;
+
+ /* load ctx to r3 */
+ *insn++ = BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_CTX, offset);
+
+ if (!last) {
+ /* r7 for stack space */
+ *insn++ = BPF_MOV64_REG(BPF_REG_7, BPF_REG_FP);
+ *insn++ = BPF_ALU64_IMM(BPF_ADD, BPF_REG_7,
+ -BPF_REG_SIZE * stack_index);
+ /* clear stack */
+ *insn++ = BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_8,
+ -BPF_REG_SIZE * stack_index);
+ } else {
+ /* store r3 to stack */
+ *insn++ = BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_3,
+ -BPF_REG_SIZE * stack_index);
+ }
+ } else {
+ /* refs */
+ /* r3 += offset */
+ *insn++ = BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, offset);
+
+ /* r2 = size */
+ *insn++ = BPF_ALU64_IMM(BPF_MOV, BPF_REG_2, 0x0008);
+
+ /* r1 = r7 */
+ *insn++ = BPF_MOV64_REG(BPF_REG_1, BPF_REG_7);
+
+ /* call BPF_FUNC_probe_read
+ * r1: ptr to stack
+ * r2: stack size
+ * r3: unsafe ptr
+ */
+ *insn++ = BPF_EMIT_CALL(BPF_FUNC_probe_read);
+
+ if (!last)
+ /* fetch stack intermediate to r3 */
+ *insn++ = BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_FP,
+ -BPF_REG_SIZE * stack_index);
+ }
+
+ size = sizeof(*insn) * (insn - tmp_insns);
+ if (new_prog)
+ memcpy(new_prog, tmp_insns, size);
+
+ return size;
+}
+
+unsigned int bpf_prologue_begin(char *new_prog)
+{
+ struct bpf_insn *new_insn;
+
+ new_insn = (struct bpf_insn *)new_prog;
+
+ if (new_insn) {
+ /* save arg1 to ctx */
+ *new_insn++ = BPF_MOV64_REG(BPF_REG_CTX, BPF_REG_ARG1);
+ /* set r8 to 0 */
+ *new_insn++ = BPF_ALU64_IMM(BPF_MOV, BPF_REG_8, 0);
+ } else
+ new_insn += 2;
+
+ return (char *)new_insn - new_prog;
+}
+
+unsigned int bpf_prologue_end(char *new_prog, int nargs)
+{
+ struct bpf_insn *new_insn;
+ int i;
+
+ new_insn = (struct bpf_insn *)new_prog;
+
+ nargs = min(BPF_PROLOGUE_NRARGS_MAX, nargs);
+ for (i = 0; i < nargs; i++) {
+ /* result in stack, move to r2~r5 */
+ if (new_prog)
+ *new_insn = BPF_LDX_MEM(BPF_DW,
+ BPF_REG_ARG2 + i,
+ BPF_REG_FP,
+ -BPF_REG_SIZE * (i + 1));
+ new_insn++;
+ }
+
+ return (char *)new_insn - new_prog;
+}
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 31ff5d9..cf22a6a 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -63,4 +63,14 @@ struct bpf_map_def {
unsigned int max_entries;
};
+#define BPF_PROLOGUE_NRARGS_MAX (4)
+
+unsigned int bpf_prologue_begin(char *new_prog);
+unsigned int bpf_prologue_end(char *new_prog, int nargs);
+unsigned int bpf_prologue_arg_deref(int offset,
+ int stack_index,
+ int depth,
+ char *new_prog,
+ bool last);
+
#endif
--
1.8.5.2
next prev parent reply other threads:[~2015-05-24 8:30 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-24 8:27 [RFC PATCH v2 00/15] perf bpf: Probing with local variable He Kuang
2015-05-24 8:27 ` [RFC PATCH v2 01/15] perf tools: Add lib/bpf to cscope target list He Kuang
2015-05-24 8:27 ` [RFC PATCH v2 02/15] perf bpf: Support custom vmlinux path He Kuang
2015-05-24 8:27 ` [RFC PATCH v2 03/15] perf bpf: Save pt_regs info from debuginfo He Kuang
2015-05-24 13:31 ` Masami Hiramatsu
2015-05-25 7:38 ` He Kuang
2015-05-24 8:28 ` [RFC PATCH v2 04/15] perf tools: Add functions to get calling regs He Kuang
2015-05-24 8:28 ` [RFC PATCH v2 05/15] perf tools: Add pt_regs offsets and calling regs for x86 He Kuang
2015-05-24 8:28 ` [RFC PATCH v2 06/15] bpf tools: Add headers for generating bpf bytecode He Kuang
2015-05-24 8:28 ` He Kuang [this message]
2015-05-24 8:28 ` [RFC PATCH v2 08/15] bpf tools: Fetch calling regs to bpf arglist He Kuang
2015-05-24 8:28 ` [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo He Kuang
2015-05-24 8:49 ` Masami Hiramatsu
2015-05-25 8:33 ` He Kuang
2015-05-25 12:22 ` Masami Hiramatsu
2015-05-25 12:46 ` Arnaldo Carvalho de Melo
2015-05-25 13:06 ` Masami Hiramatsu
2015-05-26 17:50 ` Alexei Starovoitov
2015-05-27 2:27 ` He Kuang
2015-05-27 11:43 ` Masami Hiramatsu
2015-05-27 15:30 ` Alexei Starovoitov
2015-05-28 13:01 ` He Kuang
2015-05-28 18:10 ` Alexei Starovoitov
2015-05-29 6:30 ` He Kuang
2015-05-29 23:55 ` Masami Hiramatsu
2015-05-30 1:27 ` Alexei Starovoitov
2015-05-30 7:01 ` Masami Hiramatsu
2015-05-24 8:28 ` [RFC PATCH v2 10/15] perf bpf: Process debuginfo for generating bpf prologue He Kuang
2015-05-24 8:28 ` [RFC PATCH v2 11/15] perf bpf: Synthesize vars to generate " He Kuang
2015-05-24 8:28 ` [RFC PATCH v2 12/15] perf bpf: Generate bpf prologue without debuginfo He Kuang
2015-05-24 8:28 ` [RFC PATCH v2 13/15] perf bpf: Combine bpf prologue and bpf prog He Kuang
2015-05-24 8:28 ` [RFC PATCH v2 14/15] samples/bpf: Add sample for testing bpf fetch args He Kuang
2015-05-24 8:28 ` [RFC PATCH v2 15/15] samples/bpf: Add sample for no-debuginfo case He Kuang
2015-05-26 17:53 ` Alexei Starovoitov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1432456091-73384-8-git-send-email-hekuang@huawei.com \
--to=hekuang@huawei.com \
--cc=a.p.zijlstra@chello.nl \
--cc=acme@kernel.org \
--cc=ast@plumgrid.com \
--cc=brendan.d.gregg@gmail.com \
--cc=daniel@iogearbox.net \
--cc=dsahern@gmail.com \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lizefan@huawei.com \
--cc=masami.hiramatsu.pt@hitachi.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=paulus@samba.org \
--cc=wangnan0@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®