xref: /linux/drivers/gpu/drm/xe/xe_pxp.c (revision dcdd6b84d9acaa0794c29de7024cfdb20cfd7b92)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright(c) 2024 Intel Corporation.
4  */
5 
6 #include "xe_pxp.h"
7 
8 #include <drm/drm_managed.h>
9 
10 #include "xe_device_types.h"
11 #include "xe_force_wake.h"
12 #include "xe_gt.h"
13 #include "xe_gt_types.h"
14 #include "xe_mmio.h"
15 #include "xe_pxp_submit.h"
16 #include "xe_pxp_types.h"
17 #include "xe_uc_fw.h"
18 #include "regs/xe_pxp_regs.h"
19 
20 /**
21  * DOC: PXP
22  *
23  * PXP (Protected Xe Path) allows execution and flip to display of protected
24  * (i.e. encrypted) objects. This feature is currently only supported in
25  * integrated parts.
26  */
27 
28 static bool pxp_is_supported(const struct xe_device *xe)
29 {
30 	return xe->info.has_pxp && IS_ENABLED(CONFIG_INTEL_MEI_GSC_PROXY);
31 }
32 
33 static int kcr_pxp_set_status(const struct xe_pxp *pxp, bool enable)
34 {
35 	u32 val = enable ? _MASKED_BIT_ENABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES) :
36 		  _MASKED_BIT_DISABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES);
37 	unsigned int fw_ref;
38 
39 	fw_ref = xe_force_wake_get(gt_to_fw(pxp->gt), XE_FW_GT);
40 	if (!xe_force_wake_ref_has_domain(fw_ref, XE_FW_GT))
41 		return -EIO;
42 
43 	xe_mmio_write32(&pxp->gt->mmio, KCR_INIT, val);
44 	xe_force_wake_put(gt_to_fw(pxp->gt), fw_ref);
45 
46 	return 0;
47 }
48 
49 static int kcr_pxp_enable(const struct xe_pxp *pxp)
50 {
51 	return kcr_pxp_set_status(pxp, true);
52 }
53 
54 static int kcr_pxp_disable(const struct xe_pxp *pxp)
55 {
56 	return kcr_pxp_set_status(pxp, false);
57 }
58 
59 static void pxp_fini(void *arg)
60 {
61 	struct xe_pxp *pxp = arg;
62 
63 	xe_pxp_destroy_execution_resources(pxp);
64 
65 	/* no need to explicitly disable KCR since we're going to do an FLR */
66 }
67 
68 /**
69  * xe_pxp_init - initialize PXP support
70  * @xe: the xe_device structure
71  *
72  * Initialize the HW state and allocate the objects required for PXP support.
73  * Note that some of the requirement for PXP support (GSC proxy init, HuC auth)
74  * are performed asynchronously as part of the GSC init. PXP can only be used
75  * after both this function and the async worker have completed.
76  *
77  * Returns -EOPNOTSUPP if PXP is not supported, 0 if PXP initialization is
78  * successful, other errno value if there is an error during the init.
79  */
80 int xe_pxp_init(struct xe_device *xe)
81 {
82 	struct xe_gt *gt = xe->tiles[0].media_gt;
83 	struct xe_pxp *pxp;
84 	int err;
85 
86 	if (!pxp_is_supported(xe))
87 		return -EOPNOTSUPP;
88 
89 	/* we only support PXP on single tile devices with a media GT */
90 	if (xe->info.tile_count > 1 || !gt)
91 		return -EOPNOTSUPP;
92 
93 	/* The GSCCS is required for submissions to the GSC FW */
94 	if (!(gt->info.engine_mask & BIT(XE_HW_ENGINE_GSCCS0)))
95 		return -EOPNOTSUPP;
96 
97 	/* PXP requires both GSC and HuC firmwares to be available */
98 	if (!xe_uc_fw_is_loadable(&gt->uc.gsc.fw) ||
99 	    !xe_uc_fw_is_loadable(&gt->uc.huc.fw)) {
100 		drm_info(&xe->drm, "skipping PXP init due to missing FW dependencies");
101 		return -EOPNOTSUPP;
102 	}
103 
104 	pxp = drmm_kzalloc(&xe->drm, sizeof(struct xe_pxp), GFP_KERNEL);
105 	if (!pxp)
106 		return -ENOMEM;
107 
108 	pxp->xe = xe;
109 	pxp->gt = gt;
110 
111 	err = kcr_pxp_enable(pxp);
112 	if (err)
113 		goto out_free;
114 
115 	err = xe_pxp_allocate_execution_resources(pxp);
116 	if (err)
117 		goto out_kcr_disable;
118 
119 	xe->pxp = pxp;
120 
121 	return devm_add_action_or_reset(xe->drm.dev, pxp_fini, pxp);
122 
123 out_kcr_disable:
124 	kcr_pxp_disable(pxp);
125 out_free:
126 	drmm_kfree(&xe->drm, pxp);
127 	return err;
128 }
129