All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH igt] igt/gem_ctx_isolation: Check isolation of registers between contexts
@ 2017-10-24 11:07 Chris Wilson
  2017-10-24 11:16 ` Chris Wilson
                   ` (10 more replies)
  0 siblings, 11 replies; 13+ messages in thread
From: Chris Wilson @ 2017-10-24 11:07 UTC (permalink / raw)
  To: intel-gfx

A new context assumes that all of its registers are in the default state
when it is created. What may happen is that a register written by one
context may leak into the second, causing mass confusion.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 tests/Makefile.sources    |   1 +
 tests/gem_ctx_isolation.c | 351 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 352 insertions(+)
 create mode 100644 tests/gem_ctx_isolation.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index ac9f90bc..d18b7461 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -57,6 +57,7 @@ TESTS_progs = \
 	gem_ctx_basic \
 	gem_ctx_create \
 	gem_ctx_exec \
+	gem_ctx_isolation \
 	gem_ctx_param \
 	gem_ctx_switch \
 	gem_ctx_thrash \
diff --git a/tests/gem_ctx_isolation.c b/tests/gem_ctx_isolation.c
new file mode 100644
index 00000000..1569f5a8
--- /dev/null
+++ b/tests/gem_ctx_isolation.c
@@ -0,0 +1,351 @@
+/*
+ * Copyright © 2017 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 "igt.h"
+#include "igt_dummyload.h"
+
+#define MAX_REG 0x40000
+#define NUM_REGS (MAX_REG / sizeof(uint32_t))
+
+#define PAGE_ALIGN(x) ALIGN(x, 4096)
+
+#define DIRTY 0x1
+#define UNSAFE 0x2
+
+enum {
+	RCS_MASK = 0x1,
+	BCS_MASK = 0x2,
+	VCS_MASK = 0x4,
+	VECS_MASK = 0x8,
+};
+
+#define ALL ~0u
+#define GEN_RANGE(x, y) ((ALL >> (32 - (y - x + 1))) << x)
+
+static const struct named_register {
+	const char *name;
+	unsigned int gen_mask;
+	unsigned int engine_mask;
+	uint32_t offset;
+} safe_registers[] = {
+	/* Keep in ascending offset order */
+	{ "CTX_PREEMPT", GEN_RANGE(9, 10), RCS_MASK, 0x2248 },
+	{ "CS_CHICKEN1", GEN_RANGE(9, 10), RCS_MASK, 0x2580 },
+	{ "HDC_CHICKEN1", GEN_RANGE(9, 10), RCS_MASK, 0x7304 },
+	{ "L3SQREG1", GEN_RANGE(8, 10), RCS_MASK, 0xb010 },
+	{}
+}, ignore_registers[] = {
+	{ "RCS timestamp", ALL, RCS_MASK, 0x2358 },
+	{ "VCS0 timestamp", ALL, VCS_MASK, 0x12358 },
+	{ "VCS1 timestamp", ALL, VCS_MASK, 0x1c358 },
+	{ "BCS timestamp", ALL, BCS_MASK, 0x22358 },
+	{ "VECS timestamp", ALL, VECS_MASK, 0x1a358 },
+	{}
+};
+
+static const char *register_name(uint32_t offset)
+{
+	/* XXX bsearch? */
+	for (const struct named_register *r = safe_registers; r->name; r++) {
+		if (r->offset == offset)
+			return r->name;
+	}
+
+	return "unknown";
+}
+
+static bool ignore_register(uint32_t offset)
+{
+	for (const struct named_register *r = ignore_registers; r->name; r++) {
+		if (r->offset == offset)
+			return true;
+	}
+
+	return false;
+}
+
+static uint32_t read_all_regs(int fd,
+			      uint32_t ctx, unsigned int engine,
+			      unsigned int flags)
+{
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_relocation_entry *reloc;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	unsigned int regs_size, batch_size;
+	unsigned int engine_bit, gen_bit;
+	uint32_t *batch, *b;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << intel_gen(intel_get_drm_devid(fd));
+
+	reloc = calloc(NUM_REGS, sizeof(*reloc));
+	igt_assert(reloc);
+
+	regs_size = NUM_REGS * sizeof(uint32_t);
+	regs_size = PAGE_ALIGN(regs_size);
+
+	batch_size = NUM_REGS * 4 * sizeof(uint32_t) + 4;
+	batch_size = PAGE_ALIGN(batch_size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = gem_create(fd, regs_size);
+	obj[1].handle = gem_create(fd, batch_size);
+	obj[1].relocs_ptr = to_user_pointer(reloc);
+
+	b = batch = gem_mmap__cpu(fd, obj[1].handle, 0, batch_size, PROT_WRITE);
+	if (flags & UNSAFE) {
+		for (unsigned int n = 0; n < NUM_REGS; n++) {
+			*b++ = 0x24 << 23 | 2;
+			*b++ = n * sizeof(uint32_t);
+			reloc[n].target_handle = obj[0].handle;
+			reloc[n].presumed_offset = 0;
+			reloc[n].offset = (b - batch) * sizeof(*b);
+			reloc[n].delta = sizeof(uint32_t) * n;
+			reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+			reloc[n].write_domain = I915_GEM_DOMAIN_RENDER;
+			*b++ = reloc[n].delta;
+			*b++ = 0;
+		}
+		obj[1].relocation_count = NUM_REGS;
+	} else {
+		unsigned int n = 0;
+
+		for (const struct named_register *r = safe_registers;
+		     r->name; r++) {
+			if (!(r->engine_mask & engine_bit))
+				continue;
+			if (!(r->gen_mask & gen_bit))
+				continue;
+
+			*b++ = 0x24 << 23 | 2; /* SRM */
+			*b++ = r->offset;
+			reloc[n].target_handle = obj[0].handle;
+			reloc[n].presumed_offset = 0;
+			reloc[n].offset = (b - batch) * sizeof(*b);
+			reloc[n].delta = r->offset;
+			reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+			reloc[n].write_domain = I915_GEM_DOMAIN_RENDER;
+			*b++ = reloc[n].delta;
+			*b++ = 0;
+
+			n++;
+		}
+
+		obj[1].relocation_count = n;
+	}
+	*b++ = MI_BATCH_BUFFER_END;
+	munmap(batch, batch_size);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 2;
+	execbuf.flags = engine;
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj[1].handle);
+	free(reloc);
+
+	return obj[0].handle;
+}
+
+static void write_all_regs(int fd,
+			   uint32_t ctx, unsigned int engine,
+			   unsigned int flags)
+{
+	struct drm_i915_gem_exec_object2 obj;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	unsigned int engine_bit, gen_bit;
+	unsigned int batch_size;
+	uint32_t *batch, *b;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << intel_gen(intel_get_drm_devid(fd));
+
+	batch_size = NUM_REGS * 3 * sizeof(uint32_t) + 4;
+	batch_size = PAGE_ALIGN(batch_size);
+
+	memset(&obj, 0, sizeof(obj));
+	obj.handle = gem_create(fd, batch_size);
+	b = batch = gem_mmap__cpu(fd, obj.handle, 0, batch_size, PROT_WRITE);
+	if (flags & UNSAFE) {
+		for (unsigned int n = 0; n < NUM_REGS; n++) {
+			*b++ = 0x23 << 23 | 2; /* LRI */
+			*b++ = n * sizeof(uint32_t);
+			*b++ = 0xdeadbeef;
+		}
+	} else {
+		for (const struct named_register *r = safe_registers;
+		     r->name; r++) {
+			if (!(r->engine_mask & engine_bit))
+				continue;
+			if (!(r->gen_mask & gen_bit))
+				continue;
+			*b++ = 0x23 << 23 | 2; /* LRI */
+			*b++ = r->offset;
+			*b++ = 0xdeadbeef;
+		}
+	}
+	*b++ = MI_BATCH_BUFFER_END;
+	munmap(batch, batch_size);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(&obj);
+	execbuf.buffer_count = 1;
+	execbuf.flags = engine;
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj.handle);
+}
+
+static void compare_regs(int fd, uint32_t regs[2])
+{
+	unsigned int num_errors;
+	unsigned int regs_size;
+	uint32_t *a, *b;
+
+	regs_size = NUM_REGS * sizeof(uint32_t);
+	regs_size = PAGE_ALIGN(regs_size);
+
+	a = gem_mmap__cpu(fd, regs[0], 0, regs_size, PROT_READ);
+	gem_set_domain(fd, regs[0], I915_GEM_DOMAIN_CPU, 0);
+
+	b = gem_mmap__cpu(fd, regs[1], 0, regs_size, PROT_READ);
+	gem_set_domain(fd, regs[1], I915_GEM_DOMAIN_CPU, 0);
+
+	num_errors = 0;
+	for (unsigned int n = 0; n < NUM_REGS; n++) {
+		if (a[n] != b[n] && !ignore_register(n*sizeof(uint32_t))) {
+			igt_warn("Register 0x%04x [%s]: A=%08x B=%08x\n",
+				 n, register_name(n*sizeof(uint32_t)),
+				 a[n], b[n]);
+			num_errors++;
+		}
+	}
+	munmap(b, regs_size);
+	munmap(a, regs_size);
+
+	igt_assert_f(num_errors == 0,
+		     "%d registers mistached between two virgin contexts\n",
+		     num_errors);
+}
+
+static void isolation(int fd, unsigned int engine, unsigned int flags)
+{
+	igt_spin_t *spin = NULL;
+	uint32_t ctx[2];
+	uint32_t regs[2];
+
+	ctx[0] = gem_context_create(fd);
+	regs[0] = read_all_regs(fd, ctx[0], engine, flags);
+
+	if (flags & DIRTY) {
+		spin = igt_spin_batch_new(fd, ctx[0], engine, 0);
+		write_all_regs(fd, ctx[0], engine, flags);
+	}
+
+	/*
+	 * We create and execute a new context, whilst the HW is occupied
+	 * with the previous context (we should switch from the old to the
+	 * new proto context without idling, which could then load the
+	 * powercontext). If all goes well, we only see the default values
+	 * from this context, but if goes badly we see the corruption from
+	 * the previous context instead!
+	 */
+	ctx[1] = gem_context_create(fd);
+	regs[1] = read_all_regs(fd, ctx[1], engine, flags);
+
+	igt_spin_batch_free(fd, spin);
+
+	compare_regs(fd, regs);
+
+	for (int n = 0; n < ARRAY_SIZE(ctx); n++) {
+		gem_close(fd, regs[n]);
+		gem_context_destroy(fd, ctx[n]);
+	}
+}
+
+igt_main
+{
+	const unsigned int platform_validation = 0;
+	int fd = -1;
+
+	igt_fixture {
+		fd = drm_open_driver(DRIVER_INTEL);
+		igt_require_gem(fd);
+
+		igt_require(gem_has_execlists(fd));
+
+		/* check that we can create contexts. */
+		gem_context_destroy(fd, gem_context_create(fd));
+	}
+
+	for (const struct intel_execution_engine *e =
+			intel_execution_engines; e->name; e++) {
+		igt_subtest_group {
+			unsigned int engine = e->exec_id | e->flags;
+			igt_fixture {
+				gem_require_ring(fd, engine);
+			}
+
+			igt_subtest_f("%s-clean", e->name)
+				isolation(fd, engine, 0);
+			igt_subtest_f("%s-dirty", e->name)
+				isolation(fd, engine, DIRTY);
+
+			igt_subtest_f("%s-unsafe", e->name) {
+				igt_require(platform_validation);
+				isolation(fd, engine, DIRTY | UNSAFE);
+			}
+		}
+	}
+}
-- 
2.15.0.rc1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH igt] igt/gem_ctx_isolation: Check isolation of registers between contexts
  2017-10-24 11:07 [PATCH igt] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
@ 2017-10-24 11:16 ` Chris Wilson
  2017-10-24 12:52 ` [PATCH v2] drm-auth Chris Wilson
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Chris Wilson @ 2017-10-24 11:16 UTC (permalink / raw)
  To: intel-gfx

Quoting Chris Wilson (2017-10-24 12:07:58)
> A new context assumes that all of its registers are in the default state
> when it is created. What may happen is that a register written by one
> context may leak into the second, causing mass confusion.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>  tests/Makefile.sources    |   1 +
>  tests/gem_ctx_isolation.c | 351 ++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 352 insertions(+)
>  create mode 100644 tests/gem_ctx_isolation.c
> 
> diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> index ac9f90bc..d18b7461 100644
> --- a/tests/Makefile.sources
> +++ b/tests/Makefile.sources
> @@ -57,6 +57,7 @@ TESTS_progs = \
>         gem_ctx_basic \
>         gem_ctx_create \
>         gem_ctx_exec \
> +       gem_ctx_isolation \
>         gem_ctx_param \
>         gem_ctx_switch \
>         gem_ctx_thrash \
> diff --git a/tests/gem_ctx_isolation.c b/tests/gem_ctx_isolation.c
> new file mode 100644
> index 00000000..1569f5a8
> --- /dev/null
> +++ b/tests/gem_ctx_isolation.c
> @@ -0,0 +1,351 @@
> +/*
> + * Copyright © 2017 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 "igt.h"
> +#include "igt_dummyload.h"
> +
> +#define MAX_REG 0x40000
> +#define NUM_REGS (MAX_REG / sizeof(uint32_t))
> +
> +#define PAGE_ALIGN(x) ALIGN(x, 4096)
> +
> +#define DIRTY 0x1
> +#define UNSAFE 0x2
> +
> +enum {
> +       RCS_MASK = 0x1,
> +       BCS_MASK = 0x2,
> +       VCS_MASK = 0x4,
> +       VECS_MASK = 0x8,
> +};

We be nice to include these in the future intel_engine interface!

> +#define ALL ~0u
> +#define GEN_RANGE(x, y) ((ALL >> (32 - (y - x + 1))) << x)
> +
> +static const struct named_register {
> +       const char *name;
> +       unsigned int gen_mask;
> +       unsigned int engine_mask;
> +       uint32_t offset;
> +} safe_registers[] = {

This list is incomplete, we need the list of nonpriv registers.

> +       /* Keep in ascending offset order */
> +       { "CTX_PREEMPT", GEN_RANGE(9, 10), RCS_MASK, 0x2248 },
> +       { "CS_CHICKEN1", GEN_RANGE(9, 10), RCS_MASK, 0x2580 },
> +       { "HDC_CHICKEN1", GEN_RANGE(9, 10), RCS_MASK, 0x7304 },
> +       { "L3SQREG1", GEN_RANGE(8, 10), RCS_MASK, 0xb010 },
> +       {}
> +}, ignore_registers[] = {
> +       { "RCS timestamp", ALL, RCS_MASK, 0x2358 },
> +       { "VCS0 timestamp", ALL, VCS_MASK, 0x12358 },
> +       { "VCS1 timestamp", ALL, VCS_MASK, 0x1c358 },
> +       { "BCS timestamp", ALL, BCS_MASK, 0x22358 },
> +       { "VECS timestamp", ALL, VECS_MASK, 0x1a358 },
> +       {}
> +};

