// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2017 Facebook
 */
#include <linux/slab.h>
#include <linux/bpf.h>
#include <linux/btf.h>

#include "map_in_map.h"

struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd)
{
	struct bpf_map *inner_map, *inner_map_meta;
	u32 inner_map_meta_size;
	struct fd f;
	int ret;

	f = fdget(inner_map_ufd);
	inner_map = __bpf_map_get(f);
	if (IS_ERR(inner_map))
		return inner_map;

	/* Does not support >1 level map-in-map */
	if (inner_map->inner_map_meta) {
		ret = -EINVAL;
		goto put;
	}

	if (!inner_map->ops->map_meta_equal) {
		ret = -ENOTSUPP;
		goto put;
	}

	inner_map_meta_size = sizeof(*inner_map_meta);
	/* In some cases verifier needs to access beyond just base map. */
	if (inner_map->ops == &array_map_ops)
		inner_map_meta_size = sizeof(struct bpf_array);

	inner_map_meta = kzalloc(inner_map_meta_size, GFP_USER);
	if (!inner_map_meta) {
		ret = -ENOMEM;
		goto put;
	}

	inner_map_meta->map_type = inner_map->map_type;
	inner_map_meta->key_size = inner_map->key_size;
	inner_map_meta->value_size = inner_map->value_size;
	inner_map_meta->map_flags = inner_map->map_flags;
	inner_map_meta->max_entries = inner_map->max_entries;

	inner_map_meta->record = btf_record_dup(inner_map->record);
	if (IS_ERR(inner_map_meta->record)) {
		/* btf_record_dup returns NULL or valid pointer in case of
		 * invalid/empty/valid, but ERR_PTR in case of errors. During
		 * equality NULL or IS_ERR is equivalent.
		 */
		ret = PTR_ERR(inner_map_meta->record);
		goto free;
	}
	if (inner_map_meta->record) {
		struct btf_field_offs *field_offs;
		/* If btf_record is !IS_ERR_OR_NULL, then field_offs is always
		 * valid.
		 */
		field_offs = kmemdup(inner_map->field_offs, sizeof(*inner_map->field_offs), GFP_KERNEL | __GFP_NOWARN);
		if (!field_offs) {
			ret = -ENOMEM;
			goto free_rec;
		}
		inner_map_meta->field_offs = field_offs;
	}
	/* Note: We must use the same BTF, as we also used btf_record_dup above
	 * which relies on BTF being same for both maps, as some members like
	 * record->fields.list_head have pointers like value_rec pointing into
	 * inner_map->btf.
	 */
	if (inner_map->btf) {
		btf_get(inner_map->btf);
		inner_map_meta->btf = inner_map->btf;
	}

	/* Misc members not needed in bpf_map_meta_equal() check. */
	inner_map_meta->ops = inner_map->ops;
	if (inner_map->ops == &array_map_ops) {
		inner_map_meta->bypass_spec_v1 = inner_map->bypass_spec_v1;
		container_of(inner_map_meta, struct bpf_array, map)->index_mask =
		     container_of(inner_map, struct bpf_array, map)->index_mask;
	}

	fdput(f);
	return inner_map_meta;
free_rec:
	btf_record_free(inner_map_meta->record);
free:
	kfree(inner_map_meta);
put:
	fdput(f);
	return ERR_PTR(ret);
}

void bpf_map_meta_free(struct bpf_map *map_meta)
{
	kfree(map_meta->field_offs);
	bpf_map_free_record(map_meta);
	btf_put(map_meta->btf);
	kfree(map_meta);
}

bool bpf_map_meta_equal(const struct bpf_map *meta0,
			const struct bpf_map *meta1)
{
	/* No need to compare ops because it is covered by map_type */
	return meta0->map_type == meta1->map_type &&
		meta0->key_size == meta1->key_size &&
		meta0->value_size == meta1->value_size &&
		meta0->map_flags == meta1->map_flags &&
		btf_record_equal(meta0->record, meta1->record);
}

void *bpf_map_fd_get_ptr(struct bpf_map *map,
			 struct file *map_file /* not used */,
			 int ufd)
{
	struct bpf_map *inner_map, *inner_map_meta;
	struct fd f;

	f = fdget(ufd);
	inner_map = __bpf_map_get(f);
	if (IS_ERR(inner_map))
		return inner_map;

	inner_map_meta = map->inner_map_meta;
	if (inner_map_meta->ops->map_meta_equal(inner_map_meta, inner_map))
		bpf_map_inc(inner_map);
	else
		inner_map = ERR_PTR(-EINVAL);

	fdput(f);
	return inner_map;
}

void bpf_map_fd_put_ptr(void *ptr)
{
	/* ptr->ops->map_free() has to go through one
	 * rcu grace period by itself.
	 */
	bpf_map_put(ptr);
}

u32 bpf_map_fd_sys_lookup_elem(void *ptr)
{
	return ((struct bpf_map *)ptr)->id;
}
