]> Git Repo - linux.git/blob - drivers/gpu/drm/i915/pxp/intel_pxp.c
Merge tag 'amd-drm-next-6.5-2023-06-09' of https://gitlab.freedesktop.org/agd5f/linux...
[linux.git] / drivers / gpu / drm / i915 / pxp / intel_pxp.c
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_gsccs.h"
16 #include "intel_pxp_irq.h"
17 #include "intel_pxp_regs.h"
18 #include "intel_pxp_session.h"
19 #include "intel_pxp_tee.h"
20 #include "intel_pxp_types.h"
21
22 /**
23  * DOC: PXP
24  *
25  * PXP (Protected Xe Path) is a feature available in Gen12 and newer platforms.
26  * It allows execution and flip to display of protected (i.e. encrypted)
27  * objects. The SW support is enabled via the CONFIG_DRM_I915_PXP kconfig.
28  *
29  * Objects can opt-in to PXP encryption at creation time via the
30  * I915_GEM_CREATE_EXT_PROTECTED_CONTENT create_ext flag. For objects to be
31  * correctly protected they must be used in conjunction with a context created
32  * with the I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. See the documentation
33  * of those two uapi flags for details and restrictions.
34  *
35  * Protected objects are tied to a pxp session; currently we only support one
36  * session, which i915 manages and whose index is available in the uapi
37  * (I915_PROTECTED_CONTENT_DEFAULT_SESSION) for use in instructions targeting
38  * protected objects.
39  * The session is invalidated by the HW when certain events occur (e.g.
40  * suspend/resume). When this happens, all the objects that were used with the
41  * session are marked as invalid and all contexts marked as using protected
42  * content are banned. Any further attempt at using them in an execbuf call is
43  * rejected, while flips are converted to black frames.
44  *
45  * Some of the PXP setup operations are performed by the Management Engine,
46  * which is handled by the mei driver; communication between i915 and mei is
47  * performed via the mei_pxp component module.
48  */
49
50 bool intel_pxp_is_supported(const struct intel_pxp *pxp)
51 {
52         return IS_ENABLED(CONFIG_DRM_I915_PXP) && pxp;
53 }
54
55 bool intel_pxp_is_enabled(const struct intel_pxp *pxp)
56 {
57         return IS_ENABLED(CONFIG_DRM_I915_PXP) && pxp && pxp->ce;
58 }
59
60 bool intel_pxp_is_active(const struct intel_pxp *pxp)
61 {
62         return IS_ENABLED(CONFIG_DRM_I915_PXP) && pxp && pxp->arb_is_valid;
63 }
64
65 static void kcr_pxp_set_status(const struct intel_pxp *pxp, bool enable)
66 {
67         u32 val = enable ? _MASKED_BIT_ENABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES) :
68                   _MASKED_BIT_DISABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES);
69
70         intel_uncore_write(pxp->ctrl_gt->uncore, KCR_INIT(pxp->kcr_base), val);
71 }
72
73 static void kcr_pxp_enable(const struct intel_pxp *pxp)
74 {
75         kcr_pxp_set_status(pxp, true);
76 }
77
78 static void kcr_pxp_disable(const struct intel_pxp *pxp)
79 {
80         kcr_pxp_set_status(pxp, false);
81 }
82
83 static int create_vcs_context(struct intel_pxp *pxp)
84 {
85         static struct lock_class_key pxp_lock;
86         struct intel_gt *gt = pxp->ctrl_gt;
87         struct intel_engine_cs *engine;
88         struct intel_context *ce;
89         int i;
90
91         /*
92          * Find the first VCS engine present. We're guaranteed there is one
93          * if we're in this function due to the check in has_pxp
94          */
95         for (i = 0, engine = NULL; !engine; i++)
96                 engine = gt->engine_class[VIDEO_DECODE_CLASS][i];
97
98         GEM_BUG_ON(!engine || engine->class != VIDEO_DECODE_CLASS);
99
100         ce = intel_engine_create_pinned_context(engine, engine->gt->vm, SZ_4K,
101                                                 I915_GEM_HWS_PXP_ADDR,
102                                                 &pxp_lock, "pxp_context");
103         if (IS_ERR(ce)) {
104                 drm_err(&gt->i915->drm, "failed to create VCS ctx for PXP\n");
105                 return PTR_ERR(ce);
106         }
107
108         pxp->ce = ce;
109
110         return 0;
111 }
112
113 static void destroy_vcs_context(struct intel_pxp *pxp)
114 {
115         if (pxp->ce)
116                 intel_engine_destroy_pinned_context(fetch_and_zero(&pxp->ce));
117 }
118
119 static void pxp_init_full(struct intel_pxp *pxp)
120 {
121         struct intel_gt *gt = pxp->ctrl_gt;
122         int ret;
123
124         /*
125          * we'll use the completion to check if there is a termination pending,
126          * so we start it as completed and we reinit it when a termination
127          * is triggered.
128          */
129         init_completion(&pxp->termination);
130         complete_all(&pxp->termination);
131
132         if (pxp->ctrl_gt->type == GT_MEDIA)
133                 pxp->kcr_base = MTL_KCR_BASE;
134         else
135                 pxp->kcr_base = GEN12_KCR_BASE;
136
137         intel_pxp_session_management_init(pxp);
138
139         ret = create_vcs_context(pxp);
140         if (ret)
141                 return;
142
143         if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
144                 ret = intel_pxp_gsccs_init(pxp);
145         else
146                 ret = intel_pxp_tee_component_init(pxp);
147         if (ret)
148                 goto out_context;
149
150         drm_info(&gt->i915->drm, "Protected Xe Path (PXP) protected content support initialized\n");
151
152         return;
153
154 out_context:
155         destroy_vcs_context(pxp);
156 }
157
158 static struct intel_gt *find_gt_for_required_teelink(struct drm_i915_private *i915)
159 {
160         /*
161          * NOTE: Only certain platforms require PXP-tee-backend dependencies
162          * for HuC authentication. For now, its limited to DG2.
163          */
164         if (IS_ENABLED(CONFIG_INTEL_MEI_PXP) && IS_ENABLED(CONFIG_INTEL_MEI_GSC) &&
165             intel_huc_is_loaded_by_gsc(&i915->gt0.uc.huc) && intel_uc_uses_huc(&i915->gt0.uc))
166                 return &i915->gt0;
167
168         return NULL;
169 }
170
171 static struct intel_gt *find_gt_for_required_protected_content(struct drm_i915_private *i915)
172 {
173         if (!IS_ENABLED(CONFIG_DRM_I915_PXP) || !INTEL_INFO(i915)->has_pxp)
174                 return NULL;
175
176         /*
177          * For MTL onwards, PXP-controller-GT needs to have a valid GSC engine
178          * on the media GT. NOTE: if we have a media-tile with a GSC-engine,
179          * the VDBOX is already present so skip that check. We also have to
180          * ensure the GSC and HUC firmware are coming online
181          */
182         if (i915->media_gt && HAS_ENGINE(i915->media_gt, GSC0) &&
183             intel_uc_fw_is_loadable(&i915->media_gt->uc.gsc.fw) &&
184             intel_uc_fw_is_loadable(&i915->media_gt->uc.huc.fw))
185                 return i915->media_gt;
186
187         /*
188          * Else we rely on mei-pxp module but only on legacy platforms
189          * prior to having separate media GTs and has a valid VDBOX.
190          */
191         if (IS_ENABLED(CONFIG_INTEL_MEI_PXP) && !i915->media_gt && VDBOX_MASK(&i915->gt0))
192                 return &i915->gt0;
193
194         return NULL;
195 }
196
197 int intel_pxp_init(struct drm_i915_private *i915)
198 {
199         struct intel_gt *gt;
200         bool is_full_feature = false;
201
202         /*
203          * NOTE: Get the ctrl_gt before checking intel_pxp_is_supported since
204          * we still need it if PXP's backend tee transport is needed.
205          */
206         gt = find_gt_for_required_protected_content(i915);
207         if (gt)
208                 is_full_feature = true;
209         else
210                 gt = find_gt_for_required_teelink(i915);
211
212         if (!gt)
213                 return -ENODEV;
214
215         /*
216          * At this point, we will either enable full featured PXP capabilities
217          * including session and object management, or we will init the backend tee
218          * channel for internal users such as HuC loading by GSC
219          */
220         i915->pxp = kzalloc(sizeof(*i915->pxp), GFP_KERNEL);
221         if (!i915->pxp)
222                 return -ENOMEM;
223
224         /* init common info used by all feature-mode usages*/
225         i915->pxp->ctrl_gt = gt;
226         mutex_init(&i915->pxp->tee_mutex);
227
228         /*
229          * If full PXP feature is not available but HuC is loaded by GSC on pre-MTL
230          * such as DG2, we can skip the init of the full PXP session/object management
231          * and just init the tee channel.
232          */
233         if (is_full_feature)
234                 pxp_init_full(i915->pxp);
235         else
236                 intel_pxp_tee_component_init(i915->pxp);
237
238         return 0;
239 }
240
241 void intel_pxp_fini(struct drm_i915_private *i915)
242 {
243         if (!i915->pxp)
244                 return;
245
246         i915->pxp->arb_is_valid = false;
247
248         if (HAS_ENGINE(i915->pxp->ctrl_gt, GSC0))
249                 intel_pxp_gsccs_fini(i915->pxp);
250         else
251                 intel_pxp_tee_component_fini(i915->pxp);
252
253         destroy_vcs_context(i915->pxp);
254
255         kfree(i915->pxp);
256         i915->pxp = NULL;
257 }
258
259 void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp)
260 {
261         pxp->arb_is_valid = false;
262         reinit_completion(&pxp->termination);
263 }
264
265 static void pxp_queue_termination(struct intel_pxp *pxp)
266 {
267         struct intel_gt *gt = pxp->ctrl_gt;
268
269         /*
270          * We want to get the same effect as if we received a termination
271          * interrupt, so just pretend that we did.
272          */
273         spin_lock_irq(gt->irq_lock);
274         intel_pxp_mark_termination_in_progress(pxp);
275         pxp->session_events |= PXP_TERMINATION_REQUEST;
276         queue_work(system_unbound_wq, &pxp->session_work);
277         spin_unlock_irq(gt->irq_lock);
278 }
279
280 static bool pxp_component_bound(struct intel_pxp *pxp)
281 {
282         bool bound = false;
283
284         mutex_lock(&pxp->tee_mutex);
285         if (pxp->pxp_component)
286                 bound = true;
287         mutex_unlock(&pxp->tee_mutex);
288
289         return bound;
290 }
291
292 int intel_pxp_get_backend_timeout_ms(struct intel_pxp *pxp)
293 {
294         if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
295                 return GSCFW_MAX_ROUND_TRIP_LATENCY_MS;
296         else
297                 return 250;
298 }
299
300 static int __pxp_global_teardown_final(struct intel_pxp *pxp)
301 {
302         int timeout;
303
304         if (!pxp->arb_is_valid)
305                 return 0;
306         /*
307          * To ensure synchronous and coherent session teardown completion
308          * in response to suspend or shutdown triggers, don't use a worker.
309          */
310         intel_pxp_mark_termination_in_progress(pxp);
311         intel_pxp_terminate(pxp, false);
312
313         timeout = intel_pxp_get_backend_timeout_ms(pxp);
314
315         if (!wait_for_completion_timeout(&pxp->termination, msecs_to_jiffies(timeout)))
316                 return -ETIMEDOUT;
317
318         return 0;
319 }
320
321 static int __pxp_global_teardown_restart(struct intel_pxp *pxp)
322 {
323         int timeout;
324
325         if (pxp->arb_is_valid)
326                 return 0;
327         /*
328          * The arb-session is currently inactive and we are doing a reset and restart
329          * due to a runtime event. Use the worker that was designed for this.
330          */
331         pxp_queue_termination(pxp);
332
333         timeout = intel_pxp_get_backend_timeout_ms(pxp);
334
335         if (!wait_for_completion_timeout(&pxp->termination, msecs_to_jiffies(timeout)))
336                 return -ETIMEDOUT;
337
338         return 0;
339 }
340
341 void intel_pxp_end(struct intel_pxp *pxp)
342 {
343         struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
344         intel_wakeref_t wakeref;
345
346         if (!intel_pxp_is_enabled(pxp))
347                 return;
348
349         wakeref = intel_runtime_pm_get(&i915->runtime_pm);
350
351         mutex_lock(&pxp->arb_mutex);
352
353         if (__pxp_global_teardown_final(pxp))
354                 drm_dbg(&i915->drm, "PXP end timed out\n");
355
356         mutex_unlock(&pxp->arb_mutex);
357
358         intel_pxp_fini_hw(pxp);
359         intel_runtime_pm_put(&i915->runtime_pm, wakeref);
360 }
361
362 /*
363  * this helper is used by both intel_pxp_start and by
364  * the GET_PARAM IOCTL that user space calls. Thus, the
365  * return values here should match the UAPI spec.
366  */
367 int intel_pxp_get_readiness_status(struct intel_pxp *pxp)
368 {
369         if (!intel_pxp_is_enabled(pxp))
370                 return -ENODEV;
371
372         if (HAS_ENGINE(pxp->ctrl_gt, GSC0)) {
373                 if (wait_for(intel_pxp_gsccs_is_ready_for_sessions(pxp), 250))
374                         return 2;
375         } else {
376                 if (wait_for(pxp_component_bound(pxp), 250))
377                         return 2;
378         }
379         return 1;
380 }
381
382 /*
383  * the arb session is restarted from the irq work when we receive the
384  * termination completion interrupt
385  */
386 int intel_pxp_start(struct intel_pxp *pxp)
387 {
388         int ret = 0;
389
390         ret = intel_pxp_get_readiness_status(pxp);
391         if (ret < 0)
392                 return ret;
393         else if (ret > 1)
394                 return -EIO; /* per UAPI spec, user may retry later */
395
396         mutex_lock(&pxp->arb_mutex);
397
398         ret = __pxp_global_teardown_restart(pxp);
399         if (ret)
400                 goto unlock;
401
402         /* make sure the compiler doesn't optimize the double access */
403         barrier();
404
405         if (!pxp->arb_is_valid)
406                 ret = -EIO;
407
408 unlock:
409         mutex_unlock(&pxp->arb_mutex);
410         return ret;
411 }
412
413 void intel_pxp_init_hw(struct intel_pxp *pxp)
414 {
415         kcr_pxp_enable(pxp);
416         intel_pxp_irq_enable(pxp);
417 }
418
419 void intel_pxp_fini_hw(struct intel_pxp *pxp)
420 {
421         kcr_pxp_disable(pxp);
422         intel_pxp_irq_disable(pxp);
423 }
424
425 int intel_pxp_key_check(struct intel_pxp *pxp,
426                         struct drm_i915_gem_object *obj,
427                         bool assign)
428 {
429         if (!intel_pxp_is_active(pxp))
430                 return -ENODEV;
431
432         if (!i915_gem_object_is_protected(obj))
433                 return -EINVAL;
434
435         GEM_BUG_ON(!pxp->key_instance);
436
437         /*
438          * If this is the first time we're using this object, it's not
439          * encrypted yet; it will be encrypted with the current key, so mark it
440          * as such. If the object is already encrypted, check instead if the
441          * used key is still valid.
442          */
443         if (!obj->pxp_key_instance && assign)
444                 obj->pxp_key_instance = pxp->key_instance;
445
446         if (obj->pxp_key_instance != pxp->key_instance)
447                 return -ENOEXEC;
448
449         return 0;
450 }
451
452 void intel_pxp_invalidate(struct intel_pxp *pxp)
453 {
454         struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
455         struct i915_gem_context *ctx, *cn;
456
457         /* ban all contexts marked as protected */
458         spin_lock_irq(&i915->gem.contexts.lock);
459         list_for_each_entry_safe(ctx, cn, &i915->gem.contexts.list, link) {
460                 struct i915_gem_engines_iter it;
461                 struct intel_context *ce;
462
463                 if (!kref_get_unless_zero(&ctx->ref))
464                         continue;
465
466                 if (likely(!i915_gem_context_uses_protected_content(ctx))) {
467                         i915_gem_context_put(ctx);
468                         continue;
469                 }
470
471                 spin_unlock_irq(&i915->gem.contexts.lock);
472
473                 /*
474                  * By the time we get here we are either going to suspend with
475                  * quiesced execution or the HW keys are already long gone and
476                  * in this case it is worthless to attempt to close the context
477                  * and wait for its execution. It will hang the GPU if it has
478                  * not already. So, as a fast mitigation, we can ban the
479                  * context as quick as we can. That might race with the
480                  * execbuffer, but currently this is the best that can be done.
481                  */
482                 for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it)
483                         intel_context_ban(ce, NULL);
484                 i915_gem_context_unlock_engines(ctx);
485
486                 /*
487                  * The context has been banned, no need to keep the wakeref.
488                  * This is safe from races because the only other place this
489                  * is touched is context_release and we're holding a ctx ref
490                  */
491                 if (ctx->pxp_wakeref) {
492                         intel_runtime_pm_put(&i915->runtime_pm,
493                                              ctx->pxp_wakeref);
494                         ctx->pxp_wakeref = 0;
495                 }
496
497                 spin_lock_irq(&i915->gem.contexts.lock);
498                 list_safe_reset_next(ctx, cn, link);
499                 i915_gem_context_put(ctx);
500         }
501         spin_unlock_irq(&i915->gem.contexts.lock);
502 }
This page took 0.061778 seconds and 4 git commands to generate.