// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2023 Google LLC
 * Author: Vincent Donnefort <vdonnefort@google.com>
 */

#include <nvhe/alloc.h>
#include <nvhe/mem_protect.h>
#include <nvhe/mm.h>
#include <nvhe/spinlock.h>

#include <linux/build_bug.h>
#include <linux/hash.h>
#include <linux/list.h>

#define MIN_ALLOC 8UL

static struct hyp_allocator {
	struct kvm_hyp_memcache	mc[NR_CPUS];
	struct list_head	chunks;
	unsigned long		start;
	u32			size;
	hyp_spinlock_t		lock;
	u8			errno[NR_CPUS];
	u8			missing_donations[NR_CPUS];
} hyp_allocator;

struct chunk_hdr {
	u32			alloc_size;
	u32			mapped_size;
	struct list_head	node;
	u32			hash;
	char			data __aligned(8);
};

static u32 chunk_hash_compute(struct chunk_hdr *chunk)
{
	size_t len = offsetof(struct chunk_hdr, hash);
	u64 *data = (u64 *)chunk;
	u32 hash = 0;

	BUILD_BUG_ON(!IS_ALIGNED(offsetof(struct chunk_hdr, hash), sizeof(u32)));

	while (len >= sizeof(u64)) {
		hash ^= hash_64(*data, 32);
		len -= sizeof(u64);
		data++;
	}

	if (len)
		hash ^= hash_32(*(u32 *)data, 32);

	return hash;
}

static inline void chunk_hash_update(struct chunk_hdr *chunk)
{
	if (chunk)
		chunk->hash = chunk_hash_compute(chunk);
}

static inline void chunk_hash_validate(struct chunk_hdr *chunk)
{
	if (chunk)
		WARN_ON(chunk->hash != chunk_hash_compute(chunk));
}

#define chunk_is_used(chunk) \
	(!!chunk->alloc_size)

#define chunk_hdr() \
	offsetof(struct chunk_hdr, data)

#define chunk_size(size) \
	(chunk_hdr() + max((size_t)size, MIN_ALLOC))

#define chunk_data(chunk) \
	((void *)(&chunk->data))

#define __chunk_next(chunk, allocator)				\
({								\
	list_is_last(&chunk->node, &allocator->chunks) ?	\
		NULL : list_next_entry(chunk, node);		\
})

#define __chunk_prev(chunk, allocator)				\
({								\
	list_is_first(&chunk->node, &allocator->chunks) ?	\
		NULL : list_prev_entry(chunk, node);		\
})

#define chunk_get_next(chunk, allocator)			\
({								\
	struct chunk_hdr *next = __chunk_next(chunk, allocator);\
	chunk_hash_validate(next);				\
	next;							\
})

#define chunk_get_prev(chunk, allocator)			\
({								\
	struct chunk_hdr *prev = __chunk_prev(chunk, allocator);\
	chunk_hash_validate(prev);				\
	prev;							\
})

#define chunk_get(addr)						\
({								\
	struct chunk_hdr *chunk = (struct chunk_hdr *)addr;	\
	chunk_hash_validate(chunk);				\
	chunk;							\
})

#define chunk_unmapped_region(chunk) \
	((unsigned long)chunk + chunk->mapped_size)

#define chunk_unmapped_size(chunk, allocator)				\
({									\
	struct chunk_hdr *next = chunk_get_next(chunk, allocator);	\
	unsigned long allocator_end = allocator->start + allocator->size;\
	next ? (unsigned long)next - chunk_unmapped_region(chunk) :	\
		allocator_end - chunk_unmapped_region(chunk);		\
})

static inline void chunk_list_insert(struct chunk_hdr *chunk,
				     struct chunk_hdr *prev,
				     struct hyp_allocator *allocator)
{
	list_add(&chunk->node, &prev->node);
	chunk_hash_update(prev);
	chunk_hash_update(__chunk_next(chunk, allocator));
	chunk_hash_update(chunk);
}

static inline void chunk_list_del(struct chunk_hdr *chunk,
				  struct hyp_allocator *allocator)
{
	struct chunk_hdr *prev = __chunk_prev(chunk, allocator);
	struct chunk_hdr *next = __chunk_next(chunk, allocator);

	list_del(&chunk->node);
	chunk_hash_update(prev);
	chunk_hash_update(next);
}

