public inbox for igt-dev@lists.freedesktop.org
 help / color / mirror / Atom feed
* [igt-dev] [PATCH i-g-t] Add tests/gem_exec_parse_blt
@ 2019-11-14 14:14 Mika Kuoppala
  0 siblings, 0 replies; 6+ messages in thread
From: Mika Kuoppala @ 2019-11-14 14:14 UTC (permalink / raw)
  To: intel-gfx; +Cc: igt-dev

From: Mika Kuoppala <mika.kuoppala@intel.com>

For testing blitter engine command parser on gen9.

v2: bad jump offset
v3: rebase
v4: improve bb start and subcase it
v5: fix presumed offsets (Jon)
v6: name, remove spurious gem_syncs (Chris)

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 tests/Makefile.sources                |   7 +-
 tests/i915/gem_exec_parse_blt.c       | 972 ++++++++++++++++++++++++++
 tests/intel-ci/fast-feedback.testlist |   1 +
 tests/meson.build                     |   1 +
 4 files changed, 979 insertions(+), 2 deletions(-)
 create mode 100644 tests/i915/gem_exec_parse_blt.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 6b1d4cb2..33a4559d 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -206,8 +206,8 @@ gem_exec_basic_SOURCES = i915/gem_exec_basic.c
 TESTS_progs += gem_exec_big
 gem_exec_big_SOURCES = i915/gem_exec_big.c
 
-TESTS_progs += gem_exec_blt
-gem_exec_blt_SOURCES = i915/gem_exec_blt.c
+TESTS_progs += gem_exec_parse_blt
+gem_exec_blt_SOURCES = i915/gem_exec_parse_blt.c
 
 TESTS_progs += gem_exec_capture
 gem_exec_capture_SOURCES = i915/gem_exec_capture.c
@@ -245,6 +245,9 @@ gem_exec_params_SOURCES = i915/gem_exec_params.c
 TESTS_progs += gem_exec_parse
 gem_exec_parse_SOURCES = i915/gem_exec_parse.c
 
+TESTS_progs += gem_blt_parse
+gem_blt_parse_SOURCES = i915/gem_blt_parse.c
+
 TESTS_progs += gem_exec_reloc
 gem_exec_reloc_SOURCES = i915/gem_exec_reloc.c
 
