1 // SPDX-License-Identifier: MIT
2 /*
3 * Copyright(c) 2020 Intel Corporation.
4 */
5 #include <linux/workqueue.h>
6
7 #include "gem/i915_gem_context.h"
8
9 #include "gt/intel_context.h"
10 #include "gt/intel_gt.h"
11
12 #include "i915_drv.h"
13
14 #include "intel_pxp.h"
15 #include "intel_pxp_irq.h"
16 #include "intel_pxp_session.h"
17 #include "intel_pxp_tee.h"
18 #include "intel_pxp_types.h"
19
20 /**
21 * DOC: PXP
22 *
23 * PXP (Protected Xe Path) is a feature available in Gen12 and newer platforms.
24 * It allows execution and flip to display of protected (i.e. encrypted)
25 * objects. The SW support is enabled via the CONFIG_DRM_I915_PXP kconfig.
26 *
27 * Objects can opt-in to PXP encryption at creation time via the
28 * I915_GEM_CREATE_EXT_PROTECTED_CONTENT create_ext flag. For objects to be
29 * correctly protected they must be used in conjunction with a context created
30 * with the I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. See the documentation
31 * of those two uapi flags for details and restrictions.
32 *
33 * Protected objects are tied to a pxp session; currently we only support one
34 * session, which i915 manages and whose index is available in the uapi
35 * (I915_PROTECTED_CONTENT_DEFAULT_SESSION) for use in instructions targeting
36 * protected objects.
37 * The session is invalidated by the HW when certain events occur (e.g.
38 * suspend/resume). When this happens, all the objects that were used with the
39 * session are marked as invalid and all contexts marked as using protected
40 * content are banned. Any further attempt at using them in an execbuf call is
41 * rejected, while flips are converted to black frames.
42 *
43 * Some of the PXP setup operations are performed by the Management Engine,
44 * which is handled by the mei driver; communication between i915 and mei is
45 * performed via the mei_pxp component module.
46 */
47
intel_pxp_is_supported(const struct intel_pxp * pxp)48 bool intel_pxp_is_supported(const struct intel_pxp *pxp)
49 {
50 return IS_ENABLED(CONFIG_DRM_I915_PXP) && pxp;
51 }
52
intel_pxp_is_enabled(const struct intel_pxp * pxp)53 bool intel_pxp_is_enabled(const struct intel_pxp *pxp)
54 {
55 return IS_ENABLED(CONFIG_DRM_I915_PXP) && pxp && pxp->ce;
56 }
57
intel_pxp_is_active(const struct intel_pxp * pxp)58 bool intel_pxp_is_active(const struct intel_pxp *pxp)
59 {
60 return IS_ENABLED(CONFIG_DRM_I915_PXP) && pxp && pxp->arb_is_valid;
61 }
62
63 /* KCR register definitions */
64 #define KCR_INIT _MMIO(0x320f0)
65 /* Setting KCR Init bit is required after system boot */
66 #define KCR_INIT_ALLOW_DISPLAY_ME_WRITES REG_BIT(14)
67
kcr_pxp_enable(struct intel_gt * gt)68 static void kcr_pxp_enable(struct intel_gt *gt)
69 {
70 intel_uncore_write(gt->uncore, KCR_INIT,
71 _MASKED_BIT_ENABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES));
72 }
73
kcr_pxp_disable(struct intel_gt * gt)74 static void kcr_pxp_disable(struct intel_gt *gt)
75 {
76 intel_uncore_write(gt->uncore, KCR_INIT,
77 _MASKED_BIT_DISABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES));
78 }
79
create_vcs_context(struct intel_pxp * pxp)80 static int create_vcs_context(struct intel_pxp *pxp)
81 {
82 static struct lock_class_key pxp_lock;
83 struct intel_gt *gt = pxp->ctrl_gt;
84 struct intel_engine_cs *engine;
85 struct intel_context *ce;
86 int i;
87
88 /*
89 * Find the first VCS engine present. We're guaranteed there is one
90 * if we're in this function due to the check in has_pxp
91 */
92 for (i = 0, engine = NULL; !engine; i++)
93 engine = gt->engine_class[VIDEO_DECODE_CLASS][i];
94
95 GEM_BUG_ON(!engine || engine->class != VIDEO_DECODE_CLASS);
96
97 ce = intel_engine_create_pinned_context(engine, engine->gt->vm, SZ_4K,
98 I915_GEM_HWS_PXP_ADDR,
99 &pxp_lock, "pxp_context");
100 if (IS_ERR(ce)) {
101 drm_err(>->i915->drm, "failed to create VCS ctx for PXP\n");
102 return PTR_ERR(ce);
103 }
104
105 pxp->ce = ce;
106
107 return 0;
108 }
109
destroy_vcs_context(struct intel_pxp * pxp)110 static void destroy_vcs_context(struct intel_pxp *pxp)
111 {
112 if (pxp->ce)
113 intel_engine_destroy_pinned_context(fetch_and_zero(&pxp->ce));
114 }
115
pxp_init_full(struct intel_pxp * pxp)116 static void pxp_init_full(struct intel_pxp *pxp)
117 {
118 struct intel_gt *gt = pxp->ctrl_gt;
119 int ret;
120
121 /*
122 * we'll use the completion to check if there is a termination pending,
123 * so we start it as completed and we reinit it when a termination
124 * is triggered.
125 */
126 init_completion(&pxp->termination);
127 complete_all(&pxp->termination);
128
129 intel_pxp_session_management_init(pxp);
130
131 ret = create_vcs_context(pxp);
132 if (ret)
133 return;
134
135 ret = intel_pxp_tee_component_init(pxp);
136 if (ret)
137 goto out_context;
138
139 drm_info(>->i915->drm, "Protected Xe Path (PXP) protected content support initialized\n");
140
141 return;
142
143 out_context:
144 destroy_vcs_context(pxp);
145 }
146
find_gt_for_required_teelink(struct drm_i915_private * i915)147 static struct intel_gt *find_gt_for_required_teelink(struct drm_i915_private *i915)
148 {
149 /*
150 * NOTE: Only certain platforms require PXP-tee-backend dependencies
151 * for HuC authentication. For now, its limited to DG2.
152 */
153 if (IS_ENABLED(CONFIG_INTEL_MEI_PXP) && IS_ENABLED(CONFIG_INTEL_MEI_GSC) &&
154 intel_huc_is_loaded_by_gsc(&i915->gt0.uc.huc) && intel_uc_uses_huc(&i915->gt0.uc))
155 return &i915->gt0;
156
157 return NULL;
158 }
159
find_gt_for_required_protected_content(struct drm_i915_private * i915)160 static struct intel_gt *find_gt_for_required_protected_content(struct drm_i915_private *i915)
161 {
162 if (!IS_ENABLED(CONFIG_DRM_I915_PXP) || !INTEL_INFO(i915)->has_pxp)
163 return NULL;
164
165 /*
166 * For MTL onwards, PXP-controller-GT needs to have a valid GSC engine
167 * on the media GT. NOTE: if we have a media-tile with a GSC-engine,
168 * the VDBOX is already present so skip that check
169 */
170 if (i915->media_gt && HAS_ENGINE(i915->media_gt, GSC0))
171 return i915->media_gt;
172
173 /*
174 * Else we rely on mei-pxp module but only on legacy platforms
175 * prior to having separate media GTs and has a valid VDBOX.
176 */
177 if (IS_ENABLED(CONFIG_INTEL_MEI_PXP) && !i915->media_gt && VDBOX_MASK(&i915->gt0))
178 return &i915->gt0;
179
180 return NULL;
181 }
182
intel_pxp_init(struct drm_i915_private * i915)183 int intel_pxp_init(struct drm_i915_private *i915)
184 {
185 struct intel_gt *gt;
186 bool is_full_feature = false;
187
188 /*
189 * NOTE: Get the ctrl_gt before checking intel_pxp_is_supported since
190 * we still need it if PXP's backend tee transport is needed.
191 */
192 gt = find_gt_for_required_protected_content(i915);
193 if (gt)
194 is_full_feature = true;
195 else
196 gt = find_gt_for_required_teelink(i915);
197
198 if (!gt)
199 return -ENODEV;
200
201 /*
202 * At this point, we will either enable full featured PXP capabilities
203 * including session and object management, or we will init the backend tee
204 * channel for internal users such as HuC loading by GSC
205 */
206 i915->pxp = kzalloc(sizeof(*i915->pxp), GFP_KERNEL);
207 if (!i915->pxp)
208 return -ENOMEM;
209
210 i915->pxp->ctrl_gt = gt;
211
212 /*
213 * If full PXP feature is not available but HuC is loaded by GSC on pre-MTL
214 * such as DG2, we can skip the init of the full PXP session/object management
215 * and just init the tee channel.
216 */
217 if (is_full_feature)
218 pxp_init_full(i915->pxp);
219 else
220 intel_pxp_tee_component_init(i915->pxp);
221
222 return 0;
223 }
224
intel_pxp_fini(struct drm_i915_private * i915)225 void intel_pxp_fini(struct drm_i915_private *i915)
226 {
227 if (!i915->pxp)
228 return;
229
230 i915->pxp->arb_is_valid = false;
231
232 intel_pxp_tee_component_fini(i915->pxp);
233
234 destroy_vcs_context(i915->pxp);
235
236 kfree(i915->pxp);
237 i915->pxp = NULL;
238 }
239
intel_pxp_mark_termination_in_progress(struct intel_pxp * pxp)240 void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp)
241 {
242 pxp->arb_is_valid = false;
243 reinit_completion(&pxp->termination);
244 }
245
pxp_queue_termination(struct intel_pxp * pxp)246 static void pxp_queue_termination(struct intel_pxp *pxp)
247 {
248 struct intel_gt *gt = pxp->ctrl_gt;
249
250 /*
251 * We want to get the same effect as if we received a termination
252 * interrupt, so just pretend that we did.
253 */
254 spin_lock_irq(gt->irq_lock);
255 intel_pxp_mark_termination_in_progress(pxp);
256 pxp->session_events |= PXP_TERMINATION_REQUEST;
257 queue_work(system_unbound_wq, &pxp->session_work);
258 spin_unlock_irq(gt->irq_lock);
259 }
260
pxp_component_bound(struct intel_pxp * pxp)261 static bool pxp_component_bound(struct intel_pxp *pxp)
262 {
263 bool bound = false;
264
265 mutex_lock(&pxp->tee_mutex);
266 if (pxp->pxp_component)
267 bound = true;
268 mutex_unlock(&pxp->tee_mutex);
269
270 return bound;
271 }
272
273 /*
274 * the arb session is restarted from the irq work when we receive the
275 * termination completion interrupt
276 */
intel_pxp_start(struct intel_pxp * pxp)277 int intel_pxp_start(struct intel_pxp *pxp)
278 {
279 int ret = 0;
280
281 if (!intel_pxp_is_enabled(pxp))
282 return -ENODEV;
283
284 if (wait_for(pxp_component_bound(pxp), 250))
285 return -ENXIO;
286
287 mutex_lock(&pxp->arb_mutex);
288
289 if (pxp->arb_is_valid)
290 goto unlock;
291
292 pxp_queue_termination(pxp);
293
294 if (!wait_for_completion_timeout(&pxp->termination,
295 msecs_to_jiffies(250))) {
296 ret = -ETIMEDOUT;
297 goto unlock;
298 }
299
300 /* make sure the compiler doesn't optimize the double access */
301 barrier();
302
303 if (!pxp->arb_is_valid)
304 ret = -EIO;
305
306 unlock:
307 mutex_unlock(&pxp->arb_mutex);
308 return ret;
309 }
310
intel_pxp_init_hw(struct intel_pxp * pxp)311 void intel_pxp_init_hw(struct intel_pxp *pxp)
312 {
313 kcr_pxp_enable(pxp->ctrl_gt);
314 intel_pxp_irq_enable(pxp);
315 }
316
intel_pxp_fini_hw(struct intel_pxp * pxp)317 void intel_pxp_fini_hw(struct intel_pxp *pxp)
318 {
319 kcr_pxp_disable(pxp->ctrl_gt);
320
321 intel_pxp_irq_disable(pxp);
322 }
323
intel_pxp_key_check(struct intel_pxp * pxp,struct drm_i915_gem_object * obj,bool assign)324 int intel_pxp_key_check(struct intel_pxp *pxp,
325 struct drm_i915_gem_object *obj,
326 bool assign)
327 {
328 if (!intel_pxp_is_active(pxp))
329 return -ENODEV;
330
331 if (!i915_gem_object_is_protected(obj))
332 return -EINVAL;
333
334 GEM_BUG_ON(!pxp->key_instance);
335
336 /*
337 * If this is the first time we're using this object, it's not
338 * encrypted yet; it will be encrypted with the current key, so mark it
339 * as such. If the object is already encrypted, check instead if the
340 * used key is still valid.
341 */
342 if (!obj->pxp_key_instance && assign)
343 obj->pxp_key_instance = pxp->key_instance;
344
345 if (obj->pxp_key_instance != pxp->key_instance)
346 return -ENOEXEC;
347
348 return 0;
349 }
350
intel_pxp_invalidate(struct intel_pxp * pxp)351 void intel_pxp_invalidate(struct intel_pxp *pxp)
352 {
353 struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
354 struct i915_gem_context *ctx, *cn;
355
356 /* ban all contexts marked as protected */
357 spin_lock_irq(&i915->gem.contexts.lock);
358 list_for_each_entry_safe(ctx, cn, &i915->gem.contexts.list, link) {
359 struct i915_gem_engines_iter it;
360 struct intel_context *ce;
361
362 if (!kref_get_unless_zero(&ctx->ref))
363 continue;
364
365 if (likely(!i915_gem_context_uses_protected_content(ctx))) {
366 i915_gem_context_put(ctx);
367 continue;
368 }
369
370 spin_unlock_irq(&i915->gem.contexts.lock);
371
372 /*
373 * By the time we get here we are either going to suspend with
374 * quiesced execution or the HW keys are already long gone and
375 * in this case it is worthless to attempt to close the context
376 * and wait for its execution. It will hang the GPU if it has
377 * not already. So, as a fast mitigation, we can ban the
378 * context as quick as we can. That might race with the
379 * execbuffer, but currently this is the best that can be done.
380 */
381 for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it)
382 intel_context_ban(ce, NULL);
383 i915_gem_context_unlock_engines(ctx);
384
385 /*
386 * The context has been banned, no need to keep the wakeref.
387 * This is safe from races because the only other place this
388 * is touched is context_release and we're holding a ctx ref
389 */
390 if (ctx->pxp_wakeref) {
391 intel_runtime_pm_put(&i915->runtime_pm,
392 ctx->pxp_wakeref);
393 ctx->pxp_wakeref = 0;
394 }
395
396 spin_lock_irq(&i915->gem.contexts.lock);
397 list_safe_reset_next(ctx, cn, link);
398 i915_gem_context_put(ctx);
399 }
400 spin_unlock_irq(&i915->gem.contexts.lock);
401 }
402