/*
 * Copyright © 2016 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 */

#include <linux/prime_numbers.h>

#include "gem/i915_gem_context.h"
#include "gem/i915_gem_internal.h"
#include "gem/selftests/mock_context.h"

#include "i915_scatterlist.h"
#include "i915_selftest.h"

#include "mock_gem_device.h"
#include "mock_gtt.h"

static bool assert_vma(struct i915_vma *vma,
		       struct drm_i915_gem_object *obj,
		       struct i915_gem_context *ctx)
{
	bool ok = true;

	if (vma->vm != ctx->vm) {
		pr_err("VMA created with wrong VM\n");
		ok = false;
	}

	if (vma->size != obj->base.size) {
		pr_err("VMA created with wrong size, found %llu, expected %zu\n",
		       vma->size, obj->base.size);
		ok = false;
	}

	if (vma->gtt_view.type != I915_GTT_VIEW_NORMAL) {
		pr_err("VMA created with wrong type [%d]\n",
		       vma->gtt_view.type);
		ok = false;
	}

	return ok;
}

static struct i915_vma *
checked_vma_instance(struct drm_i915_gem_object *obj,
		     struct i915_address_space *vm,
		     const struct i915_gtt_view *view)
{
	struct i915_vma *vma;
	bool ok = true;

	vma = i915_vma_instance(obj, vm, view);
	if (IS_ERR(vma))
		return vma;

	/* Manual checks, will be reinforced by i915_vma_compare! */
	if (vma->vm != vm) {
		pr_err("VMA's vm [%p] does not match request [%p]\n",
		       vma->vm, vm);
		ok = false;
	}

	if (i915_is_ggtt(vm) != i915_vma_is_ggtt(vma)) {
		pr_err("VMA ggtt status [%d] does not match parent [%d]\n",
		       i915_vma_is_ggtt(vma), i915_is_ggtt(vm));
		ok = false;
	}

	if (i915_vma_compare(vma, vm, view)) {
		pr_err("i915_vma_compare failed with create parameters!\n");
		return ERR_PTR(-EINVAL);
	}

	if (i915_vma_compare(vma, vma->vm,
			     i915_vma_is_ggtt(vma) ? &vma->gtt_view : NULL)) {
		pr_err("i915_vma_compare failed with itself\n");
		return ERR_PTR(-EINVAL);
	}

	if (!ok) {
		pr_err("i915_vma_compare failed to detect the difference!\n");
		return ERR_PTR(-EINVAL);
	}

	return vma;
}

static int create_vmas(struct drm_i915_private *i915,
		       struct list_head *objects,
		       struct list_head *contexts)
{
	struct drm_i915_gem_object *obj;
	struct i915_gem_context *ctx;
	int pinned;

	list_for_each_entry(obj, objects, st_link) {
		for (pinned = 0; pinned <= 1; pinned++) {
			list_for_each_entry(ctx, contexts, link) {
				struct i915_address_space *vm;
				struct i915_vma *vma;
				int err;

				vm = i915_gem_context_get_eb_vm(ctx);
				vma = checked_vma_instance(obj, vm, NULL);
				i915_vm_put(vm);
				if (IS_ERR(vma))
					return PTR_ERR(vma);

				if (!assert_vma(vma, obj, ctx)) {
					pr_err("VMA lookup/create failed\n");
					return -EINVAL;
				}

				if (!pinned) {
					err = i915_vma_pin(vma, 0, 0, PIN_USER);
					if (err) {
						pr_err("Failed to pin VMA\n");
						return err;
					}
				} else {
					i915_vma_unpin(vma);
				}
			}
		}
	}

	return 0;
}