static void hyp_allocator_unmap(struct hyp_allocator *allocator,
				unsigned long va, size_t size)
{
	struct kvm_hyp_memcache *mc = &allocator->mc[hyp_smp_processor_id()];
	int nr_pages = size >> PAGE_SHIFT;
	unsigned long __va = va;

	WARN_ON(!PAGE_ALIGNED(va));
	WARN_ON(!PAGE_ALIGNED(size));

	while (nr_pages--) {
		phys_addr_t pa = __pkvm_private_range_pa((void *)__va);
		void *page = hyp_phys_to_virt(pa);

		push_hyp_memcache(mc, page, hyp_virt_to_phys);
		__va += PAGE_SIZE;
	}

	WARN_ON(__pkvm_remove_mappings(va, size));
}

static int hyp_allocator_map(struct hyp_allocator *allocator,
			     unsigned long va, size_t size)
{
	struct kvm_hyp_memcache *mc = &allocator->mc[hyp_smp_processor_id()];
	int ret, nr_pages = 0;

	if (!PAGE_ALIGNED(va) || !PAGE_ALIGNED(size))
		return -EINVAL;

	if ((va + size) > (allocator->start + allocator->size))
		return -E2BIG;

	if (mc->nr_pages < (size >> PAGE_SHIFT)) {
		u8 *missing_donations = &allocator->missing_donations[hyp_smp_processor_id()];
		u32 delta = (size >> PAGE_SHIFT) - mc->nr_pages;

		*missing_donations = (u8)min(delta, (u32)~((u8)0));

		return -ENOMEM;
	}

	while (nr_pages < (size >> PAGE_SHIFT)) {
		void *page;

		page = pop_hyp_memcache(mc, hyp_phys_to_virt);
		WARN_ON(!page);

		ret = __pkvm_create_mappings(va, PAGE_SIZE, hyp_virt_to_phys(page), PAGE_HYP);
		if (ret) {
			push_hyp_memcache(mc, page, hyp_virt_to_phys);
			break;
		}
		va += PAGE_SIZE;
		nr_pages++;
	}

	if (ret && nr_pages) {
		va -= PAGE_SIZE * nr_pages;
		hyp_allocator_unmap(allocator, va, nr_pages << PAGE_SHIFT);
	}

	return ret;
}

static int chunk_install(struct chunk_hdr *chunk, size_t size,
			 struct chunk_hdr *prev,
			 struct hyp_allocator *allocator)
{
	size_t prev_mapped_size;

	/* First chunk, first allocation */
	if (!prev) {
		INIT_LIST_HEAD(&chunk->node);
		list_add(&chunk->node, &allocator->chunks);
		chunk->mapped_size = PAGE_ALIGN(chunk_size(size));
		chunk->alloc_size = size;

		chunk_hash_update(chunk);

		return 0;
	}

	if (chunk_unmapped_region(prev) < (unsigned long)chunk)
		return -EINVAL;
	if ((unsigned long)chunk_data(prev) + prev->alloc_size > (unsigned long)chunk)
		return -EINVAL;

	prev_mapped_size = prev->mapped_size;
	prev->mapped_size = (unsigned long)chunk - (unsigned long)prev;

	chunk->mapped_size = prev_mapped_size - prev->mapped_size;
	chunk->alloc_size = size;

	chunk_list_insert(chunk, prev, allocator);

	return 0;
}

static int chunk_merge(struct chunk_hdr *chunk, struct hyp_allocator *allocator)
{
	/* The caller already validates prev */
	struct chunk_hdr *prev = __chunk_prev(chunk, allocator);

	if (WARN_ON(!prev))
		return -EINVAL;

	/* Can only merge free chunks */
	if (chunk_is_used(chunk) || chunk_is_used(prev))
		return -EBUSY;

	/* Can't merge non-contiguous mapped regions */
	if (chunk_unmapped_region(prev) != (unsigned long)chunk)
		return 0;

	/* mapped region inheritance */
	prev->mapped_size += chunk->mapped_size;

	chunk_list_del(chunk, allocator);

	return 0;
}

static size_t chunk_needs_mapping(struct chunk_hdr *chunk, size_t size)
{
	size_t mapping_missing, mapping_needs = chunk_size(size);

	if (mapping_needs <= chunk->mapped_size)
		return 0;

	mapping_missing = PAGE_ALIGN(mapping_needs - chunk->mapped_size);

	return mapping_missing;
}

