list_add(&tl->list_node, &bpf_map_types);
 }
 
+static int bpf_map_charge_memlock(struct bpf_map *map)
+{
+       struct user_struct *user = get_current_user();
+       unsigned long memlock_limit;
+
+       memlock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
+
+       atomic_long_add(map->pages, &user->locked_vm);
+
+       if (atomic_long_read(&user->locked_vm) > memlock_limit) {
+               atomic_long_sub(map->pages, &user->locked_vm);
+               free_uid(user);
+               return -EPERM;
+       }
+       map->user = user;
+       return 0;
+}
+
+static void bpf_map_uncharge_memlock(struct bpf_map *map)
+{
+       struct user_struct *user = map->user;
+
+       atomic_long_sub(map->pages, &user->locked_vm);
+       free_uid(user);
+}
+
 /* called from workqueue */
 static void bpf_map_free_deferred(struct work_struct *work)
 {
        struct bpf_map *map = container_of(work, struct bpf_map, work);
 
+       bpf_map_uncharge_memlock(map);
        /* implementation dependent freeing */
        map->ops->map_free(map);
 }
 
        atomic_set(&map->refcnt, 1);
 
+       err = bpf_map_charge_memlock(map);
+       if (err)
+               goto free_map;
+
        err = anon_inode_getfd("bpf-map", &bpf_map_fops, map, O_RDWR | O_CLOEXEC);
 
        if (err < 0)
        kfree(aux->used_maps);
 }
 
+static int bpf_prog_charge_memlock(struct bpf_prog *prog)
+{
+       struct user_struct *user = get_current_user();
+       unsigned long memlock_limit;
+
+       memlock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
+
+       atomic_long_add(prog->pages, &user->locked_vm);
+       if (atomic_long_read(&user->locked_vm) > memlock_limit) {
+               atomic_long_sub(prog->pages, &user->locked_vm);
+               free_uid(user);
+               return -EPERM;
+       }
+       prog->aux->user = user;
+       return 0;
+}
+
+static void bpf_prog_uncharge_memlock(struct bpf_prog *prog)
+{
+       struct user_struct *user = prog->aux->user;
+
+       atomic_long_sub(prog->pages, &user->locked_vm);
+       free_uid(user);
+}
+
 static void __prog_put_rcu(struct rcu_head *rcu)
 {
        struct bpf_prog_aux *aux = container_of(rcu, struct bpf_prog_aux, rcu);
 
        free_used_maps(aux);
+       bpf_prog_uncharge_memlock(aux->prog);
        bpf_prog_free(aux->prog);
 }
 
        if (!prog)
                return -ENOMEM;
 
+       err = bpf_prog_charge_memlock(prog);
+       if (err)
+               goto free_prog_nouncharge;
+
        prog->len = attr->insn_cnt;
 
        err = -EFAULT;
 free_used_maps:
        free_used_maps(prog->aux);
 free_prog:
+       bpf_prog_uncharge_memlock(prog);
+free_prog_nouncharge:
        bpf_prog_free(prog);
        return err;
 }