diff options
Diffstat (limited to 'arch/arm/net')
-rw-r--r-- | arch/arm/net/bpf_jit_32.c | 29 | ||||
-rw-r--r-- | arch/arm/net/bpf_jit_32.h | 2 |
2 files changed, 26 insertions, 5 deletions
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index b6f305e3b908..a34f1e214116 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/netdevice.h> | 16 | #include <linux/netdevice.h> |
17 | #include <linux/string.h> | 17 | #include <linux/string.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/if_vlan.h> | ||
19 | #include <asm/cacheflush.h> | 20 | #include <asm/cacheflush.h> |
20 | #include <asm/hwcap.h> | 21 | #include <asm/hwcap.h> |
21 | 22 | ||
@@ -168,6 +169,8 @@ static inline bool is_load_to_a(u16 inst) | |||
168 | case BPF_S_ANC_MARK: | 169 | case BPF_S_ANC_MARK: |
169 | case BPF_S_ANC_PROTOCOL: | 170 | case BPF_S_ANC_PROTOCOL: |
170 | case BPF_S_ANC_RXHASH: | 171 | case BPF_S_ANC_RXHASH: |
172 | case BPF_S_ANC_VLAN_TAG: | ||
173 | case BPF_S_ANC_VLAN_TAG_PRESENT: | ||
171 | case BPF_S_ANC_QUEUE: | 174 | case BPF_S_ANC_QUEUE: |
172 | return true; | 175 | return true; |
173 | default: | 176 | default: |
@@ -646,6 +649,16 @@ load_ind: | |||
646 | update_on_xread(ctx); | 649 | update_on_xread(ctx); |
647 | emit(ARM_ORR_R(r_A, r_A, r_X), ctx); | 650 | emit(ARM_ORR_R(r_A, r_A, r_X), ctx); |
648 | break; | 651 | break; |
652 | case BPF_S_ALU_XOR_K: | ||
653 | /* A ^= K; */ | ||
654 | OP_IMM3(ARM_EOR, r_A, r_A, k, ctx); | ||
655 | break; | ||
656 | case BPF_S_ANC_ALU_XOR_X: | ||
657 | case BPF_S_ALU_XOR_X: | ||
658 | /* A ^= X */ | ||
659 | update_on_xread(ctx); | ||
660 | emit(ARM_EOR_R(r_A, r_A, r_X), ctx); | ||
661 | break; | ||
649 | case BPF_S_ALU_AND_K: | 662 | case BPF_S_ALU_AND_K: |
650 | /* A &= K */ | 663 | /* A &= K */ |
651 | OP_IMM3(ARM_AND, r_A, r_A, k, ctx); | 664 | OP_IMM3(ARM_AND, r_A, r_A, k, ctx); |
@@ -762,11 +775,6 @@ b_epilogue: | |||
762 | update_on_xread(ctx); | 775 | update_on_xread(ctx); |
763 | emit(ARM_MOV_R(r_A, r_X), ctx); | 776 | emit(ARM_MOV_R(r_A, r_X), ctx); |
764 | break; | 777 | break; |
765 | case BPF_S_ANC_ALU_XOR_X: | ||
766 | /* A ^= X */ | ||
767 | update_on_xread(ctx); | ||
768 | emit(ARM_EOR_R(r_A, r_A, r_X), ctx); | ||
769 | break; | ||
770 | case BPF_S_ANC_PROTOCOL: | 778 | case BPF_S_ANC_PROTOCOL: |
771 | /* A = ntohs(skb->protocol) */ | 779 | /* A = ntohs(skb->protocol) */ |
772 | ctx->seen |= SEEN_SKB; | 780 | ctx->seen |= SEEN_SKB; |
@@ -810,6 +818,17 @@ b_epilogue: | |||
810 | off = offsetof(struct sk_buff, rxhash); | 818 | off = offsetof(struct sk_buff, rxhash); |
811 | emit(ARM_LDR_I(r_A, r_skb, off), ctx); | 819 | emit(ARM_LDR_I(r_A, r_skb, off), ctx); |
812 | break; | 820 | break; |
821 | case BPF_S_ANC_VLAN_TAG: | ||
822 | case BPF_S_ANC_VLAN_TAG_PRESENT: | ||
823 | ctx->seen |= SEEN_SKB; | ||
824 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_tci) != 2); | ||
825 | off = offsetof(struct sk_buff, vlan_tci); | ||
826 | emit(ARM_LDRH_I(r_A, r_skb, off), ctx); | ||
827 | if (inst->code == BPF_S_ANC_VLAN_TAG) | ||
828 | OP_IMM3(ARM_AND, r_A, r_A, VLAN_VID_MASK, ctx); | ||
829 | else | ||
830 | OP_IMM3(ARM_AND, r_A, r_A, VLAN_TAG_PRESENT, ctx); | ||
831 | break; | ||
813 | case BPF_S_ANC_QUEUE: | 832 | case BPF_S_ANC_QUEUE: |
814 | ctx->seen |= SEEN_SKB; | 833 | ctx->seen |= SEEN_SKB; |
815 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, | 834 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, |
diff --git a/arch/arm/net/bpf_jit_32.h b/arch/arm/net/bpf_jit_32.h index 7fa2f7d3cb90..afb84621ff6f 100644 --- a/arch/arm/net/bpf_jit_32.h +++ b/arch/arm/net/bpf_jit_32.h | |||
@@ -69,6 +69,7 @@ | |||
69 | #define ARM_INST_CMP_I 0x03500000 | 69 | #define ARM_INST_CMP_I 0x03500000 |
70 | 70 | ||
71 | #define ARM_INST_EOR_R 0x00200000 | 71 | #define ARM_INST_EOR_R 0x00200000 |
72 | #define ARM_INST_EOR_I 0x02200000 | ||
72 | 73 | ||
73 | #define ARM_INST_LDRB_I 0x05d00000 | 74 | #define ARM_INST_LDRB_I 0x05d00000 |
74 | #define ARM_INST_LDRB_R 0x07d00000 | 75 | #define ARM_INST_LDRB_R 0x07d00000 |
@@ -135,6 +136,7 @@ | |||
135 | #define ARM_CMP_I(rn, imm) _AL3_I(ARM_INST_CMP, 0, rn, imm) | 136 | #define ARM_CMP_I(rn, imm) _AL3_I(ARM_INST_CMP, 0, rn, imm) |
136 | 137 | ||
137 | #define ARM_EOR_R(rd, rn, rm) _AL3_R(ARM_INST_EOR, rd, rn, rm) | 138 | #define ARM_EOR_R(rd, rn, rm) _AL3_R(ARM_INST_EOR, rd, rn, rm) |
139 | #define ARM_EOR_I(rd, rn, imm) _AL3_I(ARM_INST_EOR, rd, rn, imm) | ||
138 | 140 | ||
139 | #define ARM_LDR_I(rt, rn, off) (ARM_INST_LDR_I | (rt) << 12 | (rn) << 16 \ | 141 | #define ARM_LDR_I(rt, rn, off) (ARM_INST_LDR_I | (rt) << 12 | (rn) << 16 \ |
140 | | (off)) | 142 | | (off)) |