Message ID | 20220609231955.3632596-10-daniele.ceraolospurio@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | HuC loading for DG2 | expand |
Reviewed-by: Alan Previn <alan.previn.teres.alexis@intel.com> On 6/9/2022 4:19 PM, Ceraolo Spurio, Daniele wrote: > From: Tomas Winkler <tomas.winkler@intel.com> > > Add support for loading HuC via a pxp stream command. > > Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> > Signed-off-by: Vitaly Lubart <vitaly.lubart@intel.com> > Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> > Cc: Alan Previn <alan.previn.teres.alexis@intel.com> > --- > drivers/gpu/drm/i915/Makefile | 3 +- > drivers/gpu/drm/i915/pxp/intel_pxp_huc.c | 69 +++++++++++++++++++ > drivers/gpu/drm/i915/pxp/intel_pxp_huc.h | 15 ++++ > .../drm/i915/pxp/intel_pxp_tee_interface.h | 21 ++++++ > 4 files changed, 107 insertions(+), 1 deletion(-) > create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_huc.c > create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_huc.h > > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile > index 5d3aa4807def..8d90e653958c 100644 > --- a/drivers/gpu/drm/i915/Makefile > +++ b/drivers/gpu/drm/i915/Makefile > @@ -306,7 +306,8 @@ i915-y += i915_perf.o > # Protected execution platform (PXP) support. Base support is required for HuC > i915-y += \ > pxp/intel_pxp.o \ > - pxp/intel_pxp_tee.o > + pxp/intel_pxp_tee.o \ > + pxp/intel_pxp_huc.o > > i915-$(CONFIG_DRM_I915_PXP) += \ > pxp/intel_pxp_cmd.o \ > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_huc.c b/drivers/gpu/drm/i915/pxp/intel_pxp_huc.c > new file mode 100644 > index 000000000000..6d25f436f329 > --- /dev/null > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_huc.c > @@ -0,0 +1,69 @@ > +// SPDX-License-Identifier: MIT > +/* > + * Copyright(c) 2021, Intel Corporation. All rights reserved. > + */ > + > +#include "drm/i915_drm.h" > +#include "i915_drv.h" > + > +#include "gem/i915_gem_region.h" > +#include "gt/intel_gt.h" > + > +#include "intel_pxp.h" > +#include "intel_pxp_huc.h" > +#include "intel_pxp_tee.h" > +#include "intel_pxp_types.h" > +#include "intel_pxp_tee_interface.h" > + > +int intel_pxp_huc_load_and_auth(struct intel_pxp *pxp) > +{ > + struct intel_gt *gt = pxp_to_gt(pxp); > + struct intel_huc *huc = >->uc.huc; > + struct pxp_tee_start_huc_auth_in huc_in = {0}; > + struct pxp_tee_start_huc_auth_out huc_out = {0}; > + dma_addr_t huc_phys_addr; > + u8 client_id = 0; > + u8 fence_id = 0; > + int err; > + > + if (!pxp->pxp_component) > + return -ENODEV; > + > + huc_phys_addr = i915_gem_object_get_dma_address(huc->fw.obj, 0); > + > + /* write the PXP message into the lmem (the sg list) */ > + huc_in.header.api_version = PXP_TEE_43_APIVER; > + huc_in.header.command_id = PXP_TEE_43_START_HUC_AUTH; > + huc_in.header.status = 0; > + huc_in.header.buffer_len = sizeof(huc_in.huc_base_address); > + huc_in.huc_base_address = huc_phys_addr; > + > + err = intel_pxp_tee_stream_message(pxp, client_id, fence_id, > + &huc_in, sizeof(huc_in), > + &huc_out, sizeof(huc_out)); > + if (err < 0) { > + drm_err(>->i915->drm, > + "Failed to send HuC load and auth command to GSC [%d]!\n", > + err); > + return err; > + } > + > + /* > + * HuC does sometimes survive suspend/resume (it depends on how "deep" > + * a sleep state the device reaches) so we can end up here on resume > + * with HuC already loaded, in which case the GSC will return > + * PXP_STATUS_OP_NOT_PERMITTED. We can therefore consider the GuC > + * correctly transferred in this scenario; if the same error is ever > + * returned with HuC not loaded we'll still catch it when we check the > + * authentication bit later. > + */ > + if (huc_out.header.status != PXP_STATUS_SUCCESS && > + huc_out.header.status != PXP_STATUS_OP_NOT_PERMITTED) { > + drm_err(>->i915->drm, > + "HuC load failed with GSC error = 0x%x\n", > + huc_out.header.status); > + return -EPROTO; > + } > + > + return 0; > +} > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_huc.h b/drivers/gpu/drm/i915/pxp/intel_pxp_huc.h > new file mode 100644 > index 000000000000..6cf2d00548c0 > --- /dev/null > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_huc.h > @@ -0,0 +1,15 @@ > +/* SPDX-License-Identifier: MIT */ > +/* > + * Copyright(c) 2021, Intel Corporation. All rights reserved. > + */ > + > +#ifndef __INTEL_PXP_HUC_H__ > +#define __INTEL_PXP_HUC_H__ > + > +#include <linux/types.h> > + > +struct intel_pxp; > + > +int intel_pxp_huc_load_and_auth(struct intel_pxp *pxp); > + > +#endif /* __INTEL_PXP_HUC_H__ */ > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h b/drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h > index 36e9b0868f5c..1de98959a89d 100644 > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h > @@ -9,8 +9,20 @@ > #include <linux/types.h> > > #define PXP_TEE_APIVER 0x40002 > +#define PXP_TEE_43_APIVER 0x00040003 > #define PXP_TEE_ARB_CMDID 0x1e > #define PXP_TEE_ARB_PROTECTION_MODE 0x2 > +#define PXP_TEE_43_START_HUC_AUTH 0x0000003A > + > +/* > + * there are a lot of status codes for PXP, but we only define the ones we > + * actually can handle in the driver. other failure codes will be printed to > + * error msg for debug. > + */ > +enum pxp_status { > + PXP_STATUS_SUCCESS = 0x0, > + PXP_STATUS_OP_NOT_PERMITTED = 0x4013 > +}; > > /* PXP TEE message header */ > struct pxp_tee_cmd_header { > @@ -33,4 +45,13 @@ struct pxp_tee_create_arb_out { > struct pxp_tee_cmd_header header; > } __packed; > > +struct pxp_tee_start_huc_auth_in { > + struct pxp_tee_cmd_header header; > + __le64 huc_base_address; > +}; > + > +struct pxp_tee_start_huc_auth_out { > + struct pxp_tee_cmd_header header; > +}; > + > #endif /* __INTEL_PXP_TEE_INTERFACE_H__ */
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 5d3aa4807def..8d90e653958c 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -306,7 +306,8 @@ i915-y += i915_perf.o # Protected execution platform (PXP) support. Base support is required for HuC i915-y += \ pxp/intel_pxp.o \ - pxp/intel_pxp_tee.o + pxp/intel_pxp_tee.o \ + pxp/intel_pxp_huc.o i915-$(CONFIG_DRM_I915_PXP) += \ pxp/intel_pxp_cmd.o \ diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_huc.c b/drivers/gpu/drm/i915/pxp/intel_pxp_huc.c new file mode 100644 index 000000000000..6d25f436f329 --- /dev/null +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_huc.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright(c) 2021, Intel Corporation. All rights reserved. + */ + +#include "drm/i915_drm.h" +#include "i915_drv.h" + +#include "gem/i915_gem_region.h" +#include "gt/intel_gt.h" + +#include "intel_pxp.h" +#include "intel_pxp_huc.h" +#include "intel_pxp_tee.h" +#include "intel_pxp_types.h" +#include "intel_pxp_tee_interface.h" + +int intel_pxp_huc_load_and_auth(struct intel_pxp *pxp) +{ + struct intel_gt *gt = pxp_to_gt(pxp); + struct intel_huc *huc = >->uc.huc; + struct pxp_tee_start_huc_auth_in huc_in = {0}; + struct pxp_tee_start_huc_auth_out huc_out = {0}; + dma_addr_t huc_phys_addr; + u8 client_id = 0; + u8 fence_id = 0; + int err; + + if (!pxp->pxp_component) + return -ENODEV; + + huc_phys_addr = i915_gem_object_get_dma_address(huc->fw.obj, 0); + + /* write the PXP message into the lmem (the sg list) */ + huc_in.header.api_version = PXP_TEE_43_APIVER; + huc_in.header.command_id = PXP_TEE_43_START_HUC_AUTH; + huc_in.header.status = 0; + huc_in.header.buffer_len = sizeof(huc_in.huc_base_address); + huc_in.huc_base_address = huc_phys_addr; + + err = intel_pxp_tee_stream_message(pxp, client_id, fence_id, + &huc_in, sizeof(huc_in), + &huc_out, sizeof(huc_out)); + if (err < 0) { + drm_err(>->i915->drm, + "Failed to send HuC load and auth command to GSC [%d]!\n", + err); + return err; + } + + /* + * HuC does sometimes survive suspend/resume (it depends on how "deep" + * a sleep state the device reaches) so we can end up here on resume + * with HuC already loaded, in which case the GSC will return + * PXP_STATUS_OP_NOT_PERMITTED. We can therefore consider the GuC + * correctly transferred in this scenario; if the same error is ever + * returned with HuC not loaded we'll still catch it when we check the + * authentication bit later. + */ + if (huc_out.header.status != PXP_STATUS_SUCCESS && + huc_out.header.status != PXP_STATUS_OP_NOT_PERMITTED) { + drm_err(>->i915->drm, + "HuC load failed with GSC error = 0x%x\n", + huc_out.header.status); + return -EPROTO; + } + + return 0; +} diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_huc.h b/drivers/gpu/drm/i915/pxp/intel_pxp_huc.h new file mode 100644 index 000000000000..6cf2d00548c0 --- /dev/null +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_huc.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright(c) 2021, Intel Corporation. All rights reserved. + */ + +#ifndef __INTEL_PXP_HUC_H__ +#define __INTEL_PXP_HUC_H__ + +#include <linux/types.h> + +struct intel_pxp; + +int intel_pxp_huc_load_and_auth(struct intel_pxp *pxp); + +#endif /* __INTEL_PXP_HUC_H__ */ diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h b/drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h index 36e9b0868f5c..1de98959a89d 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h @@ -9,8 +9,20 @@ #include <linux/types.h> #define PXP_TEE_APIVER 0x40002 +#define PXP_TEE_43_APIVER 0x00040003 #define PXP_TEE_ARB_CMDID 0x1e #define PXP_TEE_ARB_PROTECTION_MODE 0x2 +#define PXP_TEE_43_START_HUC_AUTH 0x0000003A + +/* + * there are a lot of status codes for PXP, but we only define the ones we + * actually can handle in the driver. other failure codes will be printed to + * error msg for debug. + */ +enum pxp_status { + PXP_STATUS_SUCCESS = 0x0, + PXP_STATUS_OP_NOT_PERMITTED = 0x4013 +}; /* PXP TEE message header */ struct pxp_tee_cmd_header { @@ -33,4 +45,13 @@ struct pxp_tee_create_arb_out { struct pxp_tee_cmd_header header; } __packed; +struct pxp_tee_start_huc_auth_in { + struct pxp_tee_cmd_header header; + __le64 huc_base_address; +}; + +struct pxp_tee_start_huc_auth_out { + struct pxp_tee_cmd_header header; +}; + #endif /* __INTEL_PXP_TEE_INTERFACE_H__ */