aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/net/bpf_jit_comp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/net/bpf_jit_comp.c')
-rw-r--r--arch/powerpc/net/bpf_jit_comp.c49
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 /*