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