static int igt_vma_create(void *arg)
{
	struct i915_ggtt *ggtt = arg;
	struct drm_i915_private *i915 = ggtt->vm.i915;
	struct drm_i915_gem_object *obj, *on;
	struct i915_gem_context *ctx, *cn;
	unsigned long num_obj, num_ctx;
	unsigned long no, nc;
	IGT_TIMEOUT(end_time);
	LIST_HEAD(contexts);
	LIST_HEAD(objects);
	int err = -ENOMEM;

	/*
	 * Exercise creating many vma amongst many objections, checking the
	 * vma creation and lookup routines.
	 */

	no = 0;
	for_each_prime_number(num_obj, ULONG_MAX - 1) {
		for (; no < num_obj; no++) {
			obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
			if (IS_ERR(obj))
				goto out;

			list_add(&obj->st_link, &objects);
		}

		nc = 0;
		for_each_prime_number(num_ctx, 2 * BITS_PER_LONG) {
			for (; nc < num_ctx; nc++) {
				ctx = mock_context(i915, "mock");
				if (!ctx)
					goto out;

				list_move(&ctx->link, &contexts);
			}

			err = create_vmas(i915, &objects, &contexts);
			if (err)
				goto out;

			if (igt_timeout(end_time,
					"%s timed out: after %lu objects in %lu contexts\n",
					__func__, no, nc))
				goto end;
		}

		list_for_each_entry_safe(ctx, cn, &contexts, link) {
			list_del_init(&ctx->link);
			mock_context_close(ctx);
		}

		cond_resched();
	}

end:
	/* Final pass to lookup all created contexts */
	err = create_vmas(i915, &objects, &contexts);
out:
	list_for_each_entry_safe(ctx, cn, &contexts, link) {
		list_del_init(&ctx->link);
		mock_context_close(ctx);
	}

	list_for_each_entry_safe(obj, on, &objects, st_link)
		i915_gem_object_put(obj);
	return err;
}

struct pin_mode {
	u64 size;
	u64 flags;
	bool (*assert)(const struct i915_vma *,
		       const struct pin_mode *mode,
		       int result);
	const char *string;
};

static bool assert_pin_valid(const struct i915_vma *vma,
			     const struct pin_mode *mode,
			     int result)
{
	if (result)
		return false;

	if (i915_vma_misplaced(vma, mode->size, 0, mode->flags))
		return false;

	return true;
}

__maybe_unused
static bool assert_pin_enospc(const struct i915_vma *vma,
			      const struct pin_mode *mode,
			      int result)
{
	return result == -ENOSPC;
}

__maybe_unused
static bool assert_pin_einval(const struct i915_vma *vma,
			      const struct pin_mode *mode,
			      int result)
{
	return result == -EINVAL;
}

static int igt_vma_pin1(void *arg)
{
	struct i915_ggtt *ggtt = arg;
	const struct pin_mode modes[] = {
#define VALID(sz, fl) { .size = (sz), .flags = (fl), .assert = assert_pin_valid, .string = #sz ", " #fl ", (valid) " }
#define __INVALID(sz, fl, check, eval) { .size = (sz), .flags = (fl), .assert = (check), .string = #sz ", " #fl ", (invalid " #eval ")" }
#define INVALID(sz, fl) __INVALID(sz, fl, assert_pin_einval, EINVAL)
#define NOSPACE(sz, fl) __INVALID(sz, fl, assert_pin_enospc, ENOSPC)
		VALID(0, PIN_GLOBAL),
		VALID(0, PIN_GLOBAL | PIN_MAPPABLE),

		VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | 4096),
		VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | 8192),
		VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | (ggtt->mappable_end - 4096)),
		VALID(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_BIAS | (ggtt->mappable_end - 4096)),
		VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | (ggtt->vm.total - 4096)),

		VALID(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_FIXED | (ggtt->mappable_end - 4096)),
		INVALID(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_FIXED | ggtt->mappable_end),
		VALID(0, PIN_GLOBAL | PIN_OFFSET_FIXED | (ggtt->vm.total - 4096)),
		INVALID(0, PIN_GLOBAL | PIN_OFFSET_FIXED | ggtt->vm.total),
		INVALID(0, PIN_GLOBAL | PIN_OFFSET_FIXED | round_down(U64_MAX, PAGE_SIZE)),

		VALID(4096, PIN_GLOBAL),
		VALID(8192, PIN_GLOBAL),
		VALID(ggtt->mappable_end - 4096, PIN_GLOBAL | PIN_MAPPABLE),
		VALID(ggtt->mappable_end, PIN_GLOBAL | PIN_MAPPABLE),
		NOSPACE(ggtt->mappable_end + 4096, PIN_GLOBAL | PIN_MAPPABLE),
		VALID(ggtt->vm.total - 4096, PIN_GLOBAL),
		VALID(ggtt->vm.total, PIN_GLOBAL),
		NOSPACE(ggtt->vm.total + 4096, PIN_GLOBAL),
		NOSPACE(round_down(U64_MAX, PAGE_SIZE), PIN_GLOBAL),
		INVALID(8192, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_FIXED | (ggtt->mappable_end - 4096)),
		INVALID(8192, PIN_GLOBAL | PIN_OFFSET_FIXED | (ggtt->vm.total - 4096)),
		INVALID(8192, PIN_GLOBAL | PIN_OFFSET_FIXED | (round_down(U64_MAX, PAGE_SIZE) - 4096)),

		VALID(8192, PIN_GLOBAL | PIN_OFFSET_BIAS | (ggtt->mappable_end - 4096)),

