From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752527AbcFZL3Q (ORCPT ); Sun, 26 Jun 2016 07:29:16 -0400 Received: from szxga04-in.huawei.com ([58.251.152.52]:19914 "EHLO szxga04-in.huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1752164AbcFZLVz (ORCPT ); Sun, 26 Jun 2016 07:21:55 -0400 From: He Kuang To: , , , , , , , , CC: Subject: [RFC PATCH v2 04/26] bpf: extract jmp and default handler and introduce UBPF_BUILD flag Date: Sun, 26 Jun 2016 11:20:56 +0000 Message-ID: <1466940078-65581-5-git-send-email-hekuang@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1466940078-65581-1-git-send-email-hekuang@huawei.com> References: <1466940078-65581-1-git-send-email-hekuang@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.107.193.250] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A090203.576FBAC1.0064,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 10ac33602ad5a0babc023efcc10517e9 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch is a preparation for compiling bpf vm into external libraries. Parts of the instruction handlers are wrapped into macros or functions so that userspace libraries can override them. There's no functionality change without UBPF_BUILD flag. Signed-off-by: He Kuang Signed-off-by: Wang Nan --- kernel/bpf/vm.c | 94 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 38 deletions(-) diff --git a/kernel/bpf/vm.c b/kernel/bpf/vm.c index 45a2880..add5669 100644 --- a/kernel/bpf/vm.c +++ b/kernel/bpf/vm.c @@ -1,8 +1,6 @@ #include #include -#include #include -#include #include #include #include @@ -11,6 +9,11 @@ #include #include +#ifndef UBPF_BUILD +#include +#include +#endif + /* Registers */ #define BPF_R0 regs[BPF_REG_0] #define BPF_R1 regs[BPF_REG_1] @@ -32,6 +35,49 @@ #define CTX regs[BPF_REG_CTX] #define IMM insn->imm +#ifndef UBPF_BUILD +/* Function call scratches BPF_R1-BPF_R5 registers, + * preserves BPF_R6-BPF_R9, and stores return value + * into BPF_R0. + */ +#define bpf_vm_jmp_call_handler(regs, ctx, insn) \ + (BPF_R0 = (__bpf_call_base + insn->imm)(BPF_R1, BPF_R2, BPF_R3, \ + BPF_R4, BPF_R5)) + +/* If we ever reach this, we have a bug somewhere. */ +#define bpf_vm_default_label_handler(ctx, insn) \ + WARN_RATELIMIT(1, "unknown opcode %02x\n", insn->code) + +static inline int bpf_vm_jmp_tail_call_handler(u64 *regs, u32 *p_tail_call_cnt, + const struct bpf_insn **p_insn) +{ + struct bpf_map *map = (struct bpf_map *) (unsigned long) BPF_R2; + struct bpf_array *array = container_of(map, struct bpf_array, map); + struct bpf_prog *prog; + u64 index = BPF_R3; + + if (unlikely(index >= array->map.max_entries)) + return -1; + + if (unlikely(*p_tail_call_cnt > MAX_TAIL_CALL_CNT)) + return -1; + + (*p_tail_call_cnt)++; + + prog = READ_ONCE(array->ptrs[index]); + if (unlikely(!prog)) + return -1; + + /* ARG1 at this point is guaranteed to point to CTX from + * the verifier side due to the fact that the tail call is + * handeled like a helper, that is, bpf_tail_call_proto, + * where arg1_type is ARG_PTR_TO_CTX. + */ + *p_insn = prog->insnsi; + return 0; +} +#endif /* UBPF_BUILD */ + unsigned int __bpf_prog_run(void *ctx, const struct bpf_insn *insn) { u64 stack[MAX_BPF_STACK / sizeof(u64)]; @@ -270,42 +316,15 @@ select_insn: /* CALL */ JMP_CALL: - /* Function call scratches BPF_R1-BPF_R5 registers, - * preserves BPF_R6-BPF_R9, and stores return value - * into BPF_R0. - */ - BPF_R0 = (__bpf_call_base + insn->imm)(BPF_R1, BPF_R2, BPF_R3, - BPF_R4, BPF_R5); + bpf_vm_jmp_call_handler(regs, ctx, insn); CONT; - JMP_TAIL_CALL: { - struct bpf_map *map = (struct bpf_map *) (unsigned long) BPF_R2; - struct bpf_array *array = container_of(map, struct bpf_array, map); - struct bpf_prog *prog; - u64 index = BPF_R3; - - if (unlikely(index >= array->map.max_entries)) - goto out; - - if (unlikely(tail_call_cnt > MAX_TAIL_CALL_CNT)) - goto out; - - tail_call_cnt++; - - prog = READ_ONCE(array->ptrs[index]); - if (unlikely(!prog)) - goto out; - - /* ARG1 at this point is guaranteed to point to CTX from - * the verifier side due to the fact that the tail call is - * handeled like a helper, that is, bpf_tail_call_proto, - * where arg1_type is ARG_PTR_TO_CTX. - */ - insn = prog->insnsi; - goto select_insn; -out: - CONT; - } + JMP_TAIL_CALL: + tmp = bpf_vm_jmp_tail_call_handler(regs, &tail_call_cnt, &insn); + if (tmp) + CONT; + else + goto select_insn; /* JMP */ JMP_JA: insn += insn->off; @@ -485,8 +504,7 @@ load_byte: goto load_byte; default_label: - /* If we ever reach this, we have a bug somewhere. */ - WARN_RATELIMIT(1, "unknown opcode %02x\n", insn->code); + bpf_vm_default_label_handler(ctx, insn); return 0; } STACK_FRAME_NON_STANDARD(__bpf_prog_run); /* jump table */ -- 1.8.5.2