diff options
Diffstat (limited to 'arch/mips/net/bpf_jit.c')
-rw-r--r-- | arch/mips/net/bpf_jit.c | 143 |
1 files changed, 69 insertions, 74 deletions
diff --git a/arch/mips/net/bpf_jit.c b/arch/mips/net/bpf_jit.c index a67b9753330b..f7c206404989 100644 --- a/arch/mips/net/bpf_jit.c +++ b/arch/mips/net/bpf_jit.c | |||
@@ -556,18 +556,10 @@ static inline void update_on_xread(struct jit_ctx *ctx) | |||
556 | static bool is_load_to_a(u16 inst) | 556 | static bool is_load_to_a(u16 inst) |
557 | { | 557 | { |
558 | switch (inst) { | 558 | switch (inst) { |
559 | case BPF_S_LD_W_LEN: | 559 | case BPF_LD | BPF_W | BPF_LEN: |
560 | case BPF_S_LD_W_ABS: | 560 | case BPF_LD | BPF_W | BPF_ABS: |
561 | case BPF_S_LD_H_ABS: | 561 | case BPF_LD | BPF_H | BPF_ABS: |
562 | case BPF_S_LD_B_ABS: | 562 | case BPF_LD | BPF_B | BPF_ABS: |
563 | case BPF_S_ANC_CPU: | ||
564 | case BPF_S_ANC_IFINDEX: | ||
565 | case BPF_S_ANC_MARK: | ||
566 | case BPF_S_ANC_PROTOCOL: | ||
567 | case BPF_S_ANC_RXHASH: | ||
568 | case BPF_S_ANC_VLAN_TAG: | ||
569 | case BPF_S_ANC_VLAN_TAG_PRESENT: | ||
570 | case BPF_S_ANC_QUEUE: | ||
571 | return true; | 563 | return true; |
572 | default: | 564 | default: |
573 | return false; | 565 | return false; |
@@ -709,7 +701,7 @@ static void build_prologue(struct jit_ctx *ctx) | |||
709 | emit_jit_reg_move(r_X, r_zero, ctx); | 701 | emit_jit_reg_move(r_X, r_zero, ctx); |
710 | 702 | ||
711 | /* Do not leak kernel data to userspace */ | 703 | /* Do not leak kernel data to userspace */ |
712 | if ((first_inst != BPF_S_RET_K) && !(is_load_to_a(first_inst))) | 704 | if ((first_inst != (BPF_RET | BPF_K)) && !(is_load_to_a(first_inst))) |
713 | emit_jit_reg_move(r_A, r_zero, ctx); | 705 | emit_jit_reg_move(r_A, r_zero, ctx); |
714 | } | 706 | } |
715 | 707 | ||
@@ -783,41 +775,44 @@ static int build_body(struct jit_ctx *ctx) | |||
783 | u32 k, b_off __maybe_unused; | 775 | u32 k, b_off __maybe_unused; |
784 | 776 | ||
785 | for (i = 0; i < prog->len; i++) { | 777 | for (i = 0; i < prog->len; i++) { |
778 | u16 code; | ||
779 | |||
786 | inst = &(prog->insns[i]); | 780 | inst = &(prog->insns[i]); |
787 | pr_debug("%s: code->0x%02x, jt->0x%x, jf->0x%x, k->0x%x\n", | 781 | pr_debug("%s: code->0x%02x, jt->0x%x, jf->0x%x, k->0x%x\n", |
788 | __func__, inst->code, inst->jt, inst->jf, inst->k); | 782 | __func__, inst->code, inst->jt, inst->jf, inst->k); |
789 | k = inst->k; | 783 | k = inst->k; |
784 | code = bpf_anc_helper(inst); | ||
790 | 785 | ||
791 | if (ctx->target == NULL) | 786 | if (ctx->target == NULL) |
792 | ctx->offsets[i] = ctx->idx * 4; | 787 | ctx->offsets[i] = ctx->idx * 4; |
793 | 788 | ||
794 | switch (inst->code) { | 789 | switch (code) { |
795 | case BPF_S_LD_IMM: | 790 | case BPF_LD | BPF_IMM: |
796 | /* A <- k ==> li r_A, k */ | 791 | /* A <- k ==> li r_A, k */ |
797 | ctx->flags |= SEEN_A; | 792 | ctx->flags |= SEEN_A; |
798 | emit_load_imm(r_A, k, ctx); | 793 | emit_load_imm(r_A, k, ctx); |
799 | break; | 794 | break; |
800 | case BPF_S_LD_W_LEN: | 795 | case BPF_LD | BPF_W | BPF_LEN: |
801 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4); | 796 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4); |
802 | /* A <- len ==> lw r_A, offset(skb) */ | 797 | /* A <- len ==> lw r_A, offset(skb) */ |
803 | ctx->flags |= SEEN_SKB | SEEN_A; | 798 | ctx->flags |= SEEN_SKB | SEEN_A; |
804 | off = offsetof(struct sk_buff, len); | 799 | off = offsetof(struct sk_buff, len); |
805 | emit_load(r_A, r_skb, off, ctx); | 800 | emit_load(r_A, r_skb, off, ctx); |
806 | break; | 801 | break; |
807 | case BPF_S_LD_MEM: | 802 | case BPF_LD | BPF_MEM: |
808 | /* A <- M[k] ==> lw r_A, offset(M) */ | 803 | /* A <- M[k] ==> lw r_A, offset(M) */ |
809 | ctx->flags |= SEEN_MEM | SEEN_A; | 804 | ctx->flags |= SEEN_MEM | SEEN_A; |
810 | emit_load(r_A, r_M, SCRATCH_OFF(k), ctx); | 805 | emit_load(r_A, r_M, SCRATCH_OFF(k), ctx); |
811 | break; | 806 | break; |
812 | case BPF_S_LD_W_ABS: | 807 | case BPF_LD | BPF_W | BPF_ABS: |
813 | /* A <- P[k:4] */ | 808 | /* A <- P[k:4] */ |
814 | load_order = 2; | 809 | load_order = 2; |
815 | goto load; | 810 | goto load; |
816 | case BPF_S_LD_H_ABS: | 811 | case BPF_LD | BPF_H | BPF_ABS: |
817 | /* A <- P[k:2] */ | 812 | /* A <- P[k:2] */ |
818 | load_order = 1; | 813 | load_order = 1; |
819 | goto load; | 814 | goto load; |
820 | case BPF_S_LD_B_ABS: | 815 | case BPF_LD | BPF_B | BPF_ABS: |
821 | /* A <- P[k:1] */ | 816 | /* A <- P[k:1] */ |
822 | load_order = 0; | 817 | load_order = 0; |
823 | load: | 818 | load: |
@@ -852,15 +847,15 @@ load_common: | |||
852 | emit_b(b_imm(prog->len, ctx), ctx); | 847 | emit_b(b_imm(prog->len, ctx), ctx); |
853 | emit_reg_move(r_ret, r_zero, ctx); | 848 | emit_reg_move(r_ret, r_zero, ctx); |
854 | break; | 849 | break; |
855 | case BPF_S_LD_W_IND: | 850 | case BPF_LD | BPF_W | BPF_IND: |
856 | /* A <- P[X + k:4] */ | 851 | /* A <- P[X + k:4] */ |
857 | load_order = 2; | 852 | load_order = 2; |
858 | goto load_ind; | 853 | goto load_ind; |
859 | case BPF_S_LD_H_IND: | 854 | case BPF_LD | BPF_H | BPF_IND: |
860 | /* A <- P[X + k:2] */ | 855 | /* A <- P[X + k:2] */ |
861 | load_order = 1; | 856 | load_order = 1; |
862 | goto load_ind; | 857 | goto load_ind; |
863 | case BPF_S_LD_B_IND: | 858 | case BPF_LD | BPF_B | BPF_IND: |
864 | /* A <- P[X + k:1] */ | 859 | /* A <- P[X + k:1] */ |
865 | load_order = 0; | 860 | load_order = 0; |
866 | load_ind: | 861 | load_ind: |
@@ -868,23 +863,23 @@ load_ind: | |||
868 | ctx->flags |= SEEN_OFF | SEEN_X; | 863 | ctx->flags |= SEEN_OFF | SEEN_X; |
869 | emit_addiu(r_off, r_X, k, ctx); | 864 | emit_addiu(r_off, r_X, k, ctx); |
870 | goto load_common; | 865 | goto load_common; |
871 | case BPF_S_LDX_IMM: | 866 | case BPF_LDX | BPF_IMM: |
872 | /* X <- k */ | 867 | /* X <- k */ |
873 | ctx->flags |= SEEN_X; | 868 | ctx->flags |= SEEN_X; |
874 | emit_load_imm(r_X, k, ctx); | 869 | emit_load_imm(r_X, k, ctx); |
875 | break; | 870 | break; |
876 | case BPF_S_LDX_MEM: | 871 | case BPF_LDX | BPF_MEM: |
877 | /* X <- M[k] */ | 872 | /* X <- M[k] */ |
878 | ctx->flags |= SEEN_X | SEEN_MEM; | 873 | ctx->flags |= SEEN_X | SEEN_MEM; |
879 | emit_load(r_X, r_M, SCRATCH_OFF(k), ctx); | 874 | emit_load(r_X, r_M, SCRATCH_OFF(k), ctx); |
880 | break; | 875 | break; |
881 | case BPF_S_LDX_W_LEN: | 876 | case BPF_LDX | BPF_W | BPF_LEN: |
882 | /* X <- len */ | 877 | /* X <- len */ |
883 | ctx->flags |= SEEN_X | SEEN_SKB; | 878 | ctx->flags |= SEEN_X | SEEN_SKB; |
884 | off = offsetof(struct sk_buff, len); | 879 | off = offsetof(struct sk_buff, len); |
885 | emit_load(r_X, r_skb, off, ctx); | 880 | emit_load(r_X, r_skb, off, ctx); |
886 | break; | 881 | break; |
887 | case BPF_S_LDX_B_MSH: | 882 | case BPF_LDX | BPF_B | BPF_MSH: |
888 | /* X <- 4 * (P[k:1] & 0xf) */ | 883 | /* X <- 4 * (P[k:1] & 0xf) */ |
889 | ctx->flags |= SEEN_X | SEEN_CALL | SEEN_S0 | SEEN_SKB; | 884 | ctx->flags |= SEEN_X | SEEN_CALL | SEEN_S0 | SEEN_SKB; |
890 | /* Load offset to a1 */ | 885 | /* Load offset to a1 */ |
@@ -917,50 +912,50 @@ load_ind: | |||
917 | emit_b(b_imm(prog->len, ctx), ctx); | 912 | emit_b(b_imm(prog->len, ctx), ctx); |
918 | emit_load_imm(r_ret, 0, ctx); /* delay slot */ | 913 | emit_load_imm(r_ret, 0, ctx); /* delay slot */ |
919 | break; | 914 | break; |
920 | case BPF_S_ST: | 915 | case BPF_ST: |
921 | /* M[k] <- A */ | 916 | /* M[k] <- A */ |
922 | ctx->flags |= SEEN_MEM | SEEN_A; | 917 | ctx->flags |= SEEN_MEM | SEEN_A; |
923 | emit_store(r_A, r_M, SCRATCH_OFF(k), ctx); | 918 | emit_store(r_A, r_M, SCRATCH_OFF(k), ctx); |
924 | break; | 919 | break; |
925 | case BPF_S_STX: | 920 | case BPF_STX: |
926 | /* M[k] <- X */ | 921 | /* M[k] <- X */ |
927 | ctx->flags |= SEEN_MEM | SEEN_X; | 922 | ctx->flags |= SEEN_MEM | SEEN_X; |
928 | emit_store(r_X, r_M, SCRATCH_OFF(k), ctx); | 923 | emit_store(r_X, r_M, SCRATCH_OFF(k), ctx); |
929 | break; | 924 | break; |
930 | case BPF_S_ALU_ADD_K: | 925 | case BPF_ALU | BPF_ADD | BPF_K: |
931 | /* A += K */ | 926 | /* A += K */ |
932 | ctx->flags |= SEEN_A; | 927 | ctx->flags |= SEEN_A; |
933 | emit_addiu(r_A, r_A, k, ctx); | 928 | emit_addiu(r_A, r_A, k, ctx); |
934 | break; | 929 | break; |
935 | case BPF_S_ALU_ADD_X: | 930 | case BPF_ALU | BPF_ADD | BPF_X: |
936 | /* A += X */ | 931 | /* A += X */ |
937 | ctx->flags |= SEEN_A | SEEN_X; | 932 | ctx->flags |= SEEN_A | SEEN_X; |
938 | emit_addu(r_A, r_A, r_X, ctx); | 933 | emit_addu(r_A, r_A, r_X, ctx); |
939 | break; | 934 | break; |
940 | case BPF_S_ALU_SUB_K: | 935 | case BPF_ALU | BPF_SUB | BPF_K: |
941 | /* A -= K */ | 936 | /* A -= K */ |
942 | ctx->flags |= SEEN_A; | 937 | ctx->flags |= SEEN_A; |
943 | emit_addiu(r_A, r_A, -k, ctx); | 938 | emit_addiu(r_A, r_A, -k, ctx); |
944 | break; | 939 | break; |
945 | case BPF_S_ALU_SUB_X: | 940 | case BPF_ALU | BPF_SUB | BPF_X: |
946 | /* A -= X */ | 941 | /* A -= X */ |
947 | ctx->flags |= SEEN_A | SEEN_X; | 942 | ctx->flags |= SEEN_A | SEEN_X; |
948 | emit_subu(r_A, r_A, r_X, ctx); | 943 | emit_subu(r_A, r_A, r_X, ctx); |
949 | break; | 944 | break; |
950 | case BPF_S_ALU_MUL_K: | 945 | case BPF_ALU | BPF_MUL | BPF_K: |
951 | /* A *= K */ | 946 | /* A *= K */ |
952 | /* Load K to scratch register before MUL */ | 947 | /* Load K to scratch register before MUL */ |
953 | ctx->flags |= SEEN_A | SEEN_S0; | 948 | ctx->flags |= SEEN_A | SEEN_S0; |
954 | emit_load_imm(r_s0, k, ctx); | 949 | emit_load_imm(r_s0, k, ctx); |
955 | emit_mul(r_A, r_A, r_s0, ctx); | 950 | emit_mul(r_A, r_A, r_s0, ctx); |
956 | break; | 951 | break; |
957 | case BPF_S_ALU_MUL_X: | 952 | case BPF_ALU | BPF_MUL | BPF_X: |
958 | /* A *= X */ | 953 | /* A *= X */ |
959 | update_on_xread(ctx); | 954 | update_on_xread(ctx); |
960 | ctx->flags |= SEEN_A | SEEN_X; | 955 | ctx->flags |= SEEN_A | SEEN_X; |
961 | emit_mul(r_A, r_A, r_X, ctx); | 956 | emit_mul(r_A, r_A, r_X, ctx); |
962 | break; | 957 | break; |
963 | case BPF_S_ALU_DIV_K: | 958 | case BPF_ALU | BPF_DIV | BPF_K: |
964 | /* A /= k */ | 959 | /* A /= k */ |
965 | if (k == 1) | 960 | if (k == 1) |
966 | break; | 961 | break; |
@@ -973,7 +968,7 @@ load_ind: | |||
973 | emit_load_imm(r_s0, k, ctx); | 968 | emit_load_imm(r_s0, k, ctx); |
974 | emit_div(r_A, r_s0, ctx); | 969 | emit_div(r_A, r_s0, ctx); |
975 | break; | 970 | break; |
976 | case BPF_S_ALU_MOD_K: | 971 | case BPF_ALU | BPF_MOD | BPF_K: |
977 | /* A %= k */ | 972 | /* A %= k */ |
978 | if (k == 1 || optimize_div(&k)) { | 973 | if (k == 1 || optimize_div(&k)) { |
979 | ctx->flags |= SEEN_A; | 974 | ctx->flags |= SEEN_A; |
@@ -984,7 +979,7 @@ load_ind: | |||
984 | emit_mod(r_A, r_s0, ctx); | 979 | emit_mod(r_A, r_s0, ctx); |
985 | } | 980 | } |
986 | break; | 981 | break; |
987 | case BPF_S_ALU_DIV_X: | 982 | case BPF_ALU | BPF_DIV | BPF_X: |
988 | /* A /= X */ | 983 | /* A /= X */ |
989 | update_on_xread(ctx); | 984 | update_on_xread(ctx); |
990 | ctx->flags |= SEEN_X | SEEN_A; | 985 | ctx->flags |= SEEN_X | SEEN_A; |
@@ -994,7 +989,7 @@ load_ind: | |||
994 | emit_load_imm(r_val, 0, ctx); /* delay slot */ | 989 | emit_load_imm(r_val, 0, ctx); /* delay slot */ |
995 | emit_div(r_A, r_X, ctx); | 990 | emit_div(r_A, r_X, ctx); |
996 | break; | 991 | break; |
997 | case BPF_S_ALU_MOD_X: | 992 | case BPF_ALU | BPF_MOD | BPF_X: |
998 | /* A %= X */ | 993 | /* A %= X */ |
999 | update_on_xread(ctx); | 994 | update_on_xread(ctx); |
1000 | ctx->flags |= SEEN_X | SEEN_A; | 995 | ctx->flags |= SEEN_X | SEEN_A; |
@@ -1004,94 +999,94 @@ load_ind: | |||
1004 | emit_load_imm(r_val, 0, ctx); /* delay slot */ | 999 | emit_load_imm(r_val, 0, ctx); /* delay slot */ |
1005 | emit_mod(r_A, r_X, ctx); | 1000 | emit_mod(r_A, r_X, ctx); |
1006 | break; | 1001 | break; |
1007 | case BPF_S_ALU_OR_K: | 1002 | case BPF_ALU | BPF_OR | BPF_K: |
1008 | /* A |= K */ | 1003 | /* A |= K */ |
1009 | ctx->flags |= SEEN_A; | 1004 | ctx->flags |= SEEN_A; |
1010 | emit_ori(r_A, r_A, k, ctx); | 1005 | emit_ori(r_A, r_A, k, ctx); |
1011 | break; | 1006 | break; |
1012 | case BPF_S_ALU_OR_X: | 1007 | case BPF_ALU | BPF_OR | BPF_X: |
1013 | /* A |= X */ | 1008 | /* A |= X */ |
1014 | update_on_xread(ctx); | 1009 | update_on_xread(ctx); |
1015 | ctx->flags |= SEEN_A; | 1010 | ctx->flags |= SEEN_A; |
1016 | emit_ori(r_A, r_A, r_X, ctx); | 1011 | emit_ori(r_A, r_A, r_X, ctx); |
1017 | break; | 1012 | break; |
1018 | case BPF_S_ALU_XOR_K: | 1013 | case BPF_ALU | BPF_XOR | BPF_K: |
1019 | /* A ^= k */ | 1014 | /* A ^= k */ |
1020 | ctx->flags |= SEEN_A; | 1015 | ctx->flags |= SEEN_A; |
1021 | emit_xori(r_A, r_A, k, ctx); | 1016 | emit_xori(r_A, r_A, k, ctx); |
1022 | break; | 1017 | break; |
1023 | case BPF_S_ANC_ALU_XOR_X: | 1018 | case BPF_ANC | SKF_AD_ALU_XOR_X: |
1024 | case BPF_S_ALU_XOR_X: | 1019 | case BPF_ALU | BPF_XOR | BPF_X: |
1025 | /* A ^= X */ | 1020 | /* A ^= X */ |
1026 | update_on_xread(ctx); | 1021 | update_on_xread(ctx); |
1027 | ctx->flags |= SEEN_A; | 1022 | ctx->flags |= SEEN_A; |
1028 | emit_xor(r_A, r_A, r_X, ctx); | 1023 | emit_xor(r_A, r_A, r_X, ctx); |
1029 | break; | 1024 | break; |
1030 | case BPF_S_ALU_AND_K: | 1025 | case BPF_ALU | BPF_AND | BPF_K: |
1031 | /* A &= K */ | 1026 | /* A &= K */ |
1032 | ctx->flags |= SEEN_A; | 1027 | ctx->flags |= SEEN_A; |
1033 | emit_andi(r_A, r_A, k, ctx); | 1028 | emit_andi(r_A, r_A, k, ctx); |
1034 | break; | 1029 | break; |
1035 | case BPF_S_ALU_AND_X: | 1030 | case BPF_ALU | BPF_AND | BPF_X: |
1036 | /* A &= X */ | 1031 | /* A &= X */ |
1037 | update_on_xread(ctx); | 1032 | update_on_xread(ctx); |
1038 | ctx->flags |= SEEN_A | SEEN_X; | 1033 | ctx->flags |= SEEN_A | SEEN_X; |
1039 | emit_and(r_A, r_A, r_X, ctx); | 1034 | emit_and(r_A, r_A, r_X, ctx); |
1040 | break; | 1035 | break; |
1041 | case BPF_S_ALU_LSH_K: | 1036 | case BPF_ALU | BPF_LSH | BPF_K: |
1042 | /* A <<= K */ | 1037 | /* A <<= K */ |
1043 | ctx->flags |= SEEN_A; | 1038 | ctx->flags |= SEEN_A; |
1044 | emit_sll(r_A, r_A, k, ctx); | 1039 | emit_sll(r_A, r_A, k, ctx); |
1045 | break; | 1040 | break; |
1046 | case BPF_S_ALU_LSH_X: | 1041 | case BPF_ALU | BPF_LSH | BPF_X: |
1047 | /* A <<= X */ | 1042 | /* A <<= X */ |
1048 | ctx->flags |= SEEN_A | SEEN_X; | 1043 | ctx->flags |= SEEN_A | SEEN_X; |
1049 | update_on_xread(ctx); | 1044 | update_on_xread(ctx); |
1050 | emit_sllv(r_A, r_A, r_X, ctx); | 1045 | emit_sllv(r_A, r_A, r_X, ctx); |
1051 | break; | 1046 | break; |
1052 | case BPF_S_ALU_RSH_K: | 1047 | case BPF_ALU | BPF_RSH | BPF_K: |
1053 | /* A >>= K */ | 1048 | /* A >>= K */ |
1054 | ctx->flags |= SEEN_A; | 1049 | ctx->flags |= SEEN_A; |
1055 | emit_srl(r_A, r_A, k, ctx); | 1050 | emit_srl(r_A, r_A, k, ctx); |
1056 | break; | 1051 | break; |
1057 | case BPF_S_ALU_RSH_X: | 1052 | case BPF_ALU | BPF_RSH | BPF_X: |
1058 | ctx->flags |= SEEN_A | SEEN_X; | 1053 | ctx->flags |= SEEN_A | SEEN_X; |
1059 | update_on_xread(ctx); | 1054 | update_on_xread(ctx); |
1060 | emit_srlv(r_A, r_A, r_X, ctx); | 1055 | emit_srlv(r_A, r_A, r_X, ctx); |
1061 | break; | 1056 | break; |
1062 | case BPF_S_ALU_NEG: | 1057 | case BPF_ALU | BPF_NEG: |
1063 | /* A = -A */ | 1058 | /* A = -A */ |
1064 | ctx->flags |= SEEN_A; | 1059 | ctx->flags |= SEEN_A; |
1065 | emit_neg(r_A, ctx); | 1060 | emit_neg(r_A, ctx); |
1066 | break; | 1061 | break; |
1067 | case BPF_S_JMP_JA: | 1062 | case BPF_JMP | BPF_JA: |
1068 | /* pc += K */ | 1063 | /* pc += K */ |
1069 | emit_b(b_imm(i + k + 1, ctx), ctx); | 1064 | emit_b(b_imm(i + k + 1, ctx), ctx); |
1070 | emit_nop(ctx); | 1065 | emit_nop(ctx); |
1071 | break; | 1066 | break; |
1072 | case BPF_S_JMP_JEQ_K: | 1067 | case BPF_JMP | BPF_JEQ | BPF_K: |
1073 | /* pc += ( A == K ) ? pc->jt : pc->jf */ | 1068 | /* pc += ( A == K ) ? pc->jt : pc->jf */ |
1074 | condt = MIPS_COND_EQ | MIPS_COND_K; | 1069 | condt = MIPS_COND_EQ | MIPS_COND_K; |
1075 | goto jmp_cmp; | 1070 | goto jmp_cmp; |
1076 | case BPF_S_JMP_JEQ_X: | 1071 | case BPF_JMP | BPF_JEQ | BPF_X: |
1077 | ctx->flags |= SEEN_X; | 1072 | ctx->flags |= SEEN_X; |
1078 | /* pc += ( A == X ) ? pc->jt : pc->jf */ | 1073 | /* pc += ( A == X ) ? pc->jt : pc->jf */ |
1079 | condt = MIPS_COND_EQ | MIPS_COND_X; | 1074 | condt = MIPS_COND_EQ | MIPS_COND_X; |
1080 | goto jmp_cmp; | 1075 | goto jmp_cmp; |
1081 | case BPF_S_JMP_JGE_K: | 1076 | case BPF_JMP | BPF_JGE | BPF_K: |
1082 | /* pc += ( A >= K ) ? pc->jt : pc->jf */ | 1077 | /* pc += ( A >= K ) ? pc->jt : pc->jf */ |
1083 | condt = MIPS_COND_GE | MIPS_COND_K; | 1078 | condt = MIPS_COND_GE | MIPS_COND_K; |
1084 | goto jmp_cmp; | 1079 | goto jmp_cmp; |
1085 | case BPF_S_JMP_JGE_X: | 1080 | case BPF_JMP | BPF_JGE | BPF_X: |
1086 | ctx->flags |= SEEN_X; | 1081 | ctx->flags |= SEEN_X; |
1087 | /* pc += ( A >= X ) ? pc->jt : pc->jf */ | 1082 | /* pc += ( A >= X ) ? pc->jt : pc->jf */ |
1088 | condt = MIPS_COND_GE | MIPS_COND_X; | 1083 | condt = MIPS_COND_GE | MIPS_COND_X; |
1089 | goto jmp_cmp; | 1084 | goto jmp_cmp; |
1090 | case BPF_S_JMP_JGT_K: | 1085 | case BPF_JMP | BPF_JGT | BPF_K: |
1091 | /* pc += ( A > K ) ? pc->jt : pc->jf */ | 1086 | /* pc += ( A > K ) ? pc->jt : pc->jf */ |
1092 | condt = MIPS_COND_GT | MIPS_COND_K; | 1087 | condt = MIPS_COND_GT | MIPS_COND_K; |
1093 | goto jmp_cmp; | 1088 | goto jmp_cmp; |
1094 | case BPF_S_JMP_JGT_X: | 1089 | case BPF_JMP | BPF_JGT | BPF_X: |
1095 | ctx->flags |= SEEN_X; | 1090 | ctx->flags |= SEEN_X; |
1096 | /* pc += ( A > X ) ? pc->jt : pc->jf */ | 1091 | /* pc += ( A > X ) ? pc->jt : pc->jf */ |
1097 | condt = MIPS_COND_GT | MIPS_COND_X; | 1092 | condt = MIPS_COND_GT | MIPS_COND_X; |
@@ -1167,7 +1162,7 @@ jmp_cmp: | |||
1167 | } | 1162 | } |
1168 | } | 1163 | } |
1169 | break; | 1164 | break; |
1170 | case BPF_S_JMP_JSET_K: | 1165 | case BPF_JMP | BPF_JSET | BPF_K: |
1171 | ctx->flags |= SEEN_S0 | SEEN_S1 | SEEN_A; | 1166 | ctx->flags |= SEEN_S0 | SEEN_S1 | SEEN_A; |
1172 | /* pc += (A & K) ? pc -> jt : pc -> jf */ | 1167 | /* pc += (A & K) ? pc -> jt : pc -> jf */ |
1173 | emit_load_imm(r_s1, k, ctx); | 1168 | emit_load_imm(r_s1, k, ctx); |
@@ -1181,7 +1176,7 @@ jmp_cmp: | |||
1181 | emit_b(b_off, ctx); | 1176 | emit_b(b_off, ctx); |
1182 | emit_nop(ctx); | 1177 | emit_nop(ctx); |
1183 | break; | 1178 | break; |
1184 | case BPF_S_JMP_JSET_X: | 1179 | case BPF_JMP | BPF_JSET | BPF_X: |
1185 | ctx->flags |= SEEN_S0 | SEEN_X | SEEN_A; | 1180 | ctx->flags |= SEEN_S0 | SEEN_X | SEEN_A; |
1186 | /* pc += (A & X) ? pc -> jt : pc -> jf */ | 1181 | /* pc += (A & X) ? pc -> jt : pc -> jf */ |
1187 | emit_and(r_s0, r_A, r_X, ctx); | 1182 | emit_and(r_s0, r_A, r_X, ctx); |
@@ -1194,7 +1189,7 @@ jmp_cmp: | |||
1194 | emit_b(b_off, ctx); | 1189 | emit_b(b_off, ctx); |
1195 | emit_nop(ctx); | 1190 | emit_nop(ctx); |
1196 | break; | 1191 | break; |
1197 | case BPF_S_RET_A: | 1192 | case BPF_RET | BPF_A: |
1198 | ctx->flags |= SEEN_A; | 1193 | ctx->flags |= SEEN_A; |
1199 | if (i != prog->len - 1) | 1194 | if (i != prog->len - 1) |
1200 | /* | 1195 | /* |
@@ -1204,7 +1199,7 @@ jmp_cmp: | |||
1204 | emit_b(b_imm(prog->len, ctx), ctx); | 1199 | emit_b(b_imm(prog->len, ctx), ctx); |
1205 | emit_reg_move(r_ret, r_A, ctx); /* delay slot */ | 1200 | emit_reg_move(r_ret, r_A, ctx); /* delay slot */ |
1206 | break; | 1201 | break; |
1207 | case BPF_S_RET_K: | 1202 | case BPF_RET | BPF_K: |
1208 | /* | 1203 | /* |
1209 | * It can emit two instructions so it does not fit on | 1204 | * It can emit two instructions so it does not fit on |
1210 | * the delay slot. | 1205 | * the delay slot. |
@@ -1219,19 +1214,19 @@ jmp_cmp: | |||
1219 | emit_nop(ctx); | 1214 | emit_nop(ctx); |
1220 | } | 1215 | } |
1221 | break; | 1216 | break; |
1222 | case BPF_S_MISC_TAX: | 1217 | case BPF_MISC | BPF_TAX: |
1223 | /* X = A */ | 1218 | /* X = A */ |
1224 | ctx->flags |= SEEN_X | SEEN_A; | 1219 | ctx->flags |= SEEN_X | SEEN_A; |
1225 | emit_jit_reg_move(r_X, r_A, ctx); | 1220 | emit_jit_reg_move(r_X, r_A, ctx); |
1226 | break; | 1221 | break; |
1227 | case BPF_S_MISC_TXA: | 1222 | case BPF_MISC | BPF_TXA: |
1228 | /* A = X */ | 1223 | /* A = X */ |
1229 | ctx->flags |= SEEN_A | SEEN_X; | 1224 | ctx->flags |= SEEN_A | SEEN_X; |
1230 | update_on_xread(ctx); | 1225 | update_on_xread(ctx); |
1231 | emit_jit_reg_move(r_A, r_X, ctx); | 1226 | emit_jit_reg_move(r_A, r_X, ctx); |
1232 | break; | 1227 | break; |
1233 | /* AUX */ | 1228 | /* AUX */ |
1234 | case BPF_S_ANC_PROTOCOL: | 1229 | case BPF_ANC | SKF_AD_PROTOCOL: |
1235 | /* A = ntohs(skb->protocol */ | 1230 | /* A = ntohs(skb->protocol */ |
1236 | ctx->flags |= SEEN_SKB | SEEN_OFF | SEEN_A; | 1231 | ctx->flags |= SEEN_SKB | SEEN_OFF | SEEN_A; |
1237 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, | 1232 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, |
@@ -1256,7 +1251,7 @@ jmp_cmp: | |||
1256 | } | 1251 | } |
1257 | #endif | 1252 | #endif |
1258 | break; | 1253 | break; |
1259 | case BPF_S_ANC_CPU: | 1254 | case BPF_ANC | SKF_AD_CPU: |
1260 | ctx->flags |= SEEN_A | SEEN_OFF; | 1255 | ctx->flags |= SEEN_A | SEEN_OFF; |
1261 | /* A = current_thread_info()->cpu */ | 1256 | /* A = current_thread_info()->cpu */ |
1262 | BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, | 1257 | BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, |
@@ -1265,7 +1260,7 @@ jmp_cmp: | |||
1265 | /* $28/gp points to the thread_info struct */ | 1260 | /* $28/gp points to the thread_info struct */ |
1266 | emit_load(r_A, 28, off, ctx); | 1261 | emit_load(r_A, 28, off, ctx); |
1267 | break; | 1262 | break; |
1268 | case BPF_S_ANC_IFINDEX: | 1263 | case BPF_ANC | SKF_AD_IFINDEX: |
1269 | /* A = skb->dev->ifindex */ | 1264 | /* A = skb->dev->ifindex */ |
1270 | ctx->flags |= SEEN_SKB | SEEN_A | SEEN_S0; | 1265 | ctx->flags |= SEEN_SKB | SEEN_A | SEEN_S0; |
1271 | off = offsetof(struct sk_buff, dev); | 1266 | off = offsetof(struct sk_buff, dev); |
@@ -1279,31 +1274,31 @@ jmp_cmp: | |||
1279 | off = offsetof(struct net_device, ifindex); | 1274 | off = offsetof(struct net_device, ifindex); |
1280 | emit_load(r_A, r_s0, off, ctx); | 1275 | emit_load(r_A, r_s0, off, ctx); |
1281 | break; | 1276 | break; |
1282 | case BPF_S_ANC_MARK: | 1277 | case BPF_ANC | SKF_AD_MARK: |
1283 | ctx->flags |= SEEN_SKB | SEEN_A; | 1278 | ctx->flags |= SEEN_SKB | SEEN_A; |
1284 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4); | 1279 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4); |
1285 | off = offsetof(struct sk_buff, mark); | 1280 | off = offsetof(struct sk_buff, mark); |
1286 | emit_load(r_A, r_skb, off, ctx); | 1281 | emit_load(r_A, r_skb, off, ctx); |
1287 | break; | 1282 | break; |
1288 | case BPF_S_ANC_RXHASH: | 1283 | case BPF_ANC | SKF_AD_RXHASH: |
1289 | ctx->flags |= SEEN_SKB | SEEN_A; | 1284 | ctx->flags |= SEEN_SKB | SEEN_A; |
1290 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4); | 1285 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4); |
1291 | off = offsetof(struct sk_buff, hash); | 1286 | off = offsetof(struct sk_buff, hash); |
1292 | emit_load(r_A, r_skb, off, ctx); | 1287 | emit_load(r_A, r_skb, off, ctx); |
1293 | break; | 1288 | break; |
1294 | case BPF_S_ANC_VLAN_TAG: | 1289 | case BPF_ANC | SKF_AD_VLAN_TAG: |
1295 | case BPF_S_ANC_VLAN_TAG_PRESENT: | 1290 | case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT: |
1296 | ctx->flags |= SEEN_SKB | SEEN_S0 | SEEN_A; | 1291 | ctx->flags |= SEEN_SKB | SEEN_S0 | SEEN_A; |
1297 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, | 1292 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, |
1298 | vlan_tci) != 2); | 1293 | vlan_tci) != 2); |
1299 | off = offsetof(struct sk_buff, vlan_tci); | 1294 | off = offsetof(struct sk_buff, vlan_tci); |
1300 | emit_half_load(r_s0, r_skb, off, ctx); | 1295 | emit_half_load(r_s0, r_skb, off, ctx); |
1301 | if (inst->code == BPF_S_ANC_VLAN_TAG) | 1296 | if (code == (BPF_ANC | SKF_AD_VLAN_TAG)) |
1302 | emit_and(r_A, r_s0, VLAN_VID_MASK, ctx); | 1297 | emit_and(r_A, r_s0, VLAN_VID_MASK, ctx); |
1303 | else | 1298 | else |
1304 | emit_and(r_A, r_s0, VLAN_TAG_PRESENT, ctx); | 1299 | emit_and(r_A, r_s0, VLAN_TAG_PRESENT, ctx); |
1305 | break; | 1300 | break; |
1306 | case BPF_S_ANC_PKTTYPE: | 1301 | case BPF_ANC | SKF_AD_PKTTYPE: |
1307 | off = pkt_type_offset(); | 1302 | off = pkt_type_offset(); |
1308 | 1303 | ||
1309 | if (off < 0) | 1304 | if (off < 0) |
@@ -1312,7 +1307,7 @@ jmp_cmp: | |||
1312 | /* Keep only the last 3 bits */ | 1307 | /* Keep only the last 3 bits */ |
1313 | emit_andi(r_A, r_tmp, PKT_TYPE_MAX, ctx); | 1308 | emit_andi(r_A, r_tmp, PKT_TYPE_MAX, ctx); |
1314 | break; | 1309 | break; |
1315 | case BPF_S_ANC_QUEUE: | 1310 | case BPF_ANC | SKF_AD_QUEUE: |
1316 | ctx->flags |= SEEN_SKB | SEEN_A; | 1311 | ctx->flags |= SEEN_SKB | SEEN_A; |
1317 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, | 1312 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, |
1318 | queue_mapping) != 2); | 1313 | queue_mapping) != 2); |