/*
 * When a chunk spans over several pages, split it at the start of the latest
 * page. This allows to punch holes in the mapping to reclaim pages.
 *
 *  +--------------+
 *  |______________|
 *  |______________|<- Next chunk
 *  |_ _ _ __ _ _ _|
 *  |              |<- New chunk installed, page aligned
 *  +--------------+
 *  +--------------+
 *  |              |
 *  |              |<- Allow to reclaim this page
 *  |              |
 *  |              |
 *  +--------------+
 *  +--------------+
 *  |              |
 *  |______________|
 *  |______________|<- Chunk to split at page alignment
 *  |              |
 *  +--------------+
 */
static int chunk_split_aligned(struct chunk_hdr *chunk,
			       struct hyp_allocator *allocator)
{
	struct chunk_hdr *next_chunk = chunk_get_next(chunk, allocator);
	unsigned long delta, mapped_end = chunk_unmapped_region(chunk);
	struct chunk_hdr *new_chunk;

	if (PAGE_ALIGNED(mapped_end))
		return 0;

	new_chunk = (struct chunk_hdr *)PAGE_ALIGN_DOWN(mapped_end);
	if ((unsigned long)new_chunk <= (unsigned long)chunk)
		return -EINVAL;

	delta = ((unsigned long)next_chunk - (unsigned long)new_chunk);

	/*
	 * This shouldn't happen, chunks are installed to a minimum distance
	 * from the page start
	 */
	WARN_ON(delta < chunk_size(0UL));

	WARN_ON(chunk_install(new_chunk, 0, chunk, allocator));

	return 0;
}

static int chunk_inc_map(struct chunk_hdr *chunk, size_t map_size,
			 struct hyp_allocator *allocator)
{
	int ret;

	if (chunk_unmapped_size(chunk, allocator) < map_size)
		return -EINVAL;

	ret = hyp_allocator_map(allocator, chunk_unmapped_region(chunk),
				map_size);
	if (ret)
		return ret;

	chunk->mapped_size += map_size;
	chunk_hash_update(chunk);

	return 0;
}

static size_t chunk_dec_map(struct chunk_hdr *chunk,
			    struct hyp_allocator *allocator,
			    size_t reclaim_target)
{
	unsigned long start, end;
	size_t reclaimable;

	start = PAGE_ALIGN((unsigned long)chunk +
			   chunk_size(chunk->alloc_size));
	end = chunk_unmapped_region(chunk);

	if (start >= end)
		return 0;

	reclaimable = end - start;
	if (reclaimable < PAGE_SIZE)
		return 0;

	if (chunk_split_aligned(chunk, allocator))
		return 0;

	end = chunk_unmapped_region(chunk);
	reclaimable = min(end - start, reclaim_target);

	hyp_allocator_unmap(allocator, start, reclaimable);

	chunk->mapped_size -= reclaimable;
	chunk_hash_update(chunk);

	return reclaimable;
}

static unsigned long chunk_addr_fixup(unsigned long addr)
{
	unsigned long min_chunk_size = chunk_size(0UL);
	unsigned long page = PAGE_ALIGN_DOWN(addr);
	unsigned long delta = addr - page;

	if (!delta)
		return addr;

	/*
	 * To maximize reclaim, a chunk must fit between the page start and this
	 * addr.
	 */
	if (delta < min_chunk_size)
		return page + min_chunk_size;

	return addr;
}

static bool chunk_can_split(struct chunk_hdr *chunk, unsigned long addr,
			    struct hyp_allocator *allocator)
{
	unsigned long chunk_end;

	/*
	 * There is no point splitting the last chunk, subsequent allocations
	 * would be able to use this space anyway.
	 */
	if (list_is_last(&chunk->node, &allocator->chunks))
		return false;

	chunk_end = (unsigned long)chunk + chunk->mapped_size +
		    chunk_unmapped_size(chunk, allocator);

	return addr + chunk_size(0UL) < chunk_end;
}

static int chunk_recycle(struct chunk_hdr *chunk, size_t size,
			 struct hyp_allocator *allocator)
{
	unsigned long new_chunk_addr = (unsigned long)chunk + chunk_size(size);
	size_t missing_map, expected_mapping = size;
	struct chunk_hdr *new_chunk = NULL;
	int ret;

	new_chunk_addr = chunk_addr_fixup(new_chunk_addr);
	if (chunk_can_split(chunk, new_chunk_addr, allocator)) {
		new_chunk = (struct chunk_hdr *)new_chunk_addr;
		expected_mapping = new_chunk_addr + chunk_hdr() -
					(unsigned long)chunk_data(chunk);
	}

	missing_map = chunk_needs_mapping(chunk, expected_mapping);
	if (missing_map) {
		ret = chunk_inc_map(chunk, missing_map, allocator);
		if (ret)
			return ret;
	}

