/*
 * SPDX-License-Identifier: MIT
 *
 * Copyright © 2016 Intel Corporation
 */

#include "i915_drv.h"
#include "i915_selftest.h"

#include "mock_dmabuf.h"
#include "selftests/mock_gem_device.h"

static int igt_dmabuf_export(void *arg)
{
	struct drm_i915_private *i915 = arg;
	struct drm_i915_gem_object *obj;
	struct dma_buf *dmabuf;

	obj = i915_gem_object_create_shmem(i915, PAGE_SIZE);
	if (IS_ERR(obj))
		return PTR_ERR(obj);

	dmabuf = i915_gem_prime_export(&obj->base, 0);
	i915_gem_object_put(obj);
	if (IS_ERR(dmabuf)) {
		pr_err("i915_gem_prime_export failed with err=%d\n",
		       (int)PTR_ERR(dmabuf));
		return PTR_ERR(dmabuf);
	}

	dma_buf_put(dmabuf);
	return 0;
}

static int igt_dmabuf_import_self(void *arg)
{
	struct drm_i915_private *i915 = arg;
	struct drm_i915_gem_object *obj, *import_obj;
	struct drm_gem_object *import;
	struct dma_buf *dmabuf;
	int err;

	obj = i915_gem_object_create_shmem(i915, PAGE_SIZE);
	if (IS_ERR(obj))
		return PTR_ERR(obj);

	dmabuf = i915_gem_prime_export(&obj->base, 0);
	if (IS_ERR(dmabuf)) {
		pr_err("i915_gem_prime_export failed with err=%d\n",
		       (int)PTR_ERR(dmabuf));
		err = PTR_ERR(dmabuf);
		goto out;
	}

	import = i915_gem_prime_import(&i915->drm, dmabuf);
	if (IS_ERR(import)) {
		pr_err("i915_gem_prime_import failed with err=%d\n",
		       (int)PTR_ERR(import));
		err = PTR_ERR(import);
		goto out_dmabuf;
	}

	if (import != &obj->base) {
		pr_err("i915_gem_prime_import created a new object!\n");
		err = -EINVAL;
		goto out_import;
	}
	import_obj = to_intel_bo(import);

	i915_gem_object_lock(import_obj, NULL);
	err = __i915_gem_object_get_pages(import_obj);
	i915_gem_object_unlock(import_obj);
	if (err) {
		pr_err("Same object dma-buf get_pages failed!\n");
		goto out_import;
	}

	err = 0;
out_import:
	i915_gem_object_put(import_obj);
out_dmabuf:
	dma_buf_put(dmabuf);
out:
	i915_gem_object_put(obj);
	return err;
}

static int igt_dmabuf_import_same_driver_lmem(void *arg)
{
	struct drm_i915_private *i915 = arg;
	struct intel_memory_region *lmem = i915->mm.regions[INTEL_REGION_LMEM];
	struct drm_i915_gem_object *obj;
	struct drm_gem_object *import;
	struct dma_buf *dmabuf;
	int err;

	if (!lmem)
		return 0;

	force_different_devices = true;

	obj = __i915_gem_object_create_user(i915, PAGE_SIZE, &lmem, 1);
	if (IS_ERR(obj)) {
		pr_err("__i915_gem_object_create_user failed with err=%ld\n",
		       PTR_ERR(dmabuf));
		err = PTR_ERR(obj);
		goto out_ret;
	}

	dmabuf = i915_gem_prime_export(&obj->base, 0);
	if (IS_ERR(dmabuf)) {
		pr_err("i915_gem_prime_export failed with err=%ld\n",
		       PTR_ERR(dmabuf));
		err = PTR_ERR(dmabuf);
		goto out;
	}

	/*
	 * We expect an import of an LMEM-only object to fail with
	 * -EOPNOTSUPP because it can't be migrated to SMEM.
	 */
	import = i915_gem_prime_import(&i915->drm, dmabuf);
	if (!IS_ERR(import)) {
		drm_gem_object_put(import);
		pr_err("i915_gem_prime_import succeeded when it shouldn't have\n");
		err = -EINVAL;
	} else if (PTR_ERR(import) != -EOPNOTSUPP) {
		pr_err("i915_gem_prime_import failed with the wrong err=%ld\n",
		       PTR_ERR(import));
		err = PTR_ERR(import);
	}

	dma_buf_put(dmabuf);
out:
	i915_gem_object_put(obj);
out_ret:
	force_different_devices = false;
	return err;
}

