/*
 * 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 amonst 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);
}