	chunk->alloc_size = size;
	chunk_hash_update(chunk);

	if (new_chunk)
		WARN_ON(chunk_install(new_chunk, 0, chunk, allocator));

	return 0;
}

static size_t chunk_try_destroy(struct chunk_hdr *chunk,
				struct hyp_allocator *allocator,
				size_t reclaim_target)
{
	size_t unmapped;

	if (chunk_is_used(chunk))
		return 0;

	/* Don't kill the entire chunk if this is not necessary */
	if (chunk->mapped_size > reclaim_target)
		return 0;

	if (list_is_first(&chunk->node, &allocator->chunks)) {
		/* last standing chunk ? */
		if (!list_is_last(&chunk->node, &allocator->chunks))
			return 0;

		list_del(&chunk->node);
		goto unmap;
	}

	/*
	 * Resolve discontiguous unmapped zones that are the result
	 * of a previous chunk_dec_map().
	 *
	 * To make sure we still keep track of that unmapped zone in our free
	 * list, we need either to be the last chunk or to have prev unused. Two
	 * contiguous chunks can be both free if they are separated by an
	 * unmapped zone (see chunk_recycle()).
	 */

	if (!PAGE_ALIGNED((unsigned long)chunk))
		return 0;

	if (list_is_last(&chunk->node, &allocator->chunks))
		goto destroy;

	if (chunk_is_used(chunk_get_prev(chunk, allocator)))
		return 0;

	if (chunk_split_aligned(chunk, allocator))
		return 0;
destroy:
	chunk_list_del(chunk, allocator);
unmap:
	unmapped = chunk->mapped_size;
	hyp_allocator_unmap(allocator, (unsigned long)chunk,
			    chunk->mapped_size);

	return unmapped;
}

static int setup_first_chunk(struct hyp_allocator *allocator, size_t size)
{
	int ret;

	ret = hyp_allocator_map(allocator, allocator->start,
				PAGE_ALIGN(chunk_size(size)));
	if (ret)
		return ret;

	return chunk_install((struct chunk_hdr *)allocator->start, size, NULL, allocator);
}

static struct chunk_hdr *
get_free_chunk(struct hyp_allocator *allocator, size_t size)
{
	struct chunk_hdr *chunk, *best_chunk = NULL;
	size_t best_available_size = allocator->size;

	list_for_each_entry(chunk, &allocator->chunks, node) {
		size_t available_size = chunk->mapped_size +
					chunk_unmapped_size(chunk, allocator);
		if (chunk_is_used(chunk))
			continue;

		if (chunk_size(size) > available_size)
			continue;

		if (!best_chunk) {
			best_chunk = chunk;
			continue;
		}

		if (best_available_size <= available_size)
			continue;

		best_chunk = chunk;
		best_available_size = available_size;
	}

	return chunk_get(best_chunk);
}

static void *hyp_allocator_alloc(struct hyp_allocator *allocator, size_t size)
{
	struct chunk_hdr *chunk, *last_chunk;
	unsigned long chunk_addr;
	int missing_map, ret = 0;

	size = ALIGN(size, MIN_ALLOC);

	hyp_spin_lock(&allocator->lock);

	if (list_empty(&hyp_allocator.chunks)) {
		ret = setup_first_chunk(allocator, size);
		if (ret)
			goto end;

		chunk = (struct chunk_hdr *)allocator->start;
		goto end;
	}

	chunk = get_free_chunk(allocator, size);
	if (chunk) {
		ret = chunk_recycle(chunk, size, allocator);
		goto end;
	}

	last_chunk = chunk_get(list_last_entry(&allocator->chunks, struct chunk_hdr, node));

	chunk_addr = (unsigned long)last_chunk + chunk_size(last_chunk->alloc_size);
	chunk_addr = chunk_addr_fixup(chunk_addr);
	chunk = (struct chunk_hdr *)chunk_addr;

	missing_map = chunk_needs_mapping(last_chunk,
					  chunk_addr + chunk_size(size) -
						(unsigned long)chunk_data(last_chunk));
	if (missing_map) {
		ret = chunk_inc_map(last_chunk, missing_map, allocator);
		if (ret)
			goto end;
	}

	WARN_ON(chunk_install(chunk, size, last_chunk, allocator));
end:
	hyp_spin_unlock(&allocator->lock);

	allocator->errno[hyp_smp_processor_id()] = (u8)(-ret);

	return ret ? NULL : chunk_data(chunk);
}