static int igt_dmabuf_import_same_driver(struct drm_i915_private *i915,
					 struct intel_memory_region **regions,
					 unsigned int num_regions)
{
	struct drm_i915_gem_object *obj, *import_obj;
	struct drm_gem_object *import;
	struct dma_buf *dmabuf;
	struct dma_buf_attachment *import_attach;
	struct sg_table *st;
	long timeout;
	int err;

	force_different_devices = true;

	obj = __i915_gem_object_create_user(i915, PAGE_SIZE,
					    regions, num_regions);
	if (IS_ERR(obj)) {
		pr_err("__i915_gem_object_create_user failed with err=%ld\n",
		       PTR_ERR(dmabuf));
		err = PTR_ERR(obj);
		goto out_ret;
	}

	dmabuf = i915_gem_prime_export(&obj->base, 0);
	if (IS_ERR(dmabuf)) {
		pr_err("i915_gem_prime_export failed with err=%ld\n",
		       PTR_ERR(dmabuf));
		err = PTR_ERR(dmabuf);
		goto out;
	}

	import = i915_gem_prime_import(&i915->drm, dmabuf);
	if (IS_ERR(import)) {
		pr_err("i915_gem_prime_import failed with err=%ld\n",
		       PTR_ERR(import));
		err = PTR_ERR(import);
		goto out_dmabuf;
	}

	if (import == &obj->base) {
		pr_err("i915_gem_prime_import reused gem object!\n");
		err = -EINVAL;
		goto out_import;
	}

	import_obj = to_intel_bo(import);

	i915_gem_object_lock(import_obj, NULL);
	err = __i915_gem_object_get_pages(import_obj);
	if (err) {
		pr_err("Different objects dma-buf get_pages failed!\n");
		i915_gem_object_unlock(import_obj);
		goto out_import;
	}

	/*
	 * If the exported object is not in system memory, something
	 * weird is going on. TODO: When p2p is supported, this is no
	 * longer considered weird.
	 */
	if (obj->mm.region != i915->mm.regions[INTEL_REGION_SMEM]) {
		pr_err("Exported dma-buf is not in system memory\n");
		err = -EINVAL;
	}

	i915_gem_object_unlock(import_obj);

	/* Now try a fake an importer */
	import_attach = dma_buf_attach(dmabuf, obj->base.dev->dev);
	if (IS_ERR(import_attach)) {
		err = PTR_ERR(import_attach);
		goto out_import;
	}

	st = dma_buf_map_attachment(import_attach, DMA_BIDIRECTIONAL);
	if (IS_ERR(st)) {
		err = PTR_ERR(st);
		goto out_detach;
	}

	timeout = dma_resv_wait_timeout(dmabuf->resv, false, true, 5 * HZ);
	if (!timeout) {
		pr_err("dmabuf wait for exclusive fence timed out.\n");
		timeout = -ETIME;
	}
	err = timeout > 0 ? 0 : timeout;
	dma_buf_unmap_attachment(import_attach, st, DMA_BIDIRECTIONAL);
out_detach:
	dma_buf_detach(dmabuf, import_attach);
out_import:
	i915_gem_object_put(import_obj);
out_dmabuf:
	dma_buf_put(dmabuf);
out:
	i915_gem_object_put(obj);
out_ret:
	force_different_devices = false;
	return err;
}

