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
50bool intel_pxp_is_supported(const struct intel_pxp *pxp)
51{
52	return IS_ENABLED(CONFIG_DRM_I915_PXP) && pxp;
53}
54
55bool intel_pxp_is_enabled(const struct intel_pxp *pxp)
56{
57	return IS_ENABLED(CONFIG_DRM_I915_PXP) && pxp && pxp->ce;
58}
59
60bool 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
65static 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
73static void kcr_pxp_enable(const struct intel_pxp *pxp)
74{
75	kcr_pxp_set_status(pxp, true);
76}
77
78static void kcr_pxp_disable(const struct intel_pxp *pxp)
79{
80	kcr_pxp_set_status(pxp, false);
81}
82
83static 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
113static 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
119static 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
154out_context:
155	destroy_vcs_context(pxp);
156}
157
158static 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(&to_gt(i915)->uc.huc) && intel_uc_uses_huc(&to_gt(i915)->uc))
166		return to_gt(i915);
167
168	return NULL;
169}
170
171static 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(to_gt(i915)))
192		return to_gt(i915);
193
194	return NULL;
195}
196
197int 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
241void 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
259void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp)
260{
261	pxp->arb_is_valid = false;
262	reinit_completion(&pxp->termination);
263}
264
265static 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
280static 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
292int 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
300static 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
321static 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
341void 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 */
367int 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 */
386int 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
408unlock:
409	mutex_unlock(&pxp->arb_mutex);
410	return ret;
411}
412
413void intel_pxp_init_hw(struct intel_pxp *pxp)
414{
415	kcr_pxp_enable(pxp);
416	intel_pxp_irq_enable(pxp);
417}
418
419void intel_pxp_fini_hw(struct intel_pxp *pxp)
420{
421	kcr_pxp_disable(pxp);
422	intel_pxp_irq_disable(pxp);
423}
424
425int 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
452void 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}
503