OSDN Git Service

drm/i915/pxp: add huc authentication and loading command
authorTomas Winkler <tomas.winkler@intel.com>
Wed, 28 Sep 2022 00:41:39 +0000 (17:41 -0700)
committerDaniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Mon, 3 Oct 2022 18:29:15 +0000 (11:29 -0700)
Add support for loading HuC via a pxp stream command.

V4:
1. Remove unnecessary include in intel_pxp_huc.h (Jani)
2. Adjust copyright year to 2022

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>
Reviewed-by: Alan Previn <alan.previn.teres.alexis@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220928004145.745803-10-daniele.ceraolospurio@intel.com
drivers/gpu/drm/i915/Makefile
drivers/gpu/drm/i915/pxp/intel_pxp_huc.c [new file with mode: 0644]
drivers/gpu/drm/i915/pxp/intel_pxp_huc.h [new file with mode: 0644]
drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h

index 26fc2f2..f8cc1eb 100644 (file)
@@ -312,7 +312,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 (file)
index 0000000..7ec36d9
--- /dev/null
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2021-2022, 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 = &gt->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(&gt->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(&gt->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 (file)
index 0000000..e40847a
--- /dev/null
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2021-2022, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_HUC_H__
+#define __INTEL_PXP_HUC_H__
+
+struct intel_pxp;
+
+int intel_pxp_huc_load_and_auth(struct intel_pxp *pxp);
+
+#endif /* __INTEL_PXP_HUC_H__ */
index 36e9b08..7edc176 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: MIT */
 /*
- * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ * Copyright(c) 2020-2022, Intel Corporation. All rights reserved.
  */
 
 #ifndef __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__ */