static void *hyp_allocator_zalloc(struct hyp_allocator *allocator, size_t size)
{
	void *ptr = hyp_allocator_alloc(allocator, size);

	if (ptr)
		memset(ptr, 0, size);

	return ptr;
}

static void hyp_allocator_free(struct hyp_allocator *allocator, void *addr)
{
	struct chunk_hdr *chunk, *prev_chunk, *next_chunk;
	char *chunk_data = (char *)addr;

	hyp_spin_lock(&allocator->lock);

	chunk = chunk_get(container_of(chunk_data, struct chunk_hdr, data));
	prev_chunk = chunk_get_prev(chunk, allocator);
	next_chunk = chunk_get_next(chunk, allocator);

	chunk->alloc_size = 0;
	chunk_hash_update(chunk);

	if (next_chunk && !chunk_is_used(next_chunk))
		WARN_ON(chunk_merge(next_chunk, allocator));

	if (prev_chunk && !chunk_is_used(prev_chunk))
		WARN_ON(chunk_merge(chunk, allocator));

	hyp_spin_unlock(&allocator->lock);
}

static bool chunk_destroyable(struct chunk_hdr *chunk,
			      struct hyp_allocator *allocator)
{
	if (chunk_is_used(chunk))
		return false;

	if (!PAGE_ALIGNED(chunk))
		return false;

	if (list_is_first(&chunk->node, &allocator->chunks)) {
		if (list_is_last(&chunk->node, &allocator->chunks))
			return true;

		return false;
	}

	return !chunk_is_used(chunk_get_prev(chunk, allocator));
}

static size_t chunk_reclaimable(struct chunk_hdr *chunk,
				struct hyp_allocator *allocator)
{
	unsigned long start, end = chunk_unmapped_region(chunk);

	/*
	 * This should not happen, chunks are installed at a minimum distance
	 * from the page start
	 */
	WARN_ON(!PAGE_ALIGNED(end) &&
		(end - PAGE_ALIGN_DOWN(end) < chunk_size(0UL)));

	if (chunk_destroyable(chunk, allocator))
		start = (unsigned long)chunk;
	else
		start = PAGE_ALIGN((unsigned long)chunk + chunk_size(chunk->alloc_size));

	end = PAGE_ALIGN_DOWN(end);
	if (start > end)
		return 0;

	return end - start;
}

static int hyp_allocator_reclaimable(struct hyp_allocator *allocator)
{
	struct chunk_hdr *chunk;
	int reclaimable = 0;
	int cpu;

	hyp_spin_lock(&allocator->lock);

	/*
	 * This is slightly pessimistic: a real reclaim might be able to "fix"
	 * discontiguous unmapped region by deleting chunks from the top to the
	 * bottom.
	 */
	list_for_each_entry(chunk, &allocator->chunks, node)
		reclaimable += chunk_reclaimable(chunk, allocator) >> PAGE_SHIFT;

	for (cpu = 0; cpu < NR_CPUS; cpu++)
		reclaimable += allocator->mc[cpu].nr_pages;

	hyp_spin_unlock(&allocator->lock);

	return reclaimable;
}

static void hyp_allocator_reclaim(struct hyp_allocator *allocator,
				  struct kvm_hyp_memcache *mc,
				  int target)
{
	struct kvm_hyp_memcache *alloc_mc;
	struct chunk_hdr *chunk, *tmp;
	int cpu;

	if (target <= 0)
		return;

	hyp_spin_lock(&allocator->lock);

	/* Start emptying potential unused memcache */
	for (cpu = 0; cpu < NR_CPUS; cpu++) {
		alloc_mc = &allocator->mc[cpu];

		while (alloc_mc->nr_pages) {
			void *page = pop_hyp_memcache(alloc_mc, hyp_phys_to_virt);

			push_hyp_memcache(mc, page, hyp_virt_to_phys);
			WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(page), 1));

			target--;
			if (target <= 0)
				goto done;
		}
	}

	list_for_each_entry_safe_reverse(chunk, tmp, &allocator->chunks, node) {
		size_t r;

		chunk_hash_validate(chunk);
		r = chunk_try_destroy(chunk, allocator, target << PAGE_SHIFT);
		if (!r)
			r = chunk_dec_map(chunk, allocator, target << PAGE_SHIFT);

		target -= r >> PAGE_SHIFT;
		if (target <= 0)
			break;
	}

	alloc_mc = &allocator->mc[hyp_smp_processor_id()];
	while (alloc_mc->nr_pages) {
		void *page = pop_hyp_memcache(alloc_mc, hyp_phys_to_virt);

		memset(page, 0, PAGE_SIZE);
		push_hyp_memcache(mc, page, hyp_virt_to_phys);
		WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(page), 1));
	}
