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