Linux Audio

Check our new training course

Linux BSP development engineering services

Need help to port Linux and bootloaders to your hardware?
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}