#if !IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
		/*
		 * Misusing BIAS is a programming error (it is not controllable
		 * from userspace) so when debugging is enabled, it explodes.
		 * However, the tests are still quite interesting for checking
		 * variable start, end and size.
		 */
		NOSPACE(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_BIAS | ggtt->mappable_end),
		NOSPACE(0, PIN_GLOBAL | PIN_OFFSET_BIAS | ggtt->vm.total),
		NOSPACE(8192, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_BIAS | (ggtt->mappable_end - 4096)),
		NOSPACE(8192, PIN_GLOBAL | PIN_OFFSET_BIAS | (ggtt->vm.total - 4096)),
#endif
		{ },
#undef NOSPACE
#undef INVALID
#undef __INVALID
#undef VALID
	}, *m;
	struct drm_i915_gem_object *obj;
	struct i915_vma *vma;
	int err = -EINVAL;

	/*
	 * Exercise all the weird and wonderful i915_vma_pin requests,
	 * focusing on error handling of boundary conditions.
	 */

	GEM_BUG_ON(!drm_mm_clean(&ggtt->vm.mm));

	obj = i915_gem_object_create_internal(ggtt->vm.i915, PAGE_SIZE);
	if (IS_ERR(obj))
		return PTR_ERR(obj);

	vma = checked_vma_instance(obj, &ggtt->vm, NULL);
	if (IS_ERR(vma))
		goto out;

	for (m = modes; m->assert; m++) {
		err = i915_vma_pin(vma, m->size, 0, m->flags);
		if (!m->assert(vma, m, err)) {
			pr_err("%s to pin single page into GGTT with mode[%d:%s]: size=%llx flags=%llx, err=%d\n",
			       m->assert == assert_pin_valid ? "Failed" : "Unexpectedly succeeded",
			       (int)(m - modes), m->string, m->size, m->flags,
			       err);
			if (!err)
				i915_vma_unpin(vma);
			err = -EINVAL;
			goto out;
		}

		if (!err) {
			i915_vma_unpin(vma);
			err = i915_vma_unbind_unlocked(vma);
			if (err) {
				pr_err("Failed to unbind single page from GGTT, err=%d\n", err);
				goto out;
			}
		}

		cond_resched();
	}

	err = 0;
out:
	i915_gem_object_put(obj);
	return err;
}

static unsigned long rotated_index(const struct intel_rotation_info *r,
				   unsigned int n,
				   unsigned int x,
				   unsigned int y)
{
	return (r->plane[n].src_stride * (r->plane[n].height - y - 1) +
		r->plane[n].offset + x);
}

static struct scatterlist *
assert_rotated(struct drm_i915_gem_object *obj,
	       const struct intel_rotation_info *r, unsigned int n,
	       struct scatterlist *sg)
{
	unsigned int x, y;

	for (x = 0; x < r->plane[n].width; x++) {
		unsigned int left;

		for (y = 0; y < r->plane[n].height; y++) {
			unsigned long src_idx;
			dma_addr_t src;

			if (!sg) {
				pr_err("Invalid sg table: too short at plane %d, (%d, %d)!\n",
				       n, x, y);
				return ERR_PTR(-EINVAL);
			}

			src_idx = rotated_index(r, n, x, y);
			src = i915_gem_object_get_dma_address(obj, src_idx);

			if (sg_dma_len(sg) != PAGE_SIZE) {
				pr_err("Invalid sg.length, found %d, expected %lu for rotated page (%d, %d) [src index %lu]\n",
				       sg_dma_len(sg), PAGE_SIZE,
				       x, y, src_idx);
				return ERR_PTR(-EINVAL);
			}

			if (sg_dma_address(sg) != src) {
				pr_err("Invalid address for rotated page (%d, %d) [src index %lu]\n",
				       x, y, src_idx);
				return ERR_PTR(-EINVAL);
			}

			sg = sg_next(sg);
		}

		left = (r->plane[n].dst_stride - y) * PAGE_SIZE;

		if (!left)
			continue;

		if (!sg) {
			pr_err("Invalid sg table: too short at plane %d, (%d, %d)!\n",
			       n, x, y);
			return ERR_PTR(-EINVAL);
		}

		if (sg_dma_len(sg) != left) {
			pr_err("Invalid sg.length, found %d, expected %u for rotated page (%d, %d)\n",
			       sg_dma_len(sg), left, x, y);
			return ERR_PTR(-EINVAL);
		}

		if (sg_dma_address(sg) != 0) {
			pr_err("Invalid address, found %pad, expected 0 for remapped page (%d, %d)\n",
			       &sg_dma_address(sg), x, y);
			return ERR_PTR(-EINVAL);
		}

		sg = sg_next(sg);
	}

