diff options
Diffstat (limited to 'arch/powerpc/net/bpf_jit_comp.c')
-rw-r--r-- | arch/powerpc/net/bpf_jit_comp.c | 49 |
1 files changed, 26 insertions, 23 deletions
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index cbae2dfd053c..1ca125b9c226 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c | |||
@@ -181,6 +181,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, | |||
181 | } | 181 | } |
182 | break; | 182 | break; |
183 | case BPF_ALU | BPF_MOD | BPF_X: /* A %= X; */ | 183 | case BPF_ALU | BPF_MOD | BPF_X: /* A %= X; */ |
184 | case BPF_ALU | BPF_DIV | BPF_X: /* A /= X; */ | ||
184 | ctx->seen |= SEEN_XREG; | 185 | ctx->seen |= SEEN_XREG; |
185 | PPC_CMPWI(r_X, 0); | 186 | PPC_CMPWI(r_X, 0); |
186 | if (ctx->pc_ret0 != -1) { | 187 | if (ctx->pc_ret0 != -1) { |
@@ -190,9 +191,13 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, | |||
190 | PPC_LI(r_ret, 0); | 191 | PPC_LI(r_ret, 0); |
191 | PPC_JMP(exit_addr); | 192 | PPC_JMP(exit_addr); |
192 | } | 193 | } |
193 | PPC_DIVWU(r_scratch1, r_A, r_X); | 194 | if (code == (BPF_ALU | BPF_MOD | BPF_X)) { |
194 | PPC_MUL(r_scratch1, r_X, r_scratch1); | 195 | PPC_DIVWU(r_scratch1, r_A, r_X); |
195 | PPC_SUB(r_A, r_A, r_scratch1); | 196 | PPC_MUL(r_scratch1, r_X, r_scratch1); |
197 | PPC_SUB(r_A, r_A, r_scratch1); | ||
198 | } else { | ||
199 | PPC_DIVWU(r_A, r_A, r_X); | ||
200 | } | ||
196 | break; | 201 | break; |
197 | case BPF_ALU | BPF_MOD | BPF_K: /* A %= K; */ | 202 | case BPF_ALU | BPF_MOD | BPF_K: /* A %= K; */ |
198 | PPC_LI32(r_scratch2, K); | 203 | PPC_LI32(r_scratch2, K); |
@@ -200,22 +205,6 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, | |||
200 | PPC_MUL(r_scratch1, r_scratch2, r_scratch1); | 205 | PPC_MUL(r_scratch1, r_scratch2, r_scratch1); |
201 | PPC_SUB(r_A, r_A, r_scratch1); | 206 | PPC_SUB(r_A, r_A, r_scratch1); |
202 | break; | 207 | break; |
203 | case BPF_ALU | BPF_DIV | BPF_X: /* A /= X; */ | ||
204 | ctx->seen |= SEEN_XREG; | ||
205 | PPC_CMPWI(r_X, 0); | ||
206 | if (ctx->pc_ret0 != -1) { | ||
207 | PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]); | ||
208 | } else { | ||
209 | /* | ||
210 | * Exit, returning 0; first pass hits here | ||
211 | * (longer worst-case code size). | ||
212 | */ | ||
213 | PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12); | ||
214 | PPC_LI(r_ret, 0); | ||
215 | PPC_JMP(exit_addr); | ||
216 | } | ||
217 | PPC_DIVWU(r_A, r_A, r_X); | ||
218 | break; | ||
219 | case BPF_ALU | BPF_DIV | BPF_K: /* A /= K */ | 208 | case BPF_ALU | BPF_DIV | BPF_K: /* A /= K */ |
220 | if (K == 1) | 209 | if (K == 1) |
221 | break; | 210 | break; |
@@ -361,6 +350,11 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, | |||
361 | protocol)); | 350 | protocol)); |
362 | break; | 351 | break; |
363 | case BPF_ANC | SKF_AD_IFINDEX: | 352 | case BPF_ANC | SKF_AD_IFINDEX: |
353 | case BPF_ANC | SKF_AD_HATYPE: | ||
354 | BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, | ||
355 | ifindex) != 4); | ||
356 | BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, | ||
357 | type) != 2); | ||
364 | PPC_LD_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff, | 358 | PPC_LD_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff, |
365 | dev)); | 359 | dev)); |
366 | PPC_CMPDI(r_scratch1, 0); | 360 | PPC_CMPDI(r_scratch1, 0); |
@@ -368,14 +362,18 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, | |||
368 | PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]); | 362 | PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]); |
369 | } else { | 363 | } else { |
370 | /* Exit, returning 0; first pass hits here. */ | 364 | /* Exit, returning 0; first pass hits here. */ |
371 | PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12); | 365 | PPC_BCC_SHORT(COND_NE, ctx->idx * 4 + 12); |
372 | PPC_LI(r_ret, 0); | 366 | PPC_LI(r_ret, 0); |
373 | PPC_JMP(exit_addr); | 367 | PPC_JMP(exit_addr); |
374 | } | 368 | } |
375 | BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, | 369 | if (code == (BPF_ANC | SKF_AD_IFINDEX)) { |
376 | ifindex) != 4); | 370 | PPC_LWZ_OFFS(r_A, r_scratch1, |
377 | PPC_LWZ_OFFS(r_A, r_scratch1, | ||
378 | offsetof(struct net_device, ifindex)); | 371 | offsetof(struct net_device, ifindex)); |
372 | } else { | ||
373 | PPC_LHZ_OFFS(r_A, r_scratch1, | ||
374 | offsetof(struct net_device, type)); | ||
375 | } | ||
376 | |||
379 | break; | 377 | break; |
380 | case BPF_ANC | SKF_AD_MARK: | 378 | case BPF_ANC | SKF_AD_MARK: |
381 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4); | 379 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4); |
@@ -407,6 +405,11 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, | |||
407 | PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, | 405 | PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, |
408 | queue_mapping)); | 406 | queue_mapping)); |
409 | break; | 407 | break; |
408 | case BPF_ANC | SKF_AD_PKTTYPE: | ||
409 | PPC_LBZ_OFFS(r_A, r_skb, PKT_TYPE_OFFSET()); | ||
410 | PPC_ANDI(r_A, r_A, PKT_TYPE_MAX); | ||
411 | PPC_SRWI(r_A, r_A, 5); | ||
412 | break; | ||
410 | case BPF_ANC | SKF_AD_CPU: | 413 | case BPF_ANC | SKF_AD_CPU: |
411 | #ifdef CONFIG_SMP | 414 | #ifdef CONFIG_SMP |
412 | /* | 415 | /* |