1 /* 2 * SPDX-License-Identifier: MIT 3 * 4 * Copyright © 2016 Intel Corporation 5 */ 6 7 #include "i915_file_private.h" 8 #include "mock_context.h" 9 #include "selftests/mock_drm.h" 10 #include "selftests/mock_gtt.h" 11 12 struct i915_gem_context * 13 mock_context(struct drm_i915_private *i915, 14 const char *name) 15 { 16 struct i915_gem_context *ctx; 17 struct i915_gem_engines *e; 18 struct intel_sseu null_sseu = {}; 19 20 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 21 if (!ctx) 22 return NULL; 23 24 kref_init(&ctx->ref); 25 INIT_LIST_HEAD(&ctx->link); 26 ctx->i915 = i915; 27 INIT_WORK(&ctx->release_work, i915_gem_context_release_work); 28 29 mutex_init(&ctx->mutex); 30 31 spin_lock_init(&ctx->stale.lock); 32 INIT_LIST_HEAD(&ctx->stale.engines); 33 34 i915_gem_context_set_persistence(ctx); 35 36 if (name) { 37 struct i915_ppgtt *ppgtt; 38 39 strscpy(ctx->name, name, sizeof(ctx->name)); 40 41 ppgtt = mock_ppgtt(i915, name); 42 if (!ppgtt) 43 goto err_free; 44 45 ctx->vm = &ppgtt->vm; 46 } 47 48 mutex_init(&ctx->engines_mutex); 49 e = default_engines(ctx, null_sseu); 50 if (IS_ERR(e)) 51 goto err_vm; 52 RCU_INIT_POINTER(ctx->engines, e); 53 54 INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL); 55 mutex_init(&ctx->lut_mutex); 56 57 return ctx; 58 59 err_vm: 60 if (ctx->vm) 61 i915_vm_put(ctx->vm); 62 err_free: 63 kfree(ctx); 64 return NULL; 65 } 66 67 void mock_context_close(struct i915_gem_context *ctx) 68 { 69 context_close(ctx); 70 } 71 72 void mock_init_contexts(struct drm_i915_private *i915) 73 { 74 init_contexts(&i915->gem.contexts); 75 } 76 77 struct i915_gem_context * 78 live_context(struct drm_i915_private *i915, struct file *file) 79 { 80 struct drm_i915_file_private *fpriv = to_drm_file(file)->driver_priv; 81 struct i915_gem_proto_context *pc; 82 struct i915_gem_context *ctx; 83 int err; 84 u32 id; 85 86 pc = proto_context_create(fpriv, i915, 0); 87 if (IS_ERR(pc)) 88 return ERR_CAST(pc); 89 90 ctx = i915_gem_create_context(i915, pc); 91 proto_context_close(i915, pc); 92 if (IS_ERR(ctx)) 93 return ctx; 94 95 i915_gem_context_set_no_error_capture(ctx); 96 97 err = xa_alloc(&fpriv->context_xa, &id, NULL, xa_limit_32b, GFP_KERNEL); 98 if (err < 0) 99 goto err_ctx; 100 101 gem_context_register(ctx, fpriv, id); 102 103 return ctx; 104 105 err_ctx: 106 context_close(ctx); 107 return ERR_PTR(err); 108 } 109 110 struct i915_gem_context * 111 kernel_context(struct drm_i915_private *i915, 112 struct i915_address_space *vm) 113 { 114 struct i915_gem_context *ctx; 115 struct i915_gem_proto_context *pc; 116 117 pc = proto_context_create(NULL, i915, 0); 118 if (IS_ERR(pc)) 119 return ERR_CAST(pc); 120 121 if (vm) { 122 if (pc->vm) 123 i915_vm_put(pc->vm); 124 pc->vm = i915_vm_get(vm); 125 } 126 127 ctx = i915_gem_create_context(i915, pc); 128 proto_context_close(i915, pc); 129 if (IS_ERR(ctx)) 130 return ctx; 131 132 i915_gem_context_clear_bannable(ctx); 133 i915_gem_context_set_persistence(ctx); 134 i915_gem_context_set_no_error_capture(ctx); 135 136 return ctx; 137 } 138 139 void kernel_context_close(struct i915_gem_context *ctx) 140 { 141 context_close(ctx); 142 } 143