1 // SPDX-License-Identifier: MIT
2 /*
3 * Copyright(c) 2020 Intel Corporation.
4 */
5 #include <linux/workqueue.h>
6 #include "intel_pxp.h"
7 #include "intel_pxp_irq.h"
8 #include "intel_pxp_session.h"
9 #include "intel_pxp_tee.h"
10 #include "gem/i915_gem_context.h"
11 #include "gt/intel_context.h"
12 #include "i915_drv.h"
13
14 /**
15 * DOC: PXP
16 *
17 * PXP (Protected Xe Path) is a feature available in Gen12 and newer platforms.
18 * It allows execution and flip to display of protected (i.e. encrypted)
19 * objects. The SW support is enabled via the CONFIG_DRM_I915_PXP kconfig.
20 *
21 * Objects can opt-in to PXP encryption at creation time via the
22 * I915_GEM_CREATE_EXT_PROTECTED_CONTENT create_ext flag. For objects to be
23 * correctly protected they must be used in conjunction with a context created
24 * with the I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. See the documentation
25 * of those two uapi flags for details and restrictions.
26 *
27 * Protected objects are tied to a pxp session; currently we only support one
28 * session, which i915 manages and whose index is available in the uapi
29 * (I915_PROTECTED_CONTENT_DEFAULT_SESSION) for use in instructions targeting
30 * protected objects.
31 * The session is invalidated by the HW when certain events occur (e.g.
32 * suspend/resume). When this happens, all the objects that were used with the
33 * session are marked as invalid and all contexts marked as using protected
34 * content are banned. Any further attempt at using them in an execbuf call is
35 * rejected, while flips are converted to black frames.
36 *
37 * Some of the PXP setup operations are performed by the Management Engine,
38 * which is handled by the mei driver; communication between i915 and mei is
39 * performed via the mei_pxp component module.
40 */
41
pxp_to_gt(const struct intel_pxp * pxp)42 struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
43 {
44 return container_of(pxp, struct intel_gt, pxp);
45 }
46
intel_pxp_is_active(const struct intel_pxp * pxp)47 bool intel_pxp_is_active(const struct intel_pxp *pxp)
48 {
49 return pxp->arb_is_valid;
50 }
51
52 /* KCR register definitions */
53 #define KCR_INIT _MMIO(0x320f0)
54 /* Setting KCR Init bit is required after system boot */
55 #define KCR_INIT_ALLOW_DISPLAY_ME_WRITES REG_BIT(14)
56
kcr_pxp_enable(struct intel_gt * gt)57 static void kcr_pxp_enable(struct intel_gt *gt)
58 {
59 intel_uncore_write(gt->uncore, KCR_INIT,
60 _MASKED_BIT_ENABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES));
61 }
62
kcr_pxp_disable(struct intel_gt * gt)63 static void kcr_pxp_disable(struct intel_gt *gt)
64 {
65 intel_uncore_write(gt->uncore, KCR_INIT,
66 _MASKED_BIT_DISABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES));
67 }
68
create_vcs_context(struct intel_pxp * pxp)69 static int create_vcs_context(struct intel_pxp *pxp)
70 {
71 static struct lock_class_key pxp_lock;
72 struct intel_gt *gt = pxp_to_gt(pxp);
73 struct intel_engine_cs *engine;
74 struct intel_context *ce;
75 int i;
76
77 /*
78 * Find the first VCS engine present. We're guaranteed there is one
79 * if we're in this function due to the check in has_pxp
80 */
81 for (i = 0, engine = NULL; !engine; i++)
82 engine = gt->engine_class[VIDEO_DECODE_CLASS][i];
83
84 GEM_BUG_ON(!engine || engine->class != VIDEO_DECODE_CLASS);
85
86 ce = intel_engine_create_pinned_context(engine, engine->gt->vm, SZ_4K,
87 I915_GEM_HWS_PXP_ADDR,
88 &pxp_lock, "pxp_context");
89 if (IS_ERR(ce)) {
90 drm_err(>->i915->drm, "failed to create VCS ctx for PXP\n");
91 return PTR_ERR(ce);
92 }
93
94 pxp->ce = ce;
95
96 return 0;
97 }
98
destroy_vcs_context(struct intel_pxp * pxp)99 static void destroy_vcs_context(struct intel_pxp *pxp)
100 {
101 intel_engine_destroy_pinned_context(fetch_and_zero(&pxp->ce));
102 }
103
intel_pxp_init(struct intel_pxp * pxp)104 void intel_pxp_init(struct intel_pxp *pxp)
105 {
106 struct intel_gt *gt = pxp_to_gt(pxp);
107 int ret;
108
109 if (!HAS_PXP(gt->i915))
110 return;
111
112 mutex_init(&pxp->tee_mutex);
113
114 /*
115 * we'll use the completion to check if there is a termination pending,
116 * so we start it as completed and we reinit it when a termination
117 * is triggered.
118 */
119 init_completion(&pxp->termination);
120 complete_all(&pxp->termination);
121
122 mutex_init(&pxp->arb_mutex);
123 INIT_WORK(&pxp->session_work, intel_pxp_session_work);
124
125 ret = create_vcs_context(pxp);
126 if (ret)
127 return;
128
129 ret = intel_pxp_tee_component_init(pxp);
130 if (ret)
131 goto out_context;
132
133 drm_info(>->i915->drm, "Protected Xe Path (PXP) protected content support initialized\n");
134
135 return;
136
137 out_context:
138 destroy_vcs_context(pxp);
139 }
140
intel_pxp_fini(struct intel_pxp * pxp)141 void intel_pxp_fini(struct intel_pxp *pxp)
142 {
143 if (!intel_pxp_is_enabled(pxp))
144 return;
145
146 pxp->arb_is_valid = false;
147
148 intel_pxp_tee_component_fini(pxp);
149
150 destroy_vcs_context(pxp);
151 }
152
intel_pxp_mark_termination_in_progress(struct intel_pxp * pxp)153 void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp)
154 {
155 pxp->arb_is_valid = false;
156 reinit_completion(&pxp->termination);
157 }
158
pxp_queue_termination(struct intel_pxp * pxp)159 static void pxp_queue_termination(struct intel_pxp *pxp)
160 {
161 struct intel_gt *gt = pxp_to_gt(pxp);
162
163 /*
164 * We want to get the same effect as if we received a termination
165 * interrupt, so just pretend that we did.
166 */
167 spin_lock_irq(>->irq_lock);
168 intel_pxp_mark_termination_in_progress(pxp);
169 pxp->session_events |= PXP_TERMINATION_REQUEST;
170 queue_work(system_unbound_wq, &pxp->session_work);
171 spin_unlock_irq(>->irq_lock);
172 }
173
174 /*
175 * the arb session is restarted from the irq work when we receive the
176 * termination completion interrupt
177 */
intel_pxp_start(struct intel_pxp * pxp)178 int intel_pxp_start(struct intel_pxp *pxp)
179 {
180 int ret = 0;
181
182 if (!intel_pxp_is_enabled(pxp))
183 return -ENODEV;
184
185 mutex_lock(&pxp->arb_mutex);
186
187 if (pxp->arb_is_valid)
188 goto unlock;
189
190 pxp_queue_termination(pxp);
191
192 if (!wait_for_completion_timeout(&pxp->termination,
193 msecs_to_jiffies(250))) {
194 ret = -ETIMEDOUT;
195 goto unlock;
196 }
197
198 /* make sure the compiler doesn't optimize the double access */
199 barrier();
200
201 if (!pxp->arb_is_valid)
202 ret = -EIO;
203
204 unlock:
205 mutex_unlock(&pxp->arb_mutex);
206 return ret;
207 }
208
intel_pxp_init_hw(struct intel_pxp * pxp)209 void intel_pxp_init_hw(struct intel_pxp *pxp)
210 {
211 kcr_pxp_enable(pxp_to_gt(pxp));
212 intel_pxp_irq_enable(pxp);
213 }
214
intel_pxp_fini_hw(struct intel_pxp * pxp)215 void intel_pxp_fini_hw(struct intel_pxp *pxp)
216 {
217 kcr_pxp_disable(pxp_to_gt(pxp));
218
219 intel_pxp_irq_disable(pxp);
220 }
221
intel_pxp_key_check(struct intel_pxp * pxp,struct drm_i915_gem_object * obj,bool assign)222 int intel_pxp_key_check(struct intel_pxp *pxp,
223 struct drm_i915_gem_object *obj,
224 bool assign)
225 {
226 if (!intel_pxp_is_active(pxp))
227 return -ENODEV;
228
229 if (!i915_gem_object_is_protected(obj))
230 return -EINVAL;
231
232 GEM_BUG_ON(!pxp->key_instance);
233
234 /*
235 * If this is the first time we're using this object, it's not
236 * encrypted yet; it will be encrypted with the current key, so mark it
237 * as such. If the object is already encrypted, check instead if the
238 * used key is still valid.
239 */
240 if (!obj->pxp_key_instance && assign)
241 obj->pxp_key_instance = pxp->key_instance;
242
243 if (obj->pxp_key_instance != pxp->key_instance)
244 return -ENOEXEC;
245
246 return 0;
247 }
248
intel_pxp_invalidate(struct intel_pxp * pxp)249 void intel_pxp_invalidate(struct intel_pxp *pxp)
250 {
251 struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
252 struct i915_gem_context *ctx, *cn;
253
254 /* ban all contexts marked as protected */
255 spin_lock_irq(&i915->gem.contexts.lock);
256 list_for_each_entry_safe(ctx, cn, &i915->gem.contexts.list, link) {
257 struct i915_gem_engines_iter it;
258 struct intel_context *ce;
259
260 if (!kref_get_unless_zero(&ctx->ref))
261 continue;
262
263 if (likely(!i915_gem_context_uses_protected_content(ctx))) {
264 i915_gem_context_put(ctx);
265 continue;
266 }
267
268 spin_unlock_irq(&i915->gem.contexts.lock);
269
270 /*
271 * By the time we get here we are either going to suspend with
272 * quiesced execution or the HW keys are already long gone and
273 * in this case it is worthless to attempt to close the context
274 * and wait for its execution. It will hang the GPU if it has
275 * not already. So, as a fast mitigation, we can ban the
276 * context as quick as we can. That might race with the
277 * execbuffer, but currently this is the best that can be done.
278 */
279 for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it)
280 intel_context_ban(ce, NULL);
281 i915_gem_context_unlock_engines(ctx);
282
283 /*
284 * The context has been banned, no need to keep the wakeref.
285 * This is safe from races because the only other place this
286 * is touched is context_release and we're holding a ctx ref
287 */
288 if (ctx->pxp_wakeref) {
289 intel_runtime_pm_put(&i915->runtime_pm,
290 ctx->pxp_wakeref);
291 ctx->pxp_wakeref = 0;
292 }
293
294 spin_lock_irq(&i915->gem.contexts.lock);
295 list_safe_reset_next(ctx, cn, link);
296 i915_gem_context_put(ctx);
297 }
298 spin_unlock_irq(&i915->gem.contexts.lock);
299 }
300