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 13 static 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 35 static 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; 70 out_import: 71 i915_gem_object_put(to_intel_bo(import)); 72 out_dmabuf: 73 dma_buf_put(dmabuf); 74 out: 75 i915_gem_object_put(obj); 76 return err; 77 } 78 79 static 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; 154 out_dma_map: 155 dma_buf_vunmap(dmabuf, &map); 156 out_obj: 157 i915_gem_object_put(obj); 158 out_dmabuf: 159 dma_buf_put(dmabuf); 160 return err; 161 } 162 163 static 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(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); 205 out_obj: 206 i915_gem_object_put(obj); 207 return err; 208 209 err_dmabuf: 210 dma_buf_put(dmabuf); 211 return err; 212 } 213 214 static 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); 254 out: 255 dma_buf_put(dmabuf); 256 return err; 257 258 err_obj: 259 i915_gem_object_put(obj); 260 return err; 261 } 262 263 int 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 285 int 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 } 293