From patchwork Wed Oct 26 16:01:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Bragg X-Patchwork-Id: 9397571 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5A6F3600BA for ; Wed, 26 Oct 2016 16:01:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 310442833A for ; Wed, 26 Oct 2016 16:01:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 259DA29BED; Wed, 26 Oct 2016 16:01:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 35D042833A for ; Wed, 26 Oct 2016 16:01:51 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8D72D6E8CA; Wed, 26 Oct 2016 16:01:50 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-pf0-x242.google.com (mail-pf0-x242.google.com [IPv6:2607:f8b0:400e:c00::242]) by gabe.freedesktop.org (Postfix) with ESMTPS id 459AD6E8C9 for ; Wed, 26 Oct 2016 16:01:48 +0000 (UTC) Received: by mail-pf0-x242.google.com with SMTP id s8so23113669pfj.2 for ; Wed, 26 Oct 2016 09:01:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=ldCRkgpMNdSj7vkiyYmcvw1IqqEI7gsNjW6zEi9HXH0=; b=FeDdnvcTrK2uGMpNUNJd7F8bJKZkbWl6RZAlpB2O67Tlzox14e1J7qaPwpVEADnkRg twGi7hYc2sSQOBhOrtmpGxcOPinXddEgiHPNWgxcUXcB4GF2liByyAKqVm32C+5jbx1Y zpR13x0VKaViiZ/r0niyjc6R/j7/AuyhO/rqWZnO5nLJucqAJIMjYnVHIF98UQis1E38 HDSGyrM2yBW07P62lcMuxwEber4c5/eKfVwxAXJTVKAIC+28Rs/Y7QMEv2AqL+IWg/nC i6Z0YFgpIJcWq2wODkaPsrkNMTYgLucJuAWu3ENKxJCEYI9tOpw4CxEQJeIc7hM3FFjV Jazg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=ldCRkgpMNdSj7vkiyYmcvw1IqqEI7gsNjW6zEi9HXH0=; b=FF95qwhSwphT2IWMTD3fX86UJGT6ds2cskXTG1FL/nPW7RBUUItMmVTg9CpZbPred8 OctI2vwxLNddmfHbDAP3tpJkOzxWALcWOwnxYfxbNvnMcT7UccFX74n1znb4oFyaDfKy GIinrqNNugYc5lWKe31CiL/AUXmDHpIIPDyPiWlGMa6D5WeVIxbBlSof4N3+yDnYLrYt /k6/mNh/vbz7Na3DY5xVUQ5cP5+XAVtOX/Jl4XE/4DOjLcR/sNZSU04Tk77SCP/XzHwW /o+hnzzfPGbwChFwtG66j8BoI2cmDFHEBaddllW37xpnQkDW4b4TJdP5i5dPjOqRL96w PxpQ== X-Gm-Message-State: ABUngvfxFe2ykjPNQxLYd0hyO8DvTgydgS1fwAMVRZ7OimbqNk7De9UZm2B6lh4fMGx1mw== X-Received: by 10.99.244.18 with SMTP id g18mr4481590pgi.129.1477497707536; Wed, 26 Oct 2016 09:01:47 -0700 (PDT) Received: from sixbynine.org ([192.198.151.62]) by smtp.gmail.com with ESMTPSA id b66sm5299638pfg.10.2016.10.26.09.01.46 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 26 Oct 2016 09:01:47 -0700 (PDT) From: Robert Bragg To: intel-gfx@lists.freedesktop.org Date: Wed, 26 Oct 2016 17:01:33 +0100 Message-Id: <20161026160133.6926-4-robert@sixbynine.org> X-Mailer: git-send-email 2.10.1 In-Reply-To: <20161026160133.6926-1-robert@sixbynine.org> References: <20161026160133.6926-1-robert@sixbynine.org> Subject: [Intel-gfx] [PATCH igt 3/3] igt/gem_exec_parse: update for version 8 changes X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP This adapts the tests to account for the parser no longer reporting privilege violations back to userspace as EINVAL errors (they are left to the HW command parser to squash the commands to NOOPS). The interface change isn't expected to affect userspace and in fact it looks like the previous behaviour was liable to break userspace, such as Mesa which explicitly tries to observe whether OACONTROL LRIs are squashed to NOOPs but Mesa will abort for execbuffer errors. Signed-off-by: Robert Bragg --- tests/gem_exec_parse.c | 368 +++++++++++++++++++++++++++---------------------- 1 file changed, 200 insertions(+), 168 deletions(-) diff --git a/tests/gem_exec_parse.c b/tests/gem_exec_parse.c index 36bf57d..4290701 100644 --- a/tests/gem_exec_parse.c +++ b/tests/gem_exec_parse.c @@ -34,7 +34,24 @@ #define I915_PARAM_CMD_PARSER_VERSION 28 #endif +#define ARRAY_LEN(A) (sizeof(A) / sizeof(A[0])) + +#define OACONTROL 0x2360 #define DERRMR 0x44050 +#define SO_WRITE_OFFSET_0 0x5280 +#define HSW_CS_GPR(n) (0x2600 + 8*(n)) +#define HSW_CS_GPR0 HSW_CS_GPR(0) +#define HSW_CS_GPR1 HSW_CS_GPR(1) + +#define MI_LOAD_REGISTER_REG (0x2a << 23) +#define MI_STORE_REGISTER_MEM (0x24 << 23) +#define MI_ARB_ON_OFF (0x8 << 23) +#define MI_DISPLAY_FLIP ((0x14 << 23) | 1) + +#define GFX_OP_PIPE_CONTROL ((0x3<<29)|(0x3<<27)|(0x2<<24)|2) +#define PIPE_CONTROL_QW_WRITE (1<<14) +#define PIPE_CONTROL_LRI_POST_OP (1<<23) + static int command_parser_version(int fd) { @@ -50,101 +67,8 @@ static int command_parser_version(int fd) return -1; } -#define HSW_CS_GPR(n) (0x2600 + 8*(n)) -#define HSW_CS_GPR0 HSW_CS_GPR(0) -#define HSW_CS_GPR1 HSW_CS_GPR(1) - -#define MI_LOAD_REGISTER_REG (0x2a << 23) -#define MI_STORE_REGISTER_MEM (0x24 << 23) -static void hsw_load_register_reg(void) -{ - uint32_t buf[16] = { - MI_LOAD_REGISTER_IMM | (5 - 2), - HSW_CS_GPR0, - 0xabcdabcd, - HSW_CS_GPR1, - 0xdeadbeef, - - MI_STORE_REGISTER_MEM | (3 - 2), - HSW_CS_GPR1, - 0, /* address0 */ - - MI_LOAD_REGISTER_REG | (3 - 2), - HSW_CS_GPR0, - HSW_CS_GPR1, - - MI_STORE_REGISTER_MEM | (3 - 2), - HSW_CS_GPR1, - 4, /* address1 */ - - MI_BATCH_BUFFER_END, - }; - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 obj[2]; - struct drm_i915_gem_relocation_entry reloc[2]; - int fd; - - /* Open again to get a non-master file descriptor */ - fd = drm_open_driver(DRIVER_INTEL); - - igt_require(IS_HASWELL(intel_get_drm_devid(fd))); - igt_require(command_parser_version(fd) >= 7); - - memset(obj, 0, sizeof(obj)); - obj[0].handle = gem_create(fd, 4096); - obj[1].handle = gem_create(fd, 4096); - gem_write(fd, obj[1].handle, 0, buf, sizeof(buf)); - - memset(reloc, 0, sizeof(reloc)); - reloc[0].offset = 7*sizeof(uint32_t); - reloc[0].target_handle = obj[0].handle; - reloc[0].delta = 0; - reloc[0].read_domains = I915_GEM_DOMAIN_INSTRUCTION; - reloc[0].write_domain = I915_GEM_DOMAIN_INSTRUCTION; - reloc[1].offset = 13*sizeof(uint32_t); - reloc[1].target_handle = obj[0].handle; - reloc[1].delta = sizeof(uint32_t); - reloc[1].read_domains = I915_GEM_DOMAIN_INSTRUCTION; - reloc[1].write_domain = I915_GEM_DOMAIN_INSTRUCTION; - obj[1].relocs_ptr = (uintptr_t)&reloc; - obj[1].relocation_count = 2; - - memset(&execbuf, 0, sizeof(execbuf)); - execbuf.buffers_ptr = (uintptr_t)obj; - execbuf.buffer_count = 2; - execbuf.batch_len = sizeof(buf); - execbuf.flags = I915_EXEC_RENDER; - gem_execbuf(fd, &execbuf); - gem_close(fd, obj[1].handle); - - gem_read(fd, obj[0].handle, 0, buf, 2*sizeof(buf[0])); - igt_assert_eq_u32(buf[0], 0xdeadbeef); /* before copy */ - igt_assert_eq_u32(buf[1], 0xabcdabcd); /* after copy */ - - /* Now a couple of negative tests that should be filtered */ - execbuf.buffer_count = 1; - execbuf.batch_len = 4*sizeof(buf[0]); - - buf[0] = MI_LOAD_REGISTER_REG | (3 - 2); - buf[1] = HSW_CS_GPR0; - buf[2] = 0; - buf[3] = MI_BATCH_BUFFER_END; - gem_write(fd, obj[0].handle, 0, buf, execbuf.batch_len); - igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL); - - buf[2] = DERRMR; /* master only */ - gem_write(fd, obj[0].handle, 0, buf, execbuf.batch_len); - igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL); - - buf[2] = 0x2038; /* RING_START: invalid */ - gem_write(fd, obj[0].handle, 0, buf, execbuf.batch_len); - igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL); - - close(fd); -} - -static void exec_batch_patched(int fd, uint32_t cmd_bo, uint32_t *cmds, - int size, int patch_offset, uint64_t expected_value) +static uint64_t __exec_batch_patched(int fd, uint32_t cmd_bo, uint32_t *cmds, + int size, int patch_offset) { struct drm_i915_gem_execbuffer2 execbuf; struct drm_i915_gem_exec_object2 objs[2]; @@ -155,50 +79,43 @@ static void exec_batch_patched(int fd, uint32_t cmd_bo, uint32_t *cmds, gem_write(fd, cmd_bo, 0, cmds, size); - reloc[0].offset = patch_offset; - reloc[0].delta = 0; - reloc[0].target_handle = target_bo; - reloc[0].read_domains = I915_GEM_DOMAIN_RENDER; - reloc[0].write_domain = I915_GEM_DOMAIN_RENDER; - reloc[0].presumed_offset = 0; + memset(objs, 0, sizeof(objs)); objs[0].handle = target_bo; - objs[0].relocation_count = 0; - objs[0].relocs_ptr = 0; - objs[0].alignment = 0; - objs[0].offset = 0; - objs[0].flags = 0; - objs[0].rsvd1 = 0; - objs[0].rsvd2 = 0; - objs[1].handle = cmd_bo; - objs[1].relocation_count = 1; + + memset(reloc, 0, sizeof(reloc)); + reloc[0].offset = patch_offset; + reloc[0].target_handle = objs[0].handle; + reloc[0].delta = 0; + reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND; + reloc[0].write_domain = I915_GEM_DOMAIN_COMMAND; objs[1].relocs_ptr = (uintptr_t)reloc; - objs[1].alignment = 0; - objs[1].offset = 0; - objs[1].flags = 0; - objs[1].rsvd1 = 0; - objs[1].rsvd2 = 0; + objs[1].relocation_count = 1; + memset(&execbuf, 0, sizeof(execbuf)); execbuf.buffers_ptr = (uintptr_t)objs; execbuf.buffer_count = 2; - execbuf.batch_start_offset = 0; execbuf.batch_len = size; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; execbuf.flags = I915_EXEC_RENDER; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; gem_execbuf(fd, &execbuf); gem_sync(fd, cmd_bo); gem_read(fd,target_bo, 0, &actual_value, sizeof(actual_value)); - igt_assert_eq(expected_value, actual_value); gem_close(fd, target_bo); + + return actual_value; +} + +static void exec_batch_patched(int fd, uint32_t cmd_bo, uint32_t *cmds, + int size, int patch_offset, + uint64_t expected_value) +{ + igt_assert_eq(__exec_batch_patched(fd, cmd_bo, cmds, + size, patch_offset), + expected_value); } static int __exec_batch(int fd, uint32_t cmd_bo, uint32_t *cmds, @@ -320,14 +237,14 @@ static void exec_batch_chained(int fd, uint32_t cmd_bo, uint32_t *cmds, reloc.offset = patch_offset; reloc.delta = 0; reloc.target_handle = target_bo; - reloc.read_domains = I915_GEM_DOMAIN_RENDER; - reloc.write_domain = I915_GEM_DOMAIN_RENDER; + reloc.read_domains = I915_GEM_DOMAIN_COMMAND; + reloc.write_domain = I915_GEM_DOMAIN_COMMAND; reloc.presumed_offset = 0; 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_INSTRUCTION; + first_level_reloc.read_domains = I915_GEM_DOMAIN_COMMAND; first_level_reloc.write_domain = 0; first_level_reloc.presumed_offset = 0; @@ -380,15 +297,91 @@ static void exec_batch_chained(int fd, uint32_t cmd_bo, uint32_t *cmds, gem_close(fd, target_bo); } -uint32_t handle; -int fd; +static void hsw_load_register_reg(void) +{ + uint32_t init_gpr0[16] = { + MI_LOAD_REGISTER_IMM | (3 - 2), + HSW_CS_GPR0, + 0xabcdabc0, /* leave [1:0] zero */ + MI_BATCH_BUFFER_END, + }; + uint32_t store_gpr0[16] = { + MI_STORE_REGISTER_MEM | (3 - 2), + HSW_CS_GPR0, + 0, /* reloc*/ + MI_BATCH_BUFFER_END, + }; + uint32_t do_lrr[16] = { + MI_LOAD_REGISTER_REG | (3 - 2), + 0, /* [1] = src */ + HSW_CS_GPR0, /* dst */ + MI_BATCH_BUFFER_END, + }; + uint32_t allowed_regs[] = { + HSW_CS_GPR1, + SO_WRITE_OFFSET_0, + }; + uint32_t disallowed_regs[] = { + 0, + DERRMR, /* master only */ + 0x2038, /* RING_START: invalid */ + }; + int fd; + uint32_t handle; -#define MI_ARB_ON_OFF (0x8 << 23) -#define MI_DISPLAY_FLIP ((0x14 << 23) | 1) + /* Open again to get a non-master file descriptor */ + fd = drm_open_driver(DRIVER_INTEL); + + igt_require(IS_HASWELL(intel_get_drm_devid(fd))); + igt_require(command_parser_version(fd) >= 7); + + handle = gem_create(fd, 4096); + + for (int i = 0 ; i < ARRAY_LEN(allowed_regs); i++) { + uint32_t var; + + exec_batch(fd, handle, init_gpr0, sizeof(init_gpr0), + I915_EXEC_RENDER, + 0); + exec_batch_patched(fd, handle, + store_gpr0, sizeof(store_gpr0), + 2 * sizeof(uint32_t), /* reloc */ + 0xabcdabc0); + do_lrr[1] = allowed_regs[i]; + exec_batch(fd, handle, do_lrr, sizeof(do_lrr), + I915_EXEC_RENDER, + 0); + var = __exec_batch_patched(fd, handle, + store_gpr0, sizeof(store_gpr0), + 2 * sizeof(uint32_t)); /* reloc */ + igt_assert_neq(var, 0xabcdabc0); + + } + + for (int i = 0 ; i < ARRAY_LEN(disallowed_regs); i++) { + exec_batch(fd, handle, init_gpr0, sizeof(init_gpr0), + I915_EXEC_RENDER, + 0); + exec_batch_patched(fd, handle, + store_gpr0, sizeof(store_gpr0), + 2 * sizeof(uint32_t), /* reloc */ + 0xabcdabc0); + do_lrr[1] = disallowed_regs[i]; + exec_batch(fd, handle, do_lrr, sizeof(do_lrr), + I915_EXEC_RENDER, + 0); + exec_batch_patched(fd, handle, + store_gpr0, sizeof(store_gpr0), + 2 * sizeof(uint32_t), /* reloc */ + 0xabcdabc0); + } + + close(fd); +} -#define GFX_OP_PIPE_CONTROL ((0x3<<29)|(0x3<<27)|(0x2<<24)|2) -#define PIPE_CONTROL_QW_WRITE (1<<14) -#define PIPE_CONTROL_LRI_POST_OP (1<<23) + +uint32_t handle; +int fd; igt_main { @@ -428,57 +421,93 @@ igt_main } igt_subtest("basic-rejected") { - uint32_t arb_on_off[] = { - MI_ARB_ON_OFF, + uint32_t invalid_cmd[] = { + (0x7<<29), /* Reserved command type, + across all engines */ MI_BATCH_BUFFER_END, }; - uint32_t display_flip[] = { - MI_DISPLAY_FLIP, - 0, 0, 0, + uint32_t invalid_set_context[] = { + MI_SET_CONTEXT | 32, /* invalid length */ MI_BATCH_BUFFER_END, - 0 }; exec_batch(fd, handle, - arb_on_off, sizeof(arb_on_off), + invalid_cmd, sizeof(invalid_cmd), I915_EXEC_RENDER, -EINVAL); exec_batch(fd, handle, - arb_on_off, sizeof(arb_on_off), + invalid_cmd, sizeof(invalid_cmd), I915_EXEC_BSD, -EINVAL); + exec_batch(fd, handle, + invalid_cmd, sizeof(invalid_cmd), + I915_EXEC_BLT, + -EINVAL); if (gem_has_vebox(fd)) { - exec_batch(fd, handle, - arb_on_off, sizeof(arb_on_off), - I915_EXEC_VEBOX, - -EINVAL); + exec_batch(fd, handle, + invalid_cmd, sizeof(invalid_cmd), + I915_EXEC_VEBOX, + -EINVAL); } + exec_batch(fd, handle, - display_flip, sizeof(display_flip), - I915_EXEC_BLT, + invalid_set_context, sizeof(invalid_set_context), + I915_EXEC_RENDER, -EINVAL); } igt_subtest("registers") { - uint32_t lri_bad[] = { - MI_LOAD_REGISTER_IMM, - 0, /* disallowed register address */ - 0x12000000, - MI_BATCH_BUFFER_END, - }; + uint32_t lri_bad[] = { + MI_LOAD_REGISTER_IMM, + OACONTROL, /* disallowed register address */ + 0x31337000, + MI_BATCH_BUFFER_END, + }; uint32_t lri_ok[] = { - MI_LOAD_REGISTER_IMM, - 0x5280, /* allowed register address (SO_WRITE_OFFSET[0]) */ - 0x1, + MI_LOAD_REGISTER_IMM | (3 - 2), + SO_WRITE_OFFSET_0, /* allowed register address */ + 0xabcdabc0, /* [1:0] MBZ */ MI_BATCH_BUFFER_END, }; - exec_batch(fd, handle, - lri_bad, sizeof(lri_bad), - I915_EXEC_RENDER, - -EINVAL); - exec_batch(fd, handle, - lri_ok, sizeof(lri_ok), - I915_EXEC_RENDER, - 0); + uint32_t store_reg[] = { + MI_STORE_REGISTER_MEM | (3 - 2), + 0, /* reg */ + 0, /* reloc */ + MI_BATCH_BUFFER_END, + }; + uint64_t val; + + /* Note: we intentionally pick OACONTROL as the disallowed + * register to test here since it used to be white listed by + * the command parser. + * + * It's especially important to check that an LRI to OACONTROL + * doesn't result in an EINVAL error because Mesa attempts + * writing to OACONTROL to determine what extensions to expose + * and will abort() for execbuffer() errors. + * + * Mesa can gracefully recognise and handle the LRI becoming + * a NOOP. + */ + exec_batch(fd, handle, + lri_bad, sizeof(lri_bad), + I915_EXEC_RENDER, + 0); + store_reg[1] = OACONTROL; + val = __exec_batch_patched(fd, handle, + store_reg, sizeof(store_reg), + 8); /* reloc offset */ + igt_assert_neq(val, 0x31337000); + + exec_batch(fd, handle, + lri_ok, sizeof(lri_ok), + I915_EXEC_RENDER, + 0); + store_reg[1] = SO_WRITE_OFFSET_0; + exec_batch_patched(fd, handle, + store_reg, + sizeof(store_reg), + 2 * sizeof(uint32_t), /* reloc offset */ + 0xabcdabc0); } igt_subtest("bitmasks") { @@ -491,10 +520,13 @@ igt_main 0, MI_BATCH_BUFFER_END, }; - exec_batch(fd, handle, - pc, sizeof(pc), - I915_EXEC_RENDER, - -EINVAL); + /* Expect to read back zero since the command should be + * squashed to a NOOP + */ + exec_batch_patched(fd, handle, + pc, sizeof(pc), + 8, /* patch offset, */ + 0x0); } igt_subtest("batch-without-end") {