* [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL
@ 2023-04-28 18:58 Daniele Ceraolo Spurio
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 1/8] DO NOT REVIEW: drm/i915: Add support for MTL GSC SW Proxy Daniele Ceraolo Spurio
` (17 more replies)
0 siblings, 18 replies; 32+ messages in thread
From: Daniele Ceraolo Spurio @ 2023-04-28 18:58 UTC (permalink / raw)
To: intel-gfx; +Cc: Alan Previn, dri-devel
The HuC loading and authentication flow is once again changing and a new
"clear-media only" authentication step is introduced. The flow is as
follows:
1) The HuC is loaded via DMA - same as all non-GSC HuC binaries.
2) The HuC is authenticated by the GuC - this is the same step as
performed for all non-GSC HuC binaries and re-uses the same code, but
it is now resulting in a partial authentication that only allows
clear-media workloads.
3) The HuC is fully authenticated for all workloads by the GSC - this
is done via a new PXP command, submitted via the GSCCS.
The advantage of this new flow is that we can start processing
clear-media workloads without having to wait for the GSC to be ready,
which can take several seconds.
As part of this change, the HuC status getparam has been updated with a
new value to indicate a partial authentication. Note tha the media
driver is checking for value > 0 for clear media workloads, so no
changes are required in userspace for that to work.
The SW proxy series [1] has been included, squashed in a single patch,
as some of some of the patches in this series depend on it. This is not
a functional dependencies, the patches just touch the same code; the
proxy patches are planned to be merged first, so it is easier to base
the new patches on top of it to avoid having to rebase them later.
v2: fix HuC auth status check for DG2.
[1] https://patchwork.freedesktop.org/series/115806/
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
Acked-by: Tony Ye <tony.ye@intel.com>
Daniele Ceraolo Spurio (8):
DO NOT REVIEW: drm/i915: Add support for MTL GSC SW Proxy
drm/i915/uc: perma-pin firmwares
drm/i915/huc: Parse the GSC-enabled HuC binary
drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so
drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow
drm/i915/mtl/huc: auth HuC via GSC
drm/i915/mtl/huc: Use the media gt for the HuC getparam
drm/i915/huc: define HuC FW version for MTL
drivers/gpu/drm/i915/Makefile | 1 +
drivers/gpu/drm/i915/gt/intel_ggtt.c | 3 +
drivers/gpu/drm/i915/gt/intel_gt_irq.c | 22 +-
drivers/gpu/drm/i915/gt/intel_gt_regs.h | 3 +
.../drm/i915/gt/uc/intel_gsc_meu_headers.h | 74 +++
drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c | 424 ++++++++++++++++++
drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.h | 18 +
drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 89 +++-
drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h | 17 +-
.../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c | 2 +-
.../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h | 1 +
drivers/gpu/drm/i915/gt/uc/intel_guc.c | 2 +-
drivers/gpu/drm/i915/gt/uc/intel_huc.c | 182 +++++---
drivers/gpu/drm/i915/gt/uc/intel_huc.h | 26 +-
drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 214 ++++++++-
drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h | 6 +-
drivers/gpu/drm/i915/gt/uc/intel_huc_print.h | 21 +
drivers/gpu/drm/i915/gt/uc/intel_uc.c | 10 +-
drivers/gpu/drm/i915/gt/uc/intel_uc.h | 2 +
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 120 ++---
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h | 9 +-
drivers/gpu/drm/i915/i915_getparam.c | 6 +-
drivers/gpu/drm/i915/i915_reg.h | 3 +
.../drm/i915/pxp/intel_pxp_cmd_interface_43.h | 14 +-
drivers/gpu/drm/i915/pxp/intel_pxp_huc.c | 2 +-
drivers/misc/mei/Kconfig | 2 +-
drivers/misc/mei/Makefile | 1 +
drivers/misc/mei/gsc_proxy/Kconfig | 14 +
drivers/misc/mei/gsc_proxy/Makefile | 7 +
drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c | 208 +++++++++
include/drm/i915_component.h | 3 +-
include/drm/i915_gsc_proxy_mei_interface.h | 53 +++
include/uapi/drm/i915_drm.h | 3 +-
33 files changed, 1428 insertions(+), 134 deletions(-)
create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.h
create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_huc_print.h
create mode 100644 drivers/misc/mei/gsc_proxy/Kconfig
create mode 100644 drivers/misc/mei/gsc_proxy/Makefile
create mode 100644 drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c
create mode 100644 include/drm/i915_gsc_proxy_mei_interface.h
--
2.40.0
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Intel-gfx] [PATCH v2 1/8] DO NOT REVIEW: drm/i915: Add support for MTL GSC SW Proxy
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
@ 2023-04-28 18:58 ` Daniele Ceraolo Spurio
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 2/8] drm/i915/uc: perma-pin firmwares Daniele Ceraolo Spurio
` (16 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Daniele Ceraolo Spurio @ 2023-04-28 18:58 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel
This is a squash of the GSC proxy series, which is being reviewed
separately [1]. It's being included here because some of the patches in
this series depend on it. This is not a functional dependencies, the
patches just touch the same code and the proxy patches are planned to be
merged first, so it is easier to base the new patches on top of it.
[1] https://patchwork.freedesktop.org/series/115806/
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
---
drivers/gpu/drm/i915/Makefile | 1 +
drivers/gpu/drm/i915/gt/intel_gt_irq.c | 22 +-
drivers/gpu/drm/i915/gt/intel_gt_regs.h | 3 +
drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c | 424 ++++++++++++++++++
drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.h | 18 +
drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 66 ++-
drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h | 17 +-
.../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h | 1 +
drivers/misc/mei/Kconfig | 2 +-
drivers/misc/mei/Makefile | 1 +
drivers/misc/mei/gsc_proxy/Kconfig | 14 +
drivers/misc/mei/gsc_proxy/Makefile | 7 +
drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c | 208 +++++++++
include/drm/i915_component.h | 3 +-
include/drm/i915_gsc_proxy_mei_interface.h | 53 +++
15 files changed, 830 insertions(+), 10 deletions(-)
create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.h
create mode 100644 drivers/misc/mei/gsc_proxy/Kconfig
create mode 100644 drivers/misc/mei/gsc_proxy/Makefile
create mode 100644 drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c
create mode 100644 include/drm/i915_gsc_proxy_mei_interface.h
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 9af76e376ca9..f2ac803e35b4 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -194,6 +194,7 @@ i915-y += \
# general-purpose microcontroller (GuC) support
i915-y += \
gt/uc/intel_gsc_fw.o \
+ gt/uc/intel_gsc_proxy.o \
gt/uc/intel_gsc_uc.o \
gt/uc/intel_gsc_uc_heci_cmd_submit.o\
gt/uc/intel_guc.o \
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
index c0f3ff4746ad..95e59ed6651d 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
@@ -16,6 +16,7 @@
#include "intel_uncore.h"
#include "intel_rps.h"
#include "pxp/intel_pxp_irq.h"
+#include "uc/intel_gsc_proxy.h"
static void guc_irq_handler(struct intel_guc *guc, u16 iir)
{
@@ -82,6 +83,9 @@ gen11_other_irq_handler(struct intel_gt *gt, const u8 instance,
if (instance == OTHER_GSC_INSTANCE)
return intel_gsc_irq_handler(gt, iir);
+ if (instance == OTHER_GSC_HECI_2_INSTANCE)
+ return intel_gsc_proxy_irq_handler(>->uc.gsc, iir);
+
WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n",
instance, iir);
}
@@ -101,6 +105,8 @@ static struct intel_gt *pick_gt(struct intel_gt *gt, u8 class, u8 instance)
case VIDEO_ENHANCEMENT_CLASS:
return media_gt;
case OTHER_CLASS:
+ if (instance == OTHER_GSC_HECI_2_INSTANCE)
+ return media_gt;
if (instance == OTHER_GSC_INSTANCE && HAS_ENGINE(media_gt, GSC0))
return media_gt;
fallthrough;
@@ -257,6 +263,7 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
u32 irqs = GT_RENDER_USER_INTERRUPT;
u32 guc_mask = intel_uc_wants_guc(>->uc) ? GUC_INTR_GUC2HOST : 0;
u32 gsc_mask = 0;
+ u32 heci_mask = 0;
u32 dmask;
u32 smask;
@@ -268,10 +275,16 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
dmask = irqs << 16 | irqs;
smask = irqs << 16;
- if (HAS_ENGINE(gt, GSC0))
+ if (HAS_ENGINE(gt, GSC0)) {
+ /*
+ * the heci2 interrupt is enabled via the same register as the
+ * GSC interrupt, but it has its own mask register.
+ */
gsc_mask = irqs;
- else if (HAS_HECI_GSC(gt->i915))
+ heci_mask = GSC_IRQ_INTF(1); /* HECI2 IRQ for SW Proxy*/
+ } else if (HAS_HECI_GSC(gt->i915)) {
gsc_mask = GSC_IRQ_INTF(0) | GSC_IRQ_INTF(1);
+ }
BUILD_BUG_ON(irqs & 0xffff0000);
@@ -281,7 +294,7 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
if (CCS_MASK(gt))
intel_uncore_write(uncore, GEN12_CCS_RSVD_INTR_ENABLE, smask);
if (gsc_mask)
- intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_ENABLE, gsc_mask);
+ intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_ENABLE, gsc_mask | heci_mask);
/* Unmask irqs on RCS, BCS, VCS and VECS engines. */
intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK, ~smask);
@@ -309,6 +322,9 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
intel_uncore_write(uncore, GEN12_CCS2_CCS3_INTR_MASK, ~dmask);
if (gsc_mask)
intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_MASK, ~gsc_mask);
+ if (heci_mask)
+ intel_uncore_write(uncore, GEN12_HECI2_RSVD_INTR_MASK,
+ ~REG_FIELD_PREP(ENGINE1_MASK, heci_mask));
if (guc_mask) {
/* the enable bit is common for both GTs but the masks are separate */
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index af80d2fe739b..b8a39c219b60 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -1596,6 +1596,7 @@
#define GEN11_GT_INTR_DW(x) _MMIO(0x190018 + ((x) * 4))
#define GEN11_CSME (31)
+#define GEN12_HECI_2 (30)
#define GEN11_GUNIT (28)
#define GEN11_GUC (25)
#define MTL_MGUC (24)
@@ -1637,6 +1638,7 @@
/* irq instances for OTHER_CLASS */
#define OTHER_GUC_INSTANCE 0
#define OTHER_GTPM_INSTANCE 1
+#define OTHER_GSC_HECI_2_INSTANCE 3
#define OTHER_KCR_INSTANCE 4
#define OTHER_GSC_INSTANCE 6
#define OTHER_MEDIA_GUC_INSTANCE 16
@@ -1652,6 +1654,7 @@
#define GEN12_VCS6_VCS7_INTR_MASK _MMIO(0x1900b4)
#define GEN11_VECS0_VECS1_INTR_MASK _MMIO(0x1900d0)
#define GEN12_VECS2_VECS3_INTR_MASK _MMIO(0x1900d4)
+#define GEN12_HECI2_RSVD_INTR_MASK _MMIO(0x1900e4)
#define GEN11_GUC_SG_INTR_MASK _MMIO(0x1900e8)
#define MTL_GUC_MGUC_INTR_MASK _MMIO(0x1900e8) /* MTL+ */
#define GEN11_GPM_WGBOXPERF_INTR_MASK _MMIO(0x1900ec)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
new file mode 100644
index 000000000000..3fa925f89dcc
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
@@ -0,0 +1,424 @@
+#include "intel_gsc_proxy.h"
+
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#include <linux/component.h>
+
+#include "drm/i915_component.h"
+#include "drm/i915_gsc_proxy_mei_interface.h"
+
+#include "gt/intel_gt.h"
+#include "gt/intel_gt_print.h"
+#include "intel_gsc_uc.h"
+#include "intel_gsc_uc_heci_cmd_submit.h"
+#include "i915_drv.h"
+#include "i915_reg.h"
+
+/*
+ * GSC proxy:
+ * The GSC uC needs to communicate with the CSME to perform certain operations.
+ * Since the GSC can't perform this communication directly on platforms where it
+ * is integrated in GT, i915 needs to transfer the messages from GSC to CSME
+ * and back. i915 must manually start the proxy flow after the GSC is loaded to
+ * signal to GSC that we're ready to handle its messages and allow it to query
+ * its init data from CSME; GSC will then trigger an HECI2 interrupt if it needs
+ * to send messages to CSME again.
+ * The proxy flow is as follow:
+ * 1 - i915 submits a request to GSC asking for the message to CSME
+ * 2 - GSC replies with the proxy header + payload for CSME
+ * 3 - i915 sends the reply from GSC as-is to CSME via the mei proxy component
+ * 4 - CSME replies with the proxy header + payload for GSC
+ * 5 - i915 submits a request to GSC with the reply from CSME
+ * 6 - GSC replies either with a new header + payload (same as step 2, so we
+ * restart from there) or with an end message.
+ */
+
+/*
+ * The component should load quite quickly in most cases, but it could take
+ * a bit. Using a very big timeout just to cover the worst case scenario
+ */
+#define GSC_PROXY_INIT_TIMEOUT_MS 20000
+
+/* the protocol supports up to 32K in each direction */
+#define GSC_PROXY_BUFFER_SIZE SZ_32K
+#define GSC_PROXY_CHANNEL_SIZE (GSC_PROXY_BUFFER_SIZE * 2)
+#define GSC_PROXY_MAX_MSG_SIZE (GSC_PROXY_BUFFER_SIZE - sizeof(struct intel_gsc_mtl_header))
+
+/* FW-defined proxy header */
+struct intel_gsc_proxy_header {
+ /*
+ * hdr:
+ * Bits 0-7: type of the proxy message (see enum intel_gsc_proxy_type)
+ * Bits 8-15: rsvd
+ * Bits 16-31: length in bytes of the payload following the proxy header
+ */
+ u32 hdr;
+#define GSC_PROXY_TYPE GENMASK(7, 0)
+#define GSC_PROXY_PAYLOAD_LENGTH GENMASK(31, 16)
+
+ u32 source; /* Source of the Proxy message */
+ u32 destination; /* Destination of the Proxy message */
+#define GSC_PROXY_ADDRESSING_KMD 0x10000
+#define GSC_PROXY_ADDRESSING_GSC 0x20000
+#define GSC_PROXY_ADDRESSING_CSME 0x30000
+
+ u32 status; /* Command status */
+} __packed;
+
+/* FW-defined proxy types */
+enum intel_gsc_proxy_type {
+ GSC_PROXY_MSG_TYPE_PROXY_INVALID = 0,
+ GSC_PROXY_MSG_TYPE_PROXY_QUERY = 1,
+ GSC_PROXY_MSG_TYPE_PROXY_PAYLOAD = 2,
+ GSC_PROXY_MSG_TYPE_PROXY_END = 3,
+ GSC_PROXY_MSG_TYPE_PROXY_NOTIFICATION = 4,
+};
+
+struct gsc_proxy_msg {
+ struct intel_gsc_mtl_header header;
+ struct intel_gsc_proxy_header proxy_header;
+} __packed;
+
+static int proxy_send_to_csme(struct intel_gsc_uc *gsc)
+{
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+ struct i915_gsc_proxy_component *comp = gsc->proxy.component;
+ struct intel_gsc_mtl_header *hdr;
+ void *in = gsc->proxy.to_csme;
+ void *out = gsc->proxy.to_gsc;
+ u32 in_size;
+ int ret;
+
+ /* CSME msg only includes the proxy */
+ hdr = in;
+ in += sizeof(struct intel_gsc_mtl_header);
+ out += sizeof(struct intel_gsc_mtl_header);
+
+ in_size = hdr->message_size - sizeof(struct intel_gsc_mtl_header);
+
+ /* the message must contain at least the proxy header */
+ if (in_size < sizeof(struct intel_gsc_proxy_header) ||
+ in_size > GSC_PROXY_MAX_MSG_SIZE) {
+ gt_err(gt, "Invalid CSME message size: %u\n", in_size);
+ return -EINVAL;
+ }
+
+ ret = comp->ops->send(comp->mei_dev, in, in_size);
+ if (ret < 0) {
+ gt_err(gt, "Failed to send CSME message\n");
+ return ret;
+ }
+
+ ret = comp->ops->recv(comp->mei_dev, out, GSC_PROXY_MAX_MSG_SIZE);
+ if (ret < 0) {
+ gt_err(gt, "Failed to receive CSME message\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+static int proxy_send_to_gsc(struct intel_gsc_uc *gsc)
+{
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+ u32 *marker = gsc->proxy.to_csme; /* first dw of the reply header */
+ u64 addr_in = i915_ggtt_offset(gsc->proxy.vma);
+ u64 addr_out = addr_in + GSC_PROXY_BUFFER_SIZE;
+ u32 size = ((struct gsc_proxy_msg *)gsc->proxy.to_gsc)->header.message_size;
+ int err;
+
+ /* the message must contain at least the gsc and proxy headers */
+ if (size < sizeof(struct gsc_proxy_msg) || size > GSC_PROXY_BUFFER_SIZE) {
+ gt_err(gt, "Invalid GSC proxy message size: %u\n", size);
+ return -EINVAL;
+ }
+
+ /* clear the message marker */
+ *marker = 0;
+ wmb();
+
+ /* send the request */
+ err = intel_gsc_uc_heci_cmd_submit_packet(gsc, addr_in, size,
+ addr_out, GSC_PROXY_BUFFER_SIZE);
+
+ if (!err) {
+ /* wait for the reply to show up */
+ err = wait_for(*marker != 0, 300);
+ if (err)
+ gt_err(gt, "Failed to get a proxy reply from gsc\n");
+ }
+
+ return err;
+}
+
+static int validate_proxy_header(struct intel_gsc_proxy_header *header,
+ u32 source, u32 dest)
+{
+ u32 type = FIELD_GET(GSC_PROXY_TYPE, header->hdr);
+ u32 length = FIELD_GET(GSC_PROXY_PAYLOAD_LENGTH, header->hdr);
+ int ret = 0;
+
+ if (header->destination != dest || header->source != source) {
+ ret = -ENOEXEC;
+ goto fail;
+ }
+
+ switch (type) {
+ case GSC_PROXY_MSG_TYPE_PROXY_PAYLOAD:
+ if (length > 0)
+ break;
+ fallthrough;
+ case GSC_PROXY_MSG_TYPE_PROXY_INVALID:
+ ret = -EIO;
+ goto fail;
+ default:
+ break;
+ }
+
+fail:
+ return ret;
+
+}
+
+static int proxy_query(struct intel_gsc_uc *gsc)
+{
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+ struct gsc_proxy_msg *to_gsc = gsc->proxy.to_gsc;
+ struct gsc_proxy_msg *to_csme = gsc->proxy.to_csme;
+ int ret;
+
+ intel_gsc_uc_heci_cmd_emit_mtl_header(&to_gsc->header,
+ HECI_MEADDRESS_PROXY,
+ sizeof(struct gsc_proxy_msg),
+ 0);
+
+ to_gsc->proxy_header.hdr =
+ FIELD_PREP(GSC_PROXY_TYPE, GSC_PROXY_MSG_TYPE_PROXY_QUERY) |
+ FIELD_PREP(GSC_PROXY_PAYLOAD_LENGTH, 0);
+
+ to_gsc->proxy_header.source = GSC_PROXY_ADDRESSING_KMD;
+ to_gsc->proxy_header.destination = GSC_PROXY_ADDRESSING_GSC;
+ to_gsc->proxy_header.status = 0;
+
+ while (1) {
+ /* clear the GSC response header space */
+ memset(gsc->proxy.to_csme, 0, sizeof(struct gsc_proxy_msg));
+
+ /* send proxy message to GSC */
+ ret = proxy_send_to_gsc(gsc);
+ if (ret) {
+ gt_err(gt, "failed to send proxy message to GSC! %d\n", ret);
+ goto proxy_error;
+ }
+
+ /* stop if this was the last message */
+ if (FIELD_GET(GSC_PROXY_TYPE, to_csme->proxy_header.hdr) ==
+ GSC_PROXY_MSG_TYPE_PROXY_END)
+ break;
+
+ /* make sure the GSC-to-CSME proxy header is sane */
+ ret = validate_proxy_header(&to_csme->proxy_header,
+ GSC_PROXY_ADDRESSING_GSC,
+ GSC_PROXY_ADDRESSING_CSME);
+ if (ret) {
+ gt_err(gt, "invalid GSC to CSME proxy header! %d\n", ret);
+ goto proxy_error;
+ }
+
+ /* send the GSC message to the CSME */
+ ret = proxy_send_to_csme(gsc);
+ if (ret < 0) {
+ gt_err(gt, "failed to send proxy message to CSME! %d\n", ret);
+ goto proxy_error;
+ }
+
+ /* update the GSC message size with the returned value from CSME */
+ to_gsc->header.message_size = ret + sizeof(struct intel_gsc_mtl_header);
+
+ /* make sure the CSME-to-GSC proxy header is sane */
+ ret = validate_proxy_header(&to_gsc->proxy_header,
+ GSC_PROXY_ADDRESSING_CSME,
+ GSC_PROXY_ADDRESSING_GSC);
+ if (ret) {
+ gt_err(gt, "invalid CSME to GSC proxy header! %d\n", ret);
+ goto proxy_error;
+ }
+ }
+
+proxy_error:
+ return ret < 0 ? ret : 0;
+}
+
+int intel_gsc_proxy_request_handler(struct intel_gsc_uc *gsc)
+{
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+ int err;
+
+ if (!gsc->proxy.component_added)
+ return -ENODEV;
+
+ assert_rpm_wakelock_held(gt->uncore->rpm);
+
+ /* when GSC is loaded, we can queue this before the component is bound */
+ err = wait_for(gsc->proxy.component, GSC_PROXY_INIT_TIMEOUT_MS);
+ if (err) {
+ gt_err(gt, "GSC proxy component didn't bind within the expected timeout\n");
+ return -EIO;
+ }
+
+ mutex_lock(&gsc->proxy.mutex);
+ if (!gsc->proxy.component) {
+ gt_err(gt, "GSC proxy worker called without the component being bound!\n");
+ err = -EIO;
+ } else {
+ /*
+ * write the status bit to clear it and allow new proxy
+ * interrupts to be generated while we handle the current
+ * request, but be sure not to write the reset bit
+ */
+ intel_uncore_rmw(gt->uncore, HECI_H_CSR(MTL_GSC_HECI2_BASE),
+ HECI_H_CSR_RST, HECI_H_CSR_IS);
+ err = proxy_query(gsc);
+ }
+ mutex_unlock(&gsc->proxy.mutex);
+ return err;
+}
+
+void intel_gsc_proxy_irq_handler(struct intel_gsc_uc *gsc, u32 iir)
+{
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+
+ if (unlikely(!iir))
+ return;
+
+ lockdep_assert_held(gt->irq_lock);
+
+ if (!gsc->proxy.component) {
+ gt_err(gt, "GSC proxy irq received without the component being bound!\n");
+ return;
+ }
+
+ gsc->gsc_work_actions |= GSC_ACTION_SW_PROXY;
+ queue_work(gsc->wq, &gsc->work);
+}
+
+static int i915_gsc_proxy_component_bind(struct device *i915_kdev,
+ struct device *mei_kdev, void *data)
+{
+ struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
+ struct intel_gt *gt = i915->media_gt;
+ struct intel_gsc_uc *gsc = >->uc.gsc;
+ intel_wakeref_t wakeref;
+
+ /* enable HECI2 IRQs */
+ with_intel_runtime_pm(&i915->runtime_pm, wakeref)
+ intel_uncore_rmw(gt->uncore, HECI_H_CSR(MTL_GSC_HECI2_BASE),
+ HECI_H_CSR_RST, HECI_H_CSR_IE);
+
+ mutex_lock(&gsc->proxy.mutex);
+ gsc->proxy.component = data;
+ gsc->proxy.component->mei_dev = mei_kdev;
+ mutex_unlock(&gsc->proxy.mutex);
+
+ return 0;
+}
+
+static void i915_gsc_proxy_component_unbind(struct device *i915_kdev,
+ struct device *mei_kdev, void *data)
+{
+ struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
+ struct intel_gt *gt = i915->media_gt;
+ struct intel_gsc_uc *gsc = >->uc.gsc;
+ intel_wakeref_t wakeref;
+
+ mutex_lock(&gsc->proxy.mutex);
+ gsc->proxy.component = NULL;
+ mutex_unlock(&gsc->proxy.mutex);
+
+ /* disable HECI2 IRQs */
+ with_intel_runtime_pm(&i915->runtime_pm, wakeref)
+ intel_uncore_rmw(gt->uncore, HECI_H_CSR(MTL_GSC_HECI2_BASE),
+ HECI_H_CSR_IE | HECI_H_CSR_RST, 0);
+}
+
+static const struct component_ops i915_gsc_proxy_component_ops = {
+ .bind = i915_gsc_proxy_component_bind,
+ .unbind = i915_gsc_proxy_component_unbind,
+};
+
+static int proxy_channel_alloc(struct intel_gsc_uc *gsc)
+{
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+ struct i915_vma *vma;
+ void *vaddr;
+ int err;
+
+ err = intel_guc_allocate_and_map_vma(>->uc.guc, GSC_PROXY_CHANNEL_SIZE,
+ &vma, &vaddr);
+ if (err)
+ return err;
+
+ gsc->proxy.vma = vma;
+ gsc->proxy.to_gsc = vaddr;
+ gsc->proxy.to_csme = vaddr + GSC_PROXY_BUFFER_SIZE;
+
+ return 0;
+}
+
+static void proxy_channel_free(struct intel_gsc_uc *gsc)
+{
+ if (!gsc->proxy.vma)
+ return;
+
+ gsc->proxy.to_gsc = NULL;
+ gsc->proxy.to_csme = NULL;
+ i915_vma_unpin_and_release(&gsc->proxy.vma, I915_VMA_RELEASE_MAP);
+}
+
+void intel_gsc_proxy_fini(struct intel_gsc_uc *gsc)
+{
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+ struct drm_i915_private *i915 = gt->i915;
+
+ if (fetch_and_zero(&gsc->proxy.component_added))
+ component_del(i915->drm.dev, &i915_gsc_proxy_component_ops);
+
+ proxy_channel_free(gsc);
+}
+
+int intel_gsc_proxy_init(struct intel_gsc_uc *gsc)
+{
+ int err;
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+ struct drm_i915_private *i915 = gt->i915;
+
+ mutex_init(&gsc->proxy.mutex);
+
+ if (!IS_ENABLED(CONFIG_INTEL_MEI_GSC_PROXY)) {
+ gt_info(gt, "can't init GSC proxy due to missing mei component\n");
+ return -ENODEV;
+ }
+
+ err = proxy_channel_alloc(gsc);
+ if (err)
+ return err;
+
+ err = component_add_typed(i915->drm.dev, &i915_gsc_proxy_component_ops,
+ I915_COMPONENT_GSC_PROXY);
+ if (err < 0) {
+ gt_err(gt, "Failed to add GSC_PROXY component (%d)\n", err);
+ goto out_free;
+ }
+
+ gsc->proxy.component_added = true;
+
+ return 0;
+
+out_free:
+ proxy_channel_free(gsc);
+ return err;
+}
+
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.h b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.h
new file mode 100644
index 000000000000..c55bafcbaec4
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#ifndef _INTEL_GSC_PROXY_H_
+#define _INTEL_GSC_PROXY_H_
+
+#include <linux/types.h>
+
+struct intel_gsc_uc;
+
+int intel_gsc_proxy_init(struct intel_gsc_uc *gsc);
+void intel_gsc_proxy_fini(struct intel_gsc_uc *gsc);
+int intel_gsc_proxy_request_handler(struct intel_gsc_uc *gsc);
+void intel_gsc_proxy_irq_handler(struct intel_gsc_uc *gsc, u32 iir);
+
+#endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
index 2d5b70b3384c..64bff01026e8 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -10,15 +10,50 @@
#include "intel_gsc_uc.h"
#include "intel_gsc_fw.h"
#include "i915_drv.h"
+#include "intel_gsc_proxy.h"
static void gsc_work(struct work_struct *work)
{
struct intel_gsc_uc *gsc = container_of(work, typeof(*gsc), work);
struct intel_gt *gt = gsc_uc_to_gt(gsc);
intel_wakeref_t wakeref;
+ u32 actions;
+ int ret;
+
+ wakeref = intel_runtime_pm_get(gt->uncore->rpm);
+
+ spin_lock_irq(gt->irq_lock);
+ actions = gsc->gsc_work_actions;
+ gsc->gsc_work_actions = 0;
+ spin_unlock_irq(gt->irq_lock);
+
+ if (actions & GSC_ACTION_FW_LOAD) {
+ ret = intel_gsc_uc_fw_upload(gsc);
+ if (ret == -EEXIST) /* skip proxy if not a new load */
+ actions &= ~GSC_ACTION_FW_LOAD;
+ else if (ret)
+ goto out_put;
+ }
+
+ if (actions & (GSC_ACTION_FW_LOAD | GSC_ACTION_SW_PROXY)) {
+ if (!intel_gsc_uc_fw_init_done(gsc)) {
+ gt_err(gt, "Proxy request received with GSC not loaded!\n");
+ goto out_put;
+ }
+
+ ret = intel_gsc_proxy_request_handler(gsc);
+ if (ret)
+ goto out_put;
+
+ /* mark the GSC FW init as done the first time we run this */
+ if (actions & GSC_ACTION_FW_LOAD) {
+ gt_dbg(gt, "GSC Proxy initialized\n");
+ intel_uc_fw_change_status(&gsc->fw, INTEL_UC_FIRMWARE_RUNNING);
+ }
+ }
- with_intel_runtime_pm(gt->uncore->rpm, wakeref)
- intel_gsc_uc_fw_upload(gsc);
+out_put:
+ intel_runtime_pm_put(gt->uncore->rpm, wakeref);
}
static bool gsc_engine_supported(struct intel_gt *gt)
@@ -43,6 +78,8 @@ static bool gsc_engine_supported(struct intel_gt *gt)
void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc)
{
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+
intel_uc_fw_init_early(&gsc->fw, INTEL_UC_FW_TYPE_GSC);
INIT_WORK(&gsc->work, gsc_work);
@@ -50,10 +87,16 @@ void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc)
* GT with it being not fully setup hence check device info's
* engine mask
*/
- if (!gsc_engine_supported(gsc_uc_to_gt(gsc))) {
+ if (!gsc_engine_supported(gt)) {
intel_uc_fw_change_status(&gsc->fw, INTEL_UC_FIRMWARE_NOT_SUPPORTED);
return;
}
+
+ gsc->wq = alloc_ordered_workqueue("i915_gsc", 0);
+ if (!gsc->wq) {
+ gt_err(gt, "failed to allocate WQ for GSC, disabling FW\n");
+ intel_uc_fw_change_status(&gsc->fw, INTEL_UC_FIRMWARE_NOT_SUPPORTED);
+ }
}
int intel_gsc_uc_init(struct intel_gsc_uc *gsc)
@@ -88,6 +131,9 @@ int intel_gsc_uc_init(struct intel_gsc_uc *gsc)
gsc->ce = ce;
+ /* if we fail to init proxy we still want to load GSC for PM */
+ intel_gsc_proxy_init(gsc);
+
intel_uc_fw_change_status(&gsc->fw, INTEL_UC_FIRMWARE_LOADABLE);
return 0;
@@ -107,6 +153,12 @@ void intel_gsc_uc_fini(struct intel_gsc_uc *gsc)
return;
flush_work(&gsc->work);
+ if (gsc->wq) {
+ destroy_workqueue(gsc->wq);
+ gsc->wq = NULL;
+ }
+
+ intel_gsc_proxy_fini(gsc);
if (gsc->ce)
intel_engine_destroy_pinned_context(fetch_and_zero(&gsc->ce));
@@ -145,11 +197,17 @@ void intel_gsc_uc_resume(struct intel_gsc_uc *gsc)
void intel_gsc_uc_load_start(struct intel_gsc_uc *gsc)
{
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+
if (!intel_uc_fw_is_loadable(&gsc->fw))
return;
if (intel_gsc_uc_fw_init_done(gsc))
return;
- queue_work(system_unbound_wq, &gsc->work);
+ spin_lock_irq(gt->irq_lock);
+ gsc->gsc_work_actions |= GSC_ACTION_FW_LOAD;
+ spin_unlock_irq(gt->irq_lock);
+
+ queue_work(gsc->wq, &gsc->work);
}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h
index 5f50fa1ff8b9..a2a0813b8a76 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h
@@ -10,6 +10,7 @@
struct i915_vma;
struct intel_context;
+struct i915_gsc_proxy_component;
struct intel_gsc_uc {
/* Generic uC firmware management */
@@ -19,7 +20,21 @@ struct intel_gsc_uc {
struct i915_vma *local; /* private memory for GSC usage */
struct intel_context *ce; /* for submission to GSC FW via GSC engine */
- struct work_struct work; /* for delayed load */
+ /* for delayed load and proxy handling */
+ struct workqueue_struct *wq;
+ struct work_struct work;
+ u32 gsc_work_actions; /* protected by gt->irq_lock */
+#define GSC_ACTION_FW_LOAD BIT(0)
+#define GSC_ACTION_SW_PROXY BIT(1)
+
+ struct {
+ struct i915_gsc_proxy_component *component;
+ bool component_added;
+ struct i915_vma *vma;
+ void *to_gsc;
+ void *to_csme;
+ struct mutex mutex; /* protects the tee channel binding */
+ } proxy;
};
void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h
index 3d56ae501991..8f199d5f963e 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h
@@ -14,6 +14,7 @@ struct intel_gsc_mtl_header {
#define GSC_HECI_VALIDITY_MARKER 0xA578875A
u8 heci_client_id;
+#define HECI_MEADDRESS_PROXY 10
#define HECI_MEADDRESS_PXP 17
#define HECI_MEADDRESS_HDCP 18
diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
index d21486d69df2..37db142de413 100644
--- a/drivers/misc/mei/Kconfig
+++ b/drivers/misc/mei/Kconfig
@@ -62,4 +62,4 @@ config INTEL_MEI_GSC
source "drivers/misc/mei/hdcp/Kconfig"
source "drivers/misc/mei/pxp/Kconfig"
-
+source "drivers/misc/mei/gsc_proxy/Kconfig"
diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
index fb740d754900..14aee253ae48 100644
--- a/drivers/misc/mei/Makefile
+++ b/drivers/misc/mei/Makefile
@@ -30,3 +30,4 @@ CFLAGS_mei-trace.o = -I$(src)
obj-$(CONFIG_INTEL_MEI_HDCP) += hdcp/
obj-$(CONFIG_INTEL_MEI_PXP) += pxp/
+obj-$(CONFIG_INTEL_MEI_GSC_PROXY) += gsc_proxy/
diff --git a/drivers/misc/mei/gsc_proxy/Kconfig b/drivers/misc/mei/gsc_proxy/Kconfig
new file mode 100644
index 000000000000..5f68d9f3d691
--- /dev/null
+++ b/drivers/misc/mei/gsc_proxy/Kconfig
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+#
+config INTEL_MEI_GSC_PROXY
+ tristate "Intel GSC Proxy services of ME Interface"
+ select INTEL_MEI_ME
+ depends on DRM_I915
+ help
+ MEI Support for GSC Proxy Services on Intel platforms.
+
+ MEI GSC proxy enables messaging between GSC service on
+ Intel graphics card and services on CSE (MEI) firmware
+ residing SoC or PCH.
+
diff --git a/drivers/misc/mei/gsc_proxy/Makefile b/drivers/misc/mei/gsc_proxy/Makefile
new file mode 100644
index 000000000000..358847e9aaa9
--- /dev/null
+++ b/drivers/misc/mei/gsc_proxy/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+#
+# Makefile - GSC Proxy client driver for Intel MEI Bus Driver.
+
+obj-$(CONFIG_INTEL_MEI_GSC_PROXY) += mei_gsc_proxy.o
diff --git a/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c b/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c
new file mode 100644
index 000000000000..be52b113aea9
--- /dev/null
+++ b/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c
@@ -0,0 +1,208 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022-2023 Intel Corporation
+ */
+
+/**
+ * DOC: MEI_GSC_PROXY Client Driver
+ *
+ * The mei_gsc_proxy driver acts as a translation layer between
+ * proxy user (I915) and ME FW by proxying messages to ME FW
+ */
+
+#include <linux/component.h>
+#include <linux/mei_cl_bus.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/uuid.h>
+#include <drm/drm_connector.h>
+#include <drm/i915_component.h>
+#include <drm/i915_gsc_proxy_mei_interface.h>
+
+/**
+ * mei_gsc_proxy_send - Sends a proxy message to ME FW.
+ * @dev: device corresponding to the mei_cl_device
+ * @buf: a message buffer to send
+ * @size: size of the message
+ * Return: bytes sent on Success, <0 on Failure
+ */
+static int mei_gsc_proxy_send(struct device *dev, const void *buf, size_t size)
+{
+ ssize_t ret;
+
+ if (!dev || !buf)
+ return -EINVAL;
+
+ ret = mei_cldev_send(to_mei_cl_device(dev), buf, size);
+ if (ret < 0)
+ dev_dbg(dev, "mei_cldev_send failed. %zd\n", ret);
+
+ return ret;
+}
+
+/**
+ * mei_gsc_proxy_recv - Receives a proxy message from ME FW.
+ * @dev: device corresponding to the mei_cl_device
+ * @buf: a message buffer to contain the received message
+ * @size: size of the buffer
+ * Return: bytes received on Success, <0 on Failure
+ */
+static int mei_gsc_proxy_recv(struct device *dev, void *buf, size_t size)
+{
+ ssize_t ret;
+
+ if (!dev || !buf)
+ return -EINVAL;
+
+ ret = mei_cldev_recv(to_mei_cl_device(dev), buf, size);
+ if (ret < 0)
+ dev_dbg(dev, "mei_cldev_recv failed. %zd\n", ret);
+
+ return ret;
+}
+
+static const struct i915_gsc_proxy_component_ops mei_gsc_proxy_ops = {
+ .owner = THIS_MODULE,
+ .send = mei_gsc_proxy_send,
+ .recv = mei_gsc_proxy_recv,
+};
+
+static int mei_component_master_bind(struct device *dev)
+{
+ struct mei_cl_device *cldev = to_mei_cl_device(dev);
+ struct i915_gsc_proxy_component *comp_master = mei_cldev_get_drvdata(cldev);
+
+ comp_master->ops = &mei_gsc_proxy_ops;
+ comp_master->mei_dev = dev;
+ return component_bind_all(dev, comp_master);
+}
+
+static void mei_component_master_unbind(struct device *dev)
+{
+ struct mei_cl_device *cldev = to_mei_cl_device(dev);
+ struct i915_gsc_proxy_component *comp_master = mei_cldev_get_drvdata(cldev);
+
+ component_unbind_all(dev, comp_master);
+}
+
+static const struct component_master_ops mei_component_master_ops = {
+ .bind = mei_component_master_bind,
+ .unbind = mei_component_master_unbind,
+};
+
+/**
+ * mei_gsc_proxy_component_match - compare function for matching mei.
+ *
+ * The function checks if the device is pci device and
+ * Intel VGA adapter, the subcomponent is SW Proxy
+ * and the parent of MEI PCI and the parent of VGA are the same PCH device.
+ *
+ * @dev: master device
+ * @subcomponent: subcomponent to match (I915_COMPONENT_SWPROXY)
+ * @data: compare data (mei pci parent)
+ *
+ * Return:
+ * * 1 - if components match
+ * * 0 - otherwise
+ */
+static int mei_gsc_proxy_component_match(struct device *dev, int subcomponent,
+ void *data)
+{
+ struct pci_dev *pdev;
+
+ if (!dev_is_pci(dev))
+ return 0;
+
+ pdev = to_pci_dev(dev);
+
+ if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8) ||
+ pdev->vendor != PCI_VENDOR_ID_INTEL)
+ return 0;
+
+ if (subcomponent != I915_COMPONENT_GSC_PROXY)
+ return 0;
+
+ return component_compare_dev(dev->parent, ((struct device *)data)->parent);
+}
+
+static int mei_gsc_proxy_probe(struct mei_cl_device *cldev,
+ const struct mei_cl_device_id *id)
+{
+ struct i915_gsc_proxy_component *comp_master;
+ struct component_match *master_match = NULL;
+ int ret;
+
+ ret = mei_cldev_enable(cldev);
+ if (ret < 0) {
+ dev_err(&cldev->dev, "mei_cldev_enable Failed. %d\n", ret);
+ goto enable_err_exit;
+ }
+
+ comp_master = kzalloc(sizeof(*comp_master), GFP_KERNEL);
+ if (!comp_master) {
+ ret = -ENOMEM;
+ goto err_exit;
+ }
+
+ component_match_add_typed(&cldev->dev, &master_match,
+ mei_gsc_proxy_component_match, cldev->dev.parent);
+ if (IS_ERR_OR_NULL(master_match)) {
+ ret = -ENOMEM;
+ goto err_exit;
+ }
+
+ mei_cldev_set_drvdata(cldev, comp_master);
+ ret = component_master_add_with_match(&cldev->dev,
+ &mei_component_master_ops,
+ master_match);
+ if (ret < 0) {
+ dev_err(&cldev->dev, "Master comp add failed %d\n", ret);
+ goto err_exit;
+ }
+
+ return 0;
+
+err_exit:
+ mei_cldev_set_drvdata(cldev, NULL);
+ kfree(comp_master);
+ mei_cldev_disable(cldev);
+enable_err_exit:
+ return ret;
+}
+
+static void mei_gsc_proxy_remove(struct mei_cl_device *cldev)
+{
+ struct i915_gsc_proxy_component *comp_master = mei_cldev_get_drvdata(cldev);
+ int ret;
+
+ component_master_del(&cldev->dev, &mei_component_master_ops);
+ kfree(comp_master);
+ mei_cldev_set_drvdata(cldev, NULL);
+
+ ret = mei_cldev_disable(cldev);
+ if (ret)
+ dev_warn(&cldev->dev, "mei_cldev_disable() failed %d\n", ret);
+}
+
+#define MEI_UUID_GSC_PROXY UUID_LE(0xf73db04, 0x97ab, 0x4125, \
+ 0xb8, 0x93, 0xe9, 0x4, 0xad, 0xd, 0x54, 0x64)
+
+static struct mei_cl_device_id mei_gsc_proxy_tbl[] = {
+ { .uuid = MEI_UUID_GSC_PROXY, .version = MEI_CL_VERSION_ANY },
+ { }
+};
+MODULE_DEVICE_TABLE(mei, mei_gsc_proxy_tbl);
+
+static struct mei_cl_driver mei_gsc_proxy_driver = {
+ .id_table = mei_gsc_proxy_tbl,
+ .name = KBUILD_MODNAME,
+ .probe = mei_gsc_proxy_probe,
+ .remove = mei_gsc_proxy_remove,
+};
+
+module_mei_cl_driver(mei_gsc_proxy_driver);
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MEI GSC PROXY");
diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
index c1e2a43d2d1e..56a84ee1c64c 100644
--- a/include/drm/i915_component.h
+++ b/include/drm/i915_component.h
@@ -29,7 +29,8 @@
enum i915_component_type {
I915_COMPONENT_AUDIO = 1,
I915_COMPONENT_HDCP,
- I915_COMPONENT_PXP
+ I915_COMPONENT_PXP,
+ I915_COMPONENT_GSC_PROXY,
};
/* MAX_PORT is the number of port
diff --git a/include/drm/i915_gsc_proxy_mei_interface.h b/include/drm/i915_gsc_proxy_mei_interface.h
new file mode 100644
index 000000000000..9462341d3ae1
--- /dev/null
+++ b/include/drm/i915_gsc_proxy_mei_interface.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (c) 2022-2023 Intel Corporation
+ */
+
+#ifndef _I915_GSC_PROXY_MEI_INTERFACE_H_
+#define _I915_GSC_PROXY_MEI_INTERFACE_H_
+
+#include <linux/types.h>
+
+struct device;
+struct module;
+
+/**
+ * struct i915_gsc_proxy_component_ops - ops for GSC Proxy services.
+ * @owner: Module providing the ops
+ * @send: sends a proxy message from GSC FW to ME FW
+ * @recv: receives a proxy message for GSC FW from ME FW
+ */
+struct i915_gsc_proxy_component_ops {
+ struct module *owner;
+
+ /**
+ * send - Sends a proxy message to ME FW.
+ * @dev: device struct corresponding to the mei device
+ * @buf: message buffer to send
+ * @size: size of the message
+ * Return: bytes sent on success, negative errno value on failure
+ */
+ int (*send)(struct device *dev, const void *buf, size_t size);
+
+ /**
+ * recv - Receives a proxy message from ME FW.
+ * @dev: device struct corresponding to the mei device
+ * @buf: message buffer to contain the received message
+ * @size: size of the buffer
+ * Return: bytes received on success, negative errno value on failure
+ */
+ int (*recv)(struct device *dev, void *buf, size_t size);
+};
+
+/**
+ * struct i915_gsc_proxy_component - Used for communication between i915 and
+ * MEI drivers for GSC proxy services
+ * @mei_dev: device that provide the GSC proxy service.
+ * @ops: Ops implemented by GSC proxy driver, used by i915 driver.
+ */
+struct i915_gsc_proxy_component {
+ struct device *mei_dev;
+ const struct i915_gsc_proxy_component_ops *ops;
+};
+
+#endif /* _I915_GSC_PROXY_MEI_INTERFACE_H_ */
--
2.40.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Intel-gfx] [PATCH v2 2/8] drm/i915/uc: perma-pin firmwares
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 1/8] DO NOT REVIEW: drm/i915: Add support for MTL GSC SW Proxy Daniele Ceraolo Spurio
@ 2023-04-28 18:58 ` Daniele Ceraolo Spurio
2023-05-17 20:59 ` John Harrison
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 3/8] drm/i915/huc: Parse the GSC-enabled HuC binary Daniele Ceraolo Spurio
` (15 subsequent siblings)
17 siblings, 1 reply; 32+ messages in thread
From: Daniele Ceraolo Spurio @ 2023-04-28 18:58 UTC (permalink / raw)
To: intel-gfx; +Cc: Alan Previn, dri-devel
Now that each FW has its own reserved area, we can keep them always
pinned and skip the pin/unpin dance on reset. This will make things
easier for the 2-step HuC authentication, which requires the FW to be
pinned in GGTT after the xfer is completed.
Given that we use dummy vmas for the pinning, we do need to explicitly
re-pin on resume because the automated helper won't cover us.
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
---
drivers/gpu/drm/i915/gt/intel_ggtt.c | 3 ++
drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 7 ++++-
drivers/gpu/drm/i915/gt/uc/intel_guc.c | 2 +-
drivers/gpu/drm/i915/gt/uc/intel_huc.c | 2 +-
drivers/gpu/drm/i915/gt/uc/intel_uc.c | 8 +++++
drivers/gpu/drm/i915/gt/uc/intel_uc.h | 2 ++
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 36 ++++++++++++++++++-----
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h | 5 +++-
8 files changed, 53 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 20915edc8bd9..ab71ed11de79 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -1322,6 +1322,9 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
ggtt->vm.scratch_range(&ggtt->vm, ggtt->error_capture.start,
ggtt->error_capture.size);
+ list_for_each_entry(gt, &ggtt->gt_list, ggtt_link)
+ intel_uc_resume_mappings(>->uc);
+
ggtt->invalidate(ggtt);
if (flush)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
index 64bff01026e8..af542e3cb3e9 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -80,7 +80,12 @@ void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc)
{
struct intel_gt *gt = gsc_uc_to_gt(gsc);
- intel_uc_fw_init_early(&gsc->fw, INTEL_UC_FW_TYPE_GSC);
+ /*
+ * GSC FW needs to be copied to a dedicated memory allocations for
+ * loading (see gsc->local), so we don't need to GGTT map the FW image
+ * itself into GGTT.
+ */
+ intel_uc_fw_init_early(&gsc->fw, INTEL_UC_FW_TYPE_GSC, false);
INIT_WORK(&gsc->work, gsc_work);
/* we can arrive here from i915_driver_early_probe for primary
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index c9f20385f6a0..2eb891b270ae 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -164,7 +164,7 @@ void intel_guc_init_early(struct intel_guc *guc)
struct intel_gt *gt = guc_to_gt(guc);
struct drm_i915_private *i915 = gt->i915;
- intel_uc_fw_init_early(&guc->fw, INTEL_UC_FW_TYPE_GUC);
+ intel_uc_fw_init_early(&guc->fw, INTEL_UC_FW_TYPE_GUC, true);
intel_guc_ct_init_early(&guc->ct);
intel_guc_log_init_early(&guc->log);
intel_guc_submission_init_early(guc);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index aefdaa62da99..9721761373fb 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -276,7 +276,7 @@ void intel_huc_init_early(struct intel_huc *huc)
struct drm_i915_private *i915 = huc_to_gt(huc)->i915;
struct intel_gt *gt = huc_to_gt(huc);
- intel_uc_fw_init_early(&huc->fw, INTEL_UC_FW_TYPE_HUC);
+ intel_uc_fw_init_early(&huc->fw, INTEL_UC_FW_TYPE_HUC, true);
/*
* we always init the fence as already completed, even if HuC is not
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index 996168312340..b6adfda3761e 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -697,6 +697,12 @@ void intel_uc_suspend(struct intel_uc *uc)
}
}
+static void __uc_resume_mappings(struct intel_uc *uc)
+{
+ intel_uc_fw_resume_mapping(&uc->guc.fw);
+ intel_uc_fw_resume_mapping(&uc->huc.fw);
+}
+
static int __uc_resume(struct intel_uc *uc, bool enable_communication)
{
struct intel_guc *guc = &uc->guc;
@@ -764,4 +770,6 @@ static const struct intel_uc_ops uc_ops_on = {
.init_hw = __uc_init_hw,
.fini_hw = __uc_fini_hw,
+
+ .resume_mappings = __uc_resume_mappings,
};
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.h b/drivers/gpu/drm/i915/gt/uc/intel_uc.h
index 5d0f1bcc381e..c2783e6e752b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.h
@@ -24,6 +24,7 @@ struct intel_uc_ops {
void (*fini)(struct intel_uc *uc);
int (*init_hw)(struct intel_uc *uc);
void (*fini_hw)(struct intel_uc *uc);
+ void (*resume_mappings)(struct intel_uc *uc);
};
struct intel_uc {
@@ -113,6 +114,7 @@ intel_uc_ops_function(init, init, int, 0);
intel_uc_ops_function(fini, fini, void, );
intel_uc_ops_function(init_hw, init_hw, int, 0);
intel_uc_ops_function(fini_hw, fini_hw, void, );
+intel_uc_ops_function(resume_mappings, resume_mappings, void, );
#undef intel_uc_ops_function
#endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index 6b71b9febd74..03f0b258aea7 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -422,12 +422,14 @@ static void __uc_fw_user_override(struct drm_i915_private *i915, struct intel_uc
* intel_uc_fw_init_early - initialize the uC object and select the firmware
* @uc_fw: uC firmware
* @type: type of uC
+ * @needs_ggtt_mapping: whether the FW needs to be GGTT mapped for loading
*
* Initialize the state of our uC object and relevant tracking and select the
* firmware to fetch and load.
*/
void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
- enum intel_uc_fw_type type)
+ enum intel_uc_fw_type type,
+ bool needs_ggtt_mapping)
{
struct drm_i915_private *i915 = ____uc_fw_to_gt(uc_fw, type)->i915;
@@ -440,6 +442,7 @@ void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
GEM_BUG_ON(uc_fw->file_selected.path);
uc_fw->type = type;
+ uc_fw->needs_ggtt_mapping = needs_ggtt_mapping;
if (HAS_GT_UC(i915)) {
__uc_fw_auto_select(i915, uc_fw);
@@ -699,7 +702,7 @@ static int try_firmware_load(struct intel_uc_fw *uc_fw, const struct firmware **
if (err)
return err;
- if ((*fw)->size > INTEL_UC_RSVD_GGTT_PER_FW) {
+ if (uc_fw->needs_ggtt_mapping && (*fw)->size > INTEL_UC_RSVD_GGTT_PER_FW) {
gt_err(gt, "%s firmware %s: size (%zuKB) exceeds max supported size (%uKB)\n",
intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
(*fw)->size / SZ_1K, INTEL_UC_RSVD_GGTT_PER_FW / SZ_1K);
@@ -880,6 +883,9 @@ static void uc_fw_bind_ggtt(struct intel_uc_fw *uc_fw)
struct i915_vma_resource *dummy = &uc_fw->dummy;
u32 pte_flags = 0;
+ if (!uc_fw->needs_ggtt_mapping)
+ return;
+
dummy->start = uc_fw_ggtt_offset(uc_fw);
dummy->node_size = obj->base.size;
dummy->bi.pages = obj->mm.pages;
@@ -901,11 +907,13 @@ static void uc_fw_bind_ggtt(struct intel_uc_fw *uc_fw)
static void uc_fw_unbind_ggtt(struct intel_uc_fw *uc_fw)
{
- struct drm_i915_gem_object *obj = uc_fw->obj;
struct i915_ggtt *ggtt = __uc_fw_to_gt(uc_fw)->ggtt;
- u64 start = uc_fw_ggtt_offset(uc_fw);
+ struct i915_vma_resource *dummy = &uc_fw->dummy;
+
+ if (!dummy->node_size)
+ return;
- ggtt->vm.clear_range(&ggtt->vm, start, obj->base.size);
+ ggtt->vm.clear_range(&ggtt->vm, dummy->start, dummy->node_size);
}
static int uc_fw_xfer(struct intel_uc_fw *uc_fw, u32 dst_offset, u32 dma_flags)
@@ -922,7 +930,7 @@ static int uc_fw_xfer(struct intel_uc_fw *uc_fw, u32 dst_offset, u32 dma_flags)
intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
/* Set the source address for the uCode */
- offset = uc_fw_ggtt_offset(uc_fw);
+ offset = uc_fw->dummy.start;
GEM_BUG_ON(upper_32_bits(offset) & 0xFFFF0000);
intel_uncore_write_fw(uncore, DMA_ADDR_0_LOW, lower_32_bits(offset));
intel_uncore_write_fw(uncore, DMA_ADDR_0_HIGH, upper_32_bits(offset));
@@ -996,9 +1004,7 @@ int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, u32 dst_offset, u32 dma_flags)
return -ENOEXEC;
/* Call custom loader */
- uc_fw_bind_ggtt(uc_fw);
err = uc_fw_xfer(uc_fw, dst_offset, dma_flags);
- uc_fw_unbind_ggtt(uc_fw);
if (err)
goto fail;
@@ -1102,6 +1108,8 @@ int intel_uc_fw_init(struct intel_uc_fw *uc_fw)
goto out_unpin;
}
+ uc_fw_bind_ggtt(uc_fw);
+
return 0;
out_unpin:
@@ -1112,6 +1120,7 @@ int intel_uc_fw_init(struct intel_uc_fw *uc_fw)
void intel_uc_fw_fini(struct intel_uc_fw *uc_fw)
{
+ uc_fw_unbind_ggtt(uc_fw);
uc_fw_rsa_data_destroy(uc_fw);
if (i915_gem_object_has_pinned_pages(uc_fw->obj))
@@ -1120,6 +1129,17 @@ void intel_uc_fw_fini(struct intel_uc_fw *uc_fw)
intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_AVAILABLE);
}
+void intel_uc_fw_resume_mapping(struct intel_uc_fw *uc_fw)
+{
+ if (!intel_uc_fw_is_available(uc_fw))
+ return;
+
+ if (!i915_gem_object_has_pinned_pages(uc_fw->obj))
+ return;
+
+ uc_fw_bind_ggtt(uc_fw);
+}
+
/**
* intel_uc_fw_cleanup_fetch - cleanup uC firmware
* @uc_fw: uC firmware
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
index 6ba00e6b3975..26a9d6e0dc00 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
@@ -105,6 +105,7 @@ struct intel_uc_fw {
* threaded as it done during driver load (inherently single threaded)
* or during a GT reset (mutex guarantees single threaded).
*/
+ bool needs_ggtt_mapping;
struct i915_vma_resource dummy;
struct i915_vma *rsa_data;
@@ -282,12 +283,14 @@ static inline u32 intel_uc_fw_get_upload_size(struct intel_uc_fw *uc_fw)
}
void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
- enum intel_uc_fw_type type);
+ enum intel_uc_fw_type type,
+ bool needs_ggtt_mapping);
int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw);
void intel_uc_fw_cleanup_fetch(struct intel_uc_fw *uc_fw);
int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, u32 offset, u32 dma_flags);
int intel_uc_fw_init(struct intel_uc_fw *uc_fw);
void intel_uc_fw_fini(struct intel_uc_fw *uc_fw);
+void intel_uc_fw_resume_mapping(struct intel_uc_fw *uc_fw);
size_t intel_uc_fw_copy_rsa(struct intel_uc_fw *uc_fw, void *dst, u32 max_len);
int intel_uc_fw_mark_load_failed(struct intel_uc_fw *uc_fw, int err);
void intel_uc_fw_dump(const struct intel_uc_fw *uc_fw, struct drm_printer *p);
--
2.40.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Intel-gfx] [PATCH v2 3/8] drm/i915/huc: Parse the GSC-enabled HuC binary
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 1/8] DO NOT REVIEW: drm/i915: Add support for MTL GSC SW Proxy Daniele Ceraolo Spurio
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 2/8] drm/i915/uc: perma-pin firmwares Daniele Ceraolo Spurio
@ 2023-04-28 18:58 ` Daniele Ceraolo Spurio
2023-05-02 15:27 ` [Intel-gfx] [PATCH v2] " Daniele Ceraolo Spurio
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 4/8] drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so Daniele Ceraolo Spurio
` (14 subsequent siblings)
17 siblings, 1 reply; 32+ messages in thread
From: Daniele Ceraolo Spurio @ 2023-04-28 18:58 UTC (permalink / raw)
To: intel-gfx; +Cc: Alan Previn, dri-devel
The new binaries that support the 2-step authentication have contain the
legacy-style binary, which we can use for loading the HuC via DMA. To
find out where this is located in the image, we need to parse the meu
manifest of the GSC binary. The manifest consist of a partition header
followed by entries, one of which contains the offset we're looking for.
Since we're now parsing the entries, we can extract the HuC version
that way instead of using hardcoded offsets.
Note that the meu structure will be re-used for parsing the GSC binary,
so they've been added in their own header.
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
---
| 74 +++++++++++
drivers/gpu/drm/i915/gt/uc/intel_huc.c | 11 +-
drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 116 ++++++++++++++++++
drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h | 5 +-
drivers/gpu/drm/i915/gt/uc/intel_huc_print.h | 21 ++++
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 71 ++++++-----
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h | 2 +
7 files changed, 253 insertions(+), 47 deletions(-)
create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_huc_print.h
--git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h b/drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
new file mode 100644
index 000000000000..df9c482a8052
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef _INTEL_GSC_MEU_H_
+#define _INTEL_GSC_MEU_H_
+
+#include <linux/types.h>
+
+/* Code partition structures */
+struct intel_gsc_cpt_directory_header_v2 {
+ u32 header_marker;
+#define INTEL_GSC_CPT_HEADER_MARKER 0x44504324
+
+ u32 num_of_entries;
+ u8 header_version;
+ u8 entry_version;
+ u8 header_length; /* in bytes */
+ u8 flags;
+ u32 partition_name;
+ u32 crc32;
+} __packed;
+
+struct intel_gsc_cpt_directory_entry {
+ u8 name[12];
+
+ /*
+ * Bits 0-24: offset from the beginning of the code partition
+ * Bit 25: huffman compressed
+ * Bits 26-31: reserved
+ */
+ u32 offset;
+#define INTEL_GSC_CPT_ENTRY_OFFSET_MASK GENMASK(24, 0)
+#define INTEL_GSC_CPT_ENTRY_HUFFMAN_COMP BIT(25)
+
+ /*
+ * Module/Item length, in bytes. For Huffman-compressed modules, this
+ * refers to the uncompressed size. For software-compressed modules,
+ * this refers to the compressed size.
+ */
+ u32 length;
+
+ u8 reserved[4];
+} __packed;
+
+struct intel_gsc_meu_version {
+ u16 major;
+ u16 minor;
+ u16 hotfix;
+ u16 build;
+} __packed;
+
+struct intel_gsc_manifest_header {
+ u32 header_type; /* 0x4 for manifest type */
+ u32 header_length; /* in dwords */
+ u32 header_version;
+ u32 flags;
+ u32 vendor;
+ u32 date;
+ u32 size; /* In dwords, size of entire manifest (header + extensions) */
+ u32 header_id;
+ u32 internal_data;
+ struct intel_gsc_meu_version fw_version;
+ u32 security_version;
+ struct intel_gsc_meu_version meu_kit_version;
+ u32 meu_manifest_version;
+ u8 general_data[4];
+ u8 reserved3[56];
+ u32 modulus_size; /* in dwords */
+ u32 exponent_size; /* in dwords */
+} __packed;
+
+#endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 9721761373fb..062ff914b274 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -6,23 +6,14 @@
#include <linux/types.h>
#include "gt/intel_gt.h"
-#include "gt/intel_gt_print.h"
#include "intel_guc_reg.h"
#include "intel_huc.h"
+#include "intel_huc_print.h"
#include "i915_drv.h"
#include <linux/device/bus.h>
#include <linux/mei_aux.h>
-#define huc_printk(_huc, _level, _fmt, ...) \
- gt_##_level(huc_to_gt(_huc), "HuC: " _fmt, ##__VA_ARGS__)
-#define huc_err(_huc, _fmt, ...) huc_printk((_huc), err, _fmt, ##__VA_ARGS__)
-#define huc_warn(_huc, _fmt, ...) huc_printk((_huc), warn, _fmt, ##__VA_ARGS__)
-#define huc_notice(_huc, _fmt, ...) huc_printk((_huc), notice, _fmt, ##__VA_ARGS__)
-#define huc_info(_huc, _fmt, ...) huc_printk((_huc), info, _fmt, ##__VA_ARGS__)
-#define huc_dbg(_huc, _fmt, ...) huc_printk((_huc), dbg, _fmt, ##__VA_ARGS__)
-#define huc_probe_error(_huc, _fmt, ...) huc_printk((_huc), probe_error, _fmt, ##__VA_ARGS__)
-
/**
* DOC: HuC
*
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
index 534b0aa43316..f1c973e1c676 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
@@ -5,11 +5,127 @@
#include "gt/intel_gsc.h"
#include "gt/intel_gt.h"
+#include "intel_gsc_meu_headers.h"
#include "intel_huc.h"
#include "intel_huc_fw.h"
+#include "intel_huc_print.h"
#include "i915_drv.h"
#include "pxp/intel_pxp_huc.h"
+static void get_version_from_meu_manifest(struct intel_uc_fw_ver *ver, const void *data)
+{
+ const struct intel_gsc_manifest_header *manifest = data;
+
+ ver->major = manifest->fw_version.major;
+ ver->minor = manifest->fw_version.minor;
+ ver->patch = manifest->fw_version.hotfix;
+}
+
+static inline u32 entry_offset(const struct intel_gsc_cpt_directory_entry *entry)
+{
+ return entry->offset & INTEL_GSC_CPT_ENTRY_OFFSET_MASK;
+}
+
+int intel_huc_fw_get_binary_info(struct intel_uc_fw *huc_fw, const void *data, size_t size)
+{
+ struct intel_huc *huc = container_of(huc_fw, struct intel_huc, fw);
+ const struct intel_gsc_cpt_directory_header_v2 *header = data;
+ const struct intel_gsc_cpt_directory_entry *entry;
+ size_t min_size = sizeof(*header);
+ int i;
+
+ if (!huc_fw->loaded_via_gsc) {
+ huc_err(huc, "Invalid FW type MEU parsing!\n");
+ return -EINVAL;
+ }
+
+ if (size < sizeof(*header)) {
+ huc_err(huc, "MEU FW too small! %zu < %zu\n", size, min_size);
+ return -ENODATA;
+ }
+
+ /*
+ * The meu HuC binary starts with a directory header, followed by a
+ * series of entries. Each entry is identified by a name and points to
+ * a specific section of the binary containing the relevant data.
+ * The entries we're interested in are
+ * - "HUCP.man": points to the GSC manifest header for the HuC, which
+ * contains the version info.
+ * - "huc_fw": points to the legacy-style binary that can be used for
+ * load via the DMA. This entry only exists on binaries for
+ * platform that support 2-step HuC load via dma and auth
+ * via GSC (like MTL).
+ *
+ * --------------------------------------------------
+ * [ intel_gsc_cpt_directory_header_v2 ]
+ * --------------------------------------------------
+ * [ intel_gsc_cpt_directory_entry[] ]
+ * [ entry1 ]
+ * [ ... ]
+ * [ entryX ]
+ * [ "HUCP.man" ]
+ * [ ... ]
+ * [ offset >----------------------------]------o
+ * [ ... ] |
+ * [ entryY ] |
+ * [ "huc_fw" ] |
+ * [ ... ] |
+ * [ offset >----------------------------]----------o
+ * -------------------------------------------------- | |
+ * | |
+ * -------------------------------------------------- | |
+ * [ intel_gsc_manifest_header ]<-----o |
+ * [ ... ] |
+ * [ intel_gsc_meu_version fw_version ] |
+ * [ ... ] |
+ * -------------------------------------------------- |
+ * |
+ * -------------------------------------------------- |
+ * [ data[] ]<---------o
+ * [ ... ]
+ * [ ... ]
+ * --------------------------------------------------
+ */
+
+ if (header->header_marker != INTEL_GSC_CPT_HEADER_MARKER) {
+ huc_err(huc, "invalid marker for meu CPT header: 0x%08x!\n",
+ header->header_marker);
+ return -EINVAL;
+ }
+
+ /* we only have binaries with header v2 and entry v1 for now */
+ if (header->header_version != 2 || header->entry_version != 1) {
+ huc_err(huc, "invalid meu CPT header/entry version %u:%u!\n",
+ header->header_version, header->entry_version);
+ return -EINVAL;
+ }
+
+ if (header->header_length < sizeof(struct intel_gsc_cpt_directory_header_v2)) {
+ huc_err(huc, "invalid meu CPT header length %u!\n",
+ header->header_length);
+ return -EINVAL;
+ }
+
+ min_size = header->header_length + sizeof(*entry) * header->num_of_entries;
+ if (size < min_size) {
+ huc_err(huc, "MEU FW too small! %zu < %zu\n", size, min_size);
+ return -ENODATA;
+ }
+
+ entry = data + header->header_length;
+
+ for (i = 0; i < header->num_of_entries; i++, entry++) {
+ if (strcmp(entry->name, "HUCP.man") == 0)
+ get_version_from_meu_manifest(&huc_fw->file_selected.ver,
+ data + entry_offset(entry));
+
+ if (strcmp(entry->name, "huc_fw") == 0)
+ huc_fw->dma_start_offset = entry_offset(entry);
+ }
+
+ return 0;
+}
+
int intel_huc_fw_load_and_auth_via_gsc(struct intel_huc *huc)
{
int ret;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
index db42e238b45f..0999ffe6f962 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
@@ -7,8 +7,11 @@
#define _INTEL_HUC_FW_H_
struct intel_huc;
+struct intel_uc_fw;
+
+#include <linux/types.h>
int intel_huc_fw_load_and_auth_via_gsc(struct intel_huc *huc);
int intel_huc_fw_upload(struct intel_huc *huc);
-
+int intel_huc_fw_get_binary_info(struct intel_uc_fw *huc_fw, const void *data, size_t size);
#endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_print.h b/drivers/gpu/drm/i915/gt/uc/intel_huc_print.h
new file mode 100644
index 000000000000..915d310ee1df
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_print.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef __INTEL_HUC_PRINT__
+#define __INTEL_HUC_PRINT__
+
+#include "gt/intel_gt.h"
+#include "gt/intel_gt_print.h"
+
+#define huc_printk(_huc, _level, _fmt, ...) \
+ gt_##_level(huc_to_gt(_huc), "HuC: " _fmt, ##__VA_ARGS__)
+#define huc_err(_huc, _fmt, ...) huc_printk((_huc), err, _fmt, ##__VA_ARGS__)
+#define huc_warn(_huc, _fmt, ...) huc_printk((_huc), warn, _fmt, ##__VA_ARGS__)
+#define huc_notice(_huc, _fmt, ...) huc_printk((_huc), notice, _fmt, ##__VA_ARGS__)
+#define huc_info(_huc, _fmt, ...) huc_printk((_huc), info, _fmt, ##__VA_ARGS__)
+#define huc_dbg(_huc, _fmt, ...) huc_printk((_huc), dbg, _fmt, ##__VA_ARGS__)
+#define huc_probe_error(_huc, _fmt, ...) huc_printk((_huc), probe_error, _fmt, ##__VA_ARGS__)
+
+#endif /* __INTEL_HUC_PRINT__ */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index 03f0b258aea7..da6fcfe1d80a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -492,33 +492,6 @@ static void __force_fw_fetch_failures(struct intel_uc_fw *uc_fw, int e)
}
}
-static int check_gsc_manifest(struct intel_gt *gt,
- const struct firmware *fw,
- struct intel_uc_fw *uc_fw)
-{
- u32 *dw = (u32 *)fw->data;
- u32 version_hi, version_lo;
- size_t min_size;
-
- /* Check the size of the blob before examining buffer contents */
- min_size = sizeof(u32) * (HUC_GSC_VERSION_LO_DW + 1);
- if (unlikely(fw->size < min_size)) {
- gt_warn(gt, "%s firmware %s: invalid size: %zu < %zu\n",
- intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
- fw->size, min_size);
- return -ENODATA;
- }
-
- version_hi = dw[HUC_GSC_VERSION_HI_DW];
- version_lo = dw[HUC_GSC_VERSION_LO_DW];
-
- uc_fw->file_selected.ver.major = FIELD_GET(HUC_GSC_MAJOR_VER_HI_MASK, version_hi);
- uc_fw->file_selected.ver.minor = FIELD_GET(HUC_GSC_MINOR_VER_HI_MASK, version_hi);
- uc_fw->file_selected.ver.patch = FIELD_GET(HUC_GSC_PATCH_VER_LO_MASK, version_lo);
-
- return 0;
-}
-
static void uc_unpack_css_version(struct intel_uc_fw_ver *ver, u32 css_value)
{
/* Get version numbers from the CSS header */
@@ -575,22 +548,22 @@ static void guc_read_css_info(struct intel_uc_fw *uc_fw, struct uc_css_header *c
uc_fw->private_data_size = css->private_data_size;
}
-static int check_ccs_header(struct intel_gt *gt,
- const struct firmware *fw,
- struct intel_uc_fw *uc_fw)
+static int __check_ccs_header(struct intel_gt *gt,
+ const void *fw_data, size_t fw_size,
+ struct intel_uc_fw *uc_fw)
{
struct uc_css_header *css;
size_t size;
/* Check the size of the blob before examining buffer contents */
- if (unlikely(fw->size < sizeof(struct uc_css_header))) {
+ if (unlikely(fw_size < sizeof(struct uc_css_header))) {
gt_warn(gt, "%s firmware %s: invalid size: %zu < %zu\n",
intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
- fw->size, sizeof(struct uc_css_header));
+ fw_size, sizeof(struct uc_css_header));
return -ENODATA;
}
- css = (struct uc_css_header *)fw->data;
+ css = (struct uc_css_header *)fw_data;
/* Check integrity of size values inside CSS header */
size = (css->header_size_dw - css->key_size_dw - css->modulus_size_dw -
@@ -598,7 +571,7 @@ static int check_ccs_header(struct intel_gt *gt,
if (unlikely(size != sizeof(struct uc_css_header))) {
gt_warn(gt, "%s firmware %s: unexpected header size: %zu != %zu\n",
intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
- fw->size, sizeof(struct uc_css_header));
+ fw_size, sizeof(struct uc_css_header));
return -EPROTO;
}
@@ -610,10 +583,10 @@ static int check_ccs_header(struct intel_gt *gt,
/* At least, it should have header, uCode and RSA. Size of all three. */
size = sizeof(struct uc_css_header) + uc_fw->ucode_size + uc_fw->rsa_size;
- if (unlikely(fw->size < size)) {
+ if (unlikely(fw_size < size)) {
gt_warn(gt, "%s firmware %s: invalid size: %zu < %zu\n",
intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
- fw->size, size);
+ fw_size, size);
return -ENOEXEC;
}
@@ -634,6 +607,32 @@ static int check_ccs_header(struct intel_gt *gt,
return 0;
}
+static int check_gsc_manifest(struct intel_gt *gt,
+ const struct firmware *fw,
+ struct intel_uc_fw *uc_fw)
+{
+ if (uc_fw->type != INTEL_UC_FW_TYPE_HUC) {
+ gt_err(gt, "trying to MEU-parse a non-HuC binary");
+ return -EINVAL;
+ }
+
+ intel_huc_fw_get_binary_info(uc_fw, fw->data, fw->size);
+
+ if (uc_fw->dma_start_offset) {
+ u32 delta = uc_fw->dma_start_offset;
+ __check_ccs_header(gt, fw->data + delta, fw->size - delta, uc_fw);
+ }
+
+ return 0;
+}
+
+static int check_ccs_header(struct intel_gt *gt,
+ const struct firmware *fw,
+ struct intel_uc_fw *uc_fw)
+{
+ return __check_ccs_header(gt, fw->data, fw->size, uc_fw);
+}
+
static bool is_ver_8bit(struct intel_uc_fw_ver *ver)
{
return ver->major < 0xFF && ver->minor < 0xFF && ver->patch < 0xFF;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
index 26a9d6e0dc00..2691bb6bde48 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
@@ -113,6 +113,8 @@ struct intel_uc_fw {
u32 ucode_size;
u32 private_data_size;
+ u32 dma_start_offset;
+
bool loaded_via_gsc;
};
--
2.40.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Intel-gfx] [PATCH v2 4/8] drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
` (2 preceding siblings ...)
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 3/8] drm/i915/huc: Parse the GSC-enabled HuC binary Daniele Ceraolo Spurio
@ 2023-04-28 18:58 ` Daniele Ceraolo Spurio
2023-05-19 18:03 ` John Harrison
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 5/8] drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow Daniele Ceraolo Spurio
` (13 subsequent siblings)
17 siblings, 1 reply; 32+ messages in thread
From: Daniele Ceraolo Spurio @ 2023-04-28 18:58 UTC (permalink / raw)
To: intel-gfx; +Cc: Alan Previn, dri-devel
In the previous patch we extracted the offset of the legacy-style HuC
binary located within the GSC-enabled blob, so now we can use that to
load the HuC via DMA if the fuse is set that way.
Note that we now need to differentiate between "GSC-enabled binary" and
"loaded by GSC", so the former case has been renamed to "MEU binary" for
clarity, while the latter is now based on the fuse instead of the binary
format. This way, all the legacy load paths are automatically taken
(including the auth by GuC) without having to implement further code
changes.
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
---
drivers/gpu/drm/i915/gt/uc/intel_huc.c | 27 ++++++++++++++---------
drivers/gpu/drm/i915/gt/uc/intel_huc.h | 4 +++-
drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 2 +-
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 14 ++++++------
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h | 2 +-
5 files changed, 29 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 062ff914b274..c189ede4ef55 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -298,31 +298,38 @@ void intel_huc_init_early(struct intel_huc *huc)
static int check_huc_loading_mode(struct intel_huc *huc)
{
struct intel_gt *gt = huc_to_gt(huc);
- bool fw_needs_gsc = intel_huc_is_loaded_by_gsc(huc);
- bool hw_uses_gsc = false;
+ bool fw_is_meu = huc->fw.is_meu_binary;
/*
* The fuse for HuC load via GSC is only valid on platforms that have
* GuC deprivilege.
*/
if (HAS_GUC_DEPRIVILEGE(gt->i915))
- hw_uses_gsc = intel_uncore_read(gt->uncore, GUC_SHIM_CONTROL2) &
- GSC_LOADS_HUC;
+ huc->loaded_via_gsc = intel_uncore_read(gt->uncore, GUC_SHIM_CONTROL2) &
+ GSC_LOADS_HUC;
- if (fw_needs_gsc != hw_uses_gsc) {
- huc_err(huc, "mismatch between FW (%s) and HW (%s) load modes\n",
- HUC_LOAD_MODE_STRING(fw_needs_gsc), HUC_LOAD_MODE_STRING(hw_uses_gsc));
+ if (huc->loaded_via_gsc && !fw_is_meu) {
+ huc_err(huc, "HW requires a MEU blob, but we found a legacy one\n");
return -ENOEXEC;
}
- /* make sure we can access the GSC via the mei driver if we need it */
+ /*
+ * Newer meu blobs contain the old FW structure inside. If we found
+ * that, we can use it to load the legacy way.
+ */
+ if (!huc->loaded_via_gsc && fw_is_meu && !huc->fw.dma_start_offset) {
+ huc_err(huc," HW in legacy mode, but we have an incompatible meu blob\n");
+ return -ENOEXEC;
+ }
+
+ /* make sure we can access the GSC if we need it */
if (!(IS_ENABLED(CONFIG_INTEL_MEI_PXP) && IS_ENABLED(CONFIG_INTEL_MEI_GSC)) &&
- fw_needs_gsc) {
+ !HAS_ENGINE(gt, GSC0) && huc->loaded_via_gsc) {
huc_info(huc, "can't load due to missing MEI modules\n");
return -EIO;
}
- huc_dbg(huc, "loaded by GSC = %s\n", str_yes_no(fw_needs_gsc));
+ huc_dbg(huc, "loaded by GSC = %s\n", str_yes_no(huc->loaded_via_gsc));
return 0;
}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.h b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
index db555b3c1f56..345e1b9aa062 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
@@ -39,6 +39,8 @@ struct intel_huc {
struct notifier_block nb;
enum intel_huc_delayed_load_status status;
} delayed_load;
+
+ bool loaded_via_gsc;
};
int intel_huc_sanitize(struct intel_huc *huc);
@@ -73,7 +75,7 @@ static inline bool intel_huc_is_used(struct intel_huc *huc)
static inline bool intel_huc_is_loaded_by_gsc(const struct intel_huc *huc)
{
- return huc->fw.loaded_via_gsc;
+ return huc->loaded_via_gsc;
}
static inline bool intel_huc_wait_required(struct intel_huc *huc)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
index f1c973e1c676..88ad2c322c4a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
@@ -34,7 +34,7 @@ int intel_huc_fw_get_binary_info(struct intel_uc_fw *huc_fw, const void *data, s
size_t min_size = sizeof(*header);
int i;
- if (!huc_fw->loaded_via_gsc) {
+ if (!huc_fw->is_meu_binary) {
huc_err(huc, "Invalid FW type MEU parsing!\n");
return -EINVAL;
}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index da6fcfe1d80a..3338dd45e78b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -180,7 +180,7 @@ struct __packed uc_fw_blob {
u8 major;
u8 minor;
u8 patch;
- bool loaded_via_gsc;
+ bool is_meu_binary;
};
#define UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \
@@ -189,9 +189,9 @@ struct __packed uc_fw_blob {
.patch = patch_, \
.path = path_,
-#define UC_FW_BLOB_NEW(major_, minor_, patch_, gsc_, path_) \
+#define UC_FW_BLOB_NEW(major_, minor_, patch_, meu_, path_) \
{ UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \
- .legacy = false, .loaded_via_gsc = gsc_ }
+ .legacy = false, .is_meu_binary = meu_ }
#define UC_FW_BLOB_OLD(major_, minor_, patch_, path_) \
{ UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \
@@ -296,7 +296,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
uc_fw->file_wanted.path = blob->path;
uc_fw->file_wanted.ver.major = blob->major;
uc_fw->file_wanted.ver.minor = blob->minor;
- uc_fw->loaded_via_gsc = blob->loaded_via_gsc;
+ uc_fw->is_meu_binary = blob->is_meu_binary;
found = true;
break;
}
@@ -680,7 +680,7 @@ static int check_fw_header(struct intel_gt *gt,
if (uc_fw->type == INTEL_UC_FW_TYPE_GSC)
return 0;
- if (uc_fw->loaded_via_gsc)
+ if (uc_fw->is_meu_binary)
err = check_gsc_manifest(gt, fw, uc_fw);
else
err = check_ccs_header(gt, fw, uc_fw);
@@ -929,7 +929,7 @@ static int uc_fw_xfer(struct intel_uc_fw *uc_fw, u32 dst_offset, u32 dma_flags)
intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
/* Set the source address for the uCode */
- offset = uc_fw->dummy.start;
+ offset = uc_fw->dummy.start + uc_fw->dma_start_offset;
GEM_BUG_ON(upper_32_bits(offset) & 0xFFFF0000);
intel_uncore_write_fw(uncore, DMA_ADDR_0_LOW, lower_32_bits(offset));
intel_uncore_write_fw(uncore, DMA_ADDR_0_HIGH, upper_32_bits(offset));
@@ -1168,7 +1168,7 @@ size_t intel_uc_fw_copy_rsa(struct intel_uc_fw *uc_fw, void *dst, u32 max_len)
{
struct intel_memory_region *mr = uc_fw->obj->mm.region;
u32 size = min_t(u32, uc_fw->rsa_size, max_len);
- u32 offset = sizeof(struct uc_css_header) + uc_fw->ucode_size;
+ u32 offset = uc_fw->dma_start_offset + sizeof(struct uc_css_header) + uc_fw->ucode_size;
struct sgt_iter iter;
size_t count = 0;
int idx;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
index 2691bb6bde48..8f2306627332 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
@@ -115,7 +115,7 @@ struct intel_uc_fw {
u32 dma_start_offset;
- bool loaded_via_gsc;
+ bool is_meu_binary;
};
/*
--
2.40.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Intel-gfx] [PATCH v2 5/8] drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
` (3 preceding siblings ...)
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 4/8] drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so Daniele Ceraolo Spurio
@ 2023-04-28 18:58 ` Daniele Ceraolo Spurio
2023-05-13 0:51 ` Teres Alexis, Alan Previn
2023-05-19 18:45 ` John Harrison
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 6/8] drm/i915/mtl/huc: auth HuC via GSC Daniele Ceraolo Spurio
` (12 subsequent siblings)
17 siblings, 2 replies; 32+ messages in thread
From: Daniele Ceraolo Spurio @ 2023-04-28 18:58 UTC (permalink / raw)
To: intel-gfx; +Cc: Alan Previn, dri-devel
Before we add the second step of the MTL HuC auth (via GSC), we need to
have the ability to differentiate between them. To do so, the huc
authentication check is duplicated for GuC and GSC auth, with meu
binaries being considered fully authenticated only after the GSC auth
step.
To report the difference between the 2 auth steps, a new case is added
to the HuC getparam. This way, the clear media driver can start
submitting before full auth, as partial auth is enough for those
workloads.
v2: fix authentication status check for DG2
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
---
drivers/gpu/drm/i915/gt/uc/intel_huc.c | 94 +++++++++++++++++------
drivers/gpu/drm/i915/gt/uc/intel_huc.h | 16 +++-
drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 4 +-
drivers/gpu/drm/i915/i915_reg.h | 3 +
include/uapi/drm/i915_drm.h | 3 +-
5 files changed, 91 insertions(+), 29 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index c189ede4ef55..60f95d98e5fd 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -10,6 +10,7 @@
#include "intel_huc.h"
#include "intel_huc_print.h"
#include "i915_drv.h"
+#include "i915_reg.h"
#include <linux/device/bus.h>
#include <linux/mei_aux.h>
@@ -106,7 +107,7 @@ static enum hrtimer_restart huc_delayed_load_timer_callback(struct hrtimer *hrti
{
struct intel_huc *huc = container_of(hrtimer, struct intel_huc, delayed_load.timer);
- if (!intel_huc_is_authenticated(huc)) {
+ if (!intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC)) {
if (huc->delayed_load.status == INTEL_HUC_WAITING_ON_GSC)
huc_notice(huc, "timed out waiting for MEI GSC\n");
else if (huc->delayed_load.status == INTEL_HUC_WAITING_ON_PXP)
@@ -124,7 +125,7 @@ static void huc_delayed_load_start(struct intel_huc *huc)
{
ktime_t delay;
- GEM_BUG_ON(intel_huc_is_authenticated(huc));
+ GEM_BUG_ON(intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC));
/*
* On resume we don't have to wait for MEI-GSC to be re-probed, but we
@@ -284,13 +285,23 @@ void intel_huc_init_early(struct intel_huc *huc)
}
if (GRAPHICS_VER(i915) >= 11) {
- huc->status.reg = GEN11_HUC_KERNEL_LOAD_INFO;
- huc->status.mask = HUC_LOAD_SUCCESSFUL;
- huc->status.value = HUC_LOAD_SUCCESSFUL;
+ huc->status[INTEL_HUC_AUTH_BY_GUC].reg = GEN11_HUC_KERNEL_LOAD_INFO;
+ huc->status[INTEL_HUC_AUTH_BY_GUC].mask = HUC_LOAD_SUCCESSFUL;
+ huc->status[INTEL_HUC_AUTH_BY_GUC].value = HUC_LOAD_SUCCESSFUL;
} else {
- huc->status.reg = HUC_STATUS2;
- huc->status.mask = HUC_FW_VERIFIED;
- huc->status.value = HUC_FW_VERIFIED;
+ huc->status[INTEL_HUC_AUTH_BY_GUC].reg = HUC_STATUS2;
+ huc->status[INTEL_HUC_AUTH_BY_GUC].mask = HUC_FW_VERIFIED;
+ huc->status[INTEL_HUC_AUTH_BY_GUC].value = HUC_FW_VERIFIED;
+ }
+
+ if (IS_DG2(i915)) {
+ huc->status[INTEL_HUC_AUTH_BY_GSC].reg = GEN11_HUC_KERNEL_LOAD_INFO;
+ huc->status[INTEL_HUC_AUTH_BY_GSC].mask = HUC_LOAD_SUCCESSFUL;
+ huc->status[INTEL_HUC_AUTH_BY_GSC].value = HUC_LOAD_SUCCESSFUL;
+ } else {
+ huc->status[INTEL_HUC_AUTH_BY_GSC].reg = HECI_FWSTS5(MTL_GSC_HECI1_BASE);
+ huc->status[INTEL_HUC_AUTH_BY_GSC].mask = HECI_FWSTS5_HUC_AUTH_DONE;
+ huc->status[INTEL_HUC_AUTH_BY_GSC].value = HECI_FWSTS5_HUC_AUTH_DONE;
}
}
@@ -381,28 +392,39 @@ void intel_huc_suspend(struct intel_huc *huc)
delayed_huc_load_complete(huc);
}
-int intel_huc_wait_for_auth_complete(struct intel_huc *huc)
+static const char *auth_mode_string(struct intel_huc *huc,
+ enum intel_huc_authentication_type type)
+{
+ bool partial = !huc->loaded_via_gsc && huc->fw.is_meu_binary &&
+ type == INTEL_HUC_AUTH_BY_GUC;
+
+ return partial ? "clear media" : "all workloads";
+}
+
+int intel_huc_wait_for_auth_complete(struct intel_huc *huc,
+ enum intel_huc_authentication_type type)
{
struct intel_gt *gt = huc_to_gt(huc);
int ret;
ret = __intel_wait_for_register(gt->uncore,
- huc->status.reg,
- huc->status.mask,
- huc->status.value,
+ huc->status[type].reg,
+ huc->status[type].mask,
+ huc->status[type].value,
2, 50, NULL);
/* mark the load process as complete even if the wait failed */
delayed_huc_load_complete(huc);
if (ret) {
- huc_err(huc, "firmware not verified %pe\n", ERR_PTR(ret));
+ huc_err(huc, "firmware not verified for %s: %pe\n",
+ auth_mode_string(huc, type), ERR_PTR(ret));
intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_LOAD_FAIL);
return ret;
}
intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_RUNNING);
- huc_info(huc, "authenticated!\n");
+ huc_info(huc, "authenticated for %s!\n", auth_mode_string(huc, type));
return 0;
}
@@ -442,7 +464,7 @@ int intel_huc_auth(struct intel_huc *huc)
}
/* Check authentication status, it should be done by now */
- ret = intel_huc_wait_for_auth_complete(huc);
+ ret = intel_huc_wait_for_auth_complete(huc, INTEL_HUC_AUTH_BY_GUC);
if (ret)
goto fail;
@@ -453,16 +475,29 @@ int intel_huc_auth(struct intel_huc *huc)
return ret;
}
-bool intel_huc_is_authenticated(struct intel_huc *huc)
+bool intel_huc_is_authenticated(struct intel_huc *huc,
+ enum intel_huc_authentication_type type)
{
struct intel_gt *gt = huc_to_gt(huc);
intel_wakeref_t wakeref;
u32 status = 0;
with_intel_runtime_pm(gt->uncore->rpm, wakeref)
- status = intel_uncore_read(gt->uncore, huc->status.reg);
+ status = intel_uncore_read(gt->uncore, huc->status[type].reg);
- return (status & huc->status.mask) == huc->status.value;
+ return (status & huc->status[type].mask) == huc->status[type].value;
+}
+
+static bool huc_is_fully_authenticated(struct intel_huc *huc)
+{
+ struct intel_uc_fw *huc_fw = &huc->fw;
+
+ if (!huc_fw->is_meu_binary)
+ return intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GUC);
+ else if (intel_huc_is_loaded_by_gsc(huc) || HAS_ENGINE(huc_to_gt(huc), GSC0))
+ return intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC);
+ else
+ return false;
}
/**
@@ -477,7 +512,9 @@ bool intel_huc_is_authenticated(struct intel_huc *huc)
*/
int intel_huc_check_status(struct intel_huc *huc)
{
- switch (__intel_uc_fw_status(&huc->fw)) {
+ struct intel_uc_fw *huc_fw = &huc->fw;
+
+ switch (__intel_uc_fw_status(huc_fw)) {
case INTEL_UC_FIRMWARE_NOT_SUPPORTED:
return -ENODEV;
case INTEL_UC_FIRMWARE_DISABLED:
@@ -494,7 +531,17 @@ int intel_huc_check_status(struct intel_huc *huc)
break;
}
- return intel_huc_is_authenticated(huc);
+ /*
+ * meu binaries loaded by GuC are first partially authenticated by GuC
+ * and then fully authenticated by GSC
+ */
+ if (huc_is_fully_authenticated(huc))
+ return 1; /* full auth */
+ else if (huc_fw->is_meu_binary && !huc->loaded_via_gsc &&
+ intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GUC))
+ return 2; /* clear media only */
+ else
+ return 0;
}
static bool huc_has_delayed_load(struct intel_huc *huc)
@@ -508,7 +555,10 @@ void intel_huc_update_auth_status(struct intel_huc *huc)
if (!intel_uc_fw_is_loadable(&huc->fw))
return;
- if (intel_huc_is_authenticated(huc))
+ if (!huc->fw.is_meu_binary)
+ return;
+
+ if (huc_is_fully_authenticated(huc))
intel_uc_fw_change_status(&huc->fw,
INTEL_UC_FIRMWARE_RUNNING);
else if (huc_has_delayed_load(huc))
@@ -541,5 +591,5 @@ void intel_huc_load_status(struct intel_huc *huc, struct drm_printer *p)
with_intel_runtime_pm(gt->uncore->rpm, wakeref)
drm_printf(p, "HuC status: 0x%08x\n",
- intel_uncore_read(gt->uncore, huc->status.reg));
+ intel_uncore_read(gt->uncore, huc->status[INTEL_HUC_AUTH_BY_GUC].reg));
}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.h b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
index 345e1b9aa062..adb063cd27a0 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
@@ -22,6 +22,12 @@ enum intel_huc_delayed_load_status {
INTEL_HUC_DELAYED_LOAD_ERROR,
};
+enum intel_huc_authentication_type {
+ INTEL_HUC_AUTH_BY_GUC = 0,
+ INTEL_HUC_AUTH_BY_GSC,
+ INTEL_HUC_AUTH_MAX_MODES
+};
+
struct intel_huc {
/* Generic uC firmware management */
struct intel_uc_fw fw;
@@ -31,7 +37,7 @@ struct intel_huc {
i915_reg_t reg;
u32 mask;
u32 value;
- } status;
+ } status[INTEL_HUC_AUTH_MAX_MODES];
struct {
struct i915_sw_fence fence;
@@ -49,10 +55,12 @@ int intel_huc_init(struct intel_huc *huc);
void intel_huc_fini(struct intel_huc *huc);
void intel_huc_suspend(struct intel_huc *huc);
int intel_huc_auth(struct intel_huc *huc);
-int intel_huc_wait_for_auth_complete(struct intel_huc *huc);
+int intel_huc_wait_for_auth_complete(struct intel_huc *huc,
+ enum intel_huc_authentication_type type);
+bool intel_huc_is_authenticated(struct intel_huc *huc,
+ enum intel_huc_authentication_type type);
int intel_huc_check_status(struct intel_huc *huc);
void intel_huc_update_auth_status(struct intel_huc *huc);
-bool intel_huc_is_authenticated(struct intel_huc *huc);
void intel_huc_register_gsc_notifier(struct intel_huc *huc, struct bus_type *bus);
void intel_huc_unregister_gsc_notifier(struct intel_huc *huc, struct bus_type *bus);
@@ -81,7 +89,7 @@ static inline bool intel_huc_is_loaded_by_gsc(const struct intel_huc *huc)
static inline bool intel_huc_wait_required(struct intel_huc *huc)
{
return intel_huc_is_used(huc) && intel_huc_is_loaded_by_gsc(huc) &&
- !intel_huc_is_authenticated(huc);
+ !intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC);
}
void intel_huc_load_status(struct intel_huc *huc, struct drm_printer *p);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
index 88ad2c322c4a..3b8edaba97d2 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
@@ -141,7 +141,7 @@ int intel_huc_fw_load_and_auth_via_gsc(struct intel_huc *huc)
* component gets re-bound and this function called again. If so, just
* mark the HuC as loaded.
*/
- if (intel_huc_is_authenticated(huc)) {
+ if (intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC)) {
intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_RUNNING);
return 0;
}
@@ -154,7 +154,7 @@ int intel_huc_fw_load_and_auth_via_gsc(struct intel_huc *huc)
intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_TRANSFERRED);
- return intel_huc_wait_for_auth_complete(huc);
+ return intel_huc_wait_for_auth_complete(huc, INTEL_HUC_AUTH_BY_GSC);
}
/**
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index dde6e91055bd..1a62e73c3d9c 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -941,6 +941,9 @@
#define HECI_H_GS1(base) _MMIO((base) + 0xc4c)
#define HECI_H_GS1_ER_PREP REG_BIT(0)
+#define HECI_FWSTS5(base) _MMIO(base + 0xc68)
+#define HECI_FWSTS5_HUC_AUTH_DONE (1 << 19)
+
#define HSW_GTT_CACHE_EN _MMIO(0x4024)
#define GTT_CACHE_EN_ALL 0xF0007FFF
#define GEN7_WR_WATERMARK _MMIO(0x4028)
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index dba7c5a5b25e..43b8de42a94e 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -659,7 +659,8 @@ typedef struct drm_i915_irq_wait {
* If the IOCTL is successful, the returned parameter will be set to one of the
* following values:
* * 0 if HuC firmware load is not complete,
- * * 1 if HuC firmware is authenticated and running.
+ * * 1 if HuC firmware is loaded and fully authenticated,
+ * * 2 if HuC firmware is loaded and authenticated for clear media only
*/
#define I915_PARAM_HUC_STATUS 42
--
2.40.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Intel-gfx] [PATCH v2 6/8] drm/i915/mtl/huc: auth HuC via GSC
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
` (4 preceding siblings ...)
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 5/8] drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow Daniele Ceraolo Spurio
@ 2023-04-28 18:58 ` Daniele Ceraolo Spurio
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 7/8] drm/i915/mtl/huc: Use the media gt for the HuC getparam Daniele Ceraolo Spurio
` (11 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Daniele Ceraolo Spurio @ 2023-04-28 18:58 UTC (permalink / raw)
To: intel-gfx; +Cc: Alan Previn, dri-devel
The full authentication via the GSC requires an heci packet submission
to the GSC FW via the GSC CS. The GSC has new PXP command for this
(literally called NEW_HUC_AUTH).
The intel_huc_auth fuction is also updated to handle both authentication
types.
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
---
drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 24 ++++-
.../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c | 2 +-
drivers/gpu/drm/i915/gt/uc/intel_huc.c | 50 +++++++---
drivers/gpu/drm/i915/gt/uc/intel_huc.h | 6 +-
drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 94 +++++++++++++++++++
drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h | 1 +
drivers/gpu/drm/i915/gt/uc/intel_uc.c | 2 +-
.../drm/i915/pxp/intel_pxp_cmd_interface_43.h | 14 ++-
drivers/gpu/drm/i915/pxp/intel_pxp_huc.c | 2 +-
9 files changed, 173 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
index af542e3cb3e9..b6d0ee1660b2 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -29,13 +29,29 @@ static void gsc_work(struct work_struct *work)
if (actions & GSC_ACTION_FW_LOAD) {
ret = intel_gsc_uc_fw_upload(gsc);
- if (ret == -EEXIST) /* skip proxy if not a new load */
- actions &= ~GSC_ACTION_FW_LOAD;
- else if (ret)
+ if (!ret)
+ /* setup proxy on a new load */
+ actions |= GSC_ACTION_SW_PROXY;
+ else if (ret != -EEXIST)
goto out_put;
+
+ /*
+ * The HuC auth can be done both before or after the proxy init;
+ * if done after, a proxy request will be issued and must be
+ * serviced before the authentication can complete.
+ * Since this worker also handles proxy requests, we can't
+ * perform an action that requires the proxy from within it and
+ * then stall waiting for it, because we'd be blocking the
+ * service path. Therefore, it is easier for us to load HuC
+ * first and do proxy later. The GSC will ack the HuC auth and
+ * then send the HuC proxy request as part of the proxy init
+ * flow.
+ */
+ if (intel_uc_uses_huc(>->uc))
+ intel_huc_auth(>->uc.huc, INTEL_HUC_AUTH_BY_GSC);
}
- if (actions & (GSC_ACTION_FW_LOAD | GSC_ACTION_SW_PROXY)) {
+ if (actions & GSC_ACTION_SW_PROXY) {
if (!intel_gsc_uc_fw_init_done(gsc)) {
gt_err(gt, "Proxy request received with GSC not loaded!\n");
goto out_put;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c
index ea0da06e2f39..edcfa990239d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c
@@ -98,7 +98,7 @@ void intel_gsc_uc_heci_cmd_emit_mtl_header(struct intel_gsc_mtl_header *header,
u64 host_session_id)
{
host_session_id &= ~HOST_SESSION_MASK;
- if (heci_client_id == HECI_MEADDRESS_PXP)
+ if (host_session_id && heci_client_id == HECI_MEADDRESS_PXP)
host_session_id |= HOST_SESSION_PXP_SINGLE;
header->validity_marker = GSC_HECI_VALIDITY_MARKER;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 60f95d98e5fd..54411ac33f35 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -347,20 +347,34 @@ static int check_huc_loading_mode(struct intel_huc *huc)
int intel_huc_init(struct intel_huc *huc)
{
+ struct intel_gt *gt = huc_to_gt(huc);
int err;
err = check_huc_loading_mode(huc);
if (err)
goto out;
+ if (HAS_ENGINE(gt, GSC0)) {
+ struct i915_vma *vma = intel_guc_allocate_vma(>->uc.guc, SZ_8K);
+ if (IS_ERR(vma)) {
+ huc_info(huc, "Failed to allocate heci pkt\n");
+ goto out;
+ }
+
+ huc->heci_pkt = vma;
+ }
+
err = intel_uc_fw_init(&huc->fw);
if (err)
- goto out;
+ goto out_pkt;
intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_LOADABLE);
return 0;
+out_pkt:
+ if (huc->heci_pkt)
+ i915_vma_unpin_and_release(&huc->heci_pkt, 0);
out:
intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_INIT_FAIL);
huc_info(huc, "initialization failed %pe\n", ERR_PTR(err));
@@ -375,6 +389,9 @@ void intel_huc_fini(struct intel_huc *huc)
*/
delayed_huc_load_fini(huc);
+ if (huc->heci_pkt)
+ i915_vma_unpin_and_release(&huc->heci_pkt, 0);
+
if (intel_uc_fw_is_loadable(&huc->fw))
intel_uc_fw_fini(&huc->fw);
}
@@ -431,6 +448,7 @@ int intel_huc_wait_for_auth_complete(struct intel_huc *huc,
/**
* intel_huc_auth() - Authenticate HuC uCode
* @huc: intel_huc structure
+ * @type: authentication type (via GuC or via GSC)
*
* Called after HuC and GuC firmware loading during intel_uc_init_hw().
*
@@ -438,7 +456,7 @@ int intel_huc_wait_for_auth_complete(struct intel_huc *huc,
* passing the offset of the RSA signature to intel_guc_auth_huc(). It then
* waits for up to 50ms for firmware verification ACK.
*/
-int intel_huc_auth(struct intel_huc *huc)
+int intel_huc_auth(struct intel_huc *huc, enum intel_huc_authentication_type type)
{
struct intel_gt *gt = huc_to_gt(huc);
struct intel_guc *guc = >->uc.guc;
@@ -447,31 +465,41 @@ int intel_huc_auth(struct intel_huc *huc)
if (!intel_uc_fw_is_loaded(&huc->fw))
return -ENOEXEC;
- /* GSC will do the auth */
+ /* GSC will do the auth with the load */
if (intel_huc_is_loaded_by_gsc(huc))
return -ENODEV;
+ if (intel_huc_is_authenticated(huc, type))
+ return -EEXIST;
+
ret = i915_inject_probe_error(gt->i915, -ENXIO);
if (ret)
goto fail;
- GEM_BUG_ON(intel_uc_fw_is_running(&huc->fw));
-
- ret = intel_guc_auth_huc(guc, intel_guc_ggtt_offset(guc, huc->fw.rsa_data));
- if (ret) {
- huc_err(huc, "authentication by GuC failed %pe\n", ERR_PTR(ret));
- goto fail;
+ switch(type) {
+ case INTEL_HUC_AUTH_BY_GUC:
+ ret = intel_guc_auth_huc(guc, intel_guc_ggtt_offset(guc, huc->fw.rsa_data));
+ break;
+ case INTEL_HUC_AUTH_BY_GSC:
+ ret = intel_huc_fw_auth_via_gsccs(huc);
+ break;
+ default:
+ MISSING_CASE(type);
+ ret = -EINVAL;
}
+ if (ret)
+ goto fail;
/* Check authentication status, it should be done by now */
- ret = intel_huc_wait_for_auth_complete(huc, INTEL_HUC_AUTH_BY_GUC);
+ ret = intel_huc_wait_for_auth_complete(huc, type);
if (ret)
goto fail;
return 0;
fail:
- huc_probe_error(huc, "authentication failed %pe\n", ERR_PTR(ret));
+ huc_probe_error(huc, "%s authentication failed %pe\n",
+ auth_mode_string(huc, type), ERR_PTR(ret));
return ret;
}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.h b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
index adb063cd27a0..319d38c4ab51 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
@@ -15,6 +15,7 @@
#include <linux/hrtimer.h>
struct bus_type;
+struct i915_vma;
enum intel_huc_delayed_load_status {
INTEL_HUC_WAITING_ON_GSC = 0,
@@ -46,6 +47,9 @@ struct intel_huc {
enum intel_huc_delayed_load_status status;
} delayed_load;
+ /* for load via GSCCS */
+ struct i915_vma *heci_pkt;
+
bool loaded_via_gsc;
};
@@ -54,7 +58,7 @@ void intel_huc_init_early(struct intel_huc *huc);
int intel_huc_init(struct intel_huc *huc);
void intel_huc_fini(struct intel_huc *huc);
void intel_huc_suspend(struct intel_huc *huc);
-int intel_huc_auth(struct intel_huc *huc);
+int intel_huc_auth(struct intel_huc *huc, enum intel_huc_authentication_type type);
int intel_huc_wait_for_auth_complete(struct intel_huc *huc,
enum intel_huc_authentication_type type);
bool intel_huc_is_authenticated(struct intel_huc *huc,
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
index 3b8edaba97d2..feb951a793ea 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
@@ -6,11 +6,105 @@
#include "gt/intel_gsc.h"
#include "gt/intel_gt.h"
#include "intel_gsc_meu_headers.h"
+#include "intel_gsc_uc_heci_cmd_submit.h"
#include "intel_huc.h"
#include "intel_huc_fw.h"
#include "intel_huc_print.h"
#include "i915_drv.h"
#include "pxp/intel_pxp_huc.h"
+#include "pxp/intel_pxp_cmd_interface_43.h"
+
+struct mtl_huc_auth_msg_in {
+ struct intel_gsc_mtl_header header;
+ struct pxp43_new_huc_auth_in huc_in;
+} __packed;
+
+struct mtl_huc_auth_msg_out {
+ struct intel_gsc_mtl_header header;
+ struct pxp43_huc_auth_out huc_out;
+} __packed;
+
+int intel_huc_fw_auth_via_gsccs(struct intel_huc *huc)
+{
+ struct intel_gt *gt = huc_to_gt(huc);
+ struct drm_i915_private *i915 = gt->i915;
+ struct drm_i915_gem_object *obj;
+ struct mtl_huc_auth_msg_in *msg_in;
+ struct mtl_huc_auth_msg_out *msg_out;
+ void *pkt_vaddr;
+ u64 pkt_offset;
+ int retry = 5;
+ int err = 0;
+
+ if (!huc->heci_pkt)
+ return -ENODEV;
+
+ obj = huc->heci_pkt->obj;
+ pkt_offset = i915_ggtt_offset(huc->heci_pkt);
+
+ pkt_vaddr = i915_gem_object_pin_map_unlocked(obj,
+ i915_coherent_map_type(i915, obj, true));
+ if (IS_ERR(pkt_vaddr))
+ return PTR_ERR(pkt_vaddr);
+
+ msg_in = pkt_vaddr;
+ msg_out = pkt_vaddr + SZ_4K;
+
+ intel_gsc_uc_heci_cmd_emit_mtl_header(&msg_in->header,
+ HECI_MEADDRESS_PXP,
+ sizeof(*msg_in), 0);
+
+ msg_in->huc_in.header.api_version = PXP_APIVER(4, 3);
+ msg_in->huc_in.header.command_id = PXP43_CMDID_NEW_HUC_AUTH;
+ msg_in->huc_in.header.status = 0;
+ msg_in->huc_in.header.buffer_len = sizeof(msg_in->huc_in) -
+ sizeof(msg_in->huc_in.header);
+ msg_in->huc_in.huc_base_address = huc->fw.dummy.start;
+ msg_in->huc_in.huc_size = huc->fw.obj->base.size;
+
+ do {
+ err = intel_gsc_uc_heci_cmd_submit_packet(>->uc.gsc,
+ pkt_offset, sizeof(*msg_in),
+ pkt_offset + SZ_4K, SZ_4K);
+ if (err) {
+ huc_err(huc, "failed to submit GSC request to auth: %d\n", err);
+ goto out_unpin;
+ }
+
+ if (msg_out->header.flags & GSC_OUTFLAG_MSG_PENDING) {
+ msg_in->header.gsc_message_handle = msg_out->header.gsc_message_handle;
+ err = -EBUSY;
+ msleep(50);
+ }
+ } while (--retry && err == -EBUSY);
+
+ if (err)
+ goto out_unpin;
+
+ if (msg_out->header.message_size != sizeof(*msg_out)) {
+ huc_err(huc, "invalid GSC reply length %u [expected %zu]\n",
+ msg_out->header.message_size, sizeof(*msg_out));
+ err = -EPROTO;
+ goto out_unpin;
+ }
+
+ /*
+ * The GSC will return PXP_STATUS_OP_NOT_PERMITTED if the HuC is already
+ * loaded. If the same error is ever returned with HuC not loaded we'll
+ * still catch it when we check the authentication bit later.
+ */
+ if (msg_out->huc_out.header.status != PXP_STATUS_SUCCESS &&
+ msg_out->huc_out.header.status != PXP_STATUS_OP_NOT_PERMITTED) {
+ huc_err(huc, "auth failed with GSC error = 0x%x\n",
+ msg_out->huc_out.header.status);
+ err = -EIO;
+ goto out_unpin;
+ }
+
+out_unpin:
+ i915_gem_object_unpin_map(obj);
+ return err;
+}
static void get_version_from_meu_manifest(struct intel_uc_fw_ver *ver, const void *data)
{
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
index 0999ffe6f962..307ab45e6b09 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
@@ -12,6 +12,7 @@ struct intel_uc_fw;
#include <linux/types.h>
int intel_huc_fw_load_and_auth_via_gsc(struct intel_huc *huc);
+int intel_huc_fw_auth_via_gsccs(struct intel_huc *huc);
int intel_huc_fw_upload(struct intel_huc *huc);
int intel_huc_fw_get_binary_info(struct intel_uc_fw *huc_fw, const void *data, size_t size);
#endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index b6adfda3761e..05ad56274007 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -535,7 +535,7 @@ static int __uc_init_hw(struct intel_uc *uc)
if (intel_huc_is_loaded_by_gsc(huc))
intel_huc_update_auth_status(huc);
else
- intel_huc_auth(huc);
+ intel_huc_auth(huc, INTEL_HUC_AUTH_BY_GUC);
if (intel_uc_uses_guc_submission(uc)) {
ret = intel_guc_submission_enable(guc);
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h
index ad67e3f49c20..ac7a3829dda6 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h
@@ -11,15 +11,23 @@
/* PXP-Cmd-Op definitions */
#define PXP43_CMDID_START_HUC_AUTH 0x0000003A
+#define PXP43_CMDID_NEW_HUC_AUTH 0x0000003F /* MTL+ */
-/* PXP-Input-Packet: HUC-Authentication */
+/* PXP-Input-Packet: HUC Load and Authentication */
struct pxp43_start_huc_auth_in {
struct pxp_cmd_header header;
__le64 huc_base_address;
} __packed;
-/* PXP-Output-Packet: HUC-Authentication */
-struct pxp43_start_huc_auth_out {
+/* PXP-Input-Packet: HUC Auth-only */
+struct pxp43_new_huc_auth_in {
+ struct pxp_cmd_header header;
+ u64 huc_base_address;
+ u32 huc_size;
+} __packed;
+
+/* PXP-Output-Packet: HUC Load and Authentication or Auth-only */
+struct pxp43_huc_auth_out {
struct pxp_cmd_header header;
} __packed;
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_huc.c b/drivers/gpu/drm/i915/pxp/intel_pxp_huc.c
index 23431c36b60b..5eedce916942 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_huc.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_huc.c
@@ -19,7 +19,7 @@ int intel_pxp_huc_load_and_auth(struct intel_pxp *pxp)
struct intel_gt *gt;
struct intel_huc *huc;
struct pxp43_start_huc_auth_in huc_in = {0};
- struct pxp43_start_huc_auth_out huc_out = {0};
+ struct pxp43_huc_auth_out huc_out = {0};
dma_addr_t huc_phys_addr;
u8 client_id = 0;
u8 fence_id = 0;
--
2.40.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Intel-gfx] [PATCH v2 7/8] drm/i915/mtl/huc: Use the media gt for the HuC getparam
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
` (5 preceding siblings ...)
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 6/8] drm/i915/mtl/huc: auth HuC via GSC Daniele Ceraolo Spurio
@ 2023-04-28 18:58 ` Daniele Ceraolo Spurio
2023-05-25 19:53 ` John Harrison
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 8/8] drm/i915/huc: define HuC FW version for MTL Daniele Ceraolo Spurio
` (10 subsequent siblings)
17 siblings, 1 reply; 32+ messages in thread
From: Daniele Ceraolo Spurio @ 2023-04-28 18:58 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel
On MTL, for obvious reasons, HuC is only available on the media tile.
We already disable SW support for HuC on the root gt due to the
absence of VCS engines, but we also need to update the getparam to point
to the HuC struct in the media GT.
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: John Harrison <John.C.Harrison@Intel.com>
---
drivers/gpu/drm/i915/i915_getparam.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/i915_getparam.c b/drivers/gpu/drm/i915/i915_getparam.c
index 2238e096c957..7aa47550e4f2 100644
--- a/drivers/gpu/drm/i915/i915_getparam.c
+++ b/drivers/gpu/drm/i915/i915_getparam.c
@@ -98,7 +98,11 @@ int i915_getparam_ioctl(struct drm_device *dev, void *data,
value = sseu->min_eu_in_pool;
break;
case I915_PARAM_HUC_STATUS:
- value = intel_huc_check_status(&to_gt(i915)->uc.huc);
+ /* On platform with a media GT, the HuC is on that GT */
+ if (i915->media_gt)
+ value = intel_huc_check_status(&i915->media_gt->uc.huc);
+ else
+ value = intel_huc_check_status(&to_gt(i915)->uc.huc);
if (value < 0)
return value;
break;
--
2.40.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Intel-gfx] [PATCH v2 8/8] drm/i915/huc: define HuC FW version for MTL
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
` (6 preceding siblings ...)
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 7/8] drm/i915/mtl/huc: Use the media gt for the HuC getparam Daniele Ceraolo Spurio
@ 2023-04-28 18:58 ` Daniele Ceraolo Spurio
2023-05-25 19:54 ` John Harrison
2023-04-28 21:29 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: HuC loading and authentication for MTL (rev2) Patchwork
` (9 subsequent siblings)
17 siblings, 1 reply; 32+ messages in thread
From: Daniele Ceraolo Spurio @ 2023-04-28 18:58 UTC (permalink / raw)
To: intel-gfx; +Cc: Alan Previn, dri-devel
Follow the same logic as DG2, so just a meu binary with no version number.
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
---
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index 3338dd45e78b..796f54a62eef 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -102,6 +102,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
fw_def(SKYLAKE, 0, guc_mmp(skl, 70, 1, 1))
#define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_raw, huc_mmp, huc_gsc) \
+ fw_def(METEORLAKE, 0, huc_gsc(mtl)) \
fw_def(DG2, 0, huc_gsc(dg2)) \
fw_def(ALDERLAKE_P, 0, huc_raw(tgl)) \
fw_def(ALDERLAKE_P, 0, huc_mmp(tgl, 7, 9, 3)) \
--
2.40.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: HuC loading and authentication for MTL (rev2)
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
` (7 preceding siblings ...)
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 8/8] drm/i915/huc: define HuC FW version for MTL Daniele Ceraolo Spurio
@ 2023-04-28 21:29 ` Patchwork
2023-04-28 21:29 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
` (8 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Patchwork @ 2023-04-28 21:29 UTC (permalink / raw)
To: Daniele Ceraolo Spurio; +Cc: intel-gfx
== Series Details ==
Series: drm/i915: HuC loading and authentication for MTL (rev2)
URL : https://patchwork.freedesktop.org/series/117080/
State : warning
== Summary ==
Error: dim checkpatch failed
4f134a76627f DO NOT REVIEW: drm/i915: Add support for MTL GSC SW Proxy
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
-:133: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#133:
new file mode 100644
-:138: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#138: FILE: drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c:1:
+#include "intel_gsc_proxy.h"
-:140: WARNING:SPDX_LICENSE_TAG: Misplaced SPDX-License-Identifier tag - use line 1 instead
#140: FILE: drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c:3:
+// SPDX-License-Identifier: MIT
-:278: WARNING:MEMORY_BARRIER: memory barrier without comment
#278: FILE: drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c:141:
+ wmb();
-:321: CHECK:BRACES: Blank lines aren't necessary before a close brace '}'
#321: FILE: drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c:184:
+
+}
total: 0 errors, 4 warnings, 1 checks, 988 lines checked
1fcb4f9f51b9 drm/i915/uc: perma-pin firmwares
-:114: ERROR:SPACING: space prohibited before that close parenthesis ')'
#114: FILE: drivers/gpu/drm/i915/gt/uc/intel_uc.h:117:
+intel_uc_ops_function(resume_mappings, resume_mappings, void, );
total: 1 errors, 0 warnings, 0 checks, 196 lines checked
8cdce6d867c8 drm/i915/huc: Parse the GSC-enabled HuC binary
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
-:21: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#21:
new file mode 100644
-:411: WARNING:LINE_SPACING: Missing a blank line after declarations
#411: FILE: drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c:623:
+ u32 delta = uc_fw->dma_start_offset;
+ __check_ccs_header(gt, fw->data + delta, fw->size - delta, uc_fw);
total: 0 errors, 2 warnings, 0 checks, 379 lines checked
84c4b445bc8b drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so
-:56: ERROR:SPACING: space required after that ',' (ctx:VxV)
#56: FILE: drivers/gpu/drm/i915/gt/uc/intel_huc.c:321:
+ huc_err(huc," HW in legacy mode, but we have an incompatible meu blob\n");
^
total: 1 errors, 0 warnings, 0 checks, 131 lines checked
19dffec79556 drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow
-:49: WARNING:AVOID_BUG: Do not crash the kernel unless it is absolutely unavoidable--use WARN_ON_ONCE() plus recovery code (if feasible) instead of BUG() or variants
#49: FILE: drivers/gpu/drm/i915/gt/uc/intel_huc.c:128:
+ GEM_BUG_ON(intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC));
-:300: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'base' may be better as '(base)' to avoid precedence issues
#300: FILE: drivers/gpu/drm/i915/i915_reg.h:944:
+#define HECI_FWSTS5(base) _MMIO(base + 0xc68)
total: 0 errors, 1 warnings, 1 checks, 258 lines checked
6222e0bf0c79 drm/i915/mtl/huc: auth HuC via GSC
-:9: WARNING:TYPO_SPELLING: 'fuction' may be misspelled - perhaps 'function'?
#9:
The intel_huc_auth fuction is also updated to handle both authentication
^^^^^^^
-:83: WARNING:LINE_SPACING: Missing a blank line after declarations
#83: FILE: drivers/gpu/drm/i915/gt/uc/intel_huc.c:359:
+ struct i915_vma *vma = intel_guc_allocate_vma(>->uc.guc, SZ_8K);
+ if (IS_ERR(vma)) {
-:155: ERROR:SPACING: space required before the open parenthesis '('
#155: FILE: drivers/gpu/drm/i915/gt/uc/intel_huc.c:479:
+ switch(type) {
total: 1 errors, 2 warnings, 0 checks, 328 lines checked
64120cc202a7 drm/i915/mtl/huc: Use the media gt for the HuC getparam
c1aa0a9ca781 drm/i915/huc: define HuC FW version for MTL
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm/i915: HuC loading and authentication for MTL (rev2)
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
` (8 preceding siblings ...)
2023-04-28 21:29 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: HuC loading and authentication for MTL (rev2) Patchwork
@ 2023-04-28 21:29 ` Patchwork
2023-04-28 21:47 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
` (7 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Patchwork @ 2023-04-28 21:29 UTC (permalink / raw)
To: Daniele Ceraolo Spurio; +Cc: intel-gfx
== Series Details ==
Series: drm/i915: HuC loading and authentication for MTL (rev2)
URL : https://patchwork.freedesktop.org/series/117080/
State : warning
== Summary ==
Error: dim sparse failed
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Intel-gfx] ✗ Fi.CI.BAT: failure for drm/i915: HuC loading and authentication for MTL (rev2)
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
` (9 preceding siblings ...)
2023-04-28 21:29 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
@ 2023-04-28 21:47 ` Patchwork
2023-05-02 16:05 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: HuC loading and authentication for MTL (rev3) Patchwork
` (6 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Patchwork @ 2023-04-28 21:47 UTC (permalink / raw)
To: Daniele Ceraolo Spurio; +Cc: intel-gfx
[-- Attachment #1: Type: text/plain, Size: 10109 bytes --]
== Series Details ==
Series: drm/i915: HuC loading and authentication for MTL (rev2)
URL : https://patchwork.freedesktop.org/series/117080/
State : failure
== Summary ==
CI Bug Log - changes from CI_DRM_13075 -> Patchwork_117080v2
====================================================
Summary
-------
**FAILURE**
Serious unknown changes coming with Patchwork_117080v2 absolutely need to be
verified manually.
If you think the reported changes have nothing to do with the changes
introduced in Patchwork_117080v2, please notify your bug team to allow them
to document this new failure mode, which will reduce false positives in CI.
External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/index.html
Participating hosts (39 -> 38)
------------------------------
Missing (1): fi-snb-2520m
Possible new issues
-------------------
Here are the unknown changes that may have been introduced in Patchwork_117080v2:
### IGT changes ###
#### Possible regressions ####
* igt@i915_selftest@live@client:
- bat-dg2-8: [PASS][1] -> [DMESG-WARN][2] +37 similar issues
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/bat-dg2-8/igt@i915_selftest@live@client.html
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/bat-dg2-8/igt@i915_selftest@live@client.html
* igt@i915_selftest@live@coherency:
- bat-dg2-9: [PASS][3] -> [DMESG-WARN][4] +38 similar issues
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/bat-dg2-9/igt@i915_selftest@live@coherency.html
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/bat-dg2-9/igt@i915_selftest@live@coherency.html
* igt@i915_selftest@live@perf:
- bat-dg2-11: [PASS][5] -> [DMESG-WARN][6] +37 similar issues
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/bat-dg2-11/igt@i915_selftest@live@perf.html
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/bat-dg2-11/igt@i915_selftest@live@perf.html
* igt@i915_selftest@live@slpc:
- bat-atsm-1: [PASS][7] -> [DMESG-WARN][8] +39 similar issues
[7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/bat-atsm-1/igt@i915_selftest@live@slpc.html
[8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/bat-atsm-1/igt@i915_selftest@live@slpc.html
#### Suppressed ####
The following results come from untrusted machines, tests, or statuses.
They do not affect the overall result.
* igt@i915_selftest@live@requests:
- {bat-mtlp-6}: [ABORT][9] ([i915#4983] / [i915#7920]) -> [DMESG-FAIL][10]
[9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/bat-mtlp-6/igt@i915_selftest@live@requests.html
[10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/bat-mtlp-6/igt@i915_selftest@live@requests.html
Known issues
------------
Here are the changes found in Patchwork_117080v2 that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@core_hotunplug@unbind-rebind:
- bat-dg2-11: [PASS][11] -> [DMESG-WARN][12] ([i915#1982])
[11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/bat-dg2-11/igt@core_hotunplug@unbind-rebind.html
[12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/bat-dg2-11/igt@core_hotunplug@unbind-rebind.html
* igt@i915_module_load@reload:
- bat-dg2-11: [PASS][13] -> [DMESG-WARN][14] ([i915#8189]) +1 similar issue
[13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/bat-dg2-11/igt@i915_module_load@reload.html
[14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/bat-dg2-11/igt@i915_module_load@reload.html
- bat-dg2-9: [PASS][15] -> [DMESG-WARN][16] ([i915#8189]) +1 similar issue
[15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/bat-dg2-9/igt@i915_module_load@reload.html
[16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/bat-dg2-9/igt@i915_module_load@reload.html
- bat-dg2-8: [PASS][17] -> [DMESG-WARN][18] ([i915#8189]) +1 similar issue
[17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/bat-dg2-8/igt@i915_module_load@reload.html
[18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/bat-dg2-8/igt@i915_module_load@reload.html
* igt@i915_pm_rpm@module-reload:
- fi-kbl-soraka: [PASS][19] -> [DMESG-WARN][20] ([i915#1982])
[19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/fi-kbl-soraka/igt@i915_pm_rpm@module-reload.html
[20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/fi-kbl-soraka/igt@i915_pm_rpm@module-reload.html
* igt@i915_selftest@live@gt_heartbeat:
- bat-atsm-1: [PASS][21] -> [DMESG-WARN][22] ([i915#7699]) +1 similar issue
[21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/bat-atsm-1/igt@i915_selftest@live@gt_heartbeat.html
[22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/bat-atsm-1/igt@i915_selftest@live@gt_heartbeat.html
- bat-dg2-9: [PASS][23] -> [DMESG-WARN][24] ([i915#7699]) +1 similar issue
[23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/bat-dg2-9/igt@i915_selftest@live@gt_heartbeat.html
[24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/bat-dg2-9/igt@i915_selftest@live@gt_heartbeat.html
- bat-dg2-8: [PASS][25] -> [DMESG-WARN][26] ([i915#7699]) +1 similar issue
[25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/bat-dg2-8/igt@i915_selftest@live@gt_heartbeat.html
[26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/bat-dg2-8/igt@i915_selftest@live@gt_heartbeat.html
- bat-dg2-11: [PASS][27] -> [DMESG-WARN][28] ([i915#7699])
[27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/bat-dg2-11/igt@i915_selftest@live@gt_heartbeat.html
[28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/bat-dg2-11/igt@i915_selftest@live@gt_heartbeat.html
* igt@kms_chamelium_hpd@common-hpd-after-suspend:
- fi-bsw-n3050: NOTRUN -> [SKIP][29] ([fdo#109271])
[29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/fi-bsw-n3050/igt@kms_chamelium_hpd@common-hpd-after-suspend.html
* igt@kms_pipe_crc_basic@suspend-read-crc@pipe-b-hdmi-a-1:
- fi-rkl-11600: [PASS][30] -> [FAIL][31] ([fdo#103375])
[30]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/fi-rkl-11600/igt@kms_pipe_crc_basic@suspend-read-crc@pipe-b-hdmi-a-1.html
[31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/fi-rkl-11600/igt@kms_pipe_crc_basic@suspend-read-crc@pipe-b-hdmi-a-1.html
#### Possible fixes ####
* igt@gem_huc_copy@huc-copy:
- {bat-mtlp-6}: [SKIP][32] ([i915#3595]) -> [PASS][33]
[32]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/bat-mtlp-6/igt@gem_huc_copy@huc-copy.html
[33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/bat-mtlp-6/igt@gem_huc_copy@huc-copy.html
- {bat-mtlp-8}: [SKIP][34] ([i915#3595]) -> [PASS][35]
[34]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/bat-mtlp-8/igt@gem_huc_copy@huc-copy.html
[35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/bat-mtlp-8/igt@gem_huc_copy@huc-copy.html
* igt@i915_selftest@live@execlists:
- fi-bsw-n3050: [ABORT][36] ([i915#7911] / [i915#7913]) -> [PASS][37]
[36]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/fi-bsw-n3050/igt@i915_selftest@live@execlists.html
[37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/fi-bsw-n3050/igt@i915_selftest@live@execlists.html
* igt@i915_selftest@live@gt_mocs:
- {bat-mtlp-8}: [ABORT][38] -> [PASS][39]
[38]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13075/bat-mtlp-8/igt@i915_selftest@live@gt_mocs.html
[39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/bat-mtlp-8/igt@i915_selftest@live@gt_mocs.html
{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).
[fdo#103375]: https://bugs.freedesktop.org/show_bug.cgi?id=103375
[fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
[i915#1845]: https://gitlab.freedesktop.org/drm/intel/issues/1845
[i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
[i915#3595]: https://gitlab.freedesktop.org/drm/intel/issues/3595
[i915#4078]: https://gitlab.freedesktop.org/drm/intel/issues/4078
[i915#4983]: https://gitlab.freedesktop.org/drm/intel/issues/4983
[i915#6645]: https://gitlab.freedesktop.org/drm/intel/issues/6645
[i915#7699]: https://gitlab.freedesktop.org/drm/intel/issues/7699
[i915#7828]: https://gitlab.freedesktop.org/drm/intel/issues/7828
[i915#7911]: https://gitlab.freedesktop.org/drm/intel/issues/7911
[i915#7913]: https://gitlab.freedesktop.org/drm/intel/issues/7913
[i915#7920]: https://gitlab.freedesktop.org/drm/intel/issues/7920
[i915#8189]: https://gitlab.freedesktop.org/drm/intel/issues/8189
[i915#8379]: https://gitlab.freedesktop.org/drm/intel/issues/8379
Build changes
-------------
* Linux: CI_DRM_13075 -> Patchwork_117080v2
CI-20190529: 20190529
CI_DRM_13075: b0058d7610b0cd455b699a3e393e416823a6bc80 @ git://anongit.freedesktop.org/gfx-ci/linux
IGT_7277: 1cb3507f3ff28d11bd5cfabcde576fe78ddab571 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
Patchwork_117080v2: b0058d7610b0cd455b699a3e393e416823a6bc80 @ git://anongit.freedesktop.org/gfx-ci/linux
### Linux commits
93a5b488bf87 drm/i915/huc: define HuC FW version for MTL
7b85c1090c5b drm/i915/mtl/huc: Use the media gt for the HuC getparam
b5ee1ec4587d drm/i915/mtl/huc: auth HuC via GSC
7e2c67c47fb2 drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow
0b868f35e6b5 drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so
9159f4f8f27f drm/i915/huc: Parse the GSC-enabled HuC binary
de5537562b4e drm/i915/uc: perma-pin firmwares
50fed1ba03b7 DO NOT REVIEW: drm/i915: Add support for MTL GSC SW Proxy
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v2/index.html
[-- Attachment #2: Type: text/html, Size: 11366 bytes --]
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Intel-gfx] [PATCH v2] drm/i915/huc: Parse the GSC-enabled HuC binary
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 3/8] drm/i915/huc: Parse the GSC-enabled HuC binary Daniele Ceraolo Spurio
@ 2023-05-02 15:27 ` Daniele Ceraolo Spurio
2023-05-13 0:38 ` Teres Alexis, Alan Previn
2023-05-17 21:04 ` John Harrison
0 siblings, 2 replies; 32+ messages in thread
From: Daniele Ceraolo Spurio @ 2023-05-02 15:27 UTC (permalink / raw)
To: intel-gfx; +Cc: Alan Previn, dri-devel
The new binaries that support the 2-step authentication have contain the
legacy-style binary, which we can use for loading the HuC via DMA. To
find out where this is located in the image, we need to parse the meu
manifest of the GSC binary. The manifest consist of a partition header
followed by entries, one of which contains the offset we're looking for.
Note that the DG2 GSC binary contains entries with the same names, but
it doesn't contain a full legacy binary, so we need to skip assigning
the dma offset in that case (which we can do by checking the ccs).
Also, since we're now parsing the entries, we can extract the HuC
version that way instead of using hardcoded offsets.
Note that the meu structure will be re-used for parsing the GSC binary,
so they've been added in their own header.
v2: fix structure names to match meu defines (s/CPT/CPD/), update commit
message, check ccs validity, drop old version location defines.
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
---
| 74 ++++++++++
drivers/gpu/drm/i915/gt/uc/intel_huc.c | 11 +-
drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 135 ++++++++++++++++++
drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h | 5 +-
drivers/gpu/drm/i915/gt/uc/intel_huc_print.h | 21 +++
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 71 +++++----
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h | 2 +
drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h | 6 -
8 files changed, 272 insertions(+), 53 deletions(-)
create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_huc_print.h
--git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h b/drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
new file mode 100644
index 000000000000..d55a66202576
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef _INTEL_GSC_MEU_H_
+#define _INTEL_GSC_MEU_H_
+
+#include <linux/types.h>
+
+/* Code partition directory (CPD) structures */
+struct intel_gsc_cpd_header_v2 {
+ u32 header_marker;
+#define INTEL_GSC_CPD_HEADER_MARKER 0x44504324
+
+ u32 num_of_entries;
+ u8 header_version;
+ u8 entry_version;
+ u8 header_length; /* in bytes */
+ u8 flags;
+ u32 partition_name;
+ u32 crc32;
+} __packed;
+
+struct intel_gsc_cpd_entry {
+ u8 name[12];
+
+ /*
+ * Bits 0-24: offset from the beginning of the code partition
+ * Bit 25: huffman compressed
+ * Bits 26-31: reserved
+ */
+ u32 offset;
+#define INTEL_GSC_CPD_ENTRY_OFFSET_MASK GENMASK(24, 0)
+#define INTEL_GSC_CPD_ENTRY_HUFFMAN_COMP BIT(25)
+
+ /*
+ * Module/Item length, in bytes. For Huffman-compressed modules, this
+ * refers to the uncompressed size. For software-compressed modules,
+ * this refers to the compressed size.
+ */
+ u32 length;
+
+ u8 reserved[4];
+} __packed;
+
+struct intel_gsc_meu_version {
+ u16 major;
+ u16 minor;
+ u16 hotfix;
+ u16 build;
+} __packed;
+
+struct intel_gsc_manifest_header {
+ u32 header_type; /* 0x4 for manifest type */
+ u32 header_length; /* in dwords */
+ u32 header_version;
+ u32 flags;
+ u32 vendor;
+ u32 date;
+ u32 size; /* In dwords, size of entire manifest (header + extensions) */
+ u32 header_id;
+ u32 internal_data;
+ struct intel_gsc_meu_version fw_version;
+ u32 security_version;
+ struct intel_gsc_meu_version meu_kit_version;
+ u32 meu_manifest_version;
+ u8 general_data[4];
+ u8 reserved3[56];
+ u32 modulus_size; /* in dwords */
+ u32 exponent_size; /* in dwords */
+} __packed;
+
+#endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 9721761373fb..062ff914b274 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -6,23 +6,14 @@
#include <linux/types.h>
#include "gt/intel_gt.h"
-#include "gt/intel_gt_print.h"
#include "intel_guc_reg.h"
#include "intel_huc.h"
+#include "intel_huc_print.h"
#include "i915_drv.h"
#include <linux/device/bus.h>
#include <linux/mei_aux.h>
-#define huc_printk(_huc, _level, _fmt, ...) \
- gt_##_level(huc_to_gt(_huc), "HuC: " _fmt, ##__VA_ARGS__)
-#define huc_err(_huc, _fmt, ...) huc_printk((_huc), err, _fmt, ##__VA_ARGS__)
-#define huc_warn(_huc, _fmt, ...) huc_printk((_huc), warn, _fmt, ##__VA_ARGS__)
-#define huc_notice(_huc, _fmt, ...) huc_printk((_huc), notice, _fmt, ##__VA_ARGS__)
-#define huc_info(_huc, _fmt, ...) huc_printk((_huc), info, _fmt, ##__VA_ARGS__)
-#define huc_dbg(_huc, _fmt, ...) huc_printk((_huc), dbg, _fmt, ##__VA_ARGS__)
-#define huc_probe_error(_huc, _fmt, ...) huc_printk((_huc), probe_error, _fmt, ##__VA_ARGS__)
-
/**
* DOC: HuC
*
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
index 534b0aa43316..0ec48c2cd749 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
@@ -5,11 +5,146 @@
#include "gt/intel_gsc.h"
#include "gt/intel_gt.h"
+#include "intel_gsc_meu_headers.h"
#include "intel_huc.h"
#include "intel_huc_fw.h"
+#include "intel_huc_print.h"
#include "i915_drv.h"
#include "pxp/intel_pxp_huc.h"
+static void get_version_from_meu_manifest(struct intel_uc_fw_ver *ver, const void *data)
+{
+ const struct intel_gsc_manifest_header *manifest = data;
+
+ ver->major = manifest->fw_version.major;
+ ver->minor = manifest->fw_version.minor;
+ ver->patch = manifest->fw_version.hotfix;
+}
+
+static bool css_valid(const void *data, size_t size)
+{
+ const struct uc_css_header *css = data;
+
+ if (unlikely(size < sizeof(struct uc_css_header)))
+ return false;
+
+ if (css->module_type != 0x6)
+ return false;
+
+ if (css->module_vendor != PCI_VENDOR_ID_INTEL)
+ return false;
+
+ return true;
+}
+
+static inline u32 entry_offset(const struct intel_gsc_cpd_entry *entry)
+{
+ return entry->offset & INTEL_GSC_CPD_ENTRY_OFFSET_MASK;
+}
+
+int intel_huc_fw_get_binary_info(struct intel_uc_fw *huc_fw, const void *data, size_t size)
+{
+ struct intel_huc *huc = container_of(huc_fw, struct intel_huc, fw);
+ const struct intel_gsc_cpd_header_v2 *header = data;
+ const struct intel_gsc_cpd_entry *entry;
+ size_t min_size = sizeof(*header);
+ int i;
+
+ if (!huc_fw->loaded_via_gsc) {
+ huc_err(huc, "Invalid FW type MEU parsing!\n");
+ return -EINVAL;
+ }
+
+ if (size < sizeof(*header)) {
+ huc_err(huc, "MEU FW too small! %zu < %zu\n", size, min_size);
+ return -ENODATA;
+ }
+
+ /*
+ * The meu HuC binary starts with a directory header, followed by a
+ * series of entries. Each entry is identified by a name and points to
+ * a specific section of the binary containing the relevant data.
+ * The entries we're interested in are
+ * - "HUCP.man": points to the GSC manifest header for the HuC, which
+ * contains the version info.
+ * - "huc_fw": points to the legacy-style binary that can be used for
+ * load via the DMA. This entry only contains a valid CSS
+ * on binaries for platforms that support 2-step HuC load
+ * via dma and auth via GSC (like MTL).
+ *
+ * --------------------------------------------------
+ * [ intel_gsc_cpd_header_v2 ]
+ * --------------------------------------------------
+ * [ intel_gsc_cpd_entry[] ]
+ * [ entry1 ]
+ * [ ... ]
+ * [ entryX ]
+ * [ "HUCP.man" ]
+ * [ ... ]
+ * [ offset >----------------------------]------o
+ * [ ... ] |
+ * [ entryY ] |
+ * [ "huc_fw" ] |
+ * [ ... ] |
+ * [ offset >----------------------------]----------o
+ * -------------------------------------------------- | |
+ * | |
+ * -------------------------------------------------- | |
+ * [ intel_gsc_manifest_header ]<-----o |
+ * [ ... ] |
+ * [ intel_gsc_meu_version fw_version ] |
+ * [ ... ] |
+ * -------------------------------------------------- |
+ * |
+ * -------------------------------------------------- |
+ * [ data[] ]<---------o
+ * [ ... ]
+ * [ ... ]
+ * --------------------------------------------------
+ */
+
+ if (header->header_marker != INTEL_GSC_CPD_HEADER_MARKER) {
+ huc_err(huc, "invalid marker for meu CPD header: 0x%08x!\n",
+ header->header_marker);
+ return -EINVAL;
+ }
+
+ /* we only have binaries with header v2 and entry v1 for now */
+ if (header->header_version != 2 || header->entry_version != 1) {
+ huc_err(huc, "invalid meu CPD header/entry version %u:%u!\n",
+ header->header_version, header->entry_version);
+ return -EINVAL;
+ }
+
+ if (header->header_length < sizeof(struct intel_gsc_cpd_header_v2)) {
+ huc_err(huc, "invalid meu CPD header length %u!\n",
+ header->header_length);
+ return -EINVAL;
+ }
+
+ min_size = header->header_length + sizeof(*entry) * header->num_of_entries;
+ if (size < min_size) {
+ huc_err(huc, "MEU FW too small! %zu < %zu\n", size, min_size);
+ return -ENODATA;
+ }
+
+ entry = data + header->header_length;
+
+ for (i = 0; i < header->num_of_entries; i++, entry++) {
+ if (strcmp(entry->name, "HUCP.man") == 0)
+ get_version_from_meu_manifest(&huc_fw->file_selected.ver,
+ data + entry_offset(entry));
+
+ if (strcmp(entry->name, "huc_fw") == 0) {
+ u32 offset = entry_offset(entry);
+ if (offset < size && css_valid(data + offset, size - offset))
+ huc_fw->dma_start_offset = offset;
+ }
+ }
+
+ return 0;
+}
+
int intel_huc_fw_load_and_auth_via_gsc(struct intel_huc *huc)
{
int ret;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
index db42e238b45f..0999ffe6f962 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
@@ -7,8 +7,11 @@
#define _INTEL_HUC_FW_H_
struct intel_huc;
+struct intel_uc_fw;
+
+#include <linux/types.h>
int intel_huc_fw_load_and_auth_via_gsc(struct intel_huc *huc);
int intel_huc_fw_upload(struct intel_huc *huc);
-
+int intel_huc_fw_get_binary_info(struct intel_uc_fw *huc_fw, const void *data, size_t size);
#endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_print.h b/drivers/gpu/drm/i915/gt/uc/intel_huc_print.h
new file mode 100644
index 000000000000..915d310ee1df
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_print.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef __INTEL_HUC_PRINT__
+#define __INTEL_HUC_PRINT__
+
+#include "gt/intel_gt.h"
+#include "gt/intel_gt_print.h"
+
+#define huc_printk(_huc, _level, _fmt, ...) \
+ gt_##_level(huc_to_gt(_huc), "HuC: " _fmt, ##__VA_ARGS__)
+#define huc_err(_huc, _fmt, ...) huc_printk((_huc), err, _fmt, ##__VA_ARGS__)
+#define huc_warn(_huc, _fmt, ...) huc_printk((_huc), warn, _fmt, ##__VA_ARGS__)
+#define huc_notice(_huc, _fmt, ...) huc_printk((_huc), notice, _fmt, ##__VA_ARGS__)
+#define huc_info(_huc, _fmt, ...) huc_printk((_huc), info, _fmt, ##__VA_ARGS__)
+#define huc_dbg(_huc, _fmt, ...) huc_printk((_huc), dbg, _fmt, ##__VA_ARGS__)
+#define huc_probe_error(_huc, _fmt, ...) huc_printk((_huc), probe_error, _fmt, ##__VA_ARGS__)
+
+#endif /* __INTEL_HUC_PRINT__ */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index 03f0b258aea7..da6fcfe1d80a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -492,33 +492,6 @@ static void __force_fw_fetch_failures(struct intel_uc_fw *uc_fw, int e)
}
}
-static int check_gsc_manifest(struct intel_gt *gt,
- const struct firmware *fw,
- struct intel_uc_fw *uc_fw)
-{
- u32 *dw = (u32 *)fw->data;
- u32 version_hi, version_lo;
- size_t min_size;
-
- /* Check the size of the blob before examining buffer contents */
- min_size = sizeof(u32) * (HUC_GSC_VERSION_LO_DW + 1);
- if (unlikely(fw->size < min_size)) {
- gt_warn(gt, "%s firmware %s: invalid size: %zu < %zu\n",
- intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
- fw->size, min_size);
- return -ENODATA;
- }
-
- version_hi = dw[HUC_GSC_VERSION_HI_DW];
- version_lo = dw[HUC_GSC_VERSION_LO_DW];
-
- uc_fw->file_selected.ver.major = FIELD_GET(HUC_GSC_MAJOR_VER_HI_MASK, version_hi);
- uc_fw->file_selected.ver.minor = FIELD_GET(HUC_GSC_MINOR_VER_HI_MASK, version_hi);
- uc_fw->file_selected.ver.patch = FIELD_GET(HUC_GSC_PATCH_VER_LO_MASK, version_lo);
-
- return 0;
-}
-
static void uc_unpack_css_version(struct intel_uc_fw_ver *ver, u32 css_value)
{
/* Get version numbers from the CSS header */
@@ -575,22 +548,22 @@ static void guc_read_css_info(struct intel_uc_fw *uc_fw, struct uc_css_header *c
uc_fw->private_data_size = css->private_data_size;
}
-static int check_ccs_header(struct intel_gt *gt,
- const struct firmware *fw,
- struct intel_uc_fw *uc_fw)
+static int __check_ccs_header(struct intel_gt *gt,
+ const void *fw_data, size_t fw_size,
+ struct intel_uc_fw *uc_fw)
{
struct uc_css_header *css;
size_t size;
/* Check the size of the blob before examining buffer contents */
- if (unlikely(fw->size < sizeof(struct uc_css_header))) {
+ if (unlikely(fw_size < sizeof(struct uc_css_header))) {
gt_warn(gt, "%s firmware %s: invalid size: %zu < %zu\n",
intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
- fw->size, sizeof(struct uc_css_header));
+ fw_size, sizeof(struct uc_css_header));
return -ENODATA;
}
- css = (struct uc_css_header *)fw->data;
+ css = (struct uc_css_header *)fw_data;
/* Check integrity of size values inside CSS header */
size = (css->header_size_dw - css->key_size_dw - css->modulus_size_dw -
@@ -598,7 +571,7 @@ static int check_ccs_header(struct intel_gt *gt,
if (unlikely(size != sizeof(struct uc_css_header))) {
gt_warn(gt, "%s firmware %s: unexpected header size: %zu != %zu\n",
intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
- fw->size, sizeof(struct uc_css_header));
+ fw_size, sizeof(struct uc_css_header));
return -EPROTO;
}
@@ -610,10 +583,10 @@ static int check_ccs_header(struct intel_gt *gt,
/* At least, it should have header, uCode and RSA. Size of all three. */
size = sizeof(struct uc_css_header) + uc_fw->ucode_size + uc_fw->rsa_size;
- if (unlikely(fw->size < size)) {
+ if (unlikely(fw_size < size)) {
gt_warn(gt, "%s firmware %s: invalid size: %zu < %zu\n",
intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
- fw->size, size);
+ fw_size, size);
return -ENOEXEC;
}
@@ -634,6 +607,32 @@ static int check_ccs_header(struct intel_gt *gt,
return 0;
}
+static int check_gsc_manifest(struct intel_gt *gt,
+ const struct firmware *fw,
+ struct intel_uc_fw *uc_fw)
+{
+ if (uc_fw->type != INTEL_UC_FW_TYPE_HUC) {
+ gt_err(gt, "trying to MEU-parse a non-HuC binary");
+ return -EINVAL;
+ }
+
+ intel_huc_fw_get_binary_info(uc_fw, fw->data, fw->size);
+
+ if (uc_fw->dma_start_offset) {
+ u32 delta = uc_fw->dma_start_offset;
+ __check_ccs_header(gt, fw->data + delta, fw->size - delta, uc_fw);
+ }
+
+ return 0;
+}
+
+static int check_ccs_header(struct intel_gt *gt,
+ const struct firmware *fw,
+ struct intel_uc_fw *uc_fw)
+{
+ return __check_ccs_header(gt, fw->data, fw->size, uc_fw);
+}
+
static bool is_ver_8bit(struct intel_uc_fw_ver *ver)
{
return ver->major < 0xFF && ver->minor < 0xFF && ver->patch < 0xFF;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
index 26a9d6e0dc00..2691bb6bde48 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
@@ -113,6 +113,8 @@ struct intel_uc_fw {
u32 ucode_size;
u32 private_data_size;
+ u32 dma_start_offset;
+
bool loaded_via_gsc;
};
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h
index 646fa8aa6cf1..7fe405126249 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h
@@ -84,10 +84,4 @@ struct uc_css_header {
} __packed;
static_assert(sizeof(struct uc_css_header) == 128);
-#define HUC_GSC_VERSION_HI_DW 44
-#define HUC_GSC_MAJOR_VER_HI_MASK (0xFF << 0)
-#define HUC_GSC_MINOR_VER_HI_MASK (0xFF << 16)
-#define HUC_GSC_VERSION_LO_DW 45
-#define HUC_GSC_PATCH_VER_LO_MASK (0xFF << 0)
-
#endif /* _INTEL_UC_FW_ABI_H */
--
2.40.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: HuC loading and authentication for MTL (rev3)
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
` (10 preceding siblings ...)
2023-04-28 21:47 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
@ 2023-05-02 16:05 ` Patchwork
2023-05-02 16:05 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
` (5 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Patchwork @ 2023-05-02 16:05 UTC (permalink / raw)
To: Daniele Ceraolo Spurio; +Cc: intel-gfx
== Series Details ==
Series: drm/i915: HuC loading and authentication for MTL (rev3)
URL : https://patchwork.freedesktop.org/series/117080/
State : warning
== Summary ==
Error: dim checkpatch failed
d1701037c3e3 DO NOT REVIEW: drm/i915: Add support for MTL GSC SW Proxy
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
-:133: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#133:
new file mode 100644
-:138: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#138: FILE: drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c:1:
+#include "intel_gsc_proxy.h"
-:140: WARNING:SPDX_LICENSE_TAG: Misplaced SPDX-License-Identifier tag - use line 1 instead
#140: FILE: drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c:3:
+// SPDX-License-Identifier: MIT
-:278: WARNING:MEMORY_BARRIER: memory barrier without comment
#278: FILE: drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c:141:
+ wmb();
-:321: CHECK:BRACES: Blank lines aren't necessary before a close brace '}'
#321: FILE: drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c:184:
+
+}
total: 0 errors, 4 warnings, 1 checks, 988 lines checked
587ab7744732 drm/i915/uc: perma-pin firmwares
-:114: ERROR:SPACING: space prohibited before that close parenthesis ')'
#114: FILE: drivers/gpu/drm/i915/gt/uc/intel_uc.h:117:
+intel_uc_ops_function(resume_mappings, resume_mappings, void, );
total: 1 errors, 0 warnings, 0 checks, 196 lines checked
11b735119b33 drm/i915/huc: Parse the GSC-enabled HuC binary
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
-:27: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#27:
new file mode 100644
-:275: WARNING:LINE_SPACING: Missing a blank line after declarations
#275: FILE: drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c:140:
+ u32 offset = entry_offset(entry);
+ if (offset < size && css_valid(data + offset, size - offset))
-:436: WARNING:LINE_SPACING: Missing a blank line after declarations
#436: FILE: drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c:623:
+ u32 delta = uc_fw->dma_start_offset;
+ __check_ccs_header(gt, fw->data + delta, fw->size - delta, uc_fw);
total: 0 errors, 3 warnings, 0 checks, 408 lines checked
eb2472e51764 drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so
-:56: ERROR:SPACING: space required after that ',' (ctx:VxV)
#56: FILE: drivers/gpu/drm/i915/gt/uc/intel_huc.c:321:
+ huc_err(huc," HW in legacy mode, but we have an incompatible meu blob\n");
^
total: 1 errors, 0 warnings, 0 checks, 131 lines checked
dcffde8d400a drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow
-:49: WARNING:AVOID_BUG: Do not crash the kernel unless it is absolutely unavoidable--use WARN_ON_ONCE() plus recovery code (if feasible) instead of BUG() or variants
#49: FILE: drivers/gpu/drm/i915/gt/uc/intel_huc.c:128:
+ GEM_BUG_ON(intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC));
-:300: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'base' may be better as '(base)' to avoid precedence issues
#300: FILE: drivers/gpu/drm/i915/i915_reg.h:944:
+#define HECI_FWSTS5(base) _MMIO(base + 0xc68)
total: 0 errors, 1 warnings, 1 checks, 258 lines checked
6903ecf86175 drm/i915/mtl/huc: auth HuC via GSC
-:9: WARNING:TYPO_SPELLING: 'fuction' may be misspelled - perhaps 'function'?
#9:
The intel_huc_auth fuction is also updated to handle both authentication
^^^^^^^
-:83: WARNING:LINE_SPACING: Missing a blank line after declarations
#83: FILE: drivers/gpu/drm/i915/gt/uc/intel_huc.c:359:
+ struct i915_vma *vma = intel_guc_allocate_vma(>->uc.guc, SZ_8K);
+ if (IS_ERR(vma)) {
-:155: ERROR:SPACING: space required before the open parenthesis '('
#155: FILE: drivers/gpu/drm/i915/gt/uc/intel_huc.c:479:
+ switch(type) {
total: 1 errors, 2 warnings, 0 checks, 328 lines checked
5921ed057ef8 drm/i915/mtl/huc: Use the media gt for the HuC getparam
74b579e7f9b1 drm/i915/huc: define HuC FW version for MTL
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm/i915: HuC loading and authentication for MTL (rev3)
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
` (11 preceding siblings ...)
2023-05-02 16:05 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: HuC loading and authentication for MTL (rev3) Patchwork
@ 2023-05-02 16:05 ` Patchwork
2023-05-02 16:22 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
` (4 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Patchwork @ 2023-05-02 16:05 UTC (permalink / raw)
To: Daniele Ceraolo Spurio; +Cc: intel-gfx
== Series Details ==
Series: drm/i915: HuC loading and authentication for MTL (rev3)
URL : https://patchwork.freedesktop.org/series/117080/
State : warning
== Summary ==
Error: dim sparse failed
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Intel-gfx] ✗ Fi.CI.BAT: failure for drm/i915: HuC loading and authentication for MTL (rev3)
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
` (12 preceding siblings ...)
2023-05-02 16:05 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
@ 2023-05-02 16:22 ` Patchwork
2023-05-03 10:17 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: HuC loading and authentication for MTL (rev4) Patchwork
` (3 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Patchwork @ 2023-05-02 16:22 UTC (permalink / raw)
To: Daniele Ceraolo Spurio; +Cc: intel-gfx
[-- Attachment #1: Type: text/plain, Size: 7752 bytes --]
== Series Details ==
Series: drm/i915: HuC loading and authentication for MTL (rev3)
URL : https://patchwork.freedesktop.org/series/117080/
State : failure
== Summary ==
CI Bug Log - changes from CI_DRM_13097 -> Patchwork_117080v3
====================================================
Summary
-------
**FAILURE**
Serious unknown changes coming with Patchwork_117080v3 absolutely need to be
verified manually.
If you think the reported changes have nothing to do with the changes
introduced in Patchwork_117080v3, please notify your bug team to allow them
to document this new failure mode, which will reduce false positives in CI.
External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v3/index.html
Participating hosts (38 -> 38)
------------------------------
Additional (1): fi-kbl-soraka
Missing (1): fi-snb-2520m
Possible new issues
-------------------
Here are the unknown changes that may have been introduced in Patchwork_117080v3:
### IGT changes ###
#### Possible regressions ####
* igt@dmabuf@all-tests@dma_fence:
- fi-bsw-n3050: [PASS][1] -> [ABORT][2]
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13097/fi-bsw-n3050/igt@dmabuf@all-tests@dma_fence.html
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v3/fi-bsw-n3050/igt@dmabuf@all-tests@dma_fence.html
* igt@dmabuf@all-tests@dma_fence_chain:
- fi-bsw-n3050: [PASS][3] -> [INCOMPLETE][4]
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13097/fi-bsw-n3050/igt@dmabuf@all-tests@dma_fence_chain.html
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v3/fi-bsw-n3050/igt@dmabuf@all-tests@dma_fence_chain.html
Known issues
------------
Here are the changes found in Patchwork_117080v3 that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@gem_huc_copy@huc-copy:
- fi-kbl-soraka: NOTRUN -> [SKIP][5] ([fdo#109271] / [i915#2190])
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v3/fi-kbl-soraka/igt@gem_huc_copy@huc-copy.html
* igt@gem_lmem_swapping@basic:
- fi-kbl-soraka: NOTRUN -> [SKIP][6] ([fdo#109271] / [i915#4613]) +3 similar issues
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v3/fi-kbl-soraka/igt@gem_lmem_swapping@basic.html
* igt@i915_selftest@live@gt_pm:
- fi-kbl-soraka: NOTRUN -> [DMESG-FAIL][7] ([i915#1886] / [i915#7913])
[7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v3/fi-kbl-soraka/igt@i915_selftest@live@gt_pm.html
* igt@i915_selftest@live@hangcheck:
- bat-adlm-1: [PASS][8] -> [INCOMPLETE][9] ([i915#4983] / [i915#7677])
[8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13097/bat-adlm-1/igt@i915_selftest@live@hangcheck.html
[9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v3/bat-adlm-1/igt@i915_selftest@live@hangcheck.html
* igt@i915_selftest@live@reset:
- bat-rpls-1: [PASS][10] -> [ABORT][11] ([i915#4983] / [i915#7461] / [i915#8347] / [i915#8384])
[10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13097/bat-rpls-1/igt@i915_selftest@live@reset.html
[11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v3/bat-rpls-1/igt@i915_selftest@live@reset.html
* igt@kms_chamelium_frames@hdmi-crc-fast:
- fi-kbl-soraka: NOTRUN -> [SKIP][12] ([fdo#109271]) +16 similar issues
[12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v3/fi-kbl-soraka/igt@kms_chamelium_frames@hdmi-crc-fast.html
#### Possible fixes ####
* igt@gem_exec_parallel@engines@fds:
- {bat-mtlp-8}: [ABORT][13] -> [PASS][14]
[13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13097/bat-mtlp-8/igt@gem_exec_parallel@engines@fds.html
[14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v3/bat-mtlp-8/igt@gem_exec_parallel@engines@fds.html
* igt@gem_huc_copy@huc-copy:
- {bat-mtlp-6}: [SKIP][15] ([i915#3595]) -> [PASS][16]
[15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13097/bat-mtlp-6/igt@gem_huc_copy@huc-copy.html
[16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v3/bat-mtlp-6/igt@gem_huc_copy@huc-copy.html
* igt@kms_pipe_crc_basic@nonblocking-crc@pipe-d-dp-1:
- bat-dg2-8: [FAIL][17] ([i915#7932]) -> [PASS][18]
[17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13097/bat-dg2-8/igt@kms_pipe_crc_basic@nonblocking-crc@pipe-d-dp-1.html
[18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v3/bat-dg2-8/igt@kms_pipe_crc_basic@nonblocking-crc@pipe-d-dp-1.html
{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).
[fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
[fdo#109285]: https://bugs.freedesktop.org/show_bug.cgi?id=109285
[i915#1886]: https://gitlab.freedesktop.org/drm/intel/issues/1886
[i915#2190]: https://gitlab.freedesktop.org/drm/intel/issues/2190
[i915#3595]: https://gitlab.freedesktop.org/drm/intel/issues/3595
[i915#3708]: https://gitlab.freedesktop.org/drm/intel/issues/3708
[i915#4077]: https://gitlab.freedesktop.org/drm/intel/issues/4077
[i915#4079]: https://gitlab.freedesktop.org/drm/intel/issues/4079
[i915#4083]: https://gitlab.freedesktop.org/drm/intel/issues/4083
[i915#4212]: https://gitlab.freedesktop.org/drm/intel/issues/4212
[i915#4213]: https://gitlab.freedesktop.org/drm/intel/issues/4213
[i915#4579]: https://gitlab.freedesktop.org/drm/intel/issues/4579
[i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
[i915#4983]: https://gitlab.freedesktop.org/drm/intel/issues/4983
[i915#5190]: https://gitlab.freedesktop.org/drm/intel/issues/5190
[i915#5274]: https://gitlab.freedesktop.org/drm/intel/issues/5274
[i915#6367]: https://gitlab.freedesktop.org/drm/intel/issues/6367
[i915#6621]: https://gitlab.freedesktop.org/drm/intel/issues/6621
[i915#6645]: https://gitlab.freedesktop.org/drm/intel/issues/6645
[i915#7461]: https://gitlab.freedesktop.org/drm/intel/issues/7461
[i915#7677]: https://gitlab.freedesktop.org/drm/intel/issues/7677
[i915#7699]: https://gitlab.freedesktop.org/drm/intel/issues/7699
[i915#7828]: https://gitlab.freedesktop.org/drm/intel/issues/7828
[i915#7913]: https://gitlab.freedesktop.org/drm/intel/issues/7913
[i915#7932]: https://gitlab.freedesktop.org/drm/intel/issues/7932
[i915#8347]: https://gitlab.freedesktop.org/drm/intel/issues/8347
[i915#8368]: https://gitlab.freedesktop.org/drm/intel/issues/8368
[i915#8379]: https://gitlab.freedesktop.org/drm/intel/issues/8379
[i915#8384]: https://gitlab.freedesktop.org/drm/intel/issues/8384
Build changes
-------------
* Linux: CI_DRM_13097 -> Patchwork_117080v3
CI-20190529: 20190529
CI_DRM_13097: 1413856e3770380da743e274a06896acabf49e0e @ git://anongit.freedesktop.org/gfx-ci/linux
IGT_7277: 1cb3507f3ff28d11bd5cfabcde576fe78ddab571 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
Patchwork_117080v3: 1413856e3770380da743e274a06896acabf49e0e @ git://anongit.freedesktop.org/gfx-ci/linux
### Linux commits
405c4d5de437 drm/i915/huc: define HuC FW version for MTL
9c655cfc0428 drm/i915/mtl/huc: Use the media gt for the HuC getparam
ef9470a8cf6c drm/i915/mtl/huc: auth HuC via GSC
99315240fd8d drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow
399d4f5e9b09 drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so
ae0cac1d8331 drm/i915/huc: Parse the GSC-enabled HuC binary
d4b70b0338f6 drm/i915/uc: perma-pin firmwares
78b9486ccfa5 DO NOT REVIEW: drm/i915: Add support for MTL GSC SW Proxy
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v3/index.html
[-- Attachment #2: Type: text/html, Size: 7739 bytes --]
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: HuC loading and authentication for MTL (rev4)
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
` (13 preceding siblings ...)
2023-05-02 16:22 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
@ 2023-05-03 10:17 ` Patchwork
2023-05-03 10:18 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
` (2 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Patchwork @ 2023-05-03 10:17 UTC (permalink / raw)
To: Daniele Ceraolo Spurio; +Cc: intel-gfx
== Series Details ==
Series: drm/i915: HuC loading and authentication for MTL (rev4)
URL : https://patchwork.freedesktop.org/series/117080/
State : warning
== Summary ==
Error: dim checkpatch failed
bd26d999612e DO NOT REVIEW: drm/i915: Add support for MTL GSC SW Proxy
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
-:133: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#133:
new file mode 100644
-:138: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#138: FILE: drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c:1:
+#include "intel_gsc_proxy.h"
-:140: WARNING:SPDX_LICENSE_TAG: Misplaced SPDX-License-Identifier tag - use line 1 instead
#140: FILE: drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c:3:
+// SPDX-License-Identifier: MIT
-:278: WARNING:MEMORY_BARRIER: memory barrier without comment
#278: FILE: drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c:141:
+ wmb();
-:321: CHECK:BRACES: Blank lines aren't necessary before a close brace '}'
#321: FILE: drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c:184:
+
+}
total: 0 errors, 4 warnings, 1 checks, 988 lines checked
a8719d2dc876 drm/i915/uc: perma-pin firmwares
-:114: ERROR:SPACING: space prohibited before that close parenthesis ')'
#114: FILE: drivers/gpu/drm/i915/gt/uc/intel_uc.h:117:
+intel_uc_ops_function(resume_mappings, resume_mappings, void, );
total: 1 errors, 0 warnings, 0 checks, 196 lines checked
6569ab2a4c5e drm/i915/huc: Parse the GSC-enabled HuC binary
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
File "scripts/spdxcheck.py", line 6, in <module>
from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
-:27: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#27:
new file mode 100644
-:275: WARNING:LINE_SPACING: Missing a blank line after declarations
#275: FILE: drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c:140:
+ u32 offset = entry_offset(entry);
+ if (offset < size && css_valid(data + offset, size - offset))
-:436: WARNING:LINE_SPACING: Missing a blank line after declarations
#436: FILE: drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c:623:
+ u32 delta = uc_fw->dma_start_offset;
+ __check_ccs_header(gt, fw->data + delta, fw->size - delta, uc_fw);
total: 0 errors, 3 warnings, 0 checks, 408 lines checked
70aef6f86329 drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so
-:56: ERROR:SPACING: space required after that ',' (ctx:VxV)
#56: FILE: drivers/gpu/drm/i915/gt/uc/intel_huc.c:321:
+ huc_err(huc," HW in legacy mode, but we have an incompatible meu blob\n");
^
total: 1 errors, 0 warnings, 0 checks, 131 lines checked
9a77681e67a6 drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow
-:49: WARNING:AVOID_BUG: Do not crash the kernel unless it is absolutely unavoidable--use WARN_ON_ONCE() plus recovery code (if feasible) instead of BUG() or variants
#49: FILE: drivers/gpu/drm/i915/gt/uc/intel_huc.c:128:
+ GEM_BUG_ON(intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC));
-:300: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'base' may be better as '(base)' to avoid precedence issues
#300: FILE: drivers/gpu/drm/i915/i915_reg.h:944:
+#define HECI_FWSTS5(base) _MMIO(base + 0xc68)
total: 0 errors, 1 warnings, 1 checks, 258 lines checked
9b6bdfab6a67 drm/i915/mtl/huc: auth HuC via GSC
-:9: WARNING:TYPO_SPELLING: 'fuction' may be misspelled - perhaps 'function'?
#9:
The intel_huc_auth fuction is also updated to handle both authentication
^^^^^^^
-:83: WARNING:LINE_SPACING: Missing a blank line after declarations
#83: FILE: drivers/gpu/drm/i915/gt/uc/intel_huc.c:359:
+ struct i915_vma *vma = intel_guc_allocate_vma(>->uc.guc, SZ_8K);
+ if (IS_ERR(vma)) {
-:155: ERROR:SPACING: space required before the open parenthesis '('
#155: FILE: drivers/gpu/drm/i915/gt/uc/intel_huc.c:479:
+ switch(type) {
total: 1 errors, 2 warnings, 0 checks, 328 lines checked
106401a13c20 drm/i915/mtl/huc: Use the media gt for the HuC getparam
ada550bf57db drm/i915/huc: define HuC FW version for MTL
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm/i915: HuC loading and authentication for MTL (rev4)
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
` (14 preceding siblings ...)
2023-05-03 10:17 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: HuC loading and authentication for MTL (rev4) Patchwork
@ 2023-05-03 10:18 ` Patchwork
2023-05-03 10:30 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2023-05-03 13:10 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
17 siblings, 0 replies; 32+ messages in thread
From: Patchwork @ 2023-05-03 10:18 UTC (permalink / raw)
To: Daniele Ceraolo Spurio; +Cc: intel-gfx
== Series Details ==
Series: drm/i915: HuC loading and authentication for MTL (rev4)
URL : https://patchwork.freedesktop.org/series/117080/
State : warning
== Summary ==
Error: dim sparse failed
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915: HuC loading and authentication for MTL (rev4)
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
` (15 preceding siblings ...)
2023-05-03 10:18 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
@ 2023-05-03 10:30 ` Patchwork
2023-05-03 13:10 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
17 siblings, 0 replies; 32+ messages in thread
From: Patchwork @ 2023-05-03 10:30 UTC (permalink / raw)
To: Daniele Ceraolo Spurio; +Cc: intel-gfx
[-- Attachment #1: Type: text/plain, Size: 6524 bytes --]
== Series Details ==
Series: drm/i915: HuC loading and authentication for MTL (rev4)
URL : https://patchwork.freedesktop.org/series/117080/
State : success
== Summary ==
CI Bug Log - changes from CI_DRM_13102 -> Patchwork_117080v4
====================================================
Summary
-------
**SUCCESS**
No regressions found.
External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/index.html
Participating hosts (38 -> 38)
------------------------------
Additional (1): fi-kbl-soraka
Missing (1): fi-snb-2520m
Known issues
------------
Here are the changes found in Patchwork_117080v4 that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@gem_exec_suspend@basic-s3@smem:
- bat-rpls-1: [PASS][1] -> [ABORT][2] ([i915#6687] / [i915#7978] / [i915#8407])
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/bat-rpls-1/igt@gem_exec_suspend@basic-s3@smem.html
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/bat-rpls-1/igt@gem_exec_suspend@basic-s3@smem.html
* igt@gem_huc_copy@huc-copy:
- fi-kbl-soraka: NOTRUN -> [SKIP][3] ([fdo#109271] / [i915#2190])
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/fi-kbl-soraka/igt@gem_huc_copy@huc-copy.html
* igt@gem_lmem_swapping@basic:
- fi-kbl-soraka: NOTRUN -> [SKIP][4] ([fdo#109271] / [i915#4613]) +3 similar issues
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/fi-kbl-soraka/igt@gem_lmem_swapping@basic.html
* igt@i915_selftest@live@gt_heartbeat:
- fi-kbl-soraka: NOTRUN -> [DMESG-FAIL][5] ([i915#5334] / [i915#7872])
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/fi-kbl-soraka/igt@i915_selftest@live@gt_heartbeat.html
* igt@i915_selftest@live@gt_pm:
- fi-kbl-soraka: NOTRUN -> [DMESG-FAIL][6] ([i915#1886] / [i915#7913])
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/fi-kbl-soraka/igt@i915_selftest@live@gt_pm.html
* igt@kms_chamelium_frames@hdmi-crc-fast:
- fi-kbl-soraka: NOTRUN -> [SKIP][7] ([fdo#109271]) +16 similar issues
[7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/fi-kbl-soraka/igt@kms_chamelium_frames@hdmi-crc-fast.html
#### Possible fixes ####
* igt@gem_huc_copy@huc-copy:
- {bat-mtlp-6}: [SKIP][8] ([i915#3595]) -> [PASS][9]
[8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/bat-mtlp-6/igt@gem_huc_copy@huc-copy.html
[9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/bat-mtlp-6/igt@gem_huc_copy@huc-copy.html
- {bat-mtlp-8}: [SKIP][10] ([i915#3595]) -> [PASS][11]
[10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/bat-mtlp-8/igt@gem_huc_copy@huc-copy.html
[11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/bat-mtlp-8/igt@gem_huc_copy@huc-copy.html
* igt@i915_selftest@live@migrate:
- bat-dg2-11: [DMESG-WARN][12] ([i915#7699]) -> [PASS][13]
[12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/bat-dg2-11/igt@i915_selftest@live@migrate.html
[13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/bat-dg2-11/igt@i915_selftest@live@migrate.html
* igt@i915_selftest@live@requests:
- {bat-mtlp-6}: [ABORT][14] ([i915#4983] / [i915#7920]) -> [PASS][15]
[14]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/bat-mtlp-6/igt@i915_selftest@live@requests.html
[15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/bat-mtlp-6/igt@i915_selftest@live@requests.html
* igt@kms_pipe_crc_basic@nonblocking-crc@pipe-d-dp-1:
- bat-dg2-8: [FAIL][16] ([i915#7932]) -> [PASS][17]
[16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/bat-dg2-8/igt@kms_pipe_crc_basic@nonblocking-crc@pipe-d-dp-1.html
[17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/bat-dg2-8/igt@kms_pipe_crc_basic@nonblocking-crc@pipe-d-dp-1.html
{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).
[fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
[i915#1845]: https://gitlab.freedesktop.org/drm/intel/issues/1845
[i915#1886]: https://gitlab.freedesktop.org/drm/intel/issues/1886
[i915#2190]: https://gitlab.freedesktop.org/drm/intel/issues/2190
[i915#3595]: https://gitlab.freedesktop.org/drm/intel/issues/3595
[i915#4078]: https://gitlab.freedesktop.org/drm/intel/issues/4078
[i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
[i915#4983]: https://gitlab.freedesktop.org/drm/intel/issues/4983
[i915#5334]: https://gitlab.freedesktop.org/drm/intel/issues/5334
[i915#6367]: https://gitlab.freedesktop.org/drm/intel/issues/6367
[i915#6645]: https://gitlab.freedesktop.org/drm/intel/issues/6645
[i915#6687]: https://gitlab.freedesktop.org/drm/intel/issues/6687
[i915#7699]: https://gitlab.freedesktop.org/drm/intel/issues/7699
[i915#7828]: https://gitlab.freedesktop.org/drm/intel/issues/7828
[i915#7872]: https://gitlab.freedesktop.org/drm/intel/issues/7872
[i915#7913]: https://gitlab.freedesktop.org/drm/intel/issues/7913
[i915#7920]: https://gitlab.freedesktop.org/drm/intel/issues/7920
[i915#7932]: https://gitlab.freedesktop.org/drm/intel/issues/7932
[i915#7978]: https://gitlab.freedesktop.org/drm/intel/issues/7978
[i915#8407]: https://gitlab.freedesktop.org/drm/intel/issues/8407
Build changes
-------------
* Linux: CI_DRM_13102 -> Patchwork_117080v4
CI-20190529: 20190529
CI_DRM_13102: b0492ca8c1cec314da218999babaa016df4cf9d1 @ git://anongit.freedesktop.org/gfx-ci/linux
IGT_7277: 1cb3507f3ff28d11bd5cfabcde576fe78ddab571 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
Patchwork_117080v4: b0492ca8c1cec314da218999babaa016df4cf9d1 @ git://anongit.freedesktop.org/gfx-ci/linux
### Linux commits
f442ed6a6e38 drm/i915/huc: define HuC FW version for MTL
c521fa5a2fcc drm/i915/mtl/huc: Use the media gt for the HuC getparam
70abd1d4dbcc drm/i915/mtl/huc: auth HuC via GSC
31667f562884 drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow
ab67f1c82df5 drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so
4b93205802da drm/i915/huc: Parse the GSC-enabled HuC binary
bdb3dd0e7617 drm/i915/uc: perma-pin firmwares
e94b83ac1e89 DO NOT REVIEW: drm/i915: Add support for MTL GSC SW Proxy
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/index.html
[-- Attachment #2: Type: text/html, Size: 7295 bytes --]
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Intel-gfx] ✓ Fi.CI.IGT: success for drm/i915: HuC loading and authentication for MTL (rev4)
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
` (16 preceding siblings ...)
2023-05-03 10:30 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
@ 2023-05-03 13:10 ` Patchwork
17 siblings, 0 replies; 32+ messages in thread
From: Patchwork @ 2023-05-03 13:10 UTC (permalink / raw)
To: Daniele Ceraolo Spurio; +Cc: intel-gfx
[-- Attachment #1: Type: text/plain, Size: 12577 bytes --]
== Series Details ==
Series: drm/i915: HuC loading and authentication for MTL (rev4)
URL : https://patchwork.freedesktop.org/series/117080/
State : success
== Summary ==
CI Bug Log - changes from CI_DRM_13102_full -> Patchwork_117080v4_full
====================================================
Summary
-------
**SUCCESS**
No regressions found.
Participating hosts (7 -> 8)
------------------------------
Additional (1): shard-rkl0
Known issues
------------
Here are the changes found in Patchwork_117080v4_full that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@gem_barrier_race@remote-request@rcs0:
- shard-apl: [PASS][1] -> [ABORT][2] ([i915#7461] / [i915#8211] / [i915#8234])
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/shard-apl6/igt@gem_barrier_race@remote-request@rcs0.html
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-apl7/igt@gem_barrier_race@remote-request@rcs0.html
* igt@gem_eio@reset-stress:
- shard-snb: [PASS][3] -> [TIMEOUT][4] ([i915#3063])
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/shard-snb5/igt@gem_eio@reset-stress.html
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-snb5/igt@gem_eio@reset-stress.html
* igt@gem_exec_fair@basic-pace-share@rcs0:
- shard-glk: [PASS][5] -> [FAIL][6] ([i915#2842])
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/shard-glk6/igt@gem_exec_fair@basic-pace-share@rcs0.html
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-glk5/igt@gem_exec_fair@basic-pace-share@rcs0.html
* igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size:
- shard-glk: [PASS][7] -> [FAIL][8] ([i915#2346])
[7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/shard-glk5/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
[8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-glk2/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
* igt@kms_flip@flip-vs-expired-vblank@c-hdmi-a1:
- shard-glk: [PASS][9] -> [FAIL][10] ([i915#2122])
[9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/shard-glk4/igt@kms_flip@flip-vs-expired-vblank@c-hdmi-a1.html
[10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-glk8/igt@kms_flip@flip-vs-expired-vblank@c-hdmi-a1.html
* igt@kms_flip@flip-vs-suspend@a-dp1:
- shard-apl: [PASS][11] -> [ABORT][12] ([i915#180])
[11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/shard-apl2/igt@kms_flip@flip-vs-suspend@a-dp1.html
[12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-apl4/igt@kms_flip@flip-vs-suspend@a-dp1.html
* igt@kms_plane_scaling@plane-upscale-with-modifiers-20x20@pipe-b-vga-1:
- shard-snb: NOTRUN -> [SKIP][13] ([fdo#109271]) +26 similar issues
[13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-snb2/igt@kms_plane_scaling@plane-upscale-with-modifiers-20x20@pipe-b-vga-1.html
#### Possible fixes ####
* igt@drm_fdinfo@most-busy-idle-check-all@rcs0:
- {shard-rkl}: [FAIL][14] ([i915#7742]) -> [PASS][15]
[14]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/shard-rkl-3/igt@drm_fdinfo@most-busy-idle-check-all@rcs0.html
[15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-rkl-3/igt@drm_fdinfo@most-busy-idle-check-all@rcs0.html
* igt@gem_barrier_race@remote-request@rcs0:
- {shard-rkl}: [ABORT][16] ([i915#7461] / [i915#8211]) -> [PASS][17]
[16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/shard-rkl-3/igt@gem_barrier_race@remote-request@rcs0.html
[17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-rkl-2/igt@gem_barrier_race@remote-request@rcs0.html
* igt@gem_eio@hibernate:
- {shard-tglu}: [ABORT][18] ([i915#7975] / [i915#8213] / [i915#8398]) -> [PASS][19]
[18]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/shard-tglu-10/igt@gem_eio@hibernate.html
[19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-tglu-3/igt@gem_eio@hibernate.html
* igt@gem_eio@reset-stress:
- {shard-dg1}: [FAIL][20] ([i915#5784]) -> [PASS][21]
[20]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/shard-dg1-17/igt@gem_eio@reset-stress.html
[21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-dg1-17/igt@gem_eio@reset-stress.html
* igt@gem_exec_fair@basic-none-share@rcs0:
- shard-glk: [FAIL][22] ([i915#2842]) -> [PASS][23]
[22]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/shard-glk6/igt@gem_exec_fair@basic-none-share@rcs0.html
[23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-glk5/igt@gem_exec_fair@basic-none-share@rcs0.html
* igt@gem_exec_fair@basic-pace@rcs0:
- {shard-rkl}: [FAIL][24] ([i915#2842]) -> [PASS][25]
[24]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/shard-rkl-7/igt@gem_exec_fair@basic-pace@rcs0.html
[25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-rkl-7/igt@gem_exec_fair@basic-pace@rcs0.html
* igt@i915_pm_rpm@modeset-non-lpsp-stress:
- {shard-rkl}: [SKIP][26] ([i915#1397]) -> [PASS][27] +1 similar issue
[26]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/shard-rkl-7/igt@i915_pm_rpm@modeset-non-lpsp-stress.html
[27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-rkl-1/igt@i915_pm_rpm@modeset-non-lpsp-stress.html
* igt@i915_selftest@live@gt_heartbeat:
- shard-glk: [DMESG-FAIL][28] ([i915#5334]) -> [PASS][29]
[28]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/shard-glk7/igt@i915_selftest@live@gt_heartbeat.html
[29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-glk1/igt@i915_selftest@live@gt_heartbeat.html
* igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions:
- shard-glk: [FAIL][30] ([i915#2346]) -> [PASS][31]
[30]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/shard-glk4/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions.html
[31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-glk8/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions.html
* igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size:
- shard-apl: [FAIL][32] ([i915#2346]) -> [PASS][33]
[32]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/shard-apl7/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
[33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-apl6/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
* igt@kms_cursor_legacy@forked-bo@pipe-b:
- {shard-rkl}: [INCOMPLETE][34] ([i915#8011]) -> [PASS][35]
[34]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/shard-rkl-7/igt@kms_cursor_legacy@forked-bo@pipe-b.html
[35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-rkl-1/igt@kms_cursor_legacy@forked-bo@pipe-b.html
* igt@kms_flip@flip-vs-expired-vblank@b-hdmi-a1:
- shard-glk: [FAIL][36] ([i915#79]) -> [PASS][37]
[36]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13102/shard-glk4/igt@kms_flip@flip-vs-expired-vblank@b-hdmi-a1.html
[37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/shard-glk8/igt@kms_flip@flip-vs-expired-vblank@b-hdmi-a1.html
{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).
[fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
[fdo#109274]: https://bugs.freedesktop.org/show_bug.cgi?id=109274
[fdo#109280]: https://bugs.freedesktop.org/show_bug.cgi?id=109280
[fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
[fdo#109300]: https://bugs.freedesktop.org/show_bug.cgi?id=109300
[fdo#109315]: https://bugs.freedesktop.org/show_bug.cgi?id=109315
[fdo#110189]: https://bugs.freedesktop.org/show_bug.cgi?id=110189
[fdo#111615]: https://bugs.freedesktop.org/show_bug.cgi?id=111615
[fdo#111825]: https://bugs.freedesktop.org/show_bug.cgi?id=111825
[fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
[i915#1072]: https://gitlab.freedesktop.org/drm/intel/issues/1072
[i915#1397]: https://gitlab.freedesktop.org/drm/intel/issues/1397
[i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
[i915#1825]: https://gitlab.freedesktop.org/drm/intel/issues/1825
[i915#2122]: https://gitlab.freedesktop.org/drm/intel/issues/2122
[i915#2346]: https://gitlab.freedesktop.org/drm/intel/issues/2346
[i915#2575]: https://gitlab.freedesktop.org/drm/intel/issues/2575
[i915#2587]: https://gitlab.freedesktop.org/drm/intel/issues/2587
[i915#2672]: https://gitlab.freedesktop.org/drm/intel/issues/2672
[i915#2681]: https://gitlab.freedesktop.org/drm/intel/issues/2681
[i915#2705]: https://gitlab.freedesktop.org/drm/intel/issues/2705
[i915#280]: https://gitlab.freedesktop.org/drm/intel/issues/280
[i915#2842]: https://gitlab.freedesktop.org/drm/intel/issues/2842
[i915#3063]: https://gitlab.freedesktop.org/drm/intel/issues/3063
[i915#315]: https://gitlab.freedesktop.org/drm/intel/issues/315
[i915#3297]: https://gitlab.freedesktop.org/drm/intel/issues/3297
[i915#3458]: https://gitlab.freedesktop.org/drm/intel/issues/3458
[i915#3555]: https://gitlab.freedesktop.org/drm/intel/issues/3555
[i915#3591]: https://gitlab.freedesktop.org/drm/intel/issues/3591
[i915#3637]: https://gitlab.freedesktop.org/drm/intel/issues/3637
[i915#3689]: https://gitlab.freedesktop.org/drm/intel/issues/3689
[i915#3804]: https://gitlab.freedesktop.org/drm/intel/issues/3804
[i915#3989]: https://gitlab.freedesktop.org/drm/intel/issues/3989
[i915#4070]: https://gitlab.freedesktop.org/drm/intel/issues/4070
[i915#4078]: https://gitlab.freedesktop.org/drm/intel/issues/4078
[i915#4083]: https://gitlab.freedesktop.org/drm/intel/issues/4083
[i915#4270]: https://gitlab.freedesktop.org/drm/intel/issues/4270
[i915#454]: https://gitlab.freedesktop.org/drm/intel/issues/454
[i915#4579]: https://gitlab.freedesktop.org/drm/intel/issues/4579
[i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
[i915#4816]: https://gitlab.freedesktop.org/drm/intel/issues/4816
[i915#5235]: https://gitlab.freedesktop.org/drm/intel/issues/5235
[i915#5286]: https://gitlab.freedesktop.org/drm/intel/issues/5286
[i915#5334]: https://gitlab.freedesktop.org/drm/intel/issues/5334
[i915#5354]: https://gitlab.freedesktop.org/drm/intel/issues/5354
[i915#5784]: https://gitlab.freedesktop.org/drm/intel/issues/5784
[i915#6095]: https://gitlab.freedesktop.org/drm/intel/issues/6095
[i915#6433]: https://gitlab.freedesktop.org/drm/intel/issues/6433
[i915#6946]: https://gitlab.freedesktop.org/drm/intel/issues/6946
[i915#7116]: https://gitlab.freedesktop.org/drm/intel/issues/7116
[i915#7461]: https://gitlab.freedesktop.org/drm/intel/issues/7461
[i915#7711]: https://gitlab.freedesktop.org/drm/intel/issues/7711
[i915#7742]: https://gitlab.freedesktop.org/drm/intel/issues/7742
[i915#7828]: https://gitlab.freedesktop.org/drm/intel/issues/7828
[i915#79]: https://gitlab.freedesktop.org/drm/intel/issues/79
[i915#7975]: https://gitlab.freedesktop.org/drm/intel/issues/7975
[i915#8011]: https://gitlab.freedesktop.org/drm/intel/issues/8011
[i915#8211]: https://gitlab.freedesktop.org/drm/intel/issues/8211
[i915#8213]: https://gitlab.freedesktop.org/drm/intel/issues/8213
[i915#8234]: https://gitlab.freedesktop.org/drm/intel/issues/8234
[i915#8253]: https://gitlab.freedesktop.org/drm/intel/issues/8253
[i915#8292]: https://gitlab.freedesktop.org/drm/intel/issues/8292
[i915#8398]: https://gitlab.freedesktop.org/drm/intel/issues/8398
Build changes
-------------
* Linux: CI_DRM_13102 -> Patchwork_117080v4
CI-20190529: 20190529
CI_DRM_13102: b0492ca8c1cec314da218999babaa016df4cf9d1 @ git://anongit.freedesktop.org/gfx-ci/linux
IGT_7277: 1cb3507f3ff28d11bd5cfabcde576fe78ddab571 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
Patchwork_117080v4: b0492ca8c1cec314da218999babaa016df4cf9d1 @ git://anongit.freedesktop.org/gfx-ci/linux
piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v4/index.html
[-- Attachment #2: Type: text/html, Size: 10992 bytes --]
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Intel-gfx] [PATCH v2] drm/i915/huc: Parse the GSC-enabled HuC binary
2023-05-02 15:27 ` [Intel-gfx] [PATCH v2] " Daniele Ceraolo Spurio
@ 2023-05-13 0:38 ` Teres Alexis, Alan Previn
2023-05-17 21:04 ` John Harrison
1 sibling, 0 replies; 32+ messages in thread
From: Teres Alexis, Alan Previn @ 2023-05-13 0:38 UTC (permalink / raw)
To: Ceraolo Spurio, Daniele, intel-gfx@lists.freedesktop.org
Cc: dri-devel@lists.freedesktop.org
On Tue, 2023-05-02 at 08:27 -0700, Ceraolo Spurio, Daniele wrote:
> The new binaries that support the 2-step authentication have contain the
> legacy-style binary, which we can use for loading the HuC via DMA. To
> find out where this is located in the image, we need to parse the meu
> manifest of the GSC binary. The manifest consist of a partition header
> followed by entries, one of which contains the offset we're looking for.
> Note that the DG2 GSC binary contains entries with the same names, but
> it doesn't contain a full legacy binary, so we need to skip assigning
> the dma offset in that case (which we can do by checking the ccs).
> Also, since we're now parsing the entries, we can extract the HuC
> version that way instead of using hardcoded offsets.
>
> Note that the meu structure will be re-used for parsing the GSC binary,
> so they've been added in their own header.
>
> v2: fix structure names to match meu defines (s/CPT/CPD/), update commit
> message, check ccs validity, drop old version location defines.
>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
> ---
> .../drm/i915/gt/uc/intel_gsc_meu_headers.h | 74 ++++++++++
Compared line by line as per internal reviews and the spec.
All looks good to me - nice to see that additional ccs validity.
LGTM, Reviewed-by: Alan Previn <alan.previn.teres.alexis@intel.com>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Intel-gfx] [PATCH v2 5/8] drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 5/8] drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow Daniele Ceraolo Spurio
@ 2023-05-13 0:51 ` Teres Alexis, Alan Previn
2023-05-19 18:45 ` John Harrison
1 sibling, 0 replies; 32+ messages in thread
From: Teres Alexis, Alan Previn @ 2023-05-13 0:51 UTC (permalink / raw)
To: Ceraolo Spurio, Daniele, intel-gfx@lists.freedesktop.org
Cc: dri-devel@lists.freedesktop.org
On Fri, 2023-04-28 at 11:58 -0700, Ceraolo Spurio, Daniele wrote:
> Before we add the second step of the MTL HuC auth (via GSC), we need to
> have the ability to differentiate between them. To do so, the huc
> authentication check is duplicated for GuC and GSC auth, with meu
> binaries being considered fully authenticated only after the GSC auth
> step.
>
> To report the difference between the 2 auth steps, a new case is added
> to the HuC getparam. This way, the clear media driver can start
> submitting before full auth, as partial auth is enough for those
> workloads.
>
> v2: fix authentication status check for DG2
>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
> ---
> drivers/gpu/drm/i915/gt/uc/intel_huc.c | 94 +++++++++++++++++------
> drivers/gpu/drm/i915/gt/uc/intel_huc.h | 16 +++-
> drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 4 +-
> drivers/gpu/drm/i915/i915_reg.h | 3 +
> include/uapi/drm/i915_drm.h | 3 +-
> 5 files changed, 91 insertions(+), 29 deletions(-)
>
I believe you need a rebase with the PXP single session merged (the
readiness code in gsccs backend). Other than that, all looks good:
Reviewed-by: Alan Previn <alan.previn.teres.alexis@intel.com>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Intel-gfx] [PATCH v2 2/8] drm/i915/uc: perma-pin firmwares
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 2/8] drm/i915/uc: perma-pin firmwares Daniele Ceraolo Spurio
@ 2023-05-17 20:59 ` John Harrison
2023-05-17 21:12 ` Ceraolo Spurio, Daniele
0 siblings, 1 reply; 32+ messages in thread
From: John Harrison @ 2023-05-17 20:59 UTC (permalink / raw)
To: Daniele Ceraolo Spurio, intel-gfx; +Cc: dri-devel, Alan Previn
On 4/28/2023 11:58, Daniele Ceraolo Spurio wrote:
> Now that each FW has its own reserved area, we can keep them always
> pinned and skip the pin/unpin dance on reset. This will make things
> easier for the 2-step HuC authentication, which requires the FW to be
> pinned in GGTT after the xfer is completed.
> Given that we use dummy vmas for the pinning, we do need to explicitly
> re-pin on resume because the automated helper won't cover us.
>
> Signed-off-by: Daniele Ceraolo Spurio<daniele.ceraolospurio@intel.com>
> Cc: Alan Previn<alan.previn.teres.alexis@intel.com>
> ---
> drivers/gpu/drm/i915/gt/intel_ggtt.c | 3 ++
> drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 7 ++++-
> drivers/gpu/drm/i915/gt/uc/intel_guc.c | 2 +-
> drivers/gpu/drm/i915/gt/uc/intel_huc.c | 2 +-
> drivers/gpu/drm/i915/gt/uc/intel_uc.c | 8 +++++
> drivers/gpu/drm/i915/gt/uc/intel_uc.h | 2 ++
> drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 36 ++++++++++++++++++-----
> drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h | 5 +++-
> 8 files changed, 53 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
> index 20915edc8bd9..ab71ed11de79 100644
> --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
> +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
> @@ -1322,6 +1322,9 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
> ggtt->vm.scratch_range(&ggtt->vm, ggtt->error_capture.start,
> ggtt->error_capture.size);
>
> + list_for_each_entry(gt, &ggtt->gt_list, ggtt_link)
> + intel_uc_resume_mappings(>->uc);
> +
> ggtt->invalidate(ggtt);
>
> if (flush)
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
> index 64bff01026e8..af542e3cb3e9 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
> @@ -80,7 +80,12 @@ void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc)
> {
> struct intel_gt *gt = gsc_uc_to_gt(gsc);
>
> - intel_uc_fw_init_early(&gsc->fw, INTEL_UC_FW_TYPE_GSC);
> + /*
> + * GSC FW needs to be copied to a dedicated memory allocations for
> + * loading (see gsc->local), so we don't need to GGTT map the FW image
> + * itself into GGTT.
> + */
> + intel_uc_fw_init_early(&gsc->fw, INTEL_UC_FW_TYPE_GSC, false);
> INIT_WORK(&gsc->work, gsc_work);
>
> /* we can arrive here from i915_driver_early_probe for primary
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> index c9f20385f6a0..2eb891b270ae 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> @@ -164,7 +164,7 @@ void intel_guc_init_early(struct intel_guc *guc)
> struct intel_gt *gt = guc_to_gt(guc);
> struct drm_i915_private *i915 = gt->i915;
>
> - intel_uc_fw_init_early(&guc->fw, INTEL_UC_FW_TYPE_GUC);
> + intel_uc_fw_init_early(&guc->fw, INTEL_UC_FW_TYPE_GUC, true);
> intel_guc_ct_init_early(&guc->ct);
> intel_guc_log_init_early(&guc->log);
> intel_guc_submission_init_early(guc);
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> index aefdaa62da99..9721761373fb 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> @@ -276,7 +276,7 @@ void intel_huc_init_early(struct intel_huc *huc)
> struct drm_i915_private *i915 = huc_to_gt(huc)->i915;
> struct intel_gt *gt = huc_to_gt(huc);
>
> - intel_uc_fw_init_early(&huc->fw, INTEL_UC_FW_TYPE_HUC);
> + intel_uc_fw_init_early(&huc->fw, INTEL_UC_FW_TYPE_HUC, true);
>
> /*
> * we always init the fence as already completed, even if HuC is not
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> index 996168312340..b6adfda3761e 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> @@ -697,6 +697,12 @@ void intel_uc_suspend(struct intel_uc *uc)
> }
> }
>
> +static void __uc_resume_mappings(struct intel_uc *uc)
> +{
> + intel_uc_fw_resume_mapping(&uc->guc.fw);
> + intel_uc_fw_resume_mapping(&uc->huc.fw);
> +}
> +
> static int __uc_resume(struct intel_uc *uc, bool enable_communication)
> {
> struct intel_guc *guc = &uc->guc;
> @@ -764,4 +770,6 @@ static const struct intel_uc_ops uc_ops_on = {
>
> .init_hw = __uc_init_hw,
> .fini_hw = __uc_fini_hw,
> +
> + .resume_mappings = __uc_resume_mappings,
> };
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.h b/drivers/gpu/drm/i915/gt/uc/intel_uc.h
> index 5d0f1bcc381e..c2783e6e752b 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.h
> @@ -24,6 +24,7 @@ struct intel_uc_ops {
> void (*fini)(struct intel_uc *uc);
> int (*init_hw)(struct intel_uc *uc);
> void (*fini_hw)(struct intel_uc *uc);
> + void (*resume_mappings)(struct intel_uc *uc);
> };
>
> struct intel_uc {
> @@ -113,6 +114,7 @@ intel_uc_ops_function(init, init, int, 0);
> intel_uc_ops_function(fini, fini, void, );
> intel_uc_ops_function(init_hw, init_hw, int, 0);
> intel_uc_ops_function(fini_hw, fini_hw, void, );
> +intel_uc_ops_function(resume_mappings, resume_mappings, void, );
> #undef intel_uc_ops_function
>
> #endif
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> index 6b71b9febd74..03f0b258aea7 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> @@ -422,12 +422,14 @@ static void __uc_fw_user_override(struct drm_i915_private *i915, struct intel_uc
> * intel_uc_fw_init_early - initialize the uC object and select the firmware
> * @uc_fw: uC firmware
> * @type: type of uC
> + * @needs_ggtt_mapping: whether the FW needs to be GGTT mapped for loading
> *
> * Initialize the state of our uC object and relevant tracking and select the
> * firmware to fetch and load.
> */
> void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
> - enum intel_uc_fw_type type)
> + enum intel_uc_fw_type type,
> + bool needs_ggtt_mapping)
> {
> struct drm_i915_private *i915 = ____uc_fw_to_gt(uc_fw, type)->i915;
>
> @@ -440,6 +442,7 @@ void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
> GEM_BUG_ON(uc_fw->file_selected.path);
>
> uc_fw->type = type;
> + uc_fw->needs_ggtt_mapping = needs_ggtt_mapping;
>
> if (HAS_GT_UC(i915)) {
> __uc_fw_auto_select(i915, uc_fw);
> @@ -699,7 +702,7 @@ static int try_firmware_load(struct intel_uc_fw *uc_fw, const struct firmware **
> if (err)
> return err;
>
> - if ((*fw)->size > INTEL_UC_RSVD_GGTT_PER_FW) {
> + if (uc_fw->needs_ggtt_mapping && (*fw)->size > INTEL_UC_RSVD_GGTT_PER_FW) {
> gt_err(gt, "%s firmware %s: size (%zuKB) exceeds max supported size (%uKB)\n",
> intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
> (*fw)->size / SZ_1K, INTEL_UC_RSVD_GGTT_PER_FW / SZ_1K);
> @@ -880,6 +883,9 @@ static void uc_fw_bind_ggtt(struct intel_uc_fw *uc_fw)
> struct i915_vma_resource *dummy = &uc_fw->dummy;
> u32 pte_flags = 0;
>
> + if (!uc_fw->needs_ggtt_mapping)
> + return;
> +
> dummy->start = uc_fw_ggtt_offset(uc_fw);
> dummy->node_size = obj->base.size;
> dummy->bi.pages = obj->mm.pages;
> @@ -901,11 +907,13 @@ static void uc_fw_bind_ggtt(struct intel_uc_fw *uc_fw)
>
> static void uc_fw_unbind_ggtt(struct intel_uc_fw *uc_fw)
> {
> - struct drm_i915_gem_object *obj = uc_fw->obj;
> struct i915_ggtt *ggtt = __uc_fw_to_gt(uc_fw)->ggtt;
> - u64 start = uc_fw_ggtt_offset(uc_fw);
> + struct i915_vma_resource *dummy = &uc_fw->dummy;
I'm confused as to why this was using uc_fw->obj previously? Why was it
not originally using dummy? And why if that was correct before, why is
not correct now?
> +
> + if (!dummy->node_size)
> + return;
>
> - ggtt->vm.clear_range(&ggtt->vm, start, obj->base.size);
> + ggtt->vm.clear_range(&ggtt->vm, dummy->start, dummy->node_size);
> }
>
> static int uc_fw_xfer(struct intel_uc_fw *uc_fw, u32 dst_offset, u32 dma_flags)
> @@ -922,7 +930,7 @@ static int uc_fw_xfer(struct intel_uc_fw *uc_fw, u32 dst_offset, u32 dma_flags)
> intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
>
> /* Set the source address for the uCode */
> - offset = uc_fw_ggtt_offset(uc_fw);
> + offset = uc_fw->dummy.start;
Same question here.
John.
> GEM_BUG_ON(upper_32_bits(offset) & 0xFFFF0000);
> intel_uncore_write_fw(uncore, DMA_ADDR_0_LOW, lower_32_bits(offset));
> intel_uncore_write_fw(uncore, DMA_ADDR_0_HIGH, upper_32_bits(offset));
> @@ -996,9 +1004,7 @@ int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, u32 dst_offset, u32 dma_flags)
> return -ENOEXEC;
>
> /* Call custom loader */
> - uc_fw_bind_ggtt(uc_fw);
> err = uc_fw_xfer(uc_fw, dst_offset, dma_flags);
> - uc_fw_unbind_ggtt(uc_fw);
> if (err)
> goto fail;
>
> @@ -1102,6 +1108,8 @@ int intel_uc_fw_init(struct intel_uc_fw *uc_fw)
> goto out_unpin;
> }
>
> + uc_fw_bind_ggtt(uc_fw);
> +
> return 0;
>
> out_unpin:
> @@ -1112,6 +1120,7 @@ int intel_uc_fw_init(struct intel_uc_fw *uc_fw)
>
> void intel_uc_fw_fini(struct intel_uc_fw *uc_fw)
> {
> + uc_fw_unbind_ggtt(uc_fw);
> uc_fw_rsa_data_destroy(uc_fw);
>
> if (i915_gem_object_has_pinned_pages(uc_fw->obj))
> @@ -1120,6 +1129,17 @@ void intel_uc_fw_fini(struct intel_uc_fw *uc_fw)
> intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_AVAILABLE);
> }
>
> +void intel_uc_fw_resume_mapping(struct intel_uc_fw *uc_fw)
> +{
> + if (!intel_uc_fw_is_available(uc_fw))
> + return;
> +
> + if (!i915_gem_object_has_pinned_pages(uc_fw->obj))
> + return;
> +
> + uc_fw_bind_ggtt(uc_fw);
> +}
> +
> /**
> * intel_uc_fw_cleanup_fetch - cleanup uC firmware
> * @uc_fw: uC firmware
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
> index 6ba00e6b3975..26a9d6e0dc00 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
> @@ -105,6 +105,7 @@ struct intel_uc_fw {
> * threaded as it done during driver load (inherently single threaded)
> * or during a GT reset (mutex guarantees single threaded).
> */
> + bool needs_ggtt_mapping;
> struct i915_vma_resource dummy;
> struct i915_vma *rsa_data;
>
> @@ -282,12 +283,14 @@ static inline u32 intel_uc_fw_get_upload_size(struct intel_uc_fw *uc_fw)
> }
>
> void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
> - enum intel_uc_fw_type type);
> + enum intel_uc_fw_type type,
> + bool needs_ggtt_mapping);
> int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw);
> void intel_uc_fw_cleanup_fetch(struct intel_uc_fw *uc_fw);
> int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, u32 offset, u32 dma_flags);
> int intel_uc_fw_init(struct intel_uc_fw *uc_fw);
> void intel_uc_fw_fini(struct intel_uc_fw *uc_fw);
> +void intel_uc_fw_resume_mapping(struct intel_uc_fw *uc_fw);
> size_t intel_uc_fw_copy_rsa(struct intel_uc_fw *uc_fw, void *dst, u32 max_len);
> int intel_uc_fw_mark_load_failed(struct intel_uc_fw *uc_fw, int err);
> void intel_uc_fw_dump(const struct intel_uc_fw *uc_fw, struct drm_printer *p);
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Intel-gfx] [PATCH v2] drm/i915/huc: Parse the GSC-enabled HuC binary
2023-05-02 15:27 ` [Intel-gfx] [PATCH v2] " Daniele Ceraolo Spurio
2023-05-13 0:38 ` Teres Alexis, Alan Previn
@ 2023-05-17 21:04 ` John Harrison
2023-05-19 20:35 ` Ceraolo Spurio, Daniele
1 sibling, 1 reply; 32+ messages in thread
From: John Harrison @ 2023-05-17 21:04 UTC (permalink / raw)
To: Daniele Ceraolo Spurio, intel-gfx; +Cc: dri-devel, Alan Previn
On 5/2/2023 08:27, Daniele Ceraolo Spurio wrote:
> The new binaries that support the 2-step authentication have contain the
have contain?
> legacy-style binary, which we can use for loading the HuC via DMA. To
> find out where this is located in the image, we need to parse the meu
'meu manifest' needs some kind of explanation. 'meu' is mentioned many
times but nothing ever seems to explain what it is or where it comes
from. Also, sometimes it is capitalised and sometimes not.
> manifest of the GSC binary. The manifest consist of a partition header
> followed by entries, one of which contains the offset we're looking for.
> Note that the DG2 GSC binary contains entries with the same names, but
> it doesn't contain a full legacy binary, so we need to skip assigning
> the dma offset in that case (which we can do by checking the ccs).
> Also, since we're now parsing the entries, we can extract the HuC
> version that way instead of using hardcoded offsets.
>
> Note that the meu structure will be re-used for parsing the GSC binary,
> so they've been added in their own header.
>
> v2: fix structure names to match meu defines (s/CPT/CPD/), update commit
> message, check ccs validity, drop old version location defines.
>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
> ---
> .../drm/i915/gt/uc/intel_gsc_meu_headers.h | 74 ++++++++++
> drivers/gpu/drm/i915/gt/uc/intel_huc.c | 11 +-
> drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 135 ++++++++++++++++++
> drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h | 5 +-
> drivers/gpu/drm/i915/gt/uc/intel_huc_print.h | 21 +++
> drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 71 +++++----
> drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h | 2 +
> drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h | 6 -
> 8 files changed, 272 insertions(+), 53 deletions(-)
> create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
> create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_huc_print.h
>
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h b/drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
> new file mode 100644
> index 000000000000..d55a66202576
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
> @@ -0,0 +1,74 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2023 Intel Corporation
> + */
> +
> +#ifndef _INTEL_GSC_MEU_H_
> +#define _INTEL_GSC_MEU_H_
> +
> +#include <linux/types.h>
> +
> +/* Code partition directory (CPD) structures */
> +struct intel_gsc_cpd_header_v2 {
> + u32 header_marker;
> +#define INTEL_GSC_CPD_HEADER_MARKER 0x44504324
> +
> + u32 num_of_entries;
> + u8 header_version;
> + u8 entry_version;
> + u8 header_length; /* in bytes */
> + u8 flags;
> + u32 partition_name;
> + u32 crc32;
> +} __packed;
> +
> +struct intel_gsc_cpd_entry {
> + u8 name[12];
> +
> + /*
> + * Bits 0-24: offset from the beginning of the code partition
> + * Bit 25: huffman compressed
> + * Bits 26-31: reserved
> + */
> + u32 offset;
> +#define INTEL_GSC_CPD_ENTRY_OFFSET_MASK GENMASK(24, 0)
> +#define INTEL_GSC_CPD_ENTRY_HUFFMAN_COMP BIT(25)
> +
> + /*
> + * Module/Item length, in bytes. For Huffman-compressed modules, this
> + * refers to the uncompressed size. For software-compressed modules,
> + * this refers to the compressed size.
> + */
> + u32 length;
> +
> + u8 reserved[4];
> +} __packed;
> +
> +struct intel_gsc_meu_version {
> + u16 major;
> + u16 minor;
> + u16 hotfix;
> + u16 build;
> +} __packed;
> +
> +struct intel_gsc_manifest_header {
> + u32 header_type; /* 0x4 for manifest type */
> + u32 header_length; /* in dwords */
> + u32 header_version;
> + u32 flags;
> + u32 vendor;
> + u32 date;
> + u32 size; /* In dwords, size of entire manifest (header + extensions) */
> + u32 header_id;
> + u32 internal_data;
> + struct intel_gsc_meu_version fw_version;
> + u32 security_version;
> + struct intel_gsc_meu_version meu_kit_version;
> + u32 meu_manifest_version;
> + u8 general_data[4];
> + u8 reserved3[56];
> + u32 modulus_size; /* in dwords */
> + u32 exponent_size; /* in dwords */
> +} __packed;
> +
> +#endif
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> index 9721761373fb..062ff914b274 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> @@ -6,23 +6,14 @@
> #include <linux/types.h>
>
> #include "gt/intel_gt.h"
> -#include "gt/intel_gt_print.h"
> #include "intel_guc_reg.h"
> #include "intel_huc.h"
> +#include "intel_huc_print.h"
> #include "i915_drv.h"
>
> #include <linux/device/bus.h>
> #include <linux/mei_aux.h>
>
> -#define huc_printk(_huc, _level, _fmt, ...) \
> - gt_##_level(huc_to_gt(_huc), "HuC: " _fmt, ##__VA_ARGS__)
> -#define huc_err(_huc, _fmt, ...) huc_printk((_huc), err, _fmt, ##__VA_ARGS__)
> -#define huc_warn(_huc, _fmt, ...) huc_printk((_huc), warn, _fmt, ##__VA_ARGS__)
> -#define huc_notice(_huc, _fmt, ...) huc_printk((_huc), notice, _fmt, ##__VA_ARGS__)
> -#define huc_info(_huc, _fmt, ...) huc_printk((_huc), info, _fmt, ##__VA_ARGS__)
> -#define huc_dbg(_huc, _fmt, ...) huc_printk((_huc), dbg, _fmt, ##__VA_ARGS__)
> -#define huc_probe_error(_huc, _fmt, ...) huc_printk((_huc), probe_error, _fmt, ##__VA_ARGS__)
> -
> /**
> * DOC: HuC
> *
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
> index 534b0aa43316..0ec48c2cd749 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
> @@ -5,11 +5,146 @@
>
> #include "gt/intel_gsc.h"
> #include "gt/intel_gt.h"
> +#include "intel_gsc_meu_headers.h"
> #include "intel_huc.h"
> #include "intel_huc_fw.h"
> +#include "intel_huc_print.h"
> #include "i915_drv.h"
> #include "pxp/intel_pxp_huc.h"
>
> +static void get_version_from_meu_manifest(struct intel_uc_fw_ver *ver, const void *data)
> +{
> + const struct intel_gsc_manifest_header *manifest = data;
> +
> + ver->major = manifest->fw_version.major;
> + ver->minor = manifest->fw_version.minor;
> + ver->patch = manifest->fw_version.hotfix;
> +}
> +
> +static bool css_valid(const void *data, size_t size)
> +{
> + const struct uc_css_header *css = data;
> +
> + if (unlikely(size < sizeof(struct uc_css_header)))
> + return false;
> +
> + if (css->module_type != 0x6)
> + return false;
> +
> + if (css->module_vendor != PCI_VENDOR_ID_INTEL)
> + return false;
> +
> + return true;
> +}
> +
> +static inline u32 entry_offset(const struct intel_gsc_cpd_entry *entry)
> +{
> + return entry->offset & INTEL_GSC_CPD_ENTRY_OFFSET_MASK;
> +}
> +
> +int intel_huc_fw_get_binary_info(struct intel_uc_fw *huc_fw, const void *data, size_t size)
> +{
> + struct intel_huc *huc = container_of(huc_fw, struct intel_huc, fw);
> + const struct intel_gsc_cpd_header_v2 *header = data;
> + const struct intel_gsc_cpd_entry *entry;
> + size_t min_size = sizeof(*header);
> + int i;
> +
> + if (!huc_fw->loaded_via_gsc) {
> + huc_err(huc, "Invalid FW type MEU parsing!\n");
Not sure what this message is meant to be saying?
John.
> + return -EINVAL;
> + }
> +
> + if (size < sizeof(*header)) {
> + huc_err(huc, "MEU FW too small! %zu < %zu\n", size, min_size);
> + return -ENODATA;
> + }
> +
> + /*
> + * The meu HuC binary starts with a directory header, followed by a
> + * series of entries. Each entry is identified by a name and points to
> + * a specific section of the binary containing the relevant data.
> + * The entries we're interested in are
> + * - "HUCP.man": points to the GSC manifest header for the HuC, which
> + * contains the version info.
> + * - "huc_fw": points to the legacy-style binary that can be used for
> + * load via the DMA. This entry only contains a valid CSS
> + * on binaries for platforms that support 2-step HuC load
> + * via dma and auth via GSC (like MTL).
> + *
> + * --------------------------------------------------
> + * [ intel_gsc_cpd_header_v2 ]
> + * --------------------------------------------------
> + * [ intel_gsc_cpd_entry[] ]
> + * [ entry1 ]
> + * [ ... ]
> + * [ entryX ]
> + * [ "HUCP.man" ]
> + * [ ... ]
> + * [ offset >----------------------------]------o
> + * [ ... ] |
> + * [ entryY ] |
> + * [ "huc_fw" ] |
> + * [ ... ] |
> + * [ offset >----------------------------]----------o
> + * -------------------------------------------------- | |
> + * | |
> + * -------------------------------------------------- | |
> + * [ intel_gsc_manifest_header ]<-----o |
> + * [ ... ] |
> + * [ intel_gsc_meu_version fw_version ] |
> + * [ ... ] |
> + * -------------------------------------------------- |
> + * |
> + * -------------------------------------------------- |
> + * [ data[] ]<---------o
> + * [ ... ]
> + * [ ... ]
> + * --------------------------------------------------
> + */
> +
> + if (header->header_marker != INTEL_GSC_CPD_HEADER_MARKER) {
> + huc_err(huc, "invalid marker for meu CPD header: 0x%08x!\n",
> + header->header_marker);
> + return -EINVAL;
> + }
> +
> + /* we only have binaries with header v2 and entry v1 for now */
> + if (header->header_version != 2 || header->entry_version != 1) {
> + huc_err(huc, "invalid meu CPD header/entry version %u:%u!\n",
> + header->header_version, header->entry_version);
> + return -EINVAL;
> + }
> +
> + if (header->header_length < sizeof(struct intel_gsc_cpd_header_v2)) {
> + huc_err(huc, "invalid meu CPD header length %u!\n",
> + header->header_length);
> + return -EINVAL;
> + }
> +
> + min_size = header->header_length + sizeof(*entry) * header->num_of_entries;
> + if (size < min_size) {
> + huc_err(huc, "MEU FW too small! %zu < %zu\n", size, min_size);
> + return -ENODATA;
> + }
> +
> + entry = data + header->header_length;
> +
> + for (i = 0; i < header->num_of_entries; i++, entry++) {
> + if (strcmp(entry->name, "HUCP.man") == 0)
> + get_version_from_meu_manifest(&huc_fw->file_selected.ver,
> + data + entry_offset(entry));
> +
> + if (strcmp(entry->name, "huc_fw") == 0) {
> + u32 offset = entry_offset(entry);
> + if (offset < size && css_valid(data + offset, size - offset))
> + huc_fw->dma_start_offset = offset;
> + }
> + }
> +
> + return 0;
> +}
> +
> int intel_huc_fw_load_and_auth_via_gsc(struct intel_huc *huc)
> {
> int ret;
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
> index db42e238b45f..0999ffe6f962 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
> @@ -7,8 +7,11 @@
> #define _INTEL_HUC_FW_H_
>
> struct intel_huc;
> +struct intel_uc_fw;
> +
> +#include <linux/types.h>
>
> int intel_huc_fw_load_and_auth_via_gsc(struct intel_huc *huc);
> int intel_huc_fw_upload(struct intel_huc *huc);
> -
> +int intel_huc_fw_get_binary_info(struct intel_uc_fw *huc_fw, const void *data, size_t size);
> #endif
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_print.h b/drivers/gpu/drm/i915/gt/uc/intel_huc_print.h
> new file mode 100644
> index 000000000000..915d310ee1df
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_print.h
> @@ -0,0 +1,21 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2023 Intel Corporation
> + */
> +
> +#ifndef __INTEL_HUC_PRINT__
> +#define __INTEL_HUC_PRINT__
> +
> +#include "gt/intel_gt.h"
> +#include "gt/intel_gt_print.h"
> +
> +#define huc_printk(_huc, _level, _fmt, ...) \
> + gt_##_level(huc_to_gt(_huc), "HuC: " _fmt, ##__VA_ARGS__)
> +#define huc_err(_huc, _fmt, ...) huc_printk((_huc), err, _fmt, ##__VA_ARGS__)
> +#define huc_warn(_huc, _fmt, ...) huc_printk((_huc), warn, _fmt, ##__VA_ARGS__)
> +#define huc_notice(_huc, _fmt, ...) huc_printk((_huc), notice, _fmt, ##__VA_ARGS__)
> +#define huc_info(_huc, _fmt, ...) huc_printk((_huc), info, _fmt, ##__VA_ARGS__)
> +#define huc_dbg(_huc, _fmt, ...) huc_printk((_huc), dbg, _fmt, ##__VA_ARGS__)
> +#define huc_probe_error(_huc, _fmt, ...) huc_printk((_huc), probe_error, _fmt, ##__VA_ARGS__)
> +
> +#endif /* __INTEL_HUC_PRINT__ */
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> index 03f0b258aea7..da6fcfe1d80a 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> @@ -492,33 +492,6 @@ static void __force_fw_fetch_failures(struct intel_uc_fw *uc_fw, int e)
> }
> }
>
> -static int check_gsc_manifest(struct intel_gt *gt,
> - const struct firmware *fw,
> - struct intel_uc_fw *uc_fw)
> -{
> - u32 *dw = (u32 *)fw->data;
> - u32 version_hi, version_lo;
> - size_t min_size;
> -
> - /* Check the size of the blob before examining buffer contents */
> - min_size = sizeof(u32) * (HUC_GSC_VERSION_LO_DW + 1);
> - if (unlikely(fw->size < min_size)) {
> - gt_warn(gt, "%s firmware %s: invalid size: %zu < %zu\n",
> - intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
> - fw->size, min_size);
> - return -ENODATA;
> - }
> -
> - version_hi = dw[HUC_GSC_VERSION_HI_DW];
> - version_lo = dw[HUC_GSC_VERSION_LO_DW];
> -
> - uc_fw->file_selected.ver.major = FIELD_GET(HUC_GSC_MAJOR_VER_HI_MASK, version_hi);
> - uc_fw->file_selected.ver.minor = FIELD_GET(HUC_GSC_MINOR_VER_HI_MASK, version_hi);
> - uc_fw->file_selected.ver.patch = FIELD_GET(HUC_GSC_PATCH_VER_LO_MASK, version_lo);
> -
> - return 0;
> -}
> -
> static void uc_unpack_css_version(struct intel_uc_fw_ver *ver, u32 css_value)
> {
> /* Get version numbers from the CSS header */
> @@ -575,22 +548,22 @@ static void guc_read_css_info(struct intel_uc_fw *uc_fw, struct uc_css_header *c
> uc_fw->private_data_size = css->private_data_size;
> }
>
> -static int check_ccs_header(struct intel_gt *gt,
> - const struct firmware *fw,
> - struct intel_uc_fw *uc_fw)
> +static int __check_ccs_header(struct intel_gt *gt,
> + const void *fw_data, size_t fw_size,
> + struct intel_uc_fw *uc_fw)
> {
> struct uc_css_header *css;
> size_t size;
>
> /* Check the size of the blob before examining buffer contents */
> - if (unlikely(fw->size < sizeof(struct uc_css_header))) {
> + if (unlikely(fw_size < sizeof(struct uc_css_header))) {
> gt_warn(gt, "%s firmware %s: invalid size: %zu < %zu\n",
> intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
> - fw->size, sizeof(struct uc_css_header));
> + fw_size, sizeof(struct uc_css_header));
> return -ENODATA;
> }
>
> - css = (struct uc_css_header *)fw->data;
> + css = (struct uc_css_header *)fw_data;
>
> /* Check integrity of size values inside CSS header */
> size = (css->header_size_dw - css->key_size_dw - css->modulus_size_dw -
> @@ -598,7 +571,7 @@ static int check_ccs_header(struct intel_gt *gt,
> if (unlikely(size != sizeof(struct uc_css_header))) {
> gt_warn(gt, "%s firmware %s: unexpected header size: %zu != %zu\n",
> intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
> - fw->size, sizeof(struct uc_css_header));
> + fw_size, sizeof(struct uc_css_header));
> return -EPROTO;
> }
>
> @@ -610,10 +583,10 @@ static int check_ccs_header(struct intel_gt *gt,
>
> /* At least, it should have header, uCode and RSA. Size of all three. */
> size = sizeof(struct uc_css_header) + uc_fw->ucode_size + uc_fw->rsa_size;
> - if (unlikely(fw->size < size)) {
> + if (unlikely(fw_size < size)) {
> gt_warn(gt, "%s firmware %s: invalid size: %zu < %zu\n",
> intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
> - fw->size, size);
> + fw_size, size);
> return -ENOEXEC;
> }
>
> @@ -634,6 +607,32 @@ static int check_ccs_header(struct intel_gt *gt,
> return 0;
> }
>
> +static int check_gsc_manifest(struct intel_gt *gt,
> + const struct firmware *fw,
> + struct intel_uc_fw *uc_fw)
> +{
> + if (uc_fw->type != INTEL_UC_FW_TYPE_HUC) {
> + gt_err(gt, "trying to MEU-parse a non-HuC binary");
> + return -EINVAL;
> + }
> +
> + intel_huc_fw_get_binary_info(uc_fw, fw->data, fw->size);
> +
> + if (uc_fw->dma_start_offset) {
> + u32 delta = uc_fw->dma_start_offset;
> + __check_ccs_header(gt, fw->data + delta, fw->size - delta, uc_fw);
> + }
> +
> + return 0;
> +}
> +
> +static int check_ccs_header(struct intel_gt *gt,
> + const struct firmware *fw,
> + struct intel_uc_fw *uc_fw)
> +{
> + return __check_ccs_header(gt, fw->data, fw->size, uc_fw);
> +}
> +
> static bool is_ver_8bit(struct intel_uc_fw_ver *ver)
> {
> return ver->major < 0xFF && ver->minor < 0xFF && ver->patch < 0xFF;
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
> index 26a9d6e0dc00..2691bb6bde48 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
> @@ -113,6 +113,8 @@ struct intel_uc_fw {
> u32 ucode_size;
> u32 private_data_size;
>
> + u32 dma_start_offset;
> +
> bool loaded_via_gsc;
> };
>
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h
> index 646fa8aa6cf1..7fe405126249 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h
> @@ -84,10 +84,4 @@ struct uc_css_header {
> } __packed;
> static_assert(sizeof(struct uc_css_header) == 128);
>
> -#define HUC_GSC_VERSION_HI_DW 44
> -#define HUC_GSC_MAJOR_VER_HI_MASK (0xFF << 0)
> -#define HUC_GSC_MINOR_VER_HI_MASK (0xFF << 16)
> -#define HUC_GSC_VERSION_LO_DW 45
> -#define HUC_GSC_PATCH_VER_LO_MASK (0xFF << 0)
> -
> #endif /* _INTEL_UC_FW_ABI_H */
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Intel-gfx] [PATCH v2 2/8] drm/i915/uc: perma-pin firmwares
2023-05-17 20:59 ` John Harrison
@ 2023-05-17 21:12 ` Ceraolo Spurio, Daniele
0 siblings, 0 replies; 32+ messages in thread
From: Ceraolo Spurio, Daniele @ 2023-05-17 21:12 UTC (permalink / raw)
To: John Harrison, intel-gfx; +Cc: dri-devel, Alan Previn
On 5/17/2023 1:59 PM, John Harrison wrote:
> On 4/28/2023 11:58, Daniele Ceraolo Spurio wrote:
>> Now that each FW has its own reserved area, we can keep them always
>> pinned and skip the pin/unpin dance on reset. This will make things
>> easier for the 2-step HuC authentication, which requires the FW to be
>> pinned in GGTT after the xfer is completed.
>> Given that we use dummy vmas for the pinning, we do need to explicitly
>> re-pin on resume because the automated helper won't cover us.
>>
>> Signed-off-by: Daniele Ceraolo Spurio<daniele.ceraolospurio@intel.com>
>> Cc: Alan Previn<alan.previn.teres.alexis@intel.com>
>> ---
>> drivers/gpu/drm/i915/gt/intel_ggtt.c | 3 ++
>> drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 7 ++++-
>> drivers/gpu/drm/i915/gt/uc/intel_guc.c | 2 +-
>> drivers/gpu/drm/i915/gt/uc/intel_huc.c | 2 +-
>> drivers/gpu/drm/i915/gt/uc/intel_uc.c | 8 +++++
>> drivers/gpu/drm/i915/gt/uc/intel_uc.h | 2 ++
>> drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 36 ++++++++++++++++++-----
>> drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h | 5 +++-
>> 8 files changed, 53 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c
>> b/drivers/gpu/drm/i915/gt/intel_ggtt.c
>> index 20915edc8bd9..ab71ed11de79 100644
>> --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
>> +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
>> @@ -1322,6 +1322,9 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
>> ggtt->vm.scratch_range(&ggtt->vm, ggtt->error_capture.start,
>> ggtt->error_capture.size);
>> + list_for_each_entry(gt, &ggtt->gt_list, ggtt_link)
>> + intel_uc_resume_mappings(>->uc);
>> +
>> ggtt->invalidate(ggtt);
>> if (flush)
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
>> b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
>> index 64bff01026e8..af542e3cb3e9 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
>> @@ -80,7 +80,12 @@ void intel_gsc_uc_init_early(struct intel_gsc_uc
>> *gsc)
>> {
>> struct intel_gt *gt = gsc_uc_to_gt(gsc);
>> - intel_uc_fw_init_early(&gsc->fw, INTEL_UC_FW_TYPE_GSC);
>> + /*
>> + * GSC FW needs to be copied to a dedicated memory allocations for
>> + * loading (see gsc->local), so we don't need to GGTT map the FW
>> image
>> + * itself into GGTT.
>> + */
>> + intel_uc_fw_init_early(&gsc->fw, INTEL_UC_FW_TYPE_GSC, false);
>> INIT_WORK(&gsc->work, gsc_work);
>> /* we can arrive here from i915_driver_early_probe for primary
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
>> b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
>> index c9f20385f6a0..2eb891b270ae 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
>> @@ -164,7 +164,7 @@ void intel_guc_init_early(struct intel_guc *guc)
>> struct intel_gt *gt = guc_to_gt(guc);
>> struct drm_i915_private *i915 = gt->i915;
>> - intel_uc_fw_init_early(&guc->fw, INTEL_UC_FW_TYPE_GUC);
>> + intel_uc_fw_init_early(&guc->fw, INTEL_UC_FW_TYPE_GUC, true);
>> intel_guc_ct_init_early(&guc->ct);
>> intel_guc_log_init_early(&guc->log);
>> intel_guc_submission_init_early(guc);
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>> b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>> index aefdaa62da99..9721761373fb 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>> @@ -276,7 +276,7 @@ void intel_huc_init_early(struct intel_huc *huc)
>> struct drm_i915_private *i915 = huc_to_gt(huc)->i915;
>> struct intel_gt *gt = huc_to_gt(huc);
>> - intel_uc_fw_init_early(&huc->fw, INTEL_UC_FW_TYPE_HUC);
>> + intel_uc_fw_init_early(&huc->fw, INTEL_UC_FW_TYPE_HUC, true);
>> /*
>> * we always init the fence as already completed, even if HuC
>> is not
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
>> b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
>> index 996168312340..b6adfda3761e 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
>> @@ -697,6 +697,12 @@ void intel_uc_suspend(struct intel_uc *uc)
>> }
>> }
>> +static void __uc_resume_mappings(struct intel_uc *uc)
>> +{
>> + intel_uc_fw_resume_mapping(&uc->guc.fw);
>> + intel_uc_fw_resume_mapping(&uc->huc.fw);
>> +}
>> +
>> static int __uc_resume(struct intel_uc *uc, bool enable_communication)
>> {
>> struct intel_guc *guc = &uc->guc;
>> @@ -764,4 +770,6 @@ static const struct intel_uc_ops uc_ops_on = {
>> .init_hw = __uc_init_hw,
>> .fini_hw = __uc_fini_hw,
>> +
>> + .resume_mappings = __uc_resume_mappings,
>> };
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.h
>> b/drivers/gpu/drm/i915/gt/uc/intel_uc.h
>> index 5d0f1bcc381e..c2783e6e752b 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.h
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.h
>> @@ -24,6 +24,7 @@ struct intel_uc_ops {
>> void (*fini)(struct intel_uc *uc);
>> int (*init_hw)(struct intel_uc *uc);
>> void (*fini_hw)(struct intel_uc *uc);
>> + void (*resume_mappings)(struct intel_uc *uc);
>> };
>> struct intel_uc {
>> @@ -113,6 +114,7 @@ intel_uc_ops_function(init, init, int, 0);
>> intel_uc_ops_function(fini, fini, void, );
>> intel_uc_ops_function(init_hw, init_hw, int, 0);
>> intel_uc_ops_function(fini_hw, fini_hw, void, );
>> +intel_uc_ops_function(resume_mappings, resume_mappings, void, );
>> #undef intel_uc_ops_function
>> #endif
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> index 6b71b9febd74..03f0b258aea7 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> @@ -422,12 +422,14 @@ static void __uc_fw_user_override(struct
>> drm_i915_private *i915, struct intel_uc
>> * intel_uc_fw_init_early - initialize the uC object and select the
>> firmware
>> * @uc_fw: uC firmware
>> * @type: type of uC
>> + * @needs_ggtt_mapping: whether the FW needs to be GGTT mapped for
>> loading
>> *
>> * Initialize the state of our uC object and relevant tracking and
>> select the
>> * firmware to fetch and load.
>> */
>> void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
>> - enum intel_uc_fw_type type)
>> + enum intel_uc_fw_type type,
>> + bool needs_ggtt_mapping)
>> {
>> struct drm_i915_private *i915 = ____uc_fw_to_gt(uc_fw,
>> type)->i915;
>> @@ -440,6 +442,7 @@ void intel_uc_fw_init_early(struct intel_uc_fw
>> *uc_fw,
>> GEM_BUG_ON(uc_fw->file_selected.path);
>> uc_fw->type = type;
>> + uc_fw->needs_ggtt_mapping = needs_ggtt_mapping;
>> if (HAS_GT_UC(i915)) {
>> __uc_fw_auto_select(i915, uc_fw);
>> @@ -699,7 +702,7 @@ static int try_firmware_load(struct intel_uc_fw
>> *uc_fw, const struct firmware **
>> if (err)
>> return err;
>> - if ((*fw)->size > INTEL_UC_RSVD_GGTT_PER_FW) {
>> + if (uc_fw->needs_ggtt_mapping && (*fw)->size >
>> INTEL_UC_RSVD_GGTT_PER_FW) {
>> gt_err(gt, "%s firmware %s: size (%zuKB) exceeds max
>> supported size (%uKB)\n",
>> intel_uc_fw_type_repr(uc_fw->type),
>> uc_fw->file_selected.path,
>> (*fw)->size / SZ_1K, INTEL_UC_RSVD_GGTT_PER_FW /
>> SZ_1K);
>> @@ -880,6 +883,9 @@ static void uc_fw_bind_ggtt(struct intel_uc_fw
>> *uc_fw)
>> struct i915_vma_resource *dummy = &uc_fw->dummy;
>> u32 pte_flags = 0;
>> + if (!uc_fw->needs_ggtt_mapping)
>> + return;
>> +
>> dummy->start = uc_fw_ggtt_offset(uc_fw);
>> dummy->node_size = obj->base.size;
>> dummy->bi.pages = obj->mm.pages;
>> @@ -901,11 +907,13 @@ static void uc_fw_bind_ggtt(struct intel_uc_fw
>> *uc_fw)
>> static void uc_fw_unbind_ggtt(struct intel_uc_fw *uc_fw)
>> {
>> - struct drm_i915_gem_object *obj = uc_fw->obj;
>> struct i915_ggtt *ggtt = __uc_fw_to_gt(uc_fw)->ggtt;
>> - u64 start = uc_fw_ggtt_offset(uc_fw);
>> + struct i915_vma_resource *dummy = &uc_fw->dummy;
> I'm confused as to why this was using uc_fw->obj previously? Why was
> it not originally using dummy? And why if that was correct before, why
> is not correct now?
Both are correct, because the values inside of dummy are initialized
based on uc_fw->obj and uc_fw_ggtt_offset(). Since now we're
perma-pinning the binary, I wanted to move to a vma-centric approach for
the functions, which also makes it easier to check if the vma has
actually been pinned (via the dummy->node_size check below) in the
fini/unbind path; this check was not required before because the vma was
immediately unpinned after load and therefore we didn't need to check it
in the fini path.
Also, the "dummy" name is probably not valid anymore; it was used
because the vma structure was not allocated via the normal functions and
not kept around, but now that it is it's probably better to rename it to
just vma_res or something like that.
Daniele
>
>> +
>> + if (!dummy->node_size)
>> + return;
>> - ggtt->vm.clear_range(&ggtt->vm, start, obj->base.size);
>> + ggtt->vm.clear_range(&ggtt->vm, dummy->start, dummy->node_size);
>> }
>> static int uc_fw_xfer(struct intel_uc_fw *uc_fw, u32 dst_offset,
>> u32 dma_flags)
>> @@ -922,7 +930,7 @@ static int uc_fw_xfer(struct intel_uc_fw *uc_fw,
>> u32 dst_offset, u32 dma_flags)
>> intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
>> /* Set the source address for the uCode */
>> - offset = uc_fw_ggtt_offset(uc_fw);
>> + offset = uc_fw->dummy.start;
> Same question here.
>
> John.
>
>> GEM_BUG_ON(upper_32_bits(offset) & 0xFFFF0000);
>> intel_uncore_write_fw(uncore, DMA_ADDR_0_LOW,
>> lower_32_bits(offset));
>> intel_uncore_write_fw(uncore, DMA_ADDR_0_HIGH,
>> upper_32_bits(offset));
>> @@ -996,9 +1004,7 @@ int intel_uc_fw_upload(struct intel_uc_fw
>> *uc_fw, u32 dst_offset, u32 dma_flags)
>> return -ENOEXEC;
>> /* Call custom loader */
>> - uc_fw_bind_ggtt(uc_fw);
>> err = uc_fw_xfer(uc_fw, dst_offset, dma_flags);
>> - uc_fw_unbind_ggtt(uc_fw);
>> if (err)
>> goto fail;
>> @@ -1102,6 +1108,8 @@ int intel_uc_fw_init(struct intel_uc_fw *uc_fw)
>> goto out_unpin;
>> }
>> + uc_fw_bind_ggtt(uc_fw);
>> +
>> return 0;
>> out_unpin:
>> @@ -1112,6 +1120,7 @@ int intel_uc_fw_init(struct intel_uc_fw *uc_fw)
>> void intel_uc_fw_fini(struct intel_uc_fw *uc_fw)
>> {
>> + uc_fw_unbind_ggtt(uc_fw);
>> uc_fw_rsa_data_destroy(uc_fw);
>> if (i915_gem_object_has_pinned_pages(uc_fw->obj))
>> @@ -1120,6 +1129,17 @@ void intel_uc_fw_fini(struct intel_uc_fw *uc_fw)
>> intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_AVAILABLE);
>> }
>> +void intel_uc_fw_resume_mapping(struct intel_uc_fw *uc_fw)
>> +{
>> + if (!intel_uc_fw_is_available(uc_fw))
>> + return;
>> +
>> + if (!i915_gem_object_has_pinned_pages(uc_fw->obj))
>> + return;
>> +
>> + uc_fw_bind_ggtt(uc_fw);
>> +}
>> +
>> /**
>> * intel_uc_fw_cleanup_fetch - cleanup uC firmware
>> * @uc_fw: uC firmware
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
>> b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
>> index 6ba00e6b3975..26a9d6e0dc00 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
>> @@ -105,6 +105,7 @@ struct intel_uc_fw {
>> * threaded as it done during driver load (inherently single
>> threaded)
>> * or during a GT reset (mutex guarantees single threaded).
>> */
>> + bool needs_ggtt_mapping;
>> struct i915_vma_resource dummy;
>> struct i915_vma *rsa_data;
>> @@ -282,12 +283,14 @@ static inline u32
>> intel_uc_fw_get_upload_size(struct intel_uc_fw *uc_fw)
>> }
>> void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
>> - enum intel_uc_fw_type type);
>> + enum intel_uc_fw_type type,
>> + bool needs_ggtt_mapping);
>> int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw);
>> void intel_uc_fw_cleanup_fetch(struct intel_uc_fw *uc_fw);
>> int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, u32 offset, u32
>> dma_flags);
>> int intel_uc_fw_init(struct intel_uc_fw *uc_fw);
>> void intel_uc_fw_fini(struct intel_uc_fw *uc_fw);
>> +void intel_uc_fw_resume_mapping(struct intel_uc_fw *uc_fw);
>> size_t intel_uc_fw_copy_rsa(struct intel_uc_fw *uc_fw, void *dst,
>> u32 max_len);
>> int intel_uc_fw_mark_load_failed(struct intel_uc_fw *uc_fw, int err);
>> void intel_uc_fw_dump(const struct intel_uc_fw *uc_fw, struct
>> drm_printer *p);
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Intel-gfx] [PATCH v2 4/8] drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 4/8] drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so Daniele Ceraolo Spurio
@ 2023-05-19 18:03 ` John Harrison
2023-05-20 0:05 ` Ceraolo Spurio, Daniele
0 siblings, 1 reply; 32+ messages in thread
From: John Harrison @ 2023-05-19 18:03 UTC (permalink / raw)
To: Daniele Ceraolo Spurio, intel-gfx; +Cc: dri-devel, Alan Previn
On 4/28/2023 11:58, Daniele Ceraolo Spurio wrote:
> In the previous patch we extracted the offset of the legacy-style HuC
> binary located within the GSC-enabled blob, so now we can use that to
> load the HuC via DMA if the fuse is set that way.
> Note that we now need to differentiate between "GSC-enabled binary" and
> "loaded by GSC", so the former case has been renamed to "MEU binary" for
> clarity, while the latter is now based on the fuse instead of the binary
> format. This way, all the legacy load paths are automatically taken
> (including the auth by GuC) without having to implement further code
> changes.
>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
> ---
> drivers/gpu/drm/i915/gt/uc/intel_huc.c | 27 ++++++++++++++---------
> drivers/gpu/drm/i915/gt/uc/intel_huc.h | 4 +++-
> drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 2 +-
> drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 14 ++++++------
> drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h | 2 +-
> 5 files changed, 29 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> index 062ff914b274..c189ede4ef55 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> @@ -298,31 +298,38 @@ void intel_huc_init_early(struct intel_huc *huc)
> static int check_huc_loading_mode(struct intel_huc *huc)
> {
> struct intel_gt *gt = huc_to_gt(huc);
> - bool fw_needs_gsc = intel_huc_is_loaded_by_gsc(huc);
> - bool hw_uses_gsc = false;
> + bool fw_is_meu = huc->fw.is_meu_binary;
>
> /*
> * The fuse for HuC load via GSC is only valid on platforms that have
> * GuC deprivilege.
> */
> if (HAS_GUC_DEPRIVILEGE(gt->i915))
> - hw_uses_gsc = intel_uncore_read(gt->uncore, GUC_SHIM_CONTROL2) &
> - GSC_LOADS_HUC;
> + huc->loaded_via_gsc = intel_uncore_read(gt->uncore, GUC_SHIM_CONTROL2) &
> + GSC_LOADS_HUC;
>
> - if (fw_needs_gsc != hw_uses_gsc) {
> - huc_err(huc, "mismatch between FW (%s) and HW (%s) load modes\n",
> - HUC_LOAD_MODE_STRING(fw_needs_gsc), HUC_LOAD_MODE_STRING(hw_uses_gsc));
> + if (huc->loaded_via_gsc && !fw_is_meu) {
> + huc_err(huc, "HW requires a MEU blob, but we found a legacy one\n");
> return -ENOEXEC;
> }
>
> - /* make sure we can access the GSC via the mei driver if we need it */
> + /*
> + * Newer meu blobs contain the old FW structure inside. If we found
> + * that, we can use it to load the legacy way.
> + */
> + if (!huc->loaded_via_gsc && fw_is_meu && !huc->fw.dma_start_offset) {
> + huc_err(huc," HW in legacy mode, but we have an incompatible meu blob\n");
Leading space in the message? MEU or meu?
> + return -ENOEXEC;
> + }
> +
> + /* make sure we can access the GSC if we need it */
> if (!(IS_ENABLED(CONFIG_INTEL_MEI_PXP) && IS_ENABLED(CONFIG_INTEL_MEI_GSC)) &&
> - fw_needs_gsc) {
> + !HAS_ENGINE(gt, GSC0) && huc->loaded_via_gsc) {
Should that be || !HAS_ENGINE ?
> huc_info(huc, "can't load due to missing MEI modules\n");
'missing MEI modules or GSC engine'?
> return -EIO;
> }
>
> - huc_dbg(huc, "loaded by GSC = %s\n", str_yes_no(fw_needs_gsc));
> + huc_dbg(huc, "loaded by GSC = %s\n", str_yes_no(huc->loaded_via_gsc));
>
> return 0;
> }
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.h b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
> index db555b3c1f56..345e1b9aa062 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
> @@ -39,6 +39,8 @@ struct intel_huc {
> struct notifier_block nb;
> enum intel_huc_delayed_load_status status;
> } delayed_load;
> +
> + bool loaded_via_gsc;
> };
>
> int intel_huc_sanitize(struct intel_huc *huc);
> @@ -73,7 +75,7 @@ static inline bool intel_huc_is_used(struct intel_huc *huc)
>
> static inline bool intel_huc_is_loaded_by_gsc(const struct intel_huc *huc)
> {
> - return huc->fw.loaded_via_gsc;
> + return huc->loaded_via_gsc;
> }
>
> static inline bool intel_huc_wait_required(struct intel_huc *huc)
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
> index f1c973e1c676..88ad2c322c4a 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
> @@ -34,7 +34,7 @@ int intel_huc_fw_get_binary_info(struct intel_uc_fw *huc_fw, const void *data, s
> size_t min_size = sizeof(*header);
> int i;
>
> - if (!huc_fw->loaded_via_gsc) {
> + if (!huc_fw->is_meu_binary) {
> huc_err(huc, "Invalid FW type MEU parsing!\n");
> return -EINVAL;
> }
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> index da6fcfe1d80a..3338dd45e78b 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> @@ -180,7 +180,7 @@ struct __packed uc_fw_blob {
> u8 major;
> u8 minor;
> u8 patch;
> - bool loaded_via_gsc;
> + bool is_meu_binary;
> };
>
> #define UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \
> @@ -189,9 +189,9 @@ struct __packed uc_fw_blob {
> .patch = patch_, \
> .path = path_,
>
> -#define UC_FW_BLOB_NEW(major_, minor_, patch_, gsc_, path_) \
> +#define UC_FW_BLOB_NEW(major_, minor_, patch_, meu_, path_) \
> { UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \
> - .legacy = false, .loaded_via_gsc = gsc_ }
> + .legacy = false, .is_meu_binary = meu_ }
Should we be changing the filename suffix to be 'meu' instead of 'gsc'?
John.
>
> #define UC_FW_BLOB_OLD(major_, minor_, patch_, path_) \
> { UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \
> @@ -296,7 +296,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
> uc_fw->file_wanted.path = blob->path;
> uc_fw->file_wanted.ver.major = blob->major;
> uc_fw->file_wanted.ver.minor = blob->minor;
> - uc_fw->loaded_via_gsc = blob->loaded_via_gsc;
> + uc_fw->is_meu_binary = blob->is_meu_binary;
> found = true;
> break;
> }
> @@ -680,7 +680,7 @@ static int check_fw_header(struct intel_gt *gt,
> if (uc_fw->type == INTEL_UC_FW_TYPE_GSC)
> return 0;
>
> - if (uc_fw->loaded_via_gsc)
> + if (uc_fw->is_meu_binary)
> err = check_gsc_manifest(gt, fw, uc_fw);
> else
> err = check_ccs_header(gt, fw, uc_fw);
> @@ -929,7 +929,7 @@ static int uc_fw_xfer(struct intel_uc_fw *uc_fw, u32 dst_offset, u32 dma_flags)
> intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
>
> /* Set the source address for the uCode */
> - offset = uc_fw->dummy.start;
> + offset = uc_fw->dummy.start + uc_fw->dma_start_offset;
> GEM_BUG_ON(upper_32_bits(offset) & 0xFFFF0000);
> intel_uncore_write_fw(uncore, DMA_ADDR_0_LOW, lower_32_bits(offset));
> intel_uncore_write_fw(uncore, DMA_ADDR_0_HIGH, upper_32_bits(offset));
> @@ -1168,7 +1168,7 @@ size_t intel_uc_fw_copy_rsa(struct intel_uc_fw *uc_fw, void *dst, u32 max_len)
> {
> struct intel_memory_region *mr = uc_fw->obj->mm.region;
> u32 size = min_t(u32, uc_fw->rsa_size, max_len);
> - u32 offset = sizeof(struct uc_css_header) + uc_fw->ucode_size;
> + u32 offset = uc_fw->dma_start_offset + sizeof(struct uc_css_header) + uc_fw->ucode_size;
> struct sgt_iter iter;
> size_t count = 0;
> int idx;
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
> index 2691bb6bde48..8f2306627332 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
> @@ -115,7 +115,7 @@ struct intel_uc_fw {
>
> u32 dma_start_offset;
>
> - bool loaded_via_gsc;
> + bool is_meu_binary;
> };
>
> /*
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Intel-gfx] [PATCH v2 5/8] drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 5/8] drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow Daniele Ceraolo Spurio
2023-05-13 0:51 ` Teres Alexis, Alan Previn
@ 2023-05-19 18:45 ` John Harrison
2023-05-20 0:17 ` Ceraolo Spurio, Daniele
1 sibling, 1 reply; 32+ messages in thread
From: John Harrison @ 2023-05-19 18:45 UTC (permalink / raw)
To: Daniele Ceraolo Spurio, intel-gfx; +Cc: dri-devel, Alan Previn
On 4/28/2023 11:58, Daniele Ceraolo Spurio wrote:
> Before we add the second step of the MTL HuC auth (via GSC), we need to
> have the ability to differentiate between them. To do so, the huc
> authentication check is duplicated for GuC and GSC auth, with meu
> binaries being considered fully authenticated only after the GSC auth
> step.
>
> To report the difference between the 2 auth steps, a new case is added
> to the HuC getparam. This way, the clear media driver can start
> submitting before full auth, as partial auth is enough for those
> workloads.
>
> v2: fix authentication status check for DG2
>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
> ---
> drivers/gpu/drm/i915/gt/uc/intel_huc.c | 94 +++++++++++++++++------
> drivers/gpu/drm/i915/gt/uc/intel_huc.h | 16 +++-
> drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 4 +-
> drivers/gpu/drm/i915/i915_reg.h | 3 +
> include/uapi/drm/i915_drm.h | 3 +-
> 5 files changed, 91 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> index c189ede4ef55..60f95d98e5fd 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> @@ -10,6 +10,7 @@
> #include "intel_huc.h"
> #include "intel_huc_print.h"
> #include "i915_drv.h"
> +#include "i915_reg.h"
>
> #include <linux/device/bus.h>
> #include <linux/mei_aux.h>
> @@ -106,7 +107,7 @@ static enum hrtimer_restart huc_delayed_load_timer_callback(struct hrtimer *hrti
> {
> struct intel_huc *huc = container_of(hrtimer, struct intel_huc, delayed_load.timer);
>
> - if (!intel_huc_is_authenticated(huc)) {
> + if (!intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC)) {
> if (huc->delayed_load.status == INTEL_HUC_WAITING_ON_GSC)
> huc_notice(huc, "timed out waiting for MEI GSC\n");
> else if (huc->delayed_load.status == INTEL_HUC_WAITING_ON_PXP)
> @@ -124,7 +125,7 @@ static void huc_delayed_load_start(struct intel_huc *huc)
> {
> ktime_t delay;
>
> - GEM_BUG_ON(intel_huc_is_authenticated(huc));
> + GEM_BUG_ON(intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC));
>
> /*
> * On resume we don't have to wait for MEI-GSC to be re-probed, but we
> @@ -284,13 +285,23 @@ void intel_huc_init_early(struct intel_huc *huc)
> }
>
> if (GRAPHICS_VER(i915) >= 11) {
> - huc->status.reg = GEN11_HUC_KERNEL_LOAD_INFO;
> - huc->status.mask = HUC_LOAD_SUCCESSFUL;
> - huc->status.value = HUC_LOAD_SUCCESSFUL;
> + huc->status[INTEL_HUC_AUTH_BY_GUC].reg = GEN11_HUC_KERNEL_LOAD_INFO;
> + huc->status[INTEL_HUC_AUTH_BY_GUC].mask = HUC_LOAD_SUCCESSFUL;
> + huc->status[INTEL_HUC_AUTH_BY_GUC].value = HUC_LOAD_SUCCESSFUL;
> } else {
> - huc->status.reg = HUC_STATUS2;
> - huc->status.mask = HUC_FW_VERIFIED;
> - huc->status.value = HUC_FW_VERIFIED;
> + huc->status[INTEL_HUC_AUTH_BY_GUC].reg = HUC_STATUS2;
> + huc->status[INTEL_HUC_AUTH_BY_GUC].mask = HUC_FW_VERIFIED;
> + huc->status[INTEL_HUC_AUTH_BY_GUC].value = HUC_FW_VERIFIED;
> + }
> +
> + if (IS_DG2(i915)) {
> + huc->status[INTEL_HUC_AUTH_BY_GSC].reg = GEN11_HUC_KERNEL_LOAD_INFO;
> + huc->status[INTEL_HUC_AUTH_BY_GSC].mask = HUC_LOAD_SUCCESSFUL;
> + huc->status[INTEL_HUC_AUTH_BY_GSC].value = HUC_LOAD_SUCCESSFUL;
> + } else {
> + huc->status[INTEL_HUC_AUTH_BY_GSC].reg = HECI_FWSTS5(MTL_GSC_HECI1_BASE);
> + huc->status[INTEL_HUC_AUTH_BY_GSC].mask = HECI_FWSTS5_HUC_AUTH_DONE;
> + huc->status[INTEL_HUC_AUTH_BY_GSC].value = HECI_FWSTS5_HUC_AUTH_DONE;
> }
> }
>
> @@ -381,28 +392,39 @@ void intel_huc_suspend(struct intel_huc *huc)
> delayed_huc_load_complete(huc);
> }
>
> -int intel_huc_wait_for_auth_complete(struct intel_huc *huc)
> +static const char *auth_mode_string(struct intel_huc *huc,
> + enum intel_huc_authentication_type type)
> +{
> + bool partial = !huc->loaded_via_gsc && huc->fw.is_meu_binary &&
> + type == INTEL_HUC_AUTH_BY_GUC;
partial = !loaded_via_gsc?
If it is not a GSC load then there is no two stage authentication, is
there? Does that mean the single stage auth does not count as 'all
workloads' even on platforms where two stage is not supported?
> +
> + return partial ? "clear media" : "all workloads";
> +}
> +
> +int intel_huc_wait_for_auth_complete(struct intel_huc *huc,
> + enum intel_huc_authentication_type type)
> {
> struct intel_gt *gt = huc_to_gt(huc);
> int ret;
>
> ret = __intel_wait_for_register(gt->uncore,
> - huc->status.reg,
> - huc->status.mask,
> - huc->status.value,
> + huc->status[type].reg,
> + huc->status[type].mask,
> + huc->status[type].value,
> 2, 50, NULL);
>
> /* mark the load process as complete even if the wait failed */
> delayed_huc_load_complete(huc);
>
> if (ret) {
> - huc_err(huc, "firmware not verified %pe\n", ERR_PTR(ret));
> + huc_err(huc, "firmware not verified for %s: %pe\n",
> + auth_mode_string(huc, type), ERR_PTR(ret));
> intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_LOAD_FAIL);
This means that if stage one works but stage two fails, we mark the HuC
as dead? So the previously working clear media support now stops working?
> return ret;
> }
>
> intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_RUNNING);
> - huc_info(huc, "authenticated!\n");
> + huc_info(huc, "authenticated for %s!\n", auth_mode_string(huc, type));
> return 0;
> }
>
> @@ -442,7 +464,7 @@ int intel_huc_auth(struct intel_huc *huc)
> }
>
> /* Check authentication status, it should be done by now */
> - ret = intel_huc_wait_for_auth_complete(huc);
> + ret = intel_huc_wait_for_auth_complete(huc, INTEL_HUC_AUTH_BY_GUC);
> if (ret)
> goto fail;
>
> @@ -453,16 +475,29 @@ int intel_huc_auth(struct intel_huc *huc)
> return ret;
> }
>
> -bool intel_huc_is_authenticated(struct intel_huc *huc)
> +bool intel_huc_is_authenticated(struct intel_huc *huc,
> + enum intel_huc_authentication_type type)
> {
> struct intel_gt *gt = huc_to_gt(huc);
> intel_wakeref_t wakeref;
> u32 status = 0;
>
> with_intel_runtime_pm(gt->uncore->rpm, wakeref)
> - status = intel_uncore_read(gt->uncore, huc->status.reg);
> + status = intel_uncore_read(gt->uncore, huc->status[type].reg);
>
> - return (status & huc->status.mask) == huc->status.value;
> + return (status & huc->status[type].mask) == huc->status[type].value;
> +}
> +
> +static bool huc_is_fully_authenticated(struct intel_huc *huc)
> +{
> + struct intel_uc_fw *huc_fw = &huc->fw;
> +
> + if (!huc_fw->is_meu_binary)
> + return intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GUC);
Is it not possible to load a non-MEU firmware on a GSC system? Don't we
just treat that as the legacy part within the MEU blob and load it for
clear media only via GuC auth? In which case, it is as 'fully
authenticated' as it is possible to be but it still can't process
protected media. So it should not count as 'fully authenticated'?
> + else if (intel_huc_is_loaded_by_gsc(huc) || HAS_ENGINE(huc_to_gt(huc), GSC0))
Why not &&? Is it possible to have loaded_by_gsc != HAS_ENGINE(gsc)?
Is it even worth making the engine check a part of the loaded_by_gsc()
helper?
> + return intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC);
> + else
> + return false;
> }
>
> /**
> @@ -477,7 +512,9 @@ bool intel_huc_is_authenticated(struct intel_huc *huc)
> */
> int intel_huc_check_status(struct intel_huc *huc)
> {
> - switch (__intel_uc_fw_status(&huc->fw)) {
> + struct intel_uc_fw *huc_fw = &huc->fw;
> +
> + switch (__intel_uc_fw_status(huc_fw)) {
> case INTEL_UC_FIRMWARE_NOT_SUPPORTED:
> return -ENODEV;
> case INTEL_UC_FIRMWARE_DISABLED:
> @@ -494,7 +531,17 @@ int intel_huc_check_status(struct intel_huc *huc)
> break;
> }
>
> - return intel_huc_is_authenticated(huc);
> + /*
> + * meu binaries loaded by GuC are first partially authenticated by GuC
> + * and then fully authenticated by GSC
> + */
> + if (huc_is_fully_authenticated(huc))
> + return 1; /* full auth */
> + else if (huc_fw->is_meu_binary && !huc->loaded_via_gsc &&
Why sometimes use the huc->loaded_via_gsc directly and sometimes use the
intel_huc_is_loaded_by_gsc() helper? Either way, I'm confused - isn't
that backwards? If the HuC is not loaded via GSC then it can't do two
stage auth and therefore cannot be partial? It is either fully
authenticated or not at all?
John.
> + intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GUC))
> + return 2; /* clear media only */
> + else
> + return 0;
> }
>
> static bool huc_has_delayed_load(struct intel_huc *huc)
> @@ -508,7 +555,10 @@ void intel_huc_update_auth_status(struct intel_huc *huc)
> if (!intel_uc_fw_is_loadable(&huc->fw))
> return;
>
> - if (intel_huc_is_authenticated(huc))
> + if (!huc->fw.is_meu_binary)
> + return;
> +
> + if (huc_is_fully_authenticated(huc))
> intel_uc_fw_change_status(&huc->fw,
> INTEL_UC_FIRMWARE_RUNNING);
> else if (huc_has_delayed_load(huc))
> @@ -541,5 +591,5 @@ void intel_huc_load_status(struct intel_huc *huc, struct drm_printer *p)
>
> with_intel_runtime_pm(gt->uncore->rpm, wakeref)
> drm_printf(p, "HuC status: 0x%08x\n",
> - intel_uncore_read(gt->uncore, huc->status.reg));
> + intel_uncore_read(gt->uncore, huc->status[INTEL_HUC_AUTH_BY_GUC].reg));
> }
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.h b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
> index 345e1b9aa062..adb063cd27a0 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
> @@ -22,6 +22,12 @@ enum intel_huc_delayed_load_status {
> INTEL_HUC_DELAYED_LOAD_ERROR,
> };
>
> +enum intel_huc_authentication_type {
> + INTEL_HUC_AUTH_BY_GUC = 0,
> + INTEL_HUC_AUTH_BY_GSC,
> + INTEL_HUC_AUTH_MAX_MODES
> +};
> +
> struct intel_huc {
> /* Generic uC firmware management */
> struct intel_uc_fw fw;
> @@ -31,7 +37,7 @@ struct intel_huc {
> i915_reg_t reg;
> u32 mask;
> u32 value;
> - } status;
> + } status[INTEL_HUC_AUTH_MAX_MODES];
>
> struct {
> struct i915_sw_fence fence;
> @@ -49,10 +55,12 @@ int intel_huc_init(struct intel_huc *huc);
> void intel_huc_fini(struct intel_huc *huc);
> void intel_huc_suspend(struct intel_huc *huc);
> int intel_huc_auth(struct intel_huc *huc);
> -int intel_huc_wait_for_auth_complete(struct intel_huc *huc);
> +int intel_huc_wait_for_auth_complete(struct intel_huc *huc,
> + enum intel_huc_authentication_type type);
> +bool intel_huc_is_authenticated(struct intel_huc *huc,
> + enum intel_huc_authentication_type type);
> int intel_huc_check_status(struct intel_huc *huc);
> void intel_huc_update_auth_status(struct intel_huc *huc);
> -bool intel_huc_is_authenticated(struct intel_huc *huc);
>
> void intel_huc_register_gsc_notifier(struct intel_huc *huc, struct bus_type *bus);
> void intel_huc_unregister_gsc_notifier(struct intel_huc *huc, struct bus_type *bus);
> @@ -81,7 +89,7 @@ static inline bool intel_huc_is_loaded_by_gsc(const struct intel_huc *huc)
> static inline bool intel_huc_wait_required(struct intel_huc *huc)
> {
> return intel_huc_is_used(huc) && intel_huc_is_loaded_by_gsc(huc) &&
> - !intel_huc_is_authenticated(huc);
> + !intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC);
> }
>
> void intel_huc_load_status(struct intel_huc *huc, struct drm_printer *p);
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
> index 88ad2c322c4a..3b8edaba97d2 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
> @@ -141,7 +141,7 @@ int intel_huc_fw_load_and_auth_via_gsc(struct intel_huc *huc)
> * component gets re-bound and this function called again. If so, just
> * mark the HuC as loaded.
> */
> - if (intel_huc_is_authenticated(huc)) {
> + if (intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC)) {
> intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_RUNNING);
> return 0;
> }
> @@ -154,7 +154,7 @@ int intel_huc_fw_load_and_auth_via_gsc(struct intel_huc *huc)
>
> intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_TRANSFERRED);
>
> - return intel_huc_wait_for_auth_complete(huc);
> + return intel_huc_wait_for_auth_complete(huc, INTEL_HUC_AUTH_BY_GSC);
> }
>
> /**
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index dde6e91055bd..1a62e73c3d9c 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -941,6 +941,9 @@
> #define HECI_H_GS1(base) _MMIO((base) + 0xc4c)
> #define HECI_H_GS1_ER_PREP REG_BIT(0)
>
> +#define HECI_FWSTS5(base) _MMIO(base + 0xc68)
> +#define HECI_FWSTS5_HUC_AUTH_DONE (1 << 19)
> +
> #define HSW_GTT_CACHE_EN _MMIO(0x4024)
> #define GTT_CACHE_EN_ALL 0xF0007FFF
> #define GEN7_WR_WATERMARK _MMIO(0x4028)
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index dba7c5a5b25e..43b8de42a94e 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -659,7 +659,8 @@ typedef struct drm_i915_irq_wait {
> * If the IOCTL is successful, the returned parameter will be set to one of the
> * following values:
> * * 0 if HuC firmware load is not complete,
> - * * 1 if HuC firmware is authenticated and running.
> + * * 1 if HuC firmware is loaded and fully authenticated,
> + * * 2 if HuC firmware is loaded and authenticated for clear media only
> */
> #define I915_PARAM_HUC_STATUS 42
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Intel-gfx] [PATCH v2] drm/i915/huc: Parse the GSC-enabled HuC binary
2023-05-17 21:04 ` John Harrison
@ 2023-05-19 20:35 ` Ceraolo Spurio, Daniele
0 siblings, 0 replies; 32+ messages in thread
From: Ceraolo Spurio, Daniele @ 2023-05-19 20:35 UTC (permalink / raw)
To: John Harrison, intel-gfx; +Cc: dri-devel, Alan Previn
On 5/17/2023 2:04 PM, John Harrison wrote:
> On 5/2/2023 08:27, Daniele Ceraolo Spurio wrote:
>> The new binaries that support the 2-step authentication have contain the
> have contain?
>
>> legacy-style binary, which we can use for loading the HuC via DMA. To
>> find out where this is located in the image, we need to parse the meu
> 'meu manifest' needs some kind of explanation. 'meu' is mentioned many
> times but nothing ever seems to explain what it is or where it comes
> from. Also, sometimes it is capitalised and sometimes not.
MEU is the name of the tool that packages the binary. I think I'll
switch it to gsc_binary instead of meu_binary, so we don't have
references to non-public tools.
>
>> manifest of the GSC binary. The manifest consist of a partition header
>> followed by entries, one of which contains the offset we're looking for.
>> Note that the DG2 GSC binary contains entries with the same names, but
>> it doesn't contain a full legacy binary, so we need to skip assigning
>> the dma offset in that case (which we can do by checking the ccs).
>> Also, since we're now parsing the entries, we can extract the HuC
>> version that way instead of using hardcoded offsets.
>>
>> Note that the meu structure will be re-used for parsing the GSC binary,
>> so they've been added in their own header.
>>
>> v2: fix structure names to match meu defines (s/CPT/CPD/), update commit
>> message, check ccs validity, drop old version location defines.
>>
>> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
>> Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
>> ---
>> .../drm/i915/gt/uc/intel_gsc_meu_headers.h | 74 ++++++++++
>> drivers/gpu/drm/i915/gt/uc/intel_huc.c | 11 +-
>> drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 135 ++++++++++++++++++
>> drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h | 5 +-
>> drivers/gpu/drm/i915/gt/uc/intel_huc_print.h | 21 +++
>> drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 71 +++++----
>> drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h | 2 +
>> drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h | 6 -
>> 8 files changed, 272 insertions(+), 53 deletions(-)
>> create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
>> create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_huc_print.h
>>
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
>> b/drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
>> new file mode 100644
>> index 000000000000..d55a66202576
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
>> @@ -0,0 +1,74 @@
>> +/* SPDX-License-Identifier: MIT */
>> +/*
>> + * Copyright © 2023 Intel Corporation
>> + */
>> +
>> +#ifndef _INTEL_GSC_MEU_H_
>> +#define _INTEL_GSC_MEU_H_
>> +
>> +#include <linux/types.h>
>> +
>> +/* Code partition directory (CPD) structures */
>> +struct intel_gsc_cpd_header_v2 {
>> + u32 header_marker;
>> +#define INTEL_GSC_CPD_HEADER_MARKER 0x44504324
>> +
>> + u32 num_of_entries;
>> + u8 header_version;
>> + u8 entry_version;
>> + u8 header_length; /* in bytes */
>> + u8 flags;
>> + u32 partition_name;
>> + u32 crc32;
>> +} __packed;
>> +
>> +struct intel_gsc_cpd_entry {
>> + u8 name[12];
>> +
>> + /*
>> + * Bits 0-24: offset from the beginning of the code partition
>> + * Bit 25: huffman compressed
>> + * Bits 26-31: reserved
>> + */
>> + u32 offset;
>> +#define INTEL_GSC_CPD_ENTRY_OFFSET_MASK GENMASK(24, 0)
>> +#define INTEL_GSC_CPD_ENTRY_HUFFMAN_COMP BIT(25)
>> +
>> + /*
>> + * Module/Item length, in bytes. For Huffman-compressed modules,
>> this
>> + * refers to the uncompressed size. For software-compressed
>> modules,
>> + * this refers to the compressed size.
>> + */
>> + u32 length;
>> +
>> + u8 reserved[4];
>> +} __packed;
>> +
>> +struct intel_gsc_meu_version {
>> + u16 major;
>> + u16 minor;
>> + u16 hotfix;
>> + u16 build;
>> +} __packed;
>> +
>> +struct intel_gsc_manifest_header {
>> + u32 header_type; /* 0x4 for manifest type */
>> + u32 header_length; /* in dwords */
>> + u32 header_version;
>> + u32 flags;
>> + u32 vendor;
>> + u32 date;
>> + u32 size; /* In dwords, size of entire manifest (header +
>> extensions) */
>> + u32 header_id;
>> + u32 internal_data;
>> + struct intel_gsc_meu_version fw_version;
>> + u32 security_version;
>> + struct intel_gsc_meu_version meu_kit_version;
>> + u32 meu_manifest_version;
>> + u8 general_data[4];
>> + u8 reserved3[56];
>> + u32 modulus_size; /* in dwords */
>> + u32 exponent_size; /* in dwords */
>> +} __packed;
>> +
>> +#endif
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>> b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>> index 9721761373fb..062ff914b274 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>> @@ -6,23 +6,14 @@
>> #include <linux/types.h>
>> #include "gt/intel_gt.h"
>> -#include "gt/intel_gt_print.h"
>> #include "intel_guc_reg.h"
>> #include "intel_huc.h"
>> +#include "intel_huc_print.h"
>> #include "i915_drv.h"
>> #include <linux/device/bus.h>
>> #include <linux/mei_aux.h>
>> -#define huc_printk(_huc, _level, _fmt, ...) \
>> - gt_##_level(huc_to_gt(_huc), "HuC: " _fmt, ##__VA_ARGS__)
>> -#define huc_err(_huc, _fmt, ...) huc_printk((_huc), err, _fmt,
>> ##__VA_ARGS__)
>> -#define huc_warn(_huc, _fmt, ...) huc_printk((_huc), warn, _fmt,
>> ##__VA_ARGS__)
>> -#define huc_notice(_huc, _fmt, ...) huc_printk((_huc), notice,
>> _fmt, ##__VA_ARGS__)
>> -#define huc_info(_huc, _fmt, ...) huc_printk((_huc), info, _fmt,
>> ##__VA_ARGS__)
>> -#define huc_dbg(_huc, _fmt, ...) huc_printk((_huc), dbg, _fmt,
>> ##__VA_ARGS__)
>> -#define huc_probe_error(_huc, _fmt, ...) huc_printk((_huc),
>> probe_error, _fmt, ##__VA_ARGS__)
>> -
>> /**
>> * DOC: HuC
>> *
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
>> b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
>> index 534b0aa43316..0ec48c2cd749 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
>> @@ -5,11 +5,146 @@
>> #include "gt/intel_gsc.h"
>> #include "gt/intel_gt.h"
>> +#include "intel_gsc_meu_headers.h"
>> #include "intel_huc.h"
>> #include "intel_huc_fw.h"
>> +#include "intel_huc_print.h"
>> #include "i915_drv.h"
>> #include "pxp/intel_pxp_huc.h"
>> +static void get_version_from_meu_manifest(struct intel_uc_fw_ver
>> *ver, const void *data)
>> +{
>> + const struct intel_gsc_manifest_header *manifest = data;
>> +
>> + ver->major = manifest->fw_version.major;
>> + ver->minor = manifest->fw_version.minor;
>> + ver->patch = manifest->fw_version.hotfix;
>> +}
>> +
>> +static bool css_valid(const void *data, size_t size)
>> +{
>> + const struct uc_css_header *css = data;
>> +
>> + if (unlikely(size < sizeof(struct uc_css_header)))
>> + return false;
>> +
>> + if (css->module_type != 0x6)
>> + return false;
>> +
>> + if (css->module_vendor != PCI_VENDOR_ID_INTEL)
>> + return false;
>> +
>> + return true;
>> +}
>> +
>> +static inline u32 entry_offset(const struct intel_gsc_cpd_entry *entry)
>> +{
>> + return entry->offset & INTEL_GSC_CPD_ENTRY_OFFSET_MASK;
>> +}
>> +
>> +int intel_huc_fw_get_binary_info(struct intel_uc_fw *huc_fw, const
>> void *data, size_t size)
>> +{
>> + struct intel_huc *huc = container_of(huc_fw, struct intel_huc, fw);
>> + const struct intel_gsc_cpd_header_v2 *header = data;
>> + const struct intel_gsc_cpd_entry *entry;
>> + size_t min_size = sizeof(*header);
>> + int i;
>> +
>> + if (!huc_fw->loaded_via_gsc) {
>> + huc_err(huc, "Invalid FW type MEU parsing!\n");
> Not sure what this message is meant to be saying?
I'll reword it.
Daniele
>
> John.
>
>> + return -EINVAL;
>> + }
>> +
>> + if (size < sizeof(*header)) {
>> + huc_err(huc, "MEU FW too small! %zu < %zu\n", size, min_size);
>> + return -ENODATA;
>> + }
>> +
>> + /*
>> + * The meu HuC binary starts with a directory header, followed by a
>> + * series of entries. Each entry is identified by a name and
>> points to
>> + * a specific section of the binary containing the relevant data.
>> + * The entries we're interested in are
>> + * - "HUCP.man": points to the GSC manifest header for the HuC,
>> which
>> + * contains the version info.
>> + * - "huc_fw": points to the legacy-style binary that can be
>> used for
>> + * load via the DMA. This entry only contains a
>> valid CSS
>> + * on binaries for platforms that support 2-step HuC
>> load
>> + * via dma and auth via GSC (like MTL).
>> + *
>> + * --------------------------------------------------
>> + * [ intel_gsc_cpd_header_v2 ]
>> + * --------------------------------------------------
>> + * [ intel_gsc_cpd_entry[] ]
>> + * [ entry1 ]
>> + * [ ... ]
>> + * [ entryX ]
>> + * [ "HUCP.man" ]
>> + * [ ... ]
>> + * [ offset >----------------------------]------o
>> + * [ ... ] |
>> + * [ entryY ] |
>> + * [ "huc_fw" ] |
>> + * [ ... ] |
>> + * [ offset >----------------------------]----------o
>> + * -------------------------------------------------- | |
>> + * | |
>> + * -------------------------------------------------- | |
>> + * [ intel_gsc_manifest_header ]<-----o |
>> + * [ ... ] |
>> + * [ intel_gsc_meu_version fw_version ] |
>> + * [ ... ] |
>> + * -------------------------------------------------- |
>> + * |
>> + * -------------------------------------------------- |
>> + * [ data[] ]<---------o
>> + * [ ... ]
>> + * [ ... ]
>> + * --------------------------------------------------
>> + */
>> +
>> + if (header->header_marker != INTEL_GSC_CPD_HEADER_MARKER) {
>> + huc_err(huc, "invalid marker for meu CPD header: 0x%08x!\n",
>> + header->header_marker);
>> + return -EINVAL;
>> + }
>> +
>> + /* we only have binaries with header v2 and entry v1 for now */
>> + if (header->header_version != 2 || header->entry_version != 1) {
>> + huc_err(huc, "invalid meu CPD header/entry version %u:%u!\n",
>> + header->header_version, header->entry_version);
>> + return -EINVAL;
>> + }
>> +
>> + if (header->header_length < sizeof(struct
>> intel_gsc_cpd_header_v2)) {
>> + huc_err(huc, "invalid meu CPD header length %u!\n",
>> + header->header_length);
>> + return -EINVAL;
>> + }
>> +
>> + min_size = header->header_length + sizeof(*entry) *
>> header->num_of_entries;
>> + if (size < min_size) {
>> + huc_err(huc, "MEU FW too small! %zu < %zu\n", size, min_size);
>> + return -ENODATA;
>> + }
>> +
>> + entry = data + header->header_length;
>> +
>> + for (i = 0; i < header->num_of_entries; i++, entry++) {
>> + if (strcmp(entry->name, "HUCP.man") == 0)
>> + get_version_from_meu_manifest(&huc_fw->file_selected.ver,
>> + data + entry_offset(entry));
>> +
>> + if (strcmp(entry->name, "huc_fw") == 0) {
>> + u32 offset = entry_offset(entry);
>> + if (offset < size && css_valid(data + offset, size -
>> offset))
>> + huc_fw->dma_start_offset = offset;
>> + }
>> + }
>> +
>> + return 0;
>> +}
>> +
>> int intel_huc_fw_load_and_auth_via_gsc(struct intel_huc *huc)
>> {
>> int ret;
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
>> b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
>> index db42e238b45f..0999ffe6f962 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
>> @@ -7,8 +7,11 @@
>> #define _INTEL_HUC_FW_H_
>> struct intel_huc;
>> +struct intel_uc_fw;
>> +
>> +#include <linux/types.h>
>> int intel_huc_fw_load_and_auth_via_gsc(struct intel_huc *huc);
>> int intel_huc_fw_upload(struct intel_huc *huc);
>> -
>> +int intel_huc_fw_get_binary_info(struct intel_uc_fw *huc_fw, const
>> void *data, size_t size);
>> #endif
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_print.h
>> b/drivers/gpu/drm/i915/gt/uc/intel_huc_print.h
>> new file mode 100644
>> index 000000000000..915d310ee1df
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_print.h
>> @@ -0,0 +1,21 @@
>> +/* SPDX-License-Identifier: MIT */
>> +/*
>> + * Copyright © 2023 Intel Corporation
>> + */
>> +
>> +#ifndef __INTEL_HUC_PRINT__
>> +#define __INTEL_HUC_PRINT__
>> +
>> +#include "gt/intel_gt.h"
>> +#include "gt/intel_gt_print.h"
>> +
>> +#define huc_printk(_huc, _level, _fmt, ...) \
>> + gt_##_level(huc_to_gt(_huc), "HuC: " _fmt, ##__VA_ARGS__)
>> +#define huc_err(_huc, _fmt, ...) huc_printk((_huc), err, _fmt,
>> ##__VA_ARGS__)
>> +#define huc_warn(_huc, _fmt, ...) huc_printk((_huc), warn, _fmt,
>> ##__VA_ARGS__)
>> +#define huc_notice(_huc, _fmt, ...) huc_printk((_huc), notice,
>> _fmt, ##__VA_ARGS__)
>> +#define huc_info(_huc, _fmt, ...) huc_printk((_huc), info, _fmt,
>> ##__VA_ARGS__)
>> +#define huc_dbg(_huc, _fmt, ...) huc_printk((_huc), dbg, _fmt,
>> ##__VA_ARGS__)
>> +#define huc_probe_error(_huc, _fmt, ...) huc_printk((_huc),
>> probe_error, _fmt, ##__VA_ARGS__)
>> +
>> +#endif /* __INTEL_HUC_PRINT__ */
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> index 03f0b258aea7..da6fcfe1d80a 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> @@ -492,33 +492,6 @@ static void __force_fw_fetch_failures(struct
>> intel_uc_fw *uc_fw, int e)
>> }
>> }
>> -static int check_gsc_manifest(struct intel_gt *gt,
>> - const struct firmware *fw,
>> - struct intel_uc_fw *uc_fw)
>> -{
>> - u32 *dw = (u32 *)fw->data;
>> - u32 version_hi, version_lo;
>> - size_t min_size;
>> -
>> - /* Check the size of the blob before examining buffer contents */
>> - min_size = sizeof(u32) * (HUC_GSC_VERSION_LO_DW + 1);
>> - if (unlikely(fw->size < min_size)) {
>> - gt_warn(gt, "%s firmware %s: invalid size: %zu < %zu\n",
>> - intel_uc_fw_type_repr(uc_fw->type),
>> uc_fw->file_selected.path,
>> - fw->size, min_size);
>> - return -ENODATA;
>> - }
>> -
>> - version_hi = dw[HUC_GSC_VERSION_HI_DW];
>> - version_lo = dw[HUC_GSC_VERSION_LO_DW];
>> -
>> - uc_fw->file_selected.ver.major =
>> FIELD_GET(HUC_GSC_MAJOR_VER_HI_MASK, version_hi);
>> - uc_fw->file_selected.ver.minor =
>> FIELD_GET(HUC_GSC_MINOR_VER_HI_MASK, version_hi);
>> - uc_fw->file_selected.ver.patch =
>> FIELD_GET(HUC_GSC_PATCH_VER_LO_MASK, version_lo);
>> -
>> - return 0;
>> -}
>> -
>> static void uc_unpack_css_version(struct intel_uc_fw_ver *ver, u32
>> css_value)
>> {
>> /* Get version numbers from the CSS header */
>> @@ -575,22 +548,22 @@ static void guc_read_css_info(struct
>> intel_uc_fw *uc_fw, struct uc_css_header *c
>> uc_fw->private_data_size = css->private_data_size;
>> }
>> -static int check_ccs_header(struct intel_gt *gt,
>> - const struct firmware *fw,
>> - struct intel_uc_fw *uc_fw)
>> +static int __check_ccs_header(struct intel_gt *gt,
>> + const void *fw_data, size_t fw_size,
>> + struct intel_uc_fw *uc_fw)
>> {
>> struct uc_css_header *css;
>> size_t size;
>> /* Check the size of the blob before examining buffer
>> contents */
>> - if (unlikely(fw->size < sizeof(struct uc_css_header))) {
>> + if (unlikely(fw_size < sizeof(struct uc_css_header))) {
>> gt_warn(gt, "%s firmware %s: invalid size: %zu < %zu\n",
>> intel_uc_fw_type_repr(uc_fw->type),
>> uc_fw->file_selected.path,
>> - fw->size, sizeof(struct uc_css_header));
>> + fw_size, sizeof(struct uc_css_header));
>> return -ENODATA;
>> }
>> - css = (struct uc_css_header *)fw->data;
>> + css = (struct uc_css_header *)fw_data;
>> /* Check integrity of size values inside CSS header */
>> size = (css->header_size_dw - css->key_size_dw -
>> css->modulus_size_dw -
>> @@ -598,7 +571,7 @@ static int check_ccs_header(struct intel_gt *gt,
>> if (unlikely(size != sizeof(struct uc_css_header))) {
>> gt_warn(gt, "%s firmware %s: unexpected header size: %zu !=
>> %zu\n",
>> intel_uc_fw_type_repr(uc_fw->type),
>> uc_fw->file_selected.path,
>> - fw->size, sizeof(struct uc_css_header));
>> + fw_size, sizeof(struct uc_css_header));
>> return -EPROTO;
>> }
>> @@ -610,10 +583,10 @@ static int check_ccs_header(struct intel_gt *gt,
>> /* At least, it should have header, uCode and RSA. Size of
>> all three. */
>> size = sizeof(struct uc_css_header) + uc_fw->ucode_size +
>> uc_fw->rsa_size;
>> - if (unlikely(fw->size < size)) {
>> + if (unlikely(fw_size < size)) {
>> gt_warn(gt, "%s firmware %s: invalid size: %zu < %zu\n",
>> intel_uc_fw_type_repr(uc_fw->type),
>> uc_fw->file_selected.path,
>> - fw->size, size);
>> + fw_size, size);
>> return -ENOEXEC;
>> }
>> @@ -634,6 +607,32 @@ static int check_ccs_header(struct intel_gt *gt,
>> return 0;
>> }
>> +static int check_gsc_manifest(struct intel_gt *gt,
>> + const struct firmware *fw,
>> + struct intel_uc_fw *uc_fw)
>> +{
>> + if (uc_fw->type != INTEL_UC_FW_TYPE_HUC) {
>> + gt_err(gt, "trying to MEU-parse a non-HuC binary");
>> + return -EINVAL;
>> + }
>> +
>> + intel_huc_fw_get_binary_info(uc_fw, fw->data, fw->size);
>> +
>> + if (uc_fw->dma_start_offset) {
>> + u32 delta = uc_fw->dma_start_offset;
>> + __check_ccs_header(gt, fw->data + delta, fw->size - delta,
>> uc_fw);
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int check_ccs_header(struct intel_gt *gt,
>> + const struct firmware *fw,
>> + struct intel_uc_fw *uc_fw)
>> +{
>> + return __check_ccs_header(gt, fw->data, fw->size, uc_fw);
>> +}
>> +
>> static bool is_ver_8bit(struct intel_uc_fw_ver *ver)
>> {
>> return ver->major < 0xFF && ver->minor < 0xFF && ver->patch <
>> 0xFF;
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
>> b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
>> index 26a9d6e0dc00..2691bb6bde48 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
>> @@ -113,6 +113,8 @@ struct intel_uc_fw {
>> u32 ucode_size;
>> u32 private_data_size;
>> + u32 dma_start_offset;
>> +
>> bool loaded_via_gsc;
>> };
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h
>> b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h
>> index 646fa8aa6cf1..7fe405126249 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h
>> @@ -84,10 +84,4 @@ struct uc_css_header {
>> } __packed;
>> static_assert(sizeof(struct uc_css_header) == 128);
>> -#define HUC_GSC_VERSION_HI_DW 44
>> -#define HUC_GSC_MAJOR_VER_HI_MASK (0xFF << 0)
>> -#define HUC_GSC_MINOR_VER_HI_MASK (0xFF << 16)
>> -#define HUC_GSC_VERSION_LO_DW 45
>> -#define HUC_GSC_PATCH_VER_LO_MASK (0xFF << 0)
>> -
>> #endif /* _INTEL_UC_FW_ABI_H */
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Intel-gfx] [PATCH v2 4/8] drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so
2023-05-19 18:03 ` John Harrison
@ 2023-05-20 0:05 ` Ceraolo Spurio, Daniele
0 siblings, 0 replies; 32+ messages in thread
From: Ceraolo Spurio, Daniele @ 2023-05-20 0:05 UTC (permalink / raw)
To: John Harrison, intel-gfx; +Cc: dri-devel, Alan Previn
On 5/19/2023 11:03 AM, John Harrison wrote:
> On 4/28/2023 11:58, Daniele Ceraolo Spurio wrote:
>> In the previous patch we extracted the offset of the legacy-style HuC
>> binary located within the GSC-enabled blob, so now we can use that to
>> load the HuC via DMA if the fuse is set that way.
>> Note that we now need to differentiate between "GSC-enabled binary" and
>> "loaded by GSC", so the former case has been renamed to "MEU binary" for
>> clarity, while the latter is now based on the fuse instead of the binary
>> format. This way, all the legacy load paths are automatically taken
>> (including the auth by GuC) without having to implement further code
>> changes.
>>
>> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
>> Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
>> ---
>> drivers/gpu/drm/i915/gt/uc/intel_huc.c | 27 ++++++++++++++---------
>> drivers/gpu/drm/i915/gt/uc/intel_huc.h | 4 +++-
>> drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 2 +-
>> drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 14 ++++++------
>> drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h | 2 +-
>> 5 files changed, 29 insertions(+), 20 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>> b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>> index 062ff914b274..c189ede4ef55 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>> @@ -298,31 +298,38 @@ void intel_huc_init_early(struct intel_huc *huc)
>> static int check_huc_loading_mode(struct intel_huc *huc)
>> {
>> struct intel_gt *gt = huc_to_gt(huc);
>> - bool fw_needs_gsc = intel_huc_is_loaded_by_gsc(huc);
>> - bool hw_uses_gsc = false;
>> + bool fw_is_meu = huc->fw.is_meu_binary;
>> /*
>> * The fuse for HuC load via GSC is only valid on platforms
>> that have
>> * GuC deprivilege.
>> */
>> if (HAS_GUC_DEPRIVILEGE(gt->i915))
>> - hw_uses_gsc = intel_uncore_read(gt->uncore,
>> GUC_SHIM_CONTROL2) &
>> - GSC_LOADS_HUC;
>> + huc->loaded_via_gsc = intel_uncore_read(gt->uncore,
>> GUC_SHIM_CONTROL2) &
>> + GSC_LOADS_HUC;
>> - if (fw_needs_gsc != hw_uses_gsc) {
>> - huc_err(huc, "mismatch between FW (%s) and HW (%s) load
>> modes\n",
>> - HUC_LOAD_MODE_STRING(fw_needs_gsc),
>> HUC_LOAD_MODE_STRING(hw_uses_gsc));
>> + if (huc->loaded_via_gsc && !fw_is_meu) {
>> + huc_err(huc, "HW requires a MEU blob, but we found a legacy
>> one\n");
>> return -ENOEXEC;
>> }
>> - /* make sure we can access the GSC via the mei driver if we
>> need it */
>> + /*
>> + * Newer meu blobs contain the old FW structure inside. If we found
>> + * that, we can use it to load the legacy way.
>> + */
>> + if (!huc->loaded_via_gsc && fw_is_meu &&
>> !huc->fw.dma_start_offset) {
>> + huc_err(huc," HW in legacy mode, but we have an incompatible
>> meu blob\n");
> Leading space in the message? MEU or meu?
As mentioned in the reply on the previous patch, I'm going to drop the
meu tag.
>
>> + return -ENOEXEC;
>> + }
>> +
>> + /* make sure we can access the GSC if we need it */
>> if (!(IS_ENABLED(CONFIG_INTEL_MEI_PXP) &&
>> IS_ENABLED(CONFIG_INTEL_MEI_GSC)) &&
>> - fw_needs_gsc) {
>> + !HAS_ENGINE(gt, GSC0) && huc->loaded_via_gsc) {
> Should that be || !HAS_ENGINE ?
No. The config check is for DG2, while the engine check is for MTL+. We
need one of the two to be true, not both, so we only fail if both are false.
>
>> huc_info(huc, "can't load due to missing MEI modules\n");
> 'missing MEI modules or GSC engine'?
I'll update it to "missing requirements" or something like that.
>
>> return -EIO;
>> }
>> - huc_dbg(huc, "loaded by GSC = %s\n", str_yes_no(fw_needs_gsc));
>> + huc_dbg(huc, "loaded by GSC = %s\n",
>> str_yes_no(huc->loaded_via_gsc));
>> return 0;
>> }
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.h
>> b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
>> index db555b3c1f56..345e1b9aa062 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.h
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
>> @@ -39,6 +39,8 @@ struct intel_huc {
>> struct notifier_block nb;
>> enum intel_huc_delayed_load_status status;
>> } delayed_load;
>> +
>> + bool loaded_via_gsc;
>> };
>> int intel_huc_sanitize(struct intel_huc *huc);
>> @@ -73,7 +75,7 @@ static inline bool intel_huc_is_used(struct
>> intel_huc *huc)
>> static inline bool intel_huc_is_loaded_by_gsc(const struct
>> intel_huc *huc)
>> {
>> - return huc->fw.loaded_via_gsc;
>> + return huc->loaded_via_gsc;
>> }
>> static inline bool intel_huc_wait_required(struct intel_huc *huc)
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
>> b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
>> index f1c973e1c676..88ad2c322c4a 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
>> @@ -34,7 +34,7 @@ int intel_huc_fw_get_binary_info(struct intel_uc_fw
>> *huc_fw, const void *data, s
>> size_t min_size = sizeof(*header);
>> int i;
>> - if (!huc_fw->loaded_via_gsc) {
>> + if (!huc_fw->is_meu_binary) {
>> huc_err(huc, "Invalid FW type MEU parsing!\n");
>> return -EINVAL;
>> }
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> index da6fcfe1d80a..3338dd45e78b 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>> @@ -180,7 +180,7 @@ struct __packed uc_fw_blob {
>> u8 major;
>> u8 minor;
>> u8 patch;
>> - bool loaded_via_gsc;
>> + bool is_meu_binary;
>> };
>> #define UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \
>> @@ -189,9 +189,9 @@ struct __packed uc_fw_blob {
>> .patch = patch_, \
>> .path = path_,
>> -#define UC_FW_BLOB_NEW(major_, minor_, patch_, gsc_, path_) \
>> +#define UC_FW_BLOB_NEW(major_, minor_, patch_, meu_, path_) \
>> { UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \
>> - .legacy = false, .loaded_via_gsc = gsc_ }
>> + .legacy = false, .is_meu_binary = meu_ }
> Should we be changing the filename suffix to be 'meu' instead of 'gsc'?
The dg2 filename already used gsc and I don't want to change that. As
already mentioned, I'll just drop the meu tag.
Daniele
>
> John.
>
>> #define UC_FW_BLOB_OLD(major_, minor_, patch_, path_) \
>> { UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \
>> @@ -296,7 +296,7 @@ __uc_fw_auto_select(struct drm_i915_private
>> *i915, struct intel_uc_fw *uc_fw)
>> uc_fw->file_wanted.path = blob->path;
>> uc_fw->file_wanted.ver.major = blob->major;
>> uc_fw->file_wanted.ver.minor = blob->minor;
>> - uc_fw->loaded_via_gsc = blob->loaded_via_gsc;
>> + uc_fw->is_meu_binary = blob->is_meu_binary;
>> found = true;
>> break;
>> }
>> @@ -680,7 +680,7 @@ static int check_fw_header(struct intel_gt *gt,
>> if (uc_fw->type == INTEL_UC_FW_TYPE_GSC)
>> return 0;
>> - if (uc_fw->loaded_via_gsc)
>> + if (uc_fw->is_meu_binary)
>> err = check_gsc_manifest(gt, fw, uc_fw);
>> else
>> err = check_ccs_header(gt, fw, uc_fw);
>> @@ -929,7 +929,7 @@ static int uc_fw_xfer(struct intel_uc_fw *uc_fw,
>> u32 dst_offset, u32 dma_flags)
>> intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
>> /* Set the source address for the uCode */
>> - offset = uc_fw->dummy.start;
>> + offset = uc_fw->dummy.start + uc_fw->dma_start_offset;
>> GEM_BUG_ON(upper_32_bits(offset) & 0xFFFF0000);
>> intel_uncore_write_fw(uncore, DMA_ADDR_0_LOW,
>> lower_32_bits(offset));
>> intel_uncore_write_fw(uncore, DMA_ADDR_0_HIGH,
>> upper_32_bits(offset));
>> @@ -1168,7 +1168,7 @@ size_t intel_uc_fw_copy_rsa(struct intel_uc_fw
>> *uc_fw, void *dst, u32 max_len)
>> {
>> struct intel_memory_region *mr = uc_fw->obj->mm.region;
>> u32 size = min_t(u32, uc_fw->rsa_size, max_len);
>> - u32 offset = sizeof(struct uc_css_header) + uc_fw->ucode_size;
>> + u32 offset = uc_fw->dma_start_offset + sizeof(struct
>> uc_css_header) + uc_fw->ucode_size;
>> struct sgt_iter iter;
>> size_t count = 0;
>> int idx;
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
>> b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
>> index 2691bb6bde48..8f2306627332 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
>> @@ -115,7 +115,7 @@ struct intel_uc_fw {
>> u32 dma_start_offset;
>> - bool loaded_via_gsc;
>> + bool is_meu_binary;
>> };
>> /*
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Intel-gfx] [PATCH v2 5/8] drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow
2023-05-19 18:45 ` John Harrison
@ 2023-05-20 0:17 ` Ceraolo Spurio, Daniele
0 siblings, 0 replies; 32+ messages in thread
From: Ceraolo Spurio, Daniele @ 2023-05-20 0:17 UTC (permalink / raw)
To: John Harrison, intel-gfx; +Cc: dri-devel, Alan Previn
On 5/19/2023 11:45 AM, John Harrison wrote:
> On 4/28/2023 11:58, Daniele Ceraolo Spurio wrote:
>> Before we add the second step of the MTL HuC auth (via GSC), we need to
>> have the ability to differentiate between them. To do so, the huc
>> authentication check is duplicated for GuC and GSC auth, with meu
>> binaries being considered fully authenticated only after the GSC auth
>> step.
>>
>> To report the difference between the 2 auth steps, a new case is added
>> to the HuC getparam. This way, the clear media driver can start
>> submitting before full auth, as partial auth is enough for those
>> workloads.
>>
>> v2: fix authentication status check for DG2
>>
>> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
>> Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
>> ---
>> drivers/gpu/drm/i915/gt/uc/intel_huc.c | 94 +++++++++++++++++------
>> drivers/gpu/drm/i915/gt/uc/intel_huc.h | 16 +++-
>> drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 4 +-
>> drivers/gpu/drm/i915/i915_reg.h | 3 +
>> include/uapi/drm/i915_drm.h | 3 +-
>> 5 files changed, 91 insertions(+), 29 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>> b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>> index c189ede4ef55..60f95d98e5fd 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
>> @@ -10,6 +10,7 @@
>> #include "intel_huc.h"
>> #include "intel_huc_print.h"
>> #include "i915_drv.h"
>> +#include "i915_reg.h"
>> #include <linux/device/bus.h>
>> #include <linux/mei_aux.h>
>> @@ -106,7 +107,7 @@ static enum hrtimer_restart
>> huc_delayed_load_timer_callback(struct hrtimer *hrti
>> {
>> struct intel_huc *huc = container_of(hrtimer, struct intel_huc,
>> delayed_load.timer);
>> - if (!intel_huc_is_authenticated(huc)) {
>> + if (!intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC)) {
>> if (huc->delayed_load.status == INTEL_HUC_WAITING_ON_GSC)
>> huc_notice(huc, "timed out waiting for MEI GSC\n");
>> else if (huc->delayed_load.status == INTEL_HUC_WAITING_ON_PXP)
>> @@ -124,7 +125,7 @@ static void huc_delayed_load_start(struct
>> intel_huc *huc)
>> {
>> ktime_t delay;
>> - GEM_BUG_ON(intel_huc_is_authenticated(huc));
>> + GEM_BUG_ON(intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC));
>> /*
>> * On resume we don't have to wait for MEI-GSC to be re-probed,
>> but we
>> @@ -284,13 +285,23 @@ void intel_huc_init_early(struct intel_huc *huc)
>> }
>> if (GRAPHICS_VER(i915) >= 11) {
>> - huc->status.reg = GEN11_HUC_KERNEL_LOAD_INFO;
>> - huc->status.mask = HUC_LOAD_SUCCESSFUL;
>> - huc->status.value = HUC_LOAD_SUCCESSFUL;
>> + huc->status[INTEL_HUC_AUTH_BY_GUC].reg =
>> GEN11_HUC_KERNEL_LOAD_INFO;
>> + huc->status[INTEL_HUC_AUTH_BY_GUC].mask = HUC_LOAD_SUCCESSFUL;
>> + huc->status[INTEL_HUC_AUTH_BY_GUC].value = HUC_LOAD_SUCCESSFUL;
>> } else {
>> - huc->status.reg = HUC_STATUS2;
>> - huc->status.mask = HUC_FW_VERIFIED;
>> - huc->status.value = HUC_FW_VERIFIED;
>> + huc->status[INTEL_HUC_AUTH_BY_GUC].reg = HUC_STATUS2;
>> + huc->status[INTEL_HUC_AUTH_BY_GUC].mask = HUC_FW_VERIFIED;
>> + huc->status[INTEL_HUC_AUTH_BY_GUC].value = HUC_FW_VERIFIED;
>> + }
>> +
>> + if (IS_DG2(i915)) {
>> + huc->status[INTEL_HUC_AUTH_BY_GSC].reg =
>> GEN11_HUC_KERNEL_LOAD_INFO;
>> + huc->status[INTEL_HUC_AUTH_BY_GSC].mask = HUC_LOAD_SUCCESSFUL;
>> + huc->status[INTEL_HUC_AUTH_BY_GSC].value = HUC_LOAD_SUCCESSFUL;
>> + } else {
>> + huc->status[INTEL_HUC_AUTH_BY_GSC].reg =
>> HECI_FWSTS5(MTL_GSC_HECI1_BASE);
>> + huc->status[INTEL_HUC_AUTH_BY_GSC].mask =
>> HECI_FWSTS5_HUC_AUTH_DONE;
>> + huc->status[INTEL_HUC_AUTH_BY_GSC].value =
>> HECI_FWSTS5_HUC_AUTH_DONE;
>> }
>> }
>> @@ -381,28 +392,39 @@ void intel_huc_suspend(struct intel_huc *huc)
>> delayed_huc_load_complete(huc);
>> }
>> -int intel_huc_wait_for_auth_complete(struct intel_huc *huc)
>> +static const char *auth_mode_string(struct intel_huc *huc,
>> + enum intel_huc_authentication_type type)
>> +{
>> + bool partial = !huc->loaded_via_gsc && huc->fw.is_meu_binary &&
>> + type == INTEL_HUC_AUTH_BY_GUC;
> partial = !loaded_via_gsc?
>
> If it is not a GSC load then there is no two stage authentication, is
> there? Does that mean the single stage auth does not count as 'all
> workloads' even on platforms where two stage is not supported?
Single step authentication always counts as "all workloads". The auth is
partial only if this is a DMA (i.e. non-gsc) load with a gsc-enabled
binary and we're doing an auth via GuC, which is what the condition
above is checking.
>
>> +
>> + return partial ? "clear media" : "all workloads";
>> +}
>> +
>> +int intel_huc_wait_for_auth_complete(struct intel_huc *huc,
>> + enum intel_huc_authentication_type type)
>> {
>> struct intel_gt *gt = huc_to_gt(huc);
>> int ret;
>> ret = __intel_wait_for_register(gt->uncore,
>> - huc->status.reg,
>> - huc->status.mask,
>> - huc->status.value,
>> + huc->status[type].reg,
>> + huc->status[type].mask,
>> + huc->status[type].value,
>> 2, 50, NULL);
>> /* mark the load process as complete even if the wait failed */
>> delayed_huc_load_complete(huc);
>> if (ret) {
>> - huc_err(huc, "firmware not verified %pe\n", ERR_PTR(ret));
>> + huc_err(huc, "firmware not verified for %s: %pe\n",
>> + auth_mode_string(huc, type), ERR_PTR(ret));
>> intel_uc_fw_change_status(&huc->fw,
>> INTEL_UC_FIRMWARE_LOAD_FAIL);
> This means that if stage one works but stage two fails, we mark the
> HuC as dead? So the previously working clear media support now stops
> working?
No, this is purely just for our internal debug tracking. The HuC will
still work if just the second stage fails (the status returned to
userspace is based on the HW regs).
>
>> return ret;
>> }
>> intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_RUNNING);
>> - huc_info(huc, "authenticated!\n");
>> + huc_info(huc, "authenticated for %s!\n", auth_mode_string(huc,
>> type));
>> return 0;
>> }
>> @@ -442,7 +464,7 @@ int intel_huc_auth(struct intel_huc *huc)
>> }
>> /* Check authentication status, it should be done by now */
>> - ret = intel_huc_wait_for_auth_complete(huc);
>> + ret = intel_huc_wait_for_auth_complete(huc, INTEL_HUC_AUTH_BY_GUC);
>> if (ret)
>> goto fail;
>> @@ -453,16 +475,29 @@ int intel_huc_auth(struct intel_huc *huc)
>> return ret;
>> }
>> -bool intel_huc_is_authenticated(struct intel_huc *huc)
>> +bool intel_huc_is_authenticated(struct intel_huc *huc,
>> + enum intel_huc_authentication_type type)
>> {
>> struct intel_gt *gt = huc_to_gt(huc);
>> intel_wakeref_t wakeref;
>> u32 status = 0;
>> with_intel_runtime_pm(gt->uncore->rpm, wakeref)
>> - status = intel_uncore_read(gt->uncore, huc->status.reg);
>> + status = intel_uncore_read(gt->uncore, huc->status[type].reg);
>> - return (status & huc->status.mask) == huc->status.value;
>> + return (status & huc->status[type].mask) ==
>> huc->status[type].value;
>> +}
>> +
>> +static bool huc_is_fully_authenticated(struct intel_huc *huc)
>> +{
>> + struct intel_uc_fw *huc_fw = &huc->fw;
>> +
>> + if (!huc_fw->is_meu_binary)
>> + return intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GUC);
> Is it not possible to load a non-MEU firmware on a GSC system? Don't
> we just treat that as the legacy part within the MEU blob and load it
> for clear media only via GuC auth? In which case, it is as 'fully
> authenticated' as it is possible to be but it still can't process
> protected media. So it should not count as 'fully authenticated'?
I guess it is technically possible, but who's going to provide such
binary? We're only shipping gsc-enabled binaries for GSC platforms.
>
>> + else if (intel_huc_is_loaded_by_gsc(huc) ||
>> HAS_ENGINE(huc_to_gt(huc), GSC0))
> Why not &&? Is it possible to have loaded_by_gsc != HAS_ENGINE(gsc)?
intel_huc_is_loaded_by_gsc is only true for DG2, while HAS_ENGINE(gsc)
covers MTL+.
>
> Is it even worth making the engine check a part of the loaded_by_gsc()
> helper?
no, because on MTL we don't load via GSC, we authenticate via it, so we
want loaded_by_gsc to be false there
>
>> + return intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC);
>> + else
>> + return false;
>> }
>> /**
>> @@ -477,7 +512,9 @@ bool intel_huc_is_authenticated(struct intel_huc
>> *huc)
>> */
>> int intel_huc_check_status(struct intel_huc *huc)
>> {
>> - switch (__intel_uc_fw_status(&huc->fw)) {
>> + struct intel_uc_fw *huc_fw = &huc->fw;
>> +
>> + switch (__intel_uc_fw_status(huc_fw)) {
>> case INTEL_UC_FIRMWARE_NOT_SUPPORTED:
>> return -ENODEV;
>> case INTEL_UC_FIRMWARE_DISABLED:
>> @@ -494,7 +531,17 @@ int intel_huc_check_status(struct intel_huc *huc)
>> break;
>> }
>> - return intel_huc_is_authenticated(huc);
>> + /*
>> + * meu binaries loaded by GuC are first partially authenticated
>> by GuC
>> + * and then fully authenticated by GSC
>> + */
>> + if (huc_is_fully_authenticated(huc))
>> + return 1; /* full auth */
>> + else if (huc_fw->is_meu_binary && !huc->loaded_via_gsc &&
> Why sometimes use the huc->loaded_via_gsc directly and sometimes use
> the intel_huc_is_loaded_by_gsc() helper? Either way, I'm confused -
> isn't that backwards? If the HuC is not loaded via GSC then it can't
> do two stage auth and therefore cannot be partial? It is either fully
> authenticated or not at all?
the aim was to use huc->loaded_via_gsc for internal huc functions and
intel_huc_is_loaded_by_gsc for external ones, but it looks like I didn't
manage it well.
Regarding the loading, the partial auth can only be done if the HuC is
NOT loaded via GSC. The load is done via DMA (same as legacy) and then
we authenticate first via GuC and then via GSC.
Daniele
>
> John.
>
>> + intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GUC))
>> + return 2; /* clear media only */
>> + else
>> + return 0;
>> }
>> static bool huc_has_delayed_load(struct intel_huc *huc)
>> @@ -508,7 +555,10 @@ void intel_huc_update_auth_status(struct
>> intel_huc *huc)
>> if (!intel_uc_fw_is_loadable(&huc->fw))
>> return;
>> - if (intel_huc_is_authenticated(huc))
>> + if (!huc->fw.is_meu_binary)
>> + return;
>> +
>> + if (huc_is_fully_authenticated(huc))
>> intel_uc_fw_change_status(&huc->fw,
>> INTEL_UC_FIRMWARE_RUNNING);
>> else if (huc_has_delayed_load(huc))
>> @@ -541,5 +591,5 @@ void intel_huc_load_status(struct intel_huc *huc,
>> struct drm_printer *p)
>> with_intel_runtime_pm(gt->uncore->rpm, wakeref)
>> drm_printf(p, "HuC status: 0x%08x\n",
>> - intel_uncore_read(gt->uncore, huc->status.reg));
>> + intel_uncore_read(gt->uncore,
>> huc->status[INTEL_HUC_AUTH_BY_GUC].reg));
>> }
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.h
>> b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
>> index 345e1b9aa062..adb063cd27a0 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.h
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
>> @@ -22,6 +22,12 @@ enum intel_huc_delayed_load_status {
>> INTEL_HUC_DELAYED_LOAD_ERROR,
>> };
>> +enum intel_huc_authentication_type {
>> + INTEL_HUC_AUTH_BY_GUC = 0,
>> + INTEL_HUC_AUTH_BY_GSC,
>> + INTEL_HUC_AUTH_MAX_MODES
>> +};
>> +
>> struct intel_huc {
>> /* Generic uC firmware management */
>> struct intel_uc_fw fw;
>> @@ -31,7 +37,7 @@ struct intel_huc {
>> i915_reg_t reg;
>> u32 mask;
>> u32 value;
>> - } status;
>> + } status[INTEL_HUC_AUTH_MAX_MODES];
>> struct {
>> struct i915_sw_fence fence;
>> @@ -49,10 +55,12 @@ int intel_huc_init(struct intel_huc *huc);
>> void intel_huc_fini(struct intel_huc *huc);
>> void intel_huc_suspend(struct intel_huc *huc);
>> int intel_huc_auth(struct intel_huc *huc);
>> -int intel_huc_wait_for_auth_complete(struct intel_huc *huc);
>> +int intel_huc_wait_for_auth_complete(struct intel_huc *huc,
>> + enum intel_huc_authentication_type type);
>> +bool intel_huc_is_authenticated(struct intel_huc *huc,
>> + enum intel_huc_authentication_type type);
>> int intel_huc_check_status(struct intel_huc *huc);
>> void intel_huc_update_auth_status(struct intel_huc *huc);
>> -bool intel_huc_is_authenticated(struct intel_huc *huc);
>> void intel_huc_register_gsc_notifier(struct intel_huc *huc,
>> struct bus_type *bus);
>> void intel_huc_unregister_gsc_notifier(struct intel_huc *huc,
>> struct bus_type *bus);
>> @@ -81,7 +89,7 @@ static inline bool intel_huc_is_loaded_by_gsc(const
>> struct intel_huc *huc)
>> static inline bool intel_huc_wait_required(struct intel_huc *huc)
>> {
>> return intel_huc_is_used(huc) &&
>> intel_huc_is_loaded_by_gsc(huc) &&
>> - !intel_huc_is_authenticated(huc);
>> + !intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC);
>> }
>> void intel_huc_load_status(struct intel_huc *huc, struct
>> drm_printer *p);
>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
>> b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
>> index 88ad2c322c4a..3b8edaba97d2 100644
>> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
>> @@ -141,7 +141,7 @@ int intel_huc_fw_load_and_auth_via_gsc(struct
>> intel_huc *huc)
>> * component gets re-bound and this function called again. If
>> so, just
>> * mark the HuC as loaded.
>> */
>> - if (intel_huc_is_authenticated(huc)) {
>> + if (intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC)) {
>> intel_uc_fw_change_status(&huc->fw,
>> INTEL_UC_FIRMWARE_RUNNING);
>> return 0;
>> }
>> @@ -154,7 +154,7 @@ int intel_huc_fw_load_and_auth_via_gsc(struct
>> intel_huc *huc)
>> intel_uc_fw_change_status(&huc->fw,
>> INTEL_UC_FIRMWARE_TRANSFERRED);
>> - return intel_huc_wait_for_auth_complete(huc);
>> + return intel_huc_wait_for_auth_complete(huc,
>> INTEL_HUC_AUTH_BY_GSC);
>> }
>> /**
>> diff --git a/drivers/gpu/drm/i915/i915_reg.h
>> b/drivers/gpu/drm/i915/i915_reg.h
>> index dde6e91055bd..1a62e73c3d9c 100644
>> --- a/drivers/gpu/drm/i915/i915_reg.h
>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>> @@ -941,6 +941,9 @@
>> #define HECI_H_GS1(base) _MMIO((base) + 0xc4c)
>> #define HECI_H_GS1_ER_PREP REG_BIT(0)
>> +#define HECI_FWSTS5(base) _MMIO(base + 0xc68)
>> +#define HECI_FWSTS5_HUC_AUTH_DONE (1 << 19)
>> +
>> #define HSW_GTT_CACHE_EN _MMIO(0x4024)
>> #define GTT_CACHE_EN_ALL 0xF0007FFF
>> #define GEN7_WR_WATERMARK _MMIO(0x4028)
>> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
>> index dba7c5a5b25e..43b8de42a94e 100644
>> --- a/include/uapi/drm/i915_drm.h
>> +++ b/include/uapi/drm/i915_drm.h
>> @@ -659,7 +659,8 @@ typedef struct drm_i915_irq_wait {
>> * If the IOCTL is successful, the returned parameter will be set
>> to one of the
>> * following values:
>> * * 0 if HuC firmware load is not complete,
>> - * * 1 if HuC firmware is authenticated and running.
>> + * * 1 if HuC firmware is loaded and fully authenticated,
>> + * * 2 if HuC firmware is loaded and authenticated for clear media
>> only
>> */
>> #define I915_PARAM_HUC_STATUS 42
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Intel-gfx] [PATCH v2 7/8] drm/i915/mtl/huc: Use the media gt for the HuC getparam
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 7/8] drm/i915/mtl/huc: Use the media gt for the HuC getparam Daniele Ceraolo Spurio
@ 2023-05-25 19:53 ` John Harrison
0 siblings, 0 replies; 32+ messages in thread
From: John Harrison @ 2023-05-25 19:53 UTC (permalink / raw)
To: Daniele Ceraolo Spurio, intel-gfx; +Cc: dri-devel
On 4/28/2023 11:58, Daniele Ceraolo Spurio wrote:
> On MTL, for obvious reasons, HuC is only available on the media tile.
> We already disable SW support for HuC on the root gt due to the
> absence of VCS engines, but we also need to update the getparam to point
> to the HuC struct in the media GT.
>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Cc: John Harrison <John.C.Harrison@Intel.com>
> ---
> drivers/gpu/drm/i915/i915_getparam.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_getparam.c b/drivers/gpu/drm/i915/i915_getparam.c
> index 2238e096c957..7aa47550e4f2 100644
> --- a/drivers/gpu/drm/i915/i915_getparam.c
> +++ b/drivers/gpu/drm/i915/i915_getparam.c
> @@ -98,7 +98,11 @@ int i915_getparam_ioctl(struct drm_device *dev, void *data,
> value = sseu->min_eu_in_pool;
> break;
> case I915_PARAM_HUC_STATUS:
> - value = intel_huc_check_status(&to_gt(i915)->uc.huc);
> + /* On platform with a media GT, the HuC is on that GT */
> + if (i915->media_gt)
> + value = intel_huc_check_status(&i915->media_gt->uc.huc);
> + else
> + value = intel_huc_check_status(&to_gt(i915)->uc.huc);
I assume the intention is to ignore multi-tile complications? As in, all
tiles are guaranteed to be the same so there is no point looking beyond
the root tile?
Reviewed-by: John Harrison <John.C.Harrison@Intel.com>
> if (value < 0)
> return value;
> break;
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Intel-gfx] [PATCH v2 8/8] drm/i915/huc: define HuC FW version for MTL
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 8/8] drm/i915/huc: define HuC FW version for MTL Daniele Ceraolo Spurio
@ 2023-05-25 19:54 ` John Harrison
0 siblings, 0 replies; 32+ messages in thread
From: John Harrison @ 2023-05-25 19:54 UTC (permalink / raw)
To: Daniele Ceraolo Spurio, intel-gfx; +Cc: dri-devel, Alan Previn
On 4/28/2023 11:58, Daniele Ceraolo Spurio wrote:
> Follow the same logic as DG2, so just a meu binary with no version number.
>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
Reviewed-by: John Harrison <John.C.Harrison@Intel.com>
> ---
> drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> index 3338dd45e78b..796f54a62eef 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> @@ -102,6 +102,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
> fw_def(SKYLAKE, 0, guc_mmp(skl, 70, 1, 1))
>
> #define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_raw, huc_mmp, huc_gsc) \
> + fw_def(METEORLAKE, 0, huc_gsc(mtl)) \
> fw_def(DG2, 0, huc_gsc(dg2)) \
> fw_def(ALDERLAKE_P, 0, huc_raw(tgl)) \
> fw_def(ALDERLAKE_P, 0, huc_mmp(tgl, 7, 9, 3)) \
^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2023-05-25 19:54 UTC | newest]
Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-28 18:58 [Intel-gfx] [PATCH v2 0/8] drm/i915: HuC loading and authentication for MTL Daniele Ceraolo Spurio
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 1/8] DO NOT REVIEW: drm/i915: Add support for MTL GSC SW Proxy Daniele Ceraolo Spurio
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 2/8] drm/i915/uc: perma-pin firmwares Daniele Ceraolo Spurio
2023-05-17 20:59 ` John Harrison
2023-05-17 21:12 ` Ceraolo Spurio, Daniele
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 3/8] drm/i915/huc: Parse the GSC-enabled HuC binary Daniele Ceraolo Spurio
2023-05-02 15:27 ` [Intel-gfx] [PATCH v2] " Daniele Ceraolo Spurio
2023-05-13 0:38 ` Teres Alexis, Alan Previn
2023-05-17 21:04 ` John Harrison
2023-05-19 20:35 ` Ceraolo Spurio, Daniele
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 4/8] drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so Daniele Ceraolo Spurio
2023-05-19 18:03 ` John Harrison
2023-05-20 0:05 ` Ceraolo Spurio, Daniele
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 5/8] drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow Daniele Ceraolo Spurio
2023-05-13 0:51 ` Teres Alexis, Alan Previn
2023-05-19 18:45 ` John Harrison
2023-05-20 0:17 ` Ceraolo Spurio, Daniele
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 6/8] drm/i915/mtl/huc: auth HuC via GSC Daniele Ceraolo Spurio
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 7/8] drm/i915/mtl/huc: Use the media gt for the HuC getparam Daniele Ceraolo Spurio
2023-05-25 19:53 ` John Harrison
2023-04-28 18:58 ` [Intel-gfx] [PATCH v2 8/8] drm/i915/huc: define HuC FW version for MTL Daniele Ceraolo Spurio
2023-05-25 19:54 ` John Harrison
2023-04-28 21:29 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: HuC loading and authentication for MTL (rev2) Patchwork
2023-04-28 21:29 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2023-04-28 21:47 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
2023-05-02 16:05 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: HuC loading and authentication for MTL (rev3) Patchwork
2023-05-02 16:05 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2023-05-02 16:22 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
2023-05-03 10:17 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: HuC loading and authentication for MTL (rev4) Patchwork
2023-05-03 10:18 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2023-05-03 10:30 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2023-05-03 13:10 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox