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