static int igt_dmabuf_import_same_driver_smem(void *arg)
{
	struct drm_i915_private *i915 = arg;
	struct intel_memory_region *smem = i915->mm.regions[INTEL_REGION_SMEM];

	return igt_dmabuf_import_same_driver(i915, &smem, 1);
}

static int igt_dmabuf_import_same_driver_lmem_smem(void *arg)
{
	struct drm_i915_private *i915 = arg;
	struct intel_memory_region *regions[2];

	if (!i915->mm.regions[INTEL_REGION_LMEM])
		return 0;

	regions[0] = i915->mm.regions[INTEL_REGION_LMEM];
	regions[1] = i915->mm.regions[INTEL_REGION_SMEM];
	return igt_dmabuf_import_same_driver(i915, regions, 2);
}

static int igt_dmabuf_import(void *arg)
{
	struct drm_i915_private *i915 = arg;
	struct drm_i915_gem_object *obj;
	struct dma_buf *dmabuf;
	void *obj_map, *dma_map;
	struct dma_buf_map map;
	u32 pattern[] = { 0, 0xaa, 0xcc, 0x55, 0xff };
	int err, i;

	dmabuf = mock_dmabuf(1);
	if (IS_ERR(dmabuf))
		return PTR_ERR(dmabuf);

	obj = to_intel_bo(i915_gem_prime_import(&i915->drm, dmabuf));
	if (IS_ERR(obj)) {
		pr_err("i915_gem_prime_import failed with err=%d\n",
		       (int)PTR_ERR(obj));
		err = PTR_ERR(obj);
		goto out_dmabuf;
	}

	if (obj->base.dev != &i915->drm) {
		pr_err("i915_gem_prime_import created a non-i915 object!\n");
		err = -EINVAL;
		goto out_obj;
	}

	if (obj->base.size != PAGE_SIZE) {
		pr_err("i915_gem_prime_import is wrong size found %lld, expected %ld\n",
		       (long long)obj->base.size, PAGE_SIZE);
		err = -EINVAL;
		goto out_obj;
	}

	err = dma_buf_vmap(dmabuf, &map);
	dma_map = err ? NULL : map.vaddr;
	if (!dma_map) {
		pr_err("dma_buf_vmap failed\n");
		err = -ENOMEM;
		goto out_obj;
	}

	if (0) { /* Can not yet map dmabuf */
		obj_map = i915_gem_object_pin_map(obj, I915_MAP_WB);
		if (IS_ERR(obj_map)) {
			err = PTR_ERR(obj_map);
			pr_err("i915_gem_object_pin_map failed with err=%d\n", err);
			goto out_dma_map;
		}

		for (i = 0; i < ARRAY_SIZE(pattern); i++) {
			memset(dma_map, pattern[i], PAGE_SIZE);
			if (memchr_inv(obj_map, pattern[i], PAGE_SIZE)) {
				err = -EINVAL;
				pr_err("imported vmap not all set to %x!\n", pattern[i]);
				i915_gem_object_unpin_map(obj);
				goto out_dma_map;
			}
		}

		for (i = 0; i < ARRAY_SIZE(pattern); i++) {
			memset(obj_map, pattern[i], PAGE_SIZE);
			if (memchr_inv(dma_map, pattern[i], PAGE_SIZE)) {
				err = -EINVAL;
				pr_err("exported vmap not all set to %x!\n", pattern[i]);
				i915_gem_object_unpin_map(obj);
				goto out_dma_map;
			}
		}

		i915_gem_object_unpin_map(obj);
	}

	err = 0;
out_dma_map:
	dma_buf_vunmap(dmabuf, &map);
out_obj:
	i915_gem_object_put(obj);
out_dmabuf:
	dma_buf_put(dmabuf);
	return err;
}

