/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES
 */
#include "kunit_iommu.h"
#include "pt_iter.h"
#include <linux/generic_pt/iommu.h>
#include <linux/iommu.h>

static void do_map(struct kunit *test, pt_vaddr_t va, pt_oaddr_t pa,
		   pt_vaddr_t len);

struct count_valids {
	u64 per_size[PT_VADDR_MAX_LG2];
};

static int __count_valids(struct pt_range *range, void *arg, unsigned int level,
			  struct pt_table_p *table)
{
	struct pt_state pts = pt_init(range, level, table);
	struct count_valids *valids = arg;

	for_each_pt_level_entry(&pts) {
		if (pts.type == PT_ENTRY_TABLE) {
			pt_descend(&pts, arg, __count_valids);
			continue;
		}
		if (pts.type == PT_ENTRY_OA) {
			valids->per_size[pt_entry_oa_lg2sz(&pts)]++;
			continue;
		}
	}
	return 0;
}

/*
 * Number of valid table entries. This counts contiguous entries as a single
 * valid.
 */
static unsigned int count_valids(struct kunit *test)
{
	struct kunit_iommu_priv *priv = test->priv;
	struct pt_range range = pt_top_range(priv->common);
	struct count_valids valids = {};
	u64 total = 0;
	unsigned int i;

	KUNIT_ASSERT_NO_ERRNO(test,
			      pt_walk_range(&range, __count_valids, &valids));

	for (i = 0; i != ARRAY_SIZE(valids.per_size); i++)
		total += valids.per_size[i];
	return total;
}

/* Only a single page size is present, count the number of valid entries */
static unsigned int count_valids_single(struct kunit *test, pt_vaddr_t pgsz)
{
	struct kunit_iommu_priv *priv = test->priv;
	struct pt_range range = pt_top_range(priv->common);
	struct count_valids valids = {};
	u64 total = 0;
	unsigned int i;

	KUNIT_ASSERT_NO_ERRNO(test,
			      pt_walk_range(&range, __count_valids, &valids));

	for (i = 0; i != ARRAY_SIZE(valids.per_size); i++) {
		if ((1ULL << i) == pgsz)
			total = valids.per_size[i];
		else
			KUNIT_ASSERT_EQ(test, valids.per_size[i], 0);
	}
	return total;
}

static void do_unmap(struct kunit *test, pt_vaddr_t va, pt_vaddr_t len)
{
	struct kunit_iommu_priv *priv = test->priv;
	size_t ret;

	ret = iommu_unmap(&priv->domain, va, len);
	KUNIT_ASSERT_EQ(test, ret, len);
}

static void check_iova(struct kunit *test, pt_vaddr_t va, pt_oaddr_t pa,
		       pt_vaddr_t len)
{
	struct kunit_iommu_priv *priv = test->priv;
	pt_vaddr_t pfn = log2_div(va, priv->smallest_pgsz_lg2);
	pt_vaddr_t end_pfn = pfn + log2_div(len, priv->smallest_pgsz_lg2);

	for (; pfn != end_pfn; pfn++) {
		phys_addr_t res = iommu_iova_to_phys(&priv->domain,
						     pfn * priv->smallest_pgsz);

		KUNIT_ASSERT_EQ(test, res, (phys_addr_t)pa);
		if (res != pa)
			break;
		pa += priv->smallest_pgsz;
	}
}

static void test_increase_level(struct kunit *test)
{
	struct kunit_iommu_priv *priv = test->priv;
	struct pt_common *common = priv->common;

	if (!pt_feature(common, PT_FEAT_DYNAMIC_TOP))
		kunit_skip(test, "PT_FEAT_DYNAMIC_TOP not set for this format");

	if (IS_32BIT)
		kunit_skip(test, "Unable to test on 32bit");

	if (common->max_vasz_lg2 <= pt_top_range(common).max_vasz_lg2)
		kunit_skip(test,
			   "max_vasz_lg2 fits in starting level, no growth possible");

	/* Add every possible level to the max */
	while (common->max_vasz_lg2 != pt_top_range(common).max_vasz_lg2) {
		struct pt_range top_range = pt_top_range(common);

		if (top_range.va == 0)
			do_map(test, top_range.last_va + 1, 0,
			       priv->smallest_pgsz);
		else
			do_map(test, top_range.va - priv->smallest_pgsz, 0,
			       priv->smallest_pgsz);

		KUNIT_ASSERT_EQ(test, pt_top_range(common).top_level,
				top_range.top_level + 1);
		KUNIT_ASSERT_GE(test, common->max_vasz_lg2,
				pt_top_range(common).max_vasz_lg2);
	}
}

static void test_map_simple(struct kunit *test)
{
	struct kunit_iommu_priv *priv = test->priv;
	struct pt_range range = pt_top_range(priv->common);
	struct count_valids valids = {};
	pt_vaddr_t pgsize_bitmap = priv->safe_pgsize_bitmap;
	unsigned int pgsz_lg2;
	pt_vaddr_t cur_va;

	/* Map every reported page size */
	cur_va = range.va + priv->smallest_pgsz * 256;
	for (pgsz_lg2 = 0; pgsz_lg2 != PT_VADDR_MAX_LG2; pgsz_lg2++) {
		pt_oaddr_t paddr = log2_set_mod(priv->test_oa, 0, pgsz_lg2);
		u64 len = log2_to_int(pgsz_lg2);

		if (!(pgsize_bitmap & len))
			continue;

		cur_va = ALIGN(cur_va, len);
		do_map(test, cur_va, paddr, len);
		if (len <= SZ_2G)
			check_iova(test, cur_va, paddr, len);
		cur_va += len;
	}

	/* The read interface reports that every page size was created */
	range = pt_top_range(priv->common);
	KUNIT_ASSERT_NO_ERRNO(test,
			      pt_walk_range(&range, __count_valids, &valids));
	for (pgsz_lg2 = 0; pgsz_lg2 != PT_VADDR_MAX_LG2; pgsz_lg2++) {
		if (pgsize_bitmap & (1ULL << pgsz_lg2))
			KUNIT_ASSERT_EQ(test, valids.per_size[pgsz_lg2], 1);
		else
			KUNIT_ASSERT_EQ(test, valids.per_size[pgsz_lg2], 0);
	}

	/* Unmap works */
	range = pt_top_range(priv->common);
	cur_va = range.va + priv->smallest_pgsz * 256;
	for (pgsz_lg2 = 0; pgsz_lg2 != PT_VADDR_MAX_LG2; pgsz_lg2++) {
		u64 len = log2_to_int(pgsz_lg2);

		if (!(pgsize_bitmap & len))
			continue;
		cur_va = ALIGN(cur_va, len);
		do_unmap(test, cur_va, len);
		cur_va += len;
	}
	KUNIT_ASSERT_EQ(test, count_valids(test), 0);
}

/*
 * Test to convert a table pointer into an OA by mapping something small,
 * unmapping it so as to leave behind a table pointer, then mapping something
 * larger that will convert the table into an OA.
 */
static void test_map_table_to_oa(struct kunit *test)
{
	struct kunit_iommu_priv *priv = test->priv;
	pt_vaddr_t limited_pgbitmap =
		priv->info.pgsize_bitmap % (IS_32BIT ? SZ_2G : SZ_16G);
	struct pt_range range = pt_top_range(priv->common);
	unsigned int pgsz_lg2;
	pt_vaddr_t max_pgsize;
	pt_vaddr_t cur_va;

	max_pgsize = 1ULL << (vafls(limited_pgbitmap) - 1);
	KUNIT_ASSERT_TRUE(test, priv->info.pgsize_bitmap & max_pgsize);

	for (pgsz_lg2 = 0; pgsz_lg2 != PT_VADDR_MAX_LG2; pgsz_lg2++) {
		pt_oaddr_t paddr = log2_set_mod(priv->test_oa, 0, pgsz_lg2);
		u64 len = log2_to_int(pgsz_lg2);
		pt_vaddr_t offset;

		if (!(priv->info.pgsize_bitmap & len))
			continue;
		if (len > max_pgsize)
			break;

		cur_va = ALIGN(range.va + priv->smallest_pgsz * 256,
			       max_pgsize);
		for (offset = 0; offset != max_pgsize; offset += len)
			do_map(test, cur_va + offset, paddr + offset, len);
		check_iova(test, cur_va, paddr, max_pgsize);
		KUNIT_ASSERT_EQ(test, count_valids_single(test, len),
				log2_div(max_pgsize, pgsz_lg2));

		if (len == max_pgsize) {
			do_unmap(test, cur_va, max_pgsize);
		} else {
			do_unmap(test, cur_va, max_pgsize / 2);
			for (offset = max_pgsize / 2; offset != max_pgsize;
			     offset += len)
				do_unmap(test, cur_va + offset, len);
		}

		KUNIT_ASSERT_EQ(test, count_valids(test), 0);
	}
}

/*
 * Test unmapping a small page at the start of a large page. This always unmaps
 * the large page.
 */