	return sg;
}

static unsigned long remapped_index(const struct intel_remapped_info *r,
				    unsigned int n,
				    unsigned int x,
				    unsigned int y)
{
	return (r->plane[n].src_stride * y +
		r->plane[n].offset + x);
}

static struct scatterlist *
assert_remapped(struct drm_i915_gem_object *obj,
		const struct intel_remapped_info *r, unsigned int n,
		struct scatterlist *sg)
{
	unsigned int x, y;
	unsigned int left = 0;
	unsigned int offset;

	for (y = 0; y < r->plane[n].height; y++) {
		for (x = 0; x < r->plane[n].width; x++) {
			unsigned long src_idx;
			dma_addr_t src;

			if (!sg) {
				pr_err("Invalid sg table: too short at plane %d, (%d, %d)!\n",
				       n, x, y);
				return ERR_PTR(-EINVAL);
			}
			if (!left) {
				offset = 0;
				left = sg_dma_len(sg);
			}

			src_idx = remapped_index(r, n, x, y);
			src = i915_gem_object_get_dma_address(obj, src_idx);

			if (left < PAGE_SIZE || left & (PAGE_SIZE-1)) {
				pr_err("Invalid sg.length, found %d, expected %lu for remapped page (%d, %d) [src index %lu]\n",
				       sg_dma_len(sg), PAGE_SIZE,
				       x, y, src_idx);
				return ERR_PTR(-EINVAL);
			}

			if (sg_dma_address(sg) + offset != src) {
				pr_err("Invalid address for remapped page (%d, %d) [src index %lu]\n",
				       x, y, src_idx);
				return ERR_PTR(-EINVAL);
			}

			left -= PAGE_SIZE;
			offset += PAGE_SIZE;


			if (!left)
				sg = sg_next(sg);
		}

		if (left) {
			pr_err("Unexpected sg tail with %d size for remapped page (%d, %d)\n",
			       left,
			       x, y);
			return ERR_PTR(-EINVAL);
		}

		left = (r->plane[n].dst_stride - r->plane[n].width) * PAGE_SIZE;

		if (!left)
			continue;

		if (!sg) {
			pr_err("Invalid sg table: too short at plane %d, (%d, %d)!\n",
			       n, x, y);
			return ERR_PTR(-EINVAL);
		}

		if (sg_dma_len(sg) != left) {
			pr_err("Invalid sg.length, found %u, expected %u for remapped page (%d, %d)\n",
			       sg_dma_len(sg), left,
			       x, y);
			return ERR_PTR(-EINVAL);
		}

		if (sg_dma_address(sg) != 0) {
			pr_err("Invalid address, found %pad, expected 0 for remapped page (%d, %d)\n",
			       &sg_dma_address(sg),
			       x, y);
			return ERR_PTR(-EINVAL);
		}

		sg = sg_next(sg);
		left = 0;
	}

	return sg;
}

static unsigned int remapped_size(enum i915_gtt_view_type view_type,
				  const struct intel_remapped_plane_info *a,
				  const struct intel_remapped_plane_info *b)
{

	if (view_type == I915_GTT_VIEW_ROTATED)
		return a->dst_stride * a->width + b->dst_stride * b->width;
	else
		return a->dst_stride * a->height + b->dst_stride * b->height;
}

static int igt_vma_rotate_remap(void *arg)
{
	struct i915_ggtt *ggtt = arg;
	struct i915_address_space *vm = &ggtt->vm;
	struct drm_i915_gem_object *obj;
	const struct intel_remapped_plane_info planes[] = {
		{ .width = 1, .height = 1, .src_stride = 1 },
		{ .width = 2, .height = 2, .src_stride = 2 },
		{ .width = 4, .height = 4, .src_stride = 4 },
		{ .width = 8, .height = 8, .src_stride = 8 },

		{ .width = 3, .height = 5, .src_stride = 3 },
		{ .width = 3, .height = 5, .src_stride = 4 },
		{ .width = 3, .height = 5, .src_stride = 5 },

		{ .width = 5, .height = 3, .src_stride = 5 },
		{ .width = 5, .height = 3, .src_stride = 7 },
		{ .width = 5, .height = 3, .src_stride = 9 },

		{ .width = 4, .height = 6, .src_stride = 6 },
		{ .width = 6, .height = 4, .src_stride = 6 },

		{ .width = 2, .height = 2, .src_stride = 2, .dst_stride = 2 },
		{ .width = 3, .height = 3, .src_stride = 3, .dst_stride = 4 },
		{ .width = 5, .height = 6, .src_stride = 7, .dst_stride = 8 },

		{ }
	}, *a, *b;
	enum i915_gtt_view_type types[] = {
		I915_GTT_VIEW_ROTATED,
		I915_GTT_VIEW_REMAPPED,
		0,
	}, *t;
	const unsigned int max_pages = 64;
	int err = -ENOMEM;

	/*
	 * Create VMA for many different combinations of planes and check
	 * that the page layout within the rotated VMA match our expectations.
	 */

	obj = i915_gem_object_create_internal(vm->i915, max_pages * PAGE_SIZE);
	if (IS_ERR(obj))
		goto out;

	for (t = types; *t; t++) {
	for (a = planes; a->width; a++) {
		for (b = planes + ARRAY_SIZE(planes); b-- != planes; ) {
			struct i915_gtt_view view = {
				.type = *t,
				.remapped.plane[0] = *a,
				.remapped.plane[1] = *b,
			};
			struct intel_remapped_plane_info *plane_info = view.remapped.plane;
			unsigned int n, max_offset;

			max_offset = max(plane_info[0].src_stride * plane_info[0].height,
					 plane_info[1].src_stride * plane_info[1].height);
			GEM_BUG_ON(max_offset > max_pages);
			max_offset = max_pages - max_offset;

			if (!plane_info[0].dst_stride)
				plane_info[0].dst_stride = view.type == I915_GTT_VIEW_ROTATED ?
									plane_info[0].height :
									plane_info[0].width;
			if (!plane_info[1].dst_stride)
				plane_info[1].dst_stride = view.type == I915_GTT_VIEW_ROTATED ?
									plane_info[1].height :
									plane_info[1].width;

			for_each_prime_number_from(plane_info[0].offset, 0, max_offset) {
				for_each_prime_number_from(plane_info[1].offset, 0, max_offset) {
					struct scatterlist *sg;
					struct i915_vma *vma;
					unsigned int expected_pages;

					vma = checked_vma_instance(obj, vm, &view);
					if (IS_ERR(vma)) {
						err = PTR_ERR(vma);
						goto out_object;
					}

					err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL);
					if (err) {
						pr_err("Failed to pin VMA, err=%d\n", err);
						goto out_object;
					}

					expected_pages = remapped_size(view.type, &plane_info[0], &plane_info[1]);

					if (view.type == I915_GTT_VIEW_ROTATED &&
					    vma->size != expected_pages * PAGE_SIZE) {
						pr_err("VMA is wrong size, expected %lu, found %llu\n",
						       PAGE_SIZE * expected_pages, vma->size);
						err = -EINVAL;
						goto out_object;
					}

					if (view.type == I915_GTT_VIEW_REMAPPED &&
					    vma->size > expected_pages * PAGE_SIZE) {
						pr_err("VMA is wrong size, expected %lu, found %llu\n",
						       PAGE_SIZE * expected_pages, vma->size);
						err = -EINVAL;
						goto out_object;
					}

					if (vma->pages->nents > expected_pages) {
						pr_err("sg table is wrong sizeo, expected %u, found %u nents\n",
						       expected_pages, vma->pages->nents);
						err = -EINVAL;
						goto out_object;
					}

					if (vma->node.size < vma->size) {
						pr_err("VMA binding too small, expected %llu, found %llu\n",
						       vma->size, vma->node.size);
						err = -EINVAL;
						goto out_object;
					}

					if (vma->pages == obj->mm.pages) {
						pr_err("VMA using unrotated object pages!\n");
						err = -EINVAL;
						goto out_object;
					}

					sg = vma->pages->sgl;
					for (n = 0; n < ARRAY_SIZE(view.rotated.plane); n++) {
						if (view.type == I915_GTT_VIEW_ROTATED)
							sg = assert_rotated(obj, &view.rotated, n, sg);
						else
							sg = assert_remapped(obj, &view.remapped, n, sg);
						if (IS_ERR(sg)) {
							pr_err("Inconsistent %s VMA pages for plane %d: [(%d, %d, %d, %d, %d), (%d, %d, %d, %d, %d)]\n",
							       view.type == I915_GTT_VIEW_ROTATED ?
							       "rotated" : "remapped", n,
							       plane_info[0].width,
							       plane_info[0].height,
							       plane_info[0].src_stride,
							       plane_info[0].dst_stride,
							       plane_info[0].offset,
							       plane_info[1].width,
							       plane_info[1].height,
							       plane_info[1].src_stride,
							       plane_info[1].dst_stride,
							       plane_info[1].offset);
							err = -EINVAL;
							goto out_object;
						}
					}

					i915_vma_unpin(vma);
					err = i915_vma_unbind_unlocked(vma);
					if (err) {
						pr_err("Unbinding returned %i\n", err);
						goto out_object;
					}
					cond_resched();
				}
			}
		}
	}
	}