> +igt_main
> +{
> +       const unsigned int platform_validation = 0;

So UNSAFE is decidedly unsafe; is there anyway we can run tests only
during PV?

> +       int fd = -1;
> +
> +       igt_fixture {
> +               fd = drm_open_driver(DRIVER_INTEL);
> +               igt_require_gem(fd);
> +
> +               igt_require(gem_has_execlists(fd));

And we need an igt_ci_fail_on(gen >= KNOWN_GEN);

> +               /* check that we can create contexts. */
> +               gem_context_destroy(fd, gem_context_create(fd));
> +       }
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2] drm-auth
  2017-10-24 11:07 [PATCH igt] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
  2017-10-24 11:16 ` Chris Wilson
@ 2017-10-24 12:52 ` Chris Wilson
  2017-10-24 12:58 ` [PATCH igt v2] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Chris Wilson @ 2017-10-24 12:52 UTC (permalink / raw)
  To: intel-gfx

---
 drivers/gpu/drm/drm_auth.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 4c14b2cbc733..c40e603e0559 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -285,7 +285,8 @@ void drm_master_release(struct drm_file *file_priv)
 	if (dev->master == file_priv->master)
 		drm_drop_master(dev, file_priv);
 out:
-	if (file_priv->is_master) {
+	if (drm_core_check_feature(dev, DRIVER_MODESET) &&
+	    file_priv->is_master) {
 		/* Revoke any leases held by this or lessees, but only if
 		 * this is the "real" master
 		 */
-- 
2.15.0.rc1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH igt v2] igt/gem_ctx_isolation: Check isolation of registers between contexts
  2017-10-24 11:07 [PATCH igt] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
  2017-10-24 11:16 ` Chris Wilson
  2017-10-24 12:52 ` [PATCH v2] drm-auth Chris Wilson
@ 2017-10-24 12:58 ` Chris Wilson
  2017-10-24 13:42 ` ✗ Fi.CI.BAT: failure for drm-auth Patchwork
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Chris Wilson @ 2017-10-24 12:58 UTC (permalink / raw)
  To: intel-gfx

A new context assumes that all of its registers are in the default state
when it is created. What may happen is that a register written by one
context may leak into the second, causing mass confusion.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 tests/Makefile.sources    |   1 +
 tests/gem_ctx_isolation.c | 650 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 651 insertions(+)
 create mode 100644 tests/gem_ctx_isolation.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index ac9f90bc..d18b7461 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -57,6 +57,7 @@ TESTS_progs = \
 	gem_ctx_basic \
 	gem_ctx_create \
 	gem_ctx_exec \
+	gem_ctx_isolation \
 	gem_ctx_param \
 	gem_ctx_switch \
 	gem_ctx_thrash \
diff --git a/tests/gem_ctx_isolation.c b/tests/gem_ctx_isolation.c
new file mode 100644
index 00000000..0bbc2279
--- /dev/null
+++ b/tests/gem_ctx_isolation.c
@@ -0,0 +1,650 @@
+/*
+ * Copyright © 2017 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 "igt.h"
+#include "igt_dummyload.h"
+
+#define MAX_REG 0x40000
+#define NUM_REGS (MAX_REG / sizeof(uint32_t))
+
+#define PAGE_ALIGN(x) ALIGN(x, 4096)
+
+#define DIRTY 0x1
+#define UNSAFE 0x2
+
+enum {
+	RCS_MASK = 0x1,
+	BCS_MASK = 0x2,
+	VCS_MASK = 0x4,
+	VECS_MASK = 0x8,
+};
+
+#define ALL ~0u
+#define GEN_RANGE(x, y) ((ALL >> (32 - (y - x + 1))) << x)
+
+#define LAST_KNOWN_GEN 10
+
+static const struct named_register {
+	const char *name;
+	unsigned int gen_mask;
+	unsigned int engine_mask;
+	uint32_t offset;
+} safe_registers[] = {
+	{ "NOPID", ALL, RCS_MASK, 0x2094 },
+	{ "MI_PREDICATE_RESULT_2", ALL, RCS_MASK, 0x23bc },
+	{ "INSTPM", ALL, RCS_MASK, 0x20c0 },
+	{ "IA_VERTICES_COUNT (low)", ALL, RCS_MASK, 0x2310 },
+	{ "IA_VERTICES_COUNT (high)", ALL, RCS_MASK, 0x2314 },
+	{ "IA_PRIMITIVES_COUNT (low)", ALL, RCS_MASK, 0x2318 },
+	{ "IA_PRIMITIVES_COUNT (high)", ALL, RCS_MASK, 0x231c },
+	{ "VS_INVOCATION_COUNT (low)", ALL, RCS_MASK, 0x2320 },
+	{ "VS_INVOCATION_COUNT (high)", ALL, RCS_MASK, 0x2324 },
+	{ "HS_INVOCATION_COUNT (low)", ALL, RCS_MASK, 0x2300 },
+	{ "HS_INVOCATION_COUNT (high)", ALL, RCS_MASK, 0x2304 },
+	{ "DS_INVOCATION_COUNT (low)", ALL, RCS_MASK, 0x2308 },
+	{ "DS_INVOCATION_COUNT (high)", ALL, RCS_MASK, 0x230c },
+	{ "GS_INVOCATION_COUNT (low)", ALL, RCS_MASK, 0x2328 },
+	{ "GS_INVOCATION_COUNT (high)", ALL, RCS_MASK, 0x232c },
+	{ "GS_PRIMITIVES_COUNT (low)", ALL, RCS_MASK, 0x2330 },
+	{ "GS_PRIMITIVES_COUNT (high)", ALL, RCS_MASK, 0x2334 },
+	{ "CL_INVOCATION_COUNT (low)", ALL, RCS_MASK, 0x2338 },
+	{ "CL_INVOCATION_COUNT (high)", ALL, RCS_MASK, 0x233c },
+	{ "CL_PRIMITIVES_COUNT (low)", ALL, RCS_MASK, 0x2340 },
+	{ "CL_PRIMITIVES_COUNT (high)", ALL, RCS_MASK, 0x2344 },
+	{ "PS_INVOCATION_COUNT_0 (low)", ALL, RCS_MASK, 0x22c8 },
+	{ "PS_INVOCATION_COUNT_0 (high)", ALL, RCS_MASK, 0x22cc },
+	{ "PS_DEPTH_COUNT_0 (low)", ALL, RCS_MASK, 0x22d8 },
+	{ "PS_DEPTH_COUNT_0 (high)", ALL, RCS_MASK, 0x22dc },
+	{ "GPUGPU_DISPATCHDIMX", ALL, RCS_MASK, 0x2500 },
+	{ "GPUGPU_DISPATCHDIMY", ALL, RCS_MASK, 0x2504 },
+	{ "GPUGPU_DISPATCHDIMZ", ALL, RCS_MASK, 0x2508 },
+	{ "MI_PREDICATE_SRC0 (low)", ALL, RCS_MASK, 0x2400 },
+	{ "MI_PREDICATE_SRC0 (high)", ALL, RCS_MASK, 0x2404 },
+	{ "MI_PREDICATE_SRC1 (low)", ALL, RCS_MASK, 0x2408 },
+	{ "MI_PREDICATE_SRC1 (high)", ALL, RCS_MASK, 0x240c },
+	{ "MI_PREDICATE_DATA (low)", ALL, RCS_MASK, 0x2410 },
+	{ "MI_PREDICATE_DATA (high)", ALL, RCS_MASK, 0x2414 },
+	{ "MI_PRED_RESULT", ALL, RCS_MASK, 0x2418 },
+	{ "3DPRIM_END_OFFSET", ALL, RCS_MASK, 0x2420 },
+	{ "3DPRIM_START_VERTEX", ALL, RCS_MASK, 0x2430 },
+	{ "3DPRIM_VERTEX_COUNT", ALL, RCS_MASK, 0x2434 },
+	{ "3DPRIM_INSTANCE_COUNT", ALL, RCS_MASK, 0x2438 },
+	{ "3DPRIM_START_INSTANCE", ALL, RCS_MASK, 0x243c },
+	{ "3DPRIM_BASE_VERTEX", ALL, RCS_MASK, 0x2440 },
+	{ "GPGPU_THREADS_DISPATCHED (low)", ALL, RCS_MASK, 0x2290 },
+	{ "GPGPU_THREADS_DISPATCHED (high)", ALL, RCS_MASK, 0x2294 },
+	{ "PS_INVOCATION_COUNT_1 (low)", ALL, RCS_MASK, 0x22f0 },
+	{ "PS_INVOCATION_COUNT_1 (high)", ALL, RCS_MASK, 0x22f4 },
+	{ "PS_DEPTH_COUNT_1 (low)", ALL, RCS_MASK, 0x22f8 },
+	{ "PS_DEPTH_COUNT_1 (high)", ALL, RCS_MASK, 0x22fc },
+	{ "BB_OFFSET", ALL, RCS_MASK, 0x2158 },
+	{ "MI_PREDICATE_RESULT_1", ALL, RCS_MASK, 0x241c },
+	{ "CS_GPR[0]", ALL, RCS_MASK, 0x2600 },
+	{ "CS_GPR[1]", ALL, RCS_MASK, 0x2604 },
+	{ "CS_GPR[2]", ALL, RCS_MASK, 0x2608 },
+	{ "CS_GPR[3]", ALL, RCS_MASK, 0x260c },
+	{ "CS_GPR[4]", ALL, RCS_MASK, 0x2610 },
+	{ "CS_GPR[5]", ALL, RCS_MASK, 0x2614 },
+	{ "CS_GPR[6]", ALL, RCS_MASK, 0x2618 },
+	{ "CS_GPR[7]", ALL, RCS_MASK, 0x261c },
+	{ "CS_GPR[8]", ALL, RCS_MASK, 0x2620 },
+	{ "CS_GPR[9]", ALL, RCS_MASK, 0x2624 },
+	{ "CS_GPR[10]", ALL, RCS_MASK, 0x2628 },
+	{ "CS_GPR[11]", ALL, RCS_MASK, 0x262c },
+	{ "CS_GPR[12]", ALL, RCS_MASK, 0x2630 },
+	{ "CS_GPR[13]", ALL, RCS_MASK, 0x2634 },
+	{ "CS_GPR[14]", ALL, RCS_MASK, 0x2638 },
+	{ "CS_GPR[15]", ALL, RCS_MASK, 0x263c },
+	{ "CS_GPR[16]", ALL, RCS_MASK, 0x2640 },
+	{ "CS_GPR[17]", ALL, RCS_MASK, 0x2644 },
+	{ "CS_GPR[18]", ALL, RCS_MASK, 0x2648 },
+	{ "CS_GPR[19]", ALL, RCS_MASK, 0x264c },
+	{ "CS_GPR[20]", ALL, RCS_MASK, 0x2650 },
+	{ "CS_GPR[21]", ALL, RCS_MASK, 0x2654 },
+	{ "CS_GPR[22]", ALL, RCS_MASK, 0x2658 },
+	{ "CS_GPR[23]", ALL, RCS_MASK, 0x265c },
+	{ "CS_GPR[24]", ALL, RCS_MASK, 0x2660 },
+	{ "CS_GPR[25]", ALL, RCS_MASK, 0x2664 },
+	{ "CS_GPR[26]", ALL, RCS_MASK, 0x2668 },
+	{ "CS_GPR[27]", ALL, RCS_MASK, 0x266c },
+	{ "CS_GPR[28]", ALL, RCS_MASK, 0x2670 },
+	{ "CS_GPR[29]", ALL, RCS_MASK, 0x2674 },
+	{ "CS_GPR[30]", ALL, RCS_MASK, 0x2678 },
+	{ "CS_GPR[31]", ALL, RCS_MASK, 0x267c },
+	{ "OA_CTX_CONTROL", ALL, RCS_MASK, 0x2360 },
+	{ "OACTXID", ALL, RCS_MASK, 0x2364 },
+	{ "PS_INVOCATION_COUNT_2 (log)", ALL, RCS_MASK, 0x2448 },
+	{ "PS_INVOCATION_COUNT_2 (high)", ALL, RCS_MASK, 0x244c },
+	{ "PS_DEPTH_COUNT_2 (log)", ALL, RCS_MASK, 0x2450 },
+	{ "PS_DEPTH_COUNT_2 (high)", ALL, RCS_MASK, 0x245c },
+	{ "Cache_Mode_0", ALL, RCS_MASK, 0x7000 },
+	{ "Cache_Mode_1", ALL, RCS_MASK, 0x7004 },
+	{ "GT_MODE", ALL, RCS_MASK, 0x7008 },
+	{ "L3_Config", ALL, RCS_MASK, 0x7034 },
+	{ "TD_CTL", ALL, RCS_MASK, 0xe400 },
+	{ "TD_CTL2", ALL, RCS_MASK, 0xe404 },
+	{ "SO_NUM_PRIMS_WRITEN0 (low)", ALL, RCS_MASK, 0x5200 },
+	{ "SO_NUM_PRIMS_WRITEN0 (high)", ALL, RCS_MASK, 0x5204 },
+	{ "SO_NUM_PRIMS_WRITEN1 (low)", ALL, RCS_MASK, 0x5208 },
+	{ "SO_NUM_PRIMS_WRITEN1 (high)", ALL, RCS_MASK, 0x520c },
+	{ "SO_NUM_PRIMS_WRITEN2 (low)", ALL, RCS_MASK, 0x5210 },
+	{ "SO_NUM_PRIMS_WRITEN2 (high)", ALL, RCS_MASK, 0x521c },
+	{ "SO_NUM_PRIMS_WRITEN3 (low)", ALL, RCS_MASK, 0x5218 },
+	{ "SO_NUM_PRIMS_WRITEN3 (high)", ALL, RCS_MASK, 0x521c },
+	{ "SO_PRIM_STORAGE_NEEDED0 (low)", ALL, RCS_MASK, 0x5240 },
+	{ "SO_PRIM_STORAGE_NEEDED0 (high)", ALL, RCS_MASK, 0x5244 },
+	{ "SO_PRIM_STORAGE_NEEDED1 (low)", ALL, RCS_MASK, 0x5248 },
+	{ "SO_PRIM_STORAGE_NEEDED1 (high)", ALL, RCS_MASK, 0x524c },
+	{ "SO_PRIM_STORAGE_NEEDED2 (low)", ALL, RCS_MASK, 0x5250 },
+	{ "SO_PRIM_STORAGE_NEEDED2 (high)", ALL, RCS_MASK, 0x5254 },
+	{ "SO_PRIM_STORAGE_NEEDED3 (low)", ALL, RCS_MASK, 0x5258 },
+	{ "SO_PRIM_STORAGE_NEEDED3 (high)", ALL, RCS_MASK, 0x525c },
+	{ "SO_WRITE_OFFSET0", ALL, RCS_MASK, 0x5280 },
+	{ "SO_WRITE_OFFSET1", ALL, RCS_MASK, 0x5284 },
+	{ "SO_WRITE_OFFSET2", ALL, RCS_MASK, 0x5288 },
+	{ "SO_WRITE_OFFSET3", ALL, RCS_MASK, 0x528c },
+	{ "OA_CONTROL", ALL, RCS_MASK, 0x2b00 },
+	{ "PERF_CNT_1_DW0", ALL, RCS_MASK, 0x91b8 },
+	{ "PERF_CNT_1_DW1", ALL, RCS_MASK, 0x91bc },
+	{ "PERF_CNT_2_DW0", ALL, RCS_MASK, 0x91c0 },
+	{ "PERF_CNT_2_DW1", ALL, RCS_MASK, 0x91c4 },
+	/* Privileged (enabled by w/a + FORCE_TO_NONPRIV) */
+	{ "CTX_PREEMPT", GEN_RANGE(9, 10), RCS_MASK, 0x2248 },
+	{ "CS_CHICKEN1", GEN_RANGE(9, 10), RCS_MASK, 0x2580 },
+	{ "HDC_CHICKEN1", GEN_RANGE(9, 10), RCS_MASK, 0x7304 },
+	{ "L3SQREG1", ALL, RCS_MASK, 0xb010 },
+
+	{ "BCS_GPR[0]", ALL, BCS_MASK, 0x22600 },
+	{ "BCS_GPR[1]", ALL, BCS_MASK, 0x22604 },
+	{ "BCS_GPR[2]", ALL, BCS_MASK, 0x22608 },
+	{ "BCS_GPR[3]", ALL, BCS_MASK, 0x2260c },
+	{ "BCS_GPR[4]", ALL, BCS_MASK, 0x22610 },
+	{ "BCS_GPR[5]", ALL, BCS_MASK, 0x22614 },
+	{ "BCS_GPR[6]", ALL, BCS_MASK, 0x22618 },
+	{ "BCS_GPR[7]", ALL, BCS_MASK, 0x2261c },
+	{ "BCS_GPR[8]", ALL, BCS_MASK, 0x22620 },
+	{ "BCS_GPR[9]", ALL, BCS_MASK, 0x22624 },
+	{ "BCS_GPR[10]", ALL, BCS_MASK, 0x22628 },
+	{ "BCS_GPR[11]", ALL, BCS_MASK, 0x2262c },
+	{ "BCS_GPR[12]", ALL, BCS_MASK, 0x22630 },
+	{ "BCS_GPR[13]", ALL, BCS_MASK, 0x22634 },
+	{ "BCS_GPR[14]", ALL, BCS_MASK, 0x22638 },
+	{ "BCS_GPR[15]", ALL, BCS_MASK, 0x2263c },
+	{ "BCS_GPR[16]", ALL, BCS_MASK, 0x22640 },
+	{ "BCS_GPR[17]", ALL, BCS_MASK, 0x22644 },
+	{ "BCS_GPR[18]", ALL, BCS_MASK, 0x22648 },
+	{ "BCS_GPR[19]", ALL, BCS_MASK, 0x2264c },
+	{ "BCS_GPR[20]", ALL, BCS_MASK, 0x22650 },
+	{ "BCS_GPR[21]", ALL, BCS_MASK, 0x22654 },
+	{ "BCS_GPR[22]", ALL, BCS_MASK, 0x22658 },
+	{ "BCS_GPR[23]", ALL, BCS_MASK, 0x2265c },
+	{ "BCS_GPR[24]", ALL, BCS_MASK, 0x22660 },
+	{ "BCS_GPR[25]", ALL, BCS_MASK, 0x22664 },
+	{ "BCS_GPR[26]", ALL, BCS_MASK, 0x22668 },
+	{ "BCS_GPR[27]", ALL, BCS_MASK, 0x2266c },
+	{ "BCS_GPR[28]", ALL, BCS_MASK, 0x22670 },
+	{ "BCS_GPR[29]", ALL, BCS_MASK, 0x22674 },
+	{ "BCS_GPR[30]", ALL, BCS_MASK, 0x22678 },
+	{ "BCS_GPR[31]", ALL, BCS_MASK, 0x2267c },
+	{ "BCS_SWCTRL[0]", ALL, BCS_MASK, 0x22200 },
+	{ "BCS_SWCTRL[1]", ALL, BCS_MASK, 0x22204 },
+	{ "BCS_SWCTRL[2]", ALL, BCS_MASK, 0x22208 },
+	{ "BCS_SWCTRL[3]", ALL, BCS_MASK, 0x2220c },
+	{ "BCS_SWCTRL[4]", ALL, BCS_MASK, 0x22210 },
+	{ "BCS_SWCTRL[5]", ALL, BCS_MASK, 0x22214 },
+	{ "BCS_SWCTRL[6]", ALL, BCS_MASK, 0x22218 },
+	{ "BCS_SWCTRL[7]", ALL, BCS_MASK, 0x2221c },
+	{ "BCS_SWCTRL[8]", ALL, BCS_MASK, 0x22220 },
+	{ "BCS_SWCTRL[9]", ALL, BCS_MASK, 0x22224 },
+	{ "BCS_SWCTRL[10]", ALL, BCS_MASK, 0x22228 },
+	{ "BCS_SWCTRL[11]", ALL, BCS_MASK, 0x2222c },
+	{ "BCS_SWCTRL[12]", ALL, BCS_MASK, 0x22230 },
+	{ "BCS_SWCTRL[13]", ALL, BCS_MASK, 0x22234 },
+	{ "BCS_SWCTRL[14]", ALL, BCS_MASK, 0x22238 },
+	{ "BCS_SWCTRL[15]", ALL, BCS_MASK, 0x2223c },
+	{ "BCS_SWCTRL[16]", ALL, BCS_MASK, 0x22240 },
+	{ "BCS_SWCTRL[17]", ALL, BCS_MASK, 0x22244 },
+	{ "BCS_SWCTRL[18]", ALL, BCS_MASK, 0x22248 },
+	{ "BCS_SWCTRL[19]", ALL, BCS_MASK, 0x2224c },
+	{ "BCS_SWCTRL[20]", ALL, BCS_MASK, 0x22250 },
+	{ "BCS_SWCTRL[21]", ALL, BCS_MASK, 0x22254 },
+	{ "BCS_SWCTRL[22]", ALL, BCS_MASK, 0x22258 },
+	{ "BCS_SWCTRL[23]", ALL, BCS_MASK, 0x2225c },
+	{ "BCS_SWCTRL[24]", ALL, BCS_MASK, 0x22260 },
+	{ "BCS_SWCTRL[25]", ALL, BCS_MASK, 0x22264 },
+	{ "BCS_SWCTRL[26]", ALL, BCS_MASK, 0x22268 },
+	{ "BCS_SWCTRL[27]", ALL, BCS_MASK, 0x2226c },
+	{ "BCS_SWCTRL[28]", ALL, BCS_MASK, 0x22270 },
+	{ "BCS_SWCTRL[29]", ALL, BCS_MASK, 0x22274 },
+	{ "BCS_SWCTRL[30]", ALL, BCS_MASK, 0x22278 },
+	{ "BCS_SWCTRL[31]", ALL, BCS_MASK, 0x2227c },
+
+	{ "VCS0_GPR[0]", ALL, VCS_MASK, 0x12600 },
+	{ "VCS0_GPR[1]", ALL, VCS_MASK, 0x12604 },
+	{ "VCS0_GPR[2]", ALL, VCS_MASK, 0x12608 },
+	{ "VCS0_GPR[3]", ALL, VCS_MASK, 0x1260c },
+	{ "VCS0_GPR[4]", ALL, VCS_MASK, 0x12610 },
+	{ "VCS0_GPR[5]", ALL, VCS_MASK, 0x12614 },
+	{ "VCS0_GPR[6]", ALL, VCS_MASK, 0x12618 },
+	{ "VCS0_GPR[7]", ALL, VCS_MASK, 0x1261c },
+	{ "VCS0_GPR[8]", ALL, VCS_MASK, 0x12620 },
+	{ "VCS0_GPR[9]", ALL, VCS_MASK, 0x12624 },
+	{ "VCS0_GPR[10]", ALL, VCS_MASK, 0x12628 },
+	{ "VCS0_GPR[11]", ALL, VCS_MASK, 0x1262c },
+	{ "VCS0_GPR[12]", ALL, VCS_MASK, 0x12630 },
+	{ "VCS0_GPR[13]", ALL, VCS_MASK, 0x12634 },
+	{ "VCS0_GPR[14]", ALL, VCS_MASK, 0x12638 },
+	{ "VCS0_GPR[15]", ALL, VCS_MASK, 0x1263c },
+	{ "VCS0_GPR[16]", ALL, VCS_MASK, 0x22640 },
+	{ "VCS0_GPR[17]", ALL, VCS_MASK, 0x12644 },
+	{ "VCS0_GPR[18]", ALL, VCS_MASK, 0x12648 },
+	{ "VCS0_GPR[19]", ALL, VCS_MASK, 0x1264c },
+	{ "VCS0_GPR[20]", ALL, VCS_MASK, 0x12650 },
+	{ "VCS0_GPR[21]", ALL, VCS_MASK, 0x12654 },
+	{ "VCS0_GPR[22]", ALL, VCS_MASK, 0x12658 },
+	{ "VCS0_GPR[23]", ALL, VCS_MASK, 0x1265c },
+	{ "VCS0_GPR[24]", ALL, VCS_MASK, 0x12660 },
+	{ "VCS0_GPR[25]", ALL, VCS_MASK, 0x12664 },
+	{ "VCS0_GPR[26]", ALL, VCS_MASK, 0x12668 },
+	{ "VCS0_GPR[27]", ALL, VCS_MASK, 0x1266c },
+	{ "VCS0_GPR[28]", ALL, VCS_MASK, 0x12670 },
+	{ "VCS0_GPR[29]", ALL, VCS_MASK, 0x12674 },
+	{ "VCS0_GPR[30]", ALL, VCS_MASK, 0x12678 },
+	{ "VCS0_GPR[31]", ALL, VCS_MASK, 0x1267c },
+
+	//{ "MFC_VBDOX1[]", ALL, VCS_MASK, 0x12800 }, x 64
+	//{ "MFC_VBDOX2[]", ALL, VCS_MASK, 0x1c800 }, x 64
+
+	{ "VCS1_GPR[0]", ALL, VCS_MASK, 0x1c600 },
+	{ "VCS1_GPR[1]", ALL, VCS_MASK, 0x1c604 },
+	{ "VCS1_GPR[2]", ALL, VCS_MASK, 0x1c608 },
+	{ "VCS1_GPR[3]", ALL, VCS_MASK, 0x1c60c },
+	{ "VCS1_GPR[4]", ALL, VCS_MASK, 0x1c610 },
+	{ "VCS1_GPR[5]", ALL, VCS_MASK, 0x1c614 },
+	{ "VCS1_GPR[6]", ALL, VCS_MASK, 0x1c618 },
+	{ "VCS1_GPR[7]", ALL, VCS_MASK, 0x1c61c },
+	{ "VCS1_GPR[8]", ALL, VCS_MASK, 0x1c620 },
+	{ "VCS1_GPR[9]", ALL, VCS_MASK, 0x1c624 },
+	{ "VCS1_GPR[10]", ALL, VCS_MASK, 0x1c628 },
+	{ "VCS1_GPR[11]", ALL, VCS_MASK, 0x1c62c },
+	{ "VCS1_GPR[12]", ALL, VCS_MASK, 0x1c630 },
+	{ "VCS1_GPR[13]", ALL, VCS_MASK, 0x1c634 },
+	{ "VCS1_GPR[14]", ALL, VCS_MASK, 0x1c638 },
+	{ "VCS1_GPR[15]", ALL, VCS_MASK, 0x1c63c },
+	{ "VCS1_GPR[16]", ALL, VCS_MASK, 0x22640 },
+	{ "VCS1_GPR[17]", ALL, VCS_MASK, 0x1c644 },
+	{ "VCS1_GPR[18]", ALL, VCS_MASK, 0x1c648 },
+	{ "VCS1_GPR[19]", ALL, VCS_MASK, 0x1c64c },
+	{ "VCS1_GPR[20]", ALL, VCS_MASK, 0x1c650 },
+	{ "VCS1_GPR[21]", ALL, VCS_MASK, 0x1c654 },
+	{ "VCS1_GPR[22]", ALL, VCS_MASK, 0x1c658 },
+	{ "VCS1_GPR[23]", ALL, VCS_MASK, 0x1c65c },
+	{ "VCS1_GPR[24]", ALL, VCS_MASK, 0x1c660 },
+	{ "VCS1_GPR[25]", ALL, VCS_MASK, 0x1c664 },
+	{ "VCS1_GPR[26]", ALL, VCS_MASK, 0x1c668 },
+	{ "VCS1_GPR[27]", ALL, VCS_MASK, 0x1c66c },
+	{ "VCS1_GPR[28]", ALL, VCS_MASK, 0x1c670 },
+	{ "VCS1_GPR[29]", ALL, VCS_MASK, 0x1c674 },
+	{ "VCS1_GPR[30]", ALL, VCS_MASK, 0x1c678 },
+	{ "VCS1_GPR[31]", ALL, VCS_MASK, 0x1c67c },
+
+	{ "VECS_GPR[0]", ALL, VECS_MASK, 0x1a600 },
+	{ "VECS_GPR[1]", ALL, VECS_MASK, 0x1a604 },
+	{ "VECS_GPR[2]", ALL, VECS_MASK, 0x1a608 },
+	{ "VECS_GPR[3]", ALL, VECS_MASK, 0x1a60c },
+	{ "VECS_GPR[4]", ALL, VECS_MASK, 0x1a610 },
+	{ "VECS_GPR[5]", ALL, VECS_MASK, 0x1a614 },
+	{ "VECS_GPR[6]", ALL, VECS_MASK, 0x1a618 },
+	{ "VECS_GPR[7]", ALL, VECS_MASK, 0x1a61c },
+	{ "VECS_GPR[8]", ALL, VECS_MASK, 0x1a620 },
+	{ "VECS_GPR[9]", ALL, VECS_MASK, 0x1a624 },
+	{ "VECS_GPR[10]", ALL, VECS_MASK, 0x1a628 },
+	{ "VECS_GPR[11]", ALL, VECS_MASK, 0x1a62c },
+	{ "VECS_GPR[12]", ALL, VECS_MASK, 0x1a630 },
+	{ "VECS_GPR[13]", ALL, VECS_MASK, 0x1a634 },
+	{ "VECS_GPR[14]", ALL, VECS_MASK, 0x1a638 },
+	{ "VECS_GPR[15]", ALL, VECS_MASK, 0x1a63c },
+	{ "VECS_GPR[16]", ALL, VECS_MASK, 0x22640 },
+	{ "VECS_GPR[17]", ALL, VECS_MASK, 0x1a644 },
+	{ "VECS_GPR[18]", ALL, VECS_MASK, 0x1a648 },
+	{ "VECS_GPR[19]", ALL, VECS_MASK, 0x1a64c },
+	{ "VECS_GPR[20]", ALL, VECS_MASK, 0x1a650 },
+	{ "VECS_GPR[21]", ALL, VECS_MASK, 0x1a654 },
+	{ "VECS_GPR[22]", ALL, VECS_MASK, 0x1a658 },
+	{ "VECS_GPR[23]", ALL, VECS_MASK, 0x1a65c },
+	{ "VECS_GPR[24]", ALL, VECS_MASK, 0x1a660 },
+	{ "VECS_GPR[25]", ALL, VECS_MASK, 0x1a664 },
+	{ "VECS_GPR[26]", ALL, VECS_MASK, 0x1a668 },
+	{ "VECS_GPR[27]", ALL, VECS_MASK, 0x1a66c },
+	{ "VECS_GPR[28]", ALL, VECS_MASK, 0x1a670 },
+	{ "VECS_GPR[29]", ALL, VECS_MASK, 0x1a674 },
+	{ "VECS_GPR[30]", ALL, VECS_MASK, 0x1a678 },
+	{ "VECS_GPR[31]", ALL, VECS_MASK, 0x1a67c },
+
+	{}
+}, ignore_registers[] = {
+	{ "RCS timestamp", ALL, RCS_MASK, 0x2358 },
+	{ "VCS0 timestamp", ALL, VCS_MASK, 0x12358 },
+	{ "VCS1 timestamp", ALL, VCS_MASK, 0x1c358 },
+	{ "BCS timestamp", ALL, BCS_MASK, 0x22358 },
+	{ "VECS timestamp", ALL, VECS_MASK, 0x1a358 },
+	{}
+};
+
+static const char *register_name(uint32_t offset)
+{
+	for (const struct named_register *r = safe_registers; r->name; r++) {
+		if (r->offset == offset)
+			return r->name;
+	}
+
+	return "unknown";
+}
+
+static bool ignore_register(uint32_t offset)
+{
+	for (const struct named_register *r = ignore_registers; r->name; r++) {
+		if (r->offset == offset)
+			return true;
+	}
+
+	return false;
+}
+
+static uint32_t read_all_regs(int fd,
+			      uint32_t ctx, unsigned int engine,
+			      unsigned int flags)
+{
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_relocation_entry *reloc;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	unsigned int regs_size, batch_size;
+	unsigned int engine_bit, gen_bit;
+	uint32_t *batch, *b;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << intel_gen(intel_get_drm_devid(fd));
+
+	reloc = calloc(NUM_REGS, sizeof(*reloc));
+	igt_assert(reloc);
+
+	regs_size = NUM_REGS * sizeof(uint32_t);
+	regs_size = PAGE_ALIGN(regs_size);
+
+	batch_size = NUM_REGS * 4 * sizeof(uint32_t) + 4;
+	batch_size = PAGE_ALIGN(batch_size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = gem_create(fd, regs_size);
+	obj[1].handle = gem_create(fd, batch_size);
+	obj[1].relocs_ptr = to_user_pointer(reloc);
+
+	b = batch = gem_mmap__cpu(fd, obj[1].handle, 0, batch_size, PROT_WRITE);
+	gem_set_domain(fd, obj[1].handle,
+		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+
+	if (flags & UNSAFE) {
+		for (unsigned int n = 0; n < NUM_REGS; n++) {
+			*b++ = 0x24 << 23 | 2;
+			*b++ = n * sizeof(uint32_t);
+			reloc[n].target_handle = obj[0].handle;
+			reloc[n].presumed_offset = 0;
+			reloc[n].offset = (b - batch) * sizeof(*b);
+			reloc[n].delta = sizeof(uint32_t) * n;
+			reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+			reloc[n].write_domain = I915_GEM_DOMAIN_RENDER;
+			*b++ = reloc[n].delta;
+			*b++ = 0;
+		}
+		obj[1].relocation_count = NUM_REGS;
+	} else {
+		unsigned int n = 0;
+
+		for (const struct named_register *r = safe_registers;
+		     r->name; r++) {
+			if (!(r->engine_mask & engine_bit))
+				continue;
+			if (!(r->gen_mask & gen_bit))
+				continue;
+
+			*b++ = 0x24 << 23 | 2; /* SRM */
+			*b++ = r->offset;
+			reloc[n].target_handle = obj[0].handle;
+			reloc[n].presumed_offset = 0;
+			reloc[n].offset = (b - batch) * sizeof(*b);
+			reloc[n].delta = r->offset;
+			reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+			reloc[n].write_domain = I915_GEM_DOMAIN_RENDER;
+			*b++ = reloc[n].delta;
+			*b++ = 0;
+
+			n++;
+		}
+
+		obj[1].relocation_count = n;
+	}
+	*b++ = MI_BATCH_BUFFER_END;
+	munmap(batch, batch_size);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 2;
+	execbuf.flags = engine;
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj[1].handle);
+	free(reloc);
+
+	return obj[0].handle;
+}
+
+static void write_all_regs(int fd,
+			   uint32_t ctx, unsigned int engine,
+			   unsigned int flags)
+{
+	struct drm_i915_gem_exec_object2 obj;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	unsigned int engine_bit, gen_bit;
+	unsigned int batch_size;
+	uint32_t *batch, *b;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << intel_gen(intel_get_drm_devid(fd));
+
+	batch_size = NUM_REGS * 3 * sizeof(uint32_t) + 4;
+	batch_size = PAGE_ALIGN(batch_size);
+
+	memset(&obj, 0, sizeof(obj));
+	obj.handle = gem_create(fd, batch_size);
+
+	b = batch = gem_mmap__cpu(fd, obj.handle, 0, batch_size, PROT_WRITE);
+	gem_set_domain(fd, obj.handle,
+		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+
+	if (flags & UNSAFE) {
+		for (unsigned int n = 0; n < NUM_REGS; n++) {
+			*b++ = 0x23 << 23 | 1; /* LRI */
+			*b++ = n * sizeof(uint32_t);
+			*b++ = 0xdeadbeef;
+		}
+	} else {
+		for (const struct named_register *r = safe_registers;
+		     r->name; r++) {
+			if (!(r->engine_mask & engine_bit))
+				continue;
+			if (!(r->gen_mask & gen_bit))
+				continue;
+			*b++ = 0x23 << 23 | 1; /* LRI */
+			*b++ = r->offset;
+			*b++ = 0xdeadbeef;
+		}
+	}
+	*b++ = MI_BATCH_BUFFER_END;
+	munmap(batch, batch_size);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(&obj);
+	execbuf.buffer_count = 1;
+	execbuf.flags = engine;
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj.handle);
+}
+
+static void compare_regs(int fd, uint32_t regs[2])
+{
+	unsigned int num_errors;
+	unsigned int regs_size;
+	uint32_t *a, *b;
+
+	regs_size = NUM_REGS * sizeof(uint32_t);
+	regs_size = PAGE_ALIGN(regs_size);
+
+	a = gem_mmap__cpu(fd, regs[0], 0, regs_size, PROT_READ);
+	gem_set_domain(fd, regs[0], I915_GEM_DOMAIN_CPU, 0);
+
+	b = gem_mmap__cpu(fd, regs[1], 0, regs_size, PROT_READ);
+	gem_set_domain(fd, regs[1], I915_GEM_DOMAIN_CPU, 0);
+
+	num_errors = 0;
+	for (unsigned int n = 0; n < NUM_REGS; n++) {
+		uint32_t offset = n * sizeof(uint32_t);
+		if (a[n] != b[n] && !ignore_register(offset)) {
+			igt_warn("Register 0x%04x [%s]: A=%08x B=%08x\n",
+				 offset, register_name(offset), a[n], b[n]);
+			num_errors++;
+		}
+	}
+	munmap(b, regs_size);
+	munmap(a, regs_size);
+
+	igt_assert_f(num_errors == 0,
+		     "%d registers mistached between two virgin contexts\n",
+		     num_errors);
+}
+
+static void isolation(int fd, unsigned int engine, unsigned int flags)
+{
+	igt_spin_t *spin = NULL;
+	uint32_t ctx[2];
+	uint32_t regs[2];
+
+	ctx[0] = gem_context_create(fd);
+	regs[0] = read_all_regs(fd, ctx[0], engine, flags);
+
+	if (flags & DIRTY) {
+		spin = igt_spin_batch_new(fd, ctx[0], engine, 0);
+		write_all_regs(fd, ctx[0], engine, flags);
+	}
+
+	/*
+	 * We create and execute a new context, whilst the HW is occupied
+	 * with the previous context (we should switch from the old to the
+	 * new proto context without idling, which could then load the
+	 * powercontext). If all goes well, we only see the default values
+	 * from this context, but if goes badly we see the corruption from
+	 * the previous context instead!
+	 */
+	ctx[1] = gem_context_create(fd);
+	regs[1] = read_all_regs(fd, ctx[1], engine, flags);
+
+	igt_spin_batch_free(fd, spin);
+
+	compare_regs(fd, regs);
+
+	for (int n = 0; n < ARRAY_SIZE(ctx); n++) {
+		gem_close(fd, regs[n]);
+		gem_context_destroy(fd, ctx[n]);
+	}
+}
+
+igt_main
+{
+	const unsigned int platform_validation = 0;
+	int fd = -1;
+
+	igt_fixture {
+		int gen;
+
+		fd = drm_open_driver(DRIVER_INTEL);
+		igt_require_gem(fd);
+
+		/* For guaranteed context isolation */
+		igt_require(gem_has_execlists(fd));
+		gem_context_destroy(fd, gem_context_create(fd));
+
+		gen = intel_gen(intel_get_drm_devid(fd));
+		//igt_ci_fail_on(gen > LAST_KNOWN_GEN);
+		igt_skip_on(gen > LAST_KNOWN_GEN);
+	}
+
+	for (const struct intel_execution_engine *e =
+			intel_execution_engines; e->name; e++) {
+		igt_subtest_group {
+			unsigned int engine = e->exec_id | e->flags;
+			igt_fixture {
+				gem_require_ring(fd, engine);
+			}
+
+			igt_subtest_f("%s-clean", e->name)
+				isolation(fd, engine, 0);
+			igt_subtest_f("%s-dirty", e->name)
+				isolation(fd, engine, DIRTY);
+
+			igt_subtest_f("%s-unsafe", e->name) {
+				igt_require(platform_validation);
+				isolation(fd, engine, DIRTY | UNSAFE);
+			}
+		}
+	}
+}
-- 
2.15.0.rc1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* ✗ Fi.CI.BAT: failure for drm-auth
  2017-10-24 11:07 [PATCH igt] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
                   ` (2 preceding siblings ...)
  2017-10-24 12:58 ` [PATCH igt v2] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
@ 2017-10-24 13:42 ` Patchwork
  2017-10-24 14:20 ` [PATCH xf86-video-intel v3] hmm Chris Wilson
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Patchwork @ 2017-10-24 13:42 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: drm-auth
URL   : https://patchwork.freedesktop.org/series/32538/
State : failure

== Summary ==

Series 32538 revision 1 was fully merged or fully failed: no git log

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH xf86-video-intel v3] hmm
  2017-10-24 11:07 [PATCH igt] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
                   ` (3 preceding siblings ...)
  2017-10-24 13:42 ` ✗ Fi.CI.BAT: failure for drm-auth Patchwork
@ 2017-10-24 14:20 ` Chris Wilson
  2017-10-24 14:22   ` Chris Wilson
  2017-10-24 14:21 ` [PATCH igt v3] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 13+ messages in thread
