1 /*
2 * Copyright © 2016 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "igt.h"
25
26 IGT_TEST_DESCRIPTION("Basic sanity check of execbuf-ioctl rings.");
27
batch_create(int fd)28 static uint32_t batch_create(int fd)
29 {
30 const uint32_t bbe = MI_BATCH_BUFFER_END;
31 uint32_t handle;
32
33 handle = gem_create(fd, 4096);
34 gem_write(fd, handle, 0, &bbe, sizeof(bbe));
35
36 return handle;
37 }
38
batch_fini(int fd,uint32_t handle)39 static void batch_fini(int fd, uint32_t handle)
40 {
41 gem_sync(fd, handle); /* catch any GPU hang */
42 gem_close(fd, handle);
43 }
44
noop(int fd,uint64_t flags)45 static void noop(int fd, uint64_t flags)
46 {
47 struct drm_i915_gem_execbuffer2 execbuf;
48 struct drm_i915_gem_exec_object2 exec;
49
50 gem_require_ring(fd, flags);
51
52 memset(&exec, 0, sizeof(exec));
53
54 exec.handle = batch_create(fd);
55
56 memset(&execbuf, 0, sizeof(execbuf));
57 execbuf.buffers_ptr = to_user_pointer(&exec);
58 execbuf.buffer_count = 1;
59 execbuf.flags = flags;
60 gem_execbuf(fd, &execbuf);
61
62 batch_fini(fd, exec.handle);
63 }
64
readonly(int fd,uint64_t flags)65 static void readonly(int fd, uint64_t flags)
66 {
67 struct drm_i915_gem_execbuffer2 *execbuf;
68 struct drm_i915_gem_exec_object2 exec;
69
70 gem_require_ring(fd, flags);
71
72 memset(&exec, 0, sizeof(exec));
73 exec.handle = batch_create(fd);
74
75 execbuf = mmap(NULL, 4096, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
76 igt_assert(execbuf != NULL);
77
78 execbuf->buffers_ptr = to_user_pointer(&exec);
79 execbuf->buffer_count = 1;
80 execbuf->flags = flags;
81 igt_assert(mprotect(execbuf, 4096, PROT_READ) == 0);
82
83 gem_execbuf(fd, execbuf);
84
85 munmap(execbuf, 4096);
86
87 batch_fini(fd, exec.handle);
88 }
89
gtt(int fd,uint64_t flags)90 static void gtt(int fd, uint64_t flags)
91 {
92 struct drm_i915_gem_execbuffer2 *execbuf;
93 struct drm_i915_gem_exec_object2 *exec;
94 uint32_t handle;
95
96 gem_require_ring(fd, flags);
97
98 handle = gem_create(fd, 4096);
99
100 gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
101 execbuf = gem_mmap__gtt(fd, handle, 4096, PROT_WRITE);
102 exec = (struct drm_i915_gem_exec_object2 *)(execbuf + 1);
103 gem_close(fd, handle);
104
105 exec->handle = batch_create(fd);
106
107 execbuf->buffers_ptr = to_user_pointer(exec);
108 execbuf->buffer_count = 1;
109 execbuf->flags = flags;
110
111 gem_execbuf(fd, execbuf);
112
113 batch_fini(fd, exec->handle);
114 munmap(execbuf, 4096);
115 }
116
all(int i915)117 static void all(int i915)
118 {
119 const struct intel_execution_engine2 *e;
120
121 __for_each_physical_engine(i915, e)
122 noop(i915, e->flags);
123 }
124
readonly_all(int i915)125 static void readonly_all(int i915)
126 {
127 const struct intel_execution_engine2 *e;
128
129 __for_each_physical_engine(i915, e)
130 readonly(i915, e->flags);
131 }
132
gtt_all(int i915)133 static void gtt_all(int i915)
134 {
135 const struct intel_execution_engine2 *e;
136
137 __for_each_physical_engine(i915, e)
138 gtt(i915, e->flags);
139 }
140
141 igt_main
142 {
143 const struct intel_execution_engine2 *e;
144 int fd = -1;
145
146 igt_fixture {
147 fd = drm_open_driver(DRIVER_INTEL);
148 igt_require_gem(fd);
149
150 igt_fork_hang_detector(fd);
151 }
152
153 igt_subtest("basic-all")
154 all(fd);
155
156 igt_subtest("readonly-all")
157 readonly_all(fd);
158
159 igt_subtest("gtt-all")
160 gtt_all(fd);
161
__for_each_physical_engine(fd,e)162 __for_each_physical_engine(fd, e) {
163 igt_subtest_f("basic-%s", e->name)
164 noop(fd, e->flags);
165 igt_subtest_f("readonly-%s", e->name)
166 readonly(fd, e->flags);
167 igt_subtest_f("gtt-%s", e->name)
168 gtt(fd, e->flags);
169 }
170
171 igt_fixture {
172 igt_stop_hang_detector();
173 close(fd);
174 }
175 }
176