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 
18 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
19 	if (!ctx)
20 		return NULL;
21 
22 	kref_init(&ctx->ref);
23 	INIT_LIST_HEAD(&ctx->link);
24 	ctx->i915 = i915;
25 
26 	mutex_init(&ctx->mutex);
27 
28 	spin_lock_init(&ctx->stale.lock);
29 	INIT_LIST_HEAD(&ctx->stale.engines);
30 
31 	i915_gem_context_set_persistence(ctx);
32 
33 	mutex_init(&ctx->engines_mutex);
34 	e = default_engines(ctx);
35 	if (IS_ERR(e))
36 		goto err_free;
37 	RCU_INIT_POINTER(ctx->engines, e);
38 
39 	INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
40 	mutex_init(&ctx->lut_mutex);
41 
42 	if (name) {
43 		struct i915_ppgtt *ppgtt;
44 
45 		strncpy(ctx->name, name, sizeof(ctx->name) - 1);
46 
47 		ppgtt = mock_ppgtt(i915, name);
48 		if (!ppgtt)
49 			goto err_put;
50 
51 		mutex_lock(&ctx->mutex);
52 		__set_ppgtt(ctx, &ppgtt->vm);
53 		mutex_unlock(&ctx->mutex);
54 
55 		i915_vm_put(&ppgtt->vm);
56 	}
57 
58 	return ctx;
59 
60 err_free:
61 	kfree(ctx);
62 	return NULL;
63 
64 err_put:
65 	i915_gem_context_set_closed(ctx);
66 	i915_gem_context_put(ctx);
67 	return NULL;
68 }
69 
70 void mock_context_close(struct i915_gem_context *ctx)
71 {
72 	context_close(ctx);
73 }
74 
75 void mock_init_contexts(struct drm_i915_private *i915)
76 {
77 	init_contexts(&i915->gem.contexts);
78 }
79 
80 struct i915_gem_context *
81 live_context(struct drm_i915_private *i915, struct file *file)
82 {
83 	struct i915_gem_context *ctx;
84 	int err;
85 	u32 id;
86 
87 	ctx = i915_gem_create_context(i915, 0);
88 	if (IS_ERR(ctx))
89 		return ctx;
90 
91 	i915_gem_context_set_no_error_capture(ctx);
92 
93 	err = gem_context_register(ctx, to_drm_file(file)->driver_priv, &id);
94 	if (err < 0)
95 		goto err_ctx;
96 
97 	return ctx;
98 
99 err_ctx:
100 	context_close(ctx);
101 	return ERR_PTR(err);
102 }
103 
104 struct i915_gem_context *
105 live_context_for_engine(struct intel_engine_cs *engine, struct file *file)
106 {
107 	struct i915_gem_engines *engines;
108 	struct i915_gem_context *ctx;
109 	struct intel_context *ce;
110 
111 	engines = alloc_engines(1);
112 	if (!engines)
113 		return ERR_PTR(-ENOMEM);
114 
115 	ctx = live_context(engine->i915, file);
116 	if (IS_ERR(ctx)) {
117 		__free_engines(engines, 0);
118 		return ctx;
119 	}
120 
121 	ce = intel_context_create(engine);
122 	if (IS_ERR(ce)) {
123 		__free_engines(engines, 0);
124 		return ERR_CAST(ce);
125 	}
126 
127 	intel_context_set_gem(ce, ctx);
128 	engines->engines[0] = ce;
129 	engines->num_engines = 1;
130 
131 	mutex_lock(&ctx->engines_mutex);
132 	i915_gem_context_set_user_engines(ctx);
133 	engines = rcu_replace_pointer(ctx->engines, engines, 1);
134 	mutex_unlock(&ctx->engines_mutex);
135 
136 	engines_idle_release(ctx, engines);
137 
138 	return ctx;
139 }
140 
141 struct i915_gem_context *
142 kernel_context(struct drm_i915_private *i915)
143 {
144 	struct i915_gem_context *ctx;
145 
146 	ctx = i915_gem_create_context(i915, 0);
147 	if (IS_ERR(ctx))
148 		return ctx;
149 
150 	i915_gem_context_clear_bannable(ctx);
151 	i915_gem_context_set_persistence(ctx);
152 	i915_gem_context_set_no_error_capture(ctx);
153 
154 	return ctx;
155 }
156 
157 void kernel_context_close(struct i915_gem_context *ctx)
158 {
159 	context_close(ctx);
160 }
161