out_object:
	i915_gem_object_put(obj);
out:
	return err;
}

static bool assert_partial(struct drm_i915_gem_object *obj,
			   struct i915_vma *vma,
			   unsigned long offset,
			   unsigned long size)
{
	struct sgt_iter sgt;
	dma_addr_t dma;

	for_each_sgt_daddr(dma, sgt, vma->pages) {
		dma_addr_t src;

		if (!size) {
			pr_err("Partial scattergather list too long\n");
			return false;
		}

		src = i915_gem_object_get_dma_address(obj, offset);
		if (src != dma) {
			pr_err("DMA mismatch for partial page offset %lu\n",
			       offset);
			return false;
		}

		offset++;
		size--;
	}

	return true;
}

static bool assert_pin(struct i915_vma *vma,
		       struct i915_gtt_view *view,
		       u64 size,
		       const char *name)
{
	bool ok = true;

	if (vma->size != size) {
		pr_err("(%s) VMA is wrong size, expected %llu, found %llu\n",
		       name, size, vma->size);
		ok = false;
	}

	if (vma->node.size < vma->size) {
		pr_err("(%s) VMA binding too small, expected %llu, found %llu\n",
		       name, vma->size, vma->node.size);
		ok = false;
	}

	if (view && view->type != I915_GTT_VIEW_NORMAL) {
		if (memcmp(&vma->gtt_view, view, sizeof(*view))) {
			pr_err("(%s) VMA mismatch upon creation!\n",
			       name);
			ok = false;
		}

		if (vma->pages == vma->obj->mm.pages) {
			pr_err("(%s) VMA using original object pages!\n",
			       name);
			ok = false;
		}
	} else {
		if (vma->gtt_view.type != I915_GTT_VIEW_NORMAL) {
			pr_err("Not the normal ggtt view! Found %d\n",
			       vma->gtt_view.type);
			ok = false;
		}

		if (vma->pages != vma->obj->mm.pages) {
			pr_err("VMA not using object pages!\n");
			ok = false;
		}
	}

	return ok;
}