diff --git a/tests/i915/gem_exec_parse_blt.c b/tests/i915/gem_exec_parse_blt.c
new file mode 100644
index 00000000..c441c6b7
--- /dev/null
+++ b/tests/i915/gem_exec_parse_blt.c
@@ -0,0 +1,972 @@
+/*
+ * Copyright © 2018 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 <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <drm.h>
+
+/* To help craft commands known to be invalid across all engines */
+#define INSTR_CLIENT_SHIFT	29
+#define   INSTR_INVALID_CLIENT  0x7
+
+#define MI_LOAD_REGISTER_REG (0x2a << 23)
+#define MI_STORE_REGISTER_MEM (0x24 << 23)
+#define MI_ARB_ON_OFF (0x8 << 23)
+#define MI_USER_INTERRUPT (0x02 << 23)
+#define MI_FLUSH_DW (0x26 << 23)
+#define MI_ARB_CHECK (0x05 << 23)
+#define MI_REPORT_HEAD (0x07 << 23)
+#define MI_SUSPEND_FLUSH (0x0b << 23)
+#define MI_LOAD_SCAN_LINES_EXCL (0x13 << 23)
+#define MI_UPDATE_GTT (0x23 << 23)
+
+#define BCS_SWCTRL     0x22200
+#define BCS_GPR_BASE   0x22600
+#define BCS_GPR(n)     (0x22600 + (n) * 8)
+#define BCS_GPR_UDW(n) (0x22600 + (n) * 8 + 4)
+
+#define HANDLE_SIZE  4096
+
+static int parser_version;
+
+static int command_parser_version(int fd)
+{
+	int version = -1;
+	drm_i915_getparam_t gp;
+
+	gp.param = I915_PARAM_CMD_PARSER_VERSION;
+	gp.value = &version;
+
+	if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp) == 0)
+		return version;
+
+	return -1;
+}
+
+static int  __exec_batch_patched(int fd, int engine,
+				 uint32_t cmd_bo, const uint32_t *cmds, int size,
+				 uint32_t target_bo, uint64_t target_offset, uint64_t target_delta)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_relocation_entry reloc[1];
+
+	gem_write(fd, cmd_bo, 0, cmds, size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = target_bo;
+	obj[1].handle = cmd_bo;
+
+	memset(reloc, 0, sizeof(reloc));
+	reloc[0].offset = target_offset;
+	reloc[0].target_handle = target_bo;
+	reloc[0].delta = target_delta;
+	reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].write_domain = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].presumed_offset = -1;
+
+	obj[1].relocs_ptr = to_user_pointer(reloc);
+	obj[1].relocation_count = 1;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 2;
+	execbuf.batch_len = size;
+	execbuf.flags = engine;
+
+	return __gem_execbuf(fd, &execbuf);
+}
+
+static void exec_batch_patched(int fd, int engine,
+			       uint32_t cmd_bo, const uint32_t *cmds,
+			       int size, int patch_offset,
+			       long int expected_value)
+{
+	const uint32_t target_bo = gem_create(fd, HANDLE_SIZE);
+	uint64_t actual_value = 0;
+	long int ret;
+
+	ret = __exec_batch_patched(fd, engine, cmd_bo, cmds, size, target_bo, patch_offset, 0);
+	if (ret) {
+		igt_assert_lt(ret, 0);
+		gem_close(fd, target_bo);
+		igt_assert_eq(ret, expected_value);
+		return;
+	}
+
+	gem_read(fd, target_bo, 0, &actual_value, sizeof(actual_value));
+
+	gem_close(fd, target_bo);
+
+	igt_assert_eq(actual_value, expected_value);
+}
+
+static int __exec_batch(int fd, int engine, uint32_t cmd_bo,
+			const uint32_t *cmds, int size)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj[1];
+	int ret;
+
+	gem_write(fd, cmd_bo, 0, cmds, size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = cmd_bo;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 1;
+	execbuf.batch_len = size;
+	execbuf.flags = engine;
+
+	ret =  __gem_execbuf(fd, &execbuf);
+
+	return ret;
+}
+
+#if 0
+static void print_batch(const uint32_t *cmds, const uint32_t sz)
+{
+	const int commands = sz / 4;
+	int i;
+
+	igt_info("Batch size %d\n", sz);
+	for (i = 0; i < commands; i++)
+		igt_info("0x%08x: 0x%08x\n", i, cmds[i]);
+}
+#else
+#define print_batch(cmds, size)
+#endif
+
+#define exec_batch(fd, engine, bo, cmds, sz, expected)	\
+	print_batch(cmds, sz); \
+	igt_assert_eq(__exec_batch(fd, engine, bo, cmds, sz), expected)
+
+static void exec_split_batch(int fd, int engine, const uint32_t *cmds,
+			     int size, int expected_ret)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj[1];
+	uint32_t cmd_bo;
+	const uint32_t noop[1024] = { 0 };
+	const int alloc_size = 4096 * 2;
+	const int actual_start_offset = 4096-sizeof(uint32_t);
+
+	/* Allocate and fill a 2-page batch with noops */
+	cmd_bo = gem_create(fd, alloc_size);
+	gem_write(fd, cmd_bo, 0, noop, sizeof(noop));
+	gem_write(fd, cmd_bo, 4096, noop, sizeof(noop));
+
+	/* Write the provided commands such that the first dword
+	 * of the command buffer is the last dword of the first
+	 * page (i.e. the command is split across the two pages).
+	 */
+	gem_write(fd, cmd_bo, actual_start_offset, cmds, size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = cmd_bo;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 1;
+	/* NB: We want batch_start_offset and batch_len to point to the block
+	 * of the actual commands (i.e. at the last dword of the first page),
+	 * but have to adjust both the start offset and length to meet the
+	 * kernel driver's requirements on the alignment of those fields.
+	 */
+	execbuf.batch_start_offset = actual_start_offset & ~0x7;
+	execbuf.batch_len =
+		ALIGN(size + actual_start_offset - execbuf.batch_start_offset,
+		      0x8);
+	execbuf.flags = engine;
+
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), expected_ret);
+
+	gem_close(fd, cmd_bo);
+}
+
+static void exec_batch_chained(int fd, int engine,
+			       uint32_t cmd_bo, const uint32_t *cmds,
+			       int size, int patch_offset,
+			       uint64_t expected_value,
+			       int expected_return)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj[3];
+	struct drm_i915_gem_relocation_entry reloc[1];
+	struct drm_i915_gem_relocation_entry first_level_reloc;
+
+	const uint32_t target_bo = gem_create(fd, 4096);
+	const uint32_t first_level_bo = gem_create(fd, 4096);
+	uint64_t actual_value = 0;
+	int ret;
+
+	const uint32_t first_level_cmds[] = {
+		MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965 | 1,
+		0,
+		0,
+		MI_BATCH_BUFFER_END,
+	};
+
+	gem_write(fd, first_level_bo, 0,
+		  first_level_cmds, sizeof(first_level_cmds));
+	gem_write(fd, cmd_bo, 0, cmds, size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = target_bo;
+	obj[1].handle = cmd_bo;
+	obj[2].handle = first_level_bo;
+
+	memset(reloc, 0, sizeof(reloc));
+	reloc[0].offset = patch_offset;
+	reloc[0].delta = 0;
+	reloc[0].target_handle = target_bo;
+	reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].write_domain = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].presumed_offset = -1;
+
+	obj[1].relocation_count = 1;
+	obj[1].relocs_ptr = to_user_pointer(&reloc);
+
+	memset(&first_level_reloc, 0, sizeof(first_level_reloc));
+	first_level_reloc.offset = 4;
+	first_level_reloc.delta = 0;
+	first_level_reloc.target_handle = cmd_bo;
+	first_level_reloc.read_domains = I915_GEM_DOMAIN_COMMAND;
+	first_level_reloc.write_domain = 0;
+	obj[2].relocation_count = 1;
+	obj[2].relocs_ptr = to_user_pointer(&first_level_reloc);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 3;
+	execbuf.batch_len = sizeof(first_level_cmds);
+	execbuf.flags = engine;
+
+	ret = __gem_execbuf(fd, &execbuf);
+	if (expected_return && ret == expected_return)
+		goto out;
+
+	gem_read(fd,target_bo, 0, &actual_value, sizeof(actual_value));
+
+out:
+	if (!expected_return)
+		igt_assert_eq(expected_value, actual_value);
+	else
+		igt_assert_neq(expected_value, actual_value);
+
+	gem_close(fd, first_level_bo);
+	gem_close(fd, target_bo);
+}
+
+static void test_secure_batches(const int fd)
+{
+	int v = -1;
+	drm_i915_getparam_t gp;
+
+	gp.param = I915_PARAM_HAS_SECURE_BATCHES;
+	gp.value = &v;
+
+	igt_assert_eq(drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp), 0);
+	igt_assert_eq(v, 0);
+}
+
+struct cmd {
+	uint32_t cmd;
+	int len;
+	const char *name;
+};
+
+#define CMD(C, L) { .cmd = (C), .len = (L), .name = #C }
+#define CMD_N(C) { .cmd = (C), .len = 1, .name = #C }
+
+static const struct cmd allowed_cmds[] = {
+	CMD_N(MI_NOOP),
+	CMD_N(MI_USER_INTERRUPT),
+	CMD_N(MI_WAIT_FOR_EVENT),
+	CMD(MI_FLUSH_DW, 5),
+	CMD_N(MI_ARB_CHECK),
+	CMD_N(MI_REPORT_HEAD),
+	CMD_N(MI_FLUSH),
+	CMD_N(MI_ARB_ON_OFF),
+	CMD_N(MI_SUSPEND_FLUSH),
+	CMD(MI_LOAD_SCAN_LINES_INCL, 2),
+	CMD(MI_LOAD_SCAN_LINES_EXCL, 2),
+};
+
+static uint32_t *inject_cmd(uint32_t *batch, const uint32_t cmd, int len)
+{
+	int i = 0;
+
+	batch[i++] = cmd;
+
+	while (--len)
+		batch[i++] = 0;
+
+	return &batch[i];
+}
+
+static unsigned long batch_num_cmds(const uint32_t * const batch_start,
+				    const uint32_t * const batch_end)
+{
+	igt_assert_lte((unsigned long)batch_start, (unsigned long)batch_end);
+
+	return batch_end - batch_start;
+}
+
+static unsigned long batch_bytes(const uint32_t * const batch_start,
+				 const uint32_t * const batch_end)
+{
+	const unsigned long bytes = batch_num_cmds(batch_start, batch_end) * 4;
+
+	igt_assert(!(bytes & 0x7));
+
+	return bytes;
+}
+
+static void test_allowed_all(const int fd, const uint32_t handle)
+{
+	uint32_t batch[4096];
+	uint32_t *b = &batch[0];
+
+	for (int i = 0; i < ARRAY_SIZE(allowed_cmds); i++)
+		b = inject_cmd(b, allowed_cmds[i].cmd,
+			       allowed_cmds[i].len);
+
+	if (!(batch_num_cmds(batch, b) % 2))
+		b = inject_cmd(b, MI_NOOP, 1);
+
+	b = inject_cmd(b, MI_BATCH_BUFFER_END, 1);
+
+	exec_batch(fd, I915_EXEC_BLT, handle, batch, batch_bytes(batch, b), 0);
+}
+
+static void test_allowed_single(const int fd, const uint32_t handle)
+{
+	uint32_t batch[4096];
+	int ret;
+
+	for (int i = 0; i < ARRAY_SIZE(allowed_cmds); i++) {
+		uint32_t *b = &batch[0];
+
+		b = inject_cmd(b, allowed_cmds[i].cmd,
+			       allowed_cmds[i].len);
+
+		if (!(batch_num_cmds(batch, b) % 2))
+			b = inject_cmd(b, MI_NOOP, 1);
+
+		b = inject_cmd(b, MI_BATCH_BUFFER_END, 1);
+
+		ret = __exec_batch(fd, I915_EXEC_BLT, handle,
+				   batch, batch_bytes(batch, b));
+
+		igt_assert_eq(ret, 0);
+	};
+}
+
+static void test_bb_secure(const int fd, const uint32_t handle)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj[1];
+	struct drm_i915_gem_relocation_entry reloc[1];
+	int ret;
+
+	const uint32_t batch_secure[] = {
+		MI_BATCH_BUFFER_START | 1,
+		12,
+		0,
+		MI_NOOP,
+		MI_NOOP,
+		MI_BATCH_BUFFER_END,
+	};
+
+	gem_write(fd, handle, 0, batch_secure, sizeof(batch_secure));
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = handle;
+
+	memset(reloc, 0, sizeof(reloc));
+	reloc[0].offset = 1 * sizeof(uint32_t);
+	reloc[0].target_handle = handle;
+	reloc[0].delta = 4 * sizeof(uint32_t);
+	reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].write_domain = 0;
+	reloc[0].presumed_offset = -1;
+
+	obj[0].relocs_ptr = to_user_pointer(reloc);
+	obj[0].relocation_count = 1;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 1;
+	execbuf.batch_len = sizeof(batch_secure);
+	execbuf.flags = I915_EXEC_BLT;
+
+	ret = __gem_execbuf(fd, &execbuf);
+
+	igt_assert_eq(ret, -EACCES);
+}
+
+#define BB_START_PARAM 0
+#define BB_START_OUT   1
+#define BB_START_CMD   2
+
+static void test_bb_start(const int fd, const uint32_t handle, int test)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_relocation_entry reloc[3];
+	const uint32_t target_bo = gem_create(fd, 4096);
+	uint32_t *dst;
+	int ret;
+	unsigned int jump_off;
+
+	const uint32_t batch[] = {
+		MI_NOOP,
+		MI_NOOP,
+		MI_NOOP,
+		MI_NOOP,
+		MI_STORE_DWORD_IMM,
+		0,
+		0,
+		1,
+		MI_STORE_DWORD_IMM,
+		4,
+		0,
+		2,
+		MI_COND_BATCH_BUFFER_END | 1,
+		0,
+		0,
+		0,
+		MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965 | 1,
+		0,
+		0,
+		MI_BATCH_BUFFER_END,
+	};
+
+	igt_require(gem_can_store_dword(fd, I915_EXEC_BLT));
+
+	switch (test) {
+	case BB_START_PARAM:
+		jump_off = 5 * sizeof(uint32_t);
+		break;
+	case BB_START_CMD:
+		jump_off = 8 * sizeof(uint32_t);
+		break;
+	default:
+		jump_off = 0xf00d0000;
+	}
+
+	gem_write(fd, handle, 0, batch, sizeof(batch));
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = target_bo;
+	obj[1].handle = handle;
+
+	memset(reloc, 0, sizeof(reloc));
+	reloc[0].offset = 5 * sizeof(uint32_t);
+	reloc[0].target_handle = obj[0].handle;
+	reloc[0].delta = 0;
+	reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].write_domain = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].presumed_offset = -1;
+
+	reloc[1].offset = 9 * sizeof(uint32_t);
+	reloc[1].target_handle = obj[0].handle;
+	reloc[1].delta = 1 * sizeof(uint32_t);
+	reloc[1].read_domains = I915_GEM_DOMAIN_COMMAND;
+	reloc[1].write_domain = I915_GEM_DOMAIN_COMMAND;
+	reloc[1].presumed_offset = -1;
+
+	reloc[2].offset = 17 * sizeof(uint32_t);
+	reloc[2].target_handle = obj[1].handle;
+	reloc[2].delta = jump_off;
+	reloc[2].read_domains = I915_GEM_DOMAIN_COMMAND;
+	reloc[2].write_domain = 0;
+	reloc[2].presumed_offset = -1;
+
+	obj[1].relocs_ptr = to_user_pointer(reloc);
+	obj[1].relocation_count = 3;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 2;
+	execbuf.batch_len = sizeof(batch);
+	execbuf.flags = I915_EXEC_BLT;
+
+	dst = gem_mmap__cpu(fd, obj[0].handle, 0, 4096,
+			    PROT_READ | PROT_WRITE);
+
+	igt_assert_eq(dst[0], 0);
+	igt_assert_eq(dst[1], 0);
+
+	ret = __gem_execbuf(fd, &execbuf);
+
+	switch (test) {
+	case BB_START_PARAM:
+		igt_assert_eq(ret, -EINVAL);
+		break;
+	case BB_START_CMD:
+		igt_assert_eq(ret, 0);
+
+		while (READ_ONCE(dst[0]) == 0)
+		       ;
+
+		while (READ_ONCE(dst[1]) == 0)
+			;
+
+		igt_assert_eq(dst[0], 1);
+		igt_assert_eq(dst[1], 2);
+
+		igt_info("values now %x %x\n", dst[0], dst[1]);
+
+		dst[0] = 0;
+
+		igt_info("values now %x %x\n", dst[0], dst[1]);
+
+		igt_assert_eq(dst[0], 0);
+		igt_assert_eq(dst[1], 2);
+
+		break;
+
+	case BB_START_OUT:
+		igt_assert_eq(ret, -EINVAL);
+		break;
+	}
+
+	gem_munmap(dst, 4096);
+	gem_close(fd, target_bo);
+}
+
+static void test_bb_chained(const int fd, const uint32_t handle)
+{
+	const uint32_t batch[] = {
+		(0x20 << 23) | 2, /* MI_STORE_DATA_IMM */
+		0,
+		0,
+		0xbaadf00d,
+		MI_NOOP,
+		MI_BATCH_BUFFER_END,
+	};
+
+	exec_batch_chained(fd, I915_EXEC_RENDER,
+			   handle,
+			   batch, sizeof(batch),
+			   4,
+			   0xbaadf00d,
+			   0);
+
+	exec_batch_chained(fd, I915_EXEC_BLT,
+			   handle,
+			   batch, sizeof(batch),
+			   4,
+			   0xbaadf00d,
+			   EPERM);
+}
+
+static void test_cmd_crossing_page(const int fd, const uint32_t handle)
+{
+	const uint32_t lri_ok[] = {
+		MI_LOAD_REGISTER_IMM,
+		BCS_GPR(0),
+		0xbaadf00d,
+		MI_BATCH_BUFFER_END,
+	};
+	const uint32_t store_reg[] = {
+		MI_STORE_REGISTER_MEM | (4 - 2),
+		BCS_GPR(0),
+		0, /* reloc */
+		0, /* reloc */
+		MI_NOOP,
+		MI_BATCH_BUFFER_END,
+	};
+
+	exec_split_batch(fd, I915_EXEC_BLT,
+			 lri_ok, sizeof(lri_ok),
+			 0);
+
+	exec_batch_patched(fd, I915_EXEC_BLT, handle,
+			   store_reg, sizeof(store_reg),
+			   2 * sizeof(uint32_t), /* reloc */
+			   0xbaadf00d);
+}
+
+static void test_invalid_length(const int fd, const uint32_t handle)
+{
+	const uint32_t ok_val = 0xbaadf00d;
+	const uint32_t bad_val = 0xf00dbaad;
+	const uint32_t noops[8192] = { 0, };
+
+	const uint32_t lri_ok[] = {
+		MI_LOAD_REGISTER_IMM,
+		BCS_GPR(0),
+		ok_val,
+		MI_BATCH_BUFFER_END,
+	};
+
+	const uint32_t lri_bad[] = {
+		MI_LOAD_REGISTER_IMM,
+		BCS_GPR(0),
+		bad_val,
+		MI_BATCH_BUFFER_END,
+	};
+
+	const uint32_t store_reg[] = {
+		MI_STORE_REGISTER_MEM | (4 - 2),
+		BCS_GPR(0),
+		0, /* reloc */
+		0, /* reloc */
+		MI_NOOP,
+		MI_BATCH_BUFFER_END,
+	};
+
+	exec_batch(fd, I915_EXEC_BLT, handle,
+		   lri_ok, sizeof(lri_ok),
+		   0);
+
+	exec_batch_patched(fd, I915_EXEC_BLT, handle,
+			   store_reg, sizeof(store_reg),
+			   2 * sizeof(uint32_t), /* reloc */
+			   ok_val);
+
+	exec_batch(fd, I915_EXEC_BLT, handle,
+		   lri_bad, 0,
+		   0);
+
+	exec_batch_patched(fd, I915_EXEC_BLT, handle,
+			   store_reg, sizeof(store_reg),
+			   2 * sizeof(uint32_t), /* reloc */
+			   ok_val);
+
+	exec_batch(fd, I915_EXEC_BLT, handle,
+		   lri_ok, 4096,
+		   0);
+
+	igt_assert_eq(__gem_write(fd, handle, 0, noops, 4097), -EINVAL);
+}
+
+struct reg {
+	uint32_t addr;
+	uint32_t mask;
+	bool masked_write;
+	bool privileged;
+};
+
+#define REG_M(ADDR, MASK, WM, P) { (ADDR), (MASK), (WM), (P) }
+#define REG(ADDR) REG_M(ADDR, 0xffffffff, false, false)
+#define REG_P(ADDR) REG_M(ADDR, 0xffffffff, false, true)
+
+static const struct reg regs[] = {
+	REG_M(BCS_SWCTRL, 0x3, true, false),
+	REG(BCS_GPR(0)),
+	REG(BCS_GPR_UDW(0)),
+	REG(BCS_GPR(1)),
+	REG(BCS_GPR_UDW(1)),
+	REG(BCS_GPR(2)),
+	REG(BCS_GPR_UDW(2)),
+	REG(BCS_GPR(3)),
+	REG(BCS_GPR_UDW(3)),
+	REG(BCS_GPR(4)),
+	REG(BCS_GPR_UDW(4)),
+	REG(BCS_GPR(5)),
+	REG(BCS_GPR_UDW(5)),
+	REG(BCS_GPR(6)),
+	REG(BCS_GPR_UDW(6)),
+	REG(BCS_GPR(7)),
+	REG(BCS_GPR_UDW(7)),
+	REG(BCS_GPR(8)),
+	REG(BCS_GPR_UDW(8)),
+	REG(BCS_GPR(9)),
+	REG(BCS_GPR_UDW(9)),
+	REG(BCS_GPR(10)),
+	REG(BCS_GPR_UDW(10)),
+	REG(BCS_GPR(11)),
+	REG(BCS_GPR_UDW(11)),
+	REG(BCS_GPR(12)),
+	REG(BCS_GPR_UDW(12)),
+	REG(BCS_GPR(13)),
+	REG(BCS_GPR_UDW(13)),
+	REG(BCS_GPR(14)),
+	REG(BCS_GPR_UDW(14)),
+	REG(BCS_GPR(15)),
+	REG(BCS_GPR_UDW(15)),
+
+	REG_P(0),
+	REG_P(200000),
+
+	REG_P(BCS_SWCTRL - 1),
+	REG_P(BCS_SWCTRL - 2),
+	REG_P(BCS_SWCTRL - 3),
+	REG_P(BCS_SWCTRL - 4),
+	REG_P(BCS_SWCTRL + 4),
+
+	REG_P(BCS_GPR(0) - 1),
+	REG_P(BCS_GPR(0) - 2),
+	REG_P(BCS_GPR(0) - 3),
+	REG_P(BCS_GPR(0) - 4),
+	REG_P(BCS_GPR_UDW(15) + 4),
+};
+
+static void test_register(const int fd, const uint32_t handle,
+			  const struct reg *r)
+{
+	const uint32_t lri_zero[] = {
+		MI_LOAD_REGISTER_IMM,
+		r->addr,
+		r->masked_write ? 0xffff0000 : 0,
+		MI_BATCH_BUFFER_END,
+	};
+
+	const uint32_t lri_mask[] = {
+		MI_LOAD_REGISTER_IMM,
+		r->addr,
+		r->masked_write ? (r->mask << 16) | r->mask : r->mask,
+		MI_BATCH_BUFFER_END,
+	};
+
+	const uint32_t store_reg[] = {
+		MI_STORE_REGISTER_MEM | (4 - 2),
+		r->addr,
+		0, /* reloc */
+		0, /* reloc */
+		MI_NOOP,
+		MI_BATCH_BUFFER_END,
+	};
+
+	exec_batch(fd, I915_EXEC_BLT, handle,
+		   lri_mask, sizeof(lri_mask),
+		   r->privileged ? -EACCES : 0);
+
+	exec_batch_patched(fd, I915_EXEC_BLT, handle,
+			   store_reg, sizeof(store_reg),
+			   2 * sizeof(uint32_t), /* reloc */
+			   r->privileged ? -EACCES : r->mask);
+
+	exec_batch(fd, I915_EXEC_BLT, handle,
+		   lri_zero, sizeof(lri_zero),
+		   r->privileged ? -EACCES : 0);
+
+	exec_batch_patched(fd, I915_EXEC_BLT, handle,
+			   store_reg, sizeof(store_reg),
+			   2 * sizeof(uint32_t), /* reloc */
+			   r->privileged ? -EACCES : 0);
+}
+
+static void test_valid_registers(const int fd, const uint32_t handle)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(regs); i++)
+		test_register(fd, handle, &regs[i]);
+}
+
+static long int read_reg(const int fd, const uint32_t handle,
+			 const uint32_t addr)
+{
+	const uint32_t store_reg[] = {
+		MI_STORE_REGISTER_MEM | (4 - 2),
+		addr,
+		0, /* reloc */
+		0, /* reloc */
+		MI_NOOP,
+		MI_BATCH_BUFFER_END,
+	};
+	uint32_t target_bo;
+	uint32_t value;
+	long int ret;
+
+	target_bo = gem_create(fd, HANDLE_SIZE);
+
+	ret = __exec_batch_patched(fd, I915_EXEC_BLT, handle,
+				   store_reg, sizeof(store_reg),
+				   target_bo, 2 * sizeof(uint32_t), 0);
+
+	if (ret) {
+		igt_assert_lt(ret, 0);
+		gem_close(fd, target_bo);
+		return ret;
+	}
+
+	gem_read(fd, target_bo, 0, &value, sizeof(value));
+
+	gem_close(fd, target_bo);
+
+	return value;
+}
+
+static int write_reg(const int fd, const uint32_t handle,
+		     const uint32_t addr, const uint32_t val)
+{
+	const uint32_t lri[] = {
+		MI_LOAD_REGISTER_IMM,
+		addr,
+		val,
+		MI_BATCH_BUFFER_END,
+	};
+
+	return __exec_batch(fd, I915_EXEC_BLT, handle,
+			    lri, sizeof(lri));
+}
+
+static void test_unaligned_access(const int fd, const uint32_t handle)
+{
+	const uint32_t addr = BCS_GPR(4);
+	const uint32_t val = 0xbaadfead;
+	const uint32_t pre = 0x12345678;
+	const uint32_t post = 0x87654321;
+
+	igt_assert_eq(write_reg(fd, handle, addr - 4, pre),  0);
+	igt_assert_eq(write_reg(fd, handle, addr, val),      0);
+	igt_assert_eq(write_reg(fd, handle, addr + 4, post), 0);
+
+	igt_assert_eq(read_reg(fd, handle, addr - 4), pre);
+	igt_assert_eq(read_reg(fd, handle, addr),     val);
+	igt_assert_eq(read_reg(fd, handle, addr + 4), post);
+
+	for (int i = 0; i < 4; i++) {
+		igt_assert_eq(write_reg(fd, handle, addr + i, val), 0);
+		igt_assert_eq(read_reg(fd, handle, addr), val);
+
+		igt_assert_eq(read_reg(fd, handle, addr + 1), val);
+		igt_assert_eq(read_reg(fd, handle, addr + 2), val);
+		igt_assert_eq(read_reg(fd, handle, addr + 3), val);
+		igt_assert_eq(read_reg(fd, handle, addr + 4), post);
+		igt_assert_eq(read_reg(fd, handle, addr - 3), pre);
+		igt_assert_eq(read_reg(fd, handle, addr - 2), pre);
+		igt_assert_eq(read_reg(fd, handle, addr - 1), pre);
+	}
+}
+
+igt_main
+{
+	uint32_t handle;
+	int fd;
+
+	igt_fixture {
+		fd = drm_open_driver(DRIVER_INTEL);
+		igt_require_gem(fd);
+		gem_require_blitter(fd);
+
+		parser_version = command_parser_version(fd);
+		/* igt_require(parser_version == 10); */
+
+		igt_require(gem_uses_ppgtt(fd));
+		igt_require(gem_has_blt(fd));
+		igt_require(intel_gen(intel_get_drm_devid(fd)) == 9);
+
+		handle = gem_create(fd, HANDLE_SIZE);
+
+		igt_fork_hang_detector(fd);
+	}
+
+	igt_subtest("secure-batches")
+		test_secure_batches(fd);
+
+	igt_subtest("allowed-all")
+		test_allowed_all(fd, handle);
+
+	igt_subtest("allowed-single")
+		test_allowed_single(fd, handle);
+
+	igt_subtest("bb-start-param")
+		test_bb_start(fd, handle, BB_START_PARAM);
+
+	igt_subtest("bb-start-out")
+		test_bb_start(fd, handle, BB_START_OUT);
+
+	igt_subtest("bb-secure")
+		test_bb_secure(fd, handle);
+
+	igt_subtest("bb-chained")
+		test_bb_chained(fd, handle);
+
+	igt_subtest("cmd-crossing-page")
+		test_cmd_crossing_page(fd, handle);
+
+	igt_subtest("batch-without-end") {
+		const uint32_t noop[1024] = { 0 };
+
+		exec_batch(fd, I915_EXEC_BLT, handle,
+			   noop, sizeof(noop),
+			   -EINVAL);
+	}
+
+	igt_subtest("batch-zero-length") {
+		const uint32_t noop[] = { 0, MI_BATCH_BUFFER_END };
+
+		exec_batch(fd, I915_EXEC_BLT, handle,
+			   noop, 0,
+			   -EINVAL);
+	}
+
+	igt_subtest("batch-invalid-length")
+		test_invalid_length(fd, handle);
+
+	igt_subtest("basic-rejected") {
+		const uint32_t invalid_cmd[] = {
+			INSTR_INVALID_CLIENT << INSTR_CLIENT_SHIFT,
+			MI_BATCH_BUFFER_END,
+		};
+		const uint32_t invalid_set_context[] = {
+			MI_SET_CONTEXT | 32, /* invalid length */
+			MI_BATCH_BUFFER_END,
+		};
+
+		exec_batch(fd, I915_EXEC_BLT, handle,
+			   invalid_cmd, sizeof(invalid_cmd),
+			   -EINVAL);
+
+		exec_batch(fd, I915_EXEC_BLT, handle,
+			   invalid_set_context, sizeof(invalid_set_context),
+			   -EINVAL);
+	}
+
+	igt_subtest("valid-registers")
+		test_valid_registers(fd, handle);
+
+	igt_subtest("unaligned-access")
+		test_unaligned_access(fd, handle);
+
+	igt_subtest_group {
+		igt_hang_t hang;
+
+		igt_fixture igt_allow_hang(fd, 0, 0);
+
+		igt_subtest("bb-start-cmd")
+			test_bb_start(fd, handle, BB_START_CMD);
+
+		igt_fixture igt_disallow_hang(fd, hang);
+	}
+
+	igt_fixture {
+		igt_stop_hang_detector();
+		gem_close(fd, handle);
+
+		close(fd);
+	}
+}
diff --git a/tests/intel-ci/fast-feedback.testlist b/tests/intel-ci/fast-feedback.testlist
index dec6fdda..47bad68c 100644
--- a/tests/intel-ci/fast-feedback.testlist
+++ b/tests/intel-ci/fast-feedback.testlist
@@ -204,3 +204,4 @@ igt@i915_module_load@reload
 igt@i915_module_load@reload-no-display
 igt@i915_module_load@reload-with-fault-injection
 igt@i915_pm_rpm@module-reload
