diff options
-rw-r--r-- | arch/arm64/net/bpf_jit_comp.c | 52 |
1 files changed, 40 insertions, 12 deletions
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index dd428807cb30..d0d51903c7e0 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c | |||
@@ -31,8 +31,8 @@ | |||
31 | 31 | ||
32 | int bpf_jit_enable __read_mostly; | 32 | int bpf_jit_enable __read_mostly; |
33 | 33 | ||
34 | #define TMP_REG_1 (MAX_BPF_REG + 0) | 34 | #define TMP_REG_1 (MAX_BPF_JIT_REG + 0) |
35 | #define TMP_REG_2 (MAX_BPF_REG + 1) | 35 | #define TMP_REG_2 (MAX_BPF_JIT_REG + 1) |
36 | 36 | ||
37 | /* Map BPF registers to A64 registers */ | 37 | /* Map BPF registers to A64 registers */ |
38 | static const int bpf2a64[] = { | 38 | static const int bpf2a64[] = { |
@@ -54,6 +54,8 @@ static const int bpf2a64[] = { | |||
54 | /* temporary register for internal BPF JIT */ | 54 | /* temporary register for internal BPF JIT */ |
55 | [TMP_REG_1] = A64_R(23), | 55 | [TMP_REG_1] = A64_R(23), |
56 | [TMP_REG_2] = A64_R(24), | 56 | [TMP_REG_2] = A64_R(24), |
57 | /* temporary register for blinding constants */ | ||
58 | [BPF_REG_AX] = A64_R(9), | ||
57 | }; | 59 | }; |
58 | 60 | ||
59 | struct jit_ctx { | 61 | struct jit_ctx { |
@@ -764,26 +766,43 @@ void bpf_jit_compile(struct bpf_prog *prog) | |||
764 | 766 | ||
765 | struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) | 767 | struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) |
766 | { | 768 | { |
769 | struct bpf_prog *tmp, *orig_prog = prog; | ||
767 | struct bpf_binary_header *header; | 770 | struct bpf_binary_header *header; |
771 | bool tmp_blinded = false; | ||
768 | struct jit_ctx ctx; | 772 | struct jit_ctx ctx; |
769 | int image_size; | 773 | int image_size; |
770 | u8 *image_ptr; | 774 | u8 *image_ptr; |
771 | 775 | ||
772 | if (!bpf_jit_enable) | 776 | if (!bpf_jit_enable) |
773 | return prog; | 777 | return orig_prog; |
778 | |||
779 | tmp = bpf_jit_blind_constants(prog); | ||
780 | /* If blinding was requested and we failed during blinding, | ||
781 | * we must fall back to the interpreter. | ||
782 | */ | ||
783 | if (IS_ERR(tmp)) | ||
784 | return orig_prog; | ||
785 | if (tmp != prog) { | ||
786 | tmp_blinded = true; | ||
787 | prog = tmp; | ||
788 | } | ||
774 | 789 | ||
775 | memset(&ctx, 0, sizeof(ctx)); | 790 | memset(&ctx, 0, sizeof(ctx)); |
776 | ctx.prog = prog; | 791 | ctx.prog = prog; |
777 | 792 | ||
778 | ctx.offset = kcalloc(prog->len, sizeof(int), GFP_KERNEL); | 793 | ctx.offset = kcalloc(prog->len, sizeof(int), GFP_KERNEL); |
779 | if (ctx.offset == NULL) | 794 | if (ctx.offset == NULL) { |
780 | return prog; | 795 | prog = orig_prog; |
796 | goto out; | ||
797 | } | ||
781 | 798 | ||
782 | /* 1. Initial fake pass to compute ctx->idx. */ | 799 | /* 1. Initial fake pass to compute ctx->idx. */ |
783 | 800 | ||
784 | /* Fake pass to fill in ctx->offset and ctx->tmp_used. */ | 801 | /* Fake pass to fill in ctx->offset and ctx->tmp_used. */ |
785 | if (build_body(&ctx)) | 802 | if (build_body(&ctx)) { |
786 | goto out; | 803 | prog = orig_prog; |
804 | goto out_off; | ||
805 | } | ||
787 | 806 | ||
788 | build_prologue(&ctx); | 807 | build_prologue(&ctx); |
789 | 808 | ||
@@ -794,8 +813,10 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) | |||
794 | image_size = sizeof(u32) * ctx.idx; | 813 | image_size = sizeof(u32) * ctx.idx; |
795 | header = bpf_jit_binary_alloc(image_size, &image_ptr, | 814 | header = bpf_jit_binary_alloc(image_size, &image_ptr, |
796 | sizeof(u32), jit_fill_hole); | 815 | sizeof(u32), jit_fill_hole); |
797 | if (header == NULL) | 816 | if (header == NULL) { |
798 | goto out; | 817 | prog = orig_prog; |
818 | goto out_off; | ||
819 | } | ||
799 | 820 | ||
800 | /* 2. Now, the actual pass. */ | 821 | /* 2. Now, the actual pass. */ |
801 | 822 | ||
@@ -806,7 +827,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) | |||
806 | 827 | ||
807 | if (build_body(&ctx)) { | 828 | if (build_body(&ctx)) { |
808 | bpf_jit_binary_free(header); | 829 | bpf_jit_binary_free(header); |
809 | goto out; | 830 | prog = orig_prog; |
831 | goto out_off; | ||
810 | } | 832 | } |
811 | 833 | ||
812 | build_epilogue(&ctx); | 834 | build_epilogue(&ctx); |
@@ -814,7 +836,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) | |||
814 | /* 3. Extra pass to validate JITed code. */ | 836 | /* 3. Extra pass to validate JITed code. */ |
815 | if (validate_code(&ctx)) { | 837 | if (validate_code(&ctx)) { |
816 | bpf_jit_binary_free(header); | 838 | bpf_jit_binary_free(header); |
817 | goto out; | 839 | prog = orig_prog; |
840 | goto out_off; | ||
818 | } | 841 | } |
819 | 842 | ||
820 | /* And we're done. */ | 843 | /* And we're done. */ |
@@ -826,8 +849,13 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) | |||
826 | set_memory_ro((unsigned long)header, header->pages); | 849 | set_memory_ro((unsigned long)header, header->pages); |
827 | prog->bpf_func = (void *)ctx.image; | 850 | prog->bpf_func = (void *)ctx.image; |
828 | prog->jited = 1; | 851 | prog->jited = 1; |
829 | out: | 852 | |
853 | out_off: | ||
830 | kfree(ctx.offset); | 854 | kfree(ctx.offset); |
855 | out: | ||
856 | if (tmp_blinded) | ||
857 | bpf_jit_prog_release_other(prog, prog == orig_prog ? | ||
858 | tmp : orig_prog); | ||
831 | return prog; | 859 | return prog; |
832 | } | 860 | } |
833 | 861 | ||