static int igt_vma_partial(void *arg)
{
	struct i915_ggtt *ggtt = arg;
	struct i915_address_space *vm = &ggtt->vm;
	const unsigned int npages = 1021; /* prime! */
	struct drm_i915_gem_object *obj;
	const struct phase {
		const char *name;
	} phases[] = {
		{ "create" },
		{ "lookup" },
		{ },
	}, *p;
	unsigned int sz, offset;
	struct i915_vma *vma;
	int err = -ENOMEM;

	/*
	 * Create lots of different VMA for the object and check that
	 * we are returned the same VMA when we later request the same range.
	 */

	obj = i915_gem_object_create_internal(vm->i915, npages * PAGE_SIZE);
	if (IS_ERR(obj))
		goto out;

	for (p = phases; p->name; p++) { /* exercise both create/lookup */
		unsigned int count, nvma;

		nvma = 0;
		for_each_prime_number_from(sz, 1, npages) {
			for_each_prime_number_from(offset, 0, npages - sz) {
				struct i915_gtt_view view;

				view.type = I915_GTT_VIEW_PARTIAL;
				view.partial.offset = offset;
				view.partial.size = sz;

				if (sz == npages)
					view.type = I915_GTT_VIEW_NORMAL;

				vma = checked_vma_instance(obj, vm, &view);
				if (IS_ERR(vma)) {
					err = PTR_ERR(vma);
					goto out_object;
				}

				err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL);
				if (err)
					goto out_object;

				if (!assert_pin(vma, &view, sz*PAGE_SIZE, p->name)) {
					pr_err("(%s) Inconsistent partial pinning for (offset=%d, size=%d)\n",
					       p->name, offset, sz);
					err = -EINVAL;
					goto out_object;
				}

				if (!assert_partial(obj, vma, offset, sz)) {
					pr_err("(%s) Inconsistent partial pages for (offset=%d, size=%d)\n",
					       p->name, offset, sz);
					err = -EINVAL;
					goto out_object;
				}

				i915_vma_unpin(vma);
				nvma++;
				err = i915_vma_unbind_unlocked(vma);
				if (err) {
					pr_err("Unbinding returned %i\n", err);
					goto out_object;
				}

				cond_resched();
			}
		}

		count = 0;
		list_for_each_entry(vma, &obj->vma.list, obj_link)
			count++;
		if (count != nvma) {
			pr_err("(%s) All partial vma were not recorded on the obj->vma_list: found %u, expected %u\n",
			       p->name, count, nvma);
			err = -EINVAL;
			goto out_object;
		}

		/* Check that we did create the whole object mapping */
		vma = checked_vma_instance(obj, vm, NULL);
		if (IS_ERR(vma)) {
			err = PTR_ERR(vma);
			goto out_object;
		}

		err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL);
		if (err)
			goto out_object;

		if (!assert_pin(vma, NULL, obj->base.size, p->name)) {
			pr_err("(%s) inconsistent full pin\n", p->name);
			err = -EINVAL;
			goto out_object;
		}

		i915_vma_unpin(vma);

		err = i915_vma_unbind_unlocked(vma);
		if (err) {
			pr_err("Unbinding returned %i\n", err);
			goto out_object;
		}

		count = 0;
		list_for_each_entry(vma, &obj->vma.list, obj_link)
			count++;
		if (count != nvma) {
			pr_err("(%s) allocated an extra full vma!\n", p->name);
			err = -EINVAL;
			goto out_object;
		}
	}

out_object:
	i915_gem_object_put(obj);
out:
	return err;
}

int i915_vma_mock_selftests(void)
{
	static const struct i915_subtest tests[] = {
		SUBTEST(igt_vma_create),
		SUBTEST(igt_vma_pin1),
		SUBTEST(igt_vma_rotate_remap),
		SUBTEST(igt_vma_partial),
	};
	struct drm_i915_private *i915;
	struct intel_gt *gt;
	int err;

	i915 = mock_gem_device();
	if (!i915)
		return -ENOMEM;

	/* allocate the ggtt */
	err = intel_gt_assign_ggtt(to_gt(i915));
	if (err)
		goto out_put;

	gt = to_gt(i915);

	mock_init_ggtt(gt);

	err = i915_subtests(tests, gt->ggtt);

	mock_device_flush(i915);
	i915_gem_drain_freed_objects(i915);
	mock_fini_ggtt(gt->ggtt);

out_put:
	mock_destroy_device(i915);
	return err;
}

