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(>->uc.gsc.fw) || 99 !xe_uc_fw_is_loadable(>->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