diff options
Diffstat (limited to 'arch/arm64/net/bpf_jit_comp.c')
-rw-r--r-- | arch/arm64/net/bpf_jit_comp.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index b162ad70effc..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 |
@@ -152,8 +152,6 @@ static void build_prologue(struct jit_ctx *ctx) | |||
152 | const u8 r8 = bpf2a64[BPF_REG_8]; | 152 | const u8 r8 = bpf2a64[BPF_REG_8]; |
153 | const u8 r9 = bpf2a64[BPF_REG_9]; | 153 | const u8 r9 = bpf2a64[BPF_REG_9]; |
154 | const u8 fp = bpf2a64[BPF_REG_FP]; | 154 | const u8 fp = bpf2a64[BPF_REG_FP]; |
155 | const u8 ra = bpf2a64[BPF_REG_A]; | ||
156 | const u8 rx = bpf2a64[BPF_REG_X]; | ||
157 | const u8 tmp1 = bpf2a64[TMP_REG_1]; | 155 | const u8 tmp1 = bpf2a64[TMP_REG_1]; |
158 | const u8 tmp2 = bpf2a64[TMP_REG_2]; | 156 | const u8 tmp2 = bpf2a64[TMP_REG_2]; |
159 | 157 | ||
@@ -200,10 +198,6 @@ static void build_prologue(struct jit_ctx *ctx) | |||
200 | 198 | ||
201 | /* Set up function call stack */ | 199 | /* Set up function call stack */ |
202 | emit(A64_SUB_I(1, A64_SP, A64_SP, STACK_SIZE), ctx); | 200 | emit(A64_SUB_I(1, A64_SP, A64_SP, STACK_SIZE), ctx); |
203 | |||
204 | /* Clear registers A and X */ | ||
205 | emit_a64_mov_i64(ra, 0, ctx); | ||
206 | emit_a64_mov_i64(rx, 0, ctx); | ||
207 | } | 201 | } |
208 | 202 | ||
209 | static void build_epilogue(struct jit_ctx *ctx) | 203 | static void build_epilogue(struct jit_ctx *ctx) |
@@ -743,6 +737,20 @@ static int build_body(struct jit_ctx *ctx) | |||
743 | return 0; | 737 | return 0; |
744 | } | 738 | } |
745 | 739 | ||
740 | static 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 | |||
746 | static inline void bpf_flush_icache(void *start, void *end) | 754 | static inline void bpf_flush_icache(void *start, void *end) |
747 | { | 755 | { |
748 | flush_icache_range((unsigned long)start, (unsigned long)end); | 756 | flush_icache_range((unsigned long)start, (unsigned long)end); |
@@ -805,6 +813,12 @@ void bpf_int_jit_compile(struct bpf_prog *prog) | |||
805 | 813 | ||
806 | build_epilogue(&ctx); | 814 | build_epilogue(&ctx); |
807 | 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 | |||
808 | /* And we're done. */ | 822 | /* And we're done. */ |
809 | if (bpf_jit_enable > 1) | 823 | if (bpf_jit_enable > 1) |
810 | bpf_jit_dump(prog->len, image_size, 2, ctx.image); | 824 | bpf_jit_dump(prog->len, image_size, 2, ctx.image); |