done:
	hyp_spin_unlock(&allocator->lock);
}

static int hyp_allocator_refill(struct hyp_allocator *allocator,
				struct kvm_hyp_memcache *host_mc)
{
	struct kvm_hyp_memcache *alloc_mc = &allocator->mc[hyp_smp_processor_id()];

	return refill_memcache(alloc_mc, host_mc->nr_pages + alloc_mc->nr_pages,
			       host_mc);
}

static int hyp_allocator_init(struct hyp_allocator *allocator, size_t size)
{
	int cpu, ret;

	/* constrained by chunk_hdr *_size types */
	if (size > U32_MAX)
		return -EINVAL;

	ret = pkvm_alloc_private_va_range(size, &allocator->start);
	if (ret)
		return ret;

	allocator->size = PAGE_ALIGN(size);
	INIT_LIST_HEAD(&allocator->chunks);
	for (cpu = 0; cpu < NR_CPUS; cpu++)
		allocator->mc[cpu].nr_pages = 0;
	hyp_spin_lock_init(&allocator->lock);

	return 0;
}

static size_t hyp_allocator_alloc_size(struct hyp_allocator *allocator,
				       void *addr)
{
	char *chunk_data = (char *)addr;
	struct chunk_hdr *chunk;

	chunk = chunk_get(container_of(chunk_data, struct chunk_hdr, data));

	return chunk->alloc_size;
}

static u8 hyp_allocator_missing_donations(struct hyp_allocator *allocator)
{
	return allocator->missing_donations[hyp_smp_processor_id()];
}

void hyp_free(void *addr)
{
	hyp_allocator_free(&hyp_allocator, addr);
}

void *hyp_alloc(size_t size)
{
	return hyp_allocator_alloc(&hyp_allocator, size);
}

void *hyp_zalloc(size_t size)
{
	return hyp_allocator_zalloc(&hyp_allocator, size);
}

int hyp_alloc_errno(void)
{
	return -((int)hyp_allocator.errno[hyp_smp_processor_id()]);
}

int hyp_alloc_refill(struct kvm_hyp_memcache *host_mc)
{
	return hyp_allocator_refill(&hyp_allocator, host_mc);
}

int hyp_alloc_reclaimable(void)
{
	return hyp_allocator_reclaimable(&hyp_allocator);
}

void hyp_alloc_reclaim(struct kvm_hyp_memcache *mc, int target)
{
	hyp_allocator_reclaim(&hyp_allocator, mc, target);
}

int hyp_alloc_init(size_t size)
{
	return hyp_allocator_init(&hyp_allocator, size);
}

size_t hyp_alloc_size(void *addr)
{
	return hyp_allocator_alloc_size(&hyp_allocator, addr);
}

u8 hyp_alloc_missing_donations(void)
{
	return hyp_allocator_missing_donations(&hyp_allocator);
}

struct hyp_allocator_chunk_dump {
	unsigned long	addr;
	unsigned long   alloc_start;
	size_t		alloc_size;
	size_t		unmapped_size;
	size_t 		mapped_size;
	u32		hash;
};

void dump_hyp_allocator(unsigned long host_va)
{
	struct hyp_allocator *allocator = &hyp_allocator;
	struct hyp_allocator_chunk_dump *chunk_dump;
	void *share = (void *)kern_hyp_va(host_va);
	struct chunk_hdr *chunk;

	WARN_ON(__pkvm_host_donate_hyp(hyp_virt_to_pfn(share), 1));

	chunk_dump = (struct hyp_allocator_chunk_dump *)share;

	hyp_spin_lock(&allocator->lock);

	list_for_each_entry(chunk, &allocator->chunks, node) {
		chunk_dump->addr = (unsigned long)chunk;
		chunk_dump->alloc_start = (unsigned long)chunk_data(chunk);
		chunk_dump->alloc_size = chunk->alloc_size;
		chunk_dump->unmapped_size = chunk_unmapped_size(chunk, allocator);
		chunk_dump->mapped_size = chunk->mapped_size;
		chunk_dump->hash = chunk->hash;
		chunk_dump++;
	}

	chunk_dump->addr = 0;

	hyp_spin_unlock(&allocator->lock);

	WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(share), 1));
}
