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

#include "gem/i915_gem_internal.h"
#include "gem/i915_gem_pm.h"
#include "gt/intel_engine_user.h"
#include "gt/intel_gt.h"
#include "i915_selftest.h"
#include "intel_reset.h"

#include "selftests/igt_flush_test.h"
#include "selftests/igt_reset.h"
#include "selftests/igt_spinner.h"
#include "selftests/intel_scheduler_helpers.h"
#include "selftests/mock_drm.h"

#include "gem/selftests/igt_gem_utils.h"
#include "gem/selftests/mock_context.h"

static const struct wo_register {
	enum intel_platform platform;
	u32 reg;
} wo_registers[] = {
	{ INTEL_GEMINILAKE, 0x731c }
};

struct wa_lists {
	struct i915_wa_list gt_wa_list;
	struct {
		struct i915_wa_list wa_list;
		struct i915_wa_list ctx_wa_list;
	} engine[I915_NUM_ENGINES];
};

static int request_add_sync(struct i915_request *rq, int err)
{
	i915_request_get(rq);
	i915_request_add(rq);
	if (i915_request_wait(rq, 0, HZ / 5) < 0)
		err = -EIO;
	i915_request_put(rq);

	return err;
}

static int request_add_spin(struct i915_request *rq, struct igt_spinner *spin)
{
	int err = 0;

	i915_request_get(rq);
	i915_request_add(rq);
	if (spin && !igt_wait_for_spinner(spin, rq))
		err = -ETIMEDOUT;
	i915_request_put(rq);

	return err;
}

static void
reference_lists_init(struct intel_gt *gt, struct wa_lists *lists)
{
	struct intel_engine_cs *engine;
	enum intel_engine_id id;

	memset(lists, 0, sizeof(*lists));

	wa_init_start(&lists->gt_wa_list, gt, "GT_REF", "global");
	gt_init_workarounds(gt, &lists->gt_wa_list);
	wa_init_finish(&lists->gt_wa_list);

	for_each_engine(engine, gt, id) {
		struct i915_wa_list *wal = &lists->engine[id].wa_list;

		wa_init_start(wal, gt, "REF", engine->name);
		engine_init_workarounds(engine, wal);
		wa_init_finish(wal);

		__intel_engine_init_ctx_wa(engine,
					   &lists->engine[id].ctx_wa_list,
					   "CTX_REF");
	}
}

static void
reference_lists_fini(struct intel_gt *gt, struct wa_lists *lists)
{
	struct intel_engine_cs *engine;
	enum intel_engine_id id;

	for_each_engine(engine, gt, id)
		intel_wa_list_free(&lists->engine[id].wa_list);

	intel_wa_list_free(&lists->gt_wa_list);
}

static struct drm_i915_gem_object *
read_nonprivs(struct intel_context *ce)
{
	struct intel_engine_cs *engine = ce->engine;
	const u32 base = engine->mmio_base;
	struct drm_i915_gem_object *result;
	struct i915_request *rq;
	struct i915_vma *vma;
	u32 srm, *cs;
	int err;
	int i;

	result = i915_gem_object_create_internal(engine->i915, PAGE_SIZE);
	if (IS_ERR(result))
		return result;

	i915_gem_object_set_cache_coherency(result, I915_CACHE_LLC);

	cs = i915_gem_object_pin_map_unlocked(result, I915_MAP_WB);
	if (IS_ERR(cs)) {
		err = PTR_ERR(cs);
		goto err_obj;
	}
	memset(cs, 0xc5, PAGE_SIZE);
	i915_gem_object_flush_map(result);
	i915_gem_object_unpin_map(result);

	vma = i915_vma_instance(result, &engine->gt->ggtt->vm, NULL);
	if (IS_ERR(vma)) {
		err = PTR_ERR(vma);
		goto err_obj;
	}

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

	rq = intel_context_create_request(ce);
	if (IS_ERR(rq)) {
		err = PTR_ERR(rq);
		goto err_pin;
	}

	err = igt_vma_move_to_active_unlocked(vma, rq, EXEC_OBJECT_WRITE);
	if (err)
		goto err_req;

	srm = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;
	if (GRAPHICS_VER(engine->i915) >= 8)
		srm++;

	cs = intel_ring_begin(rq, 4 * RING_MAX_NONPRIV_SLOTS);
	if (IS_ERR(cs)) {
		err = PTR_ERR(cs);
		goto err_req;
	}

	for (i = 0; i < RING_MAX_NONPRIV_SLOTS; i++) {
		*cs++ = srm;
		*cs++ = i915_mmio_reg_offset(RING_FORCE_TO_NONPRIV(base, i));
		*cs++ = i915_ggtt_offset(vma) + sizeof(u32) * i;
		*cs++ = 0;
	}
	intel_ring_advance(rq, cs);

	i915_request_add(rq);
	i915_vma_unpin(vma);

	return result;

err_req:
	i915_request_add(rq);
err_pin:
	i915_vma_unpin(vma);
err_obj:
	i915_gem_object_put(result);
	return ERR_PTR(err);
}

static u32
get_whitelist_reg(const struct intel_engine_cs *engine, unsigned int i)
{
	i915_reg_t reg = i < engine->whitelist.count ?
			 engine->whitelist.list[i].reg :
			 RING_NOPID(engine->mmio_base);

	return i915_mmio_reg_offset(reg);
}

static void
print_results(const struct intel_engine_cs *engine, const u32 *results)
{
	unsigned int i;

	for (i = 0; i < RING_MAX_NONPRIV_SLOTS; i++) {
		u32 expected = get_whitelist_reg(engine, i);
		u32 actual = results[i];

		pr_info("RING_NONPRIV[%d]: expected 0x%08x, found 0x%08x\n",
			i, expected, actual);
	}
}

static int check_whitelist(struct intel_context *ce)
{
	struct intel_engine_cs *engine = ce->engine;
	struct drm_i915_gem_object *results;
	struct intel_wedge_me wedge;
	u32 *vaddr;
	int err;
	int i;

	results = read_nonprivs(ce);
	if (IS_ERR(results))
		return PTR_ERR(results);

	err = 0;
	i915_gem_object_lock(results, NULL);
	intel_wedge_on_timeout(&wedge, engine->gt, HZ / 5) /* safety net! */
		err = i915_gem_object_set_to_cpu_domain(results, false);

	if (intel_gt_is_wedged(engine->gt))
		err = -EIO;
	if (err)
		goto out_put;

	vaddr = i915_gem_object_pin_map(results, I915_MAP_WB);
	if (IS_ERR(vaddr)) {
		err = PTR_ERR(vaddr);
		goto out_put;
	}

	for (i = 0; i < RING_MAX_NONPRIV_SLOTS; i++) {
		u32 expected = get_whitelist_reg(engine, i);
		u32 actual = vaddr[i];

		if (expected != actual) {
			print_results(engine, vaddr);
			pr_err("Invalid RING_NONPRIV[%d], expected 0x%08x, found 0x%08x\n",
			       i, expected, actual);

			err = -EINVAL;
			break;
		}
	}

	i915_gem_object_unpin_map(results);
out_put:
	i915_gem_object_unlock(results);
	i915_gem_object_put(results);
	return err;
}

static int do_device_reset(struct intel_engine_cs *engine)
{
	intel_gt_reset(engine->gt, engine->mask, "live_workarounds");
	return 0;
}

static int do_engine_reset(struct intel_engine_cs *engine)
{
	return intel_engine_reset(engine, "live_workarounds");
}

static int do_guc_reset(struct intel_engine_cs *engine)
{
	/* Currently a no-op as the reset is handled by GuC */
	return 0;
}

static int
switch_to_scratch_context(struct intel_engine_cs *engine,
			  struct igt_spinner *spin,
			  struct i915_request **rq)
{
	struct intel_context *ce;
	int err = 0;

	ce = intel_context_create(engine);
	if (IS_ERR(ce))
		return PTR_ERR(ce);

	*rq = igt_spinner_create_request(spin, ce, MI_NOOP);
	intel_context_put(ce);

	if (IS_ERR(*rq)) {
		spin = NULL;
		err = PTR_ERR(*rq);
		goto err;
	}

	err = request_add_spin(*rq, spin);
err:
	if (err && spin)
		igt_spinner_end(spin);

	return err;
}

static int check_whitelist_across_reset(struct intel_engine_cs *engine,
					int (*reset)(struct intel_engine_cs *),
					const char *name)
{
	struct intel_context *ce, *tmp;
	struct igt_spinner spin;
	struct i915_request *rq;
	intel_wakeref_t wakeref;
	int err;

	pr_info("Checking %d whitelisted registers on %s (RING_NONPRIV) [%s]\n",
		engine->whitelist.count, engine->name, name);

	ce = intel_context_create(engine);
	if (IS_ERR(ce))
		return PTR_ERR(ce);

	err = igt_spinner_init(&spin, engine->gt);
	if (err)
		goto out_ctx;

	err = check_whitelist(ce);
	if (err) {
		pr_err("Invalid whitelist *before* %s reset!\n", name);
		goto out_spin;
	}

	err = switch_to_scratch_context(engine, &spin, &rq);
	if (err)
		goto out_spin;

	/* Ensure the spinner hasn't aborted */
	if (i915_request_completed(rq)) {
		pr_err("%s spinner failed to start\n", name);
		err = -ETIMEDOUT;
		goto out_spin;
	}

	with_intel_runtime_pm(engine->uncore->rpm, wakeref)
		err = reset(engine);

	/* Ensure the reset happens and kills the engine */
	if (err == 0)
		err = intel_selftest_wait_for_rq(rq);

	igt_spinner_end(&spin);

	if (err) {
		pr_err("%s reset failed\n", name);
		goto out_spin;
	}

	err = check_whitelist(ce);
	if (err) {
		pr_err("Whitelist not preserved in context across %s reset!\n",
		       name);
		goto out_spin;
	}

	tmp = intel_context_create(engine);
	if (IS_ERR(tmp)) {
		err = PTR_ERR(tmp);
		goto out_spin;
	}
	intel_context_put(ce);
	ce = tmp;

	err = check_whitelist(ce);
	if (err) {
		pr_err("Invalid whitelist *after* %s reset in fresh context!\n",
		       name);
		goto out_spin;
	}

out_spin:
	igt_spinner_fini(&spin);
out_ctx:
	intel_context_put(ce);
	return err;
}

static struct i915_vma *create_batch(struct i915_address_space *vm)
{
	struct drm_i915_gem_object *obj;
	struct i915_vma *vma;
	int err;

	obj = i915_gem_object_create_internal(vm->i915, 16 * PAGE_SIZE);
	if (IS_ERR(obj))
		return ERR_CAST(obj);

	vma = i915_vma_instance(obj, vm, NULL);
	if (IS_ERR(vma)) {
		err = PTR_ERR(vma);
		goto err_obj;
	}

	err = i915_vma_pin(vma, 0, 0, PIN_USER);
	if (err)
		goto err_obj;

	return vma;

err_obj:
	i915_gem_object_put(obj);
	return ERR_PTR(err);
}

static u32 reg_write(u32 old, u32 new, u32 rsvd)
{
	if (rsvd == 0x0000ffff) {
		old &= ~(new >> 16);
		old |= new & (new >> 16);
	} else {
		old &= ~rsvd;
		old |= new & rsvd;
	}

	return old;
}

static bool wo_register(struct intel_engine_cs *engine, u32 reg)
{
	enum intel_platform platform = INTEL_INFO(engine->i915)->platform;
	int i;

	if ((reg & RING_FORCE_TO_NONPRIV_ACCESS_MASK) ==
	     RING_FORCE_TO_NONPRIV_ACCESS_WR)
		return true;

	for (i = 0; i < ARRAY_SIZE(wo_registers); i++) {
		if (wo_registers[i].platform == platform &&
		    wo_registers[i].reg == reg)
			return true;
	}

	return false;
}

static bool timestamp(const struct intel_engine_cs *engine, u32 reg)
{
	reg = (reg - engine->mmio_base) & ~RING_FORCE_TO_NONPRIV_ACCESS_MASK;
	switch (reg) {
	case 0x358:
	case 0x35c:
	case 0x3a8:
		return true;

	default:
		return false;
	}
}

static bool ro_register(u32 reg)
{
	if ((reg & RING_FORCE_TO_NONPRIV_ACCESS_MASK) ==
	     RING_FORCE_TO_NONPRIV_ACCESS_RD)
		return true;

	return false;
}

static int whitelist_writable_count(struct intel_engine_cs *engine)
{
	int count = engine->whitelist.count;
	int i;

	for (i = 0; i < engine->whitelist.count; i++) {
		u32 reg = i915_mmio_reg_offset(engine->whitelist.list[i].reg);

		if (ro_register(reg))
			count--;
	}

	return count;
}

static int check_dirty_whitelist(struct intel_context *ce)
{
	const u32 values[] = {
		0x00000000,
		0x01010101,
		0x10100101,
		0x03030303,
		0x30300303,
		0x05050505,
		0x50500505,
		0x0f0f0f0f,
		0xf00ff00f,
		0x10101010,
		0xf0f01010,
		0x30303030,
		0xa0a03030,
		0x50505050,
		0xc0c05050,
		0xf0f0f0f0,
		0x11111111,
		0x33333333,
		0x55555555,
		0x0000ffff,
		0x00ff00ff,
		0xff0000ff,
		0xffff00ff,
		0xffffffff,
	};
	struct intel_engine_cs *engine = ce->engine;
	struct i915_vma *scratch;
	struct i915_vma *batch;
	int err = 0, i, v, sz;
	u32 *cs, *results;

	sz = (2 * ARRAY_SIZE(values) + 1) * sizeof(u32);
	scratch = __vm_create_scratch_for_read_pinned(ce->vm, sz);
	if (IS_ERR(scratch))
		return PTR_ERR(scratch);

	batch = create_batch(ce->vm);
	if (IS_ERR(batch)) {
		err = PTR_ERR(batch);
		goto out_scratch;
	}

	for (i = 0; i < engine->whitelist.count; i++) {
		u32 reg = i915_mmio_reg_offset(engine->whitelist.list[i].reg);
		struct i915_gem_ww_ctx ww;
		u64 addr = i915_vma_offset(scratch);
		struct i915_request *rq;
		u32 srm, lrm, rsvd;
		u32 expect;
		int idx;
		bool ro_reg;

		if (wo_register(engine, reg))
			continue;

		if (timestamp(engine, reg))
			continue; /* timestamps are expected to autoincrement */

		ro_reg = ro_register(reg);

		i915_gem_ww_ctx_init(&ww, false);
retry:
		cs = NULL;
		err = i915_gem_object_lock(scratch->obj, &ww);
		if (!err)
			err = i915_gem_object_lock(batch->obj, &ww);
		if (!err)
			err = intel_context_pin_ww(ce, &ww);
		if (err)
			goto out;

		cs = i915_gem_object_pin_map(batch->obj, I915_MAP_WC);
		if (IS_ERR(cs)) {
			err = PTR_ERR(cs);
			goto out_ctx;
		}

		results = i915_gem_object_pin_map(scratch->obj, I915_MAP_WB);
		if (IS_ERR(results)) {
			err = PTR_ERR(results);
			goto out_unmap_batch;
		}

		/* Clear non priv flags */
		reg &= RING_FORCE_TO_NONPRIV_ADDRESS_MASK;

		srm = MI_STORE_REGISTER_MEM;
		lrm = MI_LOAD_REGISTER_MEM;
		if (GRAPHICS_VER(engine->i915) >= 8)
			lrm++, srm++;

		pr_debug("%s: Writing garbage to %x\n",
			 engine->name, reg);

		/* SRM original */
		*cs++ = srm;
		*cs++ = reg;
		*cs++ = lower_32_bits(addr);
		*cs++ = upper_32_bits(addr);

		idx = 1;
		for (v = 0; v < ARRAY_SIZE(values); v++) {
			/* LRI garbage */
			*cs++ = MI_LOAD_REGISTER_IMM(1);
			*cs++ = reg;
			*cs++ = values[v];

			/* SRM result */
			*cs++ = srm;
			*cs++ = reg;
			*cs++ = lower_32_bits(addr + sizeof(u32) * idx);
			*cs++ = upper_32_bits(addr + sizeof(u32) * idx);
			idx++;
		}
		for (v = 0; v < ARRAY_SIZE(values); v++) {
			/* LRI garbage */
			*cs++ = MI_LOAD_REGISTER_IMM(1);
			*cs++ = reg;
			*cs++ = ~values[v];

			/* SRM result */
			*cs++ = srm;
			*cs++ = reg;
			*cs++ = lower_32_bits(addr + sizeof(u32) * idx);
			*cs++ = upper_32_bits(addr + sizeof(u32) * idx);
			idx++;
		}
		GEM_BUG_ON(idx * sizeof(u32) > scratch->size);

		/* LRM original -- don't leave garbage in the context! */
		*cs++ = lrm;
		*cs++ = reg;
		*cs++ = lower_32_bits(addr);
		*cs++ = upper_32_bits(addr);

		*cs++ = MI_BATCH_BUFFER_END;

		i915_gem_object_flush_map(batch->obj);
		i915_gem_object_unpin_map(batch->obj);
		intel_gt_chipset_flush(engine->gt);
		cs = NULL;

		rq = i915_request_create(ce);
		if (IS_ERR(rq)) {
			err = PTR_ERR(rq);
			goto out_unmap_scratch;
		}

		if (engine->emit_init_breadcrumb) { /* Be nice if we hang */
			err = engine->emit_init_breadcrumb(rq);
			if (err)
				goto err_request;
		}

		err = i915_vma_move_to_active(batch, rq, 0);
		if (err)
			goto err_request;

		err = i915_vma_move_to_active(scratch, rq,
					      EXEC_OBJECT_WRITE);
		if (err)
			goto err_request;

		err = engine->emit_bb_start(rq,
					    i915_vma_offset(batch), PAGE_SIZE,
					    0);
		if (err)
			goto err_request;

err_request:
		err = request_add_sync(rq, err);
		if (err) {
			pr_err("%s: Futzing %x timedout; cancelling test\n",
			       engine->name, reg);
			intel_gt_set_wedged(engine->gt);
			goto out_unmap_scratch;
		}

		GEM_BUG_ON(values[ARRAY_SIZE(values) - 1] != 0xffffffff);
		if (!ro_reg) {
			/* detect write masking */
			rsvd = results[ARRAY_SIZE(values)];
			if (!rsvd) {
				pr_err("%s: Unable to write to whitelisted register %x\n",
				       engine->name, reg);
				err = -EINVAL;
				goto out_unmap_scratch;
			}
		} else {
			rsvd = 0;
		}

		expect = results[0];
		idx = 1;
		for (v = 0; v < ARRAY_SIZE(values); v++) {
			if (ro_reg)
				expect = results[0];
			else
				expect = reg_write(expect, values[v], rsvd);

			if (results[idx] != expect)
				err++;
			idx++;
		}
		for (v = 0; v < ARRAY_SIZE(values); v++) {
			if (ro_reg)
				expect = results[0];
			else
				expect = reg_write(expect, ~values[v], rsvd);

			if (results[idx] != expect)
				err++;
			idx++;
		}
		if (err) {
			pr_err("%s: %d mismatch between values written to whitelisted register [%x], and values read back!\n",
			       engine->name, err, reg);

			if (ro_reg)
				pr_info("%s: Whitelisted read-only register: %x, original value %08x\n",
					engine->name, reg, results[0]);
			else
				pr_info("%s: Whitelisted register: %x, original value %08x, rsvd %08x\n",
					engine->name, reg, results[0], rsvd);

			expect = results[0];
			idx = 1;
			for (v = 0; v < ARRAY_SIZE(values); v++) {
				u32 w = values[v];

				if (ro_reg)
					expect = results[0];
				else
					expect = reg_write(expect, w, rsvd);
				pr_info("Wrote %08x, read %08x, expect %08x\n",
					w, results[idx], expect);
				idx++;
			}
			for (v = 0; v < ARRAY_SIZE(values); v++) {
				u32 w = ~values[v];

				if (ro_reg)
					expect = results[0];
				else
					expect = reg_write(expect, w, rsvd);
				pr_info("Wrote %08x, read %08x, expect %08x\n",
					w, results[idx], expect);
				idx++;
			}

			err = -EINVAL;
		}
out_unmap_scratch:
		i915_gem_object_unpin_map(scratch->obj);
out_unmap_batch:
		if (cs)
			i915_gem_object_unpin_map(batch->obj);
out_ctx:
		intel_context_unpin(ce);
out:
		if (err == -EDEADLK) {
			err = i915_gem_ww_ctx_backoff(&ww);
			if (!err)
				goto retry;
		}
		i915_gem_ww_ctx_fini(&ww);
		if (err)
			break;
	}

	if (igt_flush_test(engine->i915))
		err = -EIO;

	i915_vma_unpin_and_release(&batch, 0);
out_scratch:
	i915_vma_unpin_and_release(&scratch, 0);
	return err;
}

static int live_dirty_whitelist(void *arg)
{
	struct intel_gt *gt = arg;
	struct intel_engine_cs *engine;
	enum intel_engine_id id;

	/* Can the user write to the whitelisted registers? */

	if (GRAPHICS_VER(gt->i915) < 7) /* minimum requirement for LRI, SRM, LRM */
		return 0;

	for_each_engine(engine, gt, id) {
		struct intel_context *ce;
		int err;

		if (engine->whitelist.count == 0)
			continue;

		ce = intel_context_create(engine);
		if (IS_ERR(ce))
			return PTR_ERR(ce);

		err = check_dirty_whitelist(ce);
		intel_context_put(ce);
		if (err)
			return err;
	}

	return 0;
}

static int live_reset_whitelist(void *arg)
{
	struct intel_gt *gt = arg;
	struct intel_engine_cs *engine;
	enum intel_engine_id id;
	int err = 0;

	/* If we reset the gpu, we should not lose the RING_NONPRIV */
	igt_global_reset_lock(gt);

	for_each_engine(engine, gt, id) {
		if (engine->whitelist.count == 0)
			continue;

		if (intel_has_reset_engine(gt)) {
			if (intel_engine_uses_guc(engine)) {
				struct intel_selftest_saved_policy saved;
				int err2;

				err = intel_selftest_modify_policy(engine, &saved,
								   SELFTEST_SCHEDULER_MODIFY_FAST_RESET);
				if (err)
					goto out;

				err = check_whitelist_across_reset(engine,
								   do_guc_reset,
								   "guc");

				err2 = intel_selftest_restore_policy(engine, &saved);
				if (err == 0)
					err = err2;
			} else {
				err = check_whitelist_across_reset(engine,
								   do_engine_reset,
								   "engine");
			}

			if (err)
				goto out;
		}

		if (intel_has_gpu_reset(gt)) {
			err = check_whitelist_across_reset(engine,
							   do_device_reset,
							   "device");
			if (err)
				goto out;
		}
	}

out:
	igt_global_reset_unlock(gt);
	return err;
}

static int read_whitelisted_registers(struct intel_context *ce,
				      struct i915_vma *results)
{
	struct intel_engine_cs *engine = ce->engine;
	struct i915_request *rq;
	int i, err = 0;
	u32 srm, *cs;

	rq = intel_context_create_request(ce);
	if (IS_ERR(rq))
		return PTR_ERR(rq);

	err = igt_vma_move_to_active_unlocked(results, rq, EXEC_OBJECT_WRITE);
	if (err)
		goto err_req;

	srm = MI_STORE_REGISTER_MEM;
	if (GRAPHICS_VER(engine->i915) >= 8)
		srm++;

	cs = intel_ring_begin(rq, 4 * engine->whitelist.count);
	if (IS_ERR(cs)) {
		err = PTR_ERR(cs);
		goto err_req;
	}

