]> Pileus Git - ~andy/linux/blobdiff - arch/arm/net/bpf_jit_32.c
bpf: do not use reciprocal divide
[~andy/linux] / arch / arm / net / bpf_jit_32.c
index 99b44e0e8d866983dd60d4b8324bf29010679e77..271b5e9715682ab40869a1ea8a02c9696eaebf07 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/if_vlan.h>
 #include <asm/cacheflush.h>
 #include <asm/hwcap.h>
+#include <asm/opcodes.h>
 
 #include "bpf_jit_32.h"
 
@@ -113,8 +114,11 @@ static u32 jit_udiv(u32 dividend, u32 divisor)
 
 static inline void _emit(int cond, u32 inst, struct jit_ctx *ctx)
 {
+       inst |= (cond << 28);
+       inst = __opcode_to_mem_arm(inst);
+
        if (ctx->target != NULL)
-               ctx->target[ctx->idx] = inst | (cond << 28);
+               ctx->target[ctx->idx] = inst;
 
        ctx->idx++;
 }
@@ -637,10 +641,10 @@ load_ind:
                        emit(ARM_MUL(r_A, r_A, r_X), ctx);
                        break;
                case BPF_S_ALU_DIV_K:
-                       /* current k == reciprocal_value(userspace k) */
+                       if (k == 1)
+                               break;
                        emit_mov_i(r_scratch, k, ctx);
-                       /* A = top 32 bits of the product */
-                       emit(ARM_UMULL(r_scratch, r_A, r_A, r_scratch), ctx);
+                       emit_udiv(r_A, r_A, r_scratch, ctx);
                        break;
                case BPF_S_ALU_DIV_X:
                        update_on_xread(ctx);