aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/net/bpf_jit_32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/net/bpf_jit_32.c')
-rw-r--r--arch/arm/net/bpf_jit_32.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
index c641fb685017..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
@@ -42,7 +43,7 @@
42#define r_skb_hl ARM_R8 43#define r_skb_hl ARM_R8
43 44
44#define SCRATCH_SP_OFFSET 0 45#define SCRATCH_SP_OFFSET 0
45#define SCRATCH_OFF(k) (SCRATCH_SP_OFFSET + (k)) 46#define SCRATCH_OFF(k) (SCRATCH_SP_OFFSET + 4 * (k))
46 47
47#define SEEN_MEM ((1 << BPF_MEMWORDS) - 1) 48#define SEEN_MEM ((1 << BPF_MEMWORDS) - 1)
48#define SEEN_MEM_WORD(k) (1 << (k)) 49#define SEEN_MEM_WORD(k) (1 << (k))
@@ -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,
@@ -845,7 +864,7 @@ void bpf_jit_compile(struct sk_filter *fp)
845 ctx.skf = fp; 864 ctx.skf = fp;
846 ctx.ret0_fp_idx = -1; 865 ctx.ret0_fp_idx = -1;
847 866
848 ctx.offsets = kzalloc(GFP_KERNEL, 4 * (ctx.skf->len + 1)); 867 ctx.offsets = kzalloc(4 * (ctx.skf->len + 1), GFP_KERNEL);
849 if (ctx.offsets == NULL) 868 if (ctx.offsets == NULL)
850 return; 869 return;
851 870
@@ -864,7 +883,7 @@ void bpf_jit_compile(struct sk_filter *fp)
864 883
865 ctx.idx += ctx.imm_count; 884 ctx.idx += ctx.imm_count;
866 if (ctx.imm_count) { 885 if (ctx.imm_count) {
867 ctx.imms = kzalloc(GFP_KERNEL, 4 * ctx.imm_count); 886 ctx.imms = kzalloc(4 * ctx.imm_count, GFP_KERNEL);
868 if (ctx.imms == NULL) 887 if (ctx.imms == NULL)
869 goto out; 888 goto out;
870 } 889 }