	for (i = 0; i < engine->whitelist.count; i++) {
		u64 offset = i915_vma_offset(results) + sizeof(u32) * i;
		u32 reg = i915_mmio_reg_offset(engine->whitelist.list[i].reg);

		/* Clear non priv flags */
		reg &= RING_FORCE_TO_NONPRIV_ADDRESS_MASK;

		*cs++ = srm;
		*cs++ = reg;
		*cs++ = lower_32_bits(offset);
		*cs++ = upper_32_bits(offset);
	}
	intel_ring_advance(rq, cs);

err_req:
	return request_add_sync(rq, err);
}

static int scrub_whitelisted_registers(struct intel_context *ce)
{
	struct intel_engine_cs *engine = ce->engine;
	struct i915_request *rq;
	struct i915_vma *batch;
	int i, err = 0;
	u32 *cs;

	batch = create_batch(ce->vm);
	if (IS_ERR(batch))
		return PTR_ERR(batch);

	cs = i915_gem_object_pin_map_unlocked(batch->obj, I915_MAP_WC);
	if (IS_ERR(cs)) {
		err = PTR_ERR(cs);
		goto err_batch;
	}

	*cs++ = MI_LOAD_REGISTER_IMM(whitelist_writable_count(engine));
	for (i = 0; i < engine->whitelist.count; i++) {
		u32 reg = i915_mmio_reg_offset(engine->whitelist.list[i].reg);

		if (ro_register(reg))
			continue;

		/* Clear non priv flags */
		reg &= RING_FORCE_TO_NONPRIV_ADDRESS_MASK;

		*cs++ = reg;
		*cs++ = 0xffffffff;
	}
	*cs++ = MI_BATCH_BUFFER_END;

	i915_gem_object_flush_map(batch->obj);
	intel_gt_chipset_flush(engine->gt);

	rq = intel_context_create_request(ce);
	if (IS_ERR(rq)) {
		err = PTR_ERR(rq);
		goto err_unpin;
	}

	if (engine->emit_init_breadcrumb) { /* Be nice if we hang */
		err = engine->emit_init_breadcrumb(rq);
		if (err)
			goto err_request;
	}

	err = igt_vma_move_to_active_unlocked(batch, rq, 0);
	if (err)
		goto err_request;

	/* Perform the writes from an unprivileged "user" batch */
	err = engine->emit_bb_start(rq, i915_vma_offset(batch), 0, 0);

err_request:
	err = request_add_sync(rq, err);

err_unpin:
	i915_gem_object_unpin_map(batch->obj);
err_batch:
	i915_vma_unpin_and_release(&batch, 0);
	return err;
}

struct regmask {
	i915_reg_t reg;
	u8 graphics_ver;
};

static bool find_reg(struct drm_i915_private *i915,
		     i915_reg_t reg,
		     const struct regmask *tbl,
		     unsigned long count)
{
	u32 offset = i915_mmio_reg_offset(reg);

	while (count--) {
		if (GRAPHICS_VER(i915) == tbl->graphics_ver &&
		    i915_mmio_reg_offset(tbl->reg) == offset)
			return true;
		tbl++;
	}

	return false;
}

static bool pardon_reg(struct drm_i915_private *i915, i915_reg_t reg)
{
	/* Alas, we must pardon some whitelists. Mistakes already made */
	static const struct regmask pardon[] = {
		{ GEN9_CTX_PREEMPT_REG, 9 },
		{ _MMIO(0xb118), 9 }, /* GEN8_L3SQCREG4 */
	};

	return find_reg(i915, reg, pardon, ARRAY_SIZE(pardon));
}

static bool result_eq(struct intel_engine_cs *engine,
		      u32 a, u32 b, i915_reg_t reg)
{
	if (a != b && !pardon_reg(engine->i915, reg)) {
		pr_err("Whitelisted register 0x%4x not context saved: A=%08x, B=%08x\n",
		       i915_mmio_reg_offset(reg), a, b);
		return false;
	}

	return true;
}

static bool writeonly_reg(struct drm_i915_private *i915, i915_reg_t reg)
{
	/* Some registers do not seem to behave and our writes unreadable */
	static const struct regmask wo[] = {
		{ GEN9_SLICE_COMMON_ECO_CHICKEN1, 9 },
	};

	return find_reg(i915, reg, wo, ARRAY_SIZE(wo));
}

static bool result_neq(struct intel_engine_cs *engine,
		       u32 a, u32 b, i915_reg_t reg)
{
	if (a == b && !writeonly_reg(engine->i915, reg)) {
		pr_err("Whitelist register 0x%4x:%08x was unwritable\n",
		       i915_mmio_reg_offset(reg), a);
		return false;
	}

	return true;
}

