Loading...
Note: File does not exist in v3.1.
1/*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright © 2016 Intel Corporation
5 */
6
7#include "i915_drv.h"
8#include "i915_selftest.h"
9
10#include "mock_dmabuf.h"
11#include "selftests/mock_gem_device.h"
12
13static int igt_dmabuf_export(void *arg)
14{
15 struct drm_i915_private *i915 = arg;
16 struct drm_i915_gem_object *obj;
17 struct dma_buf *dmabuf;
18
19 obj = i915_gem_object_create_shmem(i915, PAGE_SIZE);
20 if (IS_ERR(obj))
21 return PTR_ERR(obj);
22
23 dmabuf = i915_gem_prime_export(&obj->base, 0);
24 i915_gem_object_put(obj);
25 if (IS_ERR(dmabuf)) {
26 pr_err("i915_gem_prime_export failed with err=%d\n",
27 (int)PTR_ERR(dmabuf));
28 return PTR_ERR(dmabuf);
29 }
30
31 dma_buf_put(dmabuf);
32 return 0;
33}
34
35static int igt_dmabuf_import_self(void *arg)
36{
37 struct drm_i915_private *i915 = arg;
38 struct drm_i915_gem_object *obj;
39 struct drm_gem_object *import;
40 struct dma_buf *dmabuf;
41 int err;
42
43 obj = i915_gem_object_create_shmem(i915, PAGE_SIZE);
44 if (IS_ERR(obj))
45 return PTR_ERR(obj);
46
47 dmabuf = i915_gem_prime_export(&obj->base, 0);
48 if (IS_ERR(dmabuf)) {
49 pr_err("i915_gem_prime_export failed with err=%d\n",
50 (int)PTR_ERR(dmabuf));
51 err = PTR_ERR(dmabuf);
52 goto out;
53 }
54
55 import = i915_gem_prime_import(&i915->drm, dmabuf);
56 if (IS_ERR(import)) {
57 pr_err("i915_gem_prime_import failed with err=%d\n",
58 (int)PTR_ERR(import));
59 err = PTR_ERR(import);
60 goto out_dmabuf;
61 }
62
63 if (import != &obj->base) {
64 pr_err("i915_gem_prime_import created a new object!\n");
65 err = -EINVAL;
66 goto out_import;
67 }
68
69 err = 0;
70out_import:
71 i915_gem_object_put(to_intel_bo(import));
72out_dmabuf:
73 dma_buf_put(dmabuf);
74out:
75 i915_gem_object_put(obj);
76 return err;
77}
78
79static int igt_dmabuf_import(void *arg)
80{
81 struct drm_i915_private *i915 = arg;
82 struct drm_i915_gem_object *obj;
83 struct dma_buf *dmabuf;
84 void *obj_map, *dma_map;
85 struct dma_buf_map map;
86 u32 pattern[] = { 0, 0xaa, 0xcc, 0x55, 0xff };
87 int err, i;
88
89 dmabuf = mock_dmabuf(1);
90 if (IS_ERR(dmabuf))
91 return PTR_ERR(dmabuf);
92
93 obj = to_intel_bo(i915_gem_prime_import(&i915->drm, dmabuf));
94 if (IS_ERR(obj)) {
95 pr_err("i915_gem_prime_import failed with err=%d\n",
96 (int)PTR_ERR(obj));
97 err = PTR_ERR(obj);
98 goto out_dmabuf;
99 }
100
101 if (obj->base.dev != &i915->drm) {
102 pr_err("i915_gem_prime_import created a non-i915 object!\n");
103 err = -EINVAL;
104 goto out_obj;
105 }
106
107 if (obj->base.size != PAGE_SIZE) {
108 pr_err("i915_gem_prime_import is wrong size found %lld, expected %ld\n",
109 (long long)obj->base.size, PAGE_SIZE);
110 err = -EINVAL;
111 goto out_obj;
112 }
113
114 err = dma_buf_vmap(dmabuf, &map);
115 dma_map = err ? NULL : map.vaddr;
116 if (!dma_map) {
117 pr_err("dma_buf_vmap failed\n");
118 err = -ENOMEM;
119 goto out_obj;
120 }
121
122 if (0) { /* Can not yet map dmabuf */
123 obj_map = i915_gem_object_pin_map(obj, I915_MAP_WB);
124 if (IS_ERR(obj_map)) {
125 err = PTR_ERR(obj_map);
126 pr_err("i915_gem_object_pin_map failed with err=%d\n", err);
127 goto out_dma_map;
128 }
129
130 for (i = 0; i < ARRAY_SIZE(pattern); i++) {
131 memset(dma_map, pattern[i], PAGE_SIZE);
132 if (memchr_inv(obj_map, pattern[i], PAGE_SIZE)) {
133 err = -EINVAL;
134 pr_err("imported vmap not all set to %x!\n", pattern[i]);
135 i915_gem_object_unpin_map(obj);
136 goto out_dma_map;
137 }
138 }
139
140 for (i = 0; i < ARRAY_SIZE(pattern); i++) {
141 memset(obj_map, pattern[i], PAGE_SIZE);
142 if (memchr_inv(dma_map, pattern[i], PAGE_SIZE)) {
143 err = -EINVAL;
144 pr_err("exported vmap not all set to %x!\n", pattern[i]);
145 i915_gem_object_unpin_map(obj);
146 goto out_dma_map;
147 }
148 }
149
150 i915_gem_object_unpin_map(obj);
151 }
152
153 err = 0;
154out_dma_map:
155 dma_buf_vunmap(dmabuf, &map);
156out_obj:
157 i915_gem_object_put(obj);
158out_dmabuf:
159 dma_buf_put(dmabuf);
160 return err;
161}
162
163static int igt_dmabuf_import_ownership(void *arg)
164{
165 struct drm_i915_private *i915 = arg;
166 struct drm_i915_gem_object *obj;
167 struct dma_buf *dmabuf;
168 struct dma_buf_map map;
169 void *ptr;
170 int err;
171
172 dmabuf = mock_dmabuf(1);
173 if (IS_ERR(dmabuf))
174 return PTR_ERR(dmabuf);
175
176 err = dma_buf_vmap(dmabuf, &map);
177 ptr = err ? NULL : map.vaddr;
178 if (!ptr) {
179 pr_err("dma_buf_vmap failed\n");
180 err = -ENOMEM;
181 goto err_dmabuf;
182 }
183
184 memset(ptr, 0xc5, PAGE_SIZE);
185 dma_buf_vunmap(dmabuf, &map);
186
187 obj = to_intel_bo(i915_gem_prime_import(&i915->drm, dmabuf));
188 if (IS_ERR(obj)) {
189 pr_err("i915_gem_prime_import failed with err=%d\n",
190 (int)PTR_ERR(obj));
191 err = PTR_ERR(obj);
192 goto err_dmabuf;
193 }
194
195 dma_buf_put(dmabuf);
196
197 err = i915_gem_object_pin_pages_unlocked(obj);
198 if (err) {
199 pr_err("i915_gem_object_pin_pages failed with err=%d\n", err);
200 goto out_obj;
201 }
202
203 err = 0;
204 i915_gem_object_unpin_pages(obj);
205out_obj:
206 i915_gem_object_put(obj);
207 return err;
208
209err_dmabuf:
210 dma_buf_put(dmabuf);
211 return err;
212}
213
214static int igt_dmabuf_export_vmap(void *arg)
215{
216 struct drm_i915_private *i915 = arg;
217 struct drm_i915_gem_object *obj;
218 struct dma_buf *dmabuf;
219 struct dma_buf_map map;
220 void *ptr;
221 int err;
222
223 obj = i915_gem_object_create_shmem(i915, PAGE_SIZE);
224 if (IS_ERR(obj))
225 return PTR_ERR(obj);
226
227 dmabuf = i915_gem_prime_export(&obj->base, 0);
228 if (IS_ERR(dmabuf)) {
229 pr_err("i915_gem_prime_export failed with err=%d\n",
230 (int)PTR_ERR(dmabuf));
231 err = PTR_ERR(dmabuf);
232 goto err_obj;
233 }
234 i915_gem_object_put(obj);
235
236 err = dma_buf_vmap(dmabuf, &map);
237 ptr = err ? NULL : map.vaddr;
238 if (!ptr) {
239 pr_err("dma_buf_vmap failed\n");
240 err = -ENOMEM;
241 goto out;
242 }
243
244 if (memchr_inv(ptr, 0, dmabuf->size)) {
245 pr_err("Exported object not initialiased to zero!\n");
246 err = -EINVAL;
247 goto out;
248 }
249
250 memset(ptr, 0xc5, dmabuf->size);
251
252 err = 0;
253 dma_buf_vunmap(dmabuf, &map);
254out:
255 dma_buf_put(dmabuf);
256 return err;
257
258err_obj:
259 i915_gem_object_put(obj);
260 return err;
261}
262
263int i915_gem_dmabuf_mock_selftests(void)
264{
265 static const struct i915_subtest tests[] = {
266 SUBTEST(igt_dmabuf_export),
267 SUBTEST(igt_dmabuf_import_self),
268 SUBTEST(igt_dmabuf_import),
269 SUBTEST(igt_dmabuf_import_ownership),
270 SUBTEST(igt_dmabuf_export_vmap),
271 };
272 struct drm_i915_private *i915;
273 int err;
274
275 i915 = mock_gem_device();
276 if (!i915)
277 return -ENOMEM;
278
279 err = i915_subtests(tests, i915);
280
281 mock_destroy_device(i915);
282 return err;
283}
284
285int i915_gem_dmabuf_live_selftests(struct drm_i915_private *i915)
286{
287 static const struct i915_subtest tests[] = {
288 SUBTEST(igt_dmabuf_export),
289 };
290
291 return i915_subtests(tests, i915);
292}