From: Chris Wilson @ 2017-10-24 14:20 UTC (permalink / raw)
  To: intel-gfx

---
 src/sna/gen6_common.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/sna/gen6_common.h b/src/sna/gen6_common.h
index b53ec0c9..05f76f83 100644
--- a/src/sna/gen6_common.h
+++ b/src/sna/gen6_common.h
@@ -87,7 +87,7 @@ static int prefer_blt_bo(struct sna *sna,
 	if (PREFER_RENDER)
 		return PREFER_RENDER < 0;
 
-	if (dst->rq)
+	if (__kgem_bo_is_busy(&sna->kgem, dst))
 		return RQ_IS_BLT(dst->rq);
 
 	if (sna->flags & SNA_POWERSAVE)
@@ -97,7 +97,7 @@ static int prefer_blt_bo(struct sna *sna,
 		if (sna->render_state.gt > 1)
 			return false;
 
-		if (src->rq)
+		if (__kgem_bo_is_busy(&sna->kgem, src))
 			return RQ_IS_BLT(src->rq);
 
 		if (src->tiling == I915_TILING_Y)
@@ -157,8 +157,8 @@ prefer_render_ring(struct sna *sna, struct kgem_bo *bo)
 	if (sna->kgem.ring != KGEM_NONE && NO_RING_SWITCH(sna))
                 return false;
 
-	if (kgem_bo_is_render(bo))
-		return true;
+	if (__kgem_bo_is_busy(&sna->kgem, bo))
+		return !RQ_IS_BLT(bo);
 
 	if (sna->flags & SNA_POWERSAVE)
 		return false;
-- 
2.15.0.rc1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH igt v3] igt/gem_ctx_isolation: Check isolation of registers between contexts
  2017-10-24 11:07 [PATCH igt] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
                   ` (4 preceding siblings ...)
  2017-10-24 14:20 ` [PATCH xf86-video-intel v3] hmm Chris Wilson
@ 2017-10-24 14:21 ` Chris Wilson
  2017-10-24 15:02 ` ✗ Fi.CI.BAT: failure for igt/gem_ctx_isolation: Check isolation of registers between contexts (rev3) Patchwork
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Chris Wilson @ 2017-10-24 14:21 UTC (permalink / raw)
  To: intel-gfx

A new context assumes that all of its registers are in the default state
when it is created. What may happen is that a register written by one
context may leak into the second, causing mass confusion.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 tests/Makefile.sources    |   1 +
 tests/gem_ctx_isolation.c | 790 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 791 insertions(+)
 create mode 100644 tests/gem_ctx_isolation.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index ac9f90bc..d18b7461 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -57,6 +57,7 @@ TESTS_progs = \
 	gem_ctx_basic \
 	gem_ctx_create \
 	gem_ctx_exec \
+	gem_ctx_isolation \
 	gem_ctx_param \
 	gem_ctx_switch \
 	gem_ctx_thrash \
diff --git a/tests/gem_ctx_isolation.c b/tests/gem_ctx_isolation.c
new file mode 100644
index 00000000..3a0ee19a
--- /dev/null
+++ b/tests/gem_ctx_isolation.c
@@ -0,0 +1,790 @@
+/*
+ * Copyright © 2017 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 "igt.h"
+#include "igt_dummyload.h"
+
+#define MAX_REG 0x40000
+#define NUM_REGS (MAX_REG / sizeof(uint32_t))
+
+#define PAGE_ALIGN(x) ALIGN(x, 4096)
+
+#define DIRTY 0x1
+#define UNSAFE 0x2
+
+enum {
+	RCS_MASK = 0x1,
+	BCS_MASK = 0x2,
+	VCS_MASK = 0x4,
+	VECS_MASK = 0x8,
+};
+
+#define ALL ~0u
+#define GEN_RANGE(x, y) ((ALL >> (32 - (y - x + 1))) << x)
+
+#define LAST_KNOWN_GEN 10
+
+static const struct named_register {
+	const char *name;
+	unsigned int gen_mask;
+	unsigned int engine_mask;
+	uint32_t offset;
+} safe_registers[] = {
+	{ "NOPID", ALL, RCS_MASK, 0x2094 },
+	{ "MI_PREDICATE_RESULT_2", ALL, RCS_MASK, 0x23bc },
+	{ "INSTPM", ALL, RCS_MASK, 0x20c0 },
+	{ "IA_VERTICES_COUNT (low)", ALL, RCS_MASK, 0x2310 },
+	{ "IA_VERTICES_COUNT (high)", ALL, RCS_MASK, 0x2314 },
+	{ "IA_PRIMITIVES_COUNT (low)", ALL, RCS_MASK, 0x2318 },
+	{ "IA_PRIMITIVES_COUNT (high)", ALL, RCS_MASK, 0x231c },
+	{ "VS_INVOCATION_COUNT (low)", ALL, RCS_MASK, 0x2320 },
+	{ "VS_INVOCATION_COUNT (high)", ALL, RCS_MASK, 0x2324 },
+	{ "HS_INVOCATION_COUNT (low)", ALL, RCS_MASK, 0x2300 },
+	{ "HS_INVOCATION_COUNT (high)", ALL, RCS_MASK, 0x2304 },
+	{ "DS_INVOCATION_COUNT (low)", ALL, RCS_MASK, 0x2308 },
+	{ "DS_INVOCATION_COUNT (high)", ALL, RCS_MASK, 0x230c },
+	{ "GS_INVOCATION_COUNT (low)", ALL, RCS_MASK, 0x2328 },
+	{ "GS_INVOCATION_COUNT (high)", ALL, RCS_MASK, 0x232c },
+	{ "GS_PRIMITIVES_COUNT (low)", ALL, RCS_MASK, 0x2330 },
+	{ "GS_PRIMITIVES_COUNT (high)", ALL, RCS_MASK, 0x2334 },
+	{ "CL_INVOCATION_COUNT (low)", ALL, RCS_MASK, 0x2338 },
+	{ "CL_INVOCATION_COUNT (high)", ALL, RCS_MASK, 0x233c },
+	{ "CL_PRIMITIVES_COUNT (low)", ALL, RCS_MASK, 0x2340 },
+	{ "CL_PRIMITIVES_COUNT (high)", ALL, RCS_MASK, 0x2344 },
+	{ "PS_INVOCATION_COUNT_0 (low)", ALL, RCS_MASK, 0x22c8 },
+	{ "PS_INVOCATION_COUNT_0 (high)", ALL, RCS_MASK, 0x22cc },
+	{ "PS_DEPTH_COUNT_0 (low)", ALL, RCS_MASK, 0x22d8 },
+	{ "PS_DEPTH_COUNT_0 (high)", ALL, RCS_MASK, 0x22dc },
+	{ "GPUGPU_DISPATCHDIMX", ALL, RCS_MASK, 0x2500 },
+	{ "GPUGPU_DISPATCHDIMY", ALL, RCS_MASK, 0x2504 },
+	{ "GPUGPU_DISPATCHDIMZ", ALL, RCS_MASK, 0x2508 },
+	{ "MI_PREDICATE_SRC0 (low)", ALL, RCS_MASK, 0x2400 },
+	{ "MI_PREDICATE_SRC0 (high)", ALL, RCS_MASK, 0x2404 },
+	{ "MI_PREDICATE_SRC1 (low)", ALL, RCS_MASK, 0x2408 },
+	{ "MI_PREDICATE_SRC1 (high)", ALL, RCS_MASK, 0x240c },
+	{ "MI_PREDICATE_DATA (low)", ALL, RCS_MASK, 0x2410 },
+	{ "MI_PREDICATE_DATA (high)", ALL, RCS_MASK, 0x2414 },
+	{ "MI_PRED_RESULT", ALL, RCS_MASK, 0x2418 },
+	{ "3DPRIM_END_OFFSET", ALL, RCS_MASK, 0x2420 },
+	{ "3DPRIM_START_VERTEX", ALL, RCS_MASK, 0x2430 },
+	{ "3DPRIM_VERTEX_COUNT", ALL, RCS_MASK, 0x2434 },
+	{ "3DPRIM_INSTANCE_COUNT", ALL, RCS_MASK, 0x2438 },
+	{ "3DPRIM_START_INSTANCE", ALL, RCS_MASK, 0x243c },
+	{ "3DPRIM_BASE_VERTEX", ALL, RCS_MASK, 0x2440 },
+	{ "GPGPU_THREADS_DISPATCHED (low)", ALL, RCS_MASK, 0x2290 },
+	{ "GPGPU_THREADS_DISPATCHED (high)", ALL, RCS_MASK, 0x2294 },
+	{ "PS_INVOCATION_COUNT_1 (low)", ALL, RCS_MASK, 0x22f0 },
+	{ "PS_INVOCATION_COUNT_1 (high)", ALL, RCS_MASK, 0x22f4 },
+	{ "PS_DEPTH_COUNT_1 (low)", ALL, RCS_MASK, 0x22f8 },
+	{ "PS_DEPTH_COUNT_1 (high)", ALL, RCS_MASK, 0x22fc },
+	{ "BB_OFFSET", ALL, RCS_MASK, 0x2158 },
+	{ "MI_PREDICATE_RESULT_1", ALL, RCS_MASK, 0x241c },
+	{ "CS_GPR[0]", ALL, RCS_MASK, 0x2600 },
+	{ "CS_GPR[1]", ALL, RCS_MASK, 0x2604 },
+	{ "CS_GPR[2]", ALL, RCS_MASK, 0x2608 },
+	{ "CS_GPR[3]", ALL, RCS_MASK, 0x260c },
+	{ "CS_GPR[4]", ALL, RCS_MASK, 0x2610 },
+	{ "CS_GPR[5]", ALL, RCS_MASK, 0x2614 },
+	{ "CS_GPR[6]", ALL, RCS_MASK, 0x2618 },
+	{ "CS_GPR[7]", ALL, RCS_MASK, 0x261c },
+	{ "CS_GPR[8]", ALL, RCS_MASK, 0x2620 },
+	{ "CS_GPR[9]", ALL, RCS_MASK, 0x2624 },
+	{ "CS_GPR[10]", ALL, RCS_MASK, 0x2628 },
+	{ "CS_GPR[11]", ALL, RCS_MASK, 0x262c },
+	{ "CS_GPR[12]", ALL, RCS_MASK, 0x2630 },
+	{ "CS_GPR[13]", ALL, RCS_MASK, 0x2634 },
+	{ "CS_GPR[14]", ALL, RCS_MASK, 0x2638 },
+	{ "CS_GPR[15]", ALL, RCS_MASK, 0x263c },
+	{ "CS_GPR[16]", ALL, RCS_MASK, 0x2640 },
+	{ "CS_GPR[17]", ALL, RCS_MASK, 0x2644 },
+	{ "CS_GPR[18]", ALL, RCS_MASK, 0x2648 },
+	{ "CS_GPR[19]", ALL, RCS_MASK, 0x264c },
+	{ "CS_GPR[20]", ALL, RCS_MASK, 0x2650 },
+	{ "CS_GPR[21]", ALL, RCS_MASK, 0x2654 },
+	{ "CS_GPR[22]", ALL, RCS_MASK, 0x2658 },
+	{ "CS_GPR[23]", ALL, RCS_MASK, 0x265c },
+	{ "CS_GPR[24]", ALL, RCS_MASK, 0x2660 },
+	{ "CS_GPR[25]", ALL, RCS_MASK, 0x2664 },
+	{ "CS_GPR[26]", ALL, RCS_MASK, 0x2668 },
+	{ "CS_GPR[27]", ALL, RCS_MASK, 0x266c },
+	{ "CS_GPR[28]", ALL, RCS_MASK, 0x2670 },
+	{ "CS_GPR[29]", ALL, RCS_MASK, 0x2674 },
+	{ "CS_GPR[30]", ALL, RCS_MASK, 0x2678 },
+	{ "CS_GPR[31]", ALL, RCS_MASK, 0x267c },
+	{ "OA_CTX_CONTROL", ALL, RCS_MASK, 0x2360 },
+	{ "OACTXID", ALL, RCS_MASK, 0x2364 },
+	{ "PS_INVOCATION_COUNT_2 (log)", ALL, RCS_MASK, 0x2448 },
+	{ "PS_INVOCATION_COUNT_2 (high)", ALL, RCS_MASK, 0x244c },
+	{ "PS_DEPTH_COUNT_2 (log)", ALL, RCS_MASK, 0x2450 },
+	{ "PS_DEPTH_COUNT_2 (high)", ALL, RCS_MASK, 0x245c },
+	{ "Cache_Mode_0", ALL, RCS_MASK, 0x7000 },
+	{ "Cache_Mode_1", ALL, RCS_MASK, 0x7004 },
+	{ "GT_MODE", ALL, RCS_MASK, 0x7008 },
+	{ "L3_Config", ALL, RCS_MASK, 0x7034 },
+	{ "TD_CTL", ALL, RCS_MASK, 0xe400 },
+	{ "TD_CTL2", ALL, RCS_MASK, 0xe404 },
+	{ "SO_NUM_PRIMS_WRITEN0 (low)", ALL, RCS_MASK, 0x5200 },
+	{ "SO_NUM_PRIMS_WRITEN0 (high)", ALL, RCS_MASK, 0x5204 },
+	{ "SO_NUM_PRIMS_WRITEN1 (low)", ALL, RCS_MASK, 0x5208 },
+	{ "SO_NUM_PRIMS_WRITEN1 (high)", ALL, RCS_MASK, 0x520c },
+	{ "SO_NUM_PRIMS_WRITEN2 (low)", ALL, RCS_MASK, 0x5210 },
+	{ "SO_NUM_PRIMS_WRITEN2 (high)", ALL, RCS_MASK, 0x521c },
+	{ "SO_NUM_PRIMS_WRITEN3 (low)", ALL, RCS_MASK, 0x5218 },
+	{ "SO_NUM_PRIMS_WRITEN3 (high)", ALL, RCS_MASK, 0x521c },
+	{ "SO_PRIM_STORAGE_NEEDED0 (low)", ALL, RCS_MASK, 0x5240 },
+	{ "SO_PRIM_STORAGE_NEEDED0 (high)", ALL, RCS_MASK, 0x5244 },
+	{ "SO_PRIM_STORAGE_NEEDED1 (low)", ALL, RCS_MASK, 0x5248 },
+	{ "SO_PRIM_STORAGE_NEEDED1 (high)", ALL, RCS_MASK, 0x524c },
+	{ "SO_PRIM_STORAGE_NEEDED2 (low)", ALL, RCS_MASK, 0x5250 },
+	{ "SO_PRIM_STORAGE_NEEDED2 (high)", ALL, RCS_MASK, 0x5254 },
+	{ "SO_PRIM_STORAGE_NEEDED3 (low)", ALL, RCS_MASK, 0x5258 },
+	{ "SO_PRIM_STORAGE_NEEDED3 (high)", ALL, RCS_MASK, 0x525c },
+	{ "SO_WRITE_OFFSET0", ALL, RCS_MASK, 0x5280 },
+	{ "SO_WRITE_OFFSET1", ALL, RCS_MASK, 0x5284 },
+	{ "SO_WRITE_OFFSET2", ALL, RCS_MASK, 0x5288 },
+	{ "SO_WRITE_OFFSET3", ALL, RCS_MASK, 0x528c },
+	{ "OA_CONTROL", ALL, RCS_MASK, 0x2b00 },
+	{ "PERF_CNT_1_DW0", ALL, RCS_MASK, 0x91b8 },
+	{ "PERF_CNT_1_DW1", ALL, RCS_MASK, 0x91bc },
+	{ "PERF_CNT_2_DW0", ALL, RCS_MASK, 0x91c0 },
+	{ "PERF_CNT_2_DW1", ALL, RCS_MASK, 0x91c4 },
+
+	/* Privileged (enabled by w/a + FORCE_TO_NONPRIV) */
+	{ "CTX_PREEMPT", GEN_RANGE(9, 10), RCS_MASK, 0x2248 },
+	{ "CS_CHICKEN1", GEN_RANGE(9, 10), RCS_MASK, 0x2580 },
+	{ "HDC_CHICKEN1", GEN_RANGE(9, 10), RCS_MASK, 0x7304 },
+	{ "L3SQREG1", ALL, RCS_MASK, 0xb010 },
+
+	{ "BCS_GPR[0]", ALL, BCS_MASK, 0x22600 },
+	{ "BCS_GPR[1]", ALL, BCS_MASK, 0x22604 },
+	{ "BCS_GPR[2]", ALL, BCS_MASK, 0x22608 },
+	{ "BCS_GPR[3]", ALL, BCS_MASK, 0x2260c },
+	{ "BCS_GPR[4]", ALL, BCS_MASK, 0x22610 },
+	{ "BCS_GPR[5]", ALL, BCS_MASK, 0x22614 },
+	{ "BCS_GPR[6]", ALL, BCS_MASK, 0x22618 },
+	{ "BCS_GPR[7]", ALL, BCS_MASK, 0x2261c },
+	{ "BCS_GPR[8]", ALL, BCS_MASK, 0x22620 },
+	{ "BCS_GPR[9]", ALL, BCS_MASK, 0x22624 },
+	{ "BCS_GPR[10]", ALL, BCS_MASK, 0x22628 },
+	{ "BCS_GPR[11]", ALL, BCS_MASK, 0x2262c },
+	{ "BCS_GPR[12]", ALL, BCS_MASK, 0x22630 },
+	{ "BCS_GPR[13]", ALL, BCS_MASK, 0x22634 },
+	{ "BCS_GPR[14]", ALL, BCS_MASK, 0x22638 },
+	{ "BCS_GPR[15]", ALL, BCS_MASK, 0x2263c },
+	{ "BCS_GPR[16]", ALL, BCS_MASK, 0x22640 },
+	{ "BCS_GPR[17]", ALL, BCS_MASK, 0x22644 },
+	{ "BCS_GPR[18]", ALL, BCS_MASK, 0x22648 },
+	{ "BCS_GPR[19]", ALL, BCS_MASK, 0x2264c },
+	{ "BCS_GPR[20]", ALL, BCS_MASK, 0x22650 },
+	{ "BCS_GPR[21]", ALL, BCS_MASK, 0x22654 },
+	{ "BCS_GPR[22]", ALL, BCS_MASK, 0x22658 },
+	{ "BCS_GPR[23]", ALL, BCS_MASK, 0x2265c },
+	{ "BCS_GPR[24]", ALL, BCS_MASK, 0x22660 },
+	{ "BCS_GPR[25]", ALL, BCS_MASK, 0x22664 },
+	{ "BCS_GPR[26]", ALL, BCS_MASK, 0x22668 },
+	{ "BCS_GPR[27]", ALL, BCS_MASK, 0x2266c },
+	{ "BCS_GPR[28]", ALL, BCS_MASK, 0x22670 },
+	{ "BCS_GPR[29]", ALL, BCS_MASK, 0x22674 },
+	{ "BCS_GPR[30]", ALL, BCS_MASK, 0x22678 },
+	{ "BCS_GPR[31]", ALL, BCS_MASK, 0x2267c },
+	{ "BCS_SWCTRL", ALL, BCS_MASK, 0x22200 },
+
+	{ "VCS0_GPR[0]", ALL, VCS_MASK, 0x12600 },
+	{ "VCS0_GPR[1]", ALL, VCS_MASK, 0x12604 },
+	{ "VCS0_GPR[2]", ALL, VCS_MASK, 0x12608 },
+	{ "VCS0_GPR[3]", ALL, VCS_MASK, 0x1260c },
+	{ "VCS0_GPR[4]", ALL, VCS_MASK, 0x12610 },
+	{ "VCS0_GPR[5]", ALL, VCS_MASK, 0x12614 },
+	{ "VCS0_GPR[6]", ALL, VCS_MASK, 0x12618 },
+	{ "VCS0_GPR[7]", ALL, VCS_MASK, 0x1261c },
+	{ "VCS0_GPR[8]", ALL, VCS_MASK, 0x12620 },
+	{ "VCS0_GPR[9]", ALL, VCS_MASK, 0x12624 },
+	{ "VCS0_GPR[10]", ALL, VCS_MASK, 0x12628 },
+	{ "VCS0_GPR[11]", ALL, VCS_MASK, 0x1262c },
+	{ "VCS0_GPR[12]", ALL, VCS_MASK, 0x12630 },
+	{ "VCS0_GPR[13]", ALL, VCS_MASK, 0x12634 },
+	{ "VCS0_GPR[14]", ALL, VCS_MASK, 0x12638 },
+	{ "VCS0_GPR[15]", ALL, VCS_MASK, 0x1263c },
+	{ "VCS0_GPR[16]", ALL, VCS_MASK, 0x22640 },
+	{ "VCS0_GPR[17]", ALL, VCS_MASK, 0x12644 },
+	{ "VCS0_GPR[18]", ALL, VCS_MASK, 0x12648 },
+	{ "VCS0_GPR[19]", ALL, VCS_MASK, 0x1264c },
+	{ "VCS0_GPR[20]", ALL, VCS_MASK, 0x12650 },
+	{ "VCS0_GPR[21]", ALL, VCS_MASK, 0x12654 },
+	{ "VCS0_GPR[22]", ALL, VCS_MASK, 0x12658 },
+	{ "VCS0_GPR[23]", ALL, VCS_MASK, 0x1265c },
+	{ "VCS0_GPR[24]", ALL, VCS_MASK, 0x12660 },
+	{ "VCS0_GPR[25]", ALL, VCS_MASK, 0x12664 },
+	{ "VCS0_GPR[26]", ALL, VCS_MASK, 0x12668 },
+	{ "VCS0_GPR[27]", ALL, VCS_MASK, 0x1266c },
+	{ "VCS0_GPR[28]", ALL, VCS_MASK, 0x12670 },
+	{ "VCS0_GPR[29]", ALL, VCS_MASK, 0x12674 },
+	{ "VCS0_GPR[30]", ALL, VCS_MASK, 0x12678 },
+	{ "VCS0_GPR[31]", ALL, VCS_MASK, 0x1267c },
+
+	//{ "MFC_VBDOX1[]", ALL, VCS_MASK, 0x12800 }, x 64
+	//{ "MFC_VBDOX2[]", ALL, VCS_MASK, 0x1c800 }, x 64
+
+	{ "VCS1_GPR[0]", ALL, VCS_MASK, 0x1c600 },
+	{ "VCS1_GPR[1]", ALL, VCS_MASK, 0x1c604 },
+	{ "VCS1_GPR[2]", ALL, VCS_MASK, 0x1c608 },
+	{ "VCS1_GPR[3]", ALL, VCS_MASK, 0x1c60c },
+	{ "VCS1_GPR[4]", ALL, VCS_MASK, 0x1c610 },
+	{ "VCS1_GPR[5]", ALL, VCS_MASK, 0x1c614 },
+	{ "VCS1_GPR[6]", ALL, VCS_MASK, 0x1c618 },
+	{ "VCS1_GPR[7]", ALL, VCS_MASK, 0x1c61c },
+	{ "VCS1_GPR[8]", ALL, VCS_MASK, 0x1c620 },
+	{ "VCS1_GPR[9]", ALL, VCS_MASK, 0x1c624 },
+	{ "VCS1_GPR[10]", ALL, VCS_MASK, 0x1c628 },
+	{ "VCS1_GPR[11]", ALL, VCS_MASK, 0x1c62c },
+	{ "VCS1_GPR[12]", ALL, VCS_MASK, 0x1c630 },
+	{ "VCS1_GPR[13]", ALL, VCS_MASK, 0x1c634 },
+	{ "VCS1_GPR[14]", ALL, VCS_MASK, 0x1c638 },
+	{ "VCS1_GPR[15]", ALL, VCS_MASK, 0x1c63c },
+	{ "VCS1_GPR[16]", ALL, VCS_MASK, 0x22640 },
+	{ "VCS1_GPR[17]", ALL, VCS_MASK, 0x1c644 },
+	{ "VCS1_GPR[18]", ALL, VCS_MASK, 0x1c648 },
+	{ "VCS1_GPR[19]", ALL, VCS_MASK, 0x1c64c },
+	{ "VCS1_GPR[20]", ALL, VCS_MASK, 0x1c650 },
+	{ "VCS1_GPR[21]", ALL, VCS_MASK, 0x1c654 },
+	{ "VCS1_GPR[22]", ALL, VCS_MASK, 0x1c658 },
+	{ "VCS1_GPR[23]", ALL, VCS_MASK, 0x1c65c },
+	{ "VCS1_GPR[24]", ALL, VCS_MASK, 0x1c660 },
+	{ "VCS1_GPR[25]", ALL, VCS_MASK, 0x1c664 },
+	{ "VCS1_GPR[26]", ALL, VCS_MASK, 0x1c668 },
+	{ "VCS1_GPR[27]", ALL, VCS_MASK, 0x1c66c },
+	{ "VCS1_GPR[28]", ALL, VCS_MASK, 0x1c670 },
+	{ "VCS1_GPR[29]", ALL, VCS_MASK, 0x1c674 },
+	{ "VCS1_GPR[30]", ALL, VCS_MASK, 0x1c678 },
+	{ "VCS1_GPR[31]", ALL, VCS_MASK, 0x1c67c },
+
+	{ "VECS_GPR[0]", ALL, VECS_MASK, 0x1a600 },
+	{ "VECS_GPR[1]", ALL, VECS_MASK, 0x1a604 },
+	{ "VECS_GPR[2]", ALL, VECS_MASK, 0x1a608 },
+	{ "VECS_GPR[3]", ALL, VECS_MASK, 0x1a60c },
+	{ "VECS_GPR[4]", ALL, VECS_MASK, 0x1a610 },
+	{ "VECS_GPR[5]", ALL, VECS_MASK, 0x1a614 },
+	{ "VECS_GPR[6]", ALL, VECS_MASK, 0x1a618 },
+	{ "VECS_GPR[7]", ALL, VECS_MASK, 0x1a61c },
+	{ "VECS_GPR[8]", ALL, VECS_MASK, 0x1a620 },
+	{ "VECS_GPR[9]", ALL, VECS_MASK, 0x1a624 },
+	{ "VECS_GPR[10]", ALL, VECS_MASK, 0x1a628 },
+	{ "VECS_GPR[11]", ALL, VECS_MASK, 0x1a62c },
+	{ "VECS_GPR[12]", ALL, VECS_MASK, 0x1a630 },
+	{ "VECS_GPR[13]", ALL, VECS_MASK, 0x1a634 },
+	{ "VECS_GPR[14]", ALL, VECS_MASK, 0x1a638 },
+	{ "VECS_GPR[15]", ALL, VECS_MASK, 0x1a63c },
+	{ "VECS_GPR[16]", ALL, VECS_MASK, 0x22640 },
+	{ "VECS_GPR[17]", ALL, VECS_MASK, 0x1a644 },
+	{ "VECS_GPR[18]", ALL, VECS_MASK, 0x1a648 },
+	{ "VECS_GPR[19]", ALL, VECS_MASK, 0x1a64c },
+	{ "VECS_GPR[20]", ALL, VECS_MASK, 0x1a650 },
+	{ "VECS_GPR[21]", ALL, VECS_MASK, 0x1a654 },
+	{ "VECS_GPR[22]", ALL, VECS_MASK, 0x1a658 },
+	{ "VECS_GPR[23]", ALL, VECS_MASK, 0x1a65c },
+	{ "VECS_GPR[24]", ALL, VECS_MASK, 0x1a660 },
+	{ "VECS_GPR[25]", ALL, VECS_MASK, 0x1a664 },
+	{ "VECS_GPR[26]", ALL, VECS_MASK, 0x1a668 },
+	{ "VECS_GPR[27]", ALL, VECS_MASK, 0x1a66c },
+	{ "VECS_GPR[28]", ALL, VECS_MASK, 0x1a670 },
+	{ "VECS_GPR[29]", ALL, VECS_MASK, 0x1a674 },
+	{ "VECS_GPR[30]", ALL, VECS_MASK, 0x1a678 },
+	{ "VECS_GPR[31]", ALL, VECS_MASK, 0x1a67c },
+
+	{}
+}, ignore_registers[] = {
+	{ "RCS timestamp", ALL, RCS_MASK, 0x2358 },
+	{ "VCS0 timestamp", ALL, VCS_MASK, 0x12358 },
+	{ "VCS1 timestamp", ALL, VCS_MASK, 0x1c358 },
+	{ "BCS timestamp", ALL, BCS_MASK, 0x22358 },
+	{ "VECS timestamp", ALL, VECS_MASK, 0x1a358 },
+	{}
+};
+
+static const char *register_name(uint32_t offset)
+{
+	for (const struct named_register *r = safe_registers; r->name; r++) {
+		if (r->offset == offset)
+			return r->name;
+	}
+
+	return "unknown";
+}
+
+static bool ignore_register(uint32_t offset)
+{
+	for (const struct named_register *r = ignore_registers; r->name; r++) {
+		if (r->offset == offset)
+			return true;
+	}
+
+	return false;
+}
+
+static uint32_t read_regs(int fd,
+			  uint32_t ctx, unsigned int engine,
+			  unsigned int flags)
+{
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_relocation_entry *reloc;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	unsigned int regs_size, batch_size;
+	unsigned int engine_bit, gen_bit;
+	uint32_t *batch, *b;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << intel_gen(intel_get_drm_devid(fd));
+
+	reloc = calloc(NUM_REGS, sizeof(*reloc));
+	igt_assert(reloc);
+
+	regs_size = NUM_REGS * sizeof(uint32_t);
+	regs_size = PAGE_ALIGN(regs_size);
+
+	batch_size = NUM_REGS * 4 * sizeof(uint32_t) + 4;
+	batch_size = PAGE_ALIGN(batch_size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = gem_create(fd, regs_size);
+	obj[1].handle = gem_create(fd, batch_size);
+	obj[1].relocs_ptr = to_user_pointer(reloc);
+
+	b = batch = gem_mmap__cpu(fd, obj[1].handle, 0, batch_size, PROT_WRITE);
+	gem_set_domain(fd, obj[1].handle,
+		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+
+	if (flags & UNSAFE) {
+		for (unsigned int n = 0; n < NUM_REGS; n++) {
+			*b++ = 0x24 << 23 | 2;
+			*b++ = n * sizeof(uint32_t);
+			reloc[n].target_handle = obj[0].handle;
+			reloc[n].presumed_offset = 0;
+			reloc[n].offset = (b - batch) * sizeof(*b);
+			reloc[n].delta = sizeof(uint32_t) * n;
+			reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+			reloc[n].write_domain = I915_GEM_DOMAIN_RENDER;
+			*b++ = reloc[n].delta;
+			*b++ = 0;
+		}
+		obj[1].relocation_count = NUM_REGS;
+	} else {
+		unsigned int n = 0;
+
+		for (const struct named_register *r = safe_registers;
+		     r->name; r++) {
+			if (!(r->engine_mask & engine_bit))
+				continue;
+			if (!(r->gen_mask & gen_bit))
+				continue;
+
+			*b++ = 0x24 << 23 | 2; /* SRM */
+			*b++ = r->offset;
+			reloc[n].target_handle = obj[0].handle;
+			reloc[n].presumed_offset = 0;
+			reloc[n].offset = (b - batch) * sizeof(*b);
+			reloc[n].delta = r->offset;
+			reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+			reloc[n].write_domain = I915_GEM_DOMAIN_RENDER;
+			*b++ = reloc[n].delta;
+			*b++ = 0;
+
+			n++;
+		}
+
+		obj[1].relocation_count = n;
+	}
+	*b++ = MI_BATCH_BUFFER_END;
+	munmap(batch, batch_size);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 2;
+	execbuf.flags = engine;
+	execbuf.rsvd1 = ctx;
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj[1].handle);
+	free(reloc);
+
+	return obj[0].handle;
+}
+
+static void write_regs(int fd,
+		       uint32_t ctx, unsigned int engine,
+		       unsigned int flags,
+		       uint32_t value)
+{
+	struct drm_i915_gem_exec_object2 obj;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	unsigned int engine_bit, gen_bit;
+	unsigned int batch_size;
+	uint32_t *batch, *b;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << intel_gen(intel_get_drm_devid(fd));
+
+	batch_size = NUM_REGS * 3 * sizeof(uint32_t) + 4;
+	batch_size = PAGE_ALIGN(batch_size);
+
+	memset(&obj, 0, sizeof(obj));
+	obj.handle = gem_create(fd, batch_size);
+
+	b = batch = gem_mmap__cpu(fd, obj.handle, 0, batch_size, PROT_WRITE);
+	gem_set_domain(fd, obj.handle,
+		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+
+	if (flags & UNSAFE) {
+		for (unsigned int n = 0; n < NUM_REGS; n++) {
+			*b++ = 0x22 << 23 | 1; /* LRI */
+			*b++ = n * sizeof(uint32_t);
+			*b++ = value;
+		}
+	} else {
+		for (const struct named_register *r = safe_registers;
+		     r->name; r++) {
+			if (!(r->engine_mask & engine_bit))
+				continue;
+			if (!(r->gen_mask & gen_bit))
+				continue;
+			*b++ = 0x22 << 23 | 1; /* LRI */
+			*b++ = r->offset;
+			*b++ = value;
+		}
+	}
+	*b++ = MI_BATCH_BUFFER_END;
+	munmap(batch, batch_size);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(&obj);
+	execbuf.buffer_count = 1;
+	execbuf.flags = engine;
+	execbuf.rsvd1 = ctx;
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj.handle);
+}
+
+static void restore_regs(int fd,
+			 uint32_t ctx, unsigned int engine,
+			 unsigned int flags,
+			 uint32_t regs)
+{
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_relocation_entry *reloc;
+	unsigned int engine_bit, gen_bit;
+	unsigned int batch_size;
+	uint32_t *batch, *b;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << intel_gen(intel_get_drm_devid(fd));
+
+	reloc = calloc(NUM_REGS, sizeof(*reloc));
+	igt_assert(reloc);
+
+	batch_size = NUM_REGS * 3 * sizeof(uint32_t) + 4;
+	batch_size = PAGE_ALIGN(batch_size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = regs;
+	obj[1].handle = gem_create(fd, batch_size);
+	obj[1].relocs_ptr = to_user_pointer(reloc);
+
+	b = batch = gem_mmap__cpu(fd, obj[1].handle, 0, batch_size, PROT_WRITE);
+	gem_set_domain(fd, obj[1].handle,
+		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+
+	if (flags & UNSAFE) {
+		for (unsigned int n = 0; n < NUM_REGS; n++) {
+			*b++ = 0x29 << 23 | 2; /* LRM */
+			*b++ = n * sizeof(uint32_t);
+			reloc[n].target_handle = obj[0].handle;
+			reloc[n].presumed_offset = 0;
+			reloc[n].offset = (b - batch) * sizeof(*b);
+			reloc[n].delta = n * sizeof(uint32_t);
+			reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+			reloc[n].write_domain = 0;
+			*b++ = reloc[n].delta;
+			*b++ = 0;
+		}
+
+		obj[1].relocation_count = NUM_REGS;
+	} else {
+		unsigned int n = 0;
+
+		for (const struct named_register *r = safe_registers;
+		     r->name; r++) {
+			if (!(r->engine_mask & engine_bit))
+				continue;
+			if (!(r->gen_mask & gen_bit))
+				continue;
+
+			*b++ = 0x29 << 23 | 2; /* LRM */
+			*b++ = r->offset;
+			reloc[n].target_handle = obj[0].handle;
+			reloc[n].presumed_offset = 0;
+			reloc[n].offset = (b - batch) * sizeof(*b);
+			reloc[n].delta = r->offset;
+			reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+			reloc[n].write_domain = 0;
+			*b++ = reloc[n].delta;
+			*b++ = 0;
+
+			n++;
+		}
+
+		obj[1].relocation_count = n;
+	}
+	*b++ = MI_BATCH_BUFFER_END;
+	munmap(batch, batch_size);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 2;
+	execbuf.flags = engine;
+	execbuf.rsvd1 = ctx;
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj[1].handle);
+}
+
+__attribute__((unused))
+static void dump_regs(int fd, unsigned int engine, unsigned int regs)
+{
+	unsigned int engine_bit, gen_bit;
+	unsigned int regs_size;
+	uint32_t *out;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << intel_gen(intel_get_drm_devid(fd));
+
+	regs_size = NUM_REGS * sizeof(uint32_t);
+	regs_size = PAGE_ALIGN(regs_size);
+
+	out = gem_mmap__cpu(fd, regs, 0, regs_size, PROT_READ);
+	gem_set_domain(fd, regs, I915_GEM_DOMAIN_CPU, 0);
+
+	for (const struct named_register *r = safe_registers; r->name; r++) {
+		if (!(r->engine_mask & engine_bit))
+			continue;
+		if (!(r->gen_mask & gen_bit))
+			continue;
+
+		igt_debug("0x%04x [%s]: 0x%08x\n",
+			  r->offset, r->name, out[r->offset/4]);
+	}
+	munmap(out, regs_size);
+}
+
+static void compare_regs(int fd, uint32_t A, uint32_t B, const char *who)
+{
+	unsigned int num_errors;
+	unsigned int regs_size;
+	uint32_t *a, *b;
+
+	regs_size = NUM_REGS * sizeof(uint32_t);
+	regs_size = PAGE_ALIGN(regs_size);
+
+	a = gem_mmap__cpu(fd, A, 0, regs_size, PROT_READ);
+	gem_set_domain(fd, A, I915_GEM_DOMAIN_CPU, 0);
+
+	b = gem_mmap__cpu(fd, B, 0, regs_size, PROT_READ);
+	gem_set_domain(fd, B, I915_GEM_DOMAIN_CPU, 0);
+
+	num_errors = 0;
+	for (unsigned int n = 0; n < NUM_REGS; n++) {
+		uint32_t offset = n * sizeof(uint32_t);
+		if (a[n] != b[n] && !ignore_register(offset)) {
+			igt_warn("Register 0x%04x [%s]: A=%08x B=%08x\n",
+				 offset, register_name(offset), a[n], b[n]);
+			num_errors++;
+		}
+	}
+	munmap(b, regs_size);
+	munmap(a, regs_size);
+
+	igt_assert_f(num_errors == 0,
+		     "%d registers mistached between %s.",
+		     num_errors, who);
+}
+
+static void isolation(int fd, unsigned int engine, unsigned int flags)
+{
+	static const uint32_t values[] = {
+		0x0,
+		0xffffffff,
+		0xcccccccc,
+		0x33333333,
+		0x55555555,
+		0xaaaaaaaa,
+		0xdeadbeef
+	};
+	unsigned int num_values = flags & DIRTY ? ARRAY_SIZE(values) : 1;
+
+	for (int v = 0; v < num_values; v++) {
+		igt_spin_t *spin = NULL;
+		uint32_t ctx[2];
+		uint32_t regs[2];
+		uint32_t dirty;
+
+		ctx[0] = gem_context_create(fd);
+		regs[0] = read_regs(fd, ctx[0], engine, flags);
+
+		if (flags & DIRTY) {
+			spin = igt_spin_batch_new(fd, ctx[0], engine, 0);
+			write_regs(fd, ctx[0], engine, flags, values[v]);
+		}
+
+		/*
+		 * We create and execute a new context, whilst the HW is
+		 * occupied with the previous context (we should switch from
+		 * the old to the new proto-context without idling, which could
+		 * then load the powercontext). If all goes well, we only see
+		 * the default values from this context, but if goes badly we
+		 * see the corruption from the previous context instead!
+		 */
+		ctx[1] = gem_context_create(fd);
+		regs[1] = read_regs(fd, ctx[1], engine, flags);
+
+		/*
+		 * Restore the original register values before the HW idles.
+		 * Or else it may never restart!
+		 */
+		dirty = read_regs(fd, ctx[0], engine, flags);
+		restore_regs(fd, ctx[0], engine, flags, regs[0]);
+
+		igt_spin_batch_free(fd, spin);
+
+		if (!(flags & DIRTY))
+			compare_regs(fd, regs[0], dirty, "two reads of the same ctx");
+		compare_regs(fd, regs[0], regs[1], "two virgin contexts");
+
+		for (int n = 0; n < ARRAY_SIZE(ctx); n++) {
+			gem_close(fd, regs[n]);
+			gem_context_destroy(fd, ctx[n]);
+		}
+		gem_close(fd, dirty);
+	}
+}
+
+igt_main
+{
+	const unsigned int platform_validation = 0;
+	int fd = -1;
+
+	igt_fixture {
+		int gen;
+
+		fd = drm_open_driver(DRIVER_INTEL);
+		igt_require_gem(fd);
+
+		/* For guaranteed context isolation */
+		igt_require(gem_has_execlists(fd));
+		gem_context_destroy(fd, gem_context_create(fd));
+
+		gen = intel_gen(intel_get_drm_devid(fd));
+		//igt_ci_fail_on(gen > LAST_KNOWN_GEN);
+		igt_skip_on(gen > LAST_KNOWN_GEN);
+	}
+
+	for (const struct intel_execution_engine *e =
+	     intel_execution_engines; e->name; e++) {
+		igt_subtest_group {
+			unsigned int engine = e->exec_id | e->flags;
+			igt_fixture {
+				gem_require_ring(fd, engine);
+			}
+
+			igt_subtest_f("%s-clean", e->name)
+				isolation(fd, engine, 0);
+			igt_subtest_f("%s-dirty", e->name)
+				isolation(fd, engine, DIRTY);
+
+			igt_subtest_f("%s-unsafe", e->name) {
+				igt_require(platform_validation);
+				isolation(fd, engine, DIRTY | UNSAFE);
+			}
+		}
+	}
+}
-- 
2.15.0.rc1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH xf86-video-intel v3] hmm
  2017-10-24 14:20 ` [PATCH xf86-video-intel v3] hmm Chris Wilson
@ 2017-10-24 14:22   ` Chris Wilson
  0 siblings, 0 replies; 13+ messages in thread
From: Chris Wilson @ 2017-10-24 14:22 UTC (permalink / raw)
  To: intel-gfx

I am really not paying attention to the directory hopping between
machines! Sorry.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* ✗ Fi.CI.BAT: failure for igt/gem_ctx_isolation: Check isolation of registers between contexts (rev3)
  2017-10-24 11:07 [PATCH igt] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
                   ` (5 preceding siblings ...)
  2017-10-24 14:21 ` [PATCH igt v3] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
@ 2017-10-24 15:02 ` Patchwork
  2017-10-24 20:20 ` [PATCH igt v2] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Patchwork @ 2017-10-24 15:02 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: igt/gem_ctx_isolation: Check isolation of registers between contexts (rev3)
URL   : https://patchwork.freedesktop.org/series/32531/
State : failure

== Summary ==

IGT patchset build failed on latest successful build
e5f7fac9f120b0dcbf370c681b8872b8c29bf890 meson: intel_dp_compliance depends on libudev

The Meson build system
Version: 0.40.1
Source dir: /home/cidrm/intel-gpu-tools
Build dir: /home/cidrm/intel-gpu-tools/build
Build type: native build
Project name: IGT gpu tests
Native c compiler: ccache cc (gcc 6.3.0)
Build machine cpu family: x86_64
Build machine cpu: x86_64
Compiler for c supports argument -Wno-unused-parameter: YES
Compiler for c supports argument -Wno-sign-compare: YES
Compiler for c supports argument -Wno-missing-field-initializers: YES
Compiler for c supports argument -Wno-clobbered: YES
Compiler for c supports argument -Wno-type-limits: YES
Compiler for c supports argument -Wimplicit-fallthrough=0: NO
Found pkg-config: /usr/bin/pkg-config (0.29.1)
Native dependency libdrm found: YES 2.4.85
Native dependency libdrm_intel found: YES 2.4.85
Dependency libdrm_vc4 found: NO
Dependency libdrm_nouveau found: NO
Dependency libdrm_amdgpu found: NO
Native dependency pciaccess found: YES 0.13.4
Native dependency libkmod found: YES 22
Native dependency libprocps found: YES 3.3.12
Native dependency cairo found: YES 1.14.8
Native dependency libudev found: YES 232
Native dependency glib-2.0 found: YES 2.52.0
Native dependency libunwind found: YES 1.1
Native dependency gsl found: YES 2.3
Dependency alsa found: NO
Native dependency pixman-1 found: YES 0.34.0
Dependency xmlrpc found: NO
Dependency xmlrpc_util found: NO
Dependency xmlrpc_client found: NO
Program xmlrpc-c-config found: YES (/usr/bin/xmlrpc-c-config)
Dependency threads found: YES
Library m found: YES
Library rt found: YES
Library dl found: YES
Library z found: YES
Has header "linux/kd.h": YES
Has header "sys/kd.h": YES
Has header "libgen.h": YES
Has header "sys/io.h": YES
Has header "cpuid.h": YES
Checking whether type "struct sysinfo" has member "totalram": YES
Configuring config.h using configuration
Program generate_testlist.sh found: YES (/home/cidrm/intel-gpu-tools/tests/generate_testlist.sh)
Program igt_command_line.sh found: YES (/home/cidrm/intel-gpu-tools/tests/igt_command_line.sh)
Configuring intel_aubdump using configuration
Program flex found: YES (/usr/bin/flex)
Program bison found: YES (/usr/bin/bison)
Configuring intel-gen4asm.pc using configuration
Program test/run-test.sh found: YES (/bin/sh /home/cidrm/intel-gpu-tools/assembler/test/run-test.sh)
Native dependency xv found: YES 1.0.11
Native dependency x11 found: YES 1.6.4
Native dependency xext found: YES 1.3.3
Native dependency dri2proto found: YES 2.8
Native dependency cairo-xlib found: YES 1.14.8
Dependency xrandr found: NO
Configuring defs.rst using configuration
Program rst2man found: YES (/usr/bin/rst2man)
Program rst2man.sh found: YES (/home/cidrm/intel-gpu-tools/man/rst2man.sh)
Build targets in project: 369
ninja: Entering directory `build'
[1/743] Compiling c object 'lib/tests/igt_simple_test_subtests@exe/igt_simple_test_subtests.c.o'
[2/743] Compiling c object 'tests/core_auth@exe/core_auth.c.o'
[3/743] Compiling c object 'lib/igt@sha/dummy.c.o'
[4/743] Compiling c object 'lib/tests/igt_simulation@exe/igt_simulation.c.o'
[5/743] Compiling c object 'lib/tests/igt_list_only@exe/igt_list_only.c.o'
[6/743] Compiling c object 'lib/tests/igt_fork_helper@exe/igt_fork_helper.c.o'
[7/743] Compiling c object 'lib/tests/igt_hdmi_inject@exe/igt_hdmi_inject.c.o'
[8/743] Compiling c object 'lib/tests/igt_exit_handler@exe/igt_exit_handler.c.o'
[9/743] Compiling c object 'lib/tests/igt_stats@exe/igt_stats.c.o'
[10/743] Compiling c object 'lib/tests/igt_segfault@exe/igt_segfault.c.o'
[11/743] Compiling c object 'lib/tests/igt_subtest_group@exe/igt_subtest_group.c.o'
[12/743] Compiling c object 'lib/tests/igt_assert@exe/igt_assert.c.o'
[13/743] Compiling c object 'lib/tests/igt_can_fail@exe/igt_can_fail.c.o'
[14/743] Compiling c object 'lib/tests/igt_can_fail_simple@exe/igt_can_fail_simple.c.o'
[15/743] Compiling c object 'lib/tests/igt_no_exit@exe/igt_no_exit.c.o'
[16/743] Compiling c object 'lib/tests/igt_no_exit_list_only@exe/igt_no_exit_list_only.c.o'
[17/743] Compiling c object 'lib/tests/igt_no_subtest@exe/igt_no_subtest.c.o'
[18/743] Compiling c object 'lib/tests/igt_invalid_subtest_name@exe/igt_invalid_subtest_name.c.o'
[19/743] Compiling c object 'lib/tests/igt_timeout@exe/igt_timeout.c.o'
[20/743] Compiling c object 'tests/core_get_client_auth@exe/core_get_client_auth.c.o'
[21/743] Compiling c object 'tests/gem_fenced_exec_thrash@exe/gem_fenced_exec_thrash.c.o'
[22/743] Compiling c object 'tests/core_getclient@exe/core_getclient.c.o'
[23/743] Compiling c object 'tests/core_getversion@exe/core_getversion.c.o'
[24/743] Compiling c object 'tests/core_getstats@exe/core_getstats.c.o'
[25/743] Compiling c object 'tests/core_setmaster_vs_auth@exe/core_setmaster_vs_auth.c.o'
[26/743] Compiling c object 'tests/core_prop_blob@exe/core_prop_blob.c.o'
[27/743] Compiling c object 'tests/drm_vma_limiter_cached@exe/drm_vma_limiter_cached.c.o'
[28/743] Compiling c object 'tests/drm_vma_limiter@exe/drm_vma_limiter.c.o'
[29/743] Compiling c object 'tests/drm_vma_limiter_gtt@exe/drm_vma_limiter_gtt.c.o'
[30/743] Compiling c object 'tests/gem_fence_upload@exe/gem_fence_upload.c.o'
[31/743] Compiling c object 'tests/debugfs_test@exe/debugfs_test.c.o'
[32/743] Compiling c object 'tests/drm_import_export@exe/drm_import_export.c.o'
[33/743] Compiling c object 'tests/drm_mm@exe/drm_mm.c.o'
[34/743] Compiling c object 'tests/drm_read@exe/drm_read.c.o'
[35/743] Compiling c object 'tests/drm_vma_limiter_cpu@exe/drm_vma_limiter_cpu.c.o'
[36/743] Compiling c object 'tests/drv_missed_irq@exe/drv_missed_irq.c.o'
[37/743] Compiling c object 'tests/drv_getparams_basic@exe/drv_getparams_basic.c.o'
[38/743] Compiling c object 'tests/gem_exec_basic@exe/gem_exec_basic.c.o'
[39/743] Compiling c object 'tests/drv_hangman@exe/drv_hangman.c.o'
[40/743] Compiling c object 'tests/drv_module_reload@exe/drv_module_reload.c.o'
[41/743] Compiling c object 'tests/drv_suspend@exe/drv_suspend.c.o'
[42/743] Compiling c object 'tests/drv_selftest@exe/drv_selftest.c.o'
[43/743] Compiling c object 'tests/gem_busy@exe/gem_busy.c.o'
[44/743] Compiling c object 'tests/gem_bad_reloc@exe/gem_bad_reloc.c.o'
[45/743] Compiling c object 'tests/gem_basic@exe/gem_basic.c.o'
[46/743] Compiling c object 'tests/gem_close@exe/gem_close.c.o'
[47/743] Compiling c object 'tests/gem_caching@exe/gem_caching.c.o'
[48/743] Compiling c object 'tests/gem_close_race@exe/gem_close_race.c.o'
[49/743] Compiling c object 'tests/gem_create@exe/gem_create.c.o'
[50/743] Compiling c object 'tests/gem_cpu_reloc@exe/gem_cpu_reloc.c.o'
[51/743] Compiling c object 'tests/gem_concurrent_blit@exe/gem_concurrent_blit.c.o'
[52/743] Compiling c object 'tests/gem_ctx_bad_destroy@exe/gem_ctx_bad_destroy.c.o'
[53/743] Compiling c object 'tests/gem_cs_prefetch@exe/gem_cs_prefetch.c.o'
[54/743] Compiling c object 'tests/gem_cs_tlb@exe/gem_cs_tlb.c.o'
[55/743] Compiling c object 'tests/gem_ctx_basic@exe/gem_ctx_basic.c.o'
[56/743] Compiling c object 'tests/gem_ctx_bad_exec@exe/gem_ctx_bad_exec.c.o'
[57/743] Compiling c object 'tests/gem_ctx_param@exe/gem_ctx_param.c.o'
[58/743] Compiling c object 'tests/gem_ctx_exec@exe/gem_ctx_exec.c.o'
[59/743] Compiling c object 'tests/gem_ctx_create@exe/gem_ctx_create.c.o'
[60/743] Compiling c object 'tests/gem_ctx_switch@exe/gem_ctx_switch.c.o'
[61/743] Compiling c object 'tests/gem_double_irq_loop@exe/gem_double_irq_loop.c.o'
[62/743] Compiling c object 'tests/gem_ctx_thrash@exe/gem_ctx_thrash.c.o'
[63/743] Compiling c object 'tests/gem_evict_alignment@exe/gem_evict_alignment.c.o'
[64/743] Compiling c object 'tests/gem_eio@exe/gem_eio.c.o'
[65/743] Compiling c object 'tests/gem_exec_alignment@exe/gem_exec_alignment.c.o'
[66/743] Compiling c object 'tests/gem_evict_everything@exe/gem_evict_everything.c.o'
[67/743] Compiling c object 'tests/gem_exec_async@exe/gem_exec_async.c.o'
[68/743] Compiling c object 'tests/gem_exec_bad_domains@exe/gem_exec_bad_domains.c.o'
[69/743] Compiling c object 'tests/gem_exec_await@exe/gem_exec_await.c.o'
[70/743] Compiling c object 'tests/gem_exec_big@exe/gem_exec_big.c.o'
[71/743] Compiling c object 'tests/gem_exec_blt@exe/gem_exec_blt.c.o'
[72/743] Compiling c object 'tests/gem_exec_create@exe/gem_exec_create.c.o'
[73/743] Compiling c object 'tests/gem_exec_capture@exe/gem_exec_capture.c.o'
[74/743] Compiling c object 'tests/gem_exec_faulting_reloc@exe/gem_exec_faulting_reloc.c.o'
[75/743] Compiling c object 'tests/gem_exec_flush@exe/gem_exec_flush.c.o'
[76/743] Compiling c object 'tests/gem_exec_fence@exe/gem_exec_fence.c.o'
[77/743] Compiling c object 'tests/gem_exec_gttfill@exe/gem_exec_gttfill.c.o'
[78/743] Compiling c object 'tests/gem_exec_latency@exe/gem_exec_latency.c.o'
[79/743] Compiling c object 'tests/gem_exec_parallel@exe/gem_exec_parallel.c.o'
[80/743] Compiling c object 'tests/gem_exec_nop@exe/gem_exec_nop.c.o'
[81/743] Compiling c object 'tests/gem_exec_lut_handle@exe/gem_exec_lut_handle.c.o'
[82/743] Compiling c object 'tests/gem_exec_parse@exe/gem_exec_parse.c.o'
[83/743] Compiling c object 'tests/gem_exec_params@exe/gem_exec_params.c.o'
[84/743] Compiling c object 'tests/gem_exec_reuse@exe/gem_exec_reuse.c.o'
[85/743] Compiling c object 'tests/gem_exec_reloc@exe/gem_exec_reloc.c.o'
[86/743] Compiling c object 'tests/gem_exec_schedule@exe/gem_exec_schedule.c.o'
[87/743] Compiling c object 'tests/gem_exec_suspend@exe/gem_exec_suspend.c.o'
[88/743] Compiling c object 'tests/gem_exec_store@exe/gem_exec_store.c.o'
[89/743] Compiling c object 'tests/gem_exec_whisper@exe/gem_exec_whisper.c.o'
[90/743] Compiling c object 'tests/gem_fence_thrash@exe/gem_fence_thrash.c.o'
[91/743] Compiling c object 'tests/gem_fd_exhaustion@exe/gem_fd_exhaustion.c.o'
[92/743] Compiling c object 'tests/prime_vgem@exe/prime_vgem.c.o'
[93/743] Compiling c object 'tests/gem_flink_basic@exe/gem_flink_basic.c.o'
[94/743] Compiling c object 'tests/gem_gpgpu_fill@exe/gem_gpgpu_fill.c.o'
[95/743] Compiling c object 'tests/gem_flink_race@exe/gem_flink_race.c.o'
[96/743] Compiling c object 'tests/gem_gtt_hog@exe/gem_gtt_hog.c.o'
[97/743] Compiling c object 'tests/gem_gtt_cpu_tlb@exe/gem_gtt_cpu_tlb.c.o'
[98/743] Compiling c object 'tests/gem_hangcheck_forcewake@exe/gem_hangcheck_forcewake.c.o'
[99/743] Compiling c object 'tests/gem_gtt_speed@exe/gem_gtt_speed.c.o'
[100/743] Compiling c object 'tests/gem_linear_blits@exe/gem_linear_blits.c.o'
[101/743] Compiling c object 'tests/gem_largeobject@exe/gem_largeobject.c.o'
[102/743] Compiling c object 'tests/gem_media_fill@exe/gem_media_fill.c.o'
[103/743] Compiling c object 'tests/gem_madvise@exe/gem_madvise.c.o'
[104/743] Compiling c object 'tests/gem_lut_handle@exe/gem_lut_handle.c.o'
[105/743] Compiling c object 'tests/gem_mmap_gtt@exe/gem_mmap_gtt.c.o'
[106/743] Compiling c object 'tests/gem_mmap@exe/gem_mmap.c.o'
[107/743] Compiling c object 'tests/gem_mmap_offset_exhaustion@exe/gem_mmap_offset_exhaustion.c.o'
[108/743] Compiling c object 'tests/gem_mocs_settings@exe/gem_mocs_settings.c.o'
[109/743] Compiling c object 'tests/gem_mmap_wc@exe/gem_mmap_wc.c.o'
[110/743] Compiling c object 'tests/gem_persistent_relocs@exe/gem_persistent_relocs.c.o'
[111/743] Compiling c object 'tests/gem_partial_pwrite_pread@exe/gem_partial_pwrite_pread.c.o'
[112/743] Compiling c object 'tests/gem_pin@exe/gem_pin.c.o'
[113/743] Compiling c object 'tests/gem_pipe_control_store_loop@exe/gem_pipe_control_store_loop.c.o'
[114/743] Compiling c object 'tests/gem_pread@exe/gem_pread.c.o'
[115/743] Compiling c object 'tests/gem_ppgtt@exe/gem_ppgtt.c.o'
[116/743] Compiling c object 'tests/gem_pread_after_blit@exe/gem_pread_after_blit.c.o'
[117/743] Compiling c object 'tests/gem_pwrite_pread@exe/gem_pwrite_pread.c.o'
[118/743] Compiling c object 'tests/gem_pwrite@exe/gem_pwrite.c.o'
[119/743] Compiling c object 'tests/gem_read_read_speed@exe/gem_read_read_speed.c.o'
[120/743] Compiling c object 'tests/gem_pwrite_snooped@exe/gem_pwrite_snooped.c.o'
[121/743] Compiling c object 'tests/gem_readwrite@exe/gem_readwrite.c.o'
[122/743] Compiling c object 'tests/gem_reloc_overflow@exe/gem_reloc_overflow.c.o'
[123/743] Compiling c object 'tests/gem_reloc_vs_gpu@exe/gem_reloc_vs_gpu.c.o'
[124/743] Compiling c object 'tests/gem_reg_read@exe/gem_reg_read.c.o'
[125/743] Compiling c object 'tests/gem_render_copy_redux@exe/gem_render_copy_redux.c.o'
[126/743] Compiling c object 'tests/gem_render_copy@exe/gem_render_copy.c.o'
[127/743] Compiling c object 'tests/gem_render_linear_blits@exe/gem_render_linear_blits.c.o'
[128/743] Compiling c object 'tests/gem_render_tiled_blits@exe/gem_render_tiled_blits.c.o'
[129/743] Compiling c object 'tests/gem_request_retire@exe/gem_request_retire.c.o'
[130/743] Compiling c object 'tests/gem_reset_stats@exe/gem_reset_stats.c.o'
[131/743] Compiling c object 'tests/gem_ring_sync_copy@exe/gem_ring_sync_copy.c.o'
[132/743] Compiling c object 'tests/gem_ring_sync_loop@exe/gem_ring_sync_loop.c.o'
[133/743] Compiling c object 'tests/gem_ringfill@exe/gem_ringfill.c.o'
[134/743] Compiling c object 'benchmarks/vgem_mmap_bench@exe/vgem_mmap.c.o'
[135/743] Compiling c object 'tests/gem_seqno_wrap@exe/gem_seqno_wrap.c.o'
[136/743] Compiling c object 'tests/gem_set_tiling_vs_pwrite@exe/gem_set_tiling_vs_pwrite.c.o'
[137/743] Compiling c object 'tests/gem_set_tiling_vs_blt@exe/gem_set_tiling_vs_blt.c.o'
[138/743] Compiling c object 'tests/gem_set_tiling_vs_gtt@exe/gem_set_tiling_vs_gtt.c.o'
[139/743] Compiling c object 'tests/gem_shrink@exe/gem_shrink.c.o'
[140/743] Compiling c object 'tests/gem_spin_batch@exe/gem_spin_batch.c.o'
[141/743] Compiling c object 'tests/gem_softpin@exe/gem_softpin.c.o'
[142/743] Compiling c object 'tests/gem_storedw_batches_loop@exe/gem_storedw_batches_loop.c.o'
[143/743] Compiling c object 'tests/gem_stolen@exe/gem_stolen.c.o'
[144/743] Compiling c object 'tests/gem_streaming_writes@exe/gem_streaming_writes.c.o'
[145/743] Compiling c object 'tests/gem_storedw_loop@exe/gem_storedw_loop.c.o'
[146/743] Compiling c object 'tests/gem_sync@exe/gem_sync.c.o'
[147/743] Compiling c object 'tests/gem_threaded_access_tiled@exe/gem_threaded_access_tiled.c.o'
[148/743] Compiling c object 'tests/gem_tiled_blits@exe/gem_tiled_blits.c.o'
[149/743] Compiling c object 'tests/gem_tiled_fence_blits@exe/gem_tiled_fence_blits.c.o'
[150/743] Compiling c object 'tests/gem_tiled_pread_basic@exe/gem_tiled_pread_basic.c.o'
[151/743] Compiling c object 'tests/gem_tiled_partial_pwrite_pread@exe/gem_tiled_partial_pwrite_pread.c.o'
[152/743] Compiling c object 'tests/gem_tiled_swapping@exe/gem_tiled_swapping.c.o'
[153/743] Compiling c object 'tests/gem_tiled_wb@exe/gem_tiled_wb.c.o'
[154/743] Compiling c object 'tests/gem_tiled_pread_pwrite@exe/gem_tiled_pread_pwrite.c.o'
[155/743] Compiling c object 'tests/gem_tiled_wc@exe/gem_tiled_wc.c.o'
[156/743] Compiling c object 'tests/gem_tiling_max_stride@exe/gem_tiling_max_stride.c.o'
[157/743] Compiling c object 'tests/gem_unfence_active_buffers@exe/gem_unfence_active_buffers.c.o'
[158/743] Compiling c object 'tests/gem_unref_active_buffers@exe/gem_unref_active_buffers.c.o'
[159/743] Compiling c object 'tests/gem_userptr_blits@exe/gem_userptr_blits.c.o'
[160/743] Compiling c object 'tests/gem_wait@exe/gem_wait.c.o'
[161/743] Compiling c object 'tests/gem_write_read_ring_switch@exe/gem_write_read_ring_switch.c.o'
[162/743] Compiling c object 'tests/gen3_mixed_blits@exe/gen3_mixed_blits.c.o'
[163/743] Compiling c object 'tests/gem_workarounds@exe/gem_workarounds.c.o'
[164/743] Compiling c object 'tests/gen3_render_linear_blits@exe/gen3_render_linear_blits.c.o'
[165/743] Compiling c object 'tests/gen3_render_mixed_blits@exe/gen3_render_mixed_blits.c.o'
[166/743] Compiling c object 'tests/gen3_render_tiledx_blits@exe/gen3_render_tiledx_blits.c.o'
[167/743] Compiling c object 'tests/gen3_render_tiledy_blits@exe/gen3_render_tiledy_blits.c.o'
[168/743] Compiling c object 'tests/kms_3d@exe/kms_3d.c.o'
[169/743] Compiling c object 'tests/gen7_forcewake_mt@exe/gen7_forcewake_mt.c.o'
[170/743] Compiling c object 'tests/gvt_basic@exe/gvt_basic.c.o'
[171/743] Compiling c object 'tests/kms_addfb_basic@exe/kms_addfb_basic.c.o'
[172/743] Compiling c object 'tests/kms_atomic@exe/kms_atomic.c.o'
[173/743] Compiling c object 'tests/kms_atomic_interruptible@exe/kms_atomic_interruptible.c.o'
[174/743] Compiling c object 'tests/kms_atomic_transition@exe/kms_atomic_transition.c.o'
[175/743] Compiling c object 'tests/kms_busy@exe/kms_busy.c.o'
[176/743] Compiling c object 'tests/kms_chv_cursor_fail@exe/kms_chv_cursor_fail.c.o'
[177/743] Compiling c object 'tests/kms_ccs@exe/kms_ccs.c.o'
[178/743] Compiling c object 'tests/kms_color@exe/kms_color.c.o'
[179/743] Compiling c object 'tests/kms_crtc_background_color@exe/kms_crtc_background_color.c.o'
[180/743] Compiling c object 'tests/kms_concurrent@exe/kms_concurrent.c.o'
[181/743] Compiling c object 'tests/kms_cursor_legacy@exe/kms_cursor_legacy.c.o'
[182/743] Compiling c object 'tests/kms_cursor_crc@exe/kms_cursor_crc.c.o'
[183/743] Compiling c object 'tests/kms_fbcon_fbt@exe/kms_fbcon_fbt.c.o'
[184/743] Compiling c object 'tests/kms_draw_crc@exe/kms_draw_crc.c.o'
[185/743] Compiling c object 'tests/kms_fence_pin_leak@exe/kms_fence_pin_leak.c.o'
[186/743] Compiling c object 'tests/kms_flip@exe/kms_flip.c.o'
[187/743] Compiling c object 'tests/kms_flip_tiling@exe/kms_flip_tiling.c.o'
[188/743] Compiling c object 'tests/kms_flip_event_leak@exe/kms_flip_event_leak.c.o'
[189/743] Compiling c object 'tests/kms_force_connector_basic@exe/kms_force_connector_basic.c.o'
[190/743] Compiling c object 'tests/kms_legacy_colorkey@exe/kms_legacy_colorkey.c.o'
[191/743] Compiling c object 'tests/kms_invalid_dotclock@exe/kms_invalid_dotclock.c.o'
[192/743] Compiling c object 'tests/kms_frontbuffer_tracking@exe/kms_frontbuffer_tracking.c.o'
[193/743] Compiling c object 'tests/kms_hdmi_inject@exe/kms_hdmi_inject.c.o'
[194/743] Compiling c object 'tests/kms_mmio_vs_cs_flip@exe/kms_mmio_vs_cs_flip.c.o'
[195/743] Compiling c object 'tests/kms_mmap_write_crc@exe/kms_mmap_write_crc.c.o'
[196/743] Compiling c object 'tests/kms_pipe_b_c_ivb@exe/kms_pipe_b_c_ivb.c.o'
[197/743] Compiling c object 'tests/kms_panel_fitting@exe/kms_panel_fitting.c.o'
[198/743] Compiling c object 'tests/kms_pipe_crc_basic@exe/kms_pipe_crc_basic.c.o'
[199/743] Compiling c object 'tests/kms_plane@exe/kms_plane.c.o'
[200/743] Compiling c object 'tests/kms_plane_multiple@exe/kms_plane_multiple.c.o'
[201/743] Compiling c object 'tests/kms_plane_scaling@exe/kms_plane_scaling.c.o'
[202/743] Compiling c object 'tests/kms_psr_sink_crc@exe/kms_psr_sink_crc.c.o'
[203/743] Compiling c object 'tests/kms_properties@exe/kms_properties.c.o'
[204/743] Compiling c object 'tests/kms_rmfb@exe/kms_rmfb.c.o'
[205/743] Compiling c object 'tests/kms_render@exe/kms_render.c.o'
[206/743] Compiling c object 'tests/kms_pwrite_crc@exe/kms_pwrite_crc.c.o'
[207/743] Compiling c object 'tests/kms_rotation_crc@exe/kms_rotation_crc.c.o'
[208/743] Compiling c object 'tests/kms_sink_crc_basic@exe/kms_sink_crc_basic.c.o'
[209/743] Compiling c object 'tests/kms_setmode@exe/kms_setmode.c.o'
[210/743] Compiling c object 'tests/kms_sysfs_edid_timing@exe/kms_sysfs_edid_timing.c.o'
[211/743] Compiling c object 'tests/kms_tv_load_detect@exe/kms_tv_load_detect.c.o'
[212/743] Compiling c object 'tests/meta_test@exe/meta_test.c.o'
[213/743] Compiling c object 'tests/kms_universal_plane@exe/kms_universal_plane.c.o'
[214/743] Compiling c object 'tests/kms_vblank@exe/kms_vblank.c.o'
[215/743] Compiling c object 'tests/perf@exe/perf.c.o'
[216/743] Compiling c object 'tests/pm_backlight@exe/pm_backlight.c.o'
[217/743] Compiling c object 'tests/pm_lpsp@exe/pm_lpsp.c.o'
[218/743] Compiling c object 'tests/pm_rpm@exe/pm_rpm.c.o'
[219/743] Compiling c object 'tests/pm_rc6_residency@exe/pm_rc6_residency.c.o'
[220/743] Compiling c object 'tests/pm_rps@exe/pm_rps.c.o'
[221/743] Compiling c objec

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH igt v2] igt/gem_ctx_isolation: Check isolation of registers between contexts
  2017-10-24 11:07 [PATCH igt] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
                   ` (6 preceding siblings ...)
  2017-10-24 15:02 ` ✗ Fi.CI.BAT: failure for igt/gem_ctx_isolation: Check isolation of registers between contexts (rev3) Patchwork
@ 2017-10-24 20:20 ` Chris Wilson
  2017-10-24 20:45 ` ✗ Fi.CI.BAT: failure for igt/gem_ctx_isolation: Check isolation of registers between contexts (rev4) Patchwork
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Chris Wilson @ 2017-10-24 20:20 UTC (permalink / raw)
  To: intel-gfx

A new context assumes that all of its registers are in the default state
when it is created. What may happen is that a register written by one
context may leak into the second, causing mass confusion.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 tests/Makefile.sources    |   1 +
 tests/gem_ctx_isolation.c | 631 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 632 insertions(+)
 create mode 100644 tests/gem_ctx_isolation.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 2313c12b..9a25a8b5 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -56,6 +56,7 @@ TESTS_progs = \
 	gem_ctx_basic \
 	gem_ctx_create \
 	gem_ctx_exec \
+	gem_ctx_isolation \
 	gem_ctx_param \
 	gem_ctx_switch \
 	gem_ctx_thrash \
diff --git a/tests/gem_ctx_isolation.c b/tests/gem_ctx_isolation.c
new file mode 100644
index 00000000..3c13f1b8
--- /dev/null
+++ b/tests/gem_ctx_isolation.c
@@ -0,0 +1,631 @@
+/*
+ * Copyright © 2017 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 "igt.h"
+#include "igt_dummyload.h"
+
+#define MAX_REG 0x40000
+#define NUM_REGS (MAX_REG / sizeof(uint32_t))
+
+#define PAGE_ALIGN(x) ALIGN(x, 4096)
+
+#define DIRTY 0x1
+#define UNSAFE 0x2
+
+enum {
+	RCS_MASK = 0x1,
+	BCS_MASK = 0x2,
+	VCS_MASK = 0x4,
+	VECS_MASK = 0x8,
+};
+
+#define ALL ~0u
+#define GEN_RANGE(x, y) ((ALL >> (32 - (y - x + 1))) << x)
+
+#define LAST_KNOWN_GEN 10
+
+static const struct named_register {
+	const char *name;
+	unsigned int gen_mask;
+	unsigned int engine_mask;
+	uint32_t offset;
+	uint32_t count;
+} safe_registers[] = {
+	{ "NOPID", ALL, RCS_MASK, 0x2094 },
+	{ "MI_PREDICATE_RESULT_2", ALL, RCS_MASK, 0x23bc },
+	{ "INSTPM", ALL, RCS_MASK, 0x20c0 },
+	{ "IA_VERTICES_COUNT", ALL, RCS_MASK, 0x2310, 2 },
+	{ "IA_PRIMITIVES_COUNT", ALL, RCS_MASK, 0x2318, 2 },
+	{ "VS_INVOCATION_COUNT", ALL, RCS_MASK, 0x2320, 2 },
+	{ "HS_INVOCATION_COUNT", ALL, RCS_MASK, 0x2300, 2 },
+	{ "DS_INVOCATION_COUNT", ALL, RCS_MASK, 0x2308, 2 },
+	{ "GS_INVOCATION_COUNT", ALL, RCS_MASK, 0x2328, 2 },
+	{ "GS_PRIMITIVES_COUNT", ALL, RCS_MASK, 0x2330, 2 },
+	{ "CL_INVOCATION_COUNT", ALL, RCS_MASK, 0x2338, 2 },
+	{ "CL_PRIMITIVES_COUNT", ALL, RCS_MASK, 0x2340, 2 },
+	{ "PS_INVOCATION_COUNT_0", ALL, RCS_MASK, 0x22c8, 2 },
+	{ "PS_DEPTH_COUNT_0", ALL, RCS_MASK, 0x22d8, 2 },
+	{ "GPUGPU_DISPATCHDIMX", ALL, RCS_MASK, 0x2500 },
+	{ "GPUGPU_DISPATCHDIMY", ALL, RCS_MASK, 0x2504 },
+	{ "GPUGPU_DISPATCHDIMZ", ALL, RCS_MASK, 0x2508 },
+	{ "MI_PREDICATE_SRC0", ALL, RCS_MASK, 0x2400, 2 },
+	{ "MI_PREDICATE_SRC1", ALL, RCS_MASK, 0x2408, 2 },
+	{ "MI_PREDICATE_DATA", ALL, RCS_MASK, 0x2410, 2 },
+	{ "MI_PRED_RESULT", ALL, RCS_MASK, 0x2418 },
+	{ "3DPRIM_END_OFFSET", ALL, RCS_MASK, 0x2420 },
+	{ "3DPRIM_START_VERTEX", ALL, RCS_MASK, 0x2430 },
+	{ "3DPRIM_VERTEX_COUNT", ALL, RCS_MASK, 0x2434 },
+	{ "3DPRIM_INSTANCE_COUNT", ALL, RCS_MASK, 0x2438 },
+	{ "3DPRIM_START_INSTANCE", ALL, RCS_MASK, 0x243c },
+	{ "3DPRIM_BASE_VERTEX", ALL, RCS_MASK, 0x2440 },
+	{ "GPGPU_THREADS_DISPATCHED", ALL, RCS_MASK, 0x2290, 2 },
+	{ "PS_INVOCATION_COUNT_1", ALL, RCS_MASK, 0x22f0, 2 },
+	{ "PS_DEPTH_COUNT_1", ALL, RCS_MASK, 0x22f8, 2 },
+	{ "BB_OFFSET", ALL, RCS_MASK, 0x2158 },
+	{ "MI_PREDICATE_RESULT_1", ALL, RCS_MASK, 0x241c },
+	{ "CS_GPR", ALL, RCS_MASK, 0x2600, 32 },
+	{ "OA_CTX_CONTROL", ALL, RCS_MASK, 0x2360 },
+	{ "OACTXID", ALL, RCS_MASK, 0x2364 },
+	{ "PS_INVOCATION_COUNT_2", ALL, RCS_MASK, 0x2448, 2 },
+	{ "PS_DEPTH_COUNT_2", ALL, RCS_MASK, 0x2450, 2 },
+	{ "Cache_Mode_0", ALL, RCS_MASK, 0x7000 },
+	{ "Cache_Mode_1", ALL, RCS_MASK, 0x7004 },
+	{ "GT_MODE", ALL, RCS_MASK, 0x7008 },
+	{ "L3_Config", ALL, RCS_MASK, 0x7034 },
+	{ "TD_CTL", ALL, RCS_MASK, 0xe400 },
+	{ "TD_CTL2", ALL, RCS_MASK, 0xe404 },
+	{ "SO_NUM_PRIMS_WRITEN0", ALL, RCS_MASK, 0x5200, 2 },
+	{ "SO_NUM_PRIMS_WRITEN1", ALL, RCS_MASK, 0x5208, 2 },
+	{ "SO_NUM_PRIMS_WRITEN2", ALL, RCS_MASK, 0x5210, 2 },
+	{ "SO_NUM_PRIMS_WRITEN3", ALL, RCS_MASK, 0x5218, 2 },
+	{ "SO_PRIM_STORAGE_NEEDED0", ALL, RCS_MASK, 0x5240, 2 },
+	{ "SO_PRIM_STORAGE_NEEDED1", ALL, RCS_MASK, 0x5248, 2 },
+	{ "SO_PRIM_STORAGE_NEEDED2", ALL, RCS_MASK, 0x5250, 2 },
+	{ "SO_PRIM_STORAGE_NEEDED3", ALL, RCS_MASK, 0x5258, 2 },
+	{ "SO_WRITE_OFFSET0", ALL, RCS_MASK, 0x5280 },
+	{ "SO_WRITE_OFFSET1", ALL, RCS_MASK, 0x5284 },
+	{ "SO_WRITE_OFFSET2", ALL, RCS_MASK, 0x5288 },
+	{ "SO_WRITE_OFFSET3", ALL, RCS_MASK, 0x528c },
+	{ "OA_CONTROL", ALL, RCS_MASK, 0x2b00 },
+	{ "PERF_CNT_1", ALL, RCS_MASK, 0x91b8, 2 },
+	{ "PERF_CNT_2", ALL, RCS_MASK, 0x91c0, 2 },
+
+	/* Privileged (enabled by w/a + FORCE_TO_NONPRIV) */
+	{ "CTX_PREEMPT", GEN_RANGE(9, 10), RCS_MASK, 0x2248 },
+	{ "CS_CHICKEN1", GEN_RANGE(9, 10), RCS_MASK, 0x2580 },
+	{ "HDC_CHICKEN1", GEN_RANGE(9, 10), RCS_MASK, 0x7304 },
+	{ "L3SQREG1", ALL, RCS_MASK, 0xb010 },
+
+	{ "BCS_GPR", ALL, BCS_MASK, 0x22600, 32 },
+	{ "BCS_SWCTRL", ALL, BCS_MASK, 0x22200 },
+
+	{ "VCS0_GPR", ALL, VCS_MASK, 0x12600, 32 },
+	{ "MFC_VDBOX1", ALL, VCS_MASK, 0x12800, 64 },
+
+	{ "VCS1_GPR", ALL, VCS_MASK, 0x1c600, 32 },
+	{ "MFC_VDBOX2", ALL, VCS_MASK, 0x1c800, 64 },
+
+	{ "VECS_GPR", ALL, VECS_MASK, 0x1a600, 32 },
+
+	{}
+}, ignore_registers[] = {
+	{ "RCS timestamp", ALL, RCS_MASK, 0x2358 },
+	{ "VCS0 timestamp", ALL, VCS_MASK, 0x12358 },
+	{ "VCS1 timestamp", ALL, VCS_MASK, 0x1c358 },
+	{ "BCS timestamp", ALL, BCS_MASK, 0x22358 },
+	{ "VECS timestamp", ALL, VECS_MASK, 0x1a358 },
+	{}
+};
+
+static const char *register_name(uint32_t offset, char *buf, size_t len)
+{
+	for (const struct named_register *r = safe_registers; r->name; r++) {
+		unsigned int width = r->count ? 4*r->count : 4;
+		if (offset >= r->offset && offset < r->offset + width) {
+			if (r->count <= 1)
+				return r->name;
+
+			snprintf(buf, len, "%s[%d]",
+				 r->name, (offset - r->offset)/4);
+			return buf;
+		}
+	}
+
+	return "unknown";
+}
+
+static bool ignore_register(uint32_t offset)
+{
+	for (const struct named_register *r = ignore_registers; r->name; r++) {
+		unsigned int width = r->count ? 4*r->count : 4;
+		if (offset >= r->offset && offset < r->offset + width)
+			return true;
+	}
+
+	return false;
+}
+
+static uint32_t read_regs(int fd,
+			  uint32_t ctx, unsigned int engine,
+			  unsigned int flags)
+{
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_relocation_entry *reloc;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	unsigned int regs_size, batch_size;
+	unsigned int engine_bit, gen_bit;
+	uint32_t *batch, *b;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << intel_gen(intel_get_drm_devid(fd));
+
+	reloc = calloc(NUM_REGS, sizeof(*reloc));
+	igt_assert(reloc);
+
+	regs_size = NUM_REGS * sizeof(uint32_t);
+	regs_size = PAGE_ALIGN(regs_size);
+
+	batch_size = NUM_REGS * 4 * sizeof(uint32_t) + 4;
+	batch_size = PAGE_ALIGN(batch_size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = gem_create(fd, regs_size);
+	obj[1].handle = gem_create(fd, batch_size);
+	obj[1].relocs_ptr = to_user_pointer(reloc);
+
+	b = batch = gem_mmap__cpu(fd, obj[1].handle, 0, batch_size, PROT_WRITE);
+	gem_set_domain(fd, obj[1].handle,
+		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+
+	if (flags & UNSAFE) {
+		for (unsigned int n = 0; n < NUM_REGS; n++) {
+			*b++ = 0x24 << 23 | 2;
+			*b++ = n * sizeof(uint32_t);
+			reloc[n].target_handle = obj[0].handle;
+			reloc[n].presumed_offset = 0;
+			reloc[n].offset = (b - batch) * sizeof(*b);
+			reloc[n].delta = sizeof(uint32_t) * n;
+			reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+			reloc[n].write_domain = I915_GEM_DOMAIN_RENDER;
+			*b++ = reloc[n].delta;
+			*b++ = 0;
+		}
+		obj[1].relocation_count = NUM_REGS;
+	} else {
+		unsigned int n = 0;
+
+		for (const struct named_register *r = safe_registers;
+		     r->name; r++) {
+			if (!(r->engine_mask & engine_bit))
+				continue;
+			if (!(r->gen_mask & gen_bit))
+				continue;
+
+			for (unsigned count = r->count ?: 1, offset = r->offset;
+			     count--; offset += 4) {
+				*b++ = 0x24 << 23 | 2; /* SRM */
+				*b++ = offset;
+				reloc[n].target_handle = obj[0].handle;
+				reloc[n].presumed_offset = 0;
+				reloc[n].offset = (b - batch) * sizeof(*b);
+				reloc[n].delta = offset;
+				reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+				reloc[n].write_domain = I915_GEM_DOMAIN_RENDER;
+				*b++ = offset;
+				*b++ = 0;
+				n++;
+			}
+		}
+
+		obj[1].relocation_count = n;
+	}
+	*b++ = MI_BATCH_BUFFER_END;
+	munmap(batch, batch_size);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 2;
+	execbuf.flags = engine;
+	execbuf.rsvd1 = ctx;
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj[1].handle);
+	free(reloc);
+
+	return obj[0].handle;
+}
+
+static void write_regs(int fd,
+		       uint32_t ctx, unsigned int engine,
+		       unsigned int flags,
+		       uint32_t value)
+{
+	struct drm_i915_gem_exec_object2 obj;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	unsigned int engine_bit, gen_bit;
+	unsigned int batch_size;
+	uint32_t *batch, *b;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << intel_gen(intel_get_drm_devid(fd));
+
+	batch_size = NUM_REGS * 3 * sizeof(uint32_t) + 4;
+	batch_size = PAGE_ALIGN(batch_size);
+
+	memset(&obj, 0, sizeof(obj));
+	obj.handle = gem_create(fd, batch_size);
+
+	b = batch = gem_mmap__cpu(fd, obj.handle, 0, batch_size, PROT_WRITE);
+	gem_set_domain(fd, obj.handle,
+		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+
+	if (flags & UNSAFE) {
+		for (unsigned int n = 0; n < NUM_REGS; n++) {
+			*b++ = 0x22 << 23 | 1; /* LRI */
+			*b++ = n * sizeof(uint32_t);
+			*b++ = value;
+		}
+	} else {
+		for (const struct named_register *r = safe_registers;
+		     r->name; r++) {
+			if (!(r->engine_mask & engine_bit))
+				continue;
+			if (!(r->gen_mask & gen_bit))
+				continue;
+			for (unsigned count = r->count ?: 1, offset = r->offset;
+			     count--; offset += 4) {
+				*b++ = 0x22 << 23 | 1; /* LRI */
+				*b++ = offset;
+				*b++ = value;
+			}
+		}
+	}
+	*b++ = MI_BATCH_BUFFER_END;
+	munmap(batch, batch_size);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(&obj);
+	execbuf.buffer_count = 1;
+	execbuf.flags = engine;
+	execbuf.rsvd1 = ctx;
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj.handle);
+}
+
+static void restore_regs(int fd,
+			 uint32_t ctx, unsigned int engine,
+			 unsigned int flags,
+			 uint32_t regs)
+{
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_relocation_entry *reloc;
+	unsigned int engine_bit, gen_bit;
+	unsigned int batch_size;
+	uint32_t *batch, *b;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << intel_gen(intel_get_drm_devid(fd));
+
+	reloc = calloc(NUM_REGS, sizeof(*reloc));
+	igt_assert(reloc);
+
+	batch_size = NUM_REGS * 3 * sizeof(uint32_t) + 4;
+	batch_size = PAGE_ALIGN(batch_size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = regs;
+	obj[1].handle = gem_create(fd, batch_size);
+	obj[1].relocs_ptr = to_user_pointer(reloc);
+
+	b = batch = gem_mmap__cpu(fd, obj[1].handle, 0, batch_size, PROT_WRITE);
+	gem_set_domain(fd, obj[1].handle,
+		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+
+	if (flags & UNSAFE) {
+		for (unsigned int n = 0; n < NUM_REGS; n++) {
+			*b++ = 0x29 << 23 | 2; /* LRM */
+			*b++ = n * sizeof(uint32_t);
+			reloc[n].target_handle = obj[0].handle;
+			reloc[n].presumed_offset = 0;
+			reloc[n].offset = (b - batch) * sizeof(*b);
+			reloc[n].delta = n * sizeof(uint32_t);
+			reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+			reloc[n].write_domain = 0;
+			*b++ = reloc[n].delta;
+			*b++ = 0;
+		}
+
+		obj[1].relocation_count = NUM_REGS;
+	} else {
+		unsigned int n = 0;
+
+		for (const struct named_register *r = safe_registers;
+		     r->name; r++) {
+			if (!(r->engine_mask & engine_bit))
+				continue;
+			if (!(r->gen_mask & gen_bit))
+				continue;
+
+			for (unsigned count = r->count ?: 1, offset = r->offset;
+			     count--; offset += 4) {
+				*b++ = 0x29 << 23 | 2; /* LRM */
+				*b++ = offset;
+				reloc[n].target_handle = obj[0].handle;
+				reloc[n].presumed_offset = 0;
+				reloc[n].offset = (b - batch) * sizeof(*b);
+				reloc[n].delta = offset;
+				reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+				reloc[n].write_domain = 0;
+				*b++ = offset;
+				*b++ = 0;
+				n++;
+			}
+		}
+
+		obj[1].relocation_count = n;
+	}
+	*b++ = MI_BATCH_BUFFER_END;
+	munmap(batch, batch_size);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 2;
+	execbuf.flags = engine;
+	execbuf.rsvd1 = ctx;
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj[1].handle);
+}
+
+__attribute__((unused))
+static void dump_regs(int fd, unsigned int engine, unsigned int regs)
+{
+	unsigned int engine_bit, gen_bit;
+	unsigned int regs_size;
+	uint32_t *out;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << intel_gen(intel_get_drm_devid(fd));
+
+	regs_size = NUM_REGS * sizeof(uint32_t);
+	regs_size = PAGE_ALIGN(regs_size);
+
+	out = gem_mmap__cpu(fd, regs, 0, regs_size, PROT_READ);
+	gem_set_domain(fd, regs, I915_GEM_DOMAIN_CPU, 0);
+
+	for (const struct named_register *r = safe_registers; r->name; r++) {
+		if (!(r->engine_mask & engine_bit))
+			continue;
+		if (!(r->gen_mask & gen_bit))
+			continue;
+
+		if (r->count <= 1) {
+			igt_debug("0x%04x (%s): 0x%08x\n",
+				  r->offset, r->name, out[r->offset/4]);
+		} else {
+			for (unsigned x = 0; x < r->count; x++)
+				igt_debug("0x%04x (%s[%d]): 0x%08x\n",
+					  r->offset+4*x, r->name, x,
+					  out[r->offset/4 + x]);
+		}
+	}
+	munmap(out, regs_size);
+}
+
+static void compare_regs(int fd, uint32_t A, uint32_t B, const char *who)
+{
+	unsigned int num_errors;
+	unsigned int regs_size;
+	uint32_t *a, *b;
+	char buf[80];
+
+	regs_size = NUM_REGS * sizeof(uint32_t);
+	regs_size = PAGE_ALIGN(regs_size);
+
+	a = gem_mmap__cpu(fd, A, 0, regs_size, PROT_READ);
+	gem_set_domain(fd, A, I915_GEM_DOMAIN_CPU, 0);
+
+	b = gem_mmap__cpu(fd, B, 0, regs_size, PROT_READ);
+	gem_set_domain(fd, B, I915_GEM_DOMAIN_CPU, 0);
+
+	num_errors = 0;
+	for (unsigned int n = 0; n < NUM_REGS; n++) {
+		uint32_t offset = n * sizeof(uint32_t);
+		if (a[n] != b[n] && !ignore_register(offset)) {
+			igt_warn("Register 0x%04x (%s): A=%08x B=%08x\n",
+				 offset,
+				 register_name(offset, buf, sizeof(buf)),
+				 a[n], b[n]);
+			num_errors++;
+		}
+	}
+	munmap(b, regs_size);
+	munmap(a, regs_size);
+
+	igt_assert_f(num_errors == 0,
+		     "%d registers mistached between %s.\n",
+		     num_errors, who);
+}
+
+static void isolation(int fd, unsigned int engine, unsigned int flags)
+{
+	static const uint32_t values[] = {
+		0x0,
+		0xffffffff,
+		0xcccccccc,
+		0x33333333,
+		0x55555555,
+		0xaaaaaaaa,
+		0xdeadbeef
+	};
+	unsigned int num_values = flags & DIRTY ? ARRAY_SIZE(values) : 1;
+
+	for (int v = 0; v < num_values; v++) {
+		igt_spin_t *spin = NULL;
+		uint32_t ctx[2];
+		uint32_t regs[2];
+		uint32_t dirty;
+
+		ctx[0] = gem_context_create(fd);
+		regs[0] = read_regs(fd, ctx[0], engine, flags);
+
+		if (flags & DIRTY) {
+			spin = igt_spin_batch_new(fd, ctx[0], engine, 0);
+			write_regs(fd, ctx[0], engine, flags, values[v]);
+		}
+
+		/*
+		 * We create and execute a new context, whilst the HW is
+		 * occupied with the previous context (we should switch from
+		 * the old to the new proto-context without idling, which could
+		 * then load the powercontext). If all goes well, we only see
+		 * the default values from this context, but if goes badly we
+		 * see the corruption from the previous context instead!
+		 */
+		ctx[1] = gem_context_create(fd);
+		regs[1] = read_regs(fd, ctx[1], engine, flags);
+
+		/*
+		 * Restore the original register values before the HW idles.
+		 * Or else it may never restart!
+		 */
+		dirty = read_regs(fd, ctx[0], engine, flags);
+		restore_regs(fd, ctx[0], engine, flags, regs[0]);
+
+		igt_spin_batch_free(fd, spin);
+
+		if (!(flags & DIRTY))
+			compare_regs(fd, regs[0], dirty, "two reads of the same ctx");
+		compare_regs(fd, regs[0], regs[1], "two virgin contexts");
+
+		for (int n = 0; n < ARRAY_SIZE(ctx); n++) {
+			gem_close(fd, regs[n]);
+			gem_context_destroy(fd, ctx[n]);
+		}
+		gem_close(fd, dirty);
+	}
+}
+
+igt_main
+{
+	const unsigned int platform_validation = 0;
+	int fd = -1;
+
+	igt_fixture {
+		int gen;
+
+		fd = drm_open_driver(DRIVER_INTEL);
+		igt_require_gem(fd);
+
+		/* For guaranteed context isolation */
+		igt_require(gem_has_execlists(fd));
+		gem_context_destroy(fd, gem_context_create(fd));
+
+		gen = intel_gen(intel_get_drm_devid(fd));
+		//igt_ci_fail_on(gen > LAST_KNOWN_GEN);
+		igt_skip_on(gen > LAST_KNOWN_GEN);
+	}
+
+	for (const struct intel_execution_engine *e =
+	     intel_execution_engines; e->name; e++) {
+		igt_subtest_group {
+			unsigned int engine = e->exec_id | e->flags;
+			igt_fixture {
+				gem_require_ring(fd, engine);
+			}
+
+			igt_subtest_f("%s-clean", e->name)
+				isolation(fd, engine, 0);
+			igt_subtest_f("%s-dirty", e->name)
+				isolation(fd, engine, DIRTY);
+
+			igt_subtest_f("%s-unsafe", e->name) {
+				igt_require(platform_validation);
+				isolation(fd, engine, DIRTY | UNSAFE);
+			}
+		}
+	}
+}
-- 
2.15.0.rc2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* ✗ Fi.CI.BAT: failure for igt/gem_ctx_isolation: Check isolation of registers between contexts (rev4)
  2017-10-24 11:07 [PATCH igt] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
                   ` (7 preceding siblings ...)
  2017-10-24 20:20 ` [PATCH igt v2] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
@ 2017-10-24 20:45 ` Patchwork
  2017-11-01 22:58 ` [PATCH igt v2] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
  2017-11-02 11:59 ` ✗ Fi.CI.BAT: warning for igt/gem_ctx_isolation: Check isolation of registers between contexts (rev5) Patchwork
  10 siblings, 0 replies; 13+ messages in thread
From: Patchwork @ 2017-10-24 20:45 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: igt/gem_ctx_isolation: Check isolation of registers between contexts (rev4)
URL   : https://patchwork.freedesktop.org/series/32531/
State : failure

== Summary ==

IGT patchset build failed on latest successful build
45a253e34b063426d18cdf02319eb6f6bc238e6b igt/prime_mmap_coherency: Remove manual gem_sync() calls

The Meson build system
Version: 0.40.1
Source dir: /home/cidrm/intel-gpu-tools
Build dir: /home/cidrm/intel-gpu-tools/build
Build type: native build
Project name: IGT gpu tests
Native c compiler: ccache cc (gcc 6.3.0)
Build machine cpu family: x86_64
Build machine cpu: x86_64
Compiler for c supports argument -Wno-unused-parameter: YES
Compiler for c supports argument -Wno-sign-compare: YES
Compiler for c supports argument -Wno-missing-field-initializers: YES
Compiler for c supports argument -Wno-clobbered: YES
Compiler for c supports argument -Wno-type-limits: YES
Compiler for c supports argument -Wimplicit-fallthrough=0: NO
Found pkg-config: /usr/bin/pkg-config (0.29.1)
Native dependency libdrm found: YES 2.4.85
Native dependency libdrm_intel found: YES 2.4.85
Dependency libdrm_vc4 found: NO
Dependency libdrm_nouveau found: NO
Dependency libdrm_amdgpu found: NO
Native dependency pciaccess found: YES 0.13.4
Native dependency libkmod found: YES 22
Native dependency libprocps found: YES 3.3.12
Native dependency cairo found: YES 1.14.8
Native dependency libudev found: YES 232
Native dependency glib-2.0 found: YES 2.52.0
Native dependency libunwind found: YES 1.1
Native dependency gsl found: YES 2.3
Dependency alsa found: NO
Native dependency pixman-1 found: YES 0.34.0
Dependency xmlrpc found: NO
Dependency xmlrpc_util found: NO
Dependency xmlrpc_client found: NO
Program xmlrpc-c-config found: YES (/usr/bin/xmlrpc-c-config)
Dependency threads found: YES
Library m found: YES
Library rt found: YES
Library dl found: YES
Library z found: YES
Has header "linux/kd.h": YES
Has header "sys/kd.h": YES
Has header "libgen.h": YES
Has header "sys/io.h": YES
Has header "cpuid.h": YES
Checking whether type "struct sysinfo" has member "totalram": YES
Configuring config.h using configuration
Program generate_testlist.sh found: YES (/home/cidrm/intel-gpu-tools/tests/generate_testlist.sh)
Program igt_command_line.sh found: YES (/home/cidrm/intel-gpu-tools/tests/igt_command_line.sh)
Configuring intel_aubdump using configuration
Program flex found: YES (/usr/bin/flex)
Program bison found: YES (/usr/bin/bison)
Configuring intel-gen4asm.pc using configuration
Program test/run-test.sh found: YES (/bin/sh /home/cidrm/intel-gpu-tools/assembler/test/run-test.sh)
Native dependency xv found: YES 1.0.11
Native dependency x11 found: YES 1.6.4
Native dependency xext found: YES 1.3.3
Native dependency dri2proto found: YES 2.8
Native dependency cairo-xlib found: YES 1.14.8
Dependency xrandr found: NO
Configuring defs.rst using configuration
Program rst2man found: YES (/usr/bin/rst2man)
Program rst2man.sh found: YES (/home/cidrm/intel-gpu-tools/man/rst2man.sh)
Build targets in project: 369
ninja: Entering directory `build'
[1/743] Compiling c object 'lib/tests/igt_simple_test_subtests@exe/igt_simple_test_subtests.c.o'
[2/743] Compiling c object 'tests/core_auth@exe/core_auth.c.o'
[3/743] Compiling c object 'lib/igt@sha/dummy.c.o'
[4/743] Compiling c object 'lib/tests/igt_simulation@exe/igt_simulation.c.o'
[5/743] Compiling c object 'lib/tests/igt_list_only@exe/igt_list_only.c.o'
[6/743] Compiling c object 'lib/tests/igt_fork_helper@exe/igt_fork_helper.c.o'
[7/743] Compiling c object 'lib/tests/igt_hdmi_inject@exe/igt_hdmi_inject.c.o'
[8/743] Compiling c object 'lib/tests/igt_exit_handler@exe/igt_exit_handler.c.o'
[9/743] Compiling c object 'lib/tests/igt_stats@exe/igt_stats.c.o'
[10/743] Compiling c object 'lib/tests/igt_segfault@exe/igt_segfault.c.o'
[11/743] Compiling c object 'lib/tests/igt_subtest_group@exe/igt_subtest_group.c.o'
[12/743] Compiling c object 'lib/tests/igt_assert@exe/igt_assert.c.o'
[13/743] Compiling c object 'lib/tests/igt_can_fail@exe/igt_can_fail.c.o'
[14/743] Compiling c object 'lib/tests/igt_can_fail_simple@exe/igt_can_fail_simple.c.o'
[15/743] Compiling c object 'lib/tests/igt_no_exit@exe/igt_no_exit.c.o'
[16/743] Compiling c object 'lib/tests/igt_no_exit_list_only@exe/igt_no_exit_list_only.c.o'
[17/743] Compiling c object 'lib/tests/igt_no_subtest@exe/igt_no_subtest.c.o'
[18/743] Compiling c object 'lib/tests/igt_invalid_subtest_name@exe/igt_invalid_subtest_name.c.o'
[19/743] Compiling c object 'lib/tests/igt_timeout@exe/igt_timeout.c.o'
[20/743] Compiling c object 'tests/core_get_client_auth@exe/core_get_client_auth.c.o'
[21/743] Compiling c object 'tests/gem_fenced_exec_thrash@exe/gem_fenced_exec_thrash.c.o'
[22/743] Compiling c object 'tests/gem_fence_upload@exe/gem_fence_upload.c.o'
[23/743] Compiling c object 'tests/core_getversion@exe/core_getversion.c.o'
[24/743] Compiling c object 'tests/core_getstats@exe/core_getstats.c.o'
[25/743] Compiling c object 'tests/core_setmaster_vs_auth@exe/core_setmaster_vs_auth.c.o'
[26/743] Compiling c object 'tests/debugfs_test@exe/debugfs_test.c.o'
[27/743] Compiling c object 'tests/drm_import_export@exe/drm_import_export.c.o'
[28/743] Compiling c object 'tests/drm_mm@exe/drm_mm.c.o'
[29/743] Compiling c object 'tests/drm_vma_limiter_cached@exe/drm_vma_limiter_cached.c.o'
[30/743] Compiling c object 'tests/drm_vma_limiter@exe/drm_vma_limiter.c.o'
[31/743] Compiling c object 'tests/core_getclient@exe/core_getclient.c.o'
[32/743] Compiling c object 'tests/core_prop_blob@exe/core_prop_blob.c.o'
[33/743] Compiling c object 'tests/drm_read@exe/drm_read.c.o'
[34/743] Compiling c object 'tests/drm_vma_limiter_gtt@exe/drm_vma_limiter_gtt.c.o'
[35/743] Compiling c object 'tests/drm_vma_limiter_cpu@exe/drm_vma_limiter_cpu.c.o'
[36/743] Compiling c object 'tests/drv_missed_irq@exe/drv_missed_irq.c.o'
[37/743] Compiling c object 'tests/drv_getparams_basic@exe/drv_getparams_basic.c.o'
[38/743] Compiling c object 'tests/gem_exec_basic@exe/gem_exec_basic.c.o'
[39/743] Compiling c object 'tests/drv_hangman@exe/drv_hangman.c.o'
[40/743] Compiling c object 'tests/drv_module_reload@exe/drv_module_reload.c.o'
[41/743] Compiling c object 'tests/drv_suspend@exe/drv_suspend.c.o'
[42/743] Compiling c object 'tests/drv_selftest@exe/drv_selftest.c.o'
[43/743] Compiling c object 'tests/gem_busy@exe/gem_busy.c.o'
[44/743] Compiling c object 'tests/gem_bad_reloc@exe/gem_bad_reloc.c.o'
[45/743] Compiling c object 'tests/gem_basic@exe/gem_basic.c.o'
[46/743] Compiling c object 'tests/gem_close@exe/gem_close.c.o'
[47/743] Compiling c object 'tests/gem_caching@exe/gem_caching.c.o'
[48/743] Compiling c object 'tests/gem_close_race@exe/gem_close_race.c.o'
[49/743] Compiling c object 'tests/gem_create@exe/gem_create.c.o'
[50/743] Compiling c object 'tests/gem_cpu_reloc@exe/gem_cpu_reloc.c.o'
[51/743] Compiling c object 'tests/gem_concurrent_blit@exe/gem_concurrent_blit.c.o'
[52/743] Compiling c object 'tests/gem_ctx_bad_destroy@exe/gem_ctx_bad_destroy.c.o'
[53/743] Compiling c object 'tests/gem_cs_prefetch@exe/gem_cs_prefetch.c.o'
[54/743] Compiling c object 'tests/gem_cs_tlb@exe/gem_cs_tlb.c.o'
[55/743] Compiling c object 'tests/gem_ctx_basic@exe/gem_ctx_basic.c.o'
[56/743] Compiling c object 'tests/gem_ctx_bad_exec@exe/gem_ctx_bad_exec.c.o'
[57/743] Compiling c object 'tests/gem_ctx_param@exe/gem_ctx_param.c.o'
[58/743] Compiling c object 'tests/gem_ctx_exec@exe/gem_ctx_exec.c.o'
[59/743] Compiling c object 'tests/gem_ctx_create@exe/gem_ctx_create.c.o'
[60/743] Compiling c object 'tests/gem_ctx_switch@exe/gem_ctx_switch.c.o'
[61/743] Compiling c object 'tests/gem_double_irq_loop@exe/gem_double_irq_loop.c.o'
[62/743] Compiling c object 'tests/gem_ctx_thrash@exe/gem_ctx_thrash.c.o'
[63/743] Compiling c object 'tests/gem_evict_alignment@exe/gem_evict_alignment.c.o'
[64/743] Compiling c object 'tests/gem_eio@exe/gem_eio.c.o'
[65/743] Compiling c object 'tests/gem_exec_alignment@exe/gem_exec_alignment.c.o'
[66/743] Compiling c object 'tests/gem_evict_everything@exe/gem_evict_everything.c.o'
[67/743] Compiling c object 'tests/gem_exec_async@exe/gem_exec_async.c.o'
[68/743] Compiling c object 'tests/gem_exec_bad_domains@exe/gem_exec_bad_domains.c.o'
[69/743] Compiling c object 'tests/gem_exec_await@exe/gem_exec_await.c.o'
[70/743] Compiling c object 'tests/gem_exec_big@exe/gem_exec_big.c.o'
[71/743] Compiling c object 'tests/gem_exec_blt@exe/gem_exec_blt.c.o'
[72/743] Compiling c object 'tests/gem_exec_create@exe/gem_exec_create.c.o'
[73/743] Compiling c object 'tests/gem_exec_capture@exe/gem_exec_capture.c.o'
[74/743] Compiling c object 'tests/gem_exec_faulting_reloc@exe/gem_exec_faulting_reloc.c.o'
[75/743] Compiling c object 'tests/gem_exec_flush@exe/gem_exec_flush.c.o'
[76/743] Compiling c object 'tests/gem_exec_fence@exe/gem_exec_fence.c.o'
[77/743] Compiling c object 'tests/gem_exec_gttfill@exe/gem_exec_gttfill.c.o'
[78/743] Compiling c object 'tests/gem_exec_latency@exe/gem_exec_latency.c.o'
[79/743] Compiling c object 'tests/gem_exec_parallel@exe/gem_exec_parallel.c.o'
[80/743] Compiling c object 'tests/gem_exec_nop@exe/gem_exec_nop.c.o'
[81/743] Compiling c object 'tests/gem_exec_lut_handle@exe/gem_exec_lut_handle.c.o'
[82/743] Compiling c object 'tests/gem_exec_parse@exe/gem_exec_parse.c.o'
[83/743] Compiling c object 'tests/gem_exec_params@exe/gem_exec_params.c.o'
[84/743] Compiling c object 'tests/gem_exec_reuse@exe/gem_exec_reuse.c.o'
[85/743] Compiling c object 'tests/gem_exec_reloc@exe/gem_exec_reloc.c.o'
[86/743] Compiling c object 'tests/gem_exec_schedule@exe/gem_exec_schedule.c.o'
[87/743] Compiling c object 'tests/gem_exec_suspend@exe/gem_exec_suspend.c.o'
[88/743] Compiling c object 'tests/gem_exec_store@exe/gem_exec_store.c.o'
[89/743] Compiling c object 'tests/gem_exec_whisper@exe/gem_exec_whisper.c.o'
[90/743] Compiling c object 'tests/gem_fence_thrash@exe/gem_fence_thrash.c.o'
[91/743] Compiling c object 'tests/gem_fd_exhaustion@exe/gem_fd_exhaustion.c.o'
[92/743] Compiling c object 'tests/prime_vgem@exe/prime_vgem.c.o'
[93/743] Compiling c object 'tests/gem_flink_basic@exe/gem_flink_basic.c.o'
[94/743] Compiling c object 'tests/gem_gpgpu_fill@exe/gem_gpgpu_fill.c.o'
[95/743] Compiling c object 'tests/gem_flink_race@exe/gem_flink_race.c.o'
[96/743] Compiling c object 'tests/gem_gtt_cpu_tlb@exe/gem_gtt_cpu_tlb.c.o'
[97/743] Compiling c object 'tests/gem_gtt_hog@exe/gem_gtt_hog.c.o'
[98/743] Compiling c object 'tests/gem_hangcheck_forcewake@exe/gem_hangcheck_forcewake.c.o'
[99/743] Compiling c object 'tests/gem_gtt_speed@exe/gem_gtt_speed.c.o'
[100/743] Compiling c object 'tests/gem_linear_blits@exe/gem_linear_blits.c.o'
[101/743] Compiling c object 'tests/gem_largeobject@exe/gem_largeobject.c.o'
[102/743] Compiling c object 'tests/gem_media_fill@exe/gem_media_fill.c.o'
[103/743] Compiling c object 'tests/gem_madvise@exe/gem_madvise.c.o'
[104/743] Compiling c object 'tests/gem_lut_handle@exe/gem_lut_handle.c.o'
[105/743] Compiling c object 'tests/gem_mmap_gtt@exe/gem_mmap_gtt.c.o'
[106/743] Compiling c object 'tests/gem_mmap@exe/gem_mmap.c.o'
[107/743] Compiling c object 'tests/gem_mmap_offset_exhaustion@exe/gem_mmap_offset_exhaustion.c.o'
[108/743] Compiling c object 'tests/gem_mocs_settings@exe/gem_mocs_settings.c.o'
[109/743] Compiling c object 'tests/gem_mmap_wc@exe/gem_mmap_wc.c.o'
[110/743] Compiling c object 'tests/gem_persistent_relocs@exe/gem_persistent_relocs.c.o'
[111/743] Compiling c object 'tests/gem_partial_pwrite_pread@exe/gem_partial_pwrite_pread.c.o'
[112/743] Compiling c object 'tests/gem_pin@exe/gem_pin.c.o'
[113/743] Compiling c object 'tests/gem_pipe_control_store_loop@exe/gem_pipe_control_store_loop.c.o'
[114/743] Compiling c object 'tests/gem_pread@exe/gem_pread.c.o'
[115/743] Compiling c object 'tests/gem_ppgtt@exe/gem_ppgtt.c.o'
[116/743] Compiling c object 'tests/gem_pread_after_blit@exe/gem_pread_after_blit.c.o'
[117/743] Compiling c object 'tests/gem_pwrite_pread@exe/gem_pwrite_pread.c.o'
[118/743] Compiling c object 'tests/gem_pwrite@exe/gem_pwrite.c.o'
[119/743] Compiling c object 'tests/gem_read_read_speed@exe/gem_read_read_speed.c.o'
[120/743] Compiling c object 'tests/gem_pwrite_snooped@exe/gem_pwrite_snooped.c.o'
[121/743] Compiling c object 'tests/gem_readwrite@exe/gem_readwrite.c.o'
[122/743] Compiling c object 'tests/gem_reloc_overflow@exe/gem_reloc_overflow.c.o'
[123/743] Compiling c object 'tests/gem_reloc_vs_gpu@exe/gem_reloc_vs_gpu.c.o'
[124/743] Compiling c object 'tests/gem_reg_read@exe/gem_reg_read.c.o'
[125/743] Compiling c object 'tests/gem_render_copy_redux@exe/gem_render_copy_redux.c.o'
[126/743] Compiling c object 'tests/gem_render_copy@exe/gem_render_copy.c.o'
[127/743] Compiling c object 'tests/gem_request_retire@exe/gem_request_retire.c.o'
[128/743] Compiling c object 'tests/gem_render_linear_blits@exe/gem_render_linear_blits.c.o'
[129/743] Compiling c object 'tests/gem_render_tiled_blits@exe/gem_render_tiled_blits.c.o'
[130/743] Compiling c object 'tests/gem_reset_stats@exe/gem_reset_stats.c.o'
[131/743] Compiling c object 'tests/gem_ring_sync_copy@exe/gem_ring_sync_copy.c.o'
[132/743] Compiling c object 'tests/gem_ring_sync_loop@exe/gem_ring_sync_loop.c.o'
[133/743] Compiling c object 'tests/gem_ringfill@exe/gem_ringfill.c.o'
[134/743] Compiling c object 'benchmarks/vgem_mmap_bench@exe/vgem_mmap.c.o'
[135/743] Compiling c object 'tests/gem_seqno_wrap@exe/gem_seqno_wrap.c.o'
[136/743] Compiling c object 'tests/gem_set_tiling_vs_pwrite@exe/gem_set_tiling_vs_pwrite.c.o'
[137/743] Compiling c object 'tests/gem_set_tiling_vs_blt@exe/gem_set_tiling_vs_blt.c.o'
[138/743] Compiling c object 'tests/gem_set_tiling_vs_gtt@exe/gem_set_tiling_vs_gtt.c.o'
[139/743] Compiling c object 'tests/gem_shrink@exe/gem_shrink.c.o'
[140/743] Compiling c object 'tests/gem_spin_batch@exe/gem_spin_batch.c.o'
[141/743] Compiling c object 'tests/gem_softpin@exe/gem_softpin.c.o'
[142/743] Compiling c object 'tests/gem_storedw_batches_loop@exe/gem_storedw_batches_loop.c.o'
[143/743] Compiling c object 'tests/gem_stolen@exe/gem_stolen.c.o'
[144/743] Compiling c object 'tests/gem_streaming_writes@exe/gem_streaming_writes.c.o'
[145/743] Compiling c object 'tests/gem_storedw_loop@exe/gem_storedw_loop.c.o'
[146/743] Compiling c object 'tests/gem_sync@exe/gem_sync.c.o'
[147/743] Compiling c object 'tests/gem_threaded_access_tiled@exe/gem_threaded_access_tiled.c.o'
[148/743] Compiling c object 'tests/gem_tiled_blits@exe/gem_tiled_blits.c.o'
[149/743] Compiling c object 'tests/gem_tiled_fence_blits@exe/gem_tiled_fence_blits.c.o'
[150/743] Compiling c object 'tests/gem_tiled_pread_basic@exe/gem_tiled_pread_basic.c.o'
[151/743] Compiling c object 'tests/gem_tiled_partial_pwrite_pread@exe/gem_tiled_partial_pwrite_pread.c.o'
[152/743] Compiling c object 'tests/gem_tiled_swapping@exe/gem_tiled_swapping.c.o'
[153/743] Compiling c object 'tests/gem_tiled_wb@exe/gem_tiled_wb.c.o'
[154/743] Compiling c object 'tests/gem_tiled_pread_pwrite@exe/gem_tiled_pread_pwrite.c.o'
[155/743] Compiling c object 'tests/gem_tiled_wc@exe/gem_tiled_wc.c.o'
[156/743] Compiling c object 'tests/gem_tiling_max_stride@exe/gem_tiling_max_stride.c.o'
[157/743] Compiling c object 'tests/gem_unfence_active_buffers@exe/gem_unfence_active_buffers.c.o'
[158/743] Compiling c object 'tests/gem_unref_active_buffers@exe/gem_unref_active_buffers.c.o'
[159/743] Compiling c object 'tests/gem_userptr_blits@exe/gem_userptr_blits.c.o'
[160/743] Compiling c object 'tests/gem_wait@exe/gem_wait.c.o'
[161/743] Compiling c object 'tests/gem_write_read_ring_switch@exe/gem_write_read_ring_switch.c.o'
[162/743] Compiling c object 'tests/gen3_mixed_blits@exe/gen3_mixed_blits.c.o'
[163/743] Compiling c object 'tests/gem_workarounds@exe/gem_workarounds.c.o'
[164/743] Compiling c object 'tests/gen3_render_linear_blits@exe/gen3_render_linear_blits.c.o'
[165/743] Compiling c object 'tests/gen3_render_mixed_blits@exe/gen3_render_mixed_blits.c.o'
[166/743] Compiling c object 'tests/gen3_render_tiledx_blits@exe/gen3_render_tiledx_blits.c.o'
[167/743] Compiling c object 'tests/gen3_render_tiledy_blits@exe/gen3_render_tiledy_blits.c.o'
[168/743] Compiling c object 'tests/kms_3d@exe/kms_3d.c.o'
[169/743] Compiling c object 'tests/gen7_forcewake_mt@exe/gen7_forcewake_mt.c.o'
[170/743] Compiling c object 'tests/gvt_basic@exe/gvt_basic.c.o'
[171/743] Compiling c object 'tests/kms_addfb_basic@exe/kms_addfb_basic.c.o'
[172/743] Compiling c object 'tests/kms_atomic@exe/kms_atomic.c.o'
[173/743] Compiling c object 'tests/kms_atomic_interruptible@exe/kms_atomic_interruptible.c.o'
[174/743] Compiling c object 'tests/kms_atomic_transition@exe/kms_atomic_transition.c.o'
[175/743] Compiling c object 'tests/kms_busy@exe/kms_busy.c.o'
[176/743] Compiling c object 'tests/kms_chv_cursor_fail@exe/kms_chv_cursor_fail.c.o'
[177/743] Compiling c object 'tests/kms_ccs@exe/kms_ccs.c.o'
[178/743] Compiling c object 'tests/kms_color@exe/kms_color.c.o'
[179/743] Compiling c object 'tests/kms_crtc_background_color@exe/kms_crtc_background_color.c.o'
[180/743] Compiling c object 'tests/kms_concurrent@exe/kms_concurrent.c.o'
[181/743] Compiling c object 'tests/kms_cursor_legacy@exe/kms_cursor_legacy.c.o'
[182/743] Compiling c object 'tests/kms_cursor_crc@exe/kms_cursor_crc.c.o'
[183/743] Compiling c object 'tests/kms_fbcon_fbt@exe/kms_fbcon_fbt.c.o'
[184/743] Compiling c object 'tests/kms_draw_crc@exe/kms_draw_crc.c.o'
[185/743] Compiling c object 'tests/kms_fence_pin_leak@exe/kms_fence_pin_leak.c.o'
[186/743] Compiling c object 'tests/kms_flip@exe/kms_flip.c.o'
[187/743] Compiling c object 'tests/kms_flip_tiling@exe/kms_flip_tiling.c.o'
[188/743] Compiling c object 'tests/kms_flip_event_leak@exe/kms_flip_event_leak.c.o'
[189/743] Compiling c object 'tests/kms_force_connector_basic@exe/kms_force_connector_basic.c.o'
[190/743] Compiling c object 'tests/kms_frontbuffer_tracking@exe/kms_frontbuffer_tracking.c.o'
[191/743] Compiling c object 'tests/kms_hdmi_inject@exe/kms_hdmi_inject.c.o'
[192/743] Compiling c object 'tests/kms_legacy_colorkey@exe/kms_legacy_colorkey.c.o'
[193/743] Compiling c object 'tests/kms_invalid_dotclock@exe/kms_invalid_dotclock.c.o'
[194/743] Compiling c object 'tests/kms_mmio_vs_cs_flip@exe/kms_mmio_vs_cs_flip.c.o'
[195/743] Compiling c object 'tests/kms_mmap_write_crc@exe/kms_mmap_write_crc.c.o'
[196/743] Compiling c object 'tests/kms_pipe_b_c_ivb@exe/kms_pipe_b_c_ivb.c.o'
[197/743] Compiling c object 'tests/kms_panel_fitting@exe/kms_panel_fitting.c.o'
[198/743] Compiling c object 'tests/kms_pipe_crc_basic@exe/kms_pipe_crc_basic.c.o'
[199/743] Compiling c object 'tests/kms_plane@exe/kms_plane.c.o'
[200/743] Compiling c object 'tests/kms_plane_multiple@exe/kms_plane_multiple.c.o'
[201/743] Compiling c object 'tests/kms_plane_scaling@exe/kms_plane_scaling.c.o'
[202/743] Compiling c object 'tests/kms_psr_sink_crc@exe/kms_psr_sink_crc.c.o'
[203/743] Compiling c object 'tests/kms_properties@exe/kms_properties.c.o'
[204/743] Compiling c object 'tests/kms_rmfb@exe/kms_rmfb.c.o'
[205/743] Compiling c object 'tests/kms_render@exe/kms_render.c.o'
[206/743] Compiling c object 'tests/kms_pwrite_crc@exe/kms_pwrite_crc.c.o'
[207/743] Compiling c object 'tests/kms_rotation_crc@exe/kms_rotation_crc.c.o'
[208/743] Compiling c object 'tests/kms_sink_crc_basic@exe/kms_sink_crc_basic.c.o'
[209/743] Compiling c object 'tests/kms_setmode@exe/kms_setmode.c.o'
[210/743] Compiling c object 'tests/kms_sysfs_edid_timing@exe/kms_sysfs_edid_timing.c.o'
[211/743] Compiling c object 'tests/kms_tv_load_detect@exe/kms_tv_load_detect.c.o'
[212/743] Compiling c object 'tests/meta_test@exe/meta_test.c.o'
[213/743] Compiling c object 'tests/kms_universal_plane@exe/kms_universal_plane.c.o'
[214/743] Compiling c object 'tests/kms_vblank@exe/kms_vblank.c.o'
[215/743] Compiling c object 'tests/perf@exe/perf.c.o'
[216/743] Compiling c object 'tests/pm_backlight@exe/pm_backlight.c.o'
[217/743] Compiling c object 'tests/pm_lpsp@exe/pm_lpsp.c.o'
[218/743] Compiling c object 'tests/pm_rpm@exe/pm_rpm.c.o'
[219/743] Compiling c object 'tests/pm_rc6_residency@exe/pm_rc6_residency.c.o'
[220/743] Compiling c object 'tests/pm_rps@exe/pm_rps.c.o'
[221/743] Compil

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH igt v2] igt/gem_ctx_isolation: Check isolation of registers between contexts
  2017-10-24 11:07 [PATCH igt] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
                   ` (8 preceding siblings ...)
  2017-10-24 20:45 ` ✗ Fi.CI.BAT: failure for igt/gem_ctx_isolation: Check isolation of registers between contexts (rev4) Patchwork
@ 2017-11-01 22:58 ` Chris Wilson
  2017-11-02 11:59 ` ✗ Fi.CI.BAT: warning for igt/gem_ctx_isolation: Check isolation of registers between contexts (rev5) Patchwork
  10 siblings, 0 replies; 13+ messages in thread
From: Chris Wilson @ 2017-11-01 22:58 UTC (permalink / raw)
  To: intel-gfx

A new context assumes that all of its registers are in the default state
when it is created. What may happen is that a register written by one
context may leak into the second, causing mass confusion.

v2: extend back to Sandybridge, ignore non-priv registers that are not
context-saved (remind me what this test is all about!!!)

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 tests/Makefile.sources    |   1 +
 tests/gem_ctx_isolation.c | 658 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 659 insertions(+)
 create mode 100644 tests/gem_ctx_isolation.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 2313c12b..9a25a8b5 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -56,6 +56,7 @@ TESTS_progs = \
 	gem_ctx_basic \
 	gem_ctx_create \
 	gem_ctx_exec \
+	gem_ctx_isolation \
 	gem_ctx_param \
 	gem_ctx_switch \
 	gem_ctx_thrash \
diff --git a/tests/gem_ctx_isolation.c b/tests/gem_ctx_isolation.c
new file mode 100644
index 00000000..9c5ec181
--- /dev/null
+++ b/tests/gem_ctx_isolation.c
@@ -0,0 +1,658 @@
+/*
+ * Copyright © 2017 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 "igt.h"
+#include "igt_dummyload.h"
+
+#define MAX_REG 0x40000
+#define NUM_REGS (MAX_REG / sizeof(uint32_t))
+
+#define PAGE_ALIGN(x) ALIGN(x, 4096)
+
+#define DIRTY1 0x1
+#define DIRTY2 0x2
+#define UNSAFE 0x4
+
+enum {
+	RCS_MASK = 0x1,
+	BCS_MASK = 0x2,
+	VCS_MASK = 0x4,
+	VECS_MASK = 0x8,
+};
+
+#define ALL ~0u
+#define GEN_RANGE(x, y) ((ALL >> (32 - (y - x + 1))) << x)
+#define GEN6 (ALL << 6)
+#define GEN7 (ALL << 7)
+#define GEN8 (ALL << 8)
+
+#define NOCTX 0
+
+#define LAST_KNOWN_GEN 10
+
+static const struct named_register {
+	const char *name;
+	unsigned int gen_mask;
+	unsigned int engine_mask;
+	uint32_t offset;
+	uint32_t count;
+} safe_registers[] = {
+	{ "NOPID", NOCTX, RCS_MASK, 0x2094 },
+	{ "MI_PREDICATE_RESULT_2", NOCTX, RCS_MASK, 0x23bc },
+	{ "INSTPM", GEN8, RCS_MASK, 0x20c0 },
+	{ "IA_VERTICES_COUNT", GEN6, RCS_MASK, 0x2310, 2 },
+	{ "IA_PRIMITIVES_COUNT", GEN6, RCS_MASK, 0x2318, 2 },
+	{ "VS_INVOCATION_COUNT", GEN6, RCS_MASK, 0x2320, 2 },
+	{ "HS_INVOCATION_COUNT", GEN6, RCS_MASK, 0x2300, 2 },
+	{ "DS_INVOCATION_COUNT", GEN6, RCS_MASK, 0x2308, 2 },
+	{ "GS_INVOCATION_COUNT", GEN6, RCS_MASK, 0x2328, 2 },
+	{ "GS_PRIMITIVES_COUNT", GEN6, RCS_MASK, 0x2330, 2 },
+	{ "CL_INVOCATION_COUNT", GEN6, RCS_MASK, 0x2338, 2 },
+	{ "CL_PRIMITIVES_COUNT", GEN6, RCS_MASK, 0x2340, 2 },
+	{ "PS_INVOCATION_COUNT_0", GEN6, RCS_MASK, 0x22c8, 2 },
+	{ "PS_DEPTH_COUNT_0", GEN6, RCS_MASK, 0x22d8, 2 },
+	{ "GPUGPU_DISPATCHDIMX", GEN8, RCS_MASK, 0x2500 },
+	{ "GPUGPU_DISPATCHDIMY", GEN8, RCS_MASK, 0x2504 },
+	{ "GPUGPU_DISPATCHDIMZ", GEN8, RCS_MASK, 0x2508 },
+	{ "MI_PREDICATE_SRC0", GEN8, RCS_MASK, 0x2400, 2 },
+	{ "MI_PREDICATE_SRC1", GEN8, RCS_MASK, 0x2408, 2 },
+	{ "MI_PREDICATE_DATA", GEN8, RCS_MASK, 0x2410, 2 },
+	{ "MI_PRED_RESULT", GEN8, RCS_MASK, 0x2418 },
+	{ "3DPRIM_END_OFFSET", GEN6, RCS_MASK, 0x2420 },
+	{ "3DPRIM_START_VERTEX", GEN6, RCS_MASK, 0x2430 },
+	{ "3DPRIM_VERTEX_COUNT", GEN6, RCS_MASK, 0x2434 },
+	{ "3DPRIM_INSTANCE_COUNT", GEN6, RCS_MASK, 0x2438 },
+	{ "3DPRIM_START_INSTANCE", GEN6, RCS_MASK, 0x243c },
+	{ "3DPRIM_BASE_VERTEX", GEN6, RCS_MASK, 0x2440 },
+	{ "GPGPU_THREADS_DISPATCHED", GEN8, RCS_MASK, 0x2290, 2 },
+	{ "PS_INVOCATION_COUNT_1", GEN8, RCS_MASK, 0x22f0, 2 },
+	{ "PS_DEPTH_COUNT_1", GEN8, RCS_MASK, 0x22f8, 2 },
+	{ "BB_OFFSET", GEN8, RCS_MASK, 0x2158 },
+	{ "MI_PREDICATE_RESULT_1", GEN8, RCS_MASK, 0x241c },
+	{ "CS_GPR", GEN8, RCS_MASK, 0x2600, 32 },
+	{ "OA_CTX_CONTROL", GEN8, RCS_MASK, 0x2360 },
+	{ "OACTXID", GEN8, RCS_MASK, 0x2364 },
+	{ "PS_INVOCATION_COUNT_2", GEN8, RCS_MASK, 0x2448, 2 },
+	{ "PS_DEPTH_COUNT_2", GEN8, RCS_MASK, 0x2450, 2 },
+	{ "Cache_Mode_0", GEN7, RCS_MASK, 0x7000 },
+	{ "Cache_Mode_1", GEN7, RCS_MASK, 0x7004 },
+	{ "GT_MODE", GEN8, RCS_MASK, 0x7008 },
+	{ "L3_Config", GEN7, RCS_MASK, 0x7034 },
+	{ "TD_CTL", GEN8, RCS_MASK, 0xe400 },
+	{ "TD_CTL2", GEN8, RCS_MASK, 0xe404 },
+	{ "SO_NUM_PRIMS_WRITEN0", GEN6, RCS_MASK, 0x5200, 2 },
+	{ "SO_NUM_PRIMS_WRITEN1", GEN6, RCS_MASK, 0x5208, 2 },
+	{ "SO_NUM_PRIMS_WRITEN2", GEN6, RCS_MASK, 0x5210, 2 },
+	{ "SO_NUM_PRIMS_WRITEN3", GEN6, RCS_MASK, 0x5218, 2 },
+	{ "SO_PRIM_STORAGE_NEEDED0", GEN6, RCS_MASK, 0x5240, 2 },
+	{ "SO_PRIM_STORAGE_NEEDED1", GEN6, RCS_MASK, 0x5248, 2 },
+	{ "SO_PRIM_STORAGE_NEEDED2", GEN6, RCS_MASK, 0x5250, 2 },
+	{ "SO_PRIM_STORAGE_NEEDED3", GEN6, RCS_MASK, 0x5258, 2 },
+	{ "SO_WRITE_OFFSET0", GEN7, RCS_MASK, 0x5280 },
+	{ "SO_WRITE_OFFSET1", GEN7, RCS_MASK, 0x5284 },
+	{ "SO_WRITE_OFFSET2", GEN7, RCS_MASK, 0x5288 },
+	{ "SO_WRITE_OFFSET3", GEN7, RCS_MASK, 0x528c },
+	{ "OA_CONTROL", NOCTX, RCS_MASK, 0x2b00 },
+	{ "PERF_CNT_1", NOCTX, RCS_MASK, 0x91b8, 2 },
+	{ "PERF_CNT_2", NOCTX, RCS_MASK, 0x91c0, 2 },
+
+	/* Privileged (enabled by w/a + FORCE_TO_NONPRIV) */
+	{ "CTX_PREEMPT", NOCTX /* GEN_RANGE(9, 10) */, RCS_MASK, 0x2248 },
+	{ "CS_CHICKEN1", GEN_RANGE(9, 10), RCS_MASK, 0x2580 },
+	{ "HDC_CHICKEN1", GEN_RANGE(9, 10), RCS_MASK, 0x7304 },
+	{ "L3SQREG1", GEN8, RCS_MASK, 0xb010 },
+
+	{ "BCS_GPR", GEN8, BCS_MASK, 0x22600, 32 },
+	{ "BCS_SWCTRL", GEN8, BCS_MASK, 0x22200 },
+
+	{ "VCS0_GPR", GEN8, VCS_MASK, 0x12600, 32 },
+	{ "MFC_VDBOX1", NOCTX, VCS_MASK, 0x12800, 64 },
+
+	{ "VCS1_GPR", GEN8, VCS_MASK, 0x1c600, 32 },
+	{ "MFC_VDBOX2", NOCTX, VCS_MASK, 0x1c800, 64 },
+
+	{ "VECS_GPR", GEN8, VECS_MASK, 0x1a600, 32 },
+
+	{}
+}, ignore_registers[] = {
+	{ "RCS timestamp", GEN6, RCS_MASK, 0x2358 },
+	{ "VCS0 timestamp", GEN7, VCS_MASK, 0x12358 },
+	{ "VCS1 timestamp", GEN7, VCS_MASK, 0x1c358 },
+	{ "BCS timestamp", GEN7, BCS_MASK, 0x22358 },
+	{ "VECS timestamp", GEN8, VECS_MASK, 0x1a358 },
+	{}
+};
+
+static const char *register_name(uint32_t offset, char *buf, size_t len)
+{
+	for (const struct named_register *r = safe_registers; r->name; r++) {
+		unsigned int width = r->count ? 4*r->count : 4;
+		if (offset >= r->offset && offset < r->offset + width) {
+			if (r->count <= 1)
+				return r->name;
+
+			snprintf(buf, len, "%s[%d]",
+				 r->name, (offset - r->offset)/4);
+			return buf;
+		}
+	}
+
+	return "unknown";
+}
+
+static bool ignore_register(uint32_t offset)
+{
+	for (const struct named_register *r = ignore_registers; r->name; r++) {
+		unsigned int width = r->count ? 4*r->count : 4;
+		if (offset >= r->offset && offset < r->offset + width)
+			return true;
+	}
+
+	return false;
+}
+
+static uint32_t read_regs(int fd,
+			  uint32_t ctx, unsigned int engine,
+			  unsigned int flags)
+{
+	const int gen = intel_gen(intel_get_drm_devid(fd));
+	const bool r64b = gen >= 8;
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_relocation_entry *reloc;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	unsigned int regs_size, batch_size;
+	unsigned int engine_bit, gen_bit;
+	uint32_t *batch, *b;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << gen;
+
+	reloc = calloc(NUM_REGS, sizeof(*reloc));
+	igt_assert(reloc);
+
+	regs_size = NUM_REGS * sizeof(uint32_t);
+	regs_size = PAGE_ALIGN(regs_size);
+
+	batch_size = NUM_REGS * 4 * sizeof(uint32_t) + 4;
+	batch_size = PAGE_ALIGN(batch_size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = gem_create(fd, regs_size);
+	obj[1].handle = gem_create(fd, batch_size);
+	obj[1].relocs_ptr = to_user_pointer(reloc);
+
+	b = batch = gem_mmap__cpu(fd, obj[1].handle, 0, batch_size, PROT_WRITE);
+	gem_set_domain(fd, obj[1].handle,
+		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+
+	if (flags & UNSAFE) {
+		for (unsigned int n = 0; n < NUM_REGS; n++) {
+			*b++ = 0x24 << 23 | (1 + r64b);
+			*b++ = n * sizeof(uint32_t);
+			reloc[n].target_handle = obj[0].handle;
+			reloc[n].presumed_offset = 0;
+			reloc[n].offset = (b - batch) * sizeof(*b);
+			reloc[n].delta = sizeof(uint32_t) * n;
+			reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+			reloc[n].write_domain = I915_GEM_DOMAIN_RENDER;
+			*b++ = reloc[n].delta;
+			if (r64b)
+				*b++ = 0;
+		}
+		obj[1].relocation_count = NUM_REGS;
+	} else {
+		unsigned int n = 0;
+
+		for (const struct named_register *r = safe_registers;
+		     r->name; r++) {
+			if (!(r->engine_mask & engine_bit))
+				continue;
+			if (!(r->gen_mask & gen_bit))
+				continue;
+
+			for (unsigned count = r->count ?: 1, offset = r->offset;
+			     count--; offset += 4) {
+				*b++ = 0x24 << 23 | (1 + r64b); /* SRM */
+				*b++ = offset;
+				reloc[n].target_handle = obj[0].handle;
+				reloc[n].presumed_offset = 0;
+				reloc[n].offset = (b - batch) * sizeof(*b);
+				reloc[n].delta = offset;
+				reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+				reloc[n].write_domain = I915_GEM_DOMAIN_RENDER;
+				*b++ = offset;
+				if (r64b)
+					*b++ = 0;
+				n++;
+			}
+		}
+
+		obj[1].relocation_count = n;
+	}
+	*b++ = MI_BATCH_BUFFER_END;
+	munmap(batch, batch_size);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 2;
+	execbuf.flags = engine;
+	execbuf.rsvd1 = ctx;
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj[1].handle);
+	free(reloc);
+
+	return obj[0].handle;
+}
+
+static void write_regs(int fd,
+		       uint32_t ctx, unsigned int engine,
+		       unsigned int flags,
+		       uint32_t value)
+{
+	const int gen = intel_gen(intel_get_drm_devid(fd));
+	struct drm_i915_gem_exec_object2 obj;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	unsigned int engine_bit, gen_bit;
+	unsigned int batch_size;
+	uint32_t *batch, *b;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << gen;
+
+	batch_size = NUM_REGS * 3 * sizeof(uint32_t) + 4;
+	batch_size = PAGE_ALIGN(batch_size);
+
+	memset(&obj, 0, sizeof(obj));
+	obj.handle = gem_create(fd, batch_size);
+
+	b = batch = gem_mmap__cpu(fd, obj.handle, 0, batch_size, PROT_WRITE);
+	gem_set_domain(fd, obj.handle,
+		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+
+	if (flags & UNSAFE) {
+		for (unsigned int n = 0; n < NUM_REGS; n++) {
+			*b++ = 0x22 << 23 | 1; /* LRI */
+			*b++ = n * sizeof(uint32_t);
+			*b++ = value;
+		}
+	} else {
+		for (const struct named_register *r = safe_registers;
+		     r->name; r++) {
+			if (!(r->engine_mask & engine_bit))
+				continue;
+			if (!(r->gen_mask & gen_bit))
+				continue;
+			for (unsigned count = r->count ?: 1, offset = r->offset;
+			     count--; offset += 4) {
+				*b++ = 0x22 << 23 | 1; /* LRI */
+				*b++ = offset;
+				*b++ = value;
+			}
+		}
+	}
+	*b++ = MI_BATCH_BUFFER_END;
+	munmap(batch, batch_size);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(&obj);
+	execbuf.buffer_count = 1;
+	execbuf.flags = engine;
+	execbuf.rsvd1 = ctx;
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj.handle);
+}
+
+static void restore_regs(int fd,
+			 uint32_t ctx, unsigned int engine,
+			 unsigned int flags,
+			 uint32_t regs)
+{
+	const int gen = intel_gen(intel_get_drm_devid(fd));
+	const bool r64b = gen >= 8;
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_relocation_entry *reloc;
+	unsigned int engine_bit, gen_bit;
+	unsigned int batch_size;
+	uint32_t *batch, *b;
+
+	if (gen < 7) /* no LRM */
+		return;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << gen;
+
+	reloc = calloc(NUM_REGS, sizeof(*reloc));
+	igt_assert(reloc);
+
+	batch_size = NUM_REGS * 3 * sizeof(uint32_t) + 4;
+	batch_size = PAGE_ALIGN(batch_size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = regs;
+	obj[1].handle = gem_create(fd, batch_size);
+	obj[1].relocs_ptr = to_user_pointer(reloc);
+
+	b = batch = gem_mmap__cpu(fd, obj[1].handle, 0, batch_size, PROT_WRITE);
+	gem_set_domain(fd, obj[1].handle,
+		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+
+	if (flags & UNSAFE) {
+		for (unsigned int n = 0; n < NUM_REGS; n++) {
+			*b++ = 0x29 << 23 | (1 + r64b); /* LRM */
+			*b++ = n * sizeof(uint32_t);
+			reloc[n].target_handle = obj[0].handle;
+			reloc[n].presumed_offset = 0;
+			reloc[n].offset = (b - batch) * sizeof(*b);
+			reloc[n].delta = n * sizeof(uint32_t);
+			reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+			reloc[n].write_domain = 0;
+			*b++ = reloc[n].delta;
+			if (r64b)
+				*b++ = 0;
+		}
+
+		obj[1].relocation_count = NUM_REGS;
+	} else {
+		unsigned int n = 0;
+
+		for (const struct named_register *r = safe_registers;
+		     r->name; r++) {
+			if (!(r->engine_mask & engine_bit))
+				continue;
+			if (!(r->gen_mask & gen_bit))
+				continue;
+
+			for (unsigned count = r->count ?: 1, offset = r->offset;
+			     count--; offset += 4) {
+				*b++ = 0x29 << 23 | (1 + r64b); /* LRM */
+				*b++ = offset;
+				reloc[n].target_handle = obj[0].handle;
+				reloc[n].presumed_offset = 0;
+				reloc[n].offset = (b - batch) * sizeof(*b);
+				reloc[n].delta = offset;
+				reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+				reloc[n].write_domain = 0;
+				*b++ = offset;
+				if (gen >= 9)
+					*b++ = 0;
+				n++;
+			}
+		}
+
+		obj[1].relocation_count = n;
+	}
+	*b++ = MI_BATCH_BUFFER_END;
+	munmap(batch, batch_size);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 2;
+	execbuf.flags = engine;
+	execbuf.rsvd1 = ctx;
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj[1].handle);
+}
+
+__attribute__((unused))
+static void dump_regs(int fd, unsigned int engine, unsigned int regs)
+{
+	const int gen = intel_gen(intel_get_drm_devid(fd));
+	unsigned int engine_bit, gen_bit;
+	unsigned int regs_size;
+	uint32_t *out;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << gen;
+
+	regs_size = NUM_REGS * sizeof(uint32_t);
+	regs_size = PAGE_ALIGN(regs_size);
+
+	out = gem_mmap__cpu(fd, regs, 0, regs_size, PROT_READ);
+	gem_set_domain(fd, regs, I915_GEM_DOMAIN_CPU, 0);
+
+	for (const struct named_register *r = safe_registers; r->name; r++) {
+		if (!(r->engine_mask & engine_bit))
+			continue;
+		if (!(r->gen_mask & gen_bit))
+			continue;
+
+		if (r->count <= 1) {
+			igt_debug("0x%04x (%s): 0x%08x\n",
+				  r->offset, r->name, out[r->offset/4]);
+		} else {
+			for (unsigned x = 0; x < r->count; x++)
+				igt_debug("0x%04x (%s[%d]): 0x%08x\n",
+					  r->offset+4*x, r->name, x,
+					  out[r->offset/4 + x]);
+		}
+	}
+	munmap(out, regs_size);
+}
+
+static void compare_regs(int fd, uint32_t A, uint32_t B, const char *who)
+{
+	unsigned int num_errors;
+	unsigned int regs_size;
+	uint32_t *a, *b;
+	char buf[80];
+
+	regs_size = NUM_REGS * sizeof(uint32_t);
+	regs_size = PAGE_ALIGN(regs_size);
+
+	a = gem_mmap__cpu(fd, A, 0, regs_size, PROT_READ);
+	gem_set_domain(fd, A, I915_GEM_DOMAIN_CPU, 0);
+
+	b = gem_mmap__cpu(fd, B, 0, regs_size, PROT_READ);
+	gem_set_domain(fd, B, I915_GEM_DOMAIN_CPU, 0);
+
+	num_errors = 0;
+	for (unsigned int n = 0; n < NUM_REGS; n++) {
+		uint32_t offset = n * sizeof(uint32_t);
+		if (a[n] != b[n] && !ignore_register(offset)) {
+			igt_warn("Register 0x%04x (%s): A=%08x B=%08x\n",
+				 offset,
+				 register_name(offset, buf, sizeof(buf)),
+				 a[n], b[n]);
+			num_errors++;
+		}
+	}
+	munmap(b, regs_size);
+	munmap(a, regs_size);
+
+	igt_assert_f(num_errors == 0,
+		     "%d registers mistached between %s.\n",
+		     num_errors, who);
+}
+
+static void isolation(int fd, unsigned int engine, unsigned int flags)
+{
+	static const uint32_t values[] = {
+		0x0,
+		0xffffffff,
+		0xcccccccc,
+		0x33333333,
+		0x55555555,
+		0xaaaaaaaa,
+		0xdeadbeef
+	};
+	unsigned int num_values =
+		flags & (DIRTY1 | DIRTY2) ? ARRAY_SIZE(values) : 1;
+
+	for (int v = 0; v < num_values; v++) {
+		igt_spin_t *spin = NULL;
+		uint32_t ctx[2], regs[2], tmp;
+
+		ctx[0] = gem_context_create(fd);
+		regs[0] = read_regs(fd, ctx[0], engine, flags);
+
+		spin = igt_spin_batch_new(fd, ctx[0], engine, 0);
+
+		if (flags & DIRTY1) {
+			igt_debug("%s[%d]: Setting all registers of ctx 0 to 0x%08x\n",
+				  __func__, v, values[v]);
+			write_regs(fd, ctx[0], engine, flags, values[v]);
+		}
+
+		/*
+		 * We create and execute a new context, whilst the HW is
+		 * occupied with the previous context (we should switch from
+		 * the old to the new proto-context without idling, which could
+		 * then load the powercontext). If all goes well, we only see
+		 * the default values from this context, but if goes badly we
+		 * see the corruption from the previous context instead!
+		 */
+		ctx[1] = gem_context_create(fd);
+		regs[1] = read_regs(fd, ctx[1], engine, flags);
+
+		if (flags & DIRTY2) {
+			igt_debug("%s[%d]: Setting all registers of ctx 1 to 0x%08x\n",
+				  __func__, v, ~values[v]);
+			write_regs(fd, ctx[1], engine, flags, ~values[v]);
+		}
+
+		/*
+		 * Restore the original register values before the HW idles.
+		 * Or else it may never restart!
+		 */
+		tmp = read_regs(fd, ctx[0], engine, flags);
+		restore_regs(fd, ctx[0], engine, flags, regs[0]);
+
+		igt_spin_batch_free(fd, spin);
+
+		if (!(flags & DIRTY1))
+			compare_regs(fd, regs[0], tmp, "two reads of the same ctx");
+		compare_regs(fd, regs[0], regs[1], "two virgin contexts");
+
+		for (int n = 0; n < ARRAY_SIZE(ctx); n++) {
+			gem_close(fd, regs[n]);
+			gem_context_destroy(fd, ctx[n]);
+		}
+		gem_close(fd, tmp);
+	}
+}
+
+igt_main
+{
+	const unsigned int platform_validation = 0;
+	int fd = -1;
+
+	igt_fixture {
+		int gen;
+
+		fd = drm_open_driver(DRIVER_INTEL);
+		igt_require_gem(fd);
+
+		gem_context_destroy(fd, gem_context_create(fd));
+
+		gen = intel_gen(intel_get_drm_devid(fd));
+		//igt_ci_fail_on(gen > LAST_KNOWN_GEN);
+		igt_skip_on(gen > LAST_KNOWN_GEN);
+	}
+
+	for (const struct intel_execution_engine *e =
+	     intel_execution_engines; e->name; e++) {
+		igt_subtest_group {
+			unsigned int engine = e->exec_id | e->flags;
+			igt_fixture {
+				gem_require_ring(fd, engine);
+			}
+
+			igt_subtest_f("%s-clean", e->name)
+				isolation(fd, engine, 0);
+			igt_subtest_f("%s-dirty-create", e->name)
+				isolation(fd, engine, DIRTY1);
+			igt_subtest_f("%s-dirty-switch", e->name)
+				isolation(fd, engine, DIRTY2);
+
+			igt_subtest_f("%s-unsafe", e->name) {
+				igt_require(platform_validation);
+				isolation(fd, engine, DIRTY2 | DIRTY1 | UNSAFE);
+			}
+		}
+	}
+}
-- 
2.15.0.rc2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* ✗ Fi.CI.BAT: warning for igt/gem_ctx_isolation: Check isolation of registers between contexts (rev5)
  2017-10-24 11:07 [PATCH igt] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
                   ` (9 preceding siblings ...)
  2017-11-01 22:58 ` [PATCH igt v2] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
@ 2017-11-02 11:59 ` Patchwork
  10 siblings, 0 replies; 13+ messages in thread
From: Patchwork @ 2017-11-02 11:59 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: igt/gem_ctx_isolation: Check isolation of registers between contexts (rev5)
URL   : https://patchwork.freedesktop.org/series/32531/
State : warning

== Summary ==

IGT patchset tested on top of latest successful build
7aac0e88606ce453b111ce80419dc58519db05ad assembler: Fix bashism in run-test.sh

with latest DRM-Tip kernel build CI_DRM_3308
dcf7d008f606 drm-tip: 2017y-11m-02d-08h-43m-13s UTC integration manifest

Testlist changes:
+igt@gem_ctx_isolation@blt-clean
+igt@gem_ctx_isolation@blt-dirty-create
+igt@gem_ctx_isolation@blt-dirty-switch
+igt@gem_ctx_isolation@blt-unsafe
+igt@gem_ctx_isolation@bsd1-clean
+igt@gem_ctx_isolation@bsd1-dirty-create
+igt@gem_ctx_isolation@bsd1-dirty-switch
+igt@gem_ctx_isolation@bsd1-unsafe
+igt@gem_ctx_isolation@bsd2-clean
+igt@gem_ctx_isolation@bsd2-dirty-create
+igt@gem_ctx_isolation@bsd2-dirty-switch
+igt@gem_ctx_isolation@bsd2-unsafe
+igt@gem_ctx_isolation@bsd-clean
+igt@gem_ctx_isolation@bsd-dirty-create
+igt@gem_ctx_isolation@bsd-dirty-switch
+igt@gem_ctx_isolation@bsd-unsafe
+igt@gem_ctx_isolation@default-clean
+igt@gem_ctx_isolation@default-dirty-create
+igt@gem_ctx_isolation@default-dirty-switch
+igt@gem_ctx_isolation@default-unsafe
+igt@gem_ctx_isolation@render-clean
+igt@gem_ctx_isolation@render-dirty-create
+igt@gem_ctx_isolation@render-dirty-switch
+igt@gem_ctx_isolation@render-unsafe
+igt@gem_ctx_isolation@vebox-clean
+igt@gem_ctx_isolation@vebox-dirty-create
+igt@gem_ctx_isolation@vebox-dirty-switch
+igt@gem_ctx_isolation@vebox-unsafe

Test gem_exec_flush:
        Subgroup basic-batch-kernel-default-wb:
                pass       -> DMESG-WARN (fi-bsw-n3050)
Test gem_exec_reloc:
        Subgroup basic-cpu-active:
                fail       -> PASS       (fi-gdg-551) fdo#102582 +1
Test kms_force_connector_basic:
        Subgroup prune-stale-modes:
                pass       -> SKIP       (fi-ivb-3770)
Test kms_frontbuffer_tracking:
        Subgroup basic:
                dmesg-warn -> PASS       (fi-bdw-5557u) fdo#102473
Test kms_pipe_crc_basic:
        Subgroup suspend-read-crc-pipe-b:
                dmesg-warn -> PASS       (fi-byt-j1900) fdo#101705

fdo#102582 https://bugs.freedesktop.org/show_bug.cgi?id=102582
fdo#102473 https://bugs.freedesktop.org/show_bug.cgi?id=102473
fdo#101705 https://bugs.freedesktop.org/show_bug.cgi?id=101705

fi-bdw-5557u     total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:446s
fi-bdw-gvtdvm    total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:458s
fi-blb-e6850     total:289  pass:223  dwarn:1   dfail:0   fail:0   skip:65  time:379s
fi-bsw-n3050     total:289  pass:242  dwarn:1   dfail:0   fail:0   skip:46  time:544s
fi-bwr-2160      total:289  pass:183  dwarn:0   dfail:0   fail:0   skip:106 time:277s
fi-bxt-dsi       total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:515s
fi-bxt-j4205     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:512s
fi-byt-j1900     total:289  pass:254  dwarn:0   dfail:0   fail:0   skip:35  time:514s
fi-byt-n2820     total:289  pass:249  dwarn:1   dfail:0   fail:0   skip:39  time:489s
fi-cfl-s         total:289  pass:253  dwarn:4   dfail:0   fail:0   skip:32  time:563s
fi-cnl-y         total:217  pass:196  dwarn:0   dfail:0   fail:0   skip:20 
fi-elk-e7500     total:289  pass:229  dwarn:0   dfail:0   fail:0   skip:60  time:424s
fi-gdg-551       total:289  pass:178  dwarn:1   dfail:0   fail:1   skip:109 time:266s
fi-glk-1         total:289  pass:261  dwarn:0   dfail:0   fail:0   skip:28  time:585s
fi-glk-dsi       total:289  pass:258  dwarn:0   dfail:0   fail:1   skip:30  time:493s
fi-hsw-4770      total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:435s
fi-hsw-4770r     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:431s
fi-ilk-650       total:289  pass:228  dwarn:0   dfail:0   fail:0   skip:61  time:441s
fi-ivb-3520m     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:492s
fi-ivb-3770      total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:487s
fi-kbl-7500u     total:289  pass:264  dwarn:1   dfail:0   fail:0   skip:24  time:494s
fi-kbl-7560u     total:289  pass:270  dwarn:0   dfail:0   fail:0   skip:19  time:571s
fi-kbl-7567u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:479s
fi-kbl-r         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:588s
fi-pnv-d510      total:289  pass:222  dwarn:1   dfail:0   fail:0   skip:66  time:566s
fi-skl-6260u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:458s
fi-skl-6600u     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:596s
fi-skl-6700hq    total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:651s
fi-skl-6700k     total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:527s
fi-skl-6770hq    total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:508s
fi-skl-gvtdvm    total:289  pass:266  dwarn:0   dfail:0   fail:0   skip:23  time:462s
fi-snb-2520m     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:577s
fi-snb-2600      total:289  pass:249  dwarn:0   dfail:0   fail:0   skip:40  time:423s

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_465/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2017-11-02 11:59 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-24 11:07 [PATCH igt] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
2017-10-24 11:16 ` Chris Wilson
2017-10-24 12:52 ` [PATCH v2] drm-auth Chris Wilson
2017-10-24 12:58 ` [PATCH igt v2] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
2017-10-24 13:42 ` ✗ Fi.CI.BAT: failure for drm-auth Patchwork
2017-10-24 14:20 ` [PATCH xf86-video-intel v3] hmm Chris Wilson
2017-10-24 14:22   ` Chris Wilson
2017-10-24 14:21 ` [PATCH igt v3] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
2017-10-24 15:02 ` ✗ Fi.CI.BAT: failure for igt/gem_ctx_isolation: Check isolation of registers between contexts (rev3) Patchwork
2017-10-24 20:20 ` [PATCH igt v2] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
2017-10-24 20:45 ` ✗ Fi.CI.BAT: failure for igt/gem_ctx_isolation: Check isolation of registers between contexts (rev4) Patchwork
2017-11-01 22:58 ` [PATCH igt v2] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
2017-11-02 11:59 ` ✗ Fi.CI.BAT: warning for igt/gem_ctx_isolation: Check isolation of registers between contexts (rev5) Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.