aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZi Shen Lim <zlim.lnx@gmail.com>2016-01-14 02:33:22 -0500
committerDavid S. Miller <davem@davemloft.net>2016-01-17 19:15:26 -0500
commit42ff712bc0c3d7cd60d29b319aecd2d2c8cc75d4 (patch)
tree41722ff39391f428b5ee48ce461b32329be4fda4
parentc94ae4f7c5ec6b6fddde1c08809d5e32a963d7f3 (diff)
arm64: bpf: add extra pass to handle faulty codegen
Code generation functions in arch/arm64/kernel/insn.c previously BUG_ON invalid parameters. Following change of that behavior, now we need to handle the error case where AARCH64_BREAK_FAULT is returned. Instead of error-handling on every emit() in JIT, we add a new validation pass at the end of JIT compilation. There's no point in running JITed code at run-time only to trap due to AARCH64_BREAK_FAULT. Instead, we drop this failed JIT compilation and allow the system to gracefully fallback on the BPF interpreter. Signed-off-by: Zi Shen Lim <zlim.lnx@gmail.com> Suggested-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/arm64/net/bpf_jit_comp.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index 7658612d915c..a34420a5df9a 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * BPF JIT compiler for ARM64 2 * BPF JIT compiler for ARM64
3 * 3 *
4 * Copyright (C) 2014-2015 Zi Shen Lim <zlim.lnx@gmail.com> 4 * Copyright (C) 2014-2016 Zi Shen Lim <zlim.lnx@gmail.com>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
@@ -737,6 +737,20 @@ static int build_body(struct jit_ctx *ctx)
737 return 0; 737 return 0;
738} 738}
739 739
740static int validate_code(struct jit_ctx *ctx)
741{
742 int i;
743
744 for (i = 0; i < ctx->idx; i++) {
745 u32 a64_insn = le32_to_cpu(ctx->image[i]);
746
747 if (a64_insn == AARCH64_BREAK_FAULT)
748 return -1;
749 }
750
751 return 0;
752}
753
740static inline void bpf_flush_icache(void *start, void *end) 754static inline void bpf_flush_icache(void *start, void *end)
741{ 755{
742 flush_icache_range((unsigned long)start, (unsigned long)end); 756 flush_icache_range((unsigned long)start, (unsigned long)end);
@@ -799,6 +813,12 @@ void bpf_int_jit_compile(struct bpf_prog *prog)
799 813
800 build_epilogue(&ctx); 814 build_epilogue(&ctx);
801 815
816 /* 3. Extra pass to validate JITed code. */
817 if (validate_code(&ctx)) {
818 bpf_jit_binary_free(header);
819 goto out;
820 }
821
802 /* And we're done. */ 822 /* And we're done. */
803 if (bpf_jit_enable > 1) 823 if (bpf_jit_enable > 1)
804 bpf_jit_dump(prog->len, image_size, 2, ctx.image); 824 bpf_jit_dump(prog->len, image_size, 2, ctx.image);