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