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);
 
                        }
                        PPC_DIVWU(r_A, r_A, r_X);
                        break;
-               case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K); */
+               case BPF_S_ALU_DIV_K: /* A /= K */
+                       if (K == 1)
+                               break;
                        PPC_LI32(r_scratch1, K);
-                       /* Top 32 bits of 64bit result -> A */
-                       PPC_MULHWU(r_A, r_A, r_scratch1);
+                       PPC_DIVWU(r_A, r_A, r_scratch1);
                        break;
                case BPF_S_ALU_AND_X:
                        ctx->seen |= SEEN_XREG;
 
                /* dr %r4,%r12 */
                EMIT2(0x1d4c);
                break;
-       case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K) */
-               /* m %r4,<d(K)>(%r13) */
-               EMIT4_DISP(0x5c40d000, EMIT_CONST(K));
-               /* lr %r5,%r4 */
-               EMIT2(0x1854);
+       case BPF_S_ALU_DIV_K: /* A /= K */
+               if (K == 1)
+                       break;
+               /* lhi %r4,0 */
+               EMIT4(0xa7480000);
+               /* d %r4,<d(K)>(%r13) */
+               EMIT4_DISP(0x5d40d000, EMIT_CONST(K));
                break;
        case BPF_S_ALU_MOD_X: /* A %= X */
                jit->seen |= SEEN_XREG | SEEN_RET0;
                EMIT2(0x1854);
                break;
        case BPF_S_ALU_MOD_K: /* A %= K */
+               if (K == 1) {
+                       /* lhi %r5,0 */
+                       EMIT4(0xa7580000);
+                       break;
+               }
                /* lhi %r4,0 */
                EMIT4(0xa7480000);
                /* d %r4,<d(K)>(%r13) */
 
                        case BPF_S_ALU_MUL_K:   /* A *= K */
                                emit_alu_K(MUL, K);
                                break;
-                       case BPF_S_ALU_DIV_K:   /* A /= K */
-                               emit_alu_K(MUL, K);
-                               emit_read_y(r_A);
+                       case BPF_S_ALU_DIV_K:   /* A /= K with K != 0*/
+                               if (K == 1)
+                                       break;
+                               emit_write_y(G0);
+#ifdef CONFIG_SPARC32
+                               /* The Sparc v8 architecture requires
+                                * three instructions between a %y
+                                * register write and the first use.
+                                */
+                               emit_nop();
+                               emit_nop();
+                               emit_nop();
+#endif
+                               emit_alu_K(DIV, K);
                                break;
                        case BPF_S_ALU_DIV_X:   /* A /= X; */
                                emit_cmpi(r_X, 0);
 
                                EMIT2(0x89, 0xd0);      /* mov %edx,%eax */
                                break;
                        case BPF_S_ALU_MOD_K: /* A %= K; */
+                               if (K == 1) {
+                                       CLEAR_A();
+                                       break;
+                               }
                                EMIT2(0x31, 0xd2);      /* xor %edx,%edx */
                                EMIT1(0xb9);EMIT(K, 4); /* mov imm32,%ecx */
                                EMIT2(0xf7, 0xf1);      /* div %ecx */
                                EMIT2(0x89, 0xd0);      /* mov %edx,%eax */
                                break;
-                       case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K); */
-                               EMIT3(0x48, 0x69, 0xc0); /* imul imm32,%rax,%rax */
-                               EMIT(K, 4);
-                               EMIT4(0x48, 0xc1, 0xe8, 0x20); /* shr $0x20,%rax */
+                       case BPF_S_ALU_DIV_K: /* A /= K */
+                               if (K == 1)
+                                       break;
+                               EMIT2(0x31, 0xd2);      /* xor %edx,%edx */
+                               EMIT1(0xb9);EMIT(K, 4); /* mov imm32,%ecx */
+                               EMIT2(0xf7, 0xf1);      /* div %ecx */
                                break;
                        case BPF_S_ALU_AND_X:
                                seen |= SEEN_XREG;
 
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
 #include <linux/filter.h>
-#include <linux/reciprocal_div.h>
 #include <linux/ratelimit.h>
 #include <linux/seccomp.h>
 #include <linux/if_vlan.h>
                        A /= X;
                        continue;
                case BPF_S_ALU_DIV_K:
-                       A = reciprocal_divide(A, K);
+                       A /= K;
                        continue;
                case BPF_S_ALU_MOD_X:
                        if (X == 0)
                /* Some instructions need special checks */
                switch (code) {
                case BPF_S_ALU_DIV_K:
-                       /* check for division by zero */
-                       if (ftest->k == 0)
-                               return -EINVAL;
-                       ftest->k = reciprocal_value(ftest->k);
-                       break;
                case BPF_S_ALU_MOD_K:
                        /* check for division by zero */
                        if (ftest->k == 0)
        to->code = decodes[code];
        to->jt = filt->jt;
        to->jf = filt->jf;
-
-       if (code == BPF_S_ALU_DIV_K) {
-               /*
-                * When loaded this rule user gave us X, which was
-                * translated into R = r(X). Now we calculate the
-                * RR = r(R) and report it back. If next time this
-                * value is loaded and RRR = r(RR) is calculated
-                * then the R == RRR will be true.
-                *
-                * One exception. X == 1 translates into R == 0 and
-                * we can't calculate RR out of it with r().
-                */
-
-               if (filt->k == 0)
-                       to->k = 1;
-               else
-                       to->k = reciprocal_value(filt->k);
-
-               BUG_ON(reciprocal_value(to->k) != filt->k);
-       } else
-               to->k = filt->k;
+       to->k = filt->k;
 }
 
 int sk_get_filter(struct sock *sk, struct sock_filter __user *ubuf, unsigned int len)