110be98a7SChris Wilson /*
210be98a7SChris Wilson * SPDX-License-Identifier: MIT
310be98a7SChris Wilson *
410be98a7SChris Wilson * Copyright © 2016 Intel Corporation
510be98a7SChris Wilson */
610be98a7SChris Wilson
75472b3f2SJani Nikula #include "i915_file_private.h"
810be98a7SChris Wilson #include "mock_context.h"
9a8c9a7f5SChris Wilson #include "selftests/mock_drm.h"
1010be98a7SChris Wilson #include "selftests/mock_gtt.h"
1110be98a7SChris Wilson
1210be98a7SChris Wilson struct i915_gem_context *
mock_context(struct drm_i915_private * i915,const char * name)1310be98a7SChris Wilson mock_context(struct drm_i915_private *i915,
1410be98a7SChris Wilson const char *name)
1510be98a7SChris Wilson {
1610be98a7SChris Wilson struct i915_gem_context *ctx;
1710be98a7SChris Wilson struct i915_gem_engines *e;
18263ae12cSJason Ekstrand struct intel_sseu null_sseu = {};
1910be98a7SChris Wilson
2010be98a7SChris Wilson ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
2110be98a7SChris Wilson if (!ctx)
2210be98a7SChris Wilson return NULL;
2310be98a7SChris Wilson
2410be98a7SChris Wilson kref_init(&ctx->ref);
2510be98a7SChris Wilson INIT_LIST_HEAD(&ctx->link);
2610be98a7SChris Wilson ctx->i915 = i915;
2775eefd82SDaniel Vetter INIT_WORK(&ctx->release_work, i915_gem_context_release_work);
2810be98a7SChris Wilson
29f7ce8639SChris Wilson mutex_init(&ctx->mutex);
30f7ce8639SChris Wilson
31130a95e9SChris Wilson spin_lock_init(&ctx->stale.lock);
32130a95e9SChris Wilson INIT_LIST_HEAD(&ctx->stale.engines);
33130a95e9SChris Wilson
34a0e04715SChris Wilson i915_gem_context_set_persistence(ctx);
35a0e04715SChris Wilson
3610be98a7SChris Wilson if (name) {
37ab53497bSChris Wilson struct i915_ppgtt *ppgtt;
3810be98a7SChris Wilson
390a3b94a2SChris Wilson strncpy(ctx->name, name, sizeof(ctx->name) - 1);
4010be98a7SChris Wilson
4110be98a7SChris Wilson ppgtt = mock_ppgtt(i915, name);
4210be98a7SChris Wilson if (!ppgtt)
430eee9977SJason Ekstrand goto err_free;
4410be98a7SChris Wilson
45*e1a7ab4fSThomas Hellström ctx->vm = &ppgtt->vm;
4610be98a7SChris Wilson }
4710be98a7SChris Wilson
480eee9977SJason Ekstrand mutex_init(&ctx->engines_mutex);
490eee9977SJason Ekstrand e = default_engines(ctx, null_sseu);
500eee9977SJason Ekstrand if (IS_ERR(e))
510eee9977SJason Ekstrand goto err_vm;
520eee9977SJason Ekstrand RCU_INIT_POINTER(ctx->engines, e);
530eee9977SJason Ekstrand
540eee9977SJason Ekstrand INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
550eee9977SJason Ekstrand mutex_init(&ctx->lut_mutex);
560eee9977SJason Ekstrand
5710be98a7SChris Wilson return ctx;
5810be98a7SChris Wilson
590eee9977SJason Ekstrand err_vm:
600eee9977SJason Ekstrand if (ctx->vm)
61*e1a7ab4fSThomas Hellström i915_vm_put(ctx->vm);
6210be98a7SChris Wilson err_free:
6310be98a7SChris Wilson kfree(ctx);
6410be98a7SChris Wilson return NULL;
6510be98a7SChris Wilson }
6610be98a7SChris Wilson
mock_context_close(struct i915_gem_context * ctx)6710be98a7SChris Wilson void mock_context_close(struct i915_gem_context *ctx)
6810be98a7SChris Wilson {
6910be98a7SChris Wilson context_close(ctx);
7010be98a7SChris Wilson }
7110be98a7SChris Wilson
mock_init_contexts(struct drm_i915_private * i915)7210be98a7SChris Wilson void mock_init_contexts(struct drm_i915_private *i915)
7310be98a7SChris Wilson {
74a4e7ccdaSChris Wilson init_contexts(&i915->gem.contexts);
7510be98a7SChris Wilson }
7610be98a7SChris Wilson
7710be98a7SChris Wilson struct i915_gem_context *
live_context(struct drm_i915_private * i915,struct file * file)78a8c9a7f5SChris Wilson live_context(struct drm_i915_private *i915, struct file *file)
7910be98a7SChris Wilson {
80a4c1cdd3SJason Ekstrand struct drm_i915_file_private *fpriv = to_drm_file(file)->driver_priv;
81a34857dcSJason Ekstrand struct i915_gem_proto_context *pc;
8210be98a7SChris Wilson struct i915_gem_context *ctx;
8310be98a7SChris Wilson int err;
84c100777cSTvrtko Ursulin u32 id;
8510be98a7SChris Wilson
86a34857dcSJason Ekstrand pc = proto_context_create(i915, 0);
87a34857dcSJason Ekstrand if (IS_ERR(pc))
88a34857dcSJason Ekstrand return ERR_CAST(pc);
89a34857dcSJason Ekstrand
90a34857dcSJason Ekstrand ctx = i915_gem_create_context(i915, pc);
91d3ac8d42SDaniele Ceraolo Spurio proto_context_close(i915, pc);
9210be98a7SChris Wilson if (IS_ERR(ctx))
9310be98a7SChris Wilson return ctx;
9410be98a7SChris Wilson
9503d0ed8aSChris Wilson i915_gem_context_set_no_error_capture(ctx);
9603d0ed8aSChris Wilson
97a4c1cdd3SJason Ekstrand err = xa_alloc(&fpriv->context_xa, &id, NULL, xa_limit_32b, GFP_KERNEL);
9810be98a7SChris Wilson if (err < 0)
9910be98a7SChris Wilson goto err_ctx;
10010be98a7SChris Wilson
101a4c1cdd3SJason Ekstrand gem_context_register(ctx, fpriv, id);
102a4c1cdd3SJason Ekstrand
10310be98a7SChris Wilson return ctx;
10410be98a7SChris Wilson
10510be98a7SChris Wilson err_ctx:
10610be98a7SChris Wilson context_close(ctx);
10710be98a7SChris Wilson return ERR_PTR(err);
10810be98a7SChris Wilson }
10910be98a7SChris Wilson
11010be98a7SChris Wilson struct i915_gem_context *
live_context_for_engine(struct intel_engine_cs * engine,struct file * file)111d61345f3SChris Wilson live_context_for_engine(struct intel_engine_cs *engine, struct file *file)
112d61345f3SChris Wilson {
113d61345f3SChris Wilson struct i915_gem_engines *engines;
114d61345f3SChris Wilson struct i915_gem_context *ctx;
115263ae12cSJason Ekstrand struct intel_sseu null_sseu = {};
116d61345f3SChris Wilson struct intel_context *ce;
117d61345f3SChris Wilson
118d61345f3SChris Wilson engines = alloc_engines(1);
119d61345f3SChris Wilson if (!engines)
120d61345f3SChris Wilson return ERR_PTR(-ENOMEM);
121d61345f3SChris Wilson
122d61345f3SChris Wilson ctx = live_context(engine->i915, file);
123d61345f3SChris Wilson if (IS_ERR(ctx)) {
124d61345f3SChris Wilson __free_engines(engines, 0);
125d61345f3SChris Wilson return ctx;
126d61345f3SChris Wilson }
127d61345f3SChris Wilson
128d61345f3SChris Wilson ce = intel_context_create(engine);
129d61345f3SChris Wilson if (IS_ERR(ce)) {
130d61345f3SChris Wilson __free_engines(engines, 0);
131d61345f3SChris Wilson return ERR_CAST(ce);
132d61345f3SChris Wilson }
133d61345f3SChris Wilson
134263ae12cSJason Ekstrand intel_context_set_gem(ce, ctx, null_sseu);
135d61345f3SChris Wilson engines->engines[0] = ce;
136d61345f3SChris Wilson engines->num_engines = 1;
137d61345f3SChris Wilson
138d61345f3SChris Wilson mutex_lock(&ctx->engines_mutex);
139d61345f3SChris Wilson i915_gem_context_set_user_engines(ctx);
140d61345f3SChris Wilson engines = rcu_replace_pointer(ctx->engines, engines, 1);
141d61345f3SChris Wilson mutex_unlock(&ctx->engines_mutex);
142d61345f3SChris Wilson
143d61345f3SChris Wilson engines_idle_release(ctx, engines);
144d61345f3SChris Wilson
145d61345f3SChris Wilson return ctx;
146d61345f3SChris Wilson }
147d61345f3SChris Wilson
148d61345f3SChris Wilson struct i915_gem_context *
kernel_context(struct drm_i915_private * i915,struct i915_address_space * vm)1495888d588SJason Ekstrand kernel_context(struct drm_i915_private *i915,
1505888d588SJason Ekstrand struct i915_address_space *vm)
15110be98a7SChris Wilson {
152e6ba7648SChris Wilson struct i915_gem_context *ctx;
153a34857dcSJason Ekstrand struct i915_gem_proto_context *pc;
154e6ba7648SChris Wilson
155a34857dcSJason Ekstrand pc = proto_context_create(i915, 0);
156a34857dcSJason Ekstrand if (IS_ERR(pc))
157a34857dcSJason Ekstrand return ERR_CAST(pc);
158a34857dcSJason Ekstrand
1595888d588SJason Ekstrand if (vm) {
1605888d588SJason Ekstrand if (pc->vm)
1615888d588SJason Ekstrand i915_vm_put(pc->vm);
1625888d588SJason Ekstrand pc->vm = i915_vm_get(vm);
1635888d588SJason Ekstrand }
1645888d588SJason Ekstrand
165a34857dcSJason Ekstrand ctx = i915_gem_create_context(i915, pc);
166d3ac8d42SDaniele Ceraolo Spurio proto_context_close(i915, pc);
167e6ba7648SChris Wilson if (IS_ERR(ctx))
168e6ba7648SChris Wilson return ctx;
169e6ba7648SChris Wilson
170e6ba7648SChris Wilson i915_gem_context_clear_bannable(ctx);
171e6ba7648SChris Wilson i915_gem_context_set_persistence(ctx);
1723ce291a6SChris Wilson i915_gem_context_set_no_error_capture(ctx);
173e6ba7648SChris Wilson
174e6ba7648SChris Wilson return ctx;
17510be98a7SChris Wilson }
17610be98a7SChris Wilson
kernel_context_close(struct i915_gem_context * ctx)17710be98a7SChris Wilson void kernel_context_close(struct i915_gem_context *ctx)
17810be98a7SChris Wilson {
17910be98a7SChris Wilson context_close(ctx);
18010be98a7SChris Wilson }
181