+igt@gem_blt_parse@bb-start #expected hang so last
diff --git a/tests/meson.build b/tests/meson.build
index 44bddd02..755fc9e6 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -149,6 +149,7 @@ i915_progs = [
 	'gem_exec_parallel',
 	'gem_exec_params',
 	'gem_exec_parse',
+	'gem_exec_parse_blt',
 	'gem_exec_reloc',
 	'gem_exec_reuse',
 	'gem_exec_schedule',
-- 
2.17.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* [igt-dev] [PATCH i-g-t] Add tests/gem_exec_parse_blt
@ 2019-11-14 17:18 Mika Kuoppala
  2019-11-14 17:30 ` Mika Kuoppala
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Mika Kuoppala @ 2019-11-14 17:18 UTC (permalink / raw)
  To: intel-gfx; +Cc: igt-dev, Daniel Vetter

From: Mika Kuoppala <mika.kuoppala@intel.com>

For testing blitter engine command parser on gen9.

v2: bad jump offset
v3: rebase
v4: improve bb start and subcase it
v5: fix presumed offsets (Jon)
v6: name, remove spurious gem_syncs (Chris)
v7: jump further backwards (Daniel), ctx_param_engines (Chris)

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 tests/Makefile.sources                |    7 +-
 tests/i915/gem_exec_parse_blt.c       | 1030 +++++++++++++++++++++++++
 tests/intel-ci/fast-feedback.testlist |    1 +
 tests/meson.build                     |    1 +
 4 files changed, 1037 insertions(+), 2 deletions(-)
 create mode 100644 tests/i915/gem_exec_parse_blt.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 6b1d4cb2..33a4559d 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -206,8 +206,8 @@ gem_exec_basic_SOURCES = i915/gem_exec_basic.c
 TESTS_progs += gem_exec_big
 gem_exec_big_SOURCES = i915/gem_exec_big.c
 
-TESTS_progs += gem_exec_blt
-gem_exec_blt_SOURCES = i915/gem_exec_blt.c
+TESTS_progs += gem_exec_parse_blt
+gem_exec_blt_SOURCES = i915/gem_exec_parse_blt.c
 
 TESTS_progs += gem_exec_capture
 gem_exec_capture_SOURCES = i915/gem_exec_capture.c
@@ -245,6 +245,9 @@ gem_exec_params_SOURCES = i915/gem_exec_params.c
 TESTS_progs += gem_exec_parse
 gem_exec_parse_SOURCES = i915/gem_exec_parse.c
 
+TESTS_progs += gem_blt_parse
+gem_blt_parse_SOURCES = i915/gem_blt_parse.c
+
 TESTS_progs += gem_exec_reloc
 gem_exec_reloc_SOURCES = i915/gem_exec_reloc.c
 
diff --git a/tests/i915/gem_exec_parse_blt.c b/tests/i915/gem_exec_parse_blt.c
new file mode 100644
index 00000000..b8b2bb50
--- /dev/null
+++ b/tests/i915/gem_exec_parse_blt.c
@@ -0,0 +1,1030 @@
+/*
+ * Copyright © 2018 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 <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <drm.h>
+
+/* To help craft commands known to be invalid across all engines */
+#define INSTR_CLIENT_SHIFT	29
+#define   INSTR_INVALID_CLIENT  0x7
+
+#define MI_LOAD_REGISTER_REG (0x2a << 23)
+#define MI_STORE_REGISTER_MEM (0x24 << 23)
+#define MI_ARB_ON_OFF (0x8 << 23)
+#define MI_USER_INTERRUPT (0x02 << 23)
+#define MI_FLUSH_DW (0x26 << 23)
+#define MI_ARB_CHECK (0x05 << 23)
+#define MI_REPORT_HEAD (0x07 << 23)
+#define MI_SUSPEND_FLUSH (0x0b << 23)
+#define MI_LOAD_SCAN_LINES_EXCL (0x13 << 23)
+#define MI_UPDATE_GTT (0x23 << 23)
+
+#define BCS_SWCTRL     0x22200
+#define BCS_GPR_BASE   0x22600
+#define BCS_GPR(n)     (0x22600 + (n) * 8)
+#define BCS_GPR_UDW(n) (0x22600 + (n) * 8 + 4)
+
+#define HANDLE_SIZE  4096
+
+static int parser_version;
+
+static int command_parser_version(int fd)
+{
+	int version = -1;
+	drm_i915_getparam_t gp;
+
+	gp.param = I915_PARAM_CMD_PARSER_VERSION;
+	gp.value = &version;
+
+	if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp) == 0)
+		return version;
+
+	return -1;
+}
+
+static int  __exec_batch_patched(int fd, int engine,
+				 uint32_t cmd_bo, const uint32_t *cmds, int size,
+				 uint32_t target_bo, uint64_t target_offset, uint64_t target_delta)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_relocation_entry reloc[1];
+
+	gem_write(fd, cmd_bo, 0, cmds, size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = target_bo;
+	obj[1].handle = cmd_bo;
+
+	memset(reloc, 0, sizeof(reloc));
+	reloc[0].offset = target_offset;
+	reloc[0].target_handle = target_bo;
+	reloc[0].delta = target_delta;
+	reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].write_domain = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].presumed_offset = -1;
+
+	obj[1].relocs_ptr = to_user_pointer(reloc);
+	obj[1].relocation_count = 1;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 2;
+	execbuf.batch_len = size;
+	execbuf.flags = engine;
+
+	return __gem_execbuf(fd, &execbuf);
+}
+
+static void exec_batch_patched(int fd, int engine,
+			       uint32_t cmd_bo, const uint32_t *cmds,
+			       int size, int patch_offset,
+			       long int expected_value)
+{
+	const uint32_t target_bo = gem_create(fd, HANDLE_SIZE);
+	uint64_t actual_value = 0;
+	long int ret;
+
+	ret = __exec_batch_patched(fd, engine, cmd_bo, cmds, size, target_bo, patch_offset, 0);
+	if (ret) {
+		igt_assert_lt(ret, 0);
+		gem_close(fd, target_bo);
+		igt_assert_eq(ret, expected_value);
+		return;
+	}
+
+	gem_read(fd, target_bo, 0, &actual_value, sizeof(actual_value));
+
+	gem_close(fd, target_bo);
+
+	igt_assert_eq(actual_value, expected_value);
+}
+
+static int __exec_batch(int fd, int engine, uint32_t cmd_bo,
+			const uint32_t *cmds, int size)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj[1];
+	int ret;
+
+	gem_write(fd, cmd_bo, 0, cmds, size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = cmd_bo;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 1;
+	execbuf.batch_len = size;
+	execbuf.flags = engine;
+
+	ret =  __gem_execbuf(fd, &execbuf);
+
+	return ret;
+}
+
+#if 0
+static void print_batch(const uint32_t *cmds, const uint32_t sz)
+{
+	const int commands = sz / 4;
+	int i;
+
+	igt_info("Batch size %d\n", sz);
+	for (i = 0; i < commands; i++)
+		igt_info("0x%08x: 0x%08x\n", i, cmds[i]);
+}
+#else
+#define print_batch(cmds, size)
+#endif
+
+#define exec_batch(fd, engine, bo, cmds, sz, expected)	\
+	print_batch(cmds, sz); \
+	igt_assert_eq(__exec_batch(fd, engine, bo, cmds, sz), expected)
+
+static void exec_split_batch(int fd, int engine, const uint32_t *cmds,
+			     int size, int expected_ret)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj[1];
+	uint32_t cmd_bo;
+	const uint32_t noop[1024] = { 0 };
+	const int alloc_size = 4096 * 2;
+	const int actual_start_offset = 4096-sizeof(uint32_t);
+
+	/* Allocate and fill a 2-page batch with noops */
+	cmd_bo = gem_create(fd, alloc_size);
+	gem_write(fd, cmd_bo, 0, noop, sizeof(noop));
+	gem_write(fd, cmd_bo, 4096, noop, sizeof(noop));
+
+	/* Write the provided commands such that the first dword
+	 * of the command buffer is the last dword of the first
+	 * page (i.e. the command is split across the two pages).
+	 */
+	gem_write(fd, cmd_bo, actual_start_offset, cmds, size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = cmd_bo;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 1;
+	/* NB: We want batch_start_offset and batch_len to point to the block
+	 * of the actual commands (i.e. at the last dword of the first page),
+	 * but have to adjust both the start offset and length to meet the
+	 * kernel driver's requirements on the alignment of those fields.
+	 */
+	execbuf.batch_start_offset = actual_start_offset & ~0x7;
+	execbuf.batch_len =
+		ALIGN(size + actual_start_offset - execbuf.batch_start_offset,
+		      0x8);
+	execbuf.flags = engine;
+
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), expected_ret);
+
+	gem_close(fd, cmd_bo);
+}
+
+static void exec_batch_chained(int fd, int engine,
+			       uint32_t cmd_bo, const uint32_t *cmds,
+			       int size, int patch_offset,
+			       uint64_t expected_value,
+			       int expected_return)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj[3];
+	struct drm_i915_gem_relocation_entry reloc[1];
+	struct drm_i915_gem_relocation_entry first_level_reloc;
+
+	const uint32_t target_bo = gem_create(fd, 4096);
+	const uint32_t first_level_bo = gem_create(fd, 4096);
+	uint64_t actual_value = 0;
+	int ret;
+
+	const uint32_t first_level_cmds[] = {
+		MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965 | 1,
+		0,
+		0,
+		MI_BATCH_BUFFER_END,
+	};
+
+	gem_write(fd, first_level_bo, 0,
+		  first_level_cmds, sizeof(first_level_cmds));
+	gem_write(fd, cmd_bo, 0, cmds, size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = target_bo;
+	obj[1].handle = cmd_bo;
+	obj[2].handle = first_level_bo;
+
+	memset(reloc, 0, sizeof(reloc));
+	reloc[0].offset = patch_offset;
+	reloc[0].delta = 0;
+	reloc[0].target_handle = target_bo;
+	reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].write_domain = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].presumed_offset = -1;
+
+	obj[1].relocation_count = 1;
+	obj[1].relocs_ptr = to_user_pointer(&reloc);
+
+	memset(&first_level_reloc, 0, sizeof(first_level_reloc));
+	first_level_reloc.offset = 4;
+	first_level_reloc.delta = 0;
+	first_level_reloc.target_handle = cmd_bo;
+	first_level_reloc.read_domains = I915_GEM_DOMAIN_COMMAND;
+	first_level_reloc.write_domain = 0;
+	obj[2].relocation_count = 1;
+	obj[2].relocs_ptr = to_user_pointer(&first_level_reloc);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 3;
+	execbuf.batch_len = sizeof(first_level_cmds);
+	execbuf.flags = engine;
+
+	ret = __gem_execbuf(fd, &execbuf);
+	if (expected_return && ret == expected_return)
+		goto out;
+
+	gem_read(fd,target_bo, 0, &actual_value, sizeof(actual_value));
+
+out:
+	if (!expected_return)
+		igt_assert_eq(expected_value, actual_value);
+	else
+		igt_assert_neq(expected_value, actual_value);
+
+	gem_close(fd, first_level_bo);
+	gem_close(fd, target_bo);
+}
+
+static void test_secure_batches(const int fd)
+{
+	int v = -1;
+	drm_i915_getparam_t gp;
+
+	gp.param = I915_PARAM_HAS_SECURE_BATCHES;
+	gp.value = &v;
+
+	igt_assert_eq(drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp), 0);
+	igt_assert_eq(v, 0);
+}
+
+struct cmd {
+	uint32_t cmd;
+	int len;
+	const char *name;
+};
+
+#define CMD(C, L) { .cmd = (C), .len = (L), .name = #C }
+#define CMD_N(C) { .cmd = (C), .len = 1, .name = #C }
+
+static const struct cmd allowed_cmds[] = {
+	CMD_N(MI_NOOP),
+	CMD_N(MI_USER_INTERRUPT),
+	CMD_N(MI_WAIT_FOR_EVENT),
+	CMD(MI_FLUSH_DW, 5),
+	CMD_N(MI_ARB_CHECK),
+	CMD_N(MI_REPORT_HEAD),
+	CMD_N(MI_FLUSH),
+	CMD_N(MI_ARB_ON_OFF),
+	CMD_N(MI_SUSPEND_FLUSH),
+	CMD(MI_LOAD_SCAN_LINES_INCL, 2),
+	CMD(MI_LOAD_SCAN_LINES_EXCL, 2),
+};
+
+static uint32_t *inject_cmd(uint32_t *batch, const uint32_t cmd, int len)
+{
+	int i = 0;
+
+	batch[i++] = cmd;
+
+	while (--len)
+		batch[i++] = 0;
+
+	return &batch[i];
+}
+
+static unsigned long batch_num_cmds(const uint32_t * const batch_start,
+				    const uint32_t * const batch_end)
+{
+	igt_assert_lte((unsigned long)batch_start, (unsigned long)batch_end);
+
+	return batch_end - batch_start;
+}
+
+static unsigned long batch_bytes(const uint32_t * const batch_start,
+				 const uint32_t * const batch_end)
+{
+	const unsigned long bytes = batch_num_cmds(batch_start, batch_end) * 4;
+
+	igt_assert(!(bytes & 0x7));
+
+	return bytes;
+}
+
+static void test_allowed_all(const int fd, const uint32_t handle)
+{
+	uint32_t batch[4096];
+	uint32_t *b = &batch[0];
+
+	for (int i = 0; i < ARRAY_SIZE(allowed_cmds); i++)
+		b = inject_cmd(b, allowed_cmds[i].cmd,
+			       allowed_cmds[i].len);
+
+	if (!(batch_num_cmds(batch, b) % 2))
+		b = inject_cmd(b, MI_NOOP, 1);
+
+	b = inject_cmd(b, MI_BATCH_BUFFER_END, 1);
+
+	exec_batch(fd, I915_EXEC_BLT, handle, batch, batch_bytes(batch, b), 0);
+}
+
+static void test_allowed_single(const int fd, const uint32_t handle)
+{
+	uint32_t batch[4096];
+	int ret;
+
+	for (int i = 0; i < ARRAY_SIZE(allowed_cmds); i++) {
+		uint32_t *b = &batch[0];
+
+		b = inject_cmd(b, allowed_cmds[i].cmd,
+			       allowed_cmds[i].len);
+
+		if (!(batch_num_cmds(batch, b) % 2))
+			b = inject_cmd(b, MI_NOOP, 1);
+
+		b = inject_cmd(b, MI_BATCH_BUFFER_END, 1);
+
+		ret = __exec_batch(fd, I915_EXEC_BLT, handle,
+				   batch, batch_bytes(batch, b));
+
+		igt_assert_eq(ret, 0);
+	};
+}
+
+static void test_bb_secure(const int fd, const uint32_t handle)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj[1];
+	struct drm_i915_gem_relocation_entry reloc[1];
+	int ret;
+
+	const uint32_t batch_secure[] = {
+		MI_BATCH_BUFFER_START | 1,
+		12,
+		0,
+		MI_NOOP,
+		MI_NOOP,
+		MI_BATCH_BUFFER_END,
+	};
+
+	gem_write(fd, handle, 0, batch_secure, sizeof(batch_secure));
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = handle;
+
+	memset(reloc, 0, sizeof(reloc));
+	reloc[0].offset = 1 * sizeof(uint32_t);
+	reloc[0].target_handle = handle;
+	reloc[0].delta = 4 * sizeof(uint32_t);
+	reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].write_domain = 0;
+	reloc[0].presumed_offset = -1;
+
+	obj[0].relocs_ptr = to_user_pointer(reloc);
+	obj[0].relocation_count = 1;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 1;
+	execbuf.batch_len = sizeof(batch_secure);
+	execbuf.flags = I915_EXEC_BLT;
+
+	ret = __gem_execbuf(fd, &execbuf);
+
+	igt_assert_eq(ret, -EACCES);
+}
+
+#define BB_START_PARAM 0
+#define BB_START_OUT   1
+#define BB_START_CMD   2
+#define BB_START_FAR   3
+
+static void test_bb_start(const int fd, const uint32_t handle, int test)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_relocation_entry reloc[3];
+	const uint32_t target_bo = gem_create(fd, 4096);
+	uint32_t *dst;
+	int ret;
+	unsigned int jump_off, footer_pos;
+	const uint32_t batch_header[] = {
+		MI_NOOP,
+		MI_NOOP,
+		MI_NOOP,
+		MI_NOOP,
+		MI_STORE_DWORD_IMM,
+		0,
+		0,
+		1,
+		MI_STORE_DWORD_IMM,
+		4,
+		0,
+		2,
+		MI_COND_BATCH_BUFFER_END | 1,
+		0,
+		0,
+		0
+	};
+	const uint32_t batch_footer[] = {
+		MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965 | 1,
+		0,
+		0,
+		MI_BATCH_BUFFER_END,
+	};
+	uint32_t batch[1024];
+
+	igt_require(gem_can_store_dword(fd, I915_EXEC_BLT));
+
+	memset(batch, 0, sizeof(batch));
+	memcpy(batch, batch_header, sizeof(batch_header));
+
+	switch (test) {
+	case BB_START_PARAM:
+		jump_off = 5 * sizeof(uint32_t);
+		break;
+	case BB_START_CMD:
+	case BB_START_FAR:
+		jump_off = 8 * sizeof(uint32_t);
+		break;
+	default:
+		jump_off = 0xf00d0000;
+	}
+
+	if (test == BB_START_FAR)
+		footer_pos = (sizeof(batch) - sizeof(batch_footer));
+	else
+		footer_pos = sizeof(batch_header);
+
+	memcpy(batch + footer_pos / sizeof(uint32_t),
+	       batch_footer, sizeof(batch_footer));
+	gem_write(fd, handle, 0, batch, sizeof(batch));
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = target_bo;
+	obj[1].handle = handle;
+
+	memset(reloc, 0, sizeof(reloc));
+	reloc[0].offset = 5 * sizeof(uint32_t);
+	reloc[0].target_handle = obj[0].handle;
+	reloc[0].delta = 0;
+	reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].write_domain = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].presumed_offset = -1;
+
+	reloc[1].offset = 9 * sizeof(uint32_t);
+	reloc[1].target_handle = obj[0].handle;
+	reloc[1].delta = 1 * sizeof(uint32_t);
+	reloc[1].read_domains = I915_GEM_DOMAIN_COMMAND;
+	reloc[1].write_domain = I915_GEM_DOMAIN_COMMAND;
+	reloc[1].presumed_offset = -1;
+
+	reloc[2].offset = footer_pos + 1 * sizeof(uint32_t);
+	reloc[2].target_handle = obj[1].handle;
+	reloc[2].delta = jump_off;
+	reloc[2].read_domains = I915_GEM_DOMAIN_COMMAND;
+	reloc[2].write_domain = 0;
+	reloc[2].presumed_offset = -1;
+
+	obj[1].relocs_ptr = to_user_pointer(reloc);
+	obj[1].relocation_count = 3;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 2;
+	execbuf.batch_len = sizeof(batch);
+	execbuf.flags = I915_EXEC_BLT;
+
+	dst = gem_mmap__cpu(fd, obj[0].handle, 0, 4096,
+			    PROT_READ | PROT_WRITE);
+
+	igt_assert_eq(dst[0], 0);
+	igt_assert_eq(dst[1], 0);
+
+	ret = __gem_execbuf(fd, &execbuf);
+
+	switch (test) {
+	case BB_START_PARAM:
+		igt_assert_eq(ret, -EINVAL);
+		break;
+	case BB_START_CMD:
+	case BB_START_FAR:
+		igt_assert_eq(ret, 0);
+
+		while (READ_ONCE(dst[0]) == 0)
+		       ;
+
+		while (READ_ONCE(dst[1]) == 0)
+			;
+
+		igt_assert_eq(dst[0], 1);
+		igt_assert_eq(dst[1], 2);
+
+		igt_info("values now %x %x\n", dst[0], dst[1]);
+
+		dst[0] = 0;
+
+		igt_info("values now %x %x\n", dst[0], dst[1]);
+
+		igt_assert_eq(dst[0], 0);
+		igt_assert_eq(dst[1], 2);
+
+		break;
+
+	case BB_START_OUT:
+		igt_assert_eq(ret, -EINVAL);
+		break;
+	}
+
+	gem_munmap(dst, 4096);
+	gem_close(fd, target_bo);
+}
+
+static void test_bb_chained(const int fd, const uint32_t handle)
+{
+	const uint32_t batch[] = {
+		(0x20 << 23) | 2, /* MI_STORE_DATA_IMM */
+		0,
+		0,
+		0xbaadf00d,
+		MI_NOOP,
+		MI_BATCH_BUFFER_END,
+	};
+
+	exec_batch_chained(fd, I915_EXEC_RENDER,
+			   handle,
+			   batch, sizeof(batch),
+			   4,
+			   0xbaadf00d,
+			   0);
+
+	exec_batch_chained(fd, I915_EXEC_BLT,
+			   handle,
+			   batch, sizeof(batch),
+			   4,
+			   0xbaadf00d,
+			   EPERM);
+}
+
+static void test_cmd_crossing_page(const int fd, const uint32_t handle)
+{
+	const uint32_t lri_ok[] = {
+		MI_LOAD_REGISTER_IMM,
+		BCS_GPR(0),
+		0xbaadf00d,
+		MI_BATCH_BUFFER_END,
+	};
+	const uint32_t store_reg[] = {
+		MI_STORE_REGISTER_MEM | (4 - 2),
+		BCS_GPR(0),
+		0, /* reloc */
+		0, /* reloc */
+		MI_NOOP,
+		MI_BATCH_BUFFER_END,
+	};
+
+	exec_split_batch(fd, I915_EXEC_BLT,
+			 lri_ok, sizeof(lri_ok),
+			 0);
+
+	exec_batch_patched(fd, I915_EXEC_BLT, handle,
+			   store_reg, sizeof(store_reg),
+			   2 * sizeof(uint32_t), /* reloc */
+			   0xbaadf00d);
+}
+
+static void test_invalid_length(const int fd, const uint32_t handle)
+{
+	const uint32_t ok_val = 0xbaadf00d;
+	const uint32_t bad_val = 0xf00dbaad;
+	const uint32_t noops[8192] = { 0, };
+
+	const uint32_t lri_ok[] = {
+		MI_LOAD_REGISTER_IMM,
+		BCS_GPR(0),
+		ok_val,
+		MI_BATCH_BUFFER_END,
+	};
+
+	const uint32_t lri_bad[] = {
+		MI_LOAD_REGISTER_IMM,
+		BCS_GPR(0),
+		bad_val,
+		MI_BATCH_BUFFER_END,
+	};
+
+	const uint32_t store_reg[] = {
+		MI_STORE_REGISTER_MEM | (4 - 2),
+		BCS_GPR(0),
+		0, /* reloc */
+		0, /* reloc */
+		MI_NOOP,
+		MI_BATCH_BUFFER_END,
+	};
+
+	exec_batch(fd, I915_EXEC_BLT, handle,
+		   lri_ok, sizeof(lri_ok),
+		   0);
+
+	exec_batch_patched(fd, I915_EXEC_BLT, handle,
+			   store_reg, sizeof(store_reg),
+			   2 * sizeof(uint32_t), /* reloc */
+			   ok_val);
+
+	exec_batch(fd, I915_EXEC_BLT, handle,
+		   lri_bad, 0,
+		   0);
+
+	exec_batch_patched(fd, I915_EXEC_BLT, handle,
+			   store_reg, sizeof(store_reg),
+			   2 * sizeof(uint32_t), /* reloc */
+			   ok_val);
+
+	exec_batch(fd, I915_EXEC_BLT, handle,
+		   lri_ok, 4096,
+		   0);
+
+	igt_assert_eq(__gem_write(fd, handle, 0, noops, 4097), -EINVAL);
+}
+
+struct reg {
+	uint32_t addr;
+	uint32_t mask;
+	bool masked_write;
+	bool privileged;
+};
+
+#define REG_M(ADDR, MASK, WM, P) { (ADDR), (MASK), (WM), (P) }
+#define REG(ADDR) REG_M(ADDR, 0xffffffff, false, false)
+#define REG_P(ADDR) REG_M(ADDR, 0xffffffff, false, true)
+
+static const struct reg regs[] = {
+	REG_M(BCS_SWCTRL, 0x3, true, false),
+	REG(BCS_GPR(0)),
+	REG(BCS_GPR_UDW(0)),
+	REG(BCS_GPR(1)),
+	REG(BCS_GPR_UDW(1)),
+	REG(BCS_GPR(2)),
+	REG(BCS_GPR_UDW(2)),
+	REG(BCS_GPR(3)),
+	REG(BCS_GPR_UDW(3)),
+	REG(BCS_GPR(4)),
+	REG(BCS_GPR_UDW(4)),
+	REG(BCS_GPR(5)),
+	REG(BCS_GPR_UDW(5)),
+	REG(BCS_GPR(6)),
+	REG(BCS_GPR_UDW(6)),
+	REG(BCS_GPR(7)),
+	REG(BCS_GPR_UDW(7)),
+	REG(BCS_GPR(8)),
+	REG(BCS_GPR_UDW(8)),
+	REG(BCS_GPR(9)),
+	REG(BCS_GPR_UDW(9)),
+	REG(BCS_GPR(10)),
+	REG(BCS_GPR_UDW(10)),
+	REG(BCS_GPR(11)),
+	REG(BCS_GPR_UDW(11)),
+	REG(BCS_GPR(12)),
+	REG(BCS_GPR_UDW(12)),
+	REG(BCS_GPR(13)),
+	REG(BCS_GPR_UDW(13)),
+	REG(BCS_GPR(14)),
+	REG(BCS_GPR_UDW(14)),
+	REG(BCS_GPR(15)),
+	REG(BCS_GPR_UDW(15)),
+
+	REG_P(0),
+	REG_P(200000),
+
+	REG_P(BCS_SWCTRL - 1),
+	REG_P(BCS_SWCTRL - 2),
+	REG_P(BCS_SWCTRL - 3),
+	REG_P(BCS_SWCTRL - 4),
+	REG_P(BCS_SWCTRL + 4),
+
+	REG_P(BCS_GPR(0) - 1),
+	REG_P(BCS_GPR(0) - 2),
+	REG_P(BCS_GPR(0) - 3),
+	REG_P(BCS_GPR(0) - 4),
+	REG_P(BCS_GPR_UDW(15) + 4),
+};
+
+static void test_register(const int fd, const uint32_t handle,
+			  const struct reg *r)
+{
+	const uint32_t lri_zero[] = {
+		MI_LOAD_REGISTER_IMM,
+		r->addr,
+		r->masked_write ? 0xffff0000 : 0,
+		MI_BATCH_BUFFER_END,
+	};
+
+	const uint32_t lri_mask[] = {
+		MI_LOAD_REGISTER_IMM,
+		r->addr,
+		r->masked_write ? (r->mask << 16) | r->mask : r->mask,
+		MI_BATCH_BUFFER_END,
+	};
+
+	const uint32_t store_reg[] = {
+		MI_STORE_REGISTER_MEM | (4 - 2),
+		r->addr,
+		0, /* reloc */
+		0, /* reloc */
+		MI_NOOP,
+		MI_BATCH_BUFFER_END,
+	};
+
+	exec_batch(fd, I915_EXEC_BLT, handle,
+		   lri_mask, sizeof(lri_mask),
+		   r->privileged ? -EACCES : 0);
+
+	exec_batch_patched(fd, I915_EXEC_BLT, handle,
+			   store_reg, sizeof(store_reg),
+			   2 * sizeof(uint32_t), /* reloc */
+			   r->privileged ? -EACCES : r->mask);
+
+	exec_batch(fd, I915_EXEC_BLT, handle,
+		   lri_zero, sizeof(lri_zero),
+		   r->privileged ? -EACCES : 0);
+
+	exec_batch_patched(fd, I915_EXEC_BLT, handle,
+			   store_reg, sizeof(store_reg),
+			   2 * sizeof(uint32_t), /* reloc */
+			   r->privileged ? -EACCES : 0);
+}
+
+static void test_valid_registers(const int fd, const uint32_t handle)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(regs); i++)
+		test_register(fd, handle, &regs[i]);
+}
+
+static long int read_reg(const int fd, const uint32_t handle,
+			 const uint32_t addr)
+{
+	const uint32_t store_reg[] = {
+		MI_STORE_REGISTER_MEM | (4 - 2),
+		addr,
+		0, /* reloc */
+		0, /* reloc */
+		MI_NOOP,
+		MI_BATCH_BUFFER_END,
+	};
+	uint32_t target_bo;
+	uint32_t value;
+	long int ret;
+
+	target_bo = gem_create(fd, HANDLE_SIZE);
+
+	ret = __exec_batch_patched(fd, I915_EXEC_BLT, handle,
+				   store_reg, sizeof(store_reg),
+				   target_bo, 2 * sizeof(uint32_t), 0);
+
+	if (ret) {
+		igt_assert_lt(ret, 0);
+		gem_close(fd, target_bo);
+		return ret;
+	}
+
+	gem_read(fd, target_bo, 0, &value, sizeof(value));
+
+	gem_close(fd, target_bo);
+
+	return value;
+}
+
+static int write_reg(const int fd, const uint32_t handle,
+		     const uint32_t addr, const uint32_t val)
+{
+	const uint32_t lri[] = {
+		MI_LOAD_REGISTER_IMM,
+		addr,
+		val,
+		MI_BATCH_BUFFER_END,
+	};
+
+	return __exec_batch(fd, I915_EXEC_BLT, handle,
+			    lri, sizeof(lri));
+}
+
+static void test_unaligned_access(const int fd, const uint32_t handle)
+{
+	const uint32_t addr = BCS_GPR(4);
+	const uint32_t val = 0xbaadfead;
+	const uint32_t pre = 0x12345678;
+	const uint32_t post = 0x87654321;
+
+	igt_assert_eq(write_reg(fd, handle, addr - 4, pre),  0);
+	igt_assert_eq(write_reg(fd, handle, addr, val),      0);
+	igt_assert_eq(write_reg(fd, handle, addr + 4, post), 0);
+
+	igt_assert_eq(read_reg(fd, handle, addr - 4), pre);
+	igt_assert_eq(read_reg(fd, handle, addr),     val);
+	igt_assert_eq(read_reg(fd, handle, addr + 4), post);
+
+	for (int i = 0; i < 4; i++) {
+		igt_assert_eq(write_reg(fd, handle, addr + i, val), 0);
+		igt_assert_eq(read_reg(fd, handle, addr), val);
+
+		igt_assert_eq(read_reg(fd, handle, addr + 1), val);
+		igt_assert_eq(read_reg(fd, handle, addr + 2), val);
+		igt_assert_eq(read_reg(fd, handle, addr + 3), val);
+		igt_assert_eq(read_reg(fd, handle, addr + 4), post);
+		igt_assert_eq(read_reg(fd, handle, addr - 3), pre);
+		igt_assert_eq(read_reg(fd, handle, addr - 2), pre);
+		igt_assert_eq(read_reg(fd, handle, addr - 1), pre);
+	}
+}
+
+static void test_reject_on_engine(int fd, uint32_t handle, unsigned int engine)
+{
+	const uint32_t invalid_cmd[] = {
+		INSTR_INVALID_CLIENT << INSTR_CLIENT_SHIFT,
+		MI_BATCH_BUFFER_END,
+	};
+	const uint32_t invalid_set_context[] = {
+		MI_SET_CONTEXT | 32, /* invalid length */
+		MI_BATCH_BUFFER_END,
+	};
+
+	exec_batch(fd, engine, handle,
+		   invalid_cmd, sizeof(invalid_cmd),
+		   -EINVAL);
+
+	exec_batch(fd, engine, handle,
+		   invalid_set_context, sizeof(invalid_set_context),
+		   -EINVAL);
+}
+
+static void test_rejected(int fd, uint32_t handle, bool ctx_param)
+{
+#define engine_class(e, n) ((e)->engines[(n)].engine_class)
+#define engine_instance(e, n) ((e)->engines[(n)].engine_instance)
+
+	if (ctx_param) {
+		int i;
+
+		I915_DEFINE_CONTEXT_PARAM_ENGINES(engines , I915_EXEC_RING_MASK + 1);
+		struct drm_i915_gem_context_param param = {
+			.ctx_id = 0,
+			.param = I915_CONTEXT_PARAM_ENGINES,
+			.value = to_user_pointer(&engines),
+			.size = sizeof(engines),
+		};
+
+		memset(&engines, 0, sizeof(engines));
+		for (i = 0; i <= I915_EXEC_RING_MASK; i++) {
+			engine_class(&engines, i) = I915_ENGINE_CLASS_COPY;
+			engine_instance(&engines, i) = 0;
+		}
+		gem_context_set_param(fd, &param);
+
+		for (i = 0; i <= I915_EXEC_RING_MASK; i++)
+			test_reject_on_engine(fd, handle, i);
+
+		param.size = 0;
+		gem_context_set_param(fd, &param);
+	} else {
+		test_reject_on_engine(fd, handle, I915_EXEC_BLT);
+	}
+}
+
+igt_main
+{
+	uint32_t handle;
+	int fd;
+
+	igt_fixture {
+		fd = drm_open_driver(DRIVER_INTEL);
+		igt_require_gem(fd);
+		gem_require_blitter(fd);
+
+		parser_version = command_parser_version(fd);
+		/* igt_require(parser_version == 10); */
+
+		igt_require(gem_uses_ppgtt(fd));
+		igt_require(gem_has_blt(fd));
+		igt_require(intel_gen(intel_get_drm_devid(fd)) == 9);
+
+		handle = gem_create(fd, HANDLE_SIZE);
+
+		igt_fork_hang_detector(fd);
+	}
+
+	igt_subtest("secure-batches")
+		test_secure_batches(fd);
+
+	igt_subtest("allowed-all")
+		test_allowed_all(fd, handle);
+
+	igt_subtest("allowed-single")
+		test_allowed_single(fd, handle);
+
+	igt_subtest("bb-start-param")
+		test_bb_start(fd, handle, BB_START_PARAM);
+
+	igt_subtest("bb-start-out")
+		test_bb_start(fd, handle, BB_START_OUT);
+
+	igt_subtest("bb-secure")
+		test_bb_secure(fd, handle);
+
+	igt_subtest("bb-chained")
+		test_bb_chained(fd, handle);
+
+	igt_subtest("cmd-crossing-page")
+		test_cmd_crossing_page(fd, handle);
+
+	igt_subtest("batch-without-end") {
+		const uint32_t noop[1024] = { 0 };
+
+		exec_batch(fd, I915_EXEC_BLT, handle,
+			   noop, sizeof(noop),
+			   -EINVAL);
+	}
+
+	igt_subtest("batch-zero-length") {
+		const uint32_t noop[] = { 0, MI_BATCH_BUFFER_END };
+
+		exec_batch(fd, I915_EXEC_BLT, handle,
+			   noop, 0,
+			   -EINVAL);
+	}
+
+	igt_subtest("batch-invalid-length")
+		test_invalid_length(fd, handle);
+
+	igt_subtest("basic-rejected")
+		test_rejected(fd, handle, false);
+
+	igt_subtest("basic-rejected-ctx-param")
+		test_rejected(fd, handle, true);
+
+	igt_subtest("valid-registers")
+		test_valid_registers(fd, handle);
+
+	igt_subtest("unaligned-access")
+		test_unaligned_access(fd, handle);
+
+	igt_subtest_group {
+		igt_hang_t hang;
+
+		igt_fixture igt_allow_hang(fd, 0, 0);
+
+		igt_subtest("bb-start-cmd")
+			test_bb_start(fd, handle, BB_START_CMD);
+
+		igt_subtest("bb-start-far")
+			test_bb_start(fd, handle, BB_START_FAR);
+
+		igt_fixture igt_disallow_hang(fd, hang);
+	}
+
+	igt_fixture {
+		igt_stop_hang_detector();
+		gem_close(fd, handle);
+
+		close(fd);
+	}
+}
diff --git a/tests/intel-ci/fast-feedback.testlist b/tests/intel-ci/fast-feedback.testlist
index dec6fdda..47bad68c 100644
--- a/tests/intel-ci/fast-feedback.testlist
+++ b/tests/intel-ci/fast-feedback.testlist
@@ -204,3 +204,4 @@ igt@i915_module_load@reload
 igt@i915_module_load@reload-no-display
 igt@i915_module_load@reload-with-fault-injection
 igt@i915_pm_rpm@module-reload
+igt@gem_blt_parse@bb-start #expected hang so last
diff --git a/tests/meson.build b/tests/meson.build
index 44bddd02..755fc9e6 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -149,6 +149,7 @@ i915_progs = [
 	'gem_exec_parallel',
 	'gem_exec_params',
 	'gem_exec_parse',
+	'gem_exec_parse_blt',
 	'gem_exec_reloc',
 	'gem_exec_reuse',
 	'gem_exec_schedule',
-- 
2.17.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* [igt-dev] [PATCH i-g-t] Add tests/gem_exec_parse_blt
  2019-11-14 17:18 [igt-dev] [PATCH i-g-t] Add tests/gem_exec_parse_blt Mika Kuoppala
@ 2019-11-14 17:30 ` Mika Kuoppala
  2019-11-14 18:05 ` [igt-dev] ✗ GitLab.Pipeline: failure for Add tests/gem_exec_parse_blt (rev3) Patchwork
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Mika Kuoppala @ 2019-11-14 17:30 UTC (permalink / raw)
  To: intel-gfx; +Cc: igt-dev, Daniel Vetter

From: Mika Kuoppala <mika.kuoppala@intel.com>

For testing blitter engine command parser on gen9.

v2: bad jump offset
v3: rebase
v4: improve bb start and subcase it
v5: fix presumed offsets (Jon)
v6: name, remove spurious gem_syncs (Chris)
v7: jump further backwards (Daniel), ctx_param_engines (Chris)
v8: dont mess up the Makefiles

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 tests/Makefile.sources          |    3 +
 tests/i915/gem_exec_parse_blt.c | 1030 +++++++++++++++++++++++++++++++
 tests/meson.build               |    1 +
 3 files changed, 1034 insertions(+)
 create mode 100644 tests/i915/gem_exec_parse_blt.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 6b1d4cb2..27801c89 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -245,6 +245,9 @@ gem_exec_params_SOURCES = i915/gem_exec_params.c
 TESTS_progs += gem_exec_parse
 gem_exec_parse_SOURCES = i915/gem_exec_parse.c
 
+TESTS_progs += gem_exec_parse_blt
+gem_exec_parse_blt_SOURCES = i915/gem_exec_parse_blt.c
+
 TESTS_progs += gem_exec_reloc
 gem_exec_reloc_SOURCES = i915/gem_exec_reloc.c
 
diff --git a/tests/i915/gem_exec_parse_blt.c b/tests/i915/gem_exec_parse_blt.c
new file mode 100644
index 00000000..b8b2bb50
--- /dev/null
+++ b/tests/i915/gem_exec_parse_blt.c
@@ -0,0 +1,1030 @@
+/*
+ * Copyright © 2018 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 <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <drm.h>
+
+/* To help craft commands known to be invalid across all engines */
+#define INSTR_CLIENT_SHIFT	29
+#define   INSTR_INVALID_CLIENT  0x7
+
+#define MI_LOAD_REGISTER_REG (0x2a << 23)
+#define MI_STORE_REGISTER_MEM (0x24 << 23)
+#define MI_ARB_ON_OFF (0x8 << 23)
+#define MI_USER_INTERRUPT (0x02 << 23)
+#define MI_FLUSH_DW (0x26 << 23)
+#define MI_ARB_CHECK (0x05 << 23)
+#define MI_REPORT_HEAD (0x07 << 23)
+#define MI_SUSPEND_FLUSH (0x0b << 23)
+#define MI_LOAD_SCAN_LINES_EXCL (0x13 << 23)
+#define MI_UPDATE_GTT (0x23 << 23)
+
+#define BCS_SWCTRL     0x22200
+#define BCS_GPR_BASE   0x22600
+#define BCS_GPR(n)     (0x22600 + (n) * 8)
+#define BCS_GPR_UDW(n) (0x22600 + (n) * 8 + 4)
+
+#define HANDLE_SIZE  4096
+
+static int parser_version;
+
+static int command_parser_version(int fd)
+{
+	int version = -1;
+	drm_i915_getparam_t gp;
+
+	gp.param = I915_PARAM_CMD_PARSER_VERSION;
+	gp.value = &version;
+
+	if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp) == 0)
+		return version;
+
+	return -1;
+}
+
+static int  __exec_batch_patched(int fd, int engine,
+				 uint32_t cmd_bo, const uint32_t *cmds, int size,
+				 uint32_t target_bo, uint64_t target_offset, uint64_t target_delta)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_relocation_entry reloc[1];
+
+	gem_write(fd, cmd_bo, 0, cmds, size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = target_bo;
+	obj[1].handle = cmd_bo;
+
+	memset(reloc, 0, sizeof(reloc));
+	reloc[0].offset = target_offset;
+	reloc[0].target_handle = target_bo;
+	reloc[0].delta = target_delta;
+	reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].write_domain = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].presumed_offset = -1;
+
+	obj[1].relocs_ptr = to_user_pointer(reloc);
+	obj[1].relocation_count = 1;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 2;
+	execbuf.batch_len = size;
+	execbuf.flags = engine;
+
+	return __gem_execbuf(fd, &execbuf);
+}
+
+static void exec_batch_patched(int fd, int engine,
+			       uint32_t cmd_bo, const uint32_t *cmds,
+			       int size, int patch_offset,
+			       long int expected_value)
+{
+	const uint32_t target_bo = gem_create(fd, HANDLE_SIZE);
+	uint64_t actual_value = 0;
+	long int ret;
+
+	ret = __exec_batch_patched(fd, engine, cmd_bo, cmds, size, target_bo, patch_offset, 0);
+	if (ret) {
+		igt_assert_lt(ret, 0);
+		gem_close(fd, target_bo);
+		igt_assert_eq(ret, expected_value);
+		return;
+	}
+
+	gem_read(fd, target_bo, 0, &actual_value, sizeof(actual_value));
+
+	gem_close(fd, target_bo);
+
+	igt_assert_eq(actual_value, expected_value);
+}
+
+static int __exec_batch(int fd, int engine, uint32_t cmd_bo,
+			const uint32_t *cmds, int size)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj[1];
+	int ret;
+
+	gem_write(fd, cmd_bo, 0, cmds, size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = cmd_bo;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 1;
+	execbuf.batch_len = size;
+	execbuf.flags = engine;
+
+	ret =  __gem_execbuf(fd, &execbuf);
+
+	return ret;
+}
+
+#if 0
+static void print_batch(const uint32_t *cmds, const uint32_t sz)
+{
+	const int commands = sz / 4;
+	int i;
+
+	igt_info("Batch size %d\n", sz);
+	for (i = 0; i < commands; i++)
+		igt_info("0x%08x: 0x%08x\n", i, cmds[i]);
+}
+#else
+#define print_batch(cmds, size)
+#endif
+
+#define exec_batch(fd, engine, bo, cmds, sz, expected)	\
+	print_batch(cmds, sz); \
+	igt_assert_eq(__exec_batch(fd, engine, bo, cmds, sz), expected)
+
+static void exec_split_batch(int fd, int engine, const uint32_t *cmds,
+			     int size, int expected_ret)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj[1];
+	uint32_t cmd_bo;
+	const uint32_t noop[1024] = { 0 };
+	const int alloc_size = 4096 * 2;
+	const int actual_start_offset = 4096-sizeof(uint32_t);
+
+	/* Allocate and fill a 2-page batch with noops */
+	cmd_bo = gem_create(fd, alloc_size);
+	gem_write(fd, cmd_bo, 0, noop, sizeof(noop));
+	gem_write(fd, cmd_bo, 4096, noop, sizeof(noop));
+
+	/* Write the provided commands such that the first dword
+	 * of the command buffer is the last dword of the first
+	 * page (i.e. the command is split across the two pages).
+	 */
+	gem_write(fd, cmd_bo, actual_start_offset, cmds, size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = cmd_bo;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 1;
+	/* NB: We want batch_start_offset and batch_len to point to the block
+	 * of the actual commands (i.e. at the last dword of the first page),
+	 * but have to adjust both the start offset and length to meet the
+	 * kernel driver's requirements on the alignment of those fields.
+	 */
+	execbuf.batch_start_offset = actual_start_offset & ~0x7;
+	execbuf.batch_len =
+		ALIGN(size + actual_start_offset - execbuf.batch_start_offset,
+		      0x8);
+	execbuf.flags = engine;
+
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), expected_ret);
+
+	gem_close(fd, cmd_bo);
+}
+
+static void exec_batch_chained(int fd, int engine,
+			       uint32_t cmd_bo, const uint32_t *cmds,
+			       int size, int patch_offset,
+			       uint64_t expected_value,
+			       int expected_return)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj[3];
+	struct drm_i915_gem_relocation_entry reloc[1];
+	struct drm_i915_gem_relocation_entry first_level_reloc;
+
+	const uint32_t target_bo = gem_create(fd, 4096);
+	const uint32_t first_level_bo = gem_create(fd, 4096);
+	uint64_t actual_value = 0;
+	int ret;
+
+	const uint32_t first_level_cmds[] = {
+		MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965 | 1,
+		0,
+		0,
+		MI_BATCH_BUFFER_END,
+	};
+
+	gem_write(fd, first_level_bo, 0,
+		  first_level_cmds, sizeof(first_level_cmds));
+	gem_write(fd, cmd_bo, 0, cmds, size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = target_bo;
+	obj[1].handle = cmd_bo;
+	obj[2].handle = first_level_bo;
+
+	memset(reloc, 0, sizeof(reloc));
+	reloc[0].offset = patch_offset;
+	reloc[0].delta = 0;
+	reloc[0].target_handle = target_bo;
+	reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].write_domain = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].presumed_offset = -1;
+
+	obj[1].relocation_count = 1;
+	obj[1].relocs_ptr = to_user_pointer(&reloc);
+
+	memset(&first_level_reloc, 0, sizeof(first_level_reloc));
+	first_level_reloc.offset = 4;
+	first_level_reloc.delta = 0;
+	first_level_reloc.target_handle = cmd_bo;
+	first_level_reloc.read_domains = I915_GEM_DOMAIN_COMMAND;
+	first_level_reloc.write_domain = 0;
+	obj[2].relocation_count = 1;
+	obj[2].relocs_ptr = to_user_pointer(&first_level_reloc);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 3;
+	execbuf.batch_len = sizeof(first_level_cmds);
+	execbuf.flags = engine;
+
+	ret = __gem_execbuf(fd, &execbuf);
+	if (expected_return && ret == expected_return)
+		goto out;
+
+	gem_read(fd,target_bo, 0, &actual_value, sizeof(actual_value));
+
+out:
+	if (!expected_return)
+		igt_assert_eq(expected_value, actual_value);
+	else
+		igt_assert_neq(expected_value, actual_value);
+
+	gem_close(fd, first_level_bo);
+	gem_close(fd, target_bo);
+}
+
+static void test_secure_batches(const int fd)
+{
+	int v = -1;
+	drm_i915_getparam_t gp;
+
+	gp.param = I915_PARAM_HAS_SECURE_BATCHES;
+	gp.value = &v;
+
+	igt_assert_eq(drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp), 0);
+	igt_assert_eq(v, 0);
+}
+
+struct cmd {
+	uint32_t cmd;
+	int len;
+	const char *name;
+};
+
+#define CMD(C, L) { .cmd = (C), .len = (L), .name = #C }
+#define CMD_N(C) { .cmd = (C), .len = 1, .name = #C }
+
+static const struct cmd allowed_cmds[] = {
+	CMD_N(MI_NOOP),
+	CMD_N(MI_USER_INTERRUPT),
+	CMD_N(MI_WAIT_FOR_EVENT),
+	CMD(MI_FLUSH_DW, 5),
+	CMD_N(MI_ARB_CHECK),
+	CMD_N(MI_REPORT_HEAD),
+	CMD_N(MI_FLUSH),
+	CMD_N(MI_ARB_ON_OFF),
+	CMD_N(MI_SUSPEND_FLUSH),
+	CMD(MI_LOAD_SCAN_LINES_INCL, 2),
+	CMD(MI_LOAD_SCAN_LINES_EXCL, 2),
+};
+
+static uint32_t *inject_cmd(uint32_t *batch, const uint32_t cmd, int len)
+{
+	int i = 0;
+
+	batch[i++] = cmd;
+
+	while (--len)
+		batch[i++] = 0;
+
+	return &batch[i];
+}
+
+static unsigned long batch_num_cmds(const uint32_t * const batch_start,
+				    const uint32_t * const batch_end)
+{
+	igt_assert_lte((unsigned long)batch_start, (unsigned long)batch_end);
+
+	return batch_end - batch_start;
+}
+
+static unsigned long batch_bytes(const uint32_t * const batch_start,
+				 const uint32_t * const batch_end)
+{
+	const unsigned long bytes = batch_num_cmds(batch_start, batch_end) * 4;
+
+	igt_assert(!(bytes & 0x7));
+
+	return bytes;
+}
+
+static void test_allowed_all(const int fd, const uint32_t handle)
+{
+	uint32_t batch[4096];
+	uint32_t *b = &batch[0];
+
+	for (int i = 0; i < ARRAY_SIZE(allowed_cmds); i++)
+		b = inject_cmd(b, allowed_cmds[i].cmd,
+			       allowed_cmds[i].len);
+
+	if (!(batch_num_cmds(batch, b) % 2))
+		b = inject_cmd(b, MI_NOOP, 1);
+
+	b = inject_cmd(b, MI_BATCH_BUFFER_END, 1);
+
+	exec_batch(fd, I915_EXEC_BLT, handle, batch, batch_bytes(batch, b), 0);
+}
+
+static void test_allowed_single(const int fd, const uint32_t handle)
+{
+	uint32_t batch[4096];
+	int ret;
+
+	for (int i = 0; i < ARRAY_SIZE(allowed_cmds); i++) {
+		uint32_t *b = &batch[0];
+
+		b = inject_cmd(b, allowed_cmds[i].cmd,
+			       allowed_cmds[i].len);
+
+		if (!(batch_num_cmds(batch, b) % 2))
+			b = inject_cmd(b, MI_NOOP, 1);
+
+		b = inject_cmd(b, MI_BATCH_BUFFER_END, 1);
+
+		ret = __exec_batch(fd, I915_EXEC_BLT, handle,
+				   batch, batch_bytes(batch, b));
+
+		igt_assert_eq(ret, 0);
+	};
+}
+
+static void test_bb_secure(const int fd, const uint32_t handle)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj[1];
+	struct drm_i915_gem_relocation_entry reloc[1];
+	int ret;
+
+	const uint32_t batch_secure[] = {
+		MI_BATCH_BUFFER_START | 1,
+		12,
+		0,
+		MI_NOOP,
+		MI_NOOP,
+		MI_BATCH_BUFFER_END,
+	};
+
+	gem_write(fd, handle, 0, batch_secure, sizeof(batch_secure));
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = handle;
+
+	memset(reloc, 0, sizeof(reloc));
+	reloc[0].offset = 1 * sizeof(uint32_t);
+	reloc[0].target_handle = handle;
+	reloc[0].delta = 4 * sizeof(uint32_t);
+	reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].write_domain = 0;
+	reloc[0].presumed_offset = -1;
+
+	obj[0].relocs_ptr = to_user_pointer(reloc);
+	obj[0].relocation_count = 1;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 1;
+	execbuf.batch_len = sizeof(batch_secure);
+	execbuf.flags = I915_EXEC_BLT;
+
+	ret = __gem_execbuf(fd, &execbuf);
+
+	igt_assert_eq(ret, -EACCES);
+}
+
+#define BB_START_PARAM 0
+#define BB_START_OUT   1
+#define BB_START_CMD   2
+#define BB_START_FAR   3
+
+static void test_bb_start(const int fd, const uint32_t handle, int test)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_relocation_entry reloc[3];
+	const uint32_t target_bo = gem_create(fd, 4096);
+	uint32_t *dst;
+	int ret;
+	unsigned int jump_off, footer_pos;
+	const uint32_t batch_header[] = {
+		MI_NOOP,
+		MI_NOOP,
+		MI_NOOP,
+		MI_NOOP,
+		MI_STORE_DWORD_IMM,
+		0,
+		0,
+		1,
+		MI_STORE_DWORD_IMM,
+		4,
+		0,
+		2,
+		MI_COND_BATCH_BUFFER_END | 1,
+		0,
+		0,
+		0
+	};
+	const uint32_t batch_footer[] = {
+		MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965 | 1,
+		0,
+		0,
+		MI_BATCH_BUFFER_END,
+	};
+	uint32_t batch[1024];
+
+	igt_require(gem_can_store_dword(fd, I915_EXEC_BLT));
+
+	memset(batch, 0, sizeof(batch));
+	memcpy(batch, batch_header, sizeof(batch_header));
+
+	switch (test) {
+	case BB_START_PARAM:
+		jump_off = 5 * sizeof(uint32_t);
+		break;
+	case BB_START_CMD:
+	case BB_START_FAR:
+		jump_off = 8 * sizeof(uint32_t);
+		break;
+	default:
+		jump_off = 0xf00d0000;
+	}
+
+	if (test == BB_START_FAR)
+		footer_pos = (sizeof(batch) - sizeof(batch_footer));
+	else
+		footer_pos = sizeof(batch_header);
+
+	memcpy(batch + footer_pos / sizeof(uint32_t),
+	       batch_footer, sizeof(batch_footer));
+	gem_write(fd, handle, 0, batch, sizeof(batch));
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = target_bo;
+	obj[1].handle = handle;
+
+	memset(reloc, 0, sizeof(reloc));
+	reloc[0].offset = 5 * sizeof(uint32_t);
+	reloc[0].target_handle = obj[0].handle;
+	reloc[0].delta = 0;
+	reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].write_domain = I915_GEM_DOMAIN_COMMAND;
+	reloc[0].presumed_offset = -1;
+
+	reloc[1].offset = 9 * sizeof(uint32_t);
+	reloc[1].target_handle = obj[0].handle;
+	reloc[1].delta = 1 * sizeof(uint32_t);
+	reloc[1].read_domains = I915_GEM_DOMAIN_COMMAND;
+	reloc[1].write_domain = I915_GEM_DOMAIN_COMMAND;
+	reloc[1].presumed_offset = -1;
+
+	reloc[2].offset = footer_pos + 1 * sizeof(uint32_t);
+	reloc[2].target_handle = obj[1].handle;
+	reloc[2].delta = jump_off;
+	reloc[2].read_domains = I915_GEM_DOMAIN_COMMAND;
+	reloc[2].write_domain = 0;
+	reloc[2].presumed_offset = -1;
+
+	obj[1].relocs_ptr = to_user_pointer(reloc);
+	obj[1].relocation_count = 3;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 2;
+	execbuf.batch_len = sizeof(batch);
+	execbuf.flags = I915_EXEC_BLT;
+
+	dst = gem_mmap__cpu(fd, obj[0].handle, 0, 4096,
+			    PROT_READ | PROT_WRITE);
+
+	igt_assert_eq(dst[0], 0);
+	igt_assert_eq(dst[1], 0);
+
+	ret = __gem_execbuf(fd, &execbuf);
+
+	switch (test) {
+	case BB_START_PARAM:
+		igt_assert_eq(ret, -EINVAL);
+		break;
+	case BB_START_CMD:
+	case BB_START_FAR:
+		igt_assert_eq(ret, 0);
+
+		while (READ_ONCE(dst[0]) == 0)
+		       ;
+
+		while (READ_ONCE(dst[1]) == 0)
+			;
+
+		igt_assert_eq(dst[0], 1);
+		igt_assert_eq(dst[1], 2);
+
+		igt_info("values now %x %x\n", dst[0], dst[1]);
+
+		dst[0] = 0;
+
+		igt_info("values now %x %x\n", dst[0], dst[1]);
+
+		igt_assert_eq(dst[0], 0);
+		igt_assert_eq(dst[1], 2);
+
+		break;
+
+	case BB_START_OUT:
+		igt_assert_eq(ret, -EINVAL);
+		break;
+	}
+
+	gem_munmap(dst, 4096);
+	gem_close(fd, target_bo);
+}
+
+static void test_bb_chained(const int fd, const uint32_t handle)
+{
+	const uint32_t batch[] = {
+		(0x20 << 23) | 2, /* MI_STORE_DATA_IMM */
+		0,
+		0,
+		0xbaadf00d,
+		MI_NOOP,
+		MI_BATCH_BUFFER_END,
+	};
+
+	exec_batch_chained(fd, I915_EXEC_RENDER,
+			   handle,
+			   batch, sizeof(batch),
+			   4,
+			   0xbaadf00d,
+			   0);
+
+	exec_batch_chained(fd, I915_EXEC_BLT,
+			   handle,
+			   batch, sizeof(batch),
+			   4,
+			   0xbaadf00d,
+			   EPERM);
+}
+
+static void test_cmd_crossing_page(const int fd, const uint32_t handle)
+{
+	const uint32_t lri_ok[] = {
+		MI_LOAD_REGISTER_IMM,
+		BCS_GPR(0),
+		0xbaadf00d,
+		MI_BATCH_BUFFER_END,
+	};
+	const uint32_t store_reg[] = {
+		MI_STORE_REGISTER_MEM | (4 - 2),
+		BCS_GPR(0),
+		0, /* reloc */
+		0, /* reloc */
+		MI_NOOP,
+		MI_BATCH_BUFFER_END,
+	};
+
+	exec_split_batch(fd, I915_EXEC_BLT,
+			 lri_ok, sizeof(lri_ok),
+			 0);
+
+	exec_batch_patched(fd, I915_EXEC_BLT, handle,
+			   store_reg, sizeof(store_reg),
+			   2 * sizeof(uint32_t), /* reloc */
+			   0xbaadf00d);
+}
+
+static void test_invalid_length(const int fd, const uint32_t handle)
+{
+	const uint32_t ok_val = 0xbaadf00d;
+	const uint32_t bad_val = 0xf00dbaad;
+	const uint32_t noops[8192] = { 0, };
+
+	const uint32_t lri_ok[] = {
+		MI_LOAD_REGISTER_IMM,
+		BCS_GPR(0),
+		ok_val,
+		MI_BATCH_BUFFER_END,
+	};
+
+	const uint32_t lri_bad[] = {
+		MI_LOAD_REGISTER_IMM,
+		BCS_GPR(0),
+		bad_val,
+		MI_BATCH_BUFFER_END,
+	};
+
+	const uint32_t store_reg[] = {
+		MI_STORE_REGISTER_MEM | (4 - 2),
+		BCS_GPR(0),
+		0, /* reloc */
+		0, /* reloc */
+		MI_NOOP,
+		MI_BATCH_BUFFER_END,
+	};
+
+	exec_batch(fd, I915_EXEC_BLT, handle,
+		   lri_ok, sizeof(lri_ok),
+		   0);
+
+	exec_batch_patched(fd, I915_EXEC_BLT, handle,
+			   store_reg, sizeof(store_reg),
+			   2 * sizeof(uint32_t), /* reloc */
+			   ok_val);
+
+	exec_batch(fd, I915_EXEC_BLT, handle,
+		   lri_bad, 0,
+		   0);
+
+	exec_batch_patched(fd, I915_EXEC_BLT, handle,
+			   store_reg, sizeof(store_reg),
+			   2 * sizeof(uint32_t), /* reloc */
+			   ok_val);
+
+	exec_batch(fd, I915_EXEC_BLT, handle,
+		   lri_ok, 4096,
+		   0);
+
+	igt_assert_eq(__gem_write(fd, handle, 0, noops, 4097), -EINVAL);
+}
+
+struct reg {
+	uint32_t addr;
+	uint32_t mask;
+	bool masked_write;
+	bool privileged;
+};
+
+#define REG_M(ADDR, MASK, WM, P) { (ADDR), (MASK), (WM), (P) }
+#define REG(ADDR) REG_M(ADDR, 0xffffffff, false, false)
+#define REG_P(ADDR) REG_M(ADDR, 0xffffffff, false, true)
+
+static const struct reg regs[] = {
+	REG_M(BCS_SWCTRL, 0x3, true, false),
+	REG(BCS_GPR(0)),
+	REG(BCS_GPR_UDW(0)),
+	REG(BCS_GPR(1)),
+	REG(BCS_GPR_UDW(1)),
+	REG(BCS_GPR(2)),
+	REG(BCS_GPR_UDW(2)),
+	REG(BCS_GPR(3)),
+	REG(BCS_GPR_UDW(3)),
+	REG(BCS_GPR(4)),
+	REG(BCS_GPR_UDW(4)),
+	REG(BCS_GPR(5)),
+	REG(BCS_GPR_UDW(5)),
+	REG(BCS_GPR(6)),
+	REG(BCS_GPR_UDW(6)),
+	REG(BCS_GPR(7)),
+	REG(BCS_GPR_UDW(7)),
+	REG(BCS_GPR(8)),
+	REG(BCS_GPR_UDW(8)),
+	REG(BCS_GPR(9)),
+	REG(BCS_GPR_UDW(9)),
+	REG(BCS_GPR(10)),
+	REG(BCS_GPR_UDW(10)),
+	REG(BCS_GPR(11)),
+	REG(BCS_GPR_UDW(11)),
+	REG(BCS_GPR(12)),
+	REG(BCS_GPR_UDW(12)),
+	REG(BCS_GPR(13)),
+	REG(BCS_GPR_UDW(13)),
+	REG(BCS_GPR(14)),
+	REG(BCS_GPR_UDW(14)),
+	REG(BCS_GPR(15)),
+	REG(BCS_GPR_UDW(15)),
+
+	REG_P(0),
+	REG_P(200000),
+
+	REG_P(BCS_SWCTRL - 1),
+	REG_P(BCS_SWCTRL - 2),
+	REG_P(BCS_SWCTRL - 3),
+	REG_P(BCS_SWCTRL - 4),
+	REG_P(BCS_SWCTRL + 4),
+
+	REG_P(BCS_GPR(0) - 1),
+	REG_P(BCS_GPR(0) - 2),
+	REG_P(BCS_GPR(0) - 3),
+	REG_P(BCS_GPR(0) - 4),
+	REG_P(BCS_GPR_UDW(15) + 4),
+};
+
+static void test_register(const int fd, const uint32_t handle,
+			  const struct reg *r)
+{
+	const uint32_t lri_zero[] = {
+		MI_LOAD_REGISTER_IMM,
+		r->addr,
+		r->masked_write ? 0xffff0000 : 0,
+		MI_BATCH_BUFFER_END,
+	};
+
+	const uint32_t lri_mask[] = {
+		MI_LOAD_REGISTER_IMM,
+		r->addr,
+		r->masked_write ? (r->mask << 16) | r->mask : r->mask,
+		MI_BATCH_BUFFER_END,
+	};
+
+	const uint32_t store_reg[] = {
+		MI_STORE_REGISTER_MEM | (4 - 2),
+		r->addr,
+		0, /* reloc */
+		0, /* reloc */
+		MI_NOOP,
+		MI_BATCH_BUFFER_END,
+	};
+
+	exec_batch(fd, I915_EXEC_BLT, handle,
+		   lri_mask, sizeof(lri_mask),
+		   r->privileged ? -EACCES : 0);
+
+	exec_batch_patched(fd, I915_EXEC_BLT, handle,
+			   store_reg, sizeof(store_reg),
+			   2 * sizeof(uint32_t), /* reloc */
+			   r->privileged ? -EACCES : r->mask);
+
+	exec_batch(fd, I915_EXEC_BLT, handle,
+		   lri_zero, sizeof(lri_zero),
+		   r->privileged ? -EACCES : 0);
+
+	exec_batch_patched(fd, I915_EXEC_BLT, handle,
+			   store_reg, sizeof(store_reg),
+			   2 * sizeof(uint32_t), /* reloc */
+			   r->privileged ? -EACCES : 0);
+}
+
+static void test_valid_registers(const int fd, const uint32_t handle)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(regs); i++)
+		test_register(fd, handle, &regs[i]);
+}
+
+static long int read_reg(const int fd, const uint32_t handle,
+			 const uint32_t addr)
+{
+	const uint32_t store_reg[] = {
+		MI_STORE_REGISTER_MEM | (4 - 2),
+		addr,
+		0, /* reloc */
+		0, /* reloc */
+		MI_NOOP,
+		MI_BATCH_BUFFER_END,
+	};
+	uint32_t target_bo;
+	uint32_t value;
+	long int ret;
+
+	target_bo = gem_create(fd, HANDLE_SIZE);
+
+	ret = __exec_batch_patched(fd, I915_EXEC_BLT, handle,
+				   store_reg, sizeof(store_reg),
+				   target_bo, 2 * sizeof(uint32_t), 0);
+
+	if (ret) {
+		igt_assert_lt(ret, 0);
+		gem_close(fd, target_bo);
+		return ret;
+	}
+
+	gem_read(fd, target_bo, 0, &value, sizeof(value));
+
+	gem_close(fd, target_bo);
+
+	return value;
+}
+
+static int write_reg(const int fd, const uint32_t handle,
+		     const uint32_t addr, const uint32_t val)
+{
+	const uint32_t lri[] = {
+		MI_LOAD_REGISTER_IMM,
+		addr,
+		val,
+		MI_BATCH_BUFFER_END,
+	};
+
+	return __exec_batch(fd, I915_EXEC_BLT, handle,
+			    lri, sizeof(lri));
+}
+
+static void test_unaligned_access(const int fd, const uint32_t handle)
+{
+	const uint32_t addr = BCS_GPR(4);
+	const uint32_t val = 0xbaadfead;
+	const uint32_t pre = 0x12345678;
+	const uint32_t post = 0x87654321;
+
+	igt_assert_eq(write_reg(fd, handle, addr - 4, pre),  0);
+	igt_assert_eq(write_reg(fd, handle, addr, val),      0);
+	igt_assert_eq(write_reg(fd, handle, addr + 4, post), 0);
+
+	igt_assert_eq(read_reg(fd, handle, addr - 4), pre);
+	igt_assert_eq(read_reg(fd, handle, addr),     val);
+	igt_assert_eq(read_reg(fd, handle, addr + 4), post);
+
+	for (int i = 0; i < 4; i++) {
+		igt_assert_eq(write_reg(fd, handle, addr + i, val), 0);
+		igt_assert_eq(read_reg(fd, handle, addr), val);
+
+		igt_assert_eq(read_reg(fd, handle, addr + 1), val);
+		igt_assert_eq(read_reg(fd, handle, addr + 2), val);
+		igt_assert_eq(read_reg(fd, handle, addr + 3), val);
+		igt_assert_eq(read_reg(fd, handle, addr + 4), post);
+		igt_assert_eq(read_reg(fd, handle, addr - 3), pre);
+		igt_assert_eq(read_reg(fd, handle, addr - 2), pre);
+		igt_assert_eq(read_reg(fd, handle, addr - 1), pre);
+	}
+}
+
+static void test_reject_on_engine(int fd, uint32_t handle, unsigned int engine)
+{
+	const uint32_t invalid_cmd[] = {
+		INSTR_INVALID_CLIENT << INSTR_CLIENT_SHIFT,
+		MI_BATCH_BUFFER_END,
+	};
+	const uint32_t invalid_set_context[] = {
+		MI_SET_CONTEXT | 32, /* invalid length */
+		MI_BATCH_BUFFER_END,
+	};
+
+	exec_batch(fd, engine, handle,
+		   invalid_cmd, sizeof(invalid_cmd),
+		   -EINVAL);
+
+	exec_batch(fd, engine, handle,
+		   invalid_set_context, sizeof(invalid_set_context),
+		   -EINVAL);
+}
+
+static void test_rejected(int fd, uint32_t handle, bool ctx_param)
+{
+#define engine_class(e, n) ((e)->engines[(n)].engine_class)
+#define engine_instance(e, n) ((e)->engines[(n)].engine_instance)
+
+	if (ctx_param) {
+		int i;
+
+		I915_DEFINE_CONTEXT_PARAM_ENGINES(engines , I915_EXEC_RING_MASK + 1);
+		struct drm_i915_gem_context_param param = {
+			.ctx_id = 0,
+			.param = I915_CONTEXT_PARAM_ENGINES,
+			.value = to_user_pointer(&engines),
+			.size = sizeof(engines),
+		};
+
+		memset(&engines, 0, sizeof(engines));
+		for (i = 0; i <= I915_EXEC_RING_MASK; i++) {
+			engine_class(&engines, i) = I915_ENGINE_CLASS_COPY;
+			engine_instance(&engines, i) = 0;
+		}
+		gem_context_set_param(fd, &param);
+
+		for (i = 0; i <= I915_EXEC_RING_MASK; i++)
+			test_reject_on_engine(fd, handle, i);
+
+		param.size = 0;
+		gem_context_set_param(fd, &param);
+	} else {
+		test_reject_on_engine(fd, handle, I915_EXEC_BLT);
+	}
+}
+
+igt_main
+{
+	uint32_t handle;
+	int fd;
+
+	igt_fixture {
+		fd = drm_open_driver(DRIVER_INTEL);
+		igt_require_gem(fd);
+		gem_require_blitter(fd);
+
+		parser_version = command_parser_version(fd);
+		/* igt_require(parser_version == 10); */
+
+		igt_require(gem_uses_ppgtt(fd));
+		igt_require(gem_has_blt(fd));
+		igt_require(intel_gen(intel_get_drm_devid(fd)) == 9);
+
+		handle = gem_create(fd, HANDLE_SIZE);
+
+		igt_fork_hang_detector(fd);
+	}
+
+	igt_subtest("secure-batches")
+		test_secure_batches(fd);
+
+	igt_subtest("allowed-all")
+		test_allowed_all(fd, handle);
+
+	igt_subtest("allowed-single")
+		test_allowed_single(fd, handle);
+
+	igt_subtest("bb-start-param")
+		test_bb_start(fd, handle, BB_START_PARAM);
+
+	igt_subtest("bb-start-out")
+		test_bb_start(fd, handle, BB_START_OUT);
+
+	igt_subtest("bb-secure")
+		test_bb_secure(fd, handle);
+
+	igt_subtest("bb-chained")
+		test_bb_chained(fd, handle);
+
+	igt_subtest("cmd-crossing-page")
+		test_cmd_crossing_page(fd, handle);
+
+	igt_subtest("batch-without-end") {
+		const uint32_t noop[1024] = { 0 };
+
+		exec_batch(fd, I915_EXEC_BLT, handle,
+			   noop, sizeof(noop),
+			   -EINVAL);
+	}
+
+	igt_subtest("batch-zero-length") {
+		const uint32_t noop[] = { 0, MI_BATCH_BUFFER_END };
+
+		exec_batch(fd, I915_EXEC_BLT, handle,
+			   noop, 0,
+			   -EINVAL);
+	}
+
+	igt_subtest("batch-invalid-length")
+		test_invalid_length(fd, handle);
+
+	igt_subtest("basic-rejected")
+		test_rejected(fd, handle, false);
+
+	igt_subtest("basic-rejected-ctx-param")
+		test_rejected(fd, handle, true);
+
+	igt_subtest("valid-registers")
+		test_valid_registers(fd, handle);
+
+	igt_subtest("unaligned-access")
+		test_unaligned_access(fd, handle);
+
+	igt_subtest_group {
+		igt_hang_t hang;
+
+		igt_fixture igt_allow_hang(fd, 0, 0);
+
+		igt_subtest("bb-start-cmd")
+			test_bb_start(fd, handle, BB_START_CMD);
+
+		igt_subtest("bb-start-far")
+			test_bb_start(fd, handle, BB_START_FAR);
+
+		igt_fixture igt_disallow_hang(fd, hang);
+	}
+
+	igt_fixture {
+		igt_stop_hang_detector();
+		gem_close(fd, handle);
+
+		close(fd);
+	}
+}
diff --git a/tests/meson.build b/tests/meson.build
index 44bddd02..755fc9e6 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -149,6 +149,7 @@ i915_progs = [
 	'gem_exec_parallel',
 	'gem_exec_params',
 	'gem_exec_parse',
+	'gem_exec_parse_blt',
 	'gem_exec_reloc',
 	'gem_exec_reuse',
 	'gem_exec_schedule',
-- 
2.17.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* [igt-dev] ✗ GitLab.Pipeline: failure for Add tests/gem_exec_parse_blt (rev3)
  2019-11-14 17:18 [igt-dev] [PATCH i-g-t] Add tests/gem_exec_parse_blt Mika Kuoppala
  2019-11-14 17:30 ` Mika Kuoppala
@ 2019-11-14 18:05 ` Patchwork
  2019-11-14 18:05 ` [igt-dev] ✓ Fi.CI.BAT: success " Patchwork
  2019-11-15 19:43 ` [igt-dev] ✗ Fi.CI.IGT: failure " Patchwork
  3 siblings, 0 replies; 6+ messages in thread
From: Patchwork @ 2019-11-14 18:05 UTC (permalink / raw)
  To: Mika Kuoppala; +Cc: igt-dev

== Series Details ==

Series: Add tests/gem_exec_parse_blt (rev3)
URL   : https://patchwork.freedesktop.org/series/69474/
State : failure

== Summary ==

ERROR! This series introduces new undocumented tests:

gem_exec_parse_blt
gem_exec_parse_blt@allowed-all
gem_exec_parse_blt@allowed-single
gem_exec_parse_blt@basic-rejected
gem_exec_parse_blt@basic-rejected-ctx-param
gem_exec_parse_blt@batch-invalid-length
gem_exec_parse_blt@batch-without-end
gem_exec_parse_blt@batch-zero-length
gem_exec_parse_blt@bb-chained
gem_exec_parse_blt@bb-secure
gem_exec_parse_blt@bb-start-cmd
gem_exec_parse_blt@bb-start-far
gem_exec_parse_blt@bb-start-out
gem_exec_parse_blt@bb-start-param
gem_exec_parse_blt@cmd-crossing-page
gem_exec_parse_blt@secure-batches
gem_exec_parse_blt@unaligned-access
gem_exec_parse_blt@valid-registers

Can you document them as per the requirement in the [CONTRIBUTING.md]?

[Documentation] has more details on how to do this.

Here are few examples:
https://gitlab.freedesktop.org/drm/igt-gpu-tools/commit/0316695d03aa46108296b27f3982ec93200c7a6e
https://gitlab.freedesktop.org/drm/igt-gpu-tools/commit/443cc658e1e6b492ee17bf4f4d891029eb7a205d

Thanks in advance!

[CONTRIBUTING.md]: https://gitlab.freedesktop.org/drm/igt-gpu-tools/blob/master/CONTRIBUTING.md#L19
[Documentation]: https://drm.pages.freedesktop.org/igt-gpu-tools/igt-gpu-tools-Core.html#igt-describe

Other than that, pipeline status: SUCCESS.

see https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/pipelines/79151 for the overview.

== Logs ==

For more details see: https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/pipelines/79151
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* [igt-dev] ✓ Fi.CI.BAT: success for Add tests/gem_exec_parse_blt (rev3)
  2019-11-14 17:18 [igt-dev] [PATCH i-g-t] Add tests/gem_exec_parse_blt Mika Kuoppala
  2019-11-14 17:30 ` Mika Kuoppala
  2019-11-14 18:05 ` [igt-dev] ✗ GitLab.Pipeline: failure for Add tests/gem_exec_parse_blt (rev3) Patchwork
@ 2019-11-14 18:05 ` Patchwork
  2019-11-15 19:43 ` [igt-dev] ✗ Fi.CI.IGT: failure " Patchwork
  3 siblings, 0 replies; 6+ messages in thread
From: Patchwork @ 2019-11-14 18:05 UTC (permalink / raw)
  To: Mika Kuoppala; +Cc: igt-dev

== Series Details ==

Series: Add tests/gem_exec_parse_blt (rev3)
URL   : https://patchwork.freedesktop.org/series/69474/
State : success

== Summary ==

CI Bug Log - changes from IGT_5283 -> IGTPW_3706
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/index.html

Known issues
------------

  Here are the changes found in IGTPW_3706 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@i915_selftest@live_gem_contexts:
    - fi-bsw-n3050:       [PASS][1] -> [INCOMPLETE][2] ([fdo# 111542])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/fi-bsw-n3050/igt@i915_selftest@live_gem_contexts.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/fi-bsw-n3050/igt@i915_selftest@live_gem_contexts.html

  * igt@kms_setmode@basic-clone-single-crtc:
    - fi-skl-6770hq:      [PASS][3] -> [WARN][4] ([fdo#112252])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/fi-skl-6770hq/igt@kms_setmode@basic-clone-single-crtc.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/fi-skl-6770hq/igt@kms_setmode@basic-clone-single-crtc.html

  
#### Possible fixes ####

  * igt@gem_basic@create-close:
    - fi-icl-dsi:         [DMESG-WARN][5] ([fdo#106107]) -> [PASS][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/fi-icl-dsi/igt@gem_basic@create-close.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/fi-icl-dsi/igt@gem_basic@create-close.html

  * igt@i915_module_load@reload-with-fault-injection:
    - fi-icl-guc:         [DMESG-WARN][7] ([fdo#106107]) -> [PASS][8]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/fi-icl-guc/igt@i915_module_load@reload-with-fault-injection.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/fi-icl-guc/igt@i915_module_load@reload-with-fault-injection.html

  * igt@kms_busy@basic-flip-pipe-b:
    - fi-skl-6770hq:      [DMESG-WARN][9] ([fdo#105541]) -> [PASS][10]
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/fi-skl-6770hq/igt@kms_busy@basic-flip-pipe-b.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/fi-skl-6770hq/igt@kms_busy@basic-flip-pipe-b.html

  * igt@kms_chamelium@hdmi-hpd-fast:
    - fi-kbl-7500u:       [FAIL][11] ([fdo#111407]) -> [PASS][12]
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/fi-kbl-7500u/igt@kms_chamelium@hdmi-hpd-fast.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/fi-kbl-7500u/igt@kms_chamelium@hdmi-hpd-fast.html

  
#### Warnings ####

  * igt@kms_chamelium@common-hpd-after-suspend:
    - fi-icl-u2:          [DMESG-WARN][13] ([fdo#102505] / [fdo#110390]) -> [DMESG-WARN][14] ([fdo#102505] / [fdo#106107] / [fdo#110390])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/fi-icl-u2/igt@kms_chamelium@common-hpd-after-suspend.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/fi-icl-u2/igt@kms_chamelium@common-hpd-after-suspend.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo# 111542]: https://bugs.freedesktop.org/show_bug.cgi?id= 111542
  [fdo#102505]: https://bugs.freedesktop.org/show_bug.cgi?id=102505
  [fdo#105541]: https://bugs.freedesktop.org/show_bug.cgi?id=105541
  [fdo#106107]: https://bugs.freedesktop.org/show_bug.cgi?id=106107
  [fdo#110343]: https://bugs.freedesktop.org/show_bug.cgi?id=110343
  [fdo#110390]: https://bugs.freedesktop.org/show_bug.cgi?id=110390
  [fdo#111407]: https://bugs.freedesktop.org/show_bug.cgi?id=111407
  [fdo#112252]: https://bugs.freedesktop.org/show_bug.cgi?id=112252


Participating hosts (50 -> 45)
------------------------------

  Missing    (5): fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-byt-clapper fi-bdw-samus 


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_5283 -> IGTPW_3706

  CI-20190529: 20190529
  CI_DRM_7344: f1908e34ae20deabec070a88efaa495aa8e051f1 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_3706: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/index.html
  IGT_5283: a802816d941a2c6ae49e7e37a98da77a3ca3dc73 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools



== Testlist changes ==

+igt@gem_exec_parse_blt@allowed-all
+igt@gem_exec_parse_blt@allowed-single
+igt@gem_exec_parse_blt@basic-rejected
+igt@gem_exec_parse_blt@basic-rejected-ctx-param
+igt@gem_exec_parse_blt@batch-invalid-length
+igt@gem_exec_parse_blt@batch-without-end
+igt@gem_exec_parse_blt@batch-zero-length
+igt@gem_exec_parse_blt@bb-chained
+igt@gem_exec_parse_blt@bb-secure
+igt@gem_exec_parse_blt@bb-start-cmd
+igt@gem_exec_parse_blt@bb-start-far
+igt@gem_exec_parse_blt@bb-start-out
+igt@gem_exec_parse_blt@bb-start-param
+igt@gem_exec_parse_blt@cmd-crossing-page
+igt@gem_exec_parse_blt@secure-batches
+igt@gem_exec_parse_blt@unaligned-access
+igt@gem_exec_parse_blt@valid-registers

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/index.html
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* [igt-dev] ✗ Fi.CI.IGT: failure for Add tests/gem_exec_parse_blt (rev3)
  2019-11-14 17:18 [igt-dev] [PATCH i-g-t] Add tests/gem_exec_parse_blt Mika Kuoppala
                   ` (2 preceding siblings ...)
  2019-11-14 18:05 ` [igt-dev] ✓ Fi.CI.BAT: success " Patchwork
@ 2019-11-15 19:43 ` Patchwork
  3 siblings, 0 replies; 6+ messages in thread
From: Patchwork @ 2019-11-15 19:43 UTC (permalink / raw)
  To: Mika Kuoppala; +Cc: igt-dev

== Series Details ==

Series: Add tests/gem_exec_parse_blt (rev3)
URL   : https://patchwork.freedesktop.org/series/69474/
State : failure

== Summary ==

CI Bug Log - changes from IGT_5283_full -> IGTPW_3706_full
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with IGTPW_3706_full absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in IGTPW_3706_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/index.html

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in IGTPW_3706_full:

### IGT changes ###

#### Possible regressions ####

  * {igt@gem_exec_parse_blt@bb-chained} (NEW):
    - shard-iclb:         NOTRUN -> [SKIP][1] +16 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-iclb4/igt@gem_exec_parse_blt@bb-chained.html

  * {igt@gem_exec_parse_blt@bb-secure} (NEW):
    - shard-tglb:         NOTRUN -> [SKIP][2] +12 similar issues
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-tglb8/igt@gem_exec_parse_blt@bb-secure.html

  * igt@i915_selftest@live_execlists:
    - shard-tglb:         [PASS][3] -> [INCOMPLETE][4]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-tglb7/igt@i915_selftest@live_execlists.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-tglb3/igt@i915_selftest@live_execlists.html

  * igt@runner@aborted:
    - shard-apl:          NOTRUN -> [FAIL][5]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-apl8/igt@runner@aborted.html

  
New tests
---------

  New tests have been introduced between IGT_5283_full and IGTPW_3706_full:

### New IGT tests (17) ###

  * igt@gem_exec_parse_blt@allowed-all:
    - Statuses : 3 pass(s) 3 skip(s)
    - Exec time: [0.0, 0.00] s

  * igt@gem_exec_parse_blt@allowed-single:
    - Statuses : 3 pass(s) 4 skip(s)
    - Exec time: [0.0, 0.00] s

  * igt@gem_exec_parse_blt@basic-rejected:
    - Statuses : 3 pass(s) 3 skip(s)
    - Exec time: [0.0, 0.00] s

  * igt@gem_exec_parse_blt@basic-rejected-ctx-param:
    - Statuses : 3 pass(s) 4 skip(s)
    - Exec time: [0.0, 0.15] s

  * igt@gem_exec_parse_blt@batch-invalid-length:
    - Statuses : 3 pass(s) 4 skip(s)
    - Exec time: [0.0, 0.00] s

  * igt@gem_exec_parse_blt@batch-without-end:
    - Statuses : 3 pass(s) 2 skip(s)
    - Exec time: [0.0, 0.00] s

  * igt@gem_exec_parse_blt@batch-zero-length:
    - Statuses : 3 pass(s) 4 skip(s)
    - Exec time: [0.0, 0.00] s

  * igt@gem_exec_parse_blt@bb-chained:
    - Statuses : 3 pass(s) 4 skip(s)
    - Exec time: [0.0, 0.00] s

  * igt@gem_exec_parse_blt@bb-secure:
    - Statuses : 3 pass(s) 4 skip(s)
    - Exec time: [0.0, 0.00] s

  * igt@gem_exec_parse_blt@bb-start-cmd:
    - Statuses : 3 pass(s) 4 skip(s)
    - Exec time: [0.0, 0.00] s

  * igt@gem_exec_parse_blt@bb-start-far:
    - Statuses : 3 pass(s) 4 skip(s)
    - Exec time: [0.0, 0.00] s

  * igt@gem_exec_parse_blt@bb-start-out:
    - Statuses : 3 pass(s) 3 skip(s)
    - Exec time: [0.0, 0.00] s

  * igt@gem_exec_parse_blt@bb-start-param:
    - Statuses : 3 pass(s) 4 skip(s)
    - Exec time: [0.0, 0.00] s

  * igt@gem_exec_parse_blt@cmd-crossing-page:
    - Statuses : 3 pass(s) 3 skip(s)
    - Exec time: [0.0, 0.00] s

  * igt@gem_exec_parse_blt@secure-batches:
    - Statuses : 3 pass(s) 4 skip(s)
    - Exec time: [0.0] s

  * igt@gem_exec_parse_blt@unaligned-access:
    - Statuses : 3 pass(s) 4 skip(s)
    - Exec time: [0.0, 0.03] s

  * igt@gem_exec_parse_blt@valid-registers:
    - Statuses : 3 pass(s) 4 skip(s)
    - Exec time: [0.0, 0.09] s

  

Known issues
------------

  Here are the changes found in IGTPW_3706_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_ctx_isolation@bcs0-s3:
    - shard-tglb:         [PASS][6] -> [INCOMPLETE][7] ([fdo#111832])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-tglb3/igt@gem_ctx_isolation@bcs0-s3.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-tglb1/igt@gem_ctx_isolation@bcs0-s3.html

  * igt@gem_ctx_persistence@vcs1-queued:
    - shard-iclb:         [PASS][8] -> [SKIP][9] ([fdo#109276] / [fdo#112080]) +2 similar issues
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-iclb2/igt@gem_ctx_persistence@vcs1-queued.html
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-iclb5/igt@gem_ctx_persistence@vcs1-queued.html

  * igt@gem_ctx_switch@all-light:
    - shard-tglb:         [PASS][10] -> [INCOMPLETE][11] ([fdo#111672])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-tglb3/igt@gem_ctx_switch@all-light.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-tglb6/igt@gem_ctx_switch@all-light.html

  * igt@gem_exec_balancer@smoke:
    - shard-iclb:         [PASS][12] -> [SKIP][13] ([fdo#110854])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-iclb2/igt@gem_exec_balancer@smoke.html
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-iclb3/igt@gem_exec_balancer@smoke.html

  * igt@gem_exec_parallel@vcs1-fds:
    - shard-iclb:         [PASS][14] -> [SKIP][15] ([fdo#112080]) +11 similar issues
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-iclb2/igt@gem_exec_parallel@vcs1-fds.html
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-iclb8/igt@gem_exec_parallel@vcs1-fds.html

  * igt@gem_exec_schedule@in-order-bsd:
    - shard-iclb:         [PASS][16] -> [SKIP][17] ([fdo#112146]) +5 similar issues
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-iclb7/igt@gem_exec_schedule@in-order-bsd.html
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-iclb1/igt@gem_exec_schedule@in-order-bsd.html

  * igt@gem_softpin@noreloc-s3:
    - shard-iclb:         [PASS][18] -> [INCOMPLETE][19] ([fdo#107713] / [fdo#109100])
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-iclb8/igt@gem_softpin@noreloc-s3.html
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-iclb6/igt@gem_softpin@noreloc-s3.html

  * igt@gem_userptr_blits@map-fixed-invalidate-busy-gup:
    - shard-hsw:          [PASS][20] -> [DMESG-WARN][21] ([fdo#111870])
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-hsw2/igt@gem_userptr_blits@map-fixed-invalidate-busy-gup.html
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-hsw8/igt@gem_userptr_blits@map-fixed-invalidate-busy-gup.html
    - shard-snb:          [PASS][22] -> [DMESG-WARN][23] ([fdo#110789] / [fdo#111870])
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-snb1/igt@gem_userptr_blits@map-fixed-invalidate-busy-gup.html
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-snb6/igt@gem_userptr_blits@map-fixed-invalidate-busy-gup.html

  * igt@gem_userptr_blits@sync-unmap-cycles:
    - shard-snb:          [PASS][24] -> [DMESG-WARN][25] ([fdo#111870]) +3 similar issues
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-snb4/igt@gem_userptr_blits@sync-unmap-cycles.html
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-snb5/igt@gem_userptr_blits@sync-unmap-cycles.html

  * igt@gem_workarounds@suspend-resume-fd:
    - shard-tglb:         [PASS][26] -> [INCOMPLETE][27] ([fdo#111832] / [fdo#111850])
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-tglb9/igt@gem_workarounds@suspend-resume-fd.html
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-tglb1/igt@gem_workarounds@suspend-resume-fd.html

  * igt@kms_busy@extended-modeset-hang-oldfb-with-reset-render-pipe-b:
    - shard-snb:          [PASS][28] -> [SKIP][29] ([fdo#109271])
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-snb6/igt@kms_busy@extended-modeset-hang-oldfb-with-reset-render-pipe-b.html
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-snb7/igt@kms_busy@extended-modeset-hang-oldfb-with-reset-render-pipe-b.html

  * igt@kms_cursor_legacy@2x-flip-vs-cursor-atomic:
    - shard-hsw:          [PASS][30] -> [SKIP][31] ([fdo#109271])
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-hsw4/igt@kms_cursor_legacy@2x-flip-vs-cursor-atomic.html
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-hsw5/igt@kms_cursor_legacy@2x-flip-vs-cursor-atomic.html

  * igt@kms_fbcon_fbt@fbc-suspend:
    - shard-tglb:         [PASS][32] -> [INCOMPLETE][33] ([fdo#111747] / [fdo#111832] / [fdo#111850])
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-tglb9/igt@kms_fbcon_fbt@fbc-suspend.html
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-tglb4/igt@kms_fbcon_fbt@fbc-suspend.html

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-render:
    - shard-iclb:         [PASS][34] -> [FAIL][35] ([fdo#103167]) +4 similar issues
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-iclb8/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-render.html
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-iclb8/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-render.html

  * igt@kms_frontbuffer_tracking@fbcpsr-stridechange:
    - shard-tglb:         [PASS][36] -> [FAIL][37] ([fdo#103167])
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-tglb8/igt@kms_frontbuffer_tracking@fbcpsr-stridechange.html
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-tglb4/igt@kms_frontbuffer_tracking@fbcpsr-stridechange.html

  * igt@kms_frontbuffer_tracking@fbcpsr-suspend:
    - shard-tglb:         [PASS][38] -> [INCOMPLETE][39] ([fdo#111832] / [fdo#111850] / [fdo#111884])
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-tglb2/igt@kms_frontbuffer_tracking@fbcpsr-suspend.html
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-tglb8/igt@kms_frontbuffer_tracking@fbcpsr-suspend.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c:
    - shard-apl:          [PASS][40] -> [DMESG-WARN][41] ([fdo#108566]) +3 similar issues
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-apl7/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c.html
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-apl1/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c.html

  * igt@kms_vblank@pipe-a-ts-continuation-suspend:
    - shard-kbl:          [PASS][42] -> [DMESG-WARN][43] ([fdo#108566]) +2 similar issues
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-kbl2/igt@kms_vblank@pipe-a-ts-continuation-suspend.html
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-kbl6/igt@kms_vblank@pipe-a-ts-continuation-suspend.html

  * igt@prime_busy@after-bsd2:
    - shard-iclb:         [PASS][44] -> [SKIP][45] ([fdo#109276]) +9 similar issues
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-iclb4/igt@prime_busy@after-bsd2.html
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-iclb7/igt@prime_busy@after-bsd2.html

  
#### Possible fixes ####

  * igt@gem_ctx_isolation@vcs0-s3:
    - shard-tglb:         [INCOMPLETE][46] ([fdo#111832]) -> [PASS][47]
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-tglb7/igt@gem_ctx_isolation@vcs0-s3.html
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-tglb9/igt@gem_ctx_isolation@vcs0-s3.html

  * igt@gem_ctx_persistence@vcs1-persistence:
    - shard-iclb:         [SKIP][48] ([fdo#109276] / [fdo#112080]) -> [PASS][49] +1 similar issue
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-iclb6/igt@gem_ctx_persistence@vcs1-persistence.html
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-iclb2/igt@gem_ctx_persistence@vcs1-persistence.html

  * igt@gem_ctx_switch@vcs1:
    - shard-iclb:         [SKIP][50] ([fdo#112080]) -> [PASS][51] +14 similar issues
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-iclb6/igt@gem_ctx_switch@vcs1.html
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-iclb2/igt@gem_ctx_switch@vcs1.html

  * igt@gem_exec_create@forked:
    - shard-tglb:         [INCOMPLETE][52] ([fdo#108838] / [fdo#111747]) -> [PASS][53]
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-tglb6/igt@gem_exec_create@forked.html
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-tglb2/igt@gem_exec_create@forked.html

  * igt@gem_exec_schedule@preemptive-hang-bsd:
    - shard-iclb:         [SKIP][54] ([fdo#112146]) -> [PASS][55] +9 similar issues
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-iclb1/igt@gem_exec_schedule@preemptive-hang-bsd.html
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-iclb8/igt@gem_exec_schedule@preemptive-hang-bsd.html

  * igt@gem_persistent_relocs@forked-faulting-reloc-thrashing:
    - shard-tglb:         [TIMEOUT][56] ([fdo#112068 ] / [fdo#112126]) -> [PASS][57]
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-tglb9/igt@gem_persistent_relocs@forked-faulting-reloc-thrashing.html
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-tglb2/igt@gem_persistent_relocs@forked-faulting-reloc-thrashing.html

  * igt@gem_persistent_relocs@forked-thrash-inactive:
    - shard-apl:          [DMESG-FAIL][58] -> [PASS][59]
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-apl3/igt@gem_persistent_relocs@forked-thrash-inactive.html
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-apl8/igt@gem_persistent_relocs@forked-thrash-inactive.html

  * igt@gem_userptr_blits@map-fixed-invalidate-busy:
    - shard-snb:          [DMESG-WARN][60] ([fdo#111870]) -> [PASS][61] +1 similar issue
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-snb6/igt@gem_userptr_blits@map-fixed-invalidate-busy.html
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-snb7/igt@gem_userptr_blits@map-fixed-invalidate-busy.html
    - shard-hsw:          [DMESG-WARN][62] ([fdo#111870]) -> [PASS][63] +2 similar issues
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-hsw8/igt@gem_userptr_blits@map-fixed-invalidate-busy.html
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-hsw2/igt@gem_userptr_blits@map-fixed-invalidate-busy.html

  * igt@gem_workarounds@suspend-resume-context:
    - shard-apl:          [DMESG-WARN][64] ([fdo#108566]) -> [PASS][65] +2 similar issues
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-apl1/igt@gem_workarounds@suspend-resume-context.html
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-apl6/igt@gem_workarounds@suspend-resume-context.html

  * igt@i915_selftest@live_hangcheck:
    - shard-hsw:          [DMESG-FAIL][66] ([fdo#111991]) -> [PASS][67]
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-hsw6/igt@i915_selftest@live_hangcheck.html
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-hsw5/igt@i915_selftest@live_hangcheck.html

  * igt@kms_cursor_crc@pipe-d-cursor-suspend:
    - shard-tglb:         [INCOMPLETE][68] ([fdo#111850]) -> [PASS][69]
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-tglb7/igt@kms_cursor_crc@pipe-d-cursor-suspend.html
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-tglb1/igt@kms_cursor_crc@pipe-d-cursor-suspend.html

  * igt@kms_frontbuffer_tracking@fbc-rgb565-draw-pwrite:
    - shard-iclb:         [FAIL][70] ([fdo#103167]) -> [PASS][71] +5 similar issues
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-iclb2/igt@kms_frontbuffer_tracking@fbc-rgb565-draw-pwrite.html
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-iclb8/igt@kms_frontbuffer_tracking@fbc-rgb565-draw-pwrite.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-shrfb-plflip-blt:
    - shard-tglb:         [FAIL][72] ([fdo#103167]) -> [PASS][73]
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-tglb9/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-shrfb-plflip-blt.html
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-tglb2/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-shrfb-plflip-blt.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
    - shard-kbl:          [DMESG-WARN][74] ([fdo#108566]) -> [PASS][75]
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-kbl3/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-kbl6/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b:
    - shard-iclb:         [DMESG-WARN][76] ([fdo#111764]) -> [PASS][77]
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-iclb4/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b.html
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-iclb4/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b.html

  * igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes:
    - shard-tglb:         [INCOMPLETE][78] ([fdo#111832] / [fdo#111850]) -> [PASS][79] +1 similar issue
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-tglb5/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes.html
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-tglb9/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes.html

  * igt@kms_psr2_su@page_flip:
    - shard-iclb:         [SKIP][80] ([fdo#109642] / [fdo#111068]) -> [PASS][81]
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-iclb1/igt@kms_psr2_su@page_flip.html
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-iclb2/igt@kms_psr2_su@page_flip.html

  * igt@kms_psr@psr2_basic:
    - shard-iclb:         [SKIP][82] ([fdo#109441]) -> [PASS][83] +1 similar issue
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-iclb6/igt@kms_psr@psr2_basic.html
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-iclb2/igt@kms_psr@psr2_basic.html

  * igt@kms_setmode@basic:
    - shard-glk:          [FAIL][84] ([fdo#99912]) -> [PASS][85]
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-glk6/igt@kms_setmode@basic.html
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-glk4/igt@kms_setmode@basic.html
    - shard-kbl:          [FAIL][86] ([fdo#99912]) -> [PASS][87]
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-kbl3/igt@kms_setmode@basic.html
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-kbl7/igt@kms_setmode@basic.html

  * igt@prime_busy@hang-bsd2:
    - shard-iclb:         [SKIP][88] ([fdo#109276]) -> [PASS][89] +14 similar issues
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-iclb8/igt@prime_busy@hang-bsd2.html
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-iclb4/igt@prime_busy@hang-bsd2.html

  * igt@prime_vgem@busy-blt:
    - shard-kbl:          [FAIL][90] ([fdo#112291]) -> [PASS][91]
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-kbl6/igt@prime_vgem@busy-blt.html
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-kbl3/igt@prime_vgem@busy-blt.html
    - shard-apl:          [FAIL][92] ([fdo#112291]) -> [PASS][93]
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-apl1/igt@prime_vgem@busy-blt.html
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-apl7/igt@prime_vgem@busy-blt.html
    - shard-glk:          [FAIL][94] ([fdo#112291]) -> [PASS][95]
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-glk1/igt@prime_vgem@busy-blt.html
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-glk4/igt@prime_vgem@busy-blt.html

  * igt@prime_vgem@wait-blt:
    - shard-kbl:          [FAIL][96] ([fdo#112292]) -> [PASS][97]
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5283/shard-kbl2/igt@prime_vgem@wait-blt.html
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/shard-kbl

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3706/index.html
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

end of thread, other threads:[~2019-11-15 19:43 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-11-14 17:18 [igt-dev] [PATCH i-g-t] Add tests/gem_exec_parse_blt Mika Kuoppala
2019-11-14 17:30 ` Mika Kuoppala
2019-11-14 18:05 ` [igt-dev] ✗ GitLab.Pipeline: failure for Add tests/gem_exec_parse_blt (rev3) Patchwork
2019-11-14 18:05 ` [igt-dev] ✓ Fi.CI.BAT: success " Patchwork
2019-11-15 19:43 ` [igt-dev] ✗ Fi.CI.IGT: failure " Patchwork
  -- strict thread matches above, loose matches on Subject: below --
2019-11-14 14:14 [igt-dev] [PATCH i-g-t] Add tests/gem_exec_parse_blt Mika Kuoppala

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox