From patchwork Fri Jun 15 15:32:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 10466781 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 5AC3A6020F for ; Fri, 15 Jun 2018 15:33:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 49C8028DD2 for ; Fri, 15 Jun 2018 15:33:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3E37B28DF8; Fri, 15 Jun 2018 15:33:05 +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=-5.2 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED 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 CA9A928DD2 for ; Fri, 15 Jun 2018 15:33:04 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 386A86EBBD; Fri, 15 Jun 2018 15:33:04 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from fireflyinternet.com (mail.fireflyinternet.com [109.228.58.192]) by gabe.freedesktop.org (Postfix) with ESMTPS id DC8D96EB6E; Fri, 15 Jun 2018 15:33:01 +0000 (UTC) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.65.138; Received: from haswell.alporthouse.com (unverified [78.156.65.138]) by fireflyinternet.com (Firefly Internet (M1)) with ESMTP id 12060402-1500050 for multiple; Fri, 15 Jun 2018 16:32:50 +0100 Received: by haswell.alporthouse.com (sSMTP sendmail emulation); Fri, 15 Jun 2018 16:32:51 +0100 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Fri, 15 Jun 2018 16:32:49 +0100 Message-Id: <20180615153250.29081-1-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.17.1 MIME-Version: 1.0 X-Originating-IP: 78.156.65.138 X-Country: code=GB country="United Kingdom" ip=78.156.65.138 Subject: [Intel-gfx] [PATCH i-g-t 1/2] igt/gem_userptr: Exercise new PROBE | POPULATE flags X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: igt-dev@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Exercise new API to probe that the userptr range is valid (backed by struct pages and not pfn) or to populate the userptr upon creation (by calling get_user_pages() on the range). Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: MichaƂ Winiarski --- tests/gem_userptr_blits.c | 140 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) diff --git a/tests/gem_userptr_blits.c b/tests/gem_userptr_blits.c index 7e3b6ef38..0c2bdf5b2 100644 --- a/tests/gem_userptr_blits.c +++ b/tests/gem_userptr_blits.c @@ -557,6 +557,140 @@ static int test_invalid_gtt_mapping(int fd) return 0; } +static void store_dword(int fd, uint32_t target, + uint32_t offset, uint32_t value) +{ + const int gen = intel_gen(intel_get_drm_devid(fd)); + struct drm_i915_gem_exec_object2 obj[2]; + struct drm_i915_gem_relocation_entry reloc; + struct drm_i915_gem_execbuffer2 execbuf; + uint32_t batch[16]; + int i; + + memset(&execbuf, 0, sizeof(execbuf)); + execbuf.buffers_ptr = to_user_pointer(obj); + execbuf.buffer_count = ARRAY_SIZE(obj); + execbuf.flags = 0; + if (gen < 6) + execbuf.flags |= I915_EXEC_SECURE; + + memset(obj, 0, sizeof(obj)); + obj[0].handle = target; + obj[1].handle = gem_create(fd, 4096); + + memset(&reloc, 0, sizeof(reloc)); + reloc.target_handle = obj[0].handle; + reloc.presumed_offset = 0; + reloc.offset = sizeof(uint32_t); + reloc.delta = offset; + reloc.read_domains = I915_GEM_DOMAIN_RENDER; + reloc.write_domain = I915_GEM_DOMAIN_RENDER; + obj[1].relocs_ptr = to_user_pointer(&reloc); + obj[1].relocation_count = 1; + + i = 0; + batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0); + if (gen >= 8) { + batch[++i] = offset; + batch[++i] = 0; + } else if (gen >= 4) { + batch[++i] = 0; + batch[++i] = offset; + reloc.offset += sizeof(uint32_t); + } else { + batch[i]--; + batch[++i] = offset; + } + batch[++i] = value; + batch[++i] = MI_BATCH_BUFFER_END; + gem_write(fd, obj[1].handle, 0, batch, sizeof(batch)); + gem_execbuf(fd, &execbuf); + gem_close(fd, obj[1].handle); +} + +#define LOCAL_USERPTR_PROBE 0x2 +#define LOCAL_USERPTR_POPULATE 0x4 +static void test_probe(int fd, unsigned int flags) +{ +#define N_PAGES 5 + struct drm_i915_gem_mmap_gtt mmap_gtt; + uint32_t handle; + + igt_require(__gem_userptr(fd, + (void *)-PAGE_SIZE, 2*PAGE_SIZE, 0, + flags, &handle) == -EFAULT); + + /* + * We allocate 5 pages, and apply various combinations + * of unmap, remap-gtt to the pages. Then we try to + * create a userptr from the middle 3 pages and check + * if unexpectedly succeeds or fails. + */ + memset(&mmap_gtt, 0, sizeof(mmap_gtt)); + mmap_gtt.handle = gem_create(fd, PAGE_SIZE); + drmIoctl(fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &mmap_gtt); + + for (unsigned long pass = 0; pass < 4 * 4 * 4 * 4 *4; pass++) { + int expected = 0; + void *ptr; + + ptr = mmap(NULL, N_PAGES * PAGE_SIZE, + PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, + -1, 0); + + for (int page = 0; page < N_PAGES; page++) { + int mode = (pass >> (2 * page)) & 3; + void *fixed = ptr + page * PAGE_SIZE; + + switch (mode) { + default: + case 0: + break; + + case 1: + munmap(fixed, PAGE_SIZE); + if (page >= 1 && page <= 3) + expected = -EFAULT; + break; + + case 2: + fixed = mmap(fixed, PAGE_SIZE, + PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_FIXED, + fd, mmap_gtt.offset); + igt_assert(fixed != MAP_FAILED); + if (page >= 1 && page <= 3) + expected = -EFAULT; + break; + } + } + + errno = 0; + handle = 0; + igt_assert_eq(__gem_userptr(fd, ptr + PAGE_SIZE, 3*PAGE_SIZE, + 0, flags, &handle), + expected); + if (handle) { + for (int page = 0; page < 3; page++) + store_dword(fd, handle, page*4096, handle); + + gem_sync(fd, handle); + + for (int page = 1; page <= 3; page++) + igt_assert_eq(*(uint32_t *)(ptr + page*PAGE_SIZE), + handle); + + gem_close(fd, handle); + } + + munmap(ptr, N_PAGES * PAGE_SIZE); + } + + gem_close(fd, mmap_gtt.handle); +#undef N_PAGES +} + #define PE_GTT_MAP 0x1 #define PE_BUSY 0x2 static void test_process_exit(int fd, int flags) @@ -1464,6 +1598,12 @@ int main(int argc, char **argv) igt_subtest("invalid-gtt-mapping") test_invalid_gtt_mapping(fd); + igt_subtest("probe") + test_probe(fd, LOCAL_USERPTR_PROBE); + + igt_subtest("populate") + test_probe(fd, LOCAL_USERPTR_POPULATE); + igt_subtest("forked-access") test_forked_access(fd);