static int
check_whitelisted_registers(struct intel_engine_cs *engine,
			    struct i915_vma *A,
			    struct i915_vma *B,
			    bool (*fn)(struct intel_engine_cs *engine,
				       u32 a, u32 b,
				       i915_reg_t reg))
{
	u32 *a, *b;
	int i, err;

	a = i915_gem_object_pin_map_unlocked(A->obj, I915_MAP_WB);
	if (IS_ERR(a))
		return PTR_ERR(a);

	b = i915_gem_object_pin_map_unlocked(B->obj, I915_MAP_WB);
	if (IS_ERR(b)) {
		err = PTR_ERR(b);
		goto err_a;
	}

	err = 0;
	for (i = 0; i < engine->whitelist.count; i++) {
		const struct i915_wa *wa = &engine->whitelist.list[i];

		if (i915_mmio_reg_offset(wa->reg) &
		    RING_FORCE_TO_NONPRIV_ACCESS_RD)
			continue;

		if (!fn(engine, a[i], b[i], wa->reg))
			err = -EINVAL;
	}

	i915_gem_object_unpin_map(B->obj);
err_a:
	i915_gem_object_unpin_map(A->obj);
	return err;
}

static int live_isolated_whitelist(void *arg)
{
	struct intel_gt *gt = arg;
	struct {
		struct i915_vma *scratch[2];
	} client[2] = {};
	struct intel_engine_cs *engine;
	enum intel_engine_id id;
	int i, err = 0;

	/*
	 * Check that a write into a whitelist register works, but
	 * invisible to a second context.
	 */

	if (!intel_engines_has_context_isolation(gt->i915))
		return 0;

	for (i = 0; i < ARRAY_SIZE(client); i++) {
		client[i].scratch[0] =
			__vm_create_scratch_for_read_pinned(gt->vm, 4096);
		if (IS_ERR(client[i].scratch[0])) {
			err = PTR_ERR(client[i].scratch[0]);
			goto err;
		}

		client[i].scratch[1] =
			__vm_create_scratch_for_read_pinned(gt->vm, 4096);
		if (IS_ERR(client[i].scratch[1])) {
			err = PTR_ERR(client[i].scratch[1]);
			i915_vma_unpin_and_release(&client[i].scratch[0], 0);
			goto err;
		}
	}

	for_each_engine(engine, gt, id) {
		struct intel_context *ce[2];

		if (!engine->kernel_context->vm)
			continue;

		if (!whitelist_writable_count(engine))
			continue;

		ce[0] = intel_context_create(engine);
		if (IS_ERR(ce[0])) {
			err = PTR_ERR(ce[0]);
			break;
		}
		ce[1] = intel_context_create(engine);
		if (IS_ERR(ce[1])) {
			err = PTR_ERR(ce[1]);
			intel_context_put(ce[0]);
			break;
		}

		/* Read default values */
		err = read_whitelisted_registers(ce[0], client[0].scratch[0]);
		if (err)
			goto err_ce;

		/* Try to overwrite registers (should only affect ctx0) */
		err = scrub_whitelisted_registers(ce[0]);
		if (err)
			goto err_ce;

		/* Read values from ctx1, we expect these to be defaults */
		err = read_whitelisted_registers(ce[1], client[1].scratch[0]);
		if (err)
			goto err_ce;

		/* Verify that both reads return the same default values */
		err = check_whitelisted_registers(engine,
						  client[0].scratch[0],
						  client[1].scratch[0],
						  result_eq);
		if (err)
			goto err_ce;

		/* Read back the updated values in ctx0 */
		err = read_whitelisted_registers(ce[0], client[0].scratch[1]);
		if (err)
			goto err_ce;

		/* User should be granted privilege to overwhite regs */
		err = check_whitelisted_registers(engine,
						  client[0].scratch[0],
						  client[0].scratch[1],
						  result_neq);
err_ce:
		intel_context_put(ce[1]);
		intel_context_put(ce[0]);
		if (err)
			break;
	}

err:
	for (i = 0; i < ARRAY_SIZE(client); i++) {
		i915_vma_unpin_and_release(&client[i].scratch[1], 0);
		i915_vma_unpin_and_release(&client[i].scratch[0], 0);
	}

	if (igt_flush_test(gt->i915))
		err = -EIO;

	return err;
}

static bool
verify_wa_lists(struct intel_gt *gt, struct wa_lists *lists,
		const char *str)
{
	struct intel_engine_cs *engine;
	enum intel_engine_id id;
	bool ok = true;

	ok &= wa_list_verify(gt, &lists->gt_wa_list, str);

	for_each_engine(engine, gt, id) {
		struct intel_context *ce;

		ce = intel_context_create(engine);
		if (IS_ERR(ce))
			return false;

		ok &= engine_wa_list_verify(ce,
					    &lists->engine[id].wa_list,
					    str) == 0;

		ok &= engine_wa_list_verify(ce,
					    &lists->engine[id].ctx_wa_list,
					    str) == 0;

		intel_context_put(ce);
	}

	return ok;
}