static int igt_dmabuf_import_ownership(void *arg)
{
	struct drm_i915_private *i915 = arg;
	struct drm_i915_gem_object *obj;
	struct dma_buf *dmabuf;
	struct dma_buf_map map;
	void *ptr;
	int err;

	dmabuf = mock_dmabuf(1);
	if (IS_ERR(dmabuf))
		return PTR_ERR(dmabuf);

	err = dma_buf_vmap(dmabuf, &map);
	ptr = err ? NULL : map.vaddr;
	if (!ptr) {
		pr_err("dma_buf_vmap failed\n");
		err = -ENOMEM;
		goto err_dmabuf;
	}

	memset(ptr, 0xc5, PAGE_SIZE);
	dma_buf_vunmap(dmabuf, &map);

	obj = to_intel_bo(i915_gem_prime_import(&i915->drm, dmabuf));
	if (IS_ERR(obj)) {
		pr_err("i915_gem_prime_import failed with err=%d\n",
		       (int)PTR_ERR(obj));
		err = PTR_ERR(obj);
		goto err_dmabuf;
	}

	dma_buf_put(dmabuf);

	err = i915_gem_object_pin_pages_unlocked(obj);
	if (err) {
		pr_err("i915_gem_object_pin_pages failed with err=%d\n", err);
		goto out_obj;
	}

	err = 0;
	i915_gem_object_unpin_pages(obj);
out_obj:
	i915_gem_object_put(obj);
	return err;

err_dmabuf:
	dma_buf_put(dmabuf);
	return err;
}

static int igt_dmabuf_export_vmap(void *arg)
{
	struct drm_i915_private *i915 = arg;
	struct drm_i915_gem_object *obj;
	struct dma_buf *dmabuf;
	struct dma_buf_map map;
	void *ptr;
	int err;

	obj = i915_gem_object_create_shmem(i915, PAGE_SIZE);
	if (IS_ERR(obj))
		return PTR_ERR(obj);

	dmabuf = i915_gem_prime_export(&obj->base, 0);
	if (IS_ERR(dmabuf)) {
		pr_err("i915_gem_prime_export failed with err=%d\n",
		       (int)PTR_ERR(dmabuf));
		err = PTR_ERR(dmabuf);
		goto err_obj;
	}
	i915_gem_object_put(obj);

	err = dma_buf_vmap(dmabuf, &map);
	ptr = err ? NULL : map.vaddr;
	if (!ptr) {
		pr_err("dma_buf_vmap failed\n");
		err = -ENOMEM;
		goto out;
	}

	if (memchr_inv(ptr, 0, dmabuf->size)) {
		pr_err("Exported object not initialiased to zero!\n");
		err = -EINVAL;
		goto out;
	}

	memset(ptr, 0xc5, dmabuf->size);

	err = 0;
	dma_buf_vunmap(dmabuf, &map);
out:
	dma_buf_put(dmabuf);
	return err;

err_obj:
	i915_gem_object_put(obj);
	return err;
}

int i915_gem_dmabuf_mock_selftests(void)
{
	static const struct i915_subtest tests[] = {
		SUBTEST(igt_dmabuf_export),
		SUBTEST(igt_dmabuf_import_self),
		SUBTEST(igt_dmabuf_import),
		SUBTEST(igt_dmabuf_import_ownership),
		SUBTEST(igt_dmabuf_export_vmap),
	};
	struct drm_i915_private *i915;
	int err;

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

	err = i915_subtests(tests, i915);

	mock_destroy_device(i915);
	return err;
}

int i915_gem_dmabuf_live_selftests(struct drm_i915_private *i915)
{
	static const struct i915_subtest tests[] = {
		SUBTEST(igt_dmabuf_export),
		SUBTEST(igt_dmabuf_import_same_driver_lmem),
		SUBTEST(igt_dmabuf_import_same_driver_smem),
		SUBTEST(igt_dmabuf_import_same_driver_lmem_smem),
	};

	return i915_subtests(tests, i915);
}
