root/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. igt_dmabuf_export
  2. igt_dmabuf_import_self
  3. igt_dmabuf_import
  4. igt_dmabuf_import_ownership
  5. igt_dmabuf_export_vmap
  6. igt_dmabuf_export_kmap
  7. i915_gem_dmabuf_mock_selftests
  8. i915_gem_dmabuf_live_selftests

   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         u32 pattern[] = { 0, 0xaa, 0xcc, 0x55, 0xff };
  86         int err, i;
  87 
  88         dmabuf = mock_dmabuf(1);
  89         if (IS_ERR(dmabuf))
  90                 return PTR_ERR(dmabuf);
  91 
  92         obj = to_intel_bo(i915_gem_prime_import(&i915->drm, dmabuf));
  93         if (IS_ERR(obj)) {
  94                 pr_err("i915_gem_prime_import failed with err=%d\n",
  95                        (int)PTR_ERR(obj));
  96                 err = PTR_ERR(obj);
  97                 goto out_dmabuf;
  98         }
  99 
 100         if (obj->base.dev != &i915->drm) {
 101                 pr_err("i915_gem_prime_import created a non-i915 object!\n");
 102                 err = -EINVAL;
 103                 goto out_obj;
 104         }
 105 
 106         if (obj->base.size != PAGE_SIZE) {
 107                 pr_err("i915_gem_prime_import is wrong size found %lld, expected %ld\n",
 108                        (long long)obj->base.size, PAGE_SIZE);
 109                 err = -EINVAL;
 110                 goto out_obj;
 111         }
 112 
 113         dma_map = dma_buf_vmap(dmabuf);
 114         if (!dma_map) {
 115                 pr_err("dma_buf_vmap failed\n");
 116                 err = -ENOMEM;
 117                 goto out_obj;
 118         }
 119 
 120         if (0) { /* Can not yet map dmabuf */
 121                 obj_map = i915_gem_object_pin_map(obj, I915_MAP_WB);
 122                 if (IS_ERR(obj_map)) {
 123                         err = PTR_ERR(obj_map);
 124                         pr_err("i915_gem_object_pin_map failed with err=%d\n", err);
 125                         goto out_dma_map;
 126                 }
 127 
 128                 for (i = 0; i < ARRAY_SIZE(pattern); i++) {
 129                         memset(dma_map, pattern[i], PAGE_SIZE);
 130                         if (memchr_inv(obj_map, pattern[i], PAGE_SIZE)) {
 131                                 err = -EINVAL;
 132                                 pr_err("imported vmap not all set to %x!\n", pattern[i]);
 133                                 i915_gem_object_unpin_map(obj);
 134                                 goto out_dma_map;
 135                         }
 136                 }
 137 
 138                 for (i = 0; i < ARRAY_SIZE(pattern); i++) {
 139                         memset(obj_map, pattern[i], PAGE_SIZE);
 140                         if (memchr_inv(dma_map, pattern[i], PAGE_SIZE)) {
 141                                 err = -EINVAL;
 142                                 pr_err("exported vmap not all set to %x!\n", pattern[i]);
 143                                 i915_gem_object_unpin_map(obj);
 144                                 goto out_dma_map;
 145                         }
 146                 }
 147 
 148                 i915_gem_object_unpin_map(obj);
 149         }
 150 
 151         err = 0;
 152 out_dma_map:
 153         dma_buf_vunmap(dmabuf, dma_map);
 154 out_obj:
 155         i915_gem_object_put(obj);
 156 out_dmabuf:
 157         dma_buf_put(dmabuf);
 158         return err;
 159 }
 160 
 161 static int igt_dmabuf_import_ownership(void *arg)
 162 {
 163         struct drm_i915_private *i915 = arg;
 164         struct drm_i915_gem_object *obj;
 165         struct dma_buf *dmabuf;
 166         void *ptr;
 167         int err;
 168 
 169         dmabuf = mock_dmabuf(1);
 170         if (IS_ERR(dmabuf))
 171                 return PTR_ERR(dmabuf);
 172 
 173         ptr = dma_buf_vmap(dmabuf);
 174         if (!ptr) {
 175                 pr_err("dma_buf_vmap failed\n");
 176                 err = -ENOMEM;
 177                 goto err_dmabuf;
 178         }
 179 
 180         memset(ptr, 0xc5, PAGE_SIZE);
 181         dma_buf_vunmap(dmabuf, ptr);
 182 
 183         obj = to_intel_bo(i915_gem_prime_import(&i915->drm, dmabuf));
 184         if (IS_ERR(obj)) {
 185                 pr_err("i915_gem_prime_import failed with err=%d\n",
 186                        (int)PTR_ERR(obj));
 187                 err = PTR_ERR(obj);
 188                 goto err_dmabuf;
 189         }
 190 
 191         dma_buf_put(dmabuf);
 192 
 193         err = i915_gem_object_pin_pages(obj);
 194         if (err) {
 195                 pr_err("i915_gem_object_pin_pages failed with err=%d\n", err);
 196                 goto out_obj;
 197         }
 198 
 199         err = 0;
 200         i915_gem_object_unpin_pages(obj);
 201 out_obj:
 202         i915_gem_object_put(obj);
 203         return err;
 204 
 205 err_dmabuf:
 206         dma_buf_put(dmabuf);
 207         return err;
 208 }
 209 
 210 static int igt_dmabuf_export_vmap(void *arg)
 211 {
 212         struct drm_i915_private *i915 = arg;
 213         struct drm_i915_gem_object *obj;
 214         struct dma_buf *dmabuf;
 215         void *ptr;
 216         int err;
 217 
 218         obj = i915_gem_object_create_shmem(i915, PAGE_SIZE);
 219         if (IS_ERR(obj))
 220                 return PTR_ERR(obj);
 221 
 222         dmabuf = i915_gem_prime_export(&obj->base, 0);
 223         if (IS_ERR(dmabuf)) {
 224                 pr_err("i915_gem_prime_export failed with err=%d\n",
 225                        (int)PTR_ERR(dmabuf));
 226                 err = PTR_ERR(dmabuf);
 227                 goto err_obj;
 228         }
 229         i915_gem_object_put(obj);
 230 
 231         ptr = dma_buf_vmap(dmabuf);
 232         if (!ptr) {
 233                 pr_err("dma_buf_vmap failed\n");
 234                 err = -ENOMEM;
 235                 goto out;
 236         }
 237 
 238         if (memchr_inv(ptr, 0, dmabuf->size)) {
 239                 pr_err("Exported object not initialiased to zero!\n");
 240                 err = -EINVAL;
 241                 goto out;
 242         }
 243 
 244         memset(ptr, 0xc5, dmabuf->size);
 245 
 246         err = 0;
 247         dma_buf_vunmap(dmabuf, ptr);
 248 out:
 249         dma_buf_put(dmabuf);
 250         return err;
 251 
 252 err_obj:
 253         i915_gem_object_put(obj);
 254         return err;
 255 }
 256 
 257 static int igt_dmabuf_export_kmap(void *arg)
 258 {
 259         struct drm_i915_private *i915 = arg;
 260         struct drm_i915_gem_object *obj;
 261         struct dma_buf *dmabuf;
 262         void *ptr;
 263         int err;
 264 
 265         obj = i915_gem_object_create_shmem(i915, 2 * PAGE_SIZE);
 266         if (IS_ERR(obj))
 267                 return PTR_ERR(obj);
 268 
 269         dmabuf = i915_gem_prime_export(&obj->base, 0);
 270         i915_gem_object_put(obj);
 271         if (IS_ERR(dmabuf)) {
 272                 err = PTR_ERR(dmabuf);
 273                 pr_err("i915_gem_prime_export failed with err=%d\n", err);
 274                 return err;
 275         }
 276 
 277         ptr = dma_buf_kmap(dmabuf, 0);
 278         if (!ptr) {
 279                 pr_err("dma_buf_kmap failed\n");
 280                 err = -ENOMEM;
 281                 goto err;
 282         }
 283 
 284         if (memchr_inv(ptr, 0, PAGE_SIZE)) {
 285                 dma_buf_kunmap(dmabuf, 0, ptr);
 286                 pr_err("Exported page[0] not initialiased to zero!\n");
 287                 err = -EINVAL;
 288                 goto err;
 289         }
 290 
 291         memset(ptr, 0xc5, PAGE_SIZE);
 292         dma_buf_kunmap(dmabuf, 0, ptr);
 293 
 294         ptr = i915_gem_object_pin_map(obj, I915_MAP_WB);
 295         if (IS_ERR(ptr)) {
 296                 err = PTR_ERR(ptr);
 297                 pr_err("i915_gem_object_pin_map failed with err=%d\n", err);
 298                 goto err;
 299         }
 300         memset(ptr + PAGE_SIZE, 0xaa, PAGE_SIZE);
 301         i915_gem_object_flush_map(obj);
 302         i915_gem_object_unpin_map(obj);
 303 
 304         ptr = dma_buf_kmap(dmabuf, 1);
 305         if (!ptr) {
 306                 pr_err("dma_buf_kmap failed\n");
 307                 err = -ENOMEM;
 308                 goto err;
 309         }
 310 
 311         if (memchr_inv(ptr, 0xaa, PAGE_SIZE)) {
 312                 dma_buf_kunmap(dmabuf, 1, ptr);
 313                 pr_err("Exported page[1] not set to 0xaa!\n");
 314                 err = -EINVAL;
 315                 goto err;
 316         }
 317 
 318         memset(ptr, 0xc5, PAGE_SIZE);
 319         dma_buf_kunmap(dmabuf, 1, ptr);
 320 
 321         ptr = dma_buf_kmap(dmabuf, 0);
 322         if (!ptr) {
 323                 pr_err("dma_buf_kmap failed\n");
 324                 err = -ENOMEM;
 325                 goto err;
 326         }
 327         if (memchr_inv(ptr, 0xc5, PAGE_SIZE)) {
 328                 dma_buf_kunmap(dmabuf, 0, ptr);
 329                 pr_err("Exported page[0] did not retain 0xc5!\n");
 330                 err = -EINVAL;
 331                 goto err;
 332         }
 333         dma_buf_kunmap(dmabuf, 0, ptr);
 334 
 335         ptr = dma_buf_kmap(dmabuf, 2);
 336         if (ptr) {
 337                 pr_err("Erroneously kmapped beyond the end of the object!\n");
 338                 dma_buf_kunmap(dmabuf, 2, ptr);
 339                 err = -EINVAL;
 340                 goto err;
 341         }
 342 
 343         ptr = dma_buf_kmap(dmabuf, -1);
 344         if (ptr) {
 345                 pr_err("Erroneously kmapped before the start of the object!\n");
 346                 dma_buf_kunmap(dmabuf, -1, ptr);
 347                 err = -EINVAL;
 348                 goto err;
 349         }
 350 
 351         err = 0;
 352 err:
 353         dma_buf_put(dmabuf);
 354         return err;
 355 }
 356 
 357 int i915_gem_dmabuf_mock_selftests(void)
 358 {
 359         static const struct i915_subtest tests[] = {
 360                 SUBTEST(igt_dmabuf_export),
 361                 SUBTEST(igt_dmabuf_import_self),
 362                 SUBTEST(igt_dmabuf_import),
 363                 SUBTEST(igt_dmabuf_import_ownership),
 364                 SUBTEST(igt_dmabuf_export_vmap),
 365                 SUBTEST(igt_dmabuf_export_kmap),
 366         };
 367         struct drm_i915_private *i915;
 368         int err;
 369 
 370         i915 = mock_gem_device();
 371         if (!i915)
 372                 return -ENOMEM;
 373 
 374         err = i915_subtests(tests, i915);
 375 
 376         drm_dev_put(&i915->drm);
 377         return err;
 378 }
 379 
 380 int i915_gem_dmabuf_live_selftests(struct drm_i915_private *i915)
 381 {
 382         static const struct i915_subtest tests[] = {
 383                 SUBTEST(igt_dmabuf_export),
 384         };
 385 
 386         return i915_subtests(tests, i915);
 387 }

/* [<][>][^][v][top][bottom][index][help] */