static int igt_vma_remapped_gtt(void *arg)
{
	struct drm_i915_private *i915 = arg;
	const struct intel_remapped_plane_info planes[] = {
		{ .width = 1, .height = 1, .src_stride = 1 },
		{ .width = 2, .height = 2, .src_stride = 2 },
		{ .width = 4, .height = 4, .src_stride = 4 },
		{ .width = 8, .height = 8, .src_stride = 8 },

		{ .width = 3, .height = 5, .src_stride = 3 },
		{ .width = 3, .height = 5, .src_stride = 4 },
		{ .width = 3, .height = 5, .src_stride = 5 },

		{ .width = 5, .height = 3, .src_stride = 5 },
		{ .width = 5, .height = 3, .src_stride = 7 },
		{ .width = 5, .height = 3, .src_stride = 9 },

		{ .width = 4, .height = 6, .src_stride = 6 },
		{ .width = 6, .height = 4, .src_stride = 6 },

		{ .width = 2, .height = 2, .src_stride = 2, .dst_stride = 2 },
		{ .width = 3, .height = 3, .src_stride = 3, .dst_stride = 4 },
		{ .width = 5, .height = 6, .src_stride = 7, .dst_stride = 8 },

		{ }
	}, *p;
	enum i915_gtt_view_type types[] = {
		I915_GTT_VIEW_ROTATED,
		I915_GTT_VIEW_REMAPPED,
		0,
	}, *t;
	struct drm_i915_gem_object *obj;
	intel_wakeref_t wakeref;
	int err = 0;

	if (!i915_ggtt_has_aperture(to_gt(i915)->ggtt))
		return 0;

	obj = i915_gem_object_create_internal(i915, 10 * 10 * PAGE_SIZE);
	if (IS_ERR(obj))
		return PTR_ERR(obj);

	wakeref = intel_runtime_pm_get(&i915->runtime_pm);

	for (t = types; *t; t++) {
		for (p = planes; p->width; p++) {
			struct i915_gtt_view view = {
				.type = *t,
				.rotated.plane[0] = *p,
			};
			struct intel_remapped_plane_info *plane_info = view.rotated.plane;
			struct i915_vma *vma;
			u32 __iomem *map;
			unsigned int x, y;

			i915_gem_object_lock(obj, NULL);
			err = i915_gem_object_set_to_gtt_domain(obj, true);
			i915_gem_object_unlock(obj);
			if (err)
				goto out;

			if (!plane_info[0].dst_stride)
				plane_info[0].dst_stride = *t == I915_GTT_VIEW_ROTATED ?
								 p->height : p->width;

			vma = i915_gem_object_ggtt_pin(obj, &view, 0, 0, PIN_MAPPABLE);
			if (IS_ERR(vma)) {
				err = PTR_ERR(vma);
				goto out;
			}

			GEM_BUG_ON(vma->gtt_view.type != *t);

			map = i915_vma_pin_iomap(vma);
			i915_vma_unpin(vma);
			if (IS_ERR(map)) {
				err = PTR_ERR(map);
				goto out;
			}

			for (y = 0 ; y < plane_info[0].height; y++) {
				for (x = 0 ; x < plane_info[0].width; x++) {
					unsigned int offset;
					u32 val = y << 16 | x;

					if (*t == I915_GTT_VIEW_ROTATED)
						offset = (x * plane_info[0].dst_stride + y) * PAGE_SIZE;
					else
						offset = (y * plane_info[0].dst_stride + x) * PAGE_SIZE;

					iowrite32(val, &map[offset / sizeof(*map)]);
				}
			}

			i915_vma_unpin_iomap(vma);

			vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE);
			if (IS_ERR(vma)) {
				err = PTR_ERR(vma);
				goto out;
			}

			GEM_BUG_ON(vma->gtt_view.type != I915_GTT_VIEW_NORMAL);

			map = i915_vma_pin_iomap(vma);
			i915_vma_unpin(vma);
			if (IS_ERR(map)) {
				err = PTR_ERR(map);
				goto out;
			}

			for (y = 0 ; y < plane_info[0].height; y++) {
				for (x = 0 ; x < plane_info[0].width; x++) {
					unsigned int offset, src_idx;
					u32 exp = y << 16 | x;
					u32 val;

					if (*t == I915_GTT_VIEW_ROTATED)
						src_idx = rotated_index(&view.rotated, 0, x, y);
					else
						src_idx = remapped_index(&view.remapped, 0, x, y);
					offset = src_idx * PAGE_SIZE;

					val = ioread32(&map[offset / sizeof(*map)]);
					if (val != exp) {
						pr_err("%s VMA write test failed, expected 0x%x, found 0x%x\n",
						       *t == I915_GTT_VIEW_ROTATED ? "Rotated" : "Remapped",
						       exp, val);
						i915_vma_unpin_iomap(vma);
						err = -EINVAL;
						goto out;
					}
				}
			}
			i915_vma_unpin_iomap(vma);

			cond_resched();
		}
	}

out:
	intel_runtime_pm_put(&i915->runtime_pm, wakeref);
	i915_gem_object_put(obj);

	return err;
}

int i915_vma_live_selftests(struct drm_i915_private *i915)
{
	static const struct i915_subtest tests[] = {
		SUBTEST(igt_vma_remapped_gtt),
	};

	return i915_live_subtests(tests, i915);
}