static int
live_gpu_reset_workarounds(void *arg)
{
	struct intel_gt *gt = arg;
	intel_wakeref_t wakeref;
	struct wa_lists *lists;
	bool ok;

	if (!intel_has_gpu_reset(gt))
		return 0;

	lists = kzalloc(sizeof(*lists), GFP_KERNEL);
	if (!lists)
		return -ENOMEM;

	pr_info("Verifying after GPU reset...\n");

	igt_global_reset_lock(gt);
	wakeref = intel_runtime_pm_get(gt->uncore->rpm);

	reference_lists_init(gt, lists);

	ok = verify_wa_lists(gt, lists, "before reset");
	if (!ok)
		goto out;

	intel_gt_reset(gt, ALL_ENGINES, "live_workarounds");

	ok = verify_wa_lists(gt, lists, "after reset");

out:
	reference_lists_fini(gt, lists);
	intel_runtime_pm_put(gt->uncore->rpm, wakeref);
	igt_global_reset_unlock(gt);
	kfree(lists);

	return ok ? 0 : -ESRCH;
}

static int
live_engine_reset_workarounds(void *arg)
{
	struct intel_gt *gt = arg;
	struct intel_engine_cs *engine;
	enum intel_engine_id id;
	struct intel_context *ce;
	struct igt_spinner spin;
	struct i915_request *rq;
	intel_wakeref_t wakeref;
	struct wa_lists *lists;
	int ret = 0;

	if (!intel_has_reset_engine(gt))
		return 0;

	lists = kzalloc(sizeof(*lists), GFP_KERNEL);
	if (!lists)
		return -ENOMEM;

	igt_global_reset_lock(gt);
	wakeref = intel_runtime_pm_get(gt->uncore->rpm);

	reference_lists_init(gt, lists);

	for_each_engine(engine, gt, id) {
		struct intel_selftest_saved_policy saved;
		bool using_guc = intel_engine_uses_guc(engine);
		bool ok;
		int ret2;

		pr_info("Verifying after %s reset...\n", engine->name);
		ret = intel_selftest_modify_policy(engine, &saved,
						   SELFTEST_SCHEDULER_MODIFY_FAST_RESET);
		if (ret)
			break;

		ce = intel_context_create(engine);
		if (IS_ERR(ce)) {
			ret = PTR_ERR(ce);
			goto restore;
		}

		if (!using_guc) {
			ok = verify_wa_lists(gt, lists, "before reset");
			if (!ok) {
				ret = -ESRCH;
				goto err;
			}

			ret = intel_engine_reset(engine, "live_workarounds:idle");
			if (ret) {
				pr_err("%s: Reset failed while idle\n", engine->name);
				goto err;
			}

			ok = verify_wa_lists(gt, lists, "after idle reset");
			if (!ok) {
				ret = -ESRCH;
				goto err;
			}
		}

		ret = igt_spinner_init(&spin, engine->gt);
		if (ret)
			goto err;

		rq = igt_spinner_create_request(&spin, ce, MI_NOOP);
		if (IS_ERR(rq)) {
			ret = PTR_ERR(rq);
			igt_spinner_fini(&spin);
			goto err;
		}

		ret = request_add_spin(rq, &spin);
		if (ret) {
			pr_err("%s: Spinner failed to start\n", engine->name);
			igt_spinner_fini(&spin);
			goto err;
		}

		/* Ensure the spinner hasn't aborted */
		if (i915_request_completed(rq)) {
			ret = -ETIMEDOUT;
			goto skip;
		}

		if (!using_guc) {
			ret = intel_engine_reset(engine, "live_workarounds:active");
			if (ret) {
				pr_err("%s: Reset failed on an active spinner\n",
				       engine->name);
				igt_spinner_fini(&spin);
				goto err;
			}
		}

		/* Ensure the reset happens and kills the engine */
		if (ret == 0)
			ret = intel_selftest_wait_for_rq(rq);

skip:
		igt_spinner_end(&spin);
		igt_spinner_fini(&spin);

		ok = verify_wa_lists(gt, lists, "after busy reset");
		if (!ok)
			ret = -ESRCH;

err:
		intel_context_put(ce);

restore:
		ret2 = intel_selftest_restore_policy(engine, &saved);
		if (ret == 0)
			ret = ret2;
		if (ret)
			break;
	}

	reference_lists_fini(gt, lists);
	intel_runtime_pm_put(gt->uncore->rpm, wakeref);
	igt_global_reset_unlock(gt);
	kfree(lists);

	igt_flush_test(gt->i915);

	return ret;
}

int intel_workarounds_live_selftests(struct drm_i915_private *i915)
{
	static const struct i915_subtest tests[] = {
		SUBTEST(live_dirty_whitelist),
		SUBTEST(live_reset_whitelist),
		SUBTEST(live_isolated_whitelist),
		SUBTEST(live_gpu_reset_workarounds),
		SUBTEST(live_engine_reset_workarounds),
	};

	if (intel_gt_is_wedged(to_gt(i915)))
		return 0;

	return intel_gt_live_subtests(tests, to_gt(i915));
}
