nfp_map_ptrs_record(struct nfp_app_bpf *bpf, struct nfp_prog *nfp_prog,
                    struct bpf_prog *prog)
 {
-       int i, cnt, err;
+       int i, cnt, err = 0;
+
+       mutex_lock(&prog->aux->used_maps_mutex);
 
        /* Quickly count the maps we will have to remember */
        cnt = 0;
                if (bpf_map_offload_neutral(prog->aux->used_maps[i]))
                        cnt++;
        if (!cnt)
-               return 0;
+               goto out;
 
        nfp_prog->map_records = kmalloc_array(cnt,
                                              sizeof(nfp_prog->map_records[0]),
                                              GFP_KERNEL);
-       if (!nfp_prog->map_records)
-               return -ENOMEM;
+       if (!nfp_prog->map_records) {
+               err = -ENOMEM;
+               goto out;
+       }
 
        for (i = 0; i < prog->aux->used_map_cnt; i++)
                if (bpf_map_offload_neutral(prog->aux->used_maps[i])) {
                                                 prog->aux->used_maps[i]);
                        if (err) {
                                nfp_map_ptrs_forget(bpf, nfp_prog);
-                               return err;
+                               goto out;
                        }
                }
        WARN_ON(cnt != nfp_prog->map_records_cnt);
 
-       return 0;
+out:
+       mutex_unlock(&prog->aux->used_maps_mutex);
+       return err;
 }
 
 static int
 
        struct bpf_ksym ksym;
        const struct bpf_prog_ops *ops;
        struct bpf_map **used_maps;
+       struct mutex used_maps_mutex; /* mutex for used_maps and used_map_cnt */
        struct bpf_prog *prog;
        struct user_struct *user;
        u64 load_time; /* ns since boottime */
 
        fp->jit_requested = ebpf_jit_enabled();
 
        INIT_LIST_HEAD_RCU(&fp->aux->ksym.lnode);
+       mutex_init(&fp->aux->used_maps_mutex);
 
        return fp;
 }
 void __bpf_prog_free(struct bpf_prog *fp)
 {
        if (fp->aux) {
+               mutex_destroy(&fp->aux->used_maps_mutex);
                free_percpu(fp->aux->stats);
                kfree(fp->aux->poke_tab);
                kfree(fp->aux);
 static int bpf_check_tail_call(const struct bpf_prog *fp)
 {
        struct bpf_prog_aux *aux = fp->aux;
-       int i;
+       int i, ret = 0;
 
+       mutex_lock(&aux->used_maps_mutex);
        for (i = 0; i < aux->used_map_cnt; i++) {
                struct bpf_map *map = aux->used_maps[i];
                struct bpf_array *array;
                        continue;
 
                array = container_of(map, struct bpf_array, map);
-               if (!bpf_prog_array_compatible(array, fp))
-                       return -EINVAL;
+               if (!bpf_prog_array_compatible(array, fp)) {
+                       ret = -EINVAL;
+                       goto out;
+               }
        }
 
-       return 0;
+out:
+       mutex_unlock(&aux->used_maps_mutex);
+       return ret;
 }
 
 static void bpf_prog_select_func(struct bpf_prog *fp)
 
        const struct bpf_map *map;
        int i;
 
+       mutex_lock(&prog->aux->used_maps_mutex);
        for (i = 0, *off = 0; i < prog->aux->used_map_cnt; i++) {
                map = prog->aux->used_maps[i];
                if (map == (void *)addr) {
                        *type = BPF_PSEUDO_MAP_FD;
-                       return map;
+                       goto out;
                }
                if (!map->ops->map_direct_value_meta)
                        continue;
                if (!map->ops->map_direct_value_meta(map, addr, off)) {
                        *type = BPF_PSEUDO_MAP_VALUE;
-                       return map;
+                       goto out;
                }
        }
+       map = NULL;
 
-       return NULL;
+out:
+       mutex_unlock(&prog->aux->used_maps_mutex);
+       return map;
 }
 
 static struct bpf_insn *bpf_insn_prepare_dump(const struct bpf_prog *prog,
        memcpy(info.tag, prog->tag, sizeof(prog->tag));
        memcpy(info.name, prog->aux->name, sizeof(prog->aux->name));
 
+       mutex_lock(&prog->aux->used_maps_mutex);
        ulen = info.nr_map_ids;
        info.nr_map_ids = prog->aux->used_map_cnt;
        ulen = min_t(u32, info.nr_map_ids, ulen);
 
                for (i = 0; i < ulen; i++)
                        if (put_user(prog->aux->used_maps[i]->id,
-                                    &user_map_ids[i]))
+                                    &user_map_ids[i])) {
+                               mutex_unlock(&prog->aux->used_maps_mutex);
                                return -EFAULT;
+                       }
        }
+       mutex_unlock(&prog->aux->used_maps_mutex);
 
        err = set_info_rec_size(&info);
        if (err)
 
        if (new) {
                u32 i;
 
+               mutex_lock(&new->aux->used_maps_mutex);
+
                /* generic XDP does not work with DEVMAPs that can
                 * have a bpf_prog installed on an entry
                 */
                for (i = 0; i < new->aux->used_map_cnt; i++) {
-                       if (dev_map_can_have_prog(new->aux->used_maps[i]))
-                               return -EINVAL;
-                       if (cpu_map_prog_allowed(new->aux->used_maps[i]))
+                       if (dev_map_can_have_prog(new->aux->used_maps[i]) ||
+                           cpu_map_prog_allowed(new->aux->used_maps[i])) {
+                               mutex_unlock(&new->aux->used_maps_mutex);
                                return -EINVAL;
+                       }
                }
+
+               mutex_unlock(&new->aux->used_maps_mutex);
        }
 
        switch (xdp->command) {