static void test_unmap_split(struct kunit *test)
{
	struct kunit_iommu_priv *priv = test->priv;
	struct pt_range top_range = pt_top_range(priv->common);
	pt_vaddr_t pgsize_bitmap = priv->safe_pgsize_bitmap;
	unsigned int pgsz_lg2;
	unsigned int count = 0;

	for (pgsz_lg2 = 0; pgsz_lg2 != PT_VADDR_MAX_LG2; pgsz_lg2++) {
		pt_vaddr_t base_len = log2_to_int(pgsz_lg2);
		unsigned int next_pgsz_lg2;

		if (!(pgsize_bitmap & base_len))
			continue;

		for (next_pgsz_lg2 = pgsz_lg2 + 1;
		     next_pgsz_lg2 != PT_VADDR_MAX_LG2; next_pgsz_lg2++) {
			pt_vaddr_t next_len = log2_to_int(next_pgsz_lg2);
			pt_vaddr_t vaddr = top_range.va;
			pt_oaddr_t paddr = 0;
			size_t gnmapped;

			if (!(pgsize_bitmap & next_len))
				continue;

			do_map(test, vaddr, paddr, next_len);
			gnmapped = iommu_unmap(&priv->domain, vaddr, base_len);
			KUNIT_ASSERT_EQ(test, gnmapped, next_len);

			/* Make sure unmap doesn't keep going */
			do_map(test, vaddr, paddr, next_len);
			do_map(test, vaddr + next_len, paddr, next_len);
			gnmapped = iommu_unmap(&priv->domain, vaddr, base_len);
			KUNIT_ASSERT_EQ(test, gnmapped, next_len);
			gnmapped = iommu_unmap(&priv->domain, vaddr + next_len,
					       next_len);
			KUNIT_ASSERT_EQ(test, gnmapped, next_len);

			count++;
		}
	}

	if (count == 0)
		kunit_skip(test, "Test needs two page sizes");
}

static void unmap_collisions(struct kunit *test, struct maple_tree *mt,
			     pt_vaddr_t start, pt_vaddr_t last)
{
	struct kunit_iommu_priv *priv = test->priv;
	MA_STATE(mas, mt, start, last);
	void *entry;

	mtree_lock(mt);
	mas_for_each(&mas, entry, last) {
		pt_vaddr_t mas_start = mas.index;
		pt_vaddr_t len = (mas.last - mas_start) + 1;
		pt_oaddr_t paddr;

		mas_erase(&mas);
		mas_pause(&mas);
		mtree_unlock(mt);

		paddr = oalog2_mod(mas_start, priv->common->max_oasz_lg2);
		check_iova(test, mas_start, paddr, len);
		do_unmap(test, mas_start, len);
		mtree_lock(mt);
	}
	mtree_unlock(mt);
}

static void clamp_range(struct kunit *test, struct pt_range *range)
{
	struct kunit_iommu_priv *priv = test->priv;

	if (range->last_va - range->va > SZ_1G)
		range->last_va = range->va + SZ_1G;
	KUNIT_ASSERT_NE(test, range->last_va, PT_VADDR_MAX);
	if (range->va <= MAPLE_RESERVED_RANGE)
		range->va =
			ALIGN(MAPLE_RESERVED_RANGE, priv->smallest_pgsz);
}

/*
 * Randomly map and unmap ranges that can large physical pages. If a random
 * range overlaps with existing ranges then unmap them. This hits all the
 * special cases.
 */
static void test_random_map(struct kunit *test)
{
	struct kunit_iommu_priv *priv = test->priv;
	struct pt_range upper_range = pt_upper_range(priv->common);
	struct pt_range top_range = pt_top_range(priv->common);
	struct maple_tree mt;
	unsigned int iter;

	mt_init(&mt);

	/*
	 * Shrink the range so randomization is more likely to have
	 * intersections
	 */
	clamp_range(test, &top_range);
	clamp_range(test, &upper_range);

	for (iter = 0; iter != 1000; iter++) {
		struct pt_range *range = &top_range;
		pt_oaddr_t paddr;
		pt_vaddr_t start;
		pt_vaddr_t end;
		int ret;

		if (pt_feature(priv->common, PT_FEAT_SIGN_EXTEND) &&
		    ULONG_MAX >= PT_VADDR_MAX && get_random_u32_inclusive(0, 1))
			range = &upper_range;

		start = get_random_u32_below(
			min(U32_MAX, range->last_va - range->va));
		end = get_random_u32_below(
			min(U32_MAX, range->last_va - start));

		start = ALIGN_DOWN(start, priv->smallest_pgsz);
		end = ALIGN(end, priv->smallest_pgsz);
		start += range->va;
		end += start;
		if (start < range->va || end > range->last_va + 1 ||
		    start >= end)
			continue;

		/* Try overmapping to test the failure handling */
		paddr = oalog2_mod(start, priv->common->max_oasz_lg2);
		ret = iommu_map(&priv->domain, start, paddr, end - start,
				IOMMU_READ | IOMMU_WRITE, GFP_KERNEL);
		if (ret) {
			KUNIT_ASSERT_EQ(test, ret, -EADDRINUSE);
			unmap_collisions(test, &mt, start, end - 1);
			do_map(test, start, paddr, end - start);
		}

		KUNIT_ASSERT_NO_ERRNO_FN(test, "mtree_insert_range",
					 mtree_insert_range(&mt, start, end - 1,
							    XA_ZERO_ENTRY,
							    GFP_KERNEL));

		check_iova(test, start, paddr, end - start);
		if (iter % 100)
			cond_resched();
	}

	unmap_collisions(test, &mt, 0, PT_VADDR_MAX);
	KUNIT_ASSERT_EQ(test, count_valids(test), 0);

	mtree_destroy(&mt);
}

/* See https://lore.kernel.org/r/b9b18a03-63a2-4065-a27e-d92dd5c860bc@amd.com */
static void test_pgsize_boundary(struct kunit *test)
{
	struct kunit_iommu_priv *priv = test->priv;
	struct pt_range top_range = pt_top_range(priv->common);

	if (top_range.va != 0 || top_range.last_va < 0xfef9ffff ||
	    priv->smallest_pgsz != SZ_4K)
		kunit_skip(test, "Format does not have the required range");

	do_map(test, 0xfef80000, 0x208b95d000, 0xfef9ffff - 0xfef80000 + 1);
}

/* See https://lore.kernel.org/r/20250826143816.38686-1-eugkoira@amazon.com */
static void test_mixed(struct kunit *test)
{
	struct kunit_iommu_priv *priv = test->priv;
	struct pt_range top_range = pt_top_range(priv->common);
	u64 start = 0x3fe400ULL << 12;
	u64 end = 0x4c0600ULL << 12;
	pt_vaddr_t len = end - start;
	pt_oaddr_t oa = start;

	if (top_range.last_va <= start || sizeof(unsigned long) == 4)
		kunit_skip(test, "range is too small");
	if ((priv->safe_pgsize_bitmap & GENMASK(30, 21)) != (BIT(30) | BIT(21)))
		kunit_skip(test, "incompatible psize");

	do_map(test, start, oa, len);
	/* 14 2M, 3 1G, 3 2M */
	KUNIT_ASSERT_EQ(test, count_valids(test), 20);
	check_iova(test, start, oa, len);
}

static struct kunit_case iommu_test_cases[] = {
	KUNIT_CASE_FMT(test_increase_level),
	KUNIT_CASE_FMT(test_map_simple),
	KUNIT_CASE_FMT(test_map_table_to_oa),
	KUNIT_CASE_FMT(test_unmap_split),
	KUNIT_CASE_FMT(test_random_map),
	KUNIT_CASE_FMT(test_pgsize_boundary),
	KUNIT_CASE_FMT(test_mixed),
	{},
};

static int pt_kunit_iommu_init(struct kunit *test)
{
	struct kunit_iommu_priv *priv;
	int ret;

	priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->orig_nr_secondary_pagetable =
		global_node_page_state(NR_SECONDARY_PAGETABLE);
	ret = pt_kunit_priv_init(test, priv);
	if (ret) {
		kunit_kfree(test, priv);
		return ret;
	}
	test->priv = priv;
	return 0;
}

static void pt_kunit_iommu_exit(struct kunit *test)
{
	struct kunit_iommu_priv *priv = test->priv;

	if (!test->priv)
		return;

	pt_iommu_deinit(priv->iommu);
	/*
	 * Look for memory leaks, assumes kunit is running isolated and nothing
	 * else is using secondary page tables.
	 */
	KUNIT_ASSERT_EQ(test, priv->orig_nr_secondary_pagetable,
			global_node_page_state(NR_SECONDARY_PAGETABLE));
	kunit_kfree(test, test->priv);
}

static struct kunit_suite NS(iommu_suite) = {
	.name = __stringify(NS(iommu_test)),
	.init = pt_kunit_iommu_init,
	.exit = pt_kunit_iommu_exit,
	.test_cases = iommu_test_cases,
};
kunit_test_suites(&NS(iommu_suite));

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Kunit for generic page table");
MODULE_IMPORT_NS("GENERIC_PT_IOMMU");
