struct bpf_insn *insn = insn_buf;
        const int ret = BPF_REG_0;
 
-       *insn++ = BPF_EMIT_CALL((u64 (*)(u64, u64, u64, u64, u64))__htab_map_lookup_elem);
+       BUILD_BUG_ON(!__same_type(&__htab_map_lookup_elem,
+                    (void *(*)(struct bpf_map *map, void *key))NULL));
+       *insn++ = BPF_EMIT_CALL(BPF_CAST_CALL(__htab_map_lookup_elem));
        *insn++ = BPF_JMP_IMM(BPF_JEQ, ret, 0, 1);
        *insn++ = BPF_ALU64_IMM(BPF_ADD, ret,
                                offsetof(struct htab_elem, key) +
        const int ret = BPF_REG_0;
        const int ref_reg = BPF_REG_1;
 
-       *insn++ = BPF_EMIT_CALL((u64 (*)(u64, u64, u64, u64, u64))__htab_map_lookup_elem);
+       BUILD_BUG_ON(!__same_type(&__htab_map_lookup_elem,
+                    (void *(*)(struct bpf_map *map, void *key))NULL));
+       *insn++ = BPF_EMIT_CALL(BPF_CAST_CALL(__htab_map_lookup_elem));
        *insn++ = BPF_JMP_IMM(BPF_JEQ, ret, 0, 4);
        *insn++ = BPF_LDX_MEM(BPF_B, ref_reg, ret,
                              offsetof(struct htab_elem, lru_node) +
        struct bpf_insn *insn = insn_buf;
        const int ret = BPF_REG_0;
 
-       *insn++ = BPF_EMIT_CALL((u64 (*)(u64, u64, u64, u64, u64))__htab_map_lookup_elem);
+       BUILD_BUG_ON(!__same_type(&__htab_map_lookup_elem,
+                    (void *(*)(struct bpf_map *map, void *key))NULL));
+       *insn++ = BPF_EMIT_CALL(BPF_CAST_CALL(__htab_map_lookup_elem));
        *insn++ = BPF_JMP_IMM(BPF_JEQ, ret, 0, 2);
        *insn++ = BPF_ALU64_IMM(BPF_ADD, ret,
                                offsetof(struct htab_elem, key) +
 
        struct bpf_insn_aux_data *aux = &env->insn_aux_data[insn_idx];
 
        if (func_id != BPF_FUNC_tail_call &&
-           func_id != BPF_FUNC_map_lookup_elem)
+           func_id != BPF_FUNC_map_lookup_elem &&
+           func_id != BPF_FUNC_map_update_elem &&
+           func_id != BPF_FUNC_map_delete_elem)
                return 0;
+
        if (meta->map_ptr == NULL) {
                verbose(env, "kernel subsystem misconfigured verifier\n");
                return -EINVAL;
        struct bpf_insn *insn = prog->insnsi;
        const struct bpf_func_proto *fn;
        const int insn_cnt = prog->len;
+       const struct bpf_map_ops *ops;
        struct bpf_insn_aux_data *aux;
        struct bpf_insn insn_buf[16];
        struct bpf_prog *new_prog;
                }
 
                /* BPF_EMIT_CALL() assumptions in some of the map_gen_lookup
-                * handlers are currently limited to 64 bit only.
+                * and other inlining handlers are currently limited to 64 bit
+                * only.
                 */
                if (prog->jit_requested && BITS_PER_LONG == 64 &&
-                   insn->imm == BPF_FUNC_map_lookup_elem) {
+                   (insn->imm == BPF_FUNC_map_lookup_elem ||
+                    insn->imm == BPF_FUNC_map_update_elem ||
+                    insn->imm == BPF_FUNC_map_delete_elem)) {
                        aux = &env->insn_aux_data[i + delta];
                        if (bpf_map_ptr_poisoned(aux))
                                goto patch_call_imm;
 
                        map_ptr = BPF_MAP_PTR(aux->map_state);
-                       if (!map_ptr->ops->map_gen_lookup)
-                               goto patch_call_imm;
+                       ops = map_ptr->ops;
+                       if (insn->imm == BPF_FUNC_map_lookup_elem &&
+                           ops->map_gen_lookup) {
+                               cnt = ops->map_gen_lookup(map_ptr, insn_buf);
+                               if (cnt == 0 || cnt >= ARRAY_SIZE(insn_buf)) {
+                                       verbose(env, "bpf verifier is misconfigured\n");
+                                       return -EINVAL;
+                               }
 
-                       cnt = map_ptr->ops->map_gen_lookup(map_ptr, insn_buf);
-                       if (cnt == 0 || cnt >= ARRAY_SIZE(insn_buf)) {
-                               verbose(env, "bpf verifier is misconfigured\n");
-                               return -EINVAL;
-                       }
+                               new_prog = bpf_patch_insn_data(env, i + delta,
+                                                              insn_buf, cnt);
+                               if (!new_prog)
+                                       return -ENOMEM;
 
-                       new_prog = bpf_patch_insn_data(env, i + delta, insn_buf,
-                                                      cnt);
-                       if (!new_prog)
-                               return -ENOMEM;
+                               delta    += cnt - 1;
+                               env->prog = prog = new_prog;
+                               insn      = new_prog->insnsi + i + delta;
+                               continue;
+                       }
 
-                       delta += cnt - 1;
+                       BUILD_BUG_ON(!__same_type(ops->map_lookup_elem,
+                                    (void *(*)(struct bpf_map *map, void *key))NULL));
+                       BUILD_BUG_ON(!__same_type(ops->map_delete_elem,
+                                    (int (*)(struct bpf_map *map, void *key))NULL));
+                       BUILD_BUG_ON(!__same_type(ops->map_update_elem,
+                                    (int (*)(struct bpf_map *map, void *key, void *value,
+                                             u64 flags))NULL));
+                       switch (insn->imm) {
+                       case BPF_FUNC_map_lookup_elem:
+                               insn->imm = BPF_CAST_CALL(ops->map_lookup_elem) -
+                                           __bpf_call_base;
+                               continue;
+                       case BPF_FUNC_map_update_elem:
+                               insn->imm = BPF_CAST_CALL(ops->map_update_elem) -
+                                           __bpf_call_base;
+                               continue;
+                       case BPF_FUNC_map_delete_elem:
+                               insn->imm = BPF_CAST_CALL(ops->map_delete_elem) -
+                                           __bpf_call_base;
+                               continue;
+                       }
 
-                       /* keep walking new program and skip insns we just inserted */
-                       env->prog = prog = new_prog;
-                       insn      = new_prog->insnsi + i + delta;
-                       continue;
+                       goto patch_call_imm;
                }
 
                if (insn->imm == BPF_FUNC_redirect_map) {