110be98a7SChris Wilson /*
210be98a7SChris Wilson * SPDX-License-Identifier: MIT
310be98a7SChris Wilson *
410be98a7SChris Wilson * Copyright © 2016 Intel Corporation
510be98a7SChris Wilson */
610be98a7SChris Wilson
737d63f8fSChris Wilson #include "i915_drv.h"
810be98a7SChris Wilson #include "i915_selftest.h"
9*6427ab57SMatthew Auld #include "gem/i915_gem_context.h"
1010be98a7SChris Wilson
11*6427ab57SMatthew Auld #include "mock_context.h"
1210be98a7SChris Wilson #include "mock_dmabuf.h"
13*6427ab57SMatthew Auld #include "igt_gem_utils.h"
14*6427ab57SMatthew Auld #include "selftests/mock_drm.h"
1510be98a7SChris Wilson #include "selftests/mock_gem_device.h"
1610be98a7SChris Wilson
igt_dmabuf_export(void * arg)1710be98a7SChris Wilson static int igt_dmabuf_export(void *arg)
1810be98a7SChris Wilson {
1910be98a7SChris Wilson struct drm_i915_private *i915 = arg;
2010be98a7SChris Wilson struct drm_i915_gem_object *obj;
2110be98a7SChris Wilson struct dma_buf *dmabuf;
2210be98a7SChris Wilson
2310be98a7SChris Wilson obj = i915_gem_object_create_shmem(i915, PAGE_SIZE);
2410be98a7SChris Wilson if (IS_ERR(obj))
2510be98a7SChris Wilson return PTR_ERR(obj);
2610be98a7SChris Wilson
27d8080976SDaniel Vetter dmabuf = i915_gem_prime_export(&obj->base, 0);
2810be98a7SChris Wilson i915_gem_object_put(obj);
2910be98a7SChris Wilson if (IS_ERR(dmabuf)) {
3010be98a7SChris Wilson pr_err("i915_gem_prime_export failed with err=%d\n",
3110be98a7SChris Wilson (int)PTR_ERR(dmabuf));
3210be98a7SChris Wilson return PTR_ERR(dmabuf);
3310be98a7SChris Wilson }
3410be98a7SChris Wilson
3510be98a7SChris Wilson dma_buf_put(dmabuf);
3610be98a7SChris Wilson return 0;
3710be98a7SChris Wilson }
3810be98a7SChris Wilson
igt_dmabuf_import_self(void * arg)3910be98a7SChris Wilson static int igt_dmabuf_import_self(void *arg)
4010be98a7SChris Wilson {
4110be98a7SChris Wilson struct drm_i915_private *i915 = arg;
42d7b2cb38SThomas Hellström struct drm_i915_gem_object *obj, *import_obj;
4310be98a7SChris Wilson struct drm_gem_object *import;
4410be98a7SChris Wilson struct dma_buf *dmabuf;
4510be98a7SChris Wilson int err;
4610be98a7SChris Wilson
4710be98a7SChris Wilson obj = i915_gem_object_create_shmem(i915, PAGE_SIZE);
4810be98a7SChris Wilson if (IS_ERR(obj))
4910be98a7SChris Wilson return PTR_ERR(obj);
5010be98a7SChris Wilson
51d8080976SDaniel Vetter dmabuf = i915_gem_prime_export(&obj->base, 0);
5210be98a7SChris Wilson if (IS_ERR(dmabuf)) {
5310be98a7SChris Wilson pr_err("i915_gem_prime_export failed with err=%d\n",
5410be98a7SChris Wilson (int)PTR_ERR(dmabuf));
5510be98a7SChris Wilson err = PTR_ERR(dmabuf);
5610be98a7SChris Wilson goto out;
5710be98a7SChris Wilson }
5810be98a7SChris Wilson
5910be98a7SChris Wilson import = i915_gem_prime_import(&i915->drm, dmabuf);
6010be98a7SChris Wilson if (IS_ERR(import)) {
6110be98a7SChris Wilson pr_err("i915_gem_prime_import failed with err=%d\n",
6210be98a7SChris Wilson (int)PTR_ERR(import));
6310be98a7SChris Wilson err = PTR_ERR(import);
6410be98a7SChris Wilson goto out_dmabuf;
6510be98a7SChris Wilson }
664796054bSNathan Chancellor import_obj = to_intel_bo(import);
6710be98a7SChris Wilson
6810be98a7SChris Wilson if (import != &obj->base) {
6910be98a7SChris Wilson pr_err("i915_gem_prime_import created a new object!\n");
7010be98a7SChris Wilson err = -EINVAL;
7110be98a7SChris Wilson goto out_import;
7210be98a7SChris Wilson }
73d7b2cb38SThomas Hellström
74d7b2cb38SThomas Hellström i915_gem_object_lock(import_obj, NULL);
75d7b2cb38SThomas Hellström err = __i915_gem_object_get_pages(import_obj);
76d7b2cb38SThomas Hellström i915_gem_object_unlock(import_obj);
77d7b2cb38SThomas Hellström if (err) {
78d7b2cb38SThomas Hellström pr_err("Same object dma-buf get_pages failed!\n");
79d7b2cb38SThomas Hellström goto out_import;
80d7b2cb38SThomas Hellström }
8110be98a7SChris Wilson
8210be98a7SChris Wilson err = 0;
8310be98a7SChris Wilson out_import:
84d7b2cb38SThomas Hellström i915_gem_object_put(import_obj);
8510be98a7SChris Wilson out_dmabuf:
8610be98a7SChris Wilson dma_buf_put(dmabuf);
8710be98a7SChris Wilson out:
8810be98a7SChris Wilson i915_gem_object_put(obj);
8910be98a7SChris Wilson return err;
9010be98a7SChris Wilson }
9110be98a7SChris Wilson
igt_dmabuf_import_same_driver_lmem(void * arg)92cdb35d1eSThomas Hellström static int igt_dmabuf_import_same_driver_lmem(void *arg)
93d7b2cb38SThomas Hellström {
94d7b2cb38SThomas Hellström struct drm_i915_private *i915 = arg;
95fa732088SAndi Shyti struct intel_memory_region *lmem = i915->mm.regions[INTEL_REGION_LMEM_0];
96cdb35d1eSThomas Hellström struct drm_i915_gem_object *obj;
97cdb35d1eSThomas Hellström struct drm_gem_object *import;
98cdb35d1eSThomas Hellström struct dma_buf *dmabuf;
99cdb35d1eSThomas Hellström int err;
100cdb35d1eSThomas Hellström
101cdb35d1eSThomas Hellström if (!lmem)
102cdb35d1eSThomas Hellström return 0;
103cdb35d1eSThomas Hellström
104cdb35d1eSThomas Hellström force_different_devices = true;
105cdb35d1eSThomas Hellström
106cdb35d1eSThomas Hellström obj = __i915_gem_object_create_user(i915, PAGE_SIZE, &lmem, 1);
107cdb35d1eSThomas Hellström if (IS_ERR(obj)) {
108cdb35d1eSThomas Hellström pr_err("__i915_gem_object_create_user failed with err=%ld\n",
109fc7bf4c0SKai Song PTR_ERR(obj));
110cdb35d1eSThomas Hellström err = PTR_ERR(obj);
111cdb35d1eSThomas Hellström goto out_ret;
112cdb35d1eSThomas Hellström }
113cdb35d1eSThomas Hellström
114cdb35d1eSThomas Hellström dmabuf = i915_gem_prime_export(&obj->base, 0);
115cdb35d1eSThomas Hellström if (IS_ERR(dmabuf)) {
116cdb35d1eSThomas Hellström pr_err("i915_gem_prime_export failed with err=%ld\n",
117cdb35d1eSThomas Hellström PTR_ERR(dmabuf));
118cdb35d1eSThomas Hellström err = PTR_ERR(dmabuf);
119cdb35d1eSThomas Hellström goto out;
120cdb35d1eSThomas Hellström }
121cdb35d1eSThomas Hellström
122cdb35d1eSThomas Hellström /*
123cdb35d1eSThomas Hellström * We expect an import of an LMEM-only object to fail with
124cdb35d1eSThomas Hellström * -EOPNOTSUPP because it can't be migrated to SMEM.
125cdb35d1eSThomas Hellström */
126cdb35d1eSThomas Hellström import = i915_gem_prime_import(&i915->drm, dmabuf);
127cdb35d1eSThomas Hellström if (!IS_ERR(import)) {
128cdb35d1eSThomas Hellström drm_gem_object_put(import);
129cdb35d1eSThomas Hellström pr_err("i915_gem_prime_import succeeded when it shouldn't have\n");
130cdb35d1eSThomas Hellström err = -EINVAL;
131cdb35d1eSThomas Hellström } else if (PTR_ERR(import) != -EOPNOTSUPP) {
132cdb35d1eSThomas Hellström pr_err("i915_gem_prime_import failed with the wrong err=%ld\n",
133cdb35d1eSThomas Hellström PTR_ERR(import));
134cdb35d1eSThomas Hellström err = PTR_ERR(import);
13546f20a35SNathan Chancellor } else {
13646f20a35SNathan Chancellor err = 0;
137cdb35d1eSThomas Hellström }
138cdb35d1eSThomas Hellström
139cdb35d1eSThomas Hellström dma_buf_put(dmabuf);
140cdb35d1eSThomas Hellström out:
141cdb35d1eSThomas Hellström i915_gem_object_put(obj);
142cdb35d1eSThomas Hellström out_ret:
143cdb35d1eSThomas Hellström force_different_devices = false;
144cdb35d1eSThomas Hellström return err;
145cdb35d1eSThomas Hellström }
146cdb35d1eSThomas Hellström
verify_access(struct drm_i915_private * i915,struct drm_i915_gem_object * native_obj,struct drm_i915_gem_object * import_obj)147*6427ab57SMatthew Auld static int verify_access(struct drm_i915_private *i915,
148*6427ab57SMatthew Auld struct drm_i915_gem_object *native_obj,
149*6427ab57SMatthew Auld struct drm_i915_gem_object *import_obj)
150*6427ab57SMatthew Auld {
151*6427ab57SMatthew Auld struct i915_gem_engines_iter it;
152*6427ab57SMatthew Auld struct i915_gem_context *ctx;
153*6427ab57SMatthew Auld struct intel_context *ce;
154*6427ab57SMatthew Auld struct i915_vma *vma;
155*6427ab57SMatthew Auld struct file *file;
156*6427ab57SMatthew Auld u32 *vaddr;
157*6427ab57SMatthew Auld int err = 0, i;
158*6427ab57SMatthew Auld
159*6427ab57SMatthew Auld file = mock_file(i915);
160*6427ab57SMatthew Auld if (IS_ERR(file))
161*6427ab57SMatthew Auld return PTR_ERR(file);
162*6427ab57SMatthew Auld
163*6427ab57SMatthew Auld ctx = live_context(i915, file);
164*6427ab57SMatthew Auld if (IS_ERR(ctx)) {
165*6427ab57SMatthew Auld err = PTR_ERR(ctx);
166*6427ab57SMatthew Auld goto out_file;
167*6427ab57SMatthew Auld }
168*6427ab57SMatthew Auld
169*6427ab57SMatthew Auld for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
170*6427ab57SMatthew Auld if (intel_engine_can_store_dword(ce->engine))
171*6427ab57SMatthew Auld break;
172*6427ab57SMatthew Auld }
173*6427ab57SMatthew Auld i915_gem_context_unlock_engines(ctx);
174*6427ab57SMatthew Auld if (!ce)
175*6427ab57SMatthew Auld goto out_file;
176*6427ab57SMatthew Auld
177*6427ab57SMatthew Auld vma = i915_vma_instance(import_obj, ce->vm, NULL);
178*6427ab57SMatthew Auld if (IS_ERR(vma)) {
179*6427ab57SMatthew Auld err = PTR_ERR(vma);
180*6427ab57SMatthew Auld goto out_file;
181*6427ab57SMatthew Auld }
182*6427ab57SMatthew Auld
183*6427ab57SMatthew Auld err = i915_vma_pin(vma, 0, 0, PIN_USER);
184*6427ab57SMatthew Auld if (err)
185*6427ab57SMatthew Auld goto out_file;
186*6427ab57SMatthew Auld
187*6427ab57SMatthew Auld err = igt_gpu_fill_dw(ce, vma, 0,
188*6427ab57SMatthew Auld vma->size >> PAGE_SHIFT, 0xdeadbeaf);
189*6427ab57SMatthew Auld i915_vma_unpin(vma);
190*6427ab57SMatthew Auld if (err)
191*6427ab57SMatthew Auld goto out_file;
192*6427ab57SMatthew Auld
193*6427ab57SMatthew Auld err = i915_gem_object_wait(import_obj, 0, MAX_SCHEDULE_TIMEOUT);
194*6427ab57SMatthew Auld if (err)
195*6427ab57SMatthew Auld goto out_file;
196*6427ab57SMatthew Auld
197*6427ab57SMatthew Auld vaddr = i915_gem_object_pin_map_unlocked(native_obj, I915_MAP_WB);
198*6427ab57SMatthew Auld if (IS_ERR(vaddr)) {
199*6427ab57SMatthew Auld err = PTR_ERR(vaddr);
200*6427ab57SMatthew Auld goto out_file;
201*6427ab57SMatthew Auld }
202*6427ab57SMatthew Auld
203*6427ab57SMatthew Auld for (i = 0; i < native_obj->base.size / sizeof(u32); i += PAGE_SIZE / sizeof(u32)) {
204*6427ab57SMatthew Auld if (vaddr[i] != 0xdeadbeaf) {
205*6427ab57SMatthew Auld pr_err("Data mismatch [%d]=%u\n", i, vaddr[i]);
206*6427ab57SMatthew Auld err = -EINVAL;
207*6427ab57SMatthew Auld goto out_file;
208*6427ab57SMatthew Auld }
209*6427ab57SMatthew Auld }
210*6427ab57SMatthew Auld
211*6427ab57SMatthew Auld out_file:
212*6427ab57SMatthew Auld fput(file);
213*6427ab57SMatthew Auld return err;
214*6427ab57SMatthew Auld }
215*6427ab57SMatthew Auld
igt_dmabuf_import_same_driver(struct drm_i915_private * i915,struct intel_memory_region ** regions,unsigned int num_regions)216cdb35d1eSThomas Hellström static int igt_dmabuf_import_same_driver(struct drm_i915_private *i915,
217cdb35d1eSThomas Hellström struct intel_memory_region **regions,
218cdb35d1eSThomas Hellström unsigned int num_regions)
219cdb35d1eSThomas Hellström {
220d7b2cb38SThomas Hellström struct drm_i915_gem_object *obj, *import_obj;
221d7b2cb38SThomas Hellström struct drm_gem_object *import;
222d7b2cb38SThomas Hellström struct dma_buf *dmabuf;
223d7b2cb38SThomas Hellström struct dma_buf_attachment *import_attach;
224d7b2cb38SThomas Hellström struct sg_table *st;
225d7b2cb38SThomas Hellström long timeout;
226d7b2cb38SThomas Hellström int err;
227d7b2cb38SThomas Hellström
228d7b2cb38SThomas Hellström force_different_devices = true;
229cdb35d1eSThomas Hellström
230*6427ab57SMatthew Auld obj = __i915_gem_object_create_user(i915, SZ_8M,
231cdb35d1eSThomas Hellström regions, num_regions);
232d7b2cb38SThomas Hellström if (IS_ERR(obj)) {
233cdb35d1eSThomas Hellström pr_err("__i915_gem_object_create_user failed with err=%ld\n",
234fc7bf4c0SKai Song PTR_ERR(obj));
235d7b2cb38SThomas Hellström err = PTR_ERR(obj);
236d7b2cb38SThomas Hellström goto out_ret;
237d7b2cb38SThomas Hellström }
238d7b2cb38SThomas Hellström
239d7b2cb38SThomas Hellström dmabuf = i915_gem_prime_export(&obj->base, 0);
240d7b2cb38SThomas Hellström if (IS_ERR(dmabuf)) {
241d7b2cb38SThomas Hellström pr_err("i915_gem_prime_export failed with err=%ld\n",
242d7b2cb38SThomas Hellström PTR_ERR(dmabuf));
243d7b2cb38SThomas Hellström err = PTR_ERR(dmabuf);
244d7b2cb38SThomas Hellström goto out;
245d7b2cb38SThomas Hellström }
246d7b2cb38SThomas Hellström
247d7b2cb38SThomas Hellström import = i915_gem_prime_import(&i915->drm, dmabuf);
248d7b2cb38SThomas Hellström if (IS_ERR(import)) {
249d7b2cb38SThomas Hellström pr_err("i915_gem_prime_import failed with err=%ld\n",
250d7b2cb38SThomas Hellström PTR_ERR(import));
251d7b2cb38SThomas Hellström err = PTR_ERR(import);
252d7b2cb38SThomas Hellström goto out_dmabuf;
253d7b2cb38SThomas Hellström }
2544796054bSNathan Chancellor import_obj = to_intel_bo(import);
255d7b2cb38SThomas Hellström
256d7b2cb38SThomas Hellström if (import == &obj->base) {
257d7b2cb38SThomas Hellström pr_err("i915_gem_prime_import reused gem object!\n");
258d7b2cb38SThomas Hellström err = -EINVAL;
259d7b2cb38SThomas Hellström goto out_import;
260d7b2cb38SThomas Hellström }
261d7b2cb38SThomas Hellström
262d7b2cb38SThomas Hellström i915_gem_object_lock(import_obj, NULL);
263d7b2cb38SThomas Hellström err = __i915_gem_object_get_pages(import_obj);
264d7b2cb38SThomas Hellström if (err) {
265d7b2cb38SThomas Hellström pr_err("Different objects dma-buf get_pages failed!\n");
266d7b2cb38SThomas Hellström i915_gem_object_unlock(import_obj);
267d7b2cb38SThomas Hellström goto out_import;
268d7b2cb38SThomas Hellström }
269d7b2cb38SThomas Hellström
270d7b2cb38SThomas Hellström /*
271d7b2cb38SThomas Hellström * If the exported object is not in system memory, something
272d7b2cb38SThomas Hellström * weird is going on. TODO: When p2p is supported, this is no
273d7b2cb38SThomas Hellström * longer considered weird.
274d7b2cb38SThomas Hellström */
275d7b2cb38SThomas Hellström if (obj->mm.region != i915->mm.regions[INTEL_REGION_SMEM]) {
276d7b2cb38SThomas Hellström pr_err("Exported dma-buf is not in system memory\n");
277d7b2cb38SThomas Hellström err = -EINVAL;
278d7b2cb38SThomas Hellström }
279d7b2cb38SThomas Hellström
280d7b2cb38SThomas Hellström i915_gem_object_unlock(import_obj);
281d7b2cb38SThomas Hellström
282*6427ab57SMatthew Auld err = verify_access(i915, obj, import_obj);
283*6427ab57SMatthew Auld if (err)
284*6427ab57SMatthew Auld goto out_import;
285*6427ab57SMatthew Auld
286d7b2cb38SThomas Hellström /* Now try a fake an importer */
287d7b2cb38SThomas Hellström import_attach = dma_buf_attach(dmabuf, obj->base.dev->dev);
288d7b2cb38SThomas Hellström if (IS_ERR(import_attach)) {
289d7b2cb38SThomas Hellström err = PTR_ERR(import_attach);
290d7b2cb38SThomas Hellström goto out_import;
291d7b2cb38SThomas Hellström }
292d7b2cb38SThomas Hellström
293d7b2cb38SThomas Hellström st = dma_buf_map_attachment_unlocked(import_attach, DMA_BIDIRECTIONAL);
294d7b2cb38SThomas Hellström if (IS_ERR(st)) {
295d7b2cb38SThomas Hellström err = PTR_ERR(st);
296d7b2cb38SThomas Hellström goto out_detach;
297d7b2cb38SThomas Hellström }
298d7b2cb38SThomas Hellström
2997bc80a54SChristian König timeout = dma_resv_wait_timeout(dmabuf->resv, DMA_RESV_USAGE_WRITE,
3007bc80a54SChristian König true, 5 * HZ);
301d7b2cb38SThomas Hellström if (!timeout) {
302d7b2cb38SThomas Hellström pr_err("dmabuf wait for exclusive fence timed out.\n");
303d7b2cb38SThomas Hellström timeout = -ETIME;
304d7b2cb38SThomas Hellström }
305d7b2cb38SThomas Hellström err = timeout > 0 ? 0 : timeout;
306d7b2cb38SThomas Hellström dma_buf_unmap_attachment_unlocked(import_attach, st, DMA_BIDIRECTIONAL);
307d7b2cb38SThomas Hellström out_detach:
308d7b2cb38SThomas Hellström dma_buf_detach(dmabuf, import_attach);
309d7b2cb38SThomas Hellström out_import:
310d7b2cb38SThomas Hellström i915_gem_object_put(import_obj);
311d7b2cb38SThomas Hellström out_dmabuf:
312d7b2cb38SThomas Hellström dma_buf_put(dmabuf);
313d7b2cb38SThomas Hellström out:
314d7b2cb38SThomas Hellström i915_gem_object_put(obj);
315d7b2cb38SThomas Hellström out_ret:
316d7b2cb38SThomas Hellström force_different_devices = false;
317d7b2cb38SThomas Hellström return err;
318d7b2cb38SThomas Hellström }
319d7b2cb38SThomas Hellström
igt_dmabuf_import_same_driver_smem(void * arg)320cdb35d1eSThomas Hellström static int igt_dmabuf_import_same_driver_smem(void *arg)
321cdb35d1eSThomas Hellström {
322cdb35d1eSThomas Hellström struct drm_i915_private *i915 = arg;
323cdb35d1eSThomas Hellström struct intel_memory_region *smem = i915->mm.regions[INTEL_REGION_SMEM];
324cdb35d1eSThomas Hellström
325cdb35d1eSThomas Hellström return igt_dmabuf_import_same_driver(i915, &smem, 1);
326cdb35d1eSThomas Hellström }
327cdb35d1eSThomas Hellström
igt_dmabuf_import_same_driver_lmem_smem(void * arg)328cdb35d1eSThomas Hellström static int igt_dmabuf_import_same_driver_lmem_smem(void *arg)
329cdb35d1eSThomas Hellström {
330cdb35d1eSThomas Hellström struct drm_i915_private *i915 = arg;
331cdb35d1eSThomas Hellström struct intel_memory_region *regions[2];
332cdb35d1eSThomas Hellström
333fa732088SAndi Shyti if (!i915->mm.regions[INTEL_REGION_LMEM_0])
334cdb35d1eSThomas Hellström return 0;
335cdb35d1eSThomas Hellström
336fa732088SAndi Shyti regions[0] = i915->mm.regions[INTEL_REGION_LMEM_0];
337cdb35d1eSThomas Hellström regions[1] = i915->mm.regions[INTEL_REGION_SMEM];
338cdb35d1eSThomas Hellström return igt_dmabuf_import_same_driver(i915, regions, 2);
339cdb35d1eSThomas Hellström }
340cdb35d1eSThomas Hellström
igt_dmabuf_import(void * arg)34110be98a7SChris Wilson static int igt_dmabuf_import(void *arg)
34210be98a7SChris Wilson {
34310be98a7SChris Wilson struct drm_i915_private *i915 = arg;
34410be98a7SChris Wilson struct drm_i915_gem_object *obj;
34510be98a7SChris Wilson struct dma_buf *dmabuf;
34610be98a7SChris Wilson void *obj_map, *dma_map;
3477938f421SLucas De Marchi struct iosys_map map;
34810be98a7SChris Wilson u32 pattern[] = { 0, 0xaa, 0xcc, 0x55, 0xff };
34910be98a7SChris Wilson int err, i;
35010be98a7SChris Wilson
35110be98a7SChris Wilson dmabuf = mock_dmabuf(1);
35210be98a7SChris Wilson if (IS_ERR(dmabuf))
35310be98a7SChris Wilson return PTR_ERR(dmabuf);
35410be98a7SChris Wilson
35510be98a7SChris Wilson obj = to_intel_bo(i915_gem_prime_import(&i915->drm, dmabuf));
35610be98a7SChris Wilson if (IS_ERR(obj)) {
35710be98a7SChris Wilson pr_err("i915_gem_prime_import failed with err=%d\n",
35810be98a7SChris Wilson (int)PTR_ERR(obj));
35910be98a7SChris Wilson err = PTR_ERR(obj);
36010be98a7SChris Wilson goto out_dmabuf;
36110be98a7SChris Wilson }
36210be98a7SChris Wilson
36310be98a7SChris Wilson if (obj->base.dev != &i915->drm) {
36410be98a7SChris Wilson pr_err("i915_gem_prime_import created a non-i915 object!\n");
36510be98a7SChris Wilson err = -EINVAL;
36610be98a7SChris Wilson goto out_obj;
36710be98a7SChris Wilson }
36810be98a7SChris Wilson
36910be98a7SChris Wilson if (obj->base.size != PAGE_SIZE) {
37010be98a7SChris Wilson pr_err("i915_gem_prime_import is wrong size found %lld, expected %ld\n",
37110be98a7SChris Wilson (long long)obj->base.size, PAGE_SIZE);
37210be98a7SChris Wilson err = -EINVAL;
37310be98a7SChris Wilson goto out_obj;
37410be98a7SChris Wilson }
37510be98a7SChris Wilson
3766619ccf1SThomas Zimmermann err = dma_buf_vmap_unlocked(dmabuf, &map);
3776619ccf1SThomas Zimmermann dma_map = err ? NULL : map.vaddr;
37810be98a7SChris Wilson if (!dma_map) {
37910be98a7SChris Wilson pr_err("dma_buf_vmap failed\n");
38010be98a7SChris Wilson err = -ENOMEM;
38110be98a7SChris Wilson goto out_obj;
38210be98a7SChris Wilson }
38310be98a7SChris Wilson
38410be98a7SChris Wilson if (0) { /* Can not yet map dmabuf */
38510be98a7SChris Wilson obj_map = i915_gem_object_pin_map(obj, I915_MAP_WB);
38610be98a7SChris Wilson if (IS_ERR(obj_map)) {
38710be98a7SChris Wilson err = PTR_ERR(obj_map);
38810be98a7SChris Wilson pr_err("i915_gem_object_pin_map failed with err=%d\n", err);
38910be98a7SChris Wilson goto out_dma_map;
39010be98a7SChris Wilson }
39110be98a7SChris Wilson
39210be98a7SChris Wilson for (i = 0; i < ARRAY_SIZE(pattern); i++) {
39310be98a7SChris Wilson memset(dma_map, pattern[i], PAGE_SIZE);
39410be98a7SChris Wilson if (memchr_inv(obj_map, pattern[i], PAGE_SIZE)) {
39510be98a7SChris Wilson err = -EINVAL;
39610be98a7SChris Wilson pr_err("imported vmap not all set to %x!\n", pattern[i]);
39710be98a7SChris Wilson i915_gem_object_unpin_map(obj);
39810be98a7SChris Wilson goto out_dma_map;
39910be98a7SChris Wilson }
40010be98a7SChris Wilson }
40110be98a7SChris Wilson
40210be98a7SChris Wilson for (i = 0; i < ARRAY_SIZE(pattern); i++) {
40310be98a7SChris Wilson memset(obj_map, pattern[i], PAGE_SIZE);
40410be98a7SChris Wilson if (memchr_inv(dma_map, pattern[i], PAGE_SIZE)) {
40510be98a7SChris Wilson err = -EINVAL;
40610be98a7SChris Wilson pr_err("exported vmap not all set to %x!\n", pattern[i]);
40710be98a7SChris Wilson i915_gem_object_unpin_map(obj);
40810be98a7SChris Wilson goto out_dma_map;
40910be98a7SChris Wilson }
41010be98a7SChris Wilson }
41110be98a7SChris Wilson
41210be98a7SChris Wilson i915_gem_object_unpin_map(obj);
41310be98a7SChris Wilson }
41410be98a7SChris Wilson
41510be98a7SChris Wilson err = 0;
41610be98a7SChris Wilson out_dma_map:
41720e76f1aSThomas Zimmermann dma_buf_vunmap_unlocked(dmabuf, &map);
41810be98a7SChris Wilson out_obj:
41910be98a7SChris Wilson i915_gem_object_put(obj);
42010be98a7SChris Wilson out_dmabuf:
42110be98a7SChris Wilson dma_buf_put(dmabuf);
42210be98a7SChris Wilson return err;
42310be98a7SChris Wilson }
42410be98a7SChris Wilson
igt_dmabuf_import_ownership(void * arg)42510be98a7SChris Wilson static int igt_dmabuf_import_ownership(void *arg)
42610be98a7SChris Wilson {
42710be98a7SChris Wilson struct drm_i915_private *i915 = arg;
42810be98a7SChris Wilson struct drm_i915_gem_object *obj;
42910be98a7SChris Wilson struct dma_buf *dmabuf;
4307938f421SLucas De Marchi struct iosys_map map;
43110be98a7SChris Wilson void *ptr;
43210be98a7SChris Wilson int err;
43310be98a7SChris Wilson
43410be98a7SChris Wilson dmabuf = mock_dmabuf(1);
43510be98a7SChris Wilson if (IS_ERR(dmabuf))
43610be98a7SChris Wilson return PTR_ERR(dmabuf);
43710be98a7SChris Wilson
4386619ccf1SThomas Zimmermann err = dma_buf_vmap_unlocked(dmabuf, &map);
4396619ccf1SThomas Zimmermann ptr = err ? NULL : map.vaddr;
44010be98a7SChris Wilson if (!ptr) {
44110be98a7SChris Wilson pr_err("dma_buf_vmap failed\n");
44210be98a7SChris Wilson err = -ENOMEM;
44310be98a7SChris Wilson goto err_dmabuf;
44410be98a7SChris Wilson }
44510be98a7SChris Wilson
44610be98a7SChris Wilson memset(ptr, 0xc5, PAGE_SIZE);
44720e76f1aSThomas Zimmermann dma_buf_vunmap_unlocked(dmabuf, &map);
44810be98a7SChris Wilson
44910be98a7SChris Wilson obj = to_intel_bo(i915_gem_prime_import(&i915->drm, dmabuf));
45010be98a7SChris Wilson if (IS_ERR(obj)) {
45110be98a7SChris Wilson pr_err("i915_gem_prime_import failed with err=%d\n",
45210be98a7SChris Wilson (int)PTR_ERR(obj));
45310be98a7SChris Wilson err = PTR_ERR(obj);
45410be98a7SChris Wilson goto err_dmabuf;
45510be98a7SChris Wilson }
45610be98a7SChris Wilson
45710be98a7SChris Wilson dma_buf_put(dmabuf);
45810be98a7SChris Wilson
459e3729844SMaarten Lankhorst err = i915_gem_object_pin_pages_unlocked(obj);
46010be98a7SChris Wilson if (err) {
46110be98a7SChris Wilson pr_err("i915_gem_object_pin_pages failed with err=%d\n", err);
46210be98a7SChris Wilson goto out_obj;
46310be98a7SChris Wilson }
46410be98a7SChris Wilson
46510be98a7SChris Wilson err = 0;
46610be98a7SChris Wilson i915_gem_object_unpin_pages(obj);
46710be98a7SChris Wilson out_obj:
46810be98a7SChris Wilson i915_gem_object_put(obj);
46910be98a7SChris Wilson return err;
47010be98a7SChris Wilson
47110be98a7SChris Wilson err_dmabuf:
47210be98a7SChris Wilson dma_buf_put(dmabuf);
47310be98a7SChris Wilson return err;
47410be98a7SChris Wilson }
47510be98a7SChris Wilson
igt_dmabuf_export_vmap(void * arg)47610be98a7SChris Wilson static int igt_dmabuf_export_vmap(void *arg)
47710be98a7SChris Wilson {
47810be98a7SChris Wilson struct drm_i915_private *i915 = arg;
47910be98a7SChris Wilson struct drm_i915_gem_object *obj;
48010be98a7SChris Wilson struct dma_buf *dmabuf;
4817938f421SLucas De Marchi struct iosys_map map;
48210be98a7SChris Wilson void *ptr;
48310be98a7SChris Wilson int err;
48410be98a7SChris Wilson
48510be98a7SChris Wilson obj = i915_gem_object_create_shmem(i915, PAGE_SIZE);
48610be98a7SChris Wilson if (IS_ERR(obj))
48710be98a7SChris Wilson return PTR_ERR(obj);
48810be98a7SChris Wilson
489d8080976SDaniel Vetter dmabuf = i915_gem_prime_export(&obj->base, 0);
49010be98a7SChris Wilson if (IS_ERR(dmabuf)) {
49110be98a7SChris Wilson pr_err("i915_gem_prime_export failed with err=%d\n",
49210be98a7SChris Wilson (int)PTR_ERR(dmabuf));
49310be98a7SChris Wilson err = PTR_ERR(dmabuf);
49410be98a7SChris Wilson goto err_obj;
49510be98a7SChris Wilson }
49610be98a7SChris Wilson i915_gem_object_put(obj);
49710be98a7SChris Wilson
4986619ccf1SThomas Zimmermann err = dma_buf_vmap_unlocked(dmabuf, &map);
4996619ccf1SThomas Zimmermann ptr = err ? NULL : map.vaddr;
50010be98a7SChris Wilson if (!ptr) {
50110be98a7SChris Wilson pr_err("dma_buf_vmap failed\n");
50210be98a7SChris Wilson err = -ENOMEM;
50310be98a7SChris Wilson goto out;
50410be98a7SChris Wilson }
50510be98a7SChris Wilson
50610be98a7SChris Wilson if (memchr_inv(ptr, 0, dmabuf->size)) {
50710be98a7SChris Wilson pr_err("Exported object not initialiased to zero!\n");
50810be98a7SChris Wilson err = -EINVAL;
50910be98a7SChris Wilson goto out;
51010be98a7SChris Wilson }
51110be98a7SChris Wilson
51210be98a7SChris Wilson memset(ptr, 0xc5, dmabuf->size);
51310be98a7SChris Wilson
51410be98a7SChris Wilson err = 0;
51520e76f1aSThomas Zimmermann dma_buf_vunmap_unlocked(dmabuf, &map);
51610be98a7SChris Wilson out:
51710be98a7SChris Wilson dma_buf_put(dmabuf);
51810be98a7SChris Wilson return err;
51910be98a7SChris Wilson
52010be98a7SChris Wilson err_obj:
52110be98a7SChris Wilson i915_gem_object_put(obj);
52210be98a7SChris Wilson return err;
52310be98a7SChris Wilson }
52410be98a7SChris Wilson
i915_gem_dmabuf_mock_selftests(void)52510be98a7SChris Wilson int i915_gem_dmabuf_mock_selftests(void)
52610be98a7SChris Wilson {
52710be98a7SChris Wilson static const struct i915_subtest tests[] = {
52810be98a7SChris Wilson SUBTEST(igt_dmabuf_export),
52910be98a7SChris Wilson SUBTEST(igt_dmabuf_import_self),
53010be98a7SChris Wilson SUBTEST(igt_dmabuf_import),
53110be98a7SChris Wilson SUBTEST(igt_dmabuf_import_ownership),
53210be98a7SChris Wilson SUBTEST(igt_dmabuf_export_vmap),
53310be98a7SChris Wilson };
53410be98a7SChris Wilson struct drm_i915_private *i915;
53510be98a7SChris Wilson int err;
53610be98a7SChris Wilson
53710be98a7SChris Wilson i915 = mock_gem_device();
53810be98a7SChris Wilson if (!i915)
53910be98a7SChris Wilson return -ENOMEM;
54010be98a7SChris Wilson
54110be98a7SChris Wilson err = i915_subtests(tests, i915);
54210be98a7SChris Wilson
54382be0d75SDaniel Vetter mock_destroy_device(i915);
54410be98a7SChris Wilson return err;
54510be98a7SChris Wilson }
54610be98a7SChris Wilson
i915_gem_dmabuf_live_selftests(struct drm_i915_private * i915)54710be98a7SChris Wilson int i915_gem_dmabuf_live_selftests(struct drm_i915_private *i915)
54810be98a7SChris Wilson {
54910be98a7SChris Wilson static const struct i915_subtest tests[] = {
55010be98a7SChris Wilson SUBTEST(igt_dmabuf_export),
551cdb35d1eSThomas Hellström SUBTEST(igt_dmabuf_import_same_driver_lmem),
552cdb35d1eSThomas Hellström SUBTEST(igt_dmabuf_import_same_driver_smem),
553cdb35d1eSThomas Hellström SUBTEST(igt_dmabuf_import_same_driver_lmem_smem),
55410be98a7SChris Wilson };
55510be98a7SChris Wilson
55661faec5fSMatthew Brost return i915_live_subtests(tests, i915);
55710be98a7SChris Wilson }
558