Re: [Intel-gfx] [PATCH] drm/i915/gt: Fix reservation address in ggtt_reserve_guc_top

2023-08-31 Thread Ceraolo Spurio, Daniele




On 8/25/2023 7:33 AM, Javier Pello wrote:

There is an assertion in ggtt_reserve_guc_top that the global GTT
is of size at least GUC_GGTT_TOP, which is not the case on a 32-bit
platform; see commit 562d55d991b39ce376c492df2f7890fd6a541ffc
("drm/i915/bdw: Only use 2g GGTT for 32b platforms"). If GEM_BUG_ON
is enabled, this triggers a BUG(); if GEM_BUG_ON is disabled, the
subsequent reservation fails and the driver fails to initialise
the device:

i915 :00:02.0: [drm:i915_init_ggtt [i915]] Failed to reserve top of GGTT 
for GuC
i915 :00:02.0: Device initialization failed (-28)
i915 :00:02.0: Please file a bug on drm/i915; see 
https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs for 
details.
i915: probe of :00:02.0 failed with error -28

Make the reservation at the top of the available space, whatever
that is, instead of assuming that the top will be GUC_GGTT_TOP.

Fixes: 911800765ef6 ("drm/i915/uc: Reserve upper range of GGTT")


For tracking, it might be good to also add:

Link: https://gitlab.freedesktop.org/drm/intel/-/issues/9080


Signed-off-by: Javier Pello 
Cc: intel-gfx@lists.freedesktop.org
Cc: sta...@vger.kernel.org # v5.3+


Need the full CC list here, so that when the patch gets back-ported the 
relevant developers get automatically added.



---
  drivers/gpu/drm/i915/gt/intel_ggtt.c | 21 +++--
  1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c 
b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index e9328e1a..0157bebb 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -511,20 +511,29 @@ void intel_ggtt_unbind_vma(struct i915_address_space *vm,
vm->clear_range(vm, vma_res->start, vma_res->vma_size);
  }
  
+/* Reserve the top of the GuC address space for firmware images. Addresses

+ * beyond GUC_GGTT_TOP in the GuC address space are inaccessible by GuC,
+ * which makes for a suitable range to hold GuC/HuC firmware images if the
+ * size of the GGTT is 4G. However, on a 32-bit platform the size of the GGTT
+ * is limited to 2G, which is less than GUC_GGTT_TOP, but we reserve a chunk
+ * of the same size anyway, which is far more than needed, to keep the logic
+ * in uc_fw_ggtt_offset() simple. */


Style: multi-line comment should be formatted as:

/*
 * Text
 * more text
 */


+#define GUC_TOP_RESERVE_SIZE (SZ_4G - GUC_GGTT_TOP)
+
  static int ggtt_reserve_guc_top(struct i915_ggtt *ggtt)
  {
-   u64 size;
+   u64 offset;
int ret;
  
  	if (!intel_uc_uses_guc(>vm.gt->uc))

return 0;
  
-	GEM_BUG_ON(ggtt->vm.total <= GUC_GGTT_TOP);

-   size = ggtt->vm.total - GUC_GGTT_TOP;
+   GEM_BUG_ON(ggtt->vm.total <= GUC_TOP_RESERVE_SIZE);
+   offset = ggtt->vm.total - GUC_TOP_RESERVE_SIZE;
  
-	ret = i915_gem_gtt_reserve(>vm, NULL, >uc_fw, size,

-  GUC_GGTT_TOP, I915_COLOR_UNEVICTABLE,
-  PIN_NOEVICT);
+   ret = i915_gem_gtt_reserve(>vm, NULL, >uc_fw,
+  GUC_TOP_RESERVE_SIZE, offset,
+  I915_COLOR_UNEVICTABLE, PIN_NOEVICT);


The code change looks good to me, so with the style fix and the 
additions to the commit message this is:


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


if (ret)
drm_dbg(>vm.i915->drm,
"Failed to reserve top of GGTT for GuC\n");




Re: [Intel-gfx] [PATCH] drm/i915/gsc: define gsc fw

2023-08-25 Thread Ceraolo Spurio, Daniele




On 8/25/2023 10:20 AM, Rodrigo Vivi wrote:

On Fri, Aug 25, 2023 at 09:27:53AM -0700, Daniele Ceraolo Spurio wrote:

Add FW definition and the matching override modparam.

The GSC FW has both a release version, based on platform and a rolling
counter, and a compatibility version, which is the one tracking
interface changes. Since what we care about is the interface, we use
the compatibility version in the binary names.

Same as with the GuC, a major version bump indicate a
backward-incompatible change, while a minor version bump indicates a
backward-compatible one, so we use only the former in the file name.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Cc: Tvrtko Ursulin 
Cc: Rodrigo Vivi 
Reviewed-by: Alan Previn 
---

This patch is already merged in topic/core-for-CI. It was merged there
because we didn't have a GSC FW ready to ship to linux-firmware, but we
still wanted to start testing what we had in CI. We finally have a FW
in flight towards linux-firmware [1], so we can transition this patch
to drm-intel-gt-next. The patch is unchanged since it was first sent
and reviewed [2], so I kept the r-b and I'm looking for an ack on the
move.
Note that since this patch is already applied, pre-merge CI won't
correctly run on it (which is not a problem given that the patch is
already included in all current runs).

References: https://gitlab.freedesktop.org/drm/intel/-/issues/8705
[1] https://lists.freedesktop.org/archives/intel-gfx/2023-August/22.html
[2] https://patchwork.freedesktop.org/patch/544638/

Thanks for all the info. I agree we are ready to make the move and have
enough time until we get that in linux-firmware.git.

Acked-by: Rodrigo Vivi 


Thanks!



Btw, one last question:
Will we already include this in the new
https://gitlab.freedesktop.org/drm/firmware ?


I wasn't sure if the CI scripts would already work out of the new repo, 
so I went with the old flow for now. I'll try to follow up on the side 
to get the new repo ready and start pushing from there.


Daniele





  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 32 ++--
  1 file changed, 24 insertions(+), 8 deletions(-)

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 9e833f499ac7..fc0d05d2df59 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -131,6 +131,17 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
fw_def(BROXTON,  0, huc_mmp(bxt,  2, 0, 0)) \
fw_def(SKYLAKE,  0, huc_mmp(skl,  2, 0, 0))
  
+/*

+ * The GSC FW has multiple version (see intel_gsc_uc.h for details); since what
+ * we care about is the interface, we use the compatibility version in the
+ * binary names.
+ * Same as with the GuC, a major version bump indicate a
+ * backward-incompatible change, while a minor version bump indicates a
+ * backward-compatible one, so we use only the former in the file name.
+ */
+#define INTEL_GSC_FIRMWARE_DEFS(fw_def, gsc_def) \
+   fw_def(METEORLAKE,   0, gsc_def(mtl, 1, 0))
+
  /*
   * Set of macros for producing a list of filenames from the above table.
   */
@@ -166,6 +177,9 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
  #define MAKE_HUC_FW_PATH_MMP(prefix_, major_, minor_, patch_) \
__MAKE_UC_FW_PATH_MMP(prefix_, "huc", major_, minor_, patch_)
  
+#define MAKE_GSC_FW_PATH(prefix_, major_, minor_) \

+   __MAKE_UC_FW_PATH_MAJOR(prefix_, "gsc", major_)
+
  /*
   * All blobs need to be declared via MODULE_FIRMWARE().
   * This first expansion of the table macros is solely to provide
@@ -176,6 +190,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
  
  INTEL_GUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH_MAJOR, MAKE_GUC_FW_PATH_MMP)

  INTEL_HUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_HUC_FW_PATH_BLANK, 
MAKE_HUC_FW_PATH_MMP, MAKE_HUC_FW_PATH_GSC)
+INTEL_GSC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GSC_FW_PATH)
  
  /*

   * The next expansion of the table macros (in __uc_fw_auto_select below) 
provides
@@ -225,6 +240,10 @@ struct __packed uc_fw_blob {
  #define HUC_FW_BLOB_GSC(prefix_) \
UC_FW_BLOB_NEW(0, 0, 0, true, MAKE_HUC_FW_PATH_GSC(prefix_))
  
+#define GSC_FW_BLOB(prefix_, major_, minor_) \

+   UC_FW_BLOB_NEW(major_, minor_, 0, true, \
+  MAKE_GSC_FW_PATH(prefix_, major_, minor_))
+
  struct __packed uc_fw_platform_requirement {
enum intel_platform p;
u8 rev; /* first platform rev using this FW */
@@ -251,9 +270,14 @@ static const struct uc_fw_platform_requirement blobs_huc[] 
= {
INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, HUC_FW_BLOB_MMP, 
HUC_FW_BLOB_GSC)
  };
  
+static const struct uc_fw_platform_requirement blobs_gsc[] = {

+   INTEL_GSC_FIRMWARE_DEFS(MAKE_FW_LIST, GSC_FW_BLOB)
+};
+
  static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = {
[INTEL_UC_FW_TYPE_GUC] = { blobs_guc, 

Re: [Intel-gfx] [PATCH] gpu: drm: i915: fix documentation style

2023-08-21 Thread Ceraolo Spurio, Daniele




On 8/21/2023 9:22 AM, Jani Nikula wrote:

On Mon, 21 Aug 2023, "Ricardo B. Marliere"  wrote:

This patch fixes the following sphinx warnings in the htmldocs make target:

Documentation/gpu/i915:546: ./drivers/gpu/drm/i915/gt/uc/intel_huc.c:29: ERROR: 
Unexpected indentation.
Documentation/gpu/i915:546: ./drivers/gpu/drm/i915/gt/uc/intel_huc.c:30: 
WARNING: Block quote ends without a blank line; unexpected unindent.
Documentation/gpu/i915:546: ./drivers/gpu/drm/i915/gt/uc/intel_huc.c:35: 
WARNING: Bullet list ends without a blank line; unexpected unindent.

Signed-off-by: Ricardo B. Marliere 

Already fixed by commit 175b036472f6 ("drm/i915: fix Sphinx indentation
warning") in drm-next.


Should we send this commit through the -fixes path, so it gets included 
in 6.5?


Daniele


BR,
Jani.


---
  drivers/gpu/drm/i915/gt/uc/intel_huc.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index ddd146265beb..fa70defcb5b2 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -26,6 +26,7 @@
   * The kernel driver is only responsible for loading the HuC firmware and
   * triggering its security authentication. This is done differently depending
   * on the platform:
+ *
   * - older platforms (from Gen9 to most Gen12s): the load is performed via DMA
   *   and the authentication via GuC
   * - DG2: load and authentication are both performed via GSC.
@@ -33,6 +34,7 @@
   *   not-DG2 older platforms), while the authentication is done in 2-steps,
   *   a first auth for clear-media workloads via GuC and a second one for all
   *   workloads via GSC.
+ *
   * On platforms where the GuC does the authentication, to correctly do so the
   * HuC binary must be loaded before the GuC one.
   * Loading the HuC is optional; however, not using the HuC might negatively




Re: [Intel-gfx] [PATCH v2] drm/i915/guc: Force a reset on internal GuC error

2023-08-17 Thread Ceraolo Spurio, Daniele




On 8/15/2023 5:39 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

If GuC hits an internal error (and survives long enough to report it
to the KMD), it is basically toast and will stop until a GT reset and
subsequent GuC reload is performed. Previously, the KMD just printed
an error message and then waited for the heartbeat to eventually kick
in and trigger a reset (assuming the heartbeat had not been disabled).
Instead, force the reset immediately to guarantee that it happens and
to eliminate the very long heartbeat delay. The captured error state
is also more likely to be useful if captured at the time of the error
rather than many seconds later.

Note that it is not possible to trigger a reset from with the G2H
handler itself. The reset prepare process involves flushing
outstanding G2H contents. So a deadlock could result. Instead, the G2H
handler queues a worker thread to do the reset asynchronously.

v2: Flush the worker on suspend and shutdown. Add rate limiting to
prevent spam from a totally dead system (review feedback from Daniele).

Signed-off-by: John Harrison 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/uc/intel_guc.c| 38 +++
  drivers/gpu/drm/i915/gt/uc/intel_guc.h| 15 +
  drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |  6 +---
  3 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 569b5fe94c416..12a817b762334 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -159,6 +159,21 @@ static void gen11_disable_guc_interrupts(struct intel_guc 
*guc)
gen11_reset_guc_interrupts(guc);
  }
  
+static void guc_dead_worker_func(struct work_struct *w)

+{
+   struct intel_guc *guc = container_of(w, struct intel_guc, 
dead_guc_worker);
+   struct intel_gt *gt = guc_to_gt(guc);
+   unsigned long last = guc->last_dead_guc_jiffies;
+   unsigned long delta = jiffies_to_msecs(jiffies - last);
+
+   if (delta < 500) {
+   intel_gt_set_wedged(gt);
+   } else {
+   intel_gt_handle_error(gt, ALL_ENGINES, I915_ERROR_CAPTURE, "dead 
GuC");
+   guc->last_dead_guc_jiffies = jiffies;
+   }
+}
+
  void intel_guc_init_early(struct intel_guc *guc)
  {
struct intel_gt *gt = guc_to_gt(guc);
@@ -171,6 +186,8 @@ void intel_guc_init_early(struct intel_guc *guc)
intel_guc_slpc_init_early(>slpc);
intel_guc_rc_init_early(guc);
  
+	INIT_WORK(>dead_guc_worker, guc_dead_worker_func);

+
mutex_init(>send_mutex);
spin_lock_init(>irq_lock);
if (GRAPHICS_VER(i915) >= 11) {
@@ -461,6 +478,8 @@ void intel_guc_fini(struct intel_guc *guc)
if (!intel_uc_fw_is_loadable(>fw))
return;
  
+	flush_work(>dead_guc_worker);

+
if (intel_guc_slpc_is_used(guc))
intel_guc_slpc_fini(>slpc);
  
@@ -585,6 +604,20 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 *request, u32 len,

return ret;
  }
  
+int intel_guc_crash_process_msg(struct intel_guc *guc, u32 action)

+{
+   if (action == INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED)
+   guc_err(guc, "Crash dump notification\n");
+   else if (action == INTEL_GUC_ACTION_NOTIFY_EXCEPTION)
+   guc_err(guc, "Exception notification\n");
+   else
+   guc_err(guc, "Unknown crash notification: 0x%04X\n", action);
+
+   queue_work(system_unbound_wq, >dead_guc_worker);
+
+   return 0;
+}
+
  int intel_guc_to_host_process_recv_msg(struct intel_guc *guc,
   const u32 *payload, u32 len)
  {
@@ -601,6 +634,9 @@ int intel_guc_to_host_process_recv_msg(struct intel_guc 
*guc,
if (msg & INTEL_GUC_RECV_MSG_EXCEPTION)
guc_err(guc, "Received early exception notification!\n");
  
+	if (msg & (INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED | INTEL_GUC_RECV_MSG_EXCEPTION))

+   queue_work(system_unbound_wq, >dead_guc_worker);
+
return 0;
  }
  
@@ -640,6 +676,8 @@ int intel_guc_suspend(struct intel_guc *guc)

return 0;
  
  	if (intel_guc_submission_is_used(guc)) {

+   flush_work(>dead_guc_worker);
+
/*
 * This H2G MMIO command tears down the GuC in two steps. First 
it will
 * generate a G2H CTB for every active context indicating a 
reset. In
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 8dc291ff00935..6c392bad29c19 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -266,6 +266,20 @@ struct intel_guc {
unsigned long last_stat_jiffies;
} timestamp;
  
+	/**

+* @dead_guc_worker: Asynchronous wor

Re: [Intel-gfx] [PATCH v2 1/1] drm/i915/pxp/mtl: intel_pxp_init_hw needs runtime-pm inside pm-complete

2023-08-03 Thread Ceraolo Spurio, Daniele




On 8/2/2023 12:06 PM, Alan Previn wrote:

In the case of failed suspend flow or cases where the kernel does not go
into full suspend but goes from suspend_prepare back to resume_complete,
we get called for a pm_complete but without runtime_pm guaranteed.

Thus, ensure we take the runtime_pm when calling intel_pxp_init_hw
from within intel_pxp_resume_complete.

v2: resume_complete and runtime_resume should abstract a common
 helper with different wakeref requirements. (Daniele)

Signed-off-by: Alan Previn 




CI is showing a decent hit to the passrate on DG2, but it looks 
unrelated to me. Maybe trigger a re-run to be safe?

Once it's confirmed that the failures are unrelated, this is:

Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/pxp/intel_pxp_pm.c | 18 +-
  drivers/gpu/drm/i915/pxp/intel_pxp_pm.h |  5 +++--
  2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
index 1a04067f61fc..6dfd24918953 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
@@ -34,8 +34,10 @@ void intel_pxp_suspend(struct intel_pxp *pxp)
}
  }
  
-void intel_pxp_resume_complete(struct intel_pxp *pxp)

+static void _pxp_resume(struct intel_pxp *pxp, bool take_wakeref)
  {
+   intel_wakeref_t wakeref;
+
if (!intel_pxp_is_enabled(pxp))
return;
  
@@ -48,7 +50,21 @@ void intel_pxp_resume_complete(struct intel_pxp *pxp)

if (!HAS_ENGINE(pxp->ctrl_gt, GSC0) && !pxp->pxp_component)
return;
  
+	if (take_wakeref)

+   wakeref = intel_runtime_pm_get(>ctrl_gt->i915->runtime_pm);
intel_pxp_init_hw(pxp);
+   if (take_wakeref)
+   intel_runtime_pm_put(>ctrl_gt->i915->runtime_pm, wakeref);
+}
+
+void intel_pxp_resume_complete(struct intel_pxp *pxp)
+{
+   _pxp_resume(pxp, true);
+}
+
+void intel_pxp_runtime_resume(struct intel_pxp *pxp)
+{
+   _pxp_resume(pxp, false);
  }
  
  void intel_pxp_runtime_suspend(struct intel_pxp *pxp)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
index 06b46f535b42..8695889b8380 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
@@ -13,6 +13,7 @@ void intel_pxp_suspend_prepare(struct intel_pxp *pxp);
  void intel_pxp_suspend(struct intel_pxp *pxp);
  void intel_pxp_resume_complete(struct intel_pxp *pxp);
  void intel_pxp_runtime_suspend(struct intel_pxp *pxp);
+void intel_pxp_runtime_resume(struct intel_pxp *pxp);
  #else
  static inline void intel_pxp_suspend_prepare(struct intel_pxp *pxp)
  {
@@ -29,9 +30,9 @@ static inline void intel_pxp_resume_complete(struct intel_pxp 
*pxp)
  static inline void intel_pxp_runtime_suspend(struct intel_pxp *pxp)
  {
  }
-#endif
+
  static inline void intel_pxp_runtime_resume(struct intel_pxp *pxp)
  {
-   intel_pxp_resume_complete(pxp);
  }
+#endif
  #endif /* __INTEL_PXP_PM_H__ */

base-commit: d7a437067a2146e1035a5609dae08b9595773a16




Re: [Intel-gfx] [PATCH] drm/i915/huc: fix intel_huc.c doc bulleted list format error

2023-07-31 Thread Ceraolo Spurio, Daniele




On 7/26/2023 7:54 PM, David Reaver wrote:

Fix the following make htmldocs errors/warnings:

./drivers/gpu/drm/i915/gt/uc/intel_huc.c:29: ERROR: Unexpected indentation.
./drivers/gpu/drm/i915/gt/uc/intel_huc.c:30: WARNING: Block quote ends without 
a blank line; unexpected unindent.
./drivers/gpu/drm/i915/gt/uc/intel_huc.c:35: WARNING: Bullet list ends without 
a blank line; unexpected unindent.

This output is a bit misleading. The real issue here is we need a blank
line before and after the bulleted list.

Link: https://www.kernel.org/doc/html/latest/gpu/i915.html#huc
Link: 
https://lore.kernel.org/dri-devel/20230530152958.1384061-1-daniele.ceraolospu...@intel.com/

Signed-off-by: David Reaver 


Reviewed-by: Daniele Ceraolo Spurio 

and pushed to drm-intel-gt-next.

thanks for the fix,
Daniele


---
  drivers/gpu/drm/i915/gt/uc/intel_huc.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index ddd146265beb..fa70defcb5b2 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -26,6 +26,7 @@
   * The kernel driver is only responsible for loading the HuC firmware and
   * triggering its security authentication. This is done differently depending
   * on the platform:
+ *
   * - older platforms (from Gen9 to most Gen12s): the load is performed via DMA
   *   and the authentication via GuC
   * - DG2: load and authentication are both performed via GSC.
@@ -33,6 +34,7 @@
   *   not-DG2 older platforms), while the authentication is done in 2-steps,
   *   a first auth for clear-media workloads via GuC and a second one for all
   *   workloads via GSC.
+ *
   * On platforms where the GuC does the authentication, to correctly do so the
   * HuC binary must be loaded before the GuC one.
   * Loading the HuC is optional; however, not using the HuC might negatively




Re: [Intel-gfx] [PATCH] drm/i915/pxp/mtl: intel_pxp_init_hw needs runtime-pm inside pm-complete

2023-07-27 Thread Ceraolo Spurio, Daniele




On 6/1/2023 8:59 AM, Alan Previn wrote:

In the case of failed suspend flow or cases where the kernel does not go
into full suspend but goes from suspend_prepare back to resume_complete,
we get called for a pm_complete but without runtime_pm guaranteed.

Thus, ensure we take the runtime_pm when calling intel_pxp_init_hw
from within intel_pxp_resume_complete.

Signed-off-by: Alan Previn 
---
  drivers/gpu/drm/i915/pxp/intel_pxp_pm.c | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
index 1a04067f61fc..1d184dcd63c7 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
@@ -36,6 +36,8 @@ void intel_pxp_suspend(struct intel_pxp *pxp)
  
  void intel_pxp_resume_complete(struct intel_pxp *pxp)

  {
+   intel_wakeref_t wakeref;
+
if (!intel_pxp_is_enabled(pxp))
return;
  
@@ -48,7 +50,8 @@ void intel_pxp_resume_complete()

if (!HAS_ENGINE(pxp->ctrl_gt, GSC0) && !pxp->pxp_component)
return;
  
-	intel_pxp_init_hw(pxp);

+   with_intel_runtime_pm(>ctrl_gt->i915->runtime_pm, wakeref)


This is called from within the rpm resume path, so you can't do an rpm 
get or it will deadlock. Maybe have:


__pxp_resume_complete(struct intel_pxp *pxp, bool needs_rpm);

intel_pxp_resume_complete(..)
{
    return __pxp_resume_complete(pxp, true);
}

intel_pxp_runtime_resume(..)
{
    return __pxp_resume_complete(pxp, false);
}


or something like that.
Daniele


+   intel_pxp_init_hw(pxp);
  }
  
  void intel_pxp_runtime_suspend(struct intel_pxp *pxp)


base-commit: a66da4c33d8ede541aea9ba6d0d73b556a072d54




Re: [Intel-gfx] [PATCH v7] drm/i915/selftest/gsc: Ensure GSC Proxy init completes before selftests

2023-07-26 Thread Ceraolo Spurio, Daniele




On 7/20/2023 4:01 PM, Alan Previn wrote:

On MTL, if the GSC Proxy init flows haven't completed, submissions to the
GSC engine will fail. Those init flows are dependent on the mei's
gsc_proxy component that is loaded in parallel with i915 and a
worker that could potentially start after i915 driver init is done.

That said, all subsytems that access the GSC engine today does check
for such init flow completion before using the GSC engine. However,
selftests currently don't wait on anything before starting.

To fix this, add a waiter function at the start of __run_selftests
that waits for gsc-proxy init flows to complete. Selftests shouldn't
care if the proxy-init failed as that should be flagged elsewhere.

Difference from prior versions:
v7: - Change the fw status to INTEL_UC_FIRMWARE_LOAD_FAIL if the
  proxy-init fails so that intel_gsc_uc_fw_proxy_get_status
  catches it. (Daniele)
v6: - Add a helper that returns something more than a boolean
  so we selftest can stop waiting if proxy-init hadn't
  completed but failed (Daniele).
v5: - Move the call to __wait_gsc_proxy_completed from common
  __run_selftests dispatcher to the group-level selftest
  function (Trvtko).
- change the pr_info to pr_warn if we hit the timeout.
v4: - Remove generalized waiters function table framework (Tvrtko).
- Remove mention of CI-framework-timeout from comments (Tvrtko).
v3: - Rebase to latest drm-tip.
v2: - Based on internal testing, increase the timeout for gsc-proxy
  specific case to 8 seconds.

Signed-off-by: Alan Previn 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 14 +
  drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h |  1 +
  drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 13 +++-
  .../gpu/drm/i915/selftests/i915_selftest.c| 31 +++
  4 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index ab1a456f833d..163021705210 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -45,6 +45,20 @@ bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc 
*gsc, bool needs_wakere
   HECI1_FWSTS1_PROXY_STATE_NORMAL;
  }
  
+int intel_gsc_uc_fw_proxy_get_status(struct intel_gsc_uc *gsc)

+{
+   if (!(IS_ENABLED(CONFIG_INTEL_MEI_GSC_PROXY)))
+   return -ENODEV;
+   if (!intel_uc_fw_is_loadable(>fw))
+   return -ENODEV;
+   if (__intel_uc_fw_status(>fw) == INTEL_UC_FIRMWARE_LOAD_FAIL)
+   return -ENOLINK;
+   if (!intel_gsc_uc_fw_proxy_init_done(gsc, true))
+   return -EAGAIN;
+
+   return 0;
+}
+
  bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)
  {
return gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore, false) &
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
index ad2167ce9137..bc9dd0de8aaf 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
@@ -16,5 +16,6 @@ int intel_gsc_fw_get_binary_info(struct intel_uc_fw *gsc_fw, 
const void *data, s
  int intel_gsc_uc_fw_upload(struct intel_gsc_uc *gsc);
  bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc);
  bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc, bool 
needs_wakeref);
+int intel_gsc_uc_fw_proxy_get_status(struct intel_gsc_uc *gsc);
  
  #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 034b53a71541..0d3b22a74365 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -62,8 +62,18 @@ static void gsc_work(struct work_struct *work)
}
  
  		ret = intel_gsc_proxy_request_handler(gsc);

-   if (ret)
+   if (ret) {
+   if (actions & GSC_ACTION_FW_LOAD) {
+   /*
+* A proxy failure right after firmware load 
means the proxy-init
+* step has failed so mark GSC as not usable 
after this
+*/
+   drm_err(>i915->drm,
+   "GSC proxy handler failed to init\n");
+   intel_uc_fw_change_status(>fw, 
INTEL_UC_FIRMWARE_LOAD_FAIL);
+   }
goto out_put;
+   }
  
  		/* mark the GSC FW init as done the first time we run this */

if (actions & GSC_ACTION_FW_LOAD) {
@@ -78,6 +88,7 @@ static void gsc_work(struct work_struct *work)
} else {
drm_err(>i915->drm,

Re: [Intel-gfx] [PATCH v3] drm/i915/pxp: Optimize GET_PARAM:PXP_STATUS

2023-07-20 Thread Ceraolo Spurio, Daniele




On 6/29/2023 6:44 PM, Alan Previn wrote:

After recent discussions with Mesa folks, it was requested
that we optimize i915's GET_PARAM for the PXP_STATUS without
changing the UAPI spec.

Add these additional optimizations:
- If any PXP initializatoin flow failed, then ensure that
  we catch it so that we can change the returned PXP_STATUS
  from "2" (i.e. 'PXP is supported but not yet ready')
  to "-ENODEV". This typically should not happen and if it
  does, we have a platform configuration issue.
- If a PXP arbitration session creation event failed
  due to incorrect firmware version or blocking SOC fusing
  or blocking BIOS configuration (platform reasons that won't
  change if we retry), then reflect that blockage by also
  returning -ENODEV in the GET_PARAM:PXP_STATUS.
- GET_PARAM:PXP_STATUS should not wait at all if PXP is
  supported but non-i915 dependencies (component-driver /
  firmware) we are still pending to complete the init flows.
  In this case, just return "2" immediately (i.e. 'PXP is
  supported but not yet ready').

Difference from prio revs:
   v2: - Use a #define for the default readiness timeout (Vivaik).
   - Improve comments around the failing of proxy-init.
   v1: - Change the commit msg style to be imperative. (Jani)
   - Rename timeout to timeout_ms. (Jani)
   - Fix is_fw_err_platform_config to use higher order
 param (pxp) first. (Jani)

Signed-off-by: Alan Previn 
---
  drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c  | 10 +-
  drivers/gpu/drm/i915/i915_getparam.c   |  2 +-
  drivers/gpu/drm/i915/pxp/intel_pxp.c   | 40 ++
  drivers/gpu/drm/i915/pxp/intel_pxp.h   |  2 +-
  drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c |  7 ++--
  drivers/gpu/drm/i915/pxp/intel_pxp_tee.c   |  7 ++--
  drivers/gpu/drm/i915/pxp/intel_pxp_types.h |  9 +
  7 files changed, 61 insertions(+), 16 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 034b53a71541..21c2b7cce335 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -62,8 +62,16 @@ static void gsc_work(struct work_struct *work)
}
  
  		ret = intel_gsc_proxy_request_handler(gsc);

-   if (ret)
+   if (ret) {
+   if (actions & GSC_ACTION_FW_LOAD) {
+   /*
+* A failure right after firmware load means 
the proxy-init
+* step has failed so mark GSC as not usable 
after this
+*/
+   intel_uc_fw_change_status(>fw, 
INTEL_UC_FIRMWARE_LOAD_FAIL);


Note that proxy init can also fail below if the init_done check returns 
false, so the status needs to be changed in both cases.


Daniele


+   }
goto out_put;
+   }
  
  		/* mark the GSC FW init as done the first time we run this */

if (actions & GSC_ACTION_FW_LOAD) {
diff --git a/drivers/gpu/drm/i915/i915_getparam.c 
b/drivers/gpu/drm/i915/i915_getparam.c
index 890f2b382bee..5c3fec63cb4c 100644
--- a/drivers/gpu/drm/i915/i915_getparam.c
+++ b/drivers/gpu/drm/i915/i915_getparam.c
@@ -109,7 +109,7 @@ int i915_getparam_ioctl(struct drm_device *dev, void *data,
return value;
break;
case I915_PARAM_PXP_STATUS:
-   value = intel_pxp_get_readiness_status(i915->pxp);
+   value = intel_pxp_get_readiness_status(i915->pxp, 0);
if (value < 0)
return value;
break;
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index bb2e15329f34..e3b47525dc60 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -359,22 +359,46 @@ void intel_pxp_end(struct intel_pxp *pxp)
intel_runtime_pm_put(>runtime_pm, wakeref);
  }
  
+static bool pxp_required_fw_failed(struct intel_pxp *pxp)

+{
+   if (__intel_uc_fw_status(>ctrl_gt->uc.huc.fw) == 
INTEL_UC_FIRMWARE_LOAD_FAIL)
+   return true;
+   if (HAS_ENGINE(pxp->ctrl_gt, GSC0) &&
+   __intel_uc_fw_status(>ctrl_gt->uc.gsc.fw) == 
INTEL_UC_FIRMWARE_LOAD_FAIL)
+   return true;
+
+   return false;
+}
+
+static bool pxp_fw_dependencies_completed(struct intel_pxp *pxp)
+{
+   if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
+   return intel_pxp_gsccs_is_ready_for_sessions(pxp);
+
+   return pxp_component_bound(pxp);
+}
+
  /*
   * this helper is used by both intel_pxp_start and by
   * the GET_PARAM IOCTL that user space calls. Thus, the
   * return values here should match the UAPI spec.
   */
-int intel_pxp_get_readiness_status(struct intel_pxp *pxp)
+int intel_pxp_get_readiness_status(struct intel_pxp *pxp, int 

Re: [Intel-gfx] [PATCH v6] drm/i915/selftest/gsc: Ensure GSC Proxy init completes before selftests

2023-07-20 Thread Ceraolo Spurio, Daniele




On 7/20/2023 2:40 PM, Alan Previn wrote:

On MTL, if the GSC Proxy init flows haven't completed, submissions to the
GSC engine will fail. Those init flows are dependent on the mei's
gsc_proxy component that is loaded in parallel with i915 and a
worker that could potentially start after i915 driver init is done.

That said, all subsytems that access the GSC engine today does check
for such init flow completion before using the GSC engine. However,
selftests currently don't wait on anything before starting.

To fix this, add a waiter function at the start of __run_selftests
that waits for gsc-proxy init flows to complete. Selftests shouldn't
care if the proxy-init failed as that should be flagged elsewhere.

Difference from prior versions:
v6: - Add a helper that returns something more than a boolean
  so we selftest can stop waiting if proxy-init hadn't
  completed but failed (Daniele).
v5: - Move the call to __wait_gsc_proxy_completed from common
  __run_selftests dispatcher to the group-level selftest
  function (Trvtko).
- change the pr_info to pr_warn if we hit the timeout.
v4: - Remove generalized waiters function table framework (Tvrtko).
- Remove mention of CI-framework-timeout from comments (Tvrtko).
v3: - Rebase to latest drm-tip.
v2: - Based on internal testing, increase the timeout for gsc-proxy
  specific case to 8 seconds.

Signed-off-by: Alan Previn 
---
  drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 14 +
  drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h |  1 +
  .../gpu/drm/i915/selftests/i915_selftest.c| 31 +++
  3 files changed, 46 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index ab1a456f833d..163021705210 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -45,6 +45,20 @@ bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc 
*gsc, bool needs_wakere
   HECI1_FWSTS1_PROXY_STATE_NORMAL;
  }
  
+int intel_gsc_uc_fw_proxy_get_status(struct intel_gsc_uc *gsc)

+{
+   if (!(IS_ENABLED(CONFIG_INTEL_MEI_GSC_PROXY)))
+   return -ENODEV;
+   if (!intel_uc_fw_is_loadable(>fw))
+   return -ENODEV;
+   if (__intel_uc_fw_status(>fw) == INTEL_UC_FIRMWARE_LOAD_FAIL)


You're missing the change to move the FW status to LOAD_FAIL if the 
proxy fails to initialize. Or are you expecting 
https://patchwork.freedesktop.org/series/118723/, which included that 
change, to be merged first?


Daniele


+   return -ENOLINK;
+   if (!intel_gsc_uc_fw_proxy_init_done(gsc, true))
+   return -EAGAIN;
+
+   return 0;
+}
+
  bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)
  {
return gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore, false) &
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
index ad2167ce9137..bc9dd0de8aaf 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
@@ -16,5 +16,6 @@ int intel_gsc_fw_get_binary_info(struct intel_uc_fw *gsc_fw, 
const void *data, s
  int intel_gsc_uc_fw_upload(struct intel_gsc_uc *gsc);
  bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc);
  bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc, bool 
needs_wakeref);
+int intel_gsc_uc_fw_proxy_get_status(struct intel_gsc_uc *gsc);
  
  #endif

diff --git a/drivers/gpu/drm/i915/selftests/i915_selftest.c 
b/drivers/gpu/drm/i915/selftests/i915_selftest.c
index 39da0fb0d6d2..ee79e0809a6d 100644
--- a/drivers/gpu/drm/i915/selftests/i915_selftest.c
+++ b/drivers/gpu/drm/i915/selftests/i915_selftest.c
@@ -24,6 +24,8 @@
  #include 
  
  #include "gt/intel_gt_pm.h"

+#include "gt/uc/intel_gsc_fw.h"
+
  #include "i915_driver.h"
  #include "i915_drv.h"
  #include "i915_selftest.h"
@@ -127,6 +129,31 @@ static void set_default_test_all(struct selftest *st, 
unsigned int count)
st[i].enabled = true;
  }
  
+static bool

+__gsc_proxy_init_progressing(struct intel_gsc_uc *gsc)
+{
+   return intel_gsc_uc_fw_proxy_get_status(gsc) == -EAGAIN;
+}
+
+static void
+__wait_gsc_proxy_completed(struct drm_i915_private *i915)
+{
+   bool need_to_wait = (IS_ENABLED(CONFIG_INTEL_MEI_GSC_PROXY) &&
+i915->media_gt &&
+HAS_ENGINE(i915->media_gt, GSC0) &&
+
intel_uc_fw_is_loadable(>media_gt->uc.gsc.fw));
+   /*
+* The gsc proxy component depends on the kernel component driver load 
ordering
+* and in corner cases (the first time after an IFWI flash), 
init-completion
+* firmware flows take longer.
+*/
+   unsigned long timeout_ms = 8000;
+
+   if (need_to_wait && 
wait_for(!__gsc_proxy_init_progressing(>media_gt->uc.gsc),
+timeout_ms))
+ 

Re: [Intel-gfx] [PATCH v5] drm/i915/selftest/gsc: Ensure GSC Proxy init completes before selftests

2023-07-20 Thread Ceraolo Spurio, Daniele




On 7/12/2023 4:12 PM, Alan Previn wrote:

On MTL, if the GSC Proxy init flows haven't completed, submissions to the
GSC engine will fail. Those init flows are dependent on the mei's
gsc_proxy component that is loaded in parallel with i915 and a
worker that could potentially start after i915 driver init is done.

That said, all subsytems that access the GSC engine today does check
for such init flow completion before using the GSC engine. However,
selftests currently don't wait on anything before starting.

To fix this, add a waiter function at the start of __run_selftests
that waits for gsc-proxy init flows to complete.

Difference from prior versions:
v5: - Move the call to __wait_gsc_proxy_completed from common
  __run_selftests dispatcher to the group-level selftest
  function (Trvtko).
- change the pr_info to pr_warn if we hit the timeout.
v4: - Remove generalized waiters function table framework (Tvrtko).
- Remove mention of CI-framework-timeout from comments (Tvrtko).
v3: - Rebase to latest drm-tip.
v2: - Based on internal testing, increase the timeout for gsc-proxy
  specific case to 8 seconds.

Signed-off-by: Alan Previn 
---
  .../gpu/drm/i915/selftests/i915_selftest.c| 26 +++
  1 file changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_selftest.c 
b/drivers/gpu/drm/i915/selftests/i915_selftest.c
index 39da0fb0d6d2..b03d03eac3d6 100644
--- a/drivers/gpu/drm/i915/selftests/i915_selftest.c
+++ b/drivers/gpu/drm/i915/selftests/i915_selftest.c
@@ -24,6 +24,8 @@
  #include 
  
  #include "gt/intel_gt_pm.h"

+#include "gt/uc/intel_gsc_fw.h"
+
  #include "i915_driver.h"
  #include "i915_drv.h"
  #include "i915_selftest.h"
@@ -127,6 +129,26 @@ static void set_default_test_all(struct selftest *st, 
unsigned int count)
st[i].enabled = true;
  }
  
+static void

+__wait_gsc_proxy_completed(struct drm_i915_private *i915)
+{
+   bool need_to_wait = (IS_ENABLED(CONFIG_INTEL_MEI_GSC_PROXY) &&
+i915->media_gt &&
+HAS_ENGINE(i915->media_gt, GSC0) &&
+
intel_uc_fw_is_loadable(>media_gt->uc.gsc.fw));
+   /*
+* The gsc proxy component depends on the kernel component driver load 
ordering
+* and in corner cases (the first time after an IFWI flash), 
init-completion
+* firmware flows take longer.
+*/
+   unsigned long timeout_ms = 8000;
+
+   if (need_to_wait &&
+   (wait_for(intel_gsc_uc_fw_proxy_init_done(>media_gt->uc.gsc, 
true),


Small issue here: if proxy init fails, intel_gsc_uc_fw_proxy_init_done 
will keep returning false, so we'll wait for the full 8 secs. Maybe we 
can instead have a proxy_init_status function to differentiate between 
pending/failed/done. This would basically be a generalization of the 
checks you already have in https://patchwork.freedesktop.org/series/118723/.

Patch LGTM apart from this.

Daniele


+   timeout_ms)))
+   pr_warn(DRIVER_NAME "Timed out waiting for 
gsc_proxy_completion!\n");
+}
+
  static int __run_selftests(const char *name,
   struct selftest *st,
   unsigned int count,
@@ -206,6 +228,8 @@ int i915_live_selftests(struct pci_dev *pdev)
if (!i915_selftest.live)
return 0;
  
+	__wait_gsc_proxy_completed(pdev_to_i915(pdev));

+
err = run_selftests(live, pdev_to_i915(pdev));
if (err) {
i915_selftest.live = err;
@@ -227,6 +251,8 @@ int i915_perf_selftests(struct pci_dev *pdev)
if (!i915_selftest.perf)
return 0;
  
+	__wait_gsc_proxy_completed(pdev_to_i915(pdev));

+
err = run_selftests(perf, pdev_to_i915(pdev));
if (err) {
i915_selftest.perf = err;

base-commit: 57ea1a97c50c63c77e3bfa46ee486e8a451be5e7




Re: [Intel-gfx] [PATCH] drm/i915/huc: check HuC and GuC version compatibility on MTL

2023-07-12 Thread Ceraolo Spurio, Daniele




On 7/12/2023 3:03 AM, Andrzej Hajda wrote:

On 11.07.2023 22:31, Daniele Ceraolo Spurio wrote:

Due to a change in the auth flow on MTL, GuC 70.7.0 and newer will only
be able to authenticate HuC 8.5.1 and newer. The plan is to update the 2
binaries sinchronously in linux-firmware so that the fw repo always has
a matching pair that works; still, it's better to check in the kernel so
we can print an error message and abort HuC loading if the binaries are
out of sync instead of failing the authentication.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 42 
  1 file changed, 42 insertions(+)

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 08e16017584b..f0cc5bb47fa0 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -803,11 +803,53 @@ static int try_firmware_load(struct intel_uc_fw 
*uc_fw, const struct firmware **

  return 0;
  }
  +static int check_mtl_huc_guc_compatibility(struct intel_gt *gt,
+   struct intel_uc_fw_file *huc_selected)
+{
+    struct intel_uc_fw_file *guc_selected = 
>uc.guc.fw.file_selected;

+    struct intel_uc_fw_ver *huc_ver = _selected->ver;
+    struct intel_uc_fw_ver *guc_ver = _selected->ver;
+    bool new_huc;
+    bool new_guc;
+
+    /* we can only do this check after having fetched both GuC and 
HuC */

+    GEM_BUG_ON(!huc_selected->path || !guc_selected->path);
+
+    /*
+ * Due to changes in the authentication flow for MTL, HuC 8.5.1 
or newer
+ * requires GuC 70.7.0 or newer. Older HuC binaries will instead 
require

+ * GuC < 70.7.0.
+ */
+    new_huc = huc_ver->major > 8 ||
+  (huc_ver->major == 8 && huc_ver->minor > 5) ||
+  (huc_ver->major == 8 && huc_ver->minor == 5 && 
huc_ver->patch >= 1);

+
+    new_guc = guc_ver->major > 70 ||
+  (guc_ver->major == 70 && guc_ver->minor >= 7);


Wouldn't be more readable to define sth like UC_VER_FULL(v)
then use UC_VER_FULL(huc_ver) >= IP_VER_FULL(8, 5, 1).
I am not sure if it is worth for two checks.


We've been trying to avoid those kind of macros because the version 
would need to be a u64 under the hood (each version number is a u16) and 
therefore type casting would be required to make all the shifting work, 
which makes the macro nasty to look at and as you said IMO not worth it 
for just 2 checks. Note that the GuC is the exception because it 
guarantees its version fits in a u32, so there is some macro use in the 
GuC-specific code.






+
+    if (new_huc != new_guc) {
+    UNEXPECTED(gt, "HuC %u.%u.%u is incompatible with GuC 
%u.%u.%u\n",

+   huc_ver->major, huc_ver->minor, huc_ver->patch,
+   guc_ver->major, guc_ver->minor, guc_ver->patch);
+    gt_info(gt, "MTL GuC 70.7.0+ and HuC 8.5.1+ don't work with 
older releases\n");

+    return -ENOEXEC;
+    }
+
+    return 0;
+}
+
  int intel_uc_check_file_version(struct intel_uc_fw *uc_fw, bool 
*old_ver)

  {
  struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
  struct intel_uc_fw_file *wanted = _fw->file_wanted;
  struct intel_uc_fw_file *selected = _fw->file_selected;
+    int ret;
+
+    if (IS_METEORLAKE(gt->i915) && uc_fw->type == 
INTEL_UC_FW_TYPE_HUC) {


Moving this check inside check function would make it more generic, up 
to you.


This will hopefully never apply to any other platform. This is a light 
breach of the HuC compatibility contract, so I really don't want to have 
a generic function to handle it. I want it to be clear from a higher 
level that this is an exception for a specific platform. Maybe worth 
adding a comment? Would something like the following make things clearer?


/*
 * MTL has some compatibility issues with early GuC/HuC binaries
 * not working with newer ones. This is specific to MTL and we
 * don't expect it to extend to other platforms.
 */

Daniele



Reviewed-by: Andrzej Hajda 

Regards
Andrzej



+    ret = check_mtl_huc_guc_compatibility(gt, selected);
+    if (ret)
+    return ret;
+    }
    if (!wanted->ver.major || !selected->ver.major)
  return 0;






Re: [Intel-gfx] [PATCH v3] drm/i915/selftest/gsc: Ensure GSC Proxy init completes before selftests

2023-07-11 Thread Ceraolo Spurio, Daniele



@@ -134,6 +193,8 @@ static int __run_selftests(const char *name,
   {
int err = 0;
   
+	__wait_on_all_system_dependencies(data);

Why does this need to be top level selftests and not just a wait for
intel_gsc_uc_fw_proxy_init_done in the tests where it is relevant, via
some helper or something?

Alan: it was an offline decision because we didn't want to repeat
the same check for all permutations of selftests' subtests (i.e. considering
module params can dictate to skip some subtests but execute others).

Anyways, let me get back to you on how how many selftests' subtests actually 
excercise the
need for proxy-init to complete - if its just 1-to-2 subtest I'll move the 
remove the code
from here and move them into the individual subtests.


I don't think it is going to be easy to figure out which selftest are 
impacted. All selftests looping on all engines of course, but also tests 
triggering GT resets and/or messing with the system in other ways. Any 
new tests added will also need to be evaluated.


IMO there is minimal impact of having this check on every test. When 
running selftests we load i915 after the rest of the system has already 
fully booted, so there are no delays in getting the mei component up and 
therefore proxy init is sometimes completed even before the selftest 
code starts; when we do have to wait, it's usually for a very short 
time, because the expected total execution time for the GSC worker when 
not having to wait for the mei component to load is ~750ms (~200ms for 
GSC load + 20ms for HuC auth + ~500ms for proxy init). Having a few 
seconds added to the total selftests runtime is IMO a better option that 
having to maintain a list of impacted tests.


Daniele



Re: [Intel-gfx] [PATCH v1] drm/i915/gsc: Fix intel_gsc_uc_fw_proxy_init_done with directed wakerefs

2023-06-20 Thread Ceraolo Spurio, Daniele




On 6/16/2023 8:54 AM, Ceraolo Spurio, Daniele wrote:



On 6/15/2023 2:19 PM, Alan Previn wrote:

intel_gsc_uc_fw_proxy_init_done is used by a few code paths
and usages. However, certain paths need a wakeref while others
can't take a wakeref such as from the runtime_pm_resume callstack.

Add a param into this helper to allow callers to direct whether
to take the wakeref or not. This resolves the following bug:

    INFO: task sh:2607 blocked for more than 61 seconds.
    Not tainted 6.3.0-pxp-gsc-final-jun14+ #297
    "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this 
message.
    task:sh  state:D stack:13016 pid:2607 ppid:2602   
flags:0x4000

    Call Trace:
   
   __schedule+0x47b/0xe10
   schedule+0x58/0xd0
   rpm_resume+0x1cc/0x800
   ? __pfx_autoremove_wake_function+0x10/0x10
   __pm_runtime_resume+0x42/0x80
   __intel_runtime_pm_get+0x19/0x80 [i915]
   gsc_uc_get_fw_status+0x10/0x50 [i915]
   intel_gsc_uc_fw_init_done+0x9/0x20 [i915]
   intel_gsc_uc_load_start+0x5b/0x130 [i915]
   __uc_resume+0xa5/0x280 [i915]
   intel_runtime_resume+0xd4/0x250 [i915]
   ? __pfx_pci_pm_runtime_resume+0x10/0x10
    __rpm_callback+0x3c/0x160

Fixes: 8c33c3755b75 ("drm/i915/gsc: take a wakeref for the 
proxy-init-completion check")

Signed-off-by: Alan Previn 


Reviewed-by: Daniele Ceraolo Spurio 

I'm going to send a trybot of this patch with the FW definition patch, 
just to make sure there aren't any other issues that kick in once the 
FW is defined and the code starts being executed, and merge if the 
results are ok.


Trybot came back green 
(https://patchwork.freedesktop.org/series/119471/), so pushed.


Daniele



Daniele


---
  drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c  | 17 +++--
  drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h  |  2 +-
  drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c  |  2 +-
  drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c |  2 +-
  4 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c

index 856de9af1e3a..ab1a456f833d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -22,27 +22,32 @@ static bool gsc_is_in_reset(struct intel_uncore 
*uncore)

  HECI1_FWSTS1_CURRENT_STATE_RESET;
  }
  -static u32 gsc_uc_get_fw_status(struct intel_uncore *uncore)
+static u32 gsc_uc_get_fw_status(struct intel_uncore *uncore, bool 
needs_wakeref)

  {
  intel_wakeref_t wakeref;
  u32 fw_status = 0;
  -    with_intel_runtime_pm(uncore->rpm, wakeref)
-    fw_status = intel_uncore_read(uncore, 
HECI_FWSTS(MTL_GSC_HECI1_BASE, 1));

+    if (needs_wakeref)
+    wakeref = intel_runtime_pm_get(uncore->rpm);
  +    fw_status = intel_uncore_read(uncore, 
HECI_FWSTS(MTL_GSC_HECI1_BASE, 1));

+
+    if (needs_wakeref)
+    intel_runtime_pm_put(uncore->rpm, wakeref);
  return fw_status;
  }
  -bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc)
+bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc, bool 
needs_wakeref)

  {
  return REG_FIELD_GET(HECI1_FWSTS1_CURRENT_STATE,
- gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore)) ==
+ gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore,
+  needs_wakeref)) ==
 HECI1_FWSTS1_PROXY_STATE_NORMAL;
  }
    bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)
  {
-    return gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore) &
+    return gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore, false) &
 HECI1_FWSTS1_INIT_COMPLETE;
  }
  diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h

index 8d7b9e4f1ffc..ad2167ce9137 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
@@ -15,6 +15,6 @@ struct intel_uncore;
  int intel_gsc_fw_get_binary_info(struct intel_uc_fw *gsc_fw, const 
void *data, size_t size);

  int intel_gsc_uc_fw_upload(struct intel_gsc_uc *gsc);
  bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc);
-bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc);
+bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc, bool 
needs_wakeref);

    #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 85d90f0a15e3..75a3a0790ef3 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -72,7 +72,7 @@ static void gsc_work(struct work_struct *work)
   * complete the request handling cleanly, so we need to 
check the
   * status register to check if the proxy init was 
actually successful

   */
-    if (intel_gsc_uc_fw_proxy_init_done(gsc)) {
+    if (intel_gsc_uc_fw_proxy_init_done(gsc, false)) {
  

Re: [Intel-gfx] [PATCH v1] drm/i915/gsc: Fix intel_gsc_uc_fw_proxy_init_done with directed wakerefs

2023-06-16 Thread Ceraolo Spurio, Daniele




On 6/15/2023 2:19 PM, Alan Previn wrote:

intel_gsc_uc_fw_proxy_init_done is used by a few code paths
and usages. However, certain paths need a wakeref while others
can't take a wakeref such as from the runtime_pm_resume callstack.

Add a param into this helper to allow callers to direct whether
to take the wakeref or not. This resolves the following bug:

INFO: task sh:2607 blocked for more than 61 seconds.
Not tainted 6.3.0-pxp-gsc-final-jun14+ #297
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:sh  state:D stack:13016 pid:2607  ppid:2602   
flags:0x4000
Call Trace:
   
   __schedule+0x47b/0xe10
   schedule+0x58/0xd0
   rpm_resume+0x1cc/0x800
   ? __pfx_autoremove_wake_function+0x10/0x10
   __pm_runtime_resume+0x42/0x80
   __intel_runtime_pm_get+0x19/0x80 [i915]
   gsc_uc_get_fw_status+0x10/0x50 [i915]
   intel_gsc_uc_fw_init_done+0x9/0x20 [i915]
   intel_gsc_uc_load_start+0x5b/0x130 [i915]
   __uc_resume+0xa5/0x280 [i915]
   intel_runtime_resume+0xd4/0x250 [i915]
   ? __pfx_pci_pm_runtime_resume+0x10/0x10
__rpm_callback+0x3c/0x160

Fixes: 8c33c3755b75 ("drm/i915/gsc: take a wakeref for the proxy-init-completion 
check")
Signed-off-by: Alan Previn 


Reviewed-by: Daniele Ceraolo Spurio 

I'm going to send a trybot of this patch with the FW definition patch, 
just to make sure there aren't any other issues that kick in once the FW 
is defined and the code starts being executed, and merge if the results 
are ok.


Daniele


---
  drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c  | 17 +++--
  drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h  |  2 +-
  drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c  |  2 +-
  drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c |  2 +-
  4 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index 856de9af1e3a..ab1a456f833d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -22,27 +22,32 @@ static bool gsc_is_in_reset(struct intel_uncore *uncore)
HECI1_FWSTS1_CURRENT_STATE_RESET;
  }
  
-static u32 gsc_uc_get_fw_status(struct intel_uncore *uncore)

+static u32 gsc_uc_get_fw_status(struct intel_uncore *uncore, bool 
needs_wakeref)
  {
intel_wakeref_t wakeref;
u32 fw_status = 0;
  
-	with_intel_runtime_pm(uncore->rpm, wakeref)

-   fw_status = intel_uncore_read(uncore, 
HECI_FWSTS(MTL_GSC_HECI1_BASE, 1));
+   if (needs_wakeref)
+   wakeref = intel_runtime_pm_get(uncore->rpm);
  
+	fw_status = intel_uncore_read(uncore, HECI_FWSTS(MTL_GSC_HECI1_BASE, 1));

+
+   if (needs_wakeref)
+   intel_runtime_pm_put(uncore->rpm, wakeref);
return fw_status;
  }
  
-bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc)

+bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc, bool 
needs_wakeref)
  {
return REG_FIELD_GET(HECI1_FWSTS1_CURRENT_STATE,
-gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore)) ==
+gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore,
+ needs_wakeref)) ==
   HECI1_FWSTS1_PROXY_STATE_NORMAL;
  }
  
  bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)

  {
-   return gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore) &
+   return gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore, false) &
   HECI1_FWSTS1_INIT_COMPLETE;
  }
  
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h

index 8d7b9e4f1ffc..ad2167ce9137 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
@@ -15,6 +15,6 @@ struct intel_uncore;
  int intel_gsc_fw_get_binary_info(struct intel_uc_fw *gsc_fw, const void 
*data, size_t size);
  int intel_gsc_uc_fw_upload(struct intel_gsc_uc *gsc);
  bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc);
-bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc);
+bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc, bool 
needs_wakeref);
  
  #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 85d90f0a15e3..75a3a0790ef3 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -72,7 +72,7 @@ static void gsc_work(struct work_struct *work)
 * complete the request handling cleanly, so we need to 
check the
 * status register to check if the proxy init was 
actually successful
 */
-   if (intel_gsc_uc_fw_proxy_init_done(gsc)) {
+   if (intel_gsc_uc_fw_proxy_init_done(gsc, false)) {
drm_dbg(>i915->drm, "GSC Proxy 

Re: [Intel-gfx] [CI] drm/i915/huc: Fix missing error code in intel_huc_init()

2023-06-15 Thread Ceraolo Spurio, Daniele




On 6/14/2023 3:36 PM, Daniele Ceraolo Spurio wrote:

From: Harshit Mogalapalli 

Smatch warns:
drivers/gpu/drm/i915/gt/uc/intel_huc.c:388
intel_huc_init() warn: missing error code 'err'

When the allocation of VMAs fail: The value of err is zero at this
point and it is passed to PTR_ERR and also finally returning zero which
is success instead of failure.

Fix this by adding the missing error code when VMA allocation fails.

Fixes: 08872cb13a71 ("drm/i915/mtl/huc: auth HuC via GSC")
Signed-off-by: Harshit Mogalapalli 
Reviewed-by: Daniele Ceraolo Spurio 


CI came back green, so patch merged.

Daniele


---

Re-sending for testing, because it looks like the original didn't make
it to intel-gfx and patchwork.

  drivers/gpu/drm/i915/gt/uc/intel_huc.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index d3a7219e9ed1..bb95bdd1c3f9 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -384,6 +384,7 @@ int intel_huc_init(struct intel_huc *huc)
  
  		vma = intel_guc_allocate_vma(>uc.guc, PXP43_HUC_AUTH_INOUT_SIZE * 2);

if (IS_ERR(vma)) {
+   err = PTR_ERR(vma);
huc_info(huc, "Failed to allocate heci pkt\n");
goto out;
}




Re: [Intel-gfx] [PATCH next] drm/i915/huc: Fix missing error code in intel_huc_init()

2023-06-14 Thread Ceraolo Spurio, Daniele




On 6/14/2023 1:41 PM, Harshit Mogalapalli wrote:

Smatch warns:
drivers/gpu/drm/i915/gt/uc/intel_huc.c:388
intel_huc_init() warn: missing error code 'err'

When the allocation of VMAs fail: The value of err is zero at this
point and it is passed to PTR_ERR and also finally returning zero which
is success instead of failure.

Fix this by adding the missing error code when VMA allocation fails.

Fixes: 08872cb13a71 ("drm/i915/mtl/huc: auth HuC via GSC")
Signed-off-by: Harshit Mogalapalli 


Thanks for the fix.

Reviewed-by: Daniele Ceraolo Spurio 

It looks like the patch wasn't picked out by our CI, so I'm going to 
re-send it to intel-gfx for testing and then merge it via drm-intel once 
we get the results.


Daniele


---
Found using Static analysis with Smatch, only compile tested.
---
  drivers/gpu/drm/i915/gt/uc/intel_huc.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index e0afd8f89502..ddd146265beb 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -384,6 +384,7 @@ int intel_huc_init(struct intel_huc *huc)
  
  		vma = intel_guc_allocate_vma(>uc.guc, PXP43_HUC_AUTH_INOUT_SIZE * 2);

if (IS_ERR(vma)) {
+   err = PTR_ERR(vma);
huc_info(huc, "Failed to allocate heci pkt\n");
goto out;
}




Re: [Intel-gfx] [PATCH v2] drm/i915/gsc: take a wakeref for the proxy-init-completion check

2023-06-09 Thread Ceraolo Spurio, Daniele




On 6/8/2023 4:07 PM, Alan Previn wrote:

Ensure intel_gsc_uc_fw_init_done and intel_gsc_uc_fw_proxy_init
takes a wakeref before reading GSC Shim registers.

NOTE: another patch in review also adds a call from selftest to
this same function. (https://patchwork.freedesktop.org/series/117713/)
which is why i am adding the wakeref inside the callee, not the
caller.

v2: - add a helper, 'gsc_uc_get_fw_status' for both callers
   (Daniele Ceraolo)

Fixes: 99afb7cc8c44 ("drm/i915/pxp: Add ARB session creation and cleanup")
Signed-off-by: Alan Previn 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 22 ++
  1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index f46eb17a7a98..60e9c6c9e775 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -24,21 +24,27 @@ static bool gsc_is_in_reset(struct intel_uncore *uncore)
   GSC_FW_CURRENT_STATE_RESET;
  }
  
-bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc)

+static u32 gsc_uc_get_fw_status(struct intel_uncore *uncore)
  {
-   struct intel_uncore *uncore = gsc_uc_to_gt(gsc)->uncore;
-   u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
+   intel_wakeref_t wakeref;
+   u32 fw_status = 0;
  
-	return REG_FIELD_GET(GSC_FW_CURRENT_STATE, fw_status) ==

+   with_intel_runtime_pm(uncore->rpm, wakeref)
+   fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
+
+   return fw_status;
+}
+
+bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc)
+{
+   return REG_FIELD_GET(GSC_FW_CURRENT_STATE,
+gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore)) ==
   GSC_FW_PROXY_STATE_NORMAL;
  }
  
  bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)

  {
-   struct intel_uncore *uncore = gsc_uc_to_gt(gsc)->uncore;
-   u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
-
-   return fw_status & GSC_FW_INIT_COMPLETE_BIT;
+   return gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore) & 
GSC_FW_INIT_COMPLETE_BIT;
  }
  
  static int emit_gsc_fw_load(struct i915_request *rq, struct intel_gsc_uc *gsc)


base-commit: 27187d09511e1d47dbaaf91c7332319551a8edab




Re: [Intel-gfx] [PATCH v1] drm/i915/gsc: take a wakeref for the proxy-init-completion check

2023-06-08 Thread Ceraolo Spurio, Daniele




On 6/8/2023 11:04 AM, Alan Previn wrote:

Ensure intel_gsc_uc_fw_init_done and intel_gsc_uc_fw_proxy_init
takes a wakeref before reading GSC Shim registers.

NOTE: another patch in review also adds a call from selftest to
this same function. (https://patchwork.freedesktop.org/series/117713/)
which is why i am adding the wakeref inside the callee, not the
caller.

Fixes: 99afb7cc8c44 ("drm/i915/pxp: Add ARB session creation and cleanup")
Signed-off-by: Alan Previn 
---
  drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 12 ++--
  1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index f46eb17a7a98..1e5a8b2bdac9 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -27,7 +27,11 @@ static bool gsc_is_in_reset(struct intel_uncore *uncore)
  bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc)
  {
struct intel_uncore *uncore = gsc_uc_to_gt(gsc)->uncore;
-   u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
+   intel_wakeref_t wakeref;
+   u32 fw_status;
+
+   with_intel_runtime_pm(uncore->rpm, wakeref)
+   fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);


I think this could be moved to an helper (gsc_uc_get_fw_status?), so we 
don't have to re-do the wakeref in all the callers.


Daniele

  
  	return REG_FIELD_GET(GSC_FW_CURRENT_STATE, fw_status) ==

   GSC_FW_PROXY_STATE_NORMAL;
@@ -36,7 +40,11 @@ bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc 
*gsc)
  bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)
  {
struct intel_uncore *uncore = gsc_uc_to_gt(gsc)->uncore;
-   u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
+   intel_wakeref_t wakeref;
+   u32 fw_status;
+
+   with_intel_runtime_pm(uncore->rpm, wakeref)
+   fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
  
  	return fw_status & GSC_FW_INIT_COMPLETE_BIT;

  }

base-commit: 27187d09511e1d47dbaaf91c7332319551a8edab




Re: [Intel-gfx] [PATCH] drm/i915/guc: Force a reset on internal GuC error

2023-06-06 Thread Ceraolo Spurio, Daniele




On 6/5/2023 1:54 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

If GuC hits an internal error (and survives long enough to report it
to the KMD), it is basically toast and will stop until a GT reset and
subsequent GuC reload is performed. Previously, the KMD just printed
an error message and then waited for the heartbeat to eventually kick
in and trigger a reset (assuming the heartbeat had not been disabled).
Instead, force the reset immediately to guarantee that it happens and
to eliminate the very long heartbeat delay. The captured error state
is also more likely to be useful if captured at the time of the error
rather than many seconds later.

Note that it is not possible to trigger a reset from with the G2H
handler itself. The reset prepare process involves flushing
outstanding G2H contents. So a deadlock could result. Instead, the G2H
handler queues a worker thread to do the reset asynchronously.

Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_guc.c| 26 +++
  drivers/gpu/drm/i915/gt/uc/intel_guc.h|  9 
  drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |  6 +-
  3 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 2eb891b270aec..c35cf10f52b56 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -159,6 +159,13 @@ static void gen11_disable_guc_interrupts(struct intel_guc 
*guc)
gen11_reset_guc_interrupts(guc);
  }
  
+static void guc_dead_worker_func(struct work_struct *w)

+{
+   struct intel_guc *guc = container_of(w, struct intel_guc, 
dead_guc_worker);
+
+   intel_gt_handle_error(guc_to_gt(guc), ALL_ENGINES, I915_ERROR_CAPTURE, "dead 
GuC");
+}
+
  void intel_guc_init_early(struct intel_guc *guc)
  {
struct intel_gt *gt = guc_to_gt(guc);
@@ -171,6 +178,8 @@ void intel_guc_init_early(struct intel_guc *guc)
intel_guc_slpc_init_early(>slpc);
intel_guc_rc_init_early(guc);
  
+	INIT_WORK(>dead_guc_worker, guc_dead_worker_func);

+
mutex_init(>send_mutex);
spin_lock_init(>irq_lock);
if (GRAPHICS_VER(i915) >= 11) {
@@ -585,6 +594,20 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 
*request, u32 len,
return ret;
  }
  
+int intel_guc_crash_process_msg(struct intel_guc *guc, u32 action)

+{
+   if (action == INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED)
+   guc_err(guc, "Crash dump notification\n");
+   else if (action == INTEL_GUC_ACTION_NOTIFY_EXCEPTION)
+   guc_err(guc, "Exception notification\n");
+   else
+   guc_err(guc, "Unknown crash notification\n");
+
+   queue_work(system_unbound_wq, >dead_guc_worker);


Do we need to flush the worker on suspend/unload?


+
+   return 0;
+}
+
  int intel_guc_to_host_process_recv_msg(struct intel_guc *guc,
   const u32 *payload, u32 len)
  {
@@ -601,6 +624,9 @@ int intel_guc_to_host_process_recv_msg(struct intel_guc 
*guc,
if (msg & INTEL_GUC_RECV_MSG_EXCEPTION)
guc_err(guc, "Received early exception notification!\n");
  
+	if (msg & (INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED | INTEL_GUC_RECV_MSG_EXCEPTION))

+   queue_work(system_unbound_wq, >dead_guc_worker);


I'm a bit worried about queuing this for a failure during the init flow. 
If we have a systemic issue (e.g. bad memory) we could end up trying and 
failing to reset & reload multiple times, until the wedge code manages 
to set the wedge on init flag.


Daniele


+
return 0;
  }
  
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h

index 8dc291ff00935..0b54eec95fc00 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -266,6 +266,14 @@ struct intel_guc {
unsigned long last_stat_jiffies;
} timestamp;
  
+	/**

+* @dead_guc_worker: Asynchronous worker thread for forcing a GuC reset.
+* Specifically used when the G2H handler wants to issue a reset. Resets
+* require flushing the G2H queue. So, the G2H processing itself must 
not
+* trigger a reset directly. Instead, go via this worker.
+*/
+   struct work_struct dead_guc_worker;
+
  #ifdef CONFIG_DRM_I915_SELFTEST
/**
 * @number_guc_id_stolen: The number of guc_ids that have been stolen
@@ -476,6 +484,7 @@ int intel_guc_engine_failure_process_msg(struct intel_guc 
*guc,
 const u32 *msg, u32 len);
  int intel_guc_error_capture_process_msg(struct intel_guc *guc,
const u32 *msg, u32 len);
+int intel_guc_crash_process_msg(struct intel_guc *guc, u32 action);
  
  struct intel_engine_cs *

  intel_guc_lookup_engine(struct intel_guc *guc, u8 guc_class, u8 instance);
diff --git 

Re: [Intel-gfx] [PATCH 6/6] drm/i915/uc/gsc: Add a gsc_info debugfs

2023-06-05 Thread Ceraolo Spurio, Daniele




On 6/5/2023 4:46 PM, Teres Alexis, Alan Previn wrote:

On Wed, 2023-05-31 at 17:25 -0700, Ceraolo Spurio, Daniele wrote:

On 5/26/2023 3:57 PM, Teres Alexis, Alan Previn wrote:

On Fri, 2023-05-05 at 09:04 -0700, Ceraolo Spurio, Daniele wrote:

Add a new debugfs to dump information about the GSC. This includes:

alan:snip
Actually everything looks good except for a couple of questions + asks - hope 
we can close on this patch in next rev.


- the FW path and SW tracking status;
- the release, security and compatibility versions;
- the HECI1 status registers.

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index 0b6dcd982b14..3014e982aab2 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -12,36 +12,31 @@
   #include "intel_gsc_fw.h"
   #include "intel_gsc_meu_headers.h"
   #include "intel_gsc_uc_heci_cmd_submit.h"
-
-#define GSC_FW_STATUS_REG  _MMIO(0x116C40)
-#define GSC_FW_CURRENT_STATE   REG_GENMASK(3, 0)
-#define   GSC_FW_CURRENT_STATE_RESET   0
-#define   GSC_FW_PROXY_STATE_NORMAL5
-#define GSC_FW_INIT_COMPLETE_BIT   REG_BIT(9)
+#include "i915_reg.h"
   

alan:snip
   
alan: btw, just to be consistent with other top-level "intel_foo_is..." checking functions,

why don't we take the runtime wakeref inside the following functions and make 
it easier for any callers?
(just like what we do for "intel_huc_is_authenticated"):
  static bool gsc_is_in_reset(struct intel_uncore *uncore)
  bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc)
  bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)

The idea was that we shouldn't check the FW status if we're not planning
to do something with it, in which case we should already have a wakeref.
HuC is a special case because userspace can query that when the HW is
idle. This said, I have nothing against adding an extra wakeref , but I
don't think it should be in this patch.

alan: i believe intel_pxp_gsccs_is_ready_for_sessions is being used in a
similar way where one of the uses it to check huc-status and gsc-proxy
status without actually doing any operation. If u still wanna keep it
differently then I'll have to update the PXP code. Or perhaps you could
help me fix that on the PXP side?


Sure, but let's take this to a separate patch. This patch is not adding 
that code nor any calls to it (just updating the defines), so it isn't 
the right place to add that fix.


Daniele



alna:snip

+void intel_gsc_uc_load_status(struct intel_gsc_uc *gsc, struct drm_printer *p)
+{
+   struct intel_gt *gt = gsc_uc_to_gt(gsc);
+   struct intel_uncore *uncore = gt->uncore;
+   intel_wakeref_t wakeref;
+
+   if (!intel_gsc_uc_is_supported(gsc)) {

alan: this was already checked in caller so we'll never get here. i think we 
should remove the check in the caller, let below msg appear.

I did the same as what we do for GuC and HuC. I'd prefer to be
consistent in behavior with those.

alan: okay - sounds good

+   drm_printf(p, "GSC not supported\n");
+   return;
+   }

alan:snip

+   drm_printf(p, "HECI1 FWSTST%u = 0x%08x\n", i, status);

alan:nit: do you we could add those additional shim regs? (seemed useful in 
recent offline debugs).

Agreed that it would be useful; I'll try to get a complete list from
arch and/or the GSC FW team. Are you ok if we go ahead with this in the
meantime?

alan: yes sure.




Re: [Intel-gfx] [PATCH 2/2] drm/i915/hdcp: Modify intel_gsc_send_sync function

2023-06-01 Thread Ceraolo Spurio, Daniele




On 5/29/2023 4:49 AM, Suraj Kandpal wrote:

Modify intel_gsc_send_sync() to take into account header_out
and addr_out so as to use them to verify the message send status.

Cc: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: Ankit Nautiyal 
Signed-off-by: Suraj Kandpal 


I think this patch should be squashed with the previous one, because if 
I understand correctly the code won't work with just the first one, 
which could be a problem with bisection. The changes themselves look ok 
to me though, so for the unified patch (with the small fix I pointed out 
in the other reply):


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/display/intel_hdcp_gsc.c | 29 +++
  1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c 
b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
index 72d1e261d0a9..5f29c3c559fa 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
@@ -726,38 +726,42 @@ void intel_hdcp_gsc_fini(struct drm_i915_private *i915)
  }
  
  static int intel_gsc_send_sync(struct drm_i915_private *i915,

-  struct intel_gsc_mtl_header *header, u64 addr,
+  struct intel_gsc_mtl_header *header_in,
+  struct intel_gsc_mtl_header *header_out,
+  u64 addr_in, u64 addr_out,
   size_t msg_out_len)
  {
struct intel_gt *gt = i915->media_gt;
int ret;
  
-	header->flags = 0;

-   ret = intel_gsc_uc_heci_cmd_submit_packet(>uc.gsc, addr,
- header->message_size,
- addr,
- msg_out_len + 
sizeof(*header));
+   ret = intel_gsc_uc_heci_cmd_submit_packet(>uc.gsc, addr_in,
+ header_in->message_size,
+ addr_out,
+ msg_out_len + 
sizeof(*header_out));
if (ret) {
drm_err(>drm, "failed to send gsc HDCP msg (%d)\n", ret);
return ret;
}
  
  	/*

-* Checking validity marker for memory sanity
+* Checking validity marker and header status to see if some error has
+* blocked us from sending message to gsc cs
 */
-   if (header->validity_marker != GSC_HECI_VALIDITY_MARKER) {
+   if (header_out->validity_marker != GSC_HECI_VALIDITY_MARKER) {
drm_err(>drm, "invalid validity marker\n");
return -EINVAL;
}
  
-	if (header->status != 0) {

+   if (header_out->status != 0) {
drm_err(>drm, "header status indicates error %d\n",
-   header->status);
+   header_out->status);
return -EINVAL;
}
  
-	if (header->flags & GSC_OUTFLAG_MSG_PENDING)

+   if (header_out->flags & GSC_OUTFLAG_MSG_PENDING) {
+   header_in->gsc_message_handle = header_out->gsc_message_handle;
return -EAGAIN;
+   }
  
  	return 0;

  }
@@ -809,7 +813,8 @@ ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private 
*i915, u8 *msg_in,
 * 20 times each message 50 ms apart
 */
do {
-   ret = intel_gsc_send_sync(i915, header_in, addr_in, 
msg_out_len);
+   ret = intel_gsc_send_sync(i915, header_in, header_out, addr_in,
+ addr_out, msg_out_len);
  
  		/* Only try again if gsc says so */

if (ret != -EAGAIN)




Re: [Intel-gfx] [PATCH 1/2] drm/i915/hdcp: Allocate a multipage object to hdcp_gsc_message

2023-06-01 Thread Ceraolo Spurio, Daniele




On 5/29/2023 4:49 AM, Suraj Kandpal wrote:

Allocate a multipage object that can be used for input
and output for intel_hdcp_gsc_message so that corruption of
output message can be avoided by the current overwriting method.

--v2
-Change approach from allocating two objects to just one multipage
object [Daniele]

Cc: Ankit Nautiyal 
Cc: Alan Previn 
Cc: Daniele Ceraolo Spurio 
Signed-off-by: Suraj Kandpal 
---
  drivers/gpu/drm/i915/display/intel_hdcp_gsc.c | 55 +++
  drivers/gpu/drm/i915/display/intel_hdcp_gsc.h |  3 +-
  2 files changed, 34 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c 
b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
index 7e52aea6aa17..72d1e261d0a9 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
@@ -621,24 +621,26 @@ static int intel_hdcp_gsc_initialize_message(struct 
drm_i915_private *i915,
struct intel_gt *gt = i915->media_gt;
struct drm_i915_gem_object *obj = NULL;
struct i915_vma *vma = NULL;
-   void *cmd;
+   void *cmd_in, *cmd_out;
int err;
  
-	/* allocate object of one page for HDCP command memory and store it */

-   obj = i915_gem_object_create_shmem(i915, PAGE_SIZE);
+   /* allocate object of two page for HDCP command memory and store it */
+   obj = i915_gem_object_create_shmem(i915, 2 * PAGE_SIZE);
  
  	if (IS_ERR(obj)) {

drm_err(>drm, "Failed to allocate HDCP streaming 
command!\n");
return PTR_ERR(obj);
}
  
-	cmd = i915_gem_object_pin_map_unlocked(obj, i915_coherent_map_type(i915, obj, true));

-   if (IS_ERR(cmd)) {
+   cmd_in = i915_gem_object_pin_map_unlocked(obj, 
i915_coherent_map_type(i915, obj, true));
+   if (IS_ERR(cmd_in)) {
drm_err(>drm, "Failed to map gsc message page!\n");
-   err = PTR_ERR(cmd);
+   err = PTR_ERR(cmd_in);
goto out_unpin;
}
  
+	cmd_out = cmd_in + PAGE_SIZE;

+
vma = i915_vma_instance(obj, >ggtt->vm, NULL);
if (IS_ERR(vma)) {
err = PTR_ERR(vma);
@@ -649,9 +651,10 @@ static int intel_hdcp_gsc_initialize_message(struct 
drm_i915_private *i915,
if (err)
goto out_unmap;
  
-	memset(cmd, 0, obj->base.size);

+   memset(cmd_in, 0, obj->base.size);
  
-	hdcp_message->hdcp_cmd = cmd;

+   hdcp_message->hdcp_cmd_in = cmd_in;
+   hdcp_message->hdcp_cmd_out = cmd_out;
hdcp_message->vma = vma;
  
  	return 0;

@@ -668,7 +671,7 @@ static int intel_hdcp_gsc_hdcp2_init(struct 
drm_i915_private *i915)
struct intel_hdcp_gsc_message *hdcp_message;
int ret;
  
-	hdcp_message = kzalloc(sizeof(*hdcp_message), GFP_KERNEL);

+   hdcp_message = kzalloc(2 * sizeof(*hdcp_message), GFP_KERNEL);


As far as I can see you only need 1 hdcp_message structure, so no need 
to double the alloc size here.

With this fixed:

Reviewed-by: Daniele Ceraolo Spurio 

Daniele

  
  	if (!hdcp_message)

return -ENOMEM;
@@ -691,6 +694,8 @@ static void intel_hdcp_gsc_free_message(struct 
drm_i915_private *i915)
struct intel_hdcp_gsc_message *hdcp_message =
i915->display.hdcp.hdcp_message;
  
+	hdcp_message->hdcp_cmd_in = NULL;

+   hdcp_message->hdcp_cmd_out = NULL;
i915_vma_unpin_and_release(_message->vma, I915_VMA_RELEASE_MAP);
kfree(hdcp_message);
  }
@@ -769,11 +774,11 @@ ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private 
*i915, u8 *msg_in,
size_t msg_out_len)
  {
struct intel_gt *gt = i915->media_gt;
-   struct intel_gsc_mtl_header *header;
-   const size_t max_msg_size = PAGE_SIZE - sizeof(*header);
+   struct intel_gsc_mtl_header *header_in, *header_out;
+   const size_t max_msg_size = PAGE_SIZE - sizeof(*header_in);
struct intel_hdcp_gsc_message *hdcp_message;
-   u64 addr, host_session_id;
-   u32 reply_size, msg_size;
+   u64 addr_in, addr_out, host_session_id;
+   u32 reply_size, msg_size_in, msg_size_out;
int ret, tries = 0;
  
  	if (!intel_uc_uses_gsc_uc(>uc))

@@ -782,16 +787,20 @@ ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private 
*i915, u8 *msg_in,
if (msg_in_len > max_msg_size || msg_out_len > max_msg_size)
return -ENOSPC;
  
+	msg_size_in = msg_in_len + sizeof(*header_in);

+   msg_size_out = msg_out_len + sizeof(*header_out);
hdcp_message = i915->display.hdcp.hdcp_message;
-   header = hdcp_message->hdcp_cmd;
-   addr = i915_ggtt_offset(hdcp_message->vma);
+   header_in = hdcp_message->hdcp_cmd_in;
+   header_out = hdcp_message->hdcp_cmd_out;
+   addr_in = i915_ggtt_offset(hdcp_message->vma);
+   addr_out = addr_in + PAGE_SIZE;
  
-	msg_size = 

Re: [Intel-gfx] [PATCH 5/6] drm/i915/uc/gsc: define gsc fw

2023-05-31 Thread Ceraolo Spurio, Daniele




On 5/25/2023 4:48 PM, Teres Alexis, Alan Previn wrote:

Considering the only request i have below is touching up of existing comments 
(as
far as this patch is concerned), and since the rest of the code looks good, 
here is
my R-b - but i hope you can anwser my newbie question at the bottom:

Reviewed-by: Alan Previn 

On Fri, 2023-05-05 at 09:04 -0700, Ceraolo Spurio, Daniele wrote:

Add FW definition and the matching override modparam.

The GSC FW has both a release version, based on platform and a rolling
counter, and a compatibility version, which is the one tracking
interface changes. Since what we care about is the interface, we use
the compatibility version in the buinary names.

alan :s/buinary/binary


Same as with the GuC, a major version bump indicate a
backward-incompatible change, while a minor version bump indicates a
backward-compatible one, so we use only the former in the file name.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 32 ++--
  1 file changed, 24 insertions(+), 8 deletions(-)

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 36ee96c02d74..531cd172151d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -124,6 +124,18 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
fw_def(BROXTON,  0, huc_mmp(bxt,  2, 0, 0)) \
fw_def(SKYLAKE,  0, huc_mmp(skl,  2, 0, 0))
  
+/*

+ * The GSC FW has both a release version, based on platform and a rolling
+ * counter, and a compatibility version, which is the one tracking
+ * interface changes. Since what we care about is the interface, we use
+ * the compatibility version in the buinary names.

alan:s/buinary/binary
also, since we will (i hope) be adding several comments (alongside the new
version objects under intel_gsc_uc structure) in the patch #3 about what
their differences are and which one we care about and when they get populated,
perhaps we can minimize the information here and redirect to that other
comment... OR ... we can minimize the comments in patch #3 and redirect here
(will be good to have a single location with detailed explaination in the
comments and a redirect-ptr from the other location since a reader would
most likely stumble onto those questions from either of these locations).


I'll redirect, that makes more sense




+ * Same as with the GuC, a major version bump indicate a
+ * backward-incompatible change, while a minor version bump indicates a
+ * backward-compatible one, so we use only the former in the file name.
+ */
+#define INTEL_GSC_FIRMWARE_DEFS(fw_def, gsc_def) \
+   fw_def(METEORLAKE,   0, gsc_def(mtl, 1, 0))
+
  /*
  


alan:snip


@@ -257,14 +281,6 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct 
intel_uc_fw *uc_fw)
int i;
bool found;
  
-	/*

-* GSC FW support is still not fully in place, so we're not defining
-* the FW blob yet because we don't want the driver to attempt to load
-* it until we're ready for it.
-*/
-   if (uc_fw->type == INTEL_UC_FW_TYPE_GSC)
-   return;
-

alan: more of a newbie question from myself: considering this is a new firmware
we are adding, is there some kind of requirement to provide a link to the patch
targetting the linux firmware repo that is a dependency of this series?
or perhaps we should mention in the series that merge will only happen after
that patch gets merged (with a final rev that includes the patch on
the fw-repo side?). Just trying to understand the process.


We usually merge the kernel patch first and do the pull-request to 
linux-firmware immediately after. We did have cases where we change 
firmware version between the first rev and the one that gets merged, so 
we only go to linux-firmware once we're sure it's not going to change 
anymore. Case in point, the GSC team has asked me to hold off in sending 
the current blob to linux-firmware because they have some pending fixes 
they want to include in the first "official" release.


Daniele





/*
 * The only difference between the ADL GuC FWs is the HWConfig support.
 * ADL-N does not support HWConfig, so we should use the same binary as




Re: [Intel-gfx] [PATCH 6/6] drm/i915/uc/gsc: Add a gsc_info debugfs

2023-05-31 Thread Ceraolo Spurio, Daniele




On 5/26/2023 3:57 PM, Teres Alexis, Alan Previn wrote:

On Fri, 2023-05-05 at 09:04 -0700, Ceraolo Spurio, Daniele wrote:

Add a new debugfs to dump information about the GSC. This includes:

alan:snip
Actually everything looks good except for a couple of questions + asks - hope 
we can close on this patch in next rev.


- the FW path and SW tracking status;
- the release, security and compatibility versions;
- the HECI1 status registers.

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index 0b6dcd982b14..3014e982aab2 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -12,36 +12,31 @@
  #include "intel_gsc_fw.h"
  #include "intel_gsc_meu_headers.h"
  #include "intel_gsc_uc_heci_cmd_submit.h"
-
-#define GSC_FW_STATUS_REG  _MMIO(0x116C40)
-#define GSC_FW_CURRENT_STATE   REG_GENMASK(3, 0)
-#define   GSC_FW_CURRENT_STATE_RESET   0
-#define   GSC_FW_PROXY_STATE_NORMAL5
-#define GSC_FW_INIT_COMPLETE_BIT   REG_BIT(9)
+#include "i915_reg.h"
  

alan:snip
  
alan: btw, just to be consistent with other top-level "intel_foo_is..." checking functions,

why don't we take the runtime wakeref inside the following functions and make 
it easier for any callers?
(just like what we do for "intel_huc_is_authenticated"):
 static bool gsc_is_in_reset(struct intel_uncore *uncore)
 bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc)
 bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)


The idea was that we shouldn't check the FW status if we're not planning 
to do something with it, in which case we should already have a wakeref. 
HuC is a special case because userspace can query that when the HW is 
idle. This said, I have nothing against adding an extra wakeref , but I 
don't think it should be in this patch.






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 2ae693b01b49..5475e95d61c6 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -9,8 +9,9 @@
  #include "gt/intel_gt_print.h"
  #include "intel_gsc_uc.h"

alan: nit: not this patch's fault, alphabetically, intel_gsc_uc.h is after 
intel_gsc_proxy.h


will fix


  #include "intel_gsc_fw.h"
-#include "i915_drv.h"
  #include "intel_gsc_proxy.h"
+#include "i915_drv.h"
+#include "i915_reg.h"
  
  static void gsc_work(struct work_struct *work)

  {
@@ -301,3 +302,46 @@ void intel_gsc_uc_load_start(struct intel_gsc_uc *gsc)
queue_work(gsc->wq, >work);
  }
+

alan: btw, why are we putting intel_gsc_uc_load_status in intel_gsc_uc.c if the 
only caller is gsc_uc's debugfs?
why not just make it a static in there? unless u plan to call it from 
"err_print_uc" - then can we add that in next rev?


I do indeed plan to follow up and add this to the error state, but I'll 
do that as a separate patch as I also want to add the GSC logs to the 
error state at the same time.





+void intel_gsc_uc_load_status(struct intel_gsc_uc *gsc, struct drm_printer *p)
+{
+   struct intel_gt *gt = gsc_uc_to_gt(gsc);
+   struct intel_uncore *uncore = gt->uncore;
+   intel_wakeref_t wakeref;
+
+   if (!intel_gsc_uc_is_supported(gsc)) {

alan: this was already checked in caller so we'll never get here. i think we 
should remove the check in the caller, let below msg appear.


I did the same as what we do for GuC and HuC. I'd prefer to be 
consistent in behavior with those.



+   drm_printf(p, "GSC not supported\n");
+   return;
+   }

alan:snip




+   drm_printf(p, "HECI1 FWSTST%u = 0x%08x\n", i, status);

alan:nit: do you we could add those additional shim regs? (seemed useful in 
recent offline debugs).


Agreed that it would be useful; I'll try to get a complete list from 
arch and/or the GSC FW team. Are you ok if we go ahead with this in the 
meantime?



alan:snip


diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.c
new file mode 100644
index ..da9f96b72291
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2020 Intel Corporation

alan:2023?


D'oh!

Daniele



alan:snip


diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.h 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.h
new file mode 100644
index ..c405e5574253
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2020 Intel Corporation

alan:2023?
alan:snip


diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b

Re: [Intel-gfx] [PATCH v3 5/7] drm/i915/mtl/huc: auth HuC via GSC

2023-05-31 Thread Ceraolo Spurio, Daniele




On 5/30/2023 5:33 PM, Teres Alexis, Alan Previn wrote:

On Fri, 2023-05-26 at 17:52 -0700, Ceraolo Spurio, Daniele wrote:

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.



alan:snip


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 b26f493f86fa..c659cc01f32f 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,32 @@ 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;

alan: I realize that this worker doesnt print error values that
come back from intel_gsc_uc_fw_upload - wonder if we should print
it before goto out_put.


intel_gsc_uc_fw_upload prints the error, so no need to double it up.




+
+   /*
+* 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.
+* Note that we can only do the GSC auth if the GuC auth was
+* successful.
+*/
+   if (intel_uc_uses_huc(>uc) &&
+   intel_huc_is_authenticated(>uc.huc, 
INTEL_HUC_AUTH_BY_GUC))
+   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 579c0f5a1438..0ad090304ca0 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


alan:snip


diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index ab5246ae3979..5a4058d39550 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c


alan:snip


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 d2b4176c81d6..8e538d639b05 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c


alan:snip



+int intel_huc_fw_auth_via_gsccs(struct intel_huc *huc)
+{
+   struct drm_i915_gem_object *obj;
+   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;

this 4K*2 (4k for input and 4K for output) seems to be hardcoded in two 
different locations.
One is here in intel_huc_fw_auth_via_gsccs and the other location in 
intel_huc_init which was
even in a different file. Perhaps its better to use a #define after to the 
definition of
PXP43_CMDID_NEW_HUC_AUTH... maybe something like a "#define 
PXP43_NEW_HUC_AUTH_INOUT_PKT_SIZE (SZ_4K)"


I can add it in.


+
+   intel_gsc_uc_heci_cmd_emit_mtl_header(_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_CM

Re: [Intel-gfx] [PATCH v3 3/7] drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so

2023-05-30 Thread Ceraolo Spurio, Daniele




On 5/30/2023 5:20 PM, John Harrison wrote:

On 5/30/2023 17:11, Ceraolo Spurio, Daniele wrote:

On 5/30/2023 4:51 PM, John Harrison wrote:

On 5/26/2023 17:52, 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 "has GSC 
headers"

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.

v2: s/is_meu_binary/has_gsc_headers/, clearer logs (John)

Signed-off-by: Daniele Ceraolo Spurio 


Cc: Alan Previn 
Cc: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_huc.c    | 29 
++-

  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  | 12 +-
  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 6d795438b3e4..37c6a8ca5c71 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 gsc_enabled = huc->fw.has_gsc_headers;
    /*
   * 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 && !gsc_enabled) {
+    huc_err(huc, "HW requires a GSC-enabled 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 GSC_enabled 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 && gsc_enabled && 
!huc->fw.dma_start_offset) {
+    huc_err(huc,"HW in DMA mode, but we have an incompatible 
GSC-enabled blob\n");

+    return -ENOEXEC;
+    }
The comment above doesn't seem to match the check. The comment says 
'we can load the old way if possible' whereas the check is more 'can 
we load the old way if we need to'.


I'll reword it.




+
+    /* 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) {
-    huc_info(huc, "can't load due to missing MEI modules\n");
+    !HAS_ENGINE(gt, GSC0) && huc->loaded_via_gsc) {
This test still looks wrong when you read it. I think it needs a 
more detailed comment. Some kind of explanation that the modules 
only apply to one platform and the engine to a different platform. 
Or even breaking into two separate tests with an 'if(DG2)' between 
them? It certainly confuses me every time I look at it.


Is it clearer if I split it like this?

/*
 * if the FW is loaded via GSC and we're not on a platform that
 * has the GSC CS, we need the mei modules to access the GSC.
 */
if (huc->loaded_via_gsc && !HAS_ENGINE(gt, GSC0)) {
    if (!IS_ENABLED(MEI_PXP) || !IS_ENABLED(MEI_GSC)
        // error
}

It is guaranteed that if the GSC engine is present then no modules are 
required? And that if the GSC engine is not present, then the modules 
are all that is required?


What happens if the GSC engine has been fused off? Or disabled by some 
future module override, workaround, etc.?


I thinking it would be both clearer and safer to say 'if (DG2) {check 
DG2 specific stuff} else {check other stuff}'.


ok, will do.

Daniele



John.



Daniele



John.

+    huc_info(huc, "can't load due to missing mei modules or 
GSCCS\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"

Re: [Intel-gfx] [PATCH v4] drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow

2023-05-30 Thread Ceraolo Spurio, Daniele




On 5/30/2023 5:01 PM, John Harrison wrote:

On 5/30/2023 08:29, 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

meu?


leftover from the meu drop. Will reword.




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

v3: add a better comment at the top of the HuC file to explain the
 different approaches to load and auth (John)

v4: update call to intel_huc_is_authenticated in the pxp code to check
for GSC authentication

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Reviewed-by: Alan Previn  #v2
---
  drivers/gpu/drm/i915/gt/uc/intel_huc.c | 111 -
  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 +
  drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c |   2 +-
  include/uapi/drm/i915_drm.h    |   3 +-
  6 files changed, 104 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c

index 37c6a8ca5c71..ab5246ae3979 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 
  #include 
@@ -22,15 +23,23 @@
   * capabilities by adding HuC specific commands to batch buffers.
   *
   * The kernel driver is only responsible for loading the HuC 
firmware and
- * triggering its security authentication, which is performed by the 
GuC on
- * older platforms and by the GSC on newer ones. For the GuC to 
correctly
- * perform the authentication, the HuC binary must be loaded before 
the GuC one.
+ * triggering its security authentication. This is done differently 
depending

+ * on the platform:
+ * - older platforms (from Gen9 to most Gen12s): the load is 
performed via DMA

+ *   and the authentication via GuC
+ * - DG2: load and authentication are both performed via GSC.
+ * - MTL and newer platforms: the load is performed via DMA (same as 
with
+ *   not-DG2 older platforms), while the authentication is done in 
2-steps,
+ *   a first auth for clear-media workloads via GuC and a second one 
for all

+ *   workloads via GSC.
+ * On platforms where the GuC does the authentication, to correctly 
do so the

+ * HuC binary must be loaded before the GuC one.
   * Loading the HuC is optional; however, not using the HuC might 
negatively
   * impact power usage and/or performance of media workloads, 
depending on the

   * use-cases.
   * HuC must be reloaded on events that cause the WOPCM to lose its 
contents
- * (S3/S4, FLR); GuC-authenticated HuC must also be reloaded on 
GuC/GT reset,

- * while GSC-managed HuC will survive that.
+ * (S3/S4, FLR); on older platforms the HuC must also be reloaded on 
GuC/GT

+ * reset, while on newer ones it will survive that.
   *
   * See https://github.com/intel/media-driver for the latest details 
on HuC

   * functionality.
@@ -106,7 +115,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 +133,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 +293,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;
+    

Re: [Intel-gfx] [PATCH v3 3/7] drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so

2023-05-30 Thread Ceraolo Spurio, Daniele




On 5/30/2023 4:51 PM, John Harrison wrote:

On 5/26/2023 17:52, 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 "has GSC 
headers"

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.

v2: s/is_meu_binary/has_gsc_headers/, clearer logs (John)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_huc.c    | 29 ++-
  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  | 12 +-
  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 6d795438b3e4..37c6a8ca5c71 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 gsc_enabled = huc->fw.has_gsc_headers;
    /*
   * 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 && !gsc_enabled) {
+    huc_err(huc, "HW requires a GSC-enabled 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 GSC_enabled 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 && gsc_enabled && 
!huc->fw.dma_start_offset) {
+    huc_err(huc,"HW in DMA mode, but we have an incompatible 
GSC-enabled blob\n");

+    return -ENOEXEC;
+    }
The comment above doesn't seem to match the check. The comment says 
'we can load the old way if possible' whereas the check is more 'can 
we load the old way if we need to'.


I'll reword it.




+
+    /* 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) {
-    huc_info(huc, "can't load due to missing MEI modules\n");
+    !HAS_ENGINE(gt, GSC0) && huc->loaded_via_gsc) {
This test still looks wrong when you read it. I think it needs a more 
detailed comment. Some kind of explanation that the modules only apply 
to one platform and the engine to a different platform. Or even 
breaking into two separate tests with an 'if(DG2)' between them? It 
certainly confuses me every time I look at it.


Is it clearer if I split it like this?

/*
 * if the FW is loaded via GSC and we're not on a platform that
 * has the GSC CS, we need the mei modules to access the GSC.
 */
if (huc->loaded_via_gsc && !HAS_ENGINE(gt, GSC0)) {
    if (!IS_ENABLED(MEI_PXP) || !IS_ENABLED(MEI_GSC)
        // error
}

Daniele



John.

+    huc_info(huc, "can't load due to missing mei modules or 
GSCCS\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 0789184d81a2..112f0dce4702 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 

Re: [Intel-gfx] [PATCH v3 2/7] drm/i915/huc: Parse the GSC-enabled HuC binary

2023-05-30 Thread Ceraolo Spurio, Daniele




On 5/30/2023 4:30 PM, John Harrison wrote:

On 5/26/2023 17:52, Daniele Ceraolo Spurio wrote:

The new binaries that support the 2-step authentication 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
manifest of the GSC-enabled HuC 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 GSC binary uses the same structures in its binary header,
so they've been added in their own header file.

v2: fix structure names to match meu defines (s/CPT/CPD/), update commit
 message, check ccs validity, drop old version location defines.

v3: drop references to the MEU tool to reduce confusion, fix log (John)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Reviewed-by: Alan Previn  #v2
---
  .../drm/i915/gt/uc/intel_gsc_binary_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_binary_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_binary_headers.h 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h

new file mode 100644
index ..714f0c256118
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef _INTEL_GSC_BINARY_HEADERS_H_
+#define _INTEL_GSC_BINARY_HEADERS_H_
+
+#include 
+
+/* 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_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_version fw_version;
+    u32 security_version;
+    struct intel_gsc_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 268e036f8f28..6d795438b3e4 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 
    #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 
  #include 
  -#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, 

Re: [Intel-gfx] [PATCH 3/6] drm/i915/uc/gsc: extract release and security versions from the gsc binary

2023-05-26 Thread Ceraolo Spurio, Daniele




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
index d55a66202576..8bce2b8aed84 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h

alan:snip




+struct intel_gsc_layout_pointers {
+   u8 rom_bypass_vector[16];

alan:snip...

+   u32 temp_pages_offset;
+   u32 temp_pages_size;
+} __packed;

alan: structure layout seems unnecessarily repetitive... why not ->
struct partition_info {
u32 offset;
u32 size;
};
struct intel_gsc_layout_pointers {
u8 rom_bypass_vector[16];
...
struct partition_info datap;
struct partition_info bootregion[5];
struct partition_info trace;
}__packed;



I've just realized that I didn't reply to this comment. The specs have 
the structure defined that way, so I tried to keep a 1:1 match like we 
usually do. I think switching to a partition_info structure is ok, but 
I'll avoid the array because the GSC partition are 1-based, which could 
cause confusion (i.e. partition boot1 would be bootregion[0]).


Daniele



Re: [Intel-gfx] [PATCH 3/6] drm/i915/uc/gsc: extract release and security versions from the gsc binary

2023-05-25 Thread Ceraolo Spurio, Daniele




On 5/24/2023 10:14 PM, Teres Alexis, Alan Previn wrote:

On Fri, 2023-05-05 at 09:04 -0700, Ceraolo Spurio, Daniele wrote:


alan: snip



+int intel_gsc_fw_get_binary_info(struct intel_uc_fw *gsc_fw, const void *data, 
size_t size)
+{

alan:snip

+   /*
+* The GSC binary starts with the pointer layout, which contains the
+* locations of the various partitions of the binary. The one we're
+* interested in to get the version is the boot1 partition, where we can
+* find a BPDT header followed by entries, one of which points to the
+* RBE sub-section of the partition. From here, we can parse the CPD

alan: nit: could we add the meaning of 'RBE', probably not here but in the 
header file where GSC_RBE is defined?


I have no idea what RBE means, the specs just says to look for the 
section named that way. I didn't dig because we don't really care about 
its name, just that the CPD header is in there.



+* header and the following entries to find the manifest location
+* (entry identified by the "RBEP.man" name), from which we can finally
+* extract the version.
+*
+* --
+* [  intel_gsc_layout_pointers ]
+* [  ...   ]
+* [  boot1_offset  >---]--o
+* [  ...   ]  |
+* --  |
+* |
+* --  |
+* [  intel_gsc_bpdt_header ]<-o
+* --

alan: special thanks for the diagram - love these! :)
alan: snip


+   min_size = layout->boot1_offset + layout->boot1_offset > size;

alan: latter is a binary so + 1? or is this a typo and supposed to be:
min_size = layout->boot1_offset;


it's a cut & paste typo, it should be

min_size = layout->boot1_offset + layout->boot1_size;

thanks for spotting it.


actually since we are accessing a bpdt_header hanging off that offset, it 
should rather be:
min_size = layout->boot1_offset + sizeof(*bpdt_header);


I can add a check to make sure that boot1_size >= sizeof(*bpdt_header)


+   if (size < min_size) {
+   gt_err(gt, "GSC FW too small for boot section! %zu < %zu\n",
+  size, min_size);
+   return -ENODATA;
+   }
+
+   bpdt_header = data + layout->boot1_offset;
+   if (bpdt_header->signature != INTEL_GSC_BPDT_HEADER_SIGNATURE) {
+   gt_err(gt, "invalid signature for meu BPDT header: 0x%08x!\n",
+  bpdt_header->signature);
+   return -EINVAL;
+   }
+

alan: IIUC, to be strict about the size-crawl-checking, we should check minsize
again - this time with the additional "bpdt_header->descriptor_count * 
sizeof(*bpdt_entry)".
(hope i got that right?) - adding that check before parsing through the 
(bpdt_entry++)'s ->type


will do (same for the comments below)


+   bpdt_entry = (void *)bpdt_header + sizeof(*bpdt_header);
+   for (i = 0; i < bpdt_header->descriptor_count; i++, bpdt_entry++) {
+   if ((bpdt_entry->type & INTEL_GSC_BPDT_ENTRY_TYPE_MASK) !=
+   INTEL_GSC_BPDT_ENTRY_TYPE_GSC_RBE)
+   continue;
+
+   cpd_header = (void *)bpdt_header + 
bpdt_entry->sub_partition_offset;
+   break;
+   }
+
+   if (!cpd_header) {
+   gt_err(gt, "couldn't find CPD header in GSC binary!\n");
+   return -ENODATA;
+   }

alan: same as above, so for size-crawl-checking, we should check minsize again 
with the addition of cpd_header, no?

+
+   if (cpd_header->header_marker != INTEL_GSC_CPD_HEADER_MARKER) {
+   gt_err(gt, "invalid marker for meu CPD header in GSC bin: 
0x%08x!\n",
+  cpd_header->header_marker);
+   return -EINVAL;
+   }

alan: and again here, the size crawl checking with cpd_header->num_of_entries * 
*cpd_entry

+   cpd_entry = (void *)cpd_header + cpd_header->header_length;
+   for (i = 0; i < cpd_header->num_of_entries; i++, cpd_entry++) {
+   if (strcmp(cpd_entry->name, "RBEP.man") == 0) {
+   manifest = (void *)cpd_header + 
cpd_entry_offset(cpd_entry);
+   intel_uc_fw_version_from_meu_manifest(>release,
+ manifest);
+   gsc->security_version = manifest->security_version;
+   break;
+ 

Re: [Intel-gfx] [PATCH] drm/i915/gsc: use system include style for drm headers

2023-05-25 Thread Ceraolo Spurio, Daniele




On 5/25/2023 2:49 AM, Jani Nikula wrote:

Use <> instead of "" for including headers from include/.

Fixes: 8a9bf29546a1 ("drm/i915/gsc: add initial support for GSC proxy")
Cc: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Signed-off-by: Jani Nikula 


dumb mistake, thanks for fixing it

Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
index ebee0b5a2c1d..5f138de3c14f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
@@ -5,8 +5,8 @@
  
  #include 
  
-#include "drm/i915_component.h"

-#include "drm/i915_gsc_proxy_mei_interface.h"
+#include 
+#include 
  
  #include "gt/intel_gt.h"

  #include "gt/intel_gt_print.h"




Re: [Intel-gfx] [PATCH 2/6] drm/i915/uc/gsc: fixes and updates for GSC memory allocation

2023-05-23 Thread Ceraolo Spurio, Daniele




On 5/22/2023 5:13 PM, Teres Alexis, Alan Previn wrote:

On Fri, 2023-05-05 at 09:04 -0700, Ceraolo Spurio, Daniele wrote:

A few fixes/updates are required around the GSC memory allocation and it
is easier to do them all at the same time. The changes are as follows:


alan:snip


@@ -109,38 +110,21 @@ static int gsc_fw_load_prepare(struct intel_gsc_uc *gsc)
  {
struct intel_gt *gt = gsc_uc_to_gt(gsc);
struct drm_i915_private *i915 = gt->i915;
-   struct drm_i915_gem_object *obj;
-   void *src, *dst;
+   void *src;


alan:snip

  
-	memset(dst, 0, obj->base.size);

-   memcpy(dst, src, gsc->fw.size);
+   memset_io(gsc->local_vaddr, 0, gsc->local->size);
+   memcpy_toio(gsc->local_vaddr, src, gsc->fw.size);

alan: i wonder if it there is benefit to do the memcpy_toio first
and then do the memset_io but only for the balance of area from
offset 'gsc->fw.size' for (gsc->local->size - gsc->fw.size) bytes.


I usually always memset first to start from a clean slate, but you're 
right I could flip this.




alan:snip


--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -130,26 +130,85 @@ void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc)
}
  }
  
+static int gsc_allocate_and_map_vma(struct intel_gsc_uc *gsc, u32 size)

alan:snip


+   obj = i915_gem_object_create_stolen(gt->i915, size);
+   if (IS_ERR(obj))
+   return PTR_ERR(obj);
+
+   vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, 0);

alan: should we be passing in the PIN_MAPPABLE flag into the last param?


No, PIN_MAPPABLE is only for legacy platform that used the aperture BAR 
for stolen mem access via GGTT. MTL doesn't have it and stolen is 
directly accessible via the LMEM BAR (which is actually the same BAR 2, 
but now behaves differently).





alan:snip


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 a2a0813b8a76..c01286dddbdb 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h
@@ -18,6 +18,7 @@ struct intel_gsc_uc {
  
  	/* GSC-specific additions */

struct i915_vma *local; /* private memory for GSC usage */
+   void __iomem *local_vaddr; /* pointer to access the private memory */

alan:nit: relooking at the these variable names that originate from
last year's patch you worked on introducing gsc_uc, i am wondering now
if we should rename "local" to "privmem" and local_vaddr becomes privmem_vaddr.
(no significant reason other than improving readibility of the code)


IIRC I used local because one of the GSC docs referred to it that way. I 
don't mind the renaming, but I don't think it should be done as part of 
this patch.


Daniele







Re: [Intel-gfx] [PATCH 1/2] drm/i915/hdcp: Create hdcp_gsc_message in and out

2023-05-22 Thread Ceraolo Spurio, Daniele




On 5/19/2023 2:49 AM, Suraj Kandpal wrote:

Add hdcp_gsc_message_in and hdcp_gsc_message_out to help
differenctiate the reply given by gsc to avoid any kind of
message corruption due message structure reuse.
hdcp_gsc_message_out will be filled in upcoming patches


Generic question on the approach: for both PXP and GSC proxy, we 
allocate a single multi-page object and use the first half for input and 
the second half output. This makes things simpler because we don't need 
to allocate, map and then cleanup 2 separate objects. Any reason not to 
follow a similar approach here?


Daniele



Cc: Ankit Nautiyal 
Cc: Alan Previn 
Cc: Daniele Ceraolo Spurio 
Signed-off-by: Suraj Kandpal 
---
  .../gpu/drm/i915/display/intel_display_core.h |  3 +-
  drivers/gpu/drm/i915/display/intel_hdcp_gsc.c | 41 +--
  2 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h 
b/drivers/gpu/drm/i915/display/intel_display_core.h
index e36f88a39b86..ead16d341f5c 100644
--- a/drivers/gpu/drm/i915/display/intel_display_core.h
+++ b/drivers/gpu/drm/i915/display/intel_display_core.h
@@ -403,7 +403,8 @@ struct intel_display {
 * reused when sending message to gsc cs.
 * this is only populated post Meteorlake
 */
-   struct intel_hdcp_gsc_message *hdcp_message;
+   struct intel_hdcp_gsc_message *hdcp_message_in;
+   struct intel_hdcp_gsc_message *hdcp_message_out;
/* Mutex to protect the above hdcp component related values. */
struct mutex comp_mutex;
} hdcp;
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c 
b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
index 7e52aea6aa17..be505b2d679e 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
@@ -665,34 +665,51 @@ static int intel_hdcp_gsc_initialize_message(struct 
drm_i915_private *i915,
  
  static int intel_hdcp_gsc_hdcp2_init(struct drm_i915_private *i915)

  {
-   struct intel_hdcp_gsc_message *hdcp_message;
+   struct intel_hdcp_gsc_message *hdcp_message_in, *hdcp_message_out;
int ret;
  
-	hdcp_message = kzalloc(sizeof(*hdcp_message), GFP_KERNEL);

+   hdcp_message_in = kzalloc(sizeof(*hdcp_message_in), GFP_KERNEL);
  
-	if (!hdcp_message)

+   if (!hdcp_message_in)
return -ENOMEM;
  
+	hdcp_message_out = kzalloc(sizeof(*hdcp_message_out), GFP_KERNEL);

+
+   if (!hdcp_message_out)
+   return -ENOMEM;
/*
 * NOTE: No need to lock the comp mutex here as it is already
 * going to be taken before this function called
 */
-   i915->display.hdcp.hdcp_message = hdcp_message;
-   ret = intel_hdcp_gsc_initialize_message(i915, hdcp_message);
+   i915->display.hdcp.hdcp_message_in = hdcp_message_in;
+   ret = intel_hdcp_gsc_initialize_message(i915, hdcp_message_in);
+
+   if (ret) {
+   drm_err(>drm, "Could not initialize hdcp_message_in\n");
+   goto out;
+   }
+
+   i915->display.hdcp.hdcp_message_out = hdcp_message_out;
+   ret = intel_hdcp_gsc_initialize_message(i915, hdcp_message_out);
  
  	if (ret)

-   drm_err(>drm, "Could not initialize hdcp_message\n");
+   drm_err(>drm, "Could not initialize hdcp_message_out\n");
  
+out:

return ret;
  }
  
  static void intel_hdcp_gsc_free_message(struct drm_i915_private *i915)

  {
-   struct intel_hdcp_gsc_message *hdcp_message =
-   i915->display.hdcp.hdcp_message;
-
-   i915_vma_unpin_and_release(_message->vma, I915_VMA_RELEASE_MAP);
-   kfree(hdcp_message);
+   struct intel_hdcp_gsc_message *hdcp_message_in =
+   i915->display.hdcp.hdcp_message_in;
+   struct intel_hdcp_gsc_message *hdcp_message_out =
+   i915->display.hdcp.hdcp_message_out;
+
+   i915_vma_unpin_and_release(_message_in->vma, I915_VMA_RELEASE_MAP);
+   i915_vma_unpin_and_release(_message_out->vma, 
I915_VMA_RELEASE_MAP);
+   kfree(hdcp_message_in);
+   kfree(hdcp_message_out);
  }
  
  int intel_hdcp_gsc_init(struct drm_i915_private *i915)

@@ -782,7 +799,7 @@ ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private 
*i915, u8 *msg_in,
if (msg_in_len > max_msg_size || msg_out_len > max_msg_size)
return -ENOSPC;
  
-	hdcp_message = i915->display.hdcp.hdcp_message;

+   hdcp_message = i915->display.hdcp.hdcp_message_in;
header = hdcp_message->hdcp_cmd;
addr = i915_ggtt_offset(hdcp_message->vma);
  




Re: [Intel-gfx] [PATCH v2 5/8] drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow

2023-05-19 Thread Ceraolo Spurio, Daniele




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 
Cc: Alan Previn 
---
  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 
  #include 
@@ -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,
+    

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 Thread Ceraolo Spurio, Daniele




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 
Cc: Alan Previn 
---
  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");
 

Re: [Intel-gfx] [PATCH v2] drm/i915/huc: Parse the GSC-enabled HuC binary

2023-05-19 Thread Ceraolo Spurio, Daniele




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 
Cc: Alan Previn 
---
  .../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 ..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 
+
+/* 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 
    #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 
  #include 
  -#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 

Re: [Intel-gfx] [PATCH v2 2/8] drm/i915/uc: perma-pin firmwares

2023-05-17 Thread Ceraolo Spurio, Daniele




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
Cc: Alan Previn
---
  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(>vm, ggtt->error_capture.start,
 ggtt->error_capture.size);
  +    list_for_each_entry(gt, >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(>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(>fw, INTEL_UC_FW_TYPE_GSC, false);
  INIT_WORK(>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(>fw, INTEL_UC_FW_TYPE_GUC);
+    intel_uc_fw_init_early(>fw, INTEL_UC_FW_TYPE_GUC, true);
  intel_guc_ct_init_early(>ct);
  intel_guc_log_init_early(>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(>fw, INTEL_UC_FW_TYPE_HUC);
+    intel_uc_fw_init_early(>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(>guc.fw);
+    intel_uc_fw_resume_mapping(>huc.fw);
+}
+
  static int __uc_resume(struct intel_uc *uc, bool enable_communication)
  {
  struct intel_guc *guc = >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, 

Re: [Intel-gfx] [PATCH v3 4/6] drm/i915/uc: Enhancements to firmware table validation

2023-05-05 Thread Ceraolo Spurio, Daniele




On 5/3/2023 1:40 AM, john.c.harri...@intel.com wrote:

From: John Harrison 

The validation of the firmware table was being done inside the code
for scanning the table for the next available firmware blob. Which is
unnecessary. So pull it out into a separate function that is only
called once per blob type at init time.

Also, drop the CONFIG_SELFTEST requirement and make errors terminal.
It was mentioned that potential issues with backports would not be
caught by regular pre-merge CI as that only occurs on tip not stable
branches. Making the validation unconditional and failing driver load
on detecting of a problem ensures that such backports will also be
validated correctly.

This requires adding a firmware global flag to indicate an issue with
any of the per firmware tables. This is done rather than adding a new
state enum as a new enum value would be a much more invasive change -
lots of places would need updating to support the new error state.

Note also that this change means that a table error will cause the
driver to wedge even on platforms that don't require firmware files.
This is intentional as per the above backport concern - someone doing
backports is not guaranteed to test on every platform that they may
potential affect. So forcing a failure on all platforms ensures that
the problem will be noticed and corrected immediately.

v2: Change to unconditionally fail module load on a validation error
(review feedback/discussion with Daniele).
v3: Add a new flag to track table validation errors (review
feedback/discussion with Daniele).

Signed-off-by: John Harrison 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/uc/intel_uc.c|   3 +
  drivers/gpu/drm/i915/gt/uc/intel_uc.h|   1 +
  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 161 +--
  3 files changed, 99 insertions(+), 66 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index 996168312340e..1381943b8973d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -432,6 +432,9 @@ static bool uc_is_wopcm_locked(struct intel_uc *uc)
  
  static int __uc_check_hw(struct intel_uc *uc)

  {
+   if (uc->fw_table_invalid)
+   return -EIO;
+
if (!intel_uc_supports_guc(uc))
return 0;
  
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.h b/drivers/gpu/drm/i915/gt/uc/intel_uc.h

index 5d0f1bcc381e8..d585524d94deb 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.h
@@ -36,6 +36,7 @@ struct intel_uc {
struct drm_i915_gem_object *load_err_log;
  
  	bool reset_in_progress;

+   bool fw_table_invalid;
  };
  
  void intel_uc_init_early(struct intel_uc *uc);

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 55e50bd08d7ff..64e19688788d1 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -233,20 +233,22 @@ struct fw_blobs_by_type {
u32 count;
  };
  
+static const struct uc_fw_platform_requirement blobs_guc[] = {

+   INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, GUC_FW_BLOB_MMP)
+};
+
+static const struct uc_fw_platform_requirement blobs_huc[] = {
+   INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, HUC_FW_BLOB_MMP, 
HUC_FW_BLOB_GSC)
+};
+
+static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = {
+   [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
+   [INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
+};
+
  static void
  __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
  {
-   static const struct uc_fw_platform_requirement blobs_guc[] = {
-   INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, 
GUC_FW_BLOB_MMP)
-   };
-   static const struct uc_fw_platform_requirement blobs_huc[] = {
-   INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, 
HUC_FW_BLOB_MMP, HUC_FW_BLOB_GSC)
-   };
-   static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = 
{
-   [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
-   [INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
-   };
-   static bool verified[INTEL_UC_FW_NUM_TYPES];
const struct uc_fw_platform_requirement *fw_blobs;
enum intel_platform p = INTEL_INFO(i915)->platform;
u32 fw_count;
@@ -286,6 +288,11 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct 
intel_uc_fw *uc_fw)
continue;
  
  		if (uc_fw->file_selected.path) {

+   /*
+* Continuing an earlier search after a found blob 
failed to load.
+* Once the previously chosen path has been found, 
clear it out
+* and let the search cont

Re: [Intel-gfx] [PATCH 4/6] drm/i915/uc: Enhancements to firmware table validation

2023-04-28 Thread Ceraolo Spurio, Daniele




On 4/28/2023 5:32 PM, John Harrison wrote:

On 4/28/2023 17:30, John Harrison wrote:

On 4/28/2023 17:26, Ceraolo Spurio, Daniele wrote:

On 4/28/2023 5:16 PM, John Harrison wrote:

On 4/28/2023 17:04, Ceraolo Spurio, Daniele wrote:

On 4/20/2023 6:15 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

The validation of the firmware table was being done inside the code
for scanning the table for the next available firmware blob. 
Which is

unnecessary. So pull it out into a separate function that is only
called once per blob type at init time.

Also, drop the CONFIG_SELFTEST requirement and make errors terminal.
It was mentioned that potential issues with backports would not be
caught by regular pre-merge CI as that only occurs on tip not stable
branches. Making the validation unconditional and failing driver 
load

on detecting of a problem ensures that such backports will also be
validated correctly.

v2: Change to unconditionally fail module load on a validation error
(review feedback/discussion with Daniele).

Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 157 
+--

  1 file changed, 92 insertions(+), 65 deletions(-)

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 c9cd9bb47577f..eb52e8db9ae0b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -233,20 +233,22 @@ struct fw_blobs_by_type {
  u32 count;
  };
  +static const struct uc_fw_platform_requirement blobs_guc[] = {
+    INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, 
GUC_FW_BLOB_MMP)

+};
+
+static const struct uc_fw_platform_requirement blobs_huc[] = {
+    INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, 
HUC_FW_BLOB_MMP, HUC_FW_BLOB_GSC)

+};
+
+static const struct fw_blobs_by_type 
blobs_all[INTEL_UC_FW_NUM_TYPES] = {

+    [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
+    [INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
+};
+
  static void
  __uc_fw_auto_select(struct drm_i915_private *i915, struct 
intel_uc_fw *uc_fw)

  {
-    static const struct uc_fw_platform_requirement blobs_guc[] = {
-    INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, 
GUC_FW_BLOB_MMP)

-    };
-    static const struct uc_fw_platform_requirement blobs_huc[] = {
-    INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, 
HUC_FW_BLOB_MMP, HUC_FW_BLOB_GSC)

-    };
-    static const struct fw_blobs_by_type 
blobs_all[INTEL_UC_FW_NUM_TYPES] = {
-    [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, 
ARRAY_SIZE(blobs_guc) },
-    [INTEL_UC_FW_TYPE_HUC] = { blobs_huc, 
ARRAY_SIZE(blobs_huc) },

-    };
-    static bool verified[INTEL_UC_FW_NUM_TYPES];
  const struct uc_fw_platform_requirement *fw_blobs;
  enum intel_platform p = INTEL_INFO(i915)->platform;
  u32 fw_count;
@@ -286,6 +288,11 @@ __uc_fw_auto_select(struct drm_i915_private 
*i915, struct intel_uc_fw *uc_fw)

  continue;
    if (uc_fw->file_selected.path) {
+    /*
+ * Continuing an earlier search after a found blob 
failed to load.
+ * Once the previously chosen path has been found, 
clear it out

+ * and let the search continue from there.
+ */
  if (uc_fw->file_selected.path == blob->path)
  uc_fw->file_selected.path = NULL;
  @@ -306,76 +313,91 @@ __uc_fw_auto_select(struct 
drm_i915_private *i915, struct intel_uc_fw *uc_fw)

  /* Failed to find a match for the last attempt?! */
  uc_fw->file_selected.path = NULL;
  }
+}
  -    /* make sure the list is ordered as expected */
-    if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST) && 
!verified[uc_fw->type]) {

-    verified[uc_fw->type] = true;
+static bool validate_fw_table_type(struct drm_i915_private 
*i915, enum intel_uc_fw_type type)

+{
+    const struct uc_fw_platform_requirement *fw_blobs;
+    u32 fw_count;
+    int i;
  -    for (i = 1; i < fw_count; i++) {
-    /* Next platform is good: */
-    if (fw_blobs[i].p < fw_blobs[i - 1].p)
-    continue;
+    if (type >= ARRAY_SIZE(blobs_all)) {
+    drm_err(>drm, "No blob array for %s\n", 
intel_uc_fw_type_repr(type));

+    return false;
+    }
  -    /* Next platform revision is good: */
-    if (fw_blobs[i].p == fw_blobs[i - 1].p &&
-    fw_blobs[i].rev < fw_blobs[i - 1].rev)
-    continue;
+    fw_blobs = blobs_all[type].blobs;
+    fw_count = blobs_all[type].count;
  -    /* Platform/revision must be in order: */
-    if (fw_blobs[i].p != fw_blobs[i - 1].p ||
-    fw_blobs[i].rev != fw_blobs[i - 1].rev)
-    goto bad;
+    if (!fw_count)
+    return true;
  -    /* Next major version is good: */
-    if (fw_blobs[i].blob.major < fw_blobs[i - 
1

Re: [Intel-gfx] [PATCH 4/6] drm/i915/uc: Enhancements to firmware table validation

2023-04-28 Thread Ceraolo Spurio, Daniele




On 4/28/2023 5:16 PM, John Harrison wrote:

On 4/28/2023 17:04, Ceraolo Spurio, Daniele wrote:

On 4/20/2023 6:15 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

The validation of the firmware table was being done inside the code
for scanning the table for the next available firmware blob. Which is
unnecessary. So pull it out into a separate function that is only
called once per blob type at init time.

Also, drop the CONFIG_SELFTEST requirement and make errors terminal.
It was mentioned that potential issues with backports would not be
caught by regular pre-merge CI as that only occurs on tip not stable
branches. Making the validation unconditional and failing driver load
on detecting of a problem ensures that such backports will also be
validated correctly.

v2: Change to unconditionally fail module load on a validation error
(review feedback/discussion with Daniele).

Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 157 
+--

  1 file changed, 92 insertions(+), 65 deletions(-)

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 c9cd9bb47577f..eb52e8db9ae0b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -233,20 +233,22 @@ struct fw_blobs_by_type {
  u32 count;
  };
  +static const struct uc_fw_platform_requirement blobs_guc[] = {
+    INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, 
GUC_FW_BLOB_MMP)

+};
+
+static const struct uc_fw_platform_requirement blobs_huc[] = {
+    INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, 
HUC_FW_BLOB_MMP, HUC_FW_BLOB_GSC)

+};
+
+static const struct fw_blobs_by_type 
blobs_all[INTEL_UC_FW_NUM_TYPES] = {

+    [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
+    [INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
+};
+
  static void
  __uc_fw_auto_select(struct drm_i915_private *i915, struct 
intel_uc_fw *uc_fw)

  {
-    static const struct uc_fw_platform_requirement blobs_guc[] = {
-    INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, 
GUC_FW_BLOB_MMP)

-    };
-    static const struct uc_fw_platform_requirement blobs_huc[] = {
-    INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, 
HUC_FW_BLOB_MMP, HUC_FW_BLOB_GSC)

-    };
-    static const struct fw_blobs_by_type 
blobs_all[INTEL_UC_FW_NUM_TYPES] = {

-    [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
-    [INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
-    };
-    static bool verified[INTEL_UC_FW_NUM_TYPES];
  const struct uc_fw_platform_requirement *fw_blobs;
  enum intel_platform p = INTEL_INFO(i915)->platform;
  u32 fw_count;
@@ -286,6 +288,11 @@ __uc_fw_auto_select(struct drm_i915_private 
*i915, struct intel_uc_fw *uc_fw)

  continue;
    if (uc_fw->file_selected.path) {
+    /*
+ * Continuing an earlier search after a found blob 
failed to load.
+ * Once the previously chosen path has been found, 
clear it out

+ * and let the search continue from there.
+ */
  if (uc_fw->file_selected.path == blob->path)
  uc_fw->file_selected.path = NULL;
  @@ -306,76 +313,91 @@ __uc_fw_auto_select(struct drm_i915_private 
*i915, struct intel_uc_fw *uc_fw)

  /* Failed to find a match for the last attempt?! */
  uc_fw->file_selected.path = NULL;
  }
+}
  -    /* make sure the list is ordered as expected */
-    if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST) && 
!verified[uc_fw->type]) {

-    verified[uc_fw->type] = true;
+static bool validate_fw_table_type(struct drm_i915_private *i915, 
enum intel_uc_fw_type type)

+{
+    const struct uc_fw_platform_requirement *fw_blobs;
+    u32 fw_count;
+    int i;
  -    for (i = 1; i < fw_count; i++) {
-    /* Next platform is good: */
-    if (fw_blobs[i].p < fw_blobs[i - 1].p)
-    continue;
+    if (type >= ARRAY_SIZE(blobs_all)) {
+    drm_err(>drm, "No blob array for %s\n", 
intel_uc_fw_type_repr(type));

+    return false;
+    }
  -    /* Next platform revision is good: */
-    if (fw_blobs[i].p == fw_blobs[i - 1].p &&
-    fw_blobs[i].rev < fw_blobs[i - 1].rev)
-    continue;
+    fw_blobs = blobs_all[type].blobs;
+    fw_count = blobs_all[type].count;
  -    /* Platform/revision must be in order: */
-    if (fw_blobs[i].p != fw_blobs[i - 1].p ||
-    fw_blobs[i].rev != fw_blobs[i - 1].rev)
-    goto bad;
+    if (!fw_count)
+    return true;
  -    /* Next major version is good: */
-    if (fw_blobs[i].blob.major < fw_blobs[i - 1].blob.major)
-    continue;
+    /* make sure the list is ordered as expected */
+    for (i = 1; i < fw_count; i++) {
+    /* N

Re: [Intel-gfx] [PATCH 6/6] drm/i915/uc: Make unexpected firmware versions an error in debug builds

2023-04-28 Thread Ceraolo Spurio, Daniele




On 4/20/2023 6:15 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

If the DEBUG_GEM config option is set then escalate the 'unexpected
firmware version' message from a notice to an error. This will ensure
that the CI system treats such occurences as a failure and logs a bug
about it (or fails the pre-merge testing).

Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 34 ++--
  1 file changed, 20 insertions(+), 14 deletions(-)

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 bc4011d55667c..c5b21d17ca437 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -17,6 +17,12 @@
  #include "i915_drv.h"
  #include "i915_reg.h"
  
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)

+#define UNEXPECTED gt_err
+#else
+#define UNEXPECTED gt_notice


I tried to find an alternative word that had the same number of 
characters as "gt_notice" so that we could avoid the indent in the diff, 
but nothing came to mind, so:


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


+#endif
+
  static inline struct intel_gt *
  uc_fw_to_gt(struct intel_uc_fw *uc_fw, enum intel_uc_fw_type type)
  {
@@ -828,10 +834,10 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
if (uc_fw->file_wanted.ver.major && uc_fw->file_selected.ver.major) {
/* Check the file's major version was as it claimed */
if (uc_fw->file_selected.ver.major != 
uc_fw->file_wanted.ver.major) {
-   gt_notice(gt, "%s firmware %s: unexpected version: %u.%u != 
%u.%u\n",
- intel_uc_fw_type_repr(uc_fw->type), 
uc_fw->file_selected.path,
- uc_fw->file_selected.ver.major, 
uc_fw->file_selected.ver.minor,
- uc_fw->file_wanted.ver.major, 
uc_fw->file_wanted.ver.minor);
+   UNEXPECTED(gt, "%s firmware %s: unexpected version: %u.%u != 
%u.%u\n",
+  intel_uc_fw_type_repr(uc_fw->type), 
uc_fw->file_selected.path,
+  uc_fw->file_selected.ver.major, 
uc_fw->file_selected.ver.minor,
+  uc_fw->file_wanted.ver.major, 
uc_fw->file_wanted.ver.minor);
if (!intel_uc_fw_is_overridden(uc_fw)) {
err = -ENOEXEC;
goto fail;
@@ -849,16 +855,16 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
/* Preserve the version that was really wanted */
memcpy(_fw->file_wanted, _ideal, 
sizeof(uc_fw->file_wanted));
  
-		gt_notice(gt, "%s firmware %s (%d.%d.%d) is recommended, but only %s (%d.%d.%d) was found\n",

- intel_uc_fw_type_repr(uc_fw->type),
- uc_fw->file_wanted.path,
- uc_fw->file_wanted.ver.major,
- uc_fw->file_wanted.ver.minor,
- uc_fw->file_wanted.ver.patch,
- uc_fw->file_selected.path,
- uc_fw->file_selected.ver.major,
- uc_fw->file_selected.ver.minor,
- uc_fw->file_selected.ver.patch);
+   UNEXPECTED(gt, "%s firmware %s (%d.%d.%d) is recommended, but only 
%s (%d.%d.%d) was found\n",
+  intel_uc_fw_type_repr(uc_fw->type),
+  uc_fw->file_wanted.path,
+  uc_fw->file_wanted.ver.major,
+  uc_fw->file_wanted.ver.minor,
+  uc_fw->file_wanted.ver.patch,
+  uc_fw->file_selected.path,
+  uc_fw->file_selected.ver.major,
+  uc_fw->file_selected.ver.minor,
+  uc_fw->file_selected.ver.patch);
gt_info(gt, "Consider updating your linux-firmware pkg or 
downloading from %s\n",
INTEL_UC_FIRMWARE_URL);
}




Re: [Intel-gfx] [PATCH 5/6] drm/i915/uc: Reject duplicate entries in firmware table

2023-04-28 Thread Ceraolo Spurio, Daniele




On 4/20/2023 6:15 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

It was noticed that duplicate entries in the firmware table could cause
an infinite loop in the firmware loading code if that entry failed to
load. Duplicate entries are a bug anyway and so should never happen.
Ensure they don't by tweaking the table validation code to reject
duplicates.

For full m/m/p files, that can be done by simply tweaking the patch
level check to reject matching values. For reduced version entries,
the filename itself must be compared.

Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 27 +---
  1 file changed, 24 insertions(+), 3 deletions(-)

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 eb52e8db9ae0b..bc4011d55667c 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -319,7 +319,7 @@ static bool validate_fw_table_type(struct drm_i915_private 
*i915, enum intel_uc_
  {
const struct uc_fw_platform_requirement *fw_blobs;
u32 fw_count;
-   int i;
+   int i, j;
  
  	if (type >= ARRAY_SIZE(blobs_all)) {

drm_err(>drm, "No blob array for %s\n", 
intel_uc_fw_type_repr(type));
@@ -334,6 +334,27 @@ static bool validate_fw_table_type(struct drm_i915_private 
*i915, enum intel_uc_
  
  	/* make sure the list is ordered as expected */

for (i = 1; i < fw_count; i++) {
+   /* Versionless file names must be unique per platform: */
+   for (j = i + 1; j < fw_count; j++) {
+   /* Same platform? */
+   if (fw_blobs[i].p != fw_blobs[j].p)
+   continue;
+
+   if (fw_blobs[i].blob.path != fw_blobs[j].blob.path)
+   continue;
+
+   drm_err(>drm, "Diplicaate %s blobs: %s r%u %s%d.%d.%d 
[%s] matches %s r%u %s%d.%d.%d [%s]\n",


typo Diplicaate


+   intel_uc_fw_type_repr(type),
+   intel_platform_name(fw_blobs[j].p), 
fw_blobs[j].rev,
+   fw_blobs[j].blob.legacy ? "L" : "v",
+   fw_blobs[j].blob.major, fw_blobs[j].blob.minor,
+   fw_blobs[j].blob.patch, fw_blobs[j].blob.path,
+   intel_platform_name(fw_blobs[i].p), 
fw_blobs[i].rev,


nit: we could avoid printing the platform twice because you're 
explicitly checking that it is the same earlier on. Not a blocked.

With the typo fixed:

Reviewed-by: Daniele Ceraolo Spurio 

Daniele


+   fw_blobs[i].blob.legacy ? "L" : "v",
+   fw_blobs[i].blob.major, fw_blobs[i].blob.minor,
+   fw_blobs[i].blob.patch, fw_blobs[i].blob.path);
+   }
+
/* Next platform is good: */
if (fw_blobs[i].p < fw_blobs[i - 1].p)
continue;
@@ -377,8 +398,8 @@ static bool validate_fw_table_type(struct drm_i915_private 
*i915, enum intel_uc_
if (fw_blobs[i].blob.minor != fw_blobs[i - 1].blob.minor)
goto bad;
  
-		/* Patch versions must be in order: */

-   if (fw_blobs[i].blob.patch <= fw_blobs[i - 1].blob.patch)
+   /* Patch versions must be in order and unique: */
+   if (fw_blobs[i].blob.patch < fw_blobs[i - 1].blob.patch)
continue;
  
  bad:




Re: [Intel-gfx] [PATCH 4/6] drm/i915/uc: Enhancements to firmware table validation

2023-04-28 Thread Ceraolo Spurio, Daniele




On 4/20/2023 6:15 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

The validation of the firmware table was being done inside the code
for scanning the table for the next available firmware blob. Which is
unnecessary. So pull it out into a separate function that is only
called once per blob type at init time.

Also, drop the CONFIG_SELFTEST requirement and make errors terminal.
It was mentioned that potential issues with backports would not be
caught by regular pre-merge CI as that only occurs on tip not stable
branches. Making the validation unconditional and failing driver load
on detecting of a problem ensures that such backports will also be
validated correctly.

v2: Change to unconditionally fail module load on a validation error
(review feedback/discussion with Daniele).

Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 157 +--
  1 file changed, 92 insertions(+), 65 deletions(-)

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 c9cd9bb47577f..eb52e8db9ae0b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -233,20 +233,22 @@ struct fw_blobs_by_type {
u32 count;
  };
  
+static const struct uc_fw_platform_requirement blobs_guc[] = {

+   INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, GUC_FW_BLOB_MMP)
+};
+
+static const struct uc_fw_platform_requirement blobs_huc[] = {
+   INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, HUC_FW_BLOB_MMP, 
HUC_FW_BLOB_GSC)
+};
+
+static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = {
+   [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
+   [INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
+};
+
  static void
  __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
  {
-   static const struct uc_fw_platform_requirement blobs_guc[] = {
-   INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, 
GUC_FW_BLOB_MMP)
-   };
-   static const struct uc_fw_platform_requirement blobs_huc[] = {
-   INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, 
HUC_FW_BLOB_MMP, HUC_FW_BLOB_GSC)
-   };
-   static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = 
{
-   [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
-   [INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
-   };
-   static bool verified[INTEL_UC_FW_NUM_TYPES];
const struct uc_fw_platform_requirement *fw_blobs;
enum intel_platform p = INTEL_INFO(i915)->platform;
u32 fw_count;
@@ -286,6 +288,11 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct 
intel_uc_fw *uc_fw)
continue;
  
  		if (uc_fw->file_selected.path) {

+   /*
+* Continuing an earlier search after a found blob 
failed to load.
+* Once the previously chosen path has been found, 
clear it out
+* and let the search continue from there.
+*/
if (uc_fw->file_selected.path == blob->path)
uc_fw->file_selected.path = NULL;
  
@@ -306,76 +313,91 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)

/* Failed to find a match for the last attempt?! */
uc_fw->file_selected.path = NULL;
}
+}
  
-	/* make sure the list is ordered as expected */

-   if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST) && !verified[uc_fw->type]) {
-   verified[uc_fw->type] = true;
+static bool validate_fw_table_type(struct drm_i915_private *i915, enum 
intel_uc_fw_type type)
+{
+   const struct uc_fw_platform_requirement *fw_blobs;
+   u32 fw_count;
+   int i;
  
-		for (i = 1; i < fw_count; i++) {

-   /* Next platform is good: */
-   if (fw_blobs[i].p < fw_blobs[i - 1].p)
-   continue;
+   if (type >= ARRAY_SIZE(blobs_all)) {
+   drm_err(>drm, "No blob array for %s\n", 
intel_uc_fw_type_repr(type));
+   return false;
+   }
  
-			/* Next platform revision is good: */

-   if (fw_blobs[i].p == fw_blobs[i - 1].p &&
-   fw_blobs[i].rev < fw_blobs[i - 1].rev)
-   continue;
+   fw_blobs = blobs_all[type].blobs;
+   fw_count = blobs_all[type].count;
  
-			/* Platform/revision must be in order: */

-   if (fw_blobs[i].p != fw_blobs[i - 1].p ||
-   fw_blobs[i].rev != fw_blobs[i - 1].rev)
-   goto bad;
+   if (!fw_count)
+   return true;
  
-			/* Next major version is good: */

-   if (fw_blobs[i].blob.major < fw_blobs[i - 1].blob.major)

Re: [Intel-gfx] [PATCH 3/6] drm/i915/uc: Track patch level versions on reduced version firmware files

2023-04-28 Thread Ceraolo Spurio, Daniele




On 4/20/2023 6:15 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

When reduced version firmware files were added (matching major
component being the only strict requirement), the minor version was
still tracked and a notification reported if it was older. However,
the patch version should really be tracked as well for the same
reasons. The KMD can work without the change but if the effort has
been taken to release a new firmware with the change then there must
be a valid reason for doing so - important bug fix, security fix, etc.
And in that case it would be good to alert the user if they are
missing out on that new fix.

v2: Use correct patch version number and drop redunant debug print
(review by Daniele / CI results).

Signed-off-by: John Harrison 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 30 +++-
  1 file changed, 19 insertions(+), 11 deletions(-)

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 a82a53dbbc86d..c9cd9bb47577f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -80,14 +80,14 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
   */
  #define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_maj, guc_mmp) \
fw_def(METEORLAKE,   0, guc_mmp(mtl,  70, 6, 5)) \
-   fw_def(DG2,  0, guc_maj(dg2,  70, 5)) \
-   fw_def(ALDERLAKE_P,  0, guc_maj(adlp, 70, 5)) \
+   fw_def(DG2,  0, guc_maj(dg2,  70, 5, 1)) \
+   fw_def(ALDERLAKE_P,  0, guc_maj(adlp, 70, 5, 1)) \
fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 70, 1, 1)) \
fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 69, 0, 3)) \
-   fw_def(ALDERLAKE_S,  0, guc_maj(tgl,  70, 5)) \
+   fw_def(ALDERLAKE_S,  0, guc_maj(tgl,  70, 5, 1)) \
fw_def(ALDERLAKE_S,  0, guc_mmp(tgl,  70, 1, 1)) \
fw_def(ALDERLAKE_S,  0, guc_mmp(tgl,  69, 0, 3)) \
-   fw_def(DG1,  0, guc_maj(dg1,  70, 5)) \
+   fw_def(DG1,  0, guc_maj(dg1,  70, 5, 1)) \
fw_def(ROCKETLAKE,   0, guc_mmp(tgl,  70, 1, 1)) \
fw_def(TIGERLAKE,0, guc_mmp(tgl,  70, 1, 1)) \
fw_def(JASPERLAKE,   0, guc_mmp(ehl,  70, 1, 1)) \
@@ -141,7 +141,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
__stringify(patch_) ".bin"
  
  /* Minor for internal driver use, not part of file name */

-#define MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_) \
+#define MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_, patch_) \
__MAKE_UC_FW_PATH_MAJOR(prefix_, "guc", major_)
  
  #define MAKE_GUC_FW_PATH_MMP(prefix_, major_, minor_, patch_) \

@@ -197,9 +197,9 @@ struct __packed uc_fw_blob {
{ UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \
  .legacy = true }
  
-#define GUC_FW_BLOB(prefix_, major_, minor_) \

-   UC_FW_BLOB_NEW(major_, minor_, 0, false, \
-  MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_))
+#define GUC_FW_BLOB(prefix_, major_, minor_, patch_) \
+   UC_FW_BLOB_NEW(major_, minor_, patch_, false, \
+  MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_, patch_))
  
  #define GUC_FW_BLOB_MMP(prefix_, major_, minor_, patch_) \

UC_FW_BLOB_OLD(major_, minor_, patch_, \
@@ -296,6 +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->file_wanted.ver.patch = blob->patch;
uc_fw->loaded_via_gsc = blob->loaded_via_gsc;
found = true;
break;
@@ -790,6 +791,9 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
} else {
if (uc_fw->file_selected.ver.minor < 
uc_fw->file_wanted.ver.minor)
old_ver = true;
+   else if ((uc_fw->file_selected.ver.minor == 
uc_fw->file_wanted.ver.minor) &&
+(uc_fw->file_selected.ver.patch < 
uc_fw->file_wanted.ver.patch))
+   old_ver = true;
}
}
  
@@ -797,12 +801,16 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)

/* Preserve the version that was really wanted */
memcpy(_fw->file_wanted, _ideal, 
sizeof(uc_fw->file_wanted));
  
-		gt_notice(gt, "%s firmware %s (%d.%d) is recommended, but only %s (%d.%d) was found\n",

+   gt_notice(gt, "%s firmware %s (%d.%d.%d) is recommended, but only %s 
(%d.%d.%d) was found\n",
  intel_uc_fw_type_repr(uc_fw->type),
  uc_fw->file_wanted.path,
- uc_fw->file_wanted.ver.major, 

Re: [Intel-gfx] [PATCH 0/8] drm/i915: HuC loading and authentication for MTL

2023-04-28 Thread Ceraolo Spurio, Daniele




On 4/27/2023 10:25 PM, Saarinen, Jani wrote:

Hi,


-Original Message-
From: Intel-gfx  On Behalf Of Ye, Tony
Sent: perjantai 28. huhtikuuta 2023 6.11
To: Ceraolo Spurio, Daniele ; intel-
g...@lists.freedesktop.org
Cc: Teres Alexis, Alan Previn ; dri-
de...@lists.freedesktop.org; Zhang, Carl 
Subject: Re: [Intel-gfx] [PATCH 0/8] drm/i915: HuC loading and authentication 
for
MTL

Acked-by: Tony Ye 

CI results would be also good to look at before... 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_117080v1/index.html?
For some reason no single MTL tests and many aborts...


Is there any way to know if the MTLs where just offline or if they 
failed driver load? This is working fine in my local MTL testing, so not 
sure what might be broken.
Regarding the aborts, looks like I have broken DG2 reset. I tested a 
previous local version of this on DG2 but not the latest, so I must've 
broken something when refactoring the code. I'll figure it out and fix 
it up.


Daniele




Thanks,

Tony

On 4/27/2023 7:34 PM, Daniele Ceraolo Spurio wrote:

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.

[1]https://patchwork.freedesktop.org/series/115806/
Cc: Alan Previn
Cc: Tony Ye

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 10064

Re: [Intel-gfx] IOCTL feature detection (Was: Re: [PATCH 8/8] drm/i915: Allow user to set cache at BO creation)

2023-04-26 Thread Ceraolo Spurio, Daniele




On 4/26/2023 9:48 AM, Teres Alexis, Alan Previn wrote:

On Wed, 2023-04-26 at 13:52 +0200, Daniel Vetter wrote:

On Tue, Apr 25, 2023 at 04:41:54PM +0300, Joonas Lahtinen wrote:

(+ Faith and Daniel as they have been involved in previous discussions)
Quoting Jordan Justen (2023-04-24 20:13:00)

On 2023-04-24 02:08:43, Tvrtko Ursulin wrote:



alan:snip


- the more a feature spans drivers/modules, the more it should be
   discovered by trying it out, e.g. dma-buf fence import/export was a huge
   discussion, luckily mesa devs figured out how to transparantly fall back
   at runtime so we didn't end up merging the separate feature flag (I
   think at least, can't find it). pxp being split across i915/me/fw/who
   knows what else is kinda similar so I'd heavily lean towards discovery
   by creating a context

- pxp taking 8s to init a ctx sounds very broken, irrespective of anything
   else


I think there has been a bit of confusion in regards to this timeout and 
to where it applies, so let me try to clarify to make sure we're all on 
the same page (Alan has already explained most of it below, but I'm 
going to go in a bit more detail and I want to make sure it's all in one 
place for reference).
Before we can do any PXP operation, dependencies need to be satisfied, 
some of which are outside of i915. For MTL, these are:


GSC FW needs to be loaded (~250 ms)
HuC FW needs to be authenticated for PXP ops (~20 ms)
MEI modules need to be bound (depends on the probe ordering, but usually 
a few secs)
GSC SW proxy via MEI needs to be established (~500 ms normally, but can 
take a few seconds on the first boot after a firmware update)


Due to the fact that these can take several seconds in total to 
complete, to avoid stalling driver load/resume for that long we moved 
the i915-side operations to a separate worker and we register i915 
before they've completed. This means that we can get a PXP context 
creation call before all the dependencies are in place, in which case we 
do need to wait and that's where the 8s come from. After all the pieces 
are in place, a PXP context creation call is much faster (up to ~150 ms, 
which is the time required to start the PXP session if it is not already 
running).


The reason why we suggested a dedicated getparam was to avoid requiring 
early users to wait for all of that to happen just to check the 
capability. By the time an user actually wants to use PXP, we're likely 
done with the prep steps (or at least we're far along with them) and 
therefore the wait will be short.



Alan: Please be aware that:
1. the wait-timeout was changed to 1 second sometime back.
2. the I'm not deciding the time-out. I initially wanted to keep it at the same
timeout as ADL (250 milisec) - and ask the UMD to retry if user needs it. (as 
per
same ADL behavior). Daniele requested to move it to 8 seconds - but thru review
process, we reduced it to 1 second.
3. In anycase, thats just the wait-timeout - and we know it wont succeed until
~6 seconds after i915 (~9 secs after boot). The issue isnt our hardware or i915
- its the component driver load <-- this is what's broken.


I think the question here is whether the mei driver is taking a long 
time to probe or if it is just being probed late. In the latter case, I 
wouldn't call it broken.




Details: PXP context is dependent on gsc-fw load, huc-firmware load, 
mei-gsc-proxy
component driver load + bind, huc-authentication and gsc-proxy-init-handshake.
Most of above steps begin rather quickly during i915 driver load - the delay
seems to come from a very late mei-gsc-proxy component driver load. In fact the
parent mei-me driver is only getting ~6 seconds after i915 init is done. That
blocks the gsc-proxy-init-handshake and huc-authentication and lastly PXP.

That said, what is broken is why it takes so long to get the component drivers
to come up. NOTE: PXP isnt really doing anything differently in the context
creation flow (in terms of time-consuming-steps compared to ADL) besides the
extra dependency waits these.

We can actually go back to the original timeout of 250 milisecs like we have in 
ADL
but will fail if MESA calls in too early (but will succeed later) ... or...
we can create the GET_PARAMs.

A better idea would be to figure out how to control the driver load order and
force mei driver + components to get called right after i915. I was informed
there is no way to control this and changes here will likely not be accepted
upstream.


we could add a device link to mark i915 as a consumer of mei, but I 
believe that wouldn't work for 2 reasons


1 - on discrete, mei binds to a child device of i915, so the dependency 
is reversed
2 - the link might just delay the i915 load to after the mei load, which 
I'm not sure it is something we want (and at that point we could also 
just wait for mei to bind from within the i915 load).


Daniele



++ Daniele - can you chime in?

Take note that ADL has the same issue but for whatever reason, the 

Re: [Intel-gfx] [PATCH v8 3/8] drm/i915/pxp: Add MTL helpers to submit Heci-Cmd-Packet to GSC

2023-04-21 Thread Ceraolo Spurio, Daniele




On 4/20/2023 10:34 PM, Alan Previn wrote:

Add helper functions into a new file for heci-packet-submission.
The helpers will handle generating the MTL GSC-CS Memory-Header
and submission of the Heci-Cmd-Packet instructions to the engine.

NOTE1: These common functions for heci-packet-submission will be used
by different i915 callers:
  1- GSC-SW-Proxy: This is pending upstream publication awaiting
 a few remaining opens
  2- MTL-HDCP: An equivalent patch has also been published at:
 https://patchwork.freedesktop.org/series/111876/. (Patch 1)
  3- PXP: This series.

NOTE2: A difference in this patch vs what is appearing is in bullet 2
above is that HDCP (and SW-Proxy) will be using priveleged submission
(GGTT and common gsc-uc-context) while PXP will be using non-priveleged
PPGTT, context and batch buffer. Therefore this patch will only slightly
overlap with the MTL-HDCP patches despite have very similar function
names (emit_foo vs emit_nonpriv_foo). This is because HECI_CMD_PKT
instructions require different flows and hw-specific code when done
via PPGTT based submission (not different from other engines). MTL-HDCP
contains the same intel_gsc_mtl_header_t structures as this but the
helpers there are different. Both add the same new file names.

NOTE3: Additional clarity about the heci-cmd-pkt layout and where the
common helpers come in:
  - On MTL, when an i915 subsystem needs to send a command request
to the security firmware, it will send that via the GSC-
engine-command-streamer.
  - However those commands, (lets call them "gsc_specific_fw_api"
calls), are not understood by the GSC command streamer hw.
  - The GSC CS only looks at the GSC_HECI_CMD_PKT instruction and
passes it along to the GSC firmware.
  - The GSC FW on the other hand needs additional metadata to know
which usage service is being called (PXP, HDCP, proxy, etc) along
with session specific info. Thus an extra header called GSC-CS
HECI Memory Header, (C) in below diagram is prepended before
the FW specific API, (D).
  - Thus, the structural layout of the request submitted would
need to look like the diagram below (for non-priv PXP).
  - In the diagram, the common helper for HDCP, (GSC-Sw-Proxy) and
PXP (i.e. new function intel_gsc_uc_heci_cmd_emit_mtl_header)
will populate blob (C) while additional helpers, different for
PPGGTT (this patch) vs GGTT (HDCP series) will populate
blobs (A) and (B) below.
   ___
  (A)  |  MI_BATCH_BUFFER_START (ppgtt, batchbuff-addr, ...) |
   | |   |
   |_|   |
   | (B)| GSC_HECI_CMD_PKT (pkt-addr-in, pkt-size-in,|   |
   ||   pkt-addr-out, pkt-size-out)  |
   || MI_BATCH_BUFFER_END|   |   |
   |||   |   |
   | |   |
   |_|   |
 |
 -
 |
\|/
   __V___
   |   _|
   |(C)|   ||
   |   | struct intel_gsc_mtl_header { ||
   |   |   validity marker ||
   |   |   heci_clent_id   ||
   |   |   ... ||
   |   |  }||
   |   |___||
   |(D)|   ||
   |   | struct gsc_fw_specific_api_foobar {   ||
   |   | ...   ||
   |   | For an example, see   ||
   |   | 'struct pxp43_create_arb_in' at   ||
   |   | intel_pxp_cmd_interface_43.h  ||
   |   |   ||
   |   | } ||
   |   |  Struture depends on command type ||
   |   | struct gsc_fw_specific_api_foobar {   ||
   |   |___||
   ||

That said, this patch provides basic helpers but leaves the
PXP subsystem (i.e. the caller) to handle (D) and everything
else such as input/output size verification or handling the
responses from security firmware (for example, requiring a retry).

Signed-off-by: Alan Previn 


Reviewed-by: Daniele Ceraolo Spurio

Re: [Intel-gfx] [PATCH 2/4] mei: gsc_proxy: add gsc proxy driver

2023-04-20 Thread Ceraolo Spurio, Daniele




On 4/20/2023 3:04 PM, Ceraolo Spurio, Daniele wrote:



On 4/18/2023 11:57 PM, Teres Alexis, Alan Previn wrote:

On Wed, 2023-03-29 at 09:56 -0700, Ceraolo Spurio, Daniele wrote:

From: Alexander Usyskin 

Add GSC proxy driver. It to allows messaging between GSC component
on Intel on board graphics card and CSE device.
alan:nit: isn't "Intel integrated GPU" clearer than "Intel on-board 
graphics card"?
Same thing for the Kconfig description later (or am i missing 
something else here).


Will change


Thinking again, GSC proxy will be applicable to non-integrated GPUs as 
well, so I'm just going to change this to "Intel graphics card".


Daniele


Re: [Intel-gfx] [PATCH v7 3/8] drm/i915/pxp: Add MTL helpers to submit Heci-Cmd-Packet to GSC

2023-04-20 Thread Ceraolo Spurio, Daniele




On 4/17/2023 10:56 AM, Teres Alexis, Alan Previn wrote:

On Mon, 2023-04-10 at 09:10 -0700, Ceraolo Spurio, Daniele wrote:
alan:snip


+int
+intel_gsc_uc_heci_cmd_submit_nonpriv(struct intel_gsc_uc *gsc,
+struct intel_context *ce,
+struct intel_gsc_heci_non_priv_pkt *pkt,
+u32 *cmd, int timeout_ms)
+{
+   struct intel_engine_cs *eng;

We always use "engine" for engine_cs variables. IMO it's better to stick
to that here as well for consistency across the code.

alan: will do

+   struct i915_gem_ww_ctx ww;
+   struct i915_request *rq;
+   int err, trials = 0;
+

Is the assumption that the caller is holding a wakeref already?
Otherwise we're going to need and engine_pm_get() here (assuming it
doesn't interfere with any locking, otherwise it has to be in the caller)

alan: right now the only places this can get called from is via 
intel_pxp_gsccs_create_session or
intel_pxp_gsccs_end_arb_fw_session. These functions are either being called by 
intel_pxp_start
or intel_pxp_end. intel_pxp_start calls intel_runtime_pm_get_if_in_use 
indirectly from the
session-worker and while intel_pxp_end takes an explicit intel_runtime_pm_get 
(since it is
for suspend/shutdown cleanup and doesn't use the worker). I'm assuming 
runtime_pm works right?
we have a similar logic across the paths from ADL version where we dont take 
explicit
engine_pm_get for the termination via VDBOX because its part of the same code 
paths.


rpm_get works for the power management side, but not for "activeness" 
tracking, for which we need engine_pm_get. However, I've just realized 
that the context_pin contains an engine_pm_get, so we're covered.


Therefore, with the other minor comments addressed, this is:

Reviewed-by: Daniele Ceraolo Spurio 

Daniele



alan:snip


+   err = i915_vma_move_to_active(pkt->bb_vma, rq, EXEC_OBJECT_WRITE);

nit: I don't think we need EXEC_OBJECT_WRITE for the bb as we're not
going to write it.

alan: yes - will remove. (had accidentally kept above flag from offline
debugging version of the code that had additional store dwords into bb).


+   if (err)
+   goto out_rq;
+   err = i915_vma_move_to_active(pkt->heci_pkt_vma, rq, EXEC_OBJECT_WRITE);
+   if (err)
+   goto out_rq;
+
+   eng = rq->context->engine;
+   if (eng->emit_init_breadcrumb) {
+   err = eng->emit_init_breadcrumb(rq);
+   if (err)
+   goto out_rq;
+   }
+
+   err = eng->emit_bb_start(rq, i915_vma_offset(pkt->bb_vma), PAGE_SIZE, 
0);
+   if (err)
+   goto out_rq;
+
+   err = ce->engine->emit_flush(rq, 0);
+   if (err)
+   drm_err(_uc_to_gt(gsc)->i915->drm,
+   "Failed emit-flush for gsc-heci-non-priv-pkterr=%d\n", 
err);
+
+out_rq:
+   i915_request_get(rq);
+
+   if (unlikely(err))
+   i915_request_set_error_once(rq, err);
+
+   i915_request_add(rq);
+
+   if (!err) {
+   if (i915_request_wait(rq, I915_WAIT_INTERRUPTIBLE,
+ msecs_to_jiffies(timeout_ms)) < 0)
+   err = -ETIME;
+   }
+
+   i915_request_put(rq);
+
+out_unpin_ce:
+   intel_context_unpin(ce);
+out_ww:
+   if (err == -EDEADLK) {
+   err = i915_gem_ww_ctx_backoff();
+   if (!err) {
+   if (++trials < 10)
+   goto retry;
+   else
+   err = EAGAIN;
+   }
+   }
+   i915_gem_ww_ctx_fini();
+
+   return err;
+}
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..3addce861854 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
@@ -8,7 +8,10 @@
   
   #include 
   
+struct i915_vma;

+struct intel_context;
   struct intel_gsc_uc;
+
   struct intel_gsc_mtl_header {
u32 validity_marker;
   #define GSC_HECI_VALIDITY_MARKER 0xA578875A
@@ -47,7 +50,7 @@ struct intel_gsc_mtl_header {
 * we distinguish the flags using OUTFLAG or INFLAG
 */
u32 flags;
-#define GSC_OUTFLAG_MSG_PENDING1
+#define GSC_OUTFLAG_MSG_PENDING 1

Nit: this change on the define is not really needed

sure - will fix.

Daniele




Re: [Intel-gfx] [PATCH 2/4] mei: gsc_proxy: add gsc proxy driver

2023-04-20 Thread Ceraolo Spurio, Daniele




On 4/18/2023 11:57 PM, Teres Alexis, Alan Previn wrote:

On Wed, 2023-03-29 at 09:56 -0700, Ceraolo Spurio, Daniele wrote:

From: Alexander Usyskin 

Add GSC proxy driver. It to allows messaging between GSC component
on Intel on board graphics card and CSE device.

alan:nit: isn't "Intel integrated GPU" clearer than "Intel on-board graphics 
card"?
Same thing for the Kconfig description later (or am i missing something else 
here).


Will change



alan:snip




+ MEI GSC proxy enables messaging between GSC service on
+ Intel graphics on-board card and services on CSE (MEI)

alan:nit: same as above





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 ..953eda1a16fb
--- /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
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 

alan: [nit?] i thought we need to have the headers alphabetically ordered? 
(below too)


Will fix


+#include 
+#include 
+#include 
+#include 
+
+/**
+ * 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)

alan: nit: not sure if we should be checking for !size here - i do see that 
next patch
is checking for this from i915 side of the interface... but just wasnt sure 
which is the prefered style
(in terms of where to check for this condition). Either way, its a nit for me 
since i traced down
all the way to mei_cl_alloc_cb and it looks like mei bus can tolerate zero 
sized messages.

+   return -EINVAL;

alan:snip


+static int mei_gsc_proxy_recv(struct device *dev, void *buf, size_t size)
+{
+   ssize_t ret;
+
+   if (!dev || !buf)

alan: nit: same as in the 'send' above,.. not sure if we should be checking for 
!size here...
or perhaps 0 sized recv is supported.


AFAICS the lower level of the mei code do allow for size 0 for both send 
and recv. Also, this is the same check as what we do for the PXP component.





+   return -EINVAL;

alan:snip


+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);

alan: do we care if both these parents are non-null? i notice in other mei 
component
drivers match functions we do check that.


Those should always both be non-NULL, since both the mei and the GFX 
device have the PCI bus as parent (and the previous check on pdev 
ensures those are the 2 devices we're handling at this point).





+}
+

alan:snip


+#define MEI_UUID_GSC_PROXY UUID_LE(0xf73db04, 0x97ab, 0x4125, \
+  0xb8, 0x93, 0xe9, 0x4, 0xad, 0xd, 0x54, 0x64)

alan: apologies for the newbie question, but why are we using UUID for the 
gsc_proxy
as opposed to GUID like the other mei components? i am not sure if i read the 
right
archived patch review but it sounded like GUID is for internal to kernel only 
whereas
UUID is for external too? (in which case why are we not using GUID for 
gsc-proxy?)
Consider this a non-blocking inquiry since i assume mei folks have reviewed this
prior and this is an explicit design decision that I'm just not versed on.


AFAICS all other mei components use UUID_LE as well. The code was 
updated from GUID to UUID_LE in:

https://lore.kernel.org/all/20221228160558.21311-1-andriy.shevche...@linux.intel.com/

Daniele



alan:snip




Re: [Intel-gfx] [PATCH 4/4] drm/i915/gsc: add support for GSC proxy interrupt

2023-04-20 Thread Ceraolo Spurio, Daniele




On 4/20/2023 11:49 AM, Teres Alexis, Alan Previn wrote:

On Wed, 2023-03-29 at 09:56 -0700, Ceraolo Spurio, Daniele wrote:

The GSC notifies us of a proxy request via the HECI2 interrupt. The

alan:snip


@@ -256,6 +262,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;

alan: nit: should we call this heci2_mask - uniquely identifiable from legacy.


The mask is theoretically not just for HECI2, the bit we set in it is. 
If future platforms add back the HECI1 interrupt then it'd go in the 
same mask.





alan:snip


-   else if (HAS_HECI_GSC(gt->i915))
+   heci_mask = GSC_IRQ_INTF(1); /* HECI2 IRQ for SW Proxy*/

alan: does this GSC_IRQ_INTF macro still make sense for this newer platforms 
with GSC-CS / HECI2?
i dont think i see other bit definitions for this mask register, so might else 
well just define it as BIT14?


GSC_IRQ_INTF(1) is the HECI2 interrupt on DG2 and the bit has remained 
the same exactly to allow SW to re-use the same code/defines, so IMO we 
should do so.




alan:snip




diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h 
b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index 4aecb5a7b631..da11ce5ca99e 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -1577,6 +1577,7 @@
  
  #define GEN11_GT_INTR_DW(x)			_MMIO(0x190018 + ((x) * 4))

  #define   GEN11_CSME  (31)
+#define   GEN12_HECI_2 (30)

alan: I dont see this being used anywhere - should remove this.


A few of the defines for this register here are not used. I've added 
this one in as a way of documenting where the bit was, but I can remove 
it if you think it's unneeded.





+#define GEN11_HECI2_RSVD_INTR_MASK _MMIO(0x1900e4)

alan: GEN11? don't you mean GEN12?



Yup, this should be GEN12






+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");

alan: So although proxy init is only a one-time thing (even surviving 
suspend-resume), we
know that proxy runtime irqs could happen anytime (depending on other 
gpu-security-related
system interactions). However, would the component driver be bound/unbound 
through a
suspend-resume cycle? If yes, then would this check fail if an IRQ for a proxy 
request
came too early after a resume cycle. If yes, then should we not do somethign 
here to ensure that
when the component gets bound later, we know there is something waiting to be 
processed?
(in bind, if proxy-init was done before, but we have outstanding IRQs, then we 
can trigger
the worker from there, i.e. the bind func?)


A proxy request can only be triggered in response to a userspace ask, 
which in turn can only happen once we've completed the resume flow and 
the component is re-bound. Therefore, we should never have a situation 
where we get a proxy interrupt without the component being bound.




alan:snip


  static int i915_gsc_proxy_component_bind(struct device *i915_kdev,
 struct device *tee_kdev, void *data)
  {
struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
-   struct intel_gsc_uc *gsc = >media_gt->uc.gsc;
+   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(>runtime_pm, wakeref)
+   intel_uncore_rmw(gt->uncore, HECI_H_CSR(MTL_GSC_HECI2_BASE),
+0, HECI_H_CSR_IE);

alan: i notice we don't seem to care about potentially re-writing a '1' into 
reset
if it was midst reset when we read. Shouldn't we also protect against that here?


Yeah, I'll add that in



alan:snip



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 023bded10dde..a2a0813b8a76 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h
@@ -23,6 +23,9 @@ struct intel_gsc_uc {
/* 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


alan: perhaps its time to have a substruct for "proxy_worker" and include
'wq' and 'work' in additional to actions?


The worker is not just for proxy, we use it for a GSC and HuC loading as 
well. It's the main way we handle the gsc_uc, so IMO it's better o

Re: [Intel-gfx] [PATCH 5/5] drm/i915/uc: Reject doplicate entries in firmware table

2023-04-19 Thread Ceraolo Spurio, Daniele




On 4/19/2023 10:12 AM, John Harrison wrote:

On 4/19/2023 10:02, John Harrison wrote:

On 4/18/2023 16:24, Ceraolo Spurio, Daniele wrote:

Typo doplicate in patch title

On 4/14/2023 5:57 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

It was noticed that duplicte entries in the firmware table could cause


typo duplicte


an infinite loop in the firmware loading code if that entry failed to
load. Duplicate entries are a bug anyway and so should never happen.
Ensure they don't by tweaking the table validation code to reject
duplicates.


Here you're not really rejecting anything though, just printing an 
error (and even that only if the SELFTEST kconfig is selected). This 
would allow our CI to catch issues with patches sent to our ML, but 
IIRC the reported bug was on a kernel fork. We could disable the FW 
loading is the table for that particular blob type is in an invalid 
state, as it wouldn't be safe to attempt a load in that case anyway.
The validation code is rejecting duplicates. Whether the driver loads 
or not after a failed validation is another matter.


I was basically assuming that CI will fail on the error message and 
thus prevent such code ever being merged. But yeah, I guess we don't 
run CI on backports to stable kernels and such. Although, I would 
hope that anyone pushing patches to a stable kernel would run some 
testing on it first!


Any thoughts on a good way to fail the load? We don't want to just 
pretend that firmware is not wanted/required on the platform and just 
load the i915 module without the firmware. Also, what about the 
longer plan of moving the validation to a selftest. You can't fail 
the load at all then.
Actually, forgot we already have a INTEL_UC_FIRMWARE_ERROR status. 
That works fine for aborting the load. So just go with that and drop 
the plan to move to a selftest?


John.


I do actually like the idea of moving this code to a mock selftest. 
Maybe just add a comment above the tables making clear that duplicated 
entries are not allowed and will break the loading flow?


Daniele






John.





For full m/m/p files, that can be done by simply tweaking the patch
level check to reject matching values. For reduced version entries,
the filename itself must be compared.

Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 27 
+---

  1 file changed, 24 insertions(+), 3 deletions(-)

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 c589782467265..44829247ef6bc 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -319,7 +319,7 @@ static void validate_fw_table_type(struct 
drm_i915_private *i915, enum intel_uc_

  {
  const struct uc_fw_platform_requirement *fw_blobs;
  u32 fw_count;
-    int i;
+    int i, j;
    if (type >= ARRAY_SIZE(blobs_all)) {
  drm_err(>drm, "No blob array for %s\n", 
intel_uc_fw_type_repr(type));
@@ -334,6 +334,27 @@ static void validate_fw_table_type(struct 
drm_i915_private *i915, enum intel_uc_

    /* make sure the list is ordered as expected */
  for (i = 1; i < fw_count; i++) {
+    /* Versionless file names must be unique per platform: */
+    for (j = i + 1; j < fw_count; j++) {
+    /* Same platform? */
+    if (fw_blobs[i].p != fw_blobs[j].p)
+    continue;
+
+    if (fw_blobs[i].blob.path != fw_blobs[j].blob.path)
+    continue;
+
+    drm_err(>drm, "Diplicaate %s blobs: %s r%u 
%s%d.%d.%d [%s] matches %s r%u %s%d.%d.%d [%s]\n",


Typo Diplicaate

Daniele


+ intel_uc_fw_type_repr(type),
+    intel_platform_name(fw_blobs[j].p), fw_blobs[j].rev,
+    fw_blobs[j].blob.legacy ? "L" : "v",
+    fw_blobs[j].blob.major, fw_blobs[j].blob.minor,
+    fw_blobs[j].blob.patch, fw_blobs[j].blob.path,
+    intel_platform_name(fw_blobs[i].p), fw_blobs[i].rev,
+    fw_blobs[i].blob.legacy ? "L" : "v",
+    fw_blobs[i].blob.major, fw_blobs[i].blob.minor,
+    fw_blobs[i].blob.patch, fw_blobs[i].blob.path);
+    }
+
  /* Next platform is good: */
  if (fw_blobs[i].p < fw_blobs[i - 1].p)
  continue;
@@ -377,8 +398,8 @@ static void validate_fw_table_type(struct 
drm_i915_private *i915, enum intel_uc_

  if (fw_blobs[i].blob.minor != fw_blobs[i - 1].blob.minor)
  goto bad;
  -    /* Patch versions must be in order: */
-    if (fw_blobs[i].blob.patch <= fw_blobs[i - 1].blob.patch)
+    /* Patch versions must be in order and unique: */
+    if (fw_blobs[i].blob.patch < fw_blobs[i - 1].blob.patch)
  continue;
    bad:










Re: [Intel-gfx] [PATCH 5/5] drm/i915/uc: Reject doplicate entries in firmware table

2023-04-18 Thread Ceraolo Spurio, Daniele

Typo doplicate in patch title

On 4/14/2023 5:57 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

It was noticed that duplicte entries in the firmware table could cause


typo duplicte


an infinite loop in the firmware loading code if that entry failed to
load. Duplicate entries are a bug anyway and so should never happen.
Ensure they don't by tweaking the table validation code to reject
duplicates.


Here you're not really rejecting anything though, just printing an error 
(and even that only if the SELFTEST kconfig is selected). This would 
allow our CI to catch issues with patches sent to our ML, but IIRC the 
reported bug was on a kernel fork. We could disable the FW loading is 
the table for that particular blob type is in an invalid state, as it 
wouldn't be safe to attempt a load in that case anyway.




For full m/m/p files, that can be done by simply tweaking the patch
level check to reject matching values. For reduced version entries,
the filename itself must be compared.

Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 27 +---
  1 file changed, 24 insertions(+), 3 deletions(-)

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 c589782467265..44829247ef6bc 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -319,7 +319,7 @@ static void validate_fw_table_type(struct drm_i915_private 
*i915, enum intel_uc_
  {
const struct uc_fw_platform_requirement *fw_blobs;
u32 fw_count;
-   int i;
+   int i, j;
  
  	if (type >= ARRAY_SIZE(blobs_all)) {

drm_err(>drm, "No blob array for %s\n", 
intel_uc_fw_type_repr(type));
@@ -334,6 +334,27 @@ static void validate_fw_table_type(struct drm_i915_private 
*i915, enum intel_uc_
  
  	/* make sure the list is ordered as expected */

for (i = 1; i < fw_count; i++) {
+   /* Versionless file names must be unique per platform: */
+   for (j = i + 1; j < fw_count; j++) {
+   /* Same platform? */
+   if (fw_blobs[i].p != fw_blobs[j].p)
+   continue;
+
+   if (fw_blobs[i].blob.path != fw_blobs[j].blob.path)
+   continue;
+
+   drm_err(>drm, "Diplicaate %s blobs: %s r%u %s%d.%d.%d 
[%s] matches %s r%u %s%d.%d.%d [%s]\n",


Typo Diplicaate

Daniele


+   intel_uc_fw_type_repr(type),
+   intel_platform_name(fw_blobs[j].p), 
fw_blobs[j].rev,
+   fw_blobs[j].blob.legacy ? "L" : "v",
+   fw_blobs[j].blob.major, fw_blobs[j].blob.minor,
+   fw_blobs[j].blob.patch, fw_blobs[j].blob.path,
+   intel_platform_name(fw_blobs[i].p), 
fw_blobs[i].rev,
+   fw_blobs[i].blob.legacy ? "L" : "v",
+   fw_blobs[i].blob.major, fw_blobs[i].blob.minor,
+   fw_blobs[i].blob.patch, fw_blobs[i].blob.path);
+   }
+
/* Next platform is good: */
if (fw_blobs[i].p < fw_blobs[i - 1].p)
continue;
@@ -377,8 +398,8 @@ static void validate_fw_table_type(struct drm_i915_private 
*i915, enum intel_uc_
if (fw_blobs[i].blob.minor != fw_blobs[i - 1].blob.minor)
goto bad;
  
-		/* Patch versions must be in order: */

-   if (fw_blobs[i].blob.patch <= fw_blobs[i - 1].blob.patch)
+   /* Patch versions must be in order and unique: */
+   if (fw_blobs[i].blob.patch < fw_blobs[i - 1].blob.patch)
continue;
  
  bad:




Re: [Intel-gfx] [PATCH 4/5] drm/i915/uc: Split firmware table validation to a separate function

2023-04-18 Thread Ceraolo Spurio, Daniele
ivate *i915)

+{
+   enum intel_uc_fw_type type;
+   static bool done;
+
+   if (!IS_ENABLED(CONFIG_DRM_I915_SELFTEST) || done)
+   return;
+   done = true;
+
+   for (type = 0; type < INTEL_UC_FW_NUM_TYPES; type++)
+   validate_fw_table_type(i915, type);
+}
+
  static const char *__override_guc_firmware_path(struct drm_i915_private *i915)
  {
if (i915->params.enable_guc & ENABLE_GUC_MASK)
@@ -432,6 +464,8 @@ void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
  {
struct drm_i915_private *i915 = uc_fw_to_gt(uc_fw, type)->i915;
  
+	validate_fw_table(i915);


Personal preference: IMO since we're calling intel_uc_fw_init_early per 
FW type it would've been cleaner to restrict validate_fw_table() to a 
single blob type. This would have the negative side effect of having to 
track the "done" status per FW type, so I can see it's not a clean 
improvement. Not a blocker.


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


+
/*
 * we use FIRMWARE_UNINITIALIZED to detect checks against uc_fw->status
 * before we're looked at the HW caps to see if we have uc support




Re: [Intel-gfx] [PATCH 3/5] drm/i915/uc: Track patch level versions on reduced version firmware files

2023-04-18 Thread Ceraolo Spurio, Daniele




On 4/14/2023 5:57 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

When reduced version firmware files were added (matching major
component being the only strict requirement), the minor version was
still tracked and a notification reported if it was older. However,
the patch version should really be tracked as well for the same
reasons. The KMD can work without the change but if the effort has
been taken to release a new firmware with the change then there must
be a valid reason for doing so - important bug fix, security fix, etc.
And in that case it would be good to alert the user if they are
missing out on that new fix.

Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 41 +---
  1 file changed, 30 insertions(+), 11 deletions(-)

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 a82a53dbbc86d..6bb45d6b8da5f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -80,14 +80,14 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
   */
  #define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_maj, guc_mmp) \
fw_def(METEORLAKE,   0, guc_mmp(mtl,  70, 6, 5)) \
-   fw_def(DG2,  0, guc_maj(dg2,  70, 5)) \
-   fw_def(ALDERLAKE_P,  0, guc_maj(adlp, 70, 5)) \
+   fw_def(DG2,  0, guc_maj(dg2,  70, 5, 4)) \
+   fw_def(ALDERLAKE_P,  0, guc_maj(adlp, 70, 5, 4)) \
fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 70, 1, 1)) \
fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 69, 0, 3)) \
-   fw_def(ALDERLAKE_S,  0, guc_maj(tgl,  70, 5)) \
+   fw_def(ALDERLAKE_S,  0, guc_maj(tgl,  70, 5, 4)) \
fw_def(ALDERLAKE_S,  0, guc_mmp(tgl,  70, 1, 1)) \
fw_def(ALDERLAKE_S,  0, guc_mmp(tgl,  69, 0, 3)) \
-   fw_def(DG1,  0, guc_maj(dg1,  70, 5)) \
+   fw_def(DG1,  0, guc_maj(dg1,  70, 5, 4)) \
fw_def(ROCKETLAKE,   0, guc_mmp(tgl,  70, 1, 1)) \
fw_def(TIGERLAKE,0, guc_mmp(tgl,  70, 1, 1)) \
fw_def(JASPERLAKE,   0, guc_mmp(ehl,  70, 1, 1)) \


AFAICS in linux-firmware we don't have any 70.5.4 binaries, the newest 
ones are 70.5.1.



@@ -141,7 +141,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
__stringify(patch_) ".bin"
  
  /* Minor for internal driver use, not part of file name */

-#define MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_) \
+#define MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_, patch_) \
__MAKE_UC_FW_PATH_MAJOR(prefix_, "guc", major_)
  
  #define MAKE_GUC_FW_PATH_MMP(prefix_, major_, minor_, patch_) \

@@ -197,9 +197,9 @@ struct __packed uc_fw_blob {
{ UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \
  .legacy = true }
  
-#define GUC_FW_BLOB(prefix_, major_, minor_) \

-   UC_FW_BLOB_NEW(major_, minor_, 0, false, \
-  MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_))
+#define GUC_FW_BLOB(prefix_, major_, minor_, patch_) \
+   UC_FW_BLOB_NEW(major_, minor_, patch_, false, \
+  MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_, patch_))
  
  #define GUC_FW_BLOB_MMP(prefix_, major_, minor_, patch_) \

UC_FW_BLOB_OLD(major_, minor_, patch_, \
@@ -296,6 +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->file_wanted.ver.patch = blob->patch;
uc_fw->loaded_via_gsc = blob->loaded_via_gsc;
found = true;
break;
@@ -776,6 +777,17 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
if (uc_fw->type == INTEL_UC_FW_TYPE_GUC && 
!guc_check_version_range(uc_fw))
goto fail;
  
+	gt_info(gt, "%s firmware: wanted = %s / %d.%d.%d, got = %s / %d.%d.%d\n",

+   intel_uc_fw_type_repr(uc_fw->type),
+   uc_fw->file_wanted.path,
+   uc_fw->file_wanted.ver.major,
+   uc_fw->file_wanted.ver.minor,
+   uc_fw->file_wanted.ver.patch,
+   uc_fw->file_selected.path,
+   uc_fw->file_selected.ver.major,
+   uc_fw->file_selected.ver.minor,
+   uc_fw->file_selected.ver.patch);


Some of the info here is redundant from print_fw_ver(). Can we have a 
single print with all the info we need?

Something like:

GuC firmware i915/mtl_guc_70.bin (v70.6.5, expected v70.6.4 or newer)

Otherwise, I'd suggest demoting this to gt_dbg to avoid printing the 
same thing twice at info verbosity


Daniele


+
if (uc_fw->file_wanted.ver.major && uc_fw->file_selected.ver.major) {
/* Check the file's major version was as it claimed */
if (uc_fw->file_selected.ver.major != 
uc_fw->file_wanted.ver.major) {
@@ -790,6 +802,9 @@ int intel_uc_fw_fetch(struct 

Re: [Intel-gfx] [PATCH 1/5] drm/i915/guc: Decode another GuC load failure case

2023-04-18 Thread Ceraolo Spurio, Daniele




On 4/14/2023 5:57 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

Explain another potential firmware failure mode and early exit the
long wait if hit.

Signed-off-by: John Harrison 



Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h | 1 +
  drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c   | 6 ++
  2 files changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h 
b/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
index bcb1129b36102..dabeaf4f245f3 100644
--- a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
@@ -44,6 +44,7 @@ enum intel_guc_load_status {
  enum intel_bootrom_load_status {
INTEL_BOOTROM_STATUS_NO_KEY_FOUND = 0x13,
INTEL_BOOTROM_STATUS_AES_PROD_KEY_FOUND   = 0x1A,
+   INTEL_BOOTROM_STATUS_PROD_KEY_CHECK_FAILURE   = 0x2B,
INTEL_BOOTROM_STATUS_RSA_FAILED   = 0x50,
INTEL_BOOTROM_STATUS_PAVPC_FAILED = 0x73,
INTEL_BOOTROM_STATUS_WOPCM_FAILED = 0x74,
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
index 6fda3aec5c66a..0ff088a5e51a8 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -129,6 +129,7 @@ static inline bool guc_load_done(struct intel_uncore 
*uncore, u32 *status, bool
case INTEL_BOOTROM_STATUS_RC6CTXCONFIG_FAILED:
case INTEL_BOOTROM_STATUS_MPUMAP_INCORRECT:
case INTEL_BOOTROM_STATUS_EXCEPTION:
+   case INTEL_BOOTROM_STATUS_PROD_KEY_CHECK_FAILURE:
*success = false;
return true;
}
@@ -219,6 +220,11 @@ static int guc_wait_ucode(struct intel_guc *guc)
guc_info(guc, "firmware signature verification 
failed\n");
ret = -ENOEXEC;
break;
+
+   case INTEL_BOOTROM_STATUS_PROD_KEY_CHECK_FAILURE:
+   guc_info(guc, "firmware production part check 
failure\n");
+   ret = -ENOEXEC;
+   break;
}
  
  		switch (ukernel) {




Re: [Intel-gfx] [PATCH 2/5] drm/i915/guc: Print status register when waiting for GuC to load

2023-04-18 Thread Ceraolo Spurio, Daniele




On 4/14/2023 5:57 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

If the GuC load is taking an excessively long time, the wait loop
currently prints the GT frequency. Extend that to include the GuC
status as well so we can see if the GuC is actually making progress or
not.

Signed-off-by: John Harrison 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 6 --
  1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
index 0ff088a5e51a8..364d0d546ec82 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -191,8 +191,10 @@ static int guc_wait_ucode(struct intel_guc *guc)
if (!ret || !success)
break;
  
-		guc_dbg(guc, "load still in progress, count = %d, freq = %dMHz\n",

-   count, 
intel_rps_read_actual_frequency(>gt->rps));
+   guc_dbg(guc, "load still in progress, count = %d, freq = %dMHz, 
status = 0x%08X [0x%02X/%02X]\n",
+   count, 
intel_rps_read_actual_frequency(>gt->rps), status,
+   REG_FIELD_GET(GS_BOOTROM_MASK, status),
+   REG_FIELD_GET(GS_UKERNEL_MASK, status));
}
after = ktime_get();
delta = ktime_sub(after, before);




Re: [Intel-gfx] [PATCH v7 5/8] drm/i915/pxp: Add ARB session creation and cleanup

2023-04-17 Thread Ceraolo Spurio, Daniele




On 4/17/2023 11:21 AM, Teres Alexis, Alan Previn wrote:

On Mon, 2023-04-10 at 10:14 -0700, Ceraolo Spurio, Daniele wrote:




alan:snip


@@ -354,8 +368,14 @@ int intel_pxp_start(struct intel_pxp *pxp)
if (!intel_pxp_is_enabled(pxp))
return -ENODEV;
   
-	if (wait_for(pxp_component_bound(pxp), 250))

-   return -ENXIO;
+   if (HAS_ENGINE(pxp->ctrl_gt, GSC0)) {
+   /* Use a larger 1 second timeout considering all the 
dependencies. */
+   if (wait_for(intel_pxp_gsccs_is_ready_for_sessions(pxp), 1000))
+   return -ENXIO;

This needs a comment to explain that we expect userspace to retry later
if we return -ENXIO and therefore the timeout is smaller that what would
be required to guarantee that the init can complete. It also needs an
ack from the userspace drivers for this behavior.


alan: I agree with a requirement to comment this down. However, i believe its 
better
to put this int the UAPI header file comment-documentation since it applies to 
both
current MTL as well as previous ADL cases (this is not new behavior being 
introduced
in MTL but it is fixing of the spec of existing behavior).
That said, your feedback is already being addressed by patch #6 but i will 
ammend
patch #6 to add the detail you highlighted WRT ~"timeout is not larger than the 
completion-guarantee...".


Can you move that comment update for the context getparam from the next 
patch to this one? that way it's all nicely self-contained in this patch.



alan:snip

+fw_err_to_string(u32 type)
+{
+   switch (type) {
+   case PXP_STATUS_ERROR_API_VERSION:
+   return "ERR_API_VERSION";
+   case PXP_STATUS_NOT_READY:
+   return "ERR_NOT_READY";
+   case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:
+   case PXP_STATUS_PLATFCONFIG_KF1_BAD:
+   return "ERR_PLATFORM_CONFIG";
+   default:
+   break;
+   }
+   return NULL;
+}
+

There is a lot of replication for this error handling, I'm wondering if
it's worth adding a common function to handle this. Something like:

intel_pxp_header_error(u32 header, const char *op, u32 id)
{
if (is_fw_err_platform_config(header.status)) {
drm_info_once(>drm,
  "PXP %s-%d failed due to BIOS/SOC:0x%08x:%s\n",
  op, id, header.status,
  fw_err_to_string(header.status));
} else {
drm_dbg(>drm, "PXP %s-%d failed 0x%08x:%st:\n",
op, id, header.status,
fw_err_to_string(header.status));
drm_dbg(>drm, " cmd-detail: 
ID=[0x%08x],API-Ver-[0x%08x]\n",
header.command_id, header.api_version);
}
}


Not a blocker.

alan: Thanks - i will have to address as a stand alone patch since i have to
think about moving this to a comment helper layer (common to both ADL-mei-comp 
and MTL-gsccs)
while potentially have different set of error codes that can mean different 
reporting levels
(i.e. notice once coz its a platform limit vs always err out if its runtime 
related).
Once this series gets merged it will be easier to work on that patch (which 
would require both
backends to be present in the baseline).
alan:snip

+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h
@@ -10,14 +10,18 @@
   
   struct intel_pxp;
   
-#define GSC_REPLY_LATENCY_MS 200

+#define GSC_REPLY_LATENCY_MS 210

why move from 200 to 210? not a problem, I just want to understand why
this is required.

Daniele

alan: so 200 is based on the fw spec - and from real testing i observed the 
occasional highs touching ~185ms.
However, the spec gives this number as the expected max time the firmware is 
going to take to process the request
and post a reply. Therefore it doesn't include the additional overhead for the 
request creation, emision,
submission via guc and the completion pipeline completion indication. All of 
these contribute additional layers
of possible delay. Since arb-session creation and invalidation are not common 
events,
I believe a slightly wider overhead of 10 milisec will not hurt.


Agreed. Can you add a comment? something like "Max FW response time is 
200ms, to which we add 10ms to account for overhead".

With those 2 nits addressed:

Reviewed-by: Daniele Ceraolo Spurio 

Daniele







Re: [Intel-gfx] [PATCH] drm/i915/gt: Mask media GuC interrupts

2023-04-14 Thread Ceraolo Spurio, Daniele




On 4/14/2023 9:25 AM, Andi Shyti wrote:

MTL features a dedicated media engine that operates on its
independent GT, requiring activation of its specific interrupt
set.

Enable the necessary interrupts in a single action when the media
engine is present, bypassing the need to iterate through all the
GTs.

Signed-off-by: Andi Shyti 
---
Hi,

I'm starting with v0 as this patch is very different from the
ones proposed recently.

After all the discussions on this patch, I took Matt's suggestion
since it seemed the most immediate.

However, in the long run, I agree that we should have a
specific mtl_ function for enabling interrupts.

Thank you Matt and Daniele for your input.

If this patch hasn't missed anything, is it too optimistic to
expect MTL to boot? :-)


The GSC engine also has interrupts tied to the media GT and those are 
conditional, so that engine won't work with just this patch. The system 
might boot because the GSC engine gets disabled if the FW is not there, 
but IMO if we want a single function to handle both GTs we need to do it 
proper support for the engines and not hack around just the GuC.


Daniele



Andi

  drivers/gpu/drm/i915/gt/intel_gt_irq.c | 14 --
  1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c 
b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
index 1b25a60391522..162a27b4c4095 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
@@ -254,7 +254,6 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
  {
struct intel_uncore *uncore = gt->uncore;
u32 irqs = GT_RENDER_USER_INTERRUPT;
-   u32 guc_mask = intel_uc_wants_guc(>uc) ? GUC_INTR_GUC2HOST : 0;
u32 gsc_mask = 0;
u32 dmask;
u32 smask;
@@ -309,17 +308,20 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
if (gsc_mask)
intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_MASK, 
~gsc_mask);
  
-	if (guc_mask) {

+   if (intel_uc_wants_guc(>uc)) {
+   u32 guc_mask = GUC_INTR_GUC2HOST;
/* the enable bit is common for both GTs but the masks are 
separate */
-   u32 mask = gt->type == GT_MEDIA ?
-   REG_FIELD_PREP(ENGINE0_MASK, guc_mask) :
-   REG_FIELD_PREP(ENGINE1_MASK, guc_mask);
+   u32 mask = REG_FIELD_PREP(ENGINE1_MASK, guc_mask);
+
+   /* Mask the GuC interrupts of media engine if present */
+   if (MEDIA_VER(gt->i915) >= 13)
+   mask |= REG_FIELD_PREP(ENGINE0_MASK, guc_mask);
  
  		intel_uncore_write(uncore, GEN11_GUC_SG_INTR_ENABLE,

   REG_FIELD_PREP(ENGINE1_MASK, guc_mask));
  
  		/* we might not be the first GT to write this reg */

-   intel_uncore_rmw(uncore, MTL_GUC_MGUC_INTR_MASK, mask, 0);
+   intel_uncore_write(uncore, MTL_GUC_MGUC_INTR_MASK, mask);
}
  
  	/*




Re: [Intel-gfx] [PATCH] drm/i915/gt: Avoid out-of-bounds access when loading HuC

2023-04-13 Thread Ceraolo Spurio, Daniele




On 4/13/2023 1:03 PM, Lucas De Marchi wrote:

When HuC is loaded by GSC, there is no header definition for the kernel
to look at and firmware is just handed to GSC. However when reading the
version, it should still check the size of the blob to guarantee it's not
incurring into out-of-bounds array access.

If firmware is smaller than expected, the following message is now
printed:

# echo boom > /lib/firmware/i915/dg2_huc_gsc.bin
# dmesg | grep -i huc
[drm] GT0: HuC firmware i915/dg2_huc_gsc.bin: invalid size: 5 < 184
[drm] *ERROR* GT0: HuC firmware i915/dg2_huc_gsc.bin: fetch failed 
-ENODATA
...

Even without this change the size, header and signature are still
checked by GSC when loading, so this only avoids the out-of-bounds array
access.

Fixes: a7b516bd981f ("drm/i915/huc: Add fetch support for gsc-loaded HuC 
binary")
Cc: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Signed-off-by: Lucas De Marchi 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 21 +
  1 file changed, 17 insertions(+), 4 deletions(-)

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 1ac6f9f340e3..a82a53dbbc86 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -489,12 +489,25 @@ static void __force_fw_fetch_failures(struct intel_uc_fw 
*uc_fw, int e)
}
  }
  
-static int check_gsc_manifest(const struct firmware *fw,

+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 = dw[HUC_GSC_VERSION_HI_DW];
-   u32 version_lo = dw[HUC_GSC_VERSION_LO_DW];
+   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);
@@ -665,7 +678,7 @@ static int check_fw_header(struct intel_gt *gt,
return 0;
  
  	if (uc_fw->loaded_via_gsc)

-   err = check_gsc_manifest(fw, uc_fw);
+   err = check_gsc_manifest(gt, fw, uc_fw);
else
err = check_ccs_header(gt, fw, uc_fw);
if (err)




Re: [Intel-gfx] [PATCH v2] drm/i915: Make IRQ reset and postinstall multi-gt aware

2023-04-13 Thread Ceraolo Spurio, Daniele




On 4/13/2023 8:52 AM, Matt Roper wrote:

On Thu, Apr 13, 2023 at 03:56:21PM +0200, Andi Shyti wrote:

Hi Tvrtko,

(I forgot to CC Daniele)

On Thu, Apr 13, 2023 at 11:41:28AM +0100, Tvrtko Ursulin wrote:

On 13/04/2023 10:20, Andi Shyti wrote:

From: Paulo Zanoni 

In multitile systems IRQ need to be reset and enabled per GT.

Although in MTL the GUnit misc interrupts register set are
available only in GT-0, we need to loop through all the GT's
in order to initialize the media engine which lies on a different
GT.

Signed-off-by: Paulo Zanoni 
Cc: Tvrtko Ursulin 
Signed-off-by: Andi Shyti 
---
Hi,

proposing again this patch, apparently GuC needs this patch to
initialize the media GT.

What is the resolution for Matt's concern that this is wrong for MTL?

There are two explanations, one easy and one less easy.

The easy one: without this patch i915 doesn't boot on MTL!(*)

The second explanation is that in MTL the media engine has it's
own set of misc irq's registers and those are on a different GT
(Daniele pointed this out).

Assuming you're talking about MTL_GUC_MGUC_INTR_MASK, that's not true;
it's just a single sgunit register (0x1900e8) that has different
bitfields for the primary GuC and the media GuC.  So I still think we
should avoid looping over GTs; it's actually much simpler to handle
things in a single pass since we can just determine the single register
value once (all fields) and write it directly, instead of doing two
separate RMW updates to the same register to try to avoid clobbering
the other GuC's settings.

For pre-MTL platforms, it's the same register, except that the bitfield
now devoted to the media GuC was previously used for something else
(scatter/gather).


It's not just the GuC, the VCS/VECS engine programming is also tied to 
the media GT (via the HAS_ENGINE checks). It looks like we 
unconditionally program VCS 0 and 2, so it'll still work for MTL, but if 
we get a device with more VCS engines it'll break. Maybe we can add a 
MTL version of the function that just programs everything 
unconditionally? Going forward it should be ok to program things for 
engines that don't exist, but I'm not sure we can do that for older 
platforms that came before the extra engines were ever defined in HW.


Daniele




Matt


I sent this patch not to bypass any review, but to restart the
discussion as this patch was just dropped.

Thanks,
Andi


(*)
[drm] *ERROR* GT1: GUC: CT: No response for request 0x550a (fence 7)
[drm] *ERROR* GT1: GUC: CT: Sending action 0x550a failed (-ETIMEDOUT) status=0X0
[drm] *ERROR* GT1: GUC: Failed to enable usage stats: -ETIMEDOUT
[drm] *ERROR* GT1: GuC initialization failed -ETIMEDOUT
[drm] *ERROR* GT1: Enabling uc failed (-5)
[drm] *ERROR* GT1: Failed to initialize GPU, declaring it wedged!




Re: [Intel-gfx] [PATCH v7 6/8] drm/i915/uapi/pxp: Fix UAPI spec comments and add GET_PARAM for PXP

2023-04-10 Thread Ceraolo Spurio, Daniele




On 4/6/2023 10:44 AM, Alan Previn wrote:

1. UAPI update:
Without actually changing backward compatible behavior, update
i915's drm-uapi comments that describe the possible error values
when creating a context with I915_CONTEXT_PARAM_PROTECTED_CONTENT.
Since the first merge of PXP support on ADL, i915 returns
-ENXIO if a dependency such as firmware or component driver
was yet to be loaded or returns -EIO if the creation attempt
failed when requested by the PXP firmware (specific firmware
error responses are reported in dmesg).

2. GET_PARAM for PXP:
Because of the additional firmware, component-driver and
initialization depedencies required on MTL platform before a
PXP context can be created, UMD calling for PXP creation as a
way to get-caps can take a long time. An actual real world
customer stack has seen this happen in the 4-to-8 second range
after the kernel starts (which sees MESA's init appear in the
middle of this range as the compositor comes up). To avoid
unncessary delays experienced by the UMD for get-caps purposes,
add a GET_PARAM for I915_PARAM_PXP_SUPPORT.

However, some failures can still occur after all the depedencies
are met (such as firmware init flow failure, bios configurations
or SOC fusing not allowing PXP enablement). Those scenarios will
only be known to user space when it attempts creating a PXP context.

With this change, large delays are only met by user-space procsses
that explicitly need to create a PXP context and boot very early.
There is no way to avoid this today.

Signed-off-by: Alan Previn 
---
  drivers/gpu/drm/i915/i915_getparam.c |  5 +
  include/uapi/drm/i915_drm.h  | 22 ++
  2 files changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_getparam.c 
b/drivers/gpu/drm/i915/i915_getparam.c
index 2238e096c957..9729384f033f 100644
--- a/drivers/gpu/drm/i915/i915_getparam.c
+++ b/drivers/gpu/drm/i915/i915_getparam.c
@@ -5,6 +5,8 @@
  #include "gem/i915_gem_mman.h"
  #include "gt/intel_engine_user.h"
  
+#include "pxp/intel_pxp.h"

+
  #include "i915_cmd_parser.h"
  #include "i915_drv.h"
  #include "i915_getparam.h"
@@ -102,6 +104,9 @@ int i915_getparam_ioctl(struct drm_device *dev, void *data,
if (value < 0)
return value;
break;
+   case I915_PARAM_PXP_STATUS:
+   value = intel_pxp_is_enabled(i915->pxp) ? 0 : -ENODEV;
+   break;
case I915_PARAM_MMAP_GTT_VERSION:
/* Though we've started our numbering from 1, and so class all
 * earlier versions as 0, in effect their value is undefined as
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index dba7c5a5b25e..0c1729bd911d 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -771,6 +771,20 @@ typedef struct drm_i915_irq_wait {
   */
  #define I915_PARAM_OA_TIMESTAMP_FREQUENCY 57
  
+/*

+ * Query the status of PXP support in i915.
+ *
+ * The query can fail in the following scenarios with the listed error codes:
+ *  -ENODEV = PXP support is not available on the GPU device or in the kernel
+ *due to missing component drivers or kernel configs.
+ * If the IOCTL is successful, the returned parameter will be set to one of the
+ * following values:
+ *   0 = PXP support maybe available but underlying SOC fusing, BIOS or 
firmware
+ *   configuration is unknown and a PXP-context-creation would be required
+ *   for final verification of feature availibility.


Would it be useful to add:

1 = PXP support is available

And start returning that after we've successfully created our first 
session? Not sure if userspace would use this though, since they still 
need to handle the 0 case anyway.
I'm also ok with this patch as-is, as long as you get an ack from the 
userspace drivers for this interface behavior:


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


+ */
+#define I915_PARAM_PXP_STATUS   58
+
  /* Must be kept compact -- no holes and well documented */
  
  /**

@@ -2096,6 +2110,14 @@ struct drm_i915_gem_context_param {
   *
   * -ENODEV: feature not available
   * -EPERM: trying to mark a recoverable or not bannable context as protected
+ * -ENXIO: A dependency such as a component driver or firmware is not yet
+ * loaded and user space may attempt again. Depending on the device
+ * this error may be reported if the protected context creation is
+ * attempted very early from kernel start (numbers vary depending on
+ * system and kernel config):
+ *- ADL/RPL: up to 3 seconds
+ *- MTL: up to 8 seconds
+ * -EIO: The firmware did not succeed in creating the protected context.
   */
  #define I915_CONTEXT_PARAM_PROTECTED_CONTENT0xd
  /* Must be kept compact -- no holes and well documented */




Re: [Intel-gfx] [PATCH v7 5/8] drm/i915/pxp: Add ARB session creation and cleanup

2023-04-10 Thread Ceraolo Spurio, Daniele




On 4/6/2023 10:44 AM, Alan Previn wrote:

Add MTL's function for ARB session creation using PXP firmware
version 4.3 ABI structure format.

Also add MTL's function for ARB session invalidation but this
reuses PXP firmware version 4.2 ABI structure format.

For both cases, in the back-end gsccs functions for sending messages
to the firmware inspect the GSC-CS-Mem-Header's pending-bit which
means the GSC firmware is busy and we should retry.

Given the last hw requirement, lets also update functions in
front-end layer that wait for session creation or teardown
completion to use new worst case timeout periods.

Signed-off-by: Alan Previn 
---
  drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c |  10 ++
  drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h |   1 +
  drivers/gpu/drm/i915/pxp/intel_pxp.c  |  28 +++-
  .../drm/i915/pxp/intel_pxp_cmd_interface_43.h |  21 +++
  drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c| 130 ++
  drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h|   8 +-
  drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  11 +-
  7 files changed, 202 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index 1d9fdfb11268..85f720af2f75 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -13,6 +13,7 @@
  #define GSC_FW_STATUS_REG _MMIO(0x116C40)
  #define GSC_FW_CURRENT_STATE  REG_GENMASK(3, 0)
  #define   GSC_FW_CURRENT_STATE_RESET  0
+#define   GSC_FW_PROXY_STATE_NORMAL5
  #define GSC_FW_INIT_COMPLETE_BIT  REG_BIT(9)
  
  static bool gsc_is_in_reset(struct intel_uncore *uncore)

@@ -31,6 +32,15 @@ bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)
return fw_status & GSC_FW_INIT_COMPLETE_BIT;
  }
  
+bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc)

+{
+   struct intel_uncore *uncore = gsc_uc_to_gt(gsc)->uncore;
+   u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
+
+   return REG_FIELD_GET(GSC_FW_CURRENT_STATE, fw_status) ==
+  GSC_FW_PROXY_STATE_NORMAL;
+}
+
  static int emit_gsc_fw_load(struct i915_request *rq, struct intel_gsc_uc *gsc)
  {
u32 offset = i915_ggtt_offset(gsc->local);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
index f4c1106bb2a9..fff8928218df 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
@@ -13,5 +13,6 @@ struct intel_uncore;
  
  int intel_gsc_uc_fw_upload(struct intel_gsc_uc *gsc);

  bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc);
+bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc);
  
  #endif

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 8949d4be7882..550457bbb034 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -291,6 +291,8 @@ static bool pxp_component_bound(struct intel_pxp *pxp)
  
  static int __pxp_global_teardown_final(struct intel_pxp *pxp)

  {
+   int timeout;
+
if (!pxp->arb_is_valid)
return 0;
/*
@@ -300,7 +302,12 @@ static int __pxp_global_teardown_final(struct intel_pxp 
*pxp)
intel_pxp_mark_termination_in_progress(pxp);
intel_pxp_terminate(pxp, false);
  
-	if (!wait_for_completion_timeout(>termination, msecs_to_jiffies(250)))

+   if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
+   timeout = GSCFW_MAX_ROUND_TRIP_LATENCY_MS;
+   else
+   timeout = 250;
+
+   if (!wait_for_completion_timeout(>termination, 
msecs_to_jiffies(timeout)))
return -ETIMEDOUT;
  
  	return 0;

@@ -308,6 +315,8 @@ static int __pxp_global_teardown_final(struct intel_pxp 
*pxp)
  
  static int __pxp_global_teardown_restart(struct intel_pxp *pxp)

  {
+   int timeout;
+
if (pxp->arb_is_valid)
return 0;
/*
@@ -316,7 +325,12 @@ static int __pxp_global_teardown_restart(struct intel_pxp 
*pxp)
 */
pxp_queue_termination(pxp);
  
-	if (!wait_for_completion_timeout(>termination, msecs_to_jiffies(250)))

+   if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
+   timeout = GSCFW_MAX_ROUND_TRIP_LATENCY_MS;
+   else
+   timeout = 250;
+
+   if (!wait_for_completion_timeout(>termination, 
msecs_to_jiffies(timeout)))
return -ETIMEDOUT;
  
  	return 0;

@@ -354,8 +368,14 @@ int intel_pxp_start(struct intel_pxp *pxp)
if (!intel_pxp_is_enabled(pxp))
return -ENODEV;
  
-	if (wait_for(pxp_component_bound(pxp), 250))

-   return -ENXIO;
+   if (HAS_ENGINE(pxp->ctrl_gt, GSC0)) {
+   /* Use a larger 1 second timeout considering all the 
dependencies. */
+   if (wait_for(intel_pxp_gsccs_is_ready_for_sessions(pxp), 1000))
+   return 

Re: [Intel-gfx] [PATCH v7 4/8] drm/i915/pxp: Add GSC-CS backend to send GSC fw messages

2023-04-10 Thread Ceraolo Spurio, Daniele




On 4/6/2023 10:44 AM, Alan Previn wrote:

Add GSC engine based method for sending PXP firmware packets
to the GSC firmware for MTL (and future) products.

Use the newly added helpers to populate the GSC-CS memory
header and send the message packet to the FW by dispatching
the GSC_HECI_CMD_PKT instruction on the GSC engine.

We use non-priveleged batches for submission to GSC engine
which require two buffers for the request:
  - a buffer for the HECI packet that contains PXP FW commands
  - a batch-buffer that contains the engine instruction for
sending the HECI packet to the GSC firmware.

Thus, add the allocation and freeing of these buffers in gsccs
init and fini.

The GSC-fw may reply to commands with a SUCCESS but with an
additional pending-bit set in the reply packet. This bit
means the GSC-FW is currently busy and the caller needs to
try again with the gsc_message_handle the fw returned. Thus,
add a wrapper to continuously retry send_message while
replaying the gsc_message_handle. Retries need to follow the
arch-spec count and delay until GSC-FW replies with the real
SUCCESS or timeout after that spec'd delay.

The GSC-fw requires a non-zero host_session_handle provided
by the caller to enable gsc_message_handle tracking. Thus,
allocate the host_session_handle at init and destroy it
at fini (the latter requiring an FYI to the gsc-firmware).

Signed-off-by: Alan Previn 
---
  .../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h |   1 +
  .../drm/i915/pxp/intel_pxp_cmd_interface_43.h |   3 +
  drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c| 240 +-
  drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h|   4 +
  drivers/gpu/drm/i915/pxp/intel_pxp_types.h|   6 +
  5 files changed, 253 insertions(+), 1 deletion(-)

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 3addce861854..e4d6662339e8 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
@@ -51,6 +51,7 @@ struct intel_gsc_mtl_header {
 */
u32 flags;
  #define GSC_OUTFLAG_MSG_PENDING 1
+#define GSC_INFLAG_MSG_CLEANUP BIT(1)


For consistency those should all be BIT() defines

  
  	u32 status;

  } __packed;





@@ -38,18 +248,46 @@ gsccs_allocate_execution_resource(struct intel_pxp *pxp)
if (!engine)
return -ENODEV;
  
+	/*

+* Now, allocate, pin and map two objects, one for the heci message 
packet
+* and another for the batch buffer we submit into GSC engine (that 
includes the packet).
+* NOTE: GSC-CS backend is currently only supported on MTL, so we 
allocate shmem.
+*/
+   err = gsccs_create_buffer(pxp->ctrl_gt, "Heci Packet",
+ 2 * PXP43_MAX_HECI_INOUT_SIZE,
+ _res->pkt_vma, _res->pkt_vaddr);
+   if (err)
+   return err;
+
+   err = gsccs_create_buffer(pxp->ctrl_gt, "Batch Buffer", PAGE_SIZE,
+ _res->bb_vma, _res->bb_vaddr);
+   if (err)
+   goto free_pkt;
+
/* Finally, create an intel_context to be used during the submission */
ce = intel_context_create(engine);
if (IS_ERR(ce)) {
drm_err(>i915->drm, "Failed creating gsccs backend ctx\n");
-   return PTR_ERR(ce);
+   err = PTR_ERR(ce);
+   goto free_batch;
}
  
  	i915_vm_put(ce->vm);

ce->vm = i915_vm_get(pxp->ctrl_gt->vm);
exec_res->ce = ce;
  
+	/* initialize host-session-handle (for all i915-to-gsc-firmware PXP cmds) */

+   get_random_bytes(_res->host_session_handle, 
sizeof(exec_res->host_session_handle));


Thinking back at this, maybe a possible solution to avoid randomly 
generated clashing values is to check if any of the existing exec_res 
already uses the generated value. Not a blocker because we only have 1 
exec_res for now, so no chance of clashing.


With the define fixed:

Reviewed-by: Daniele Ceraolo Spurio 

Daniele


+
return 0;
+
+free_batch:
+   i915_vma_unpin_and_release(_res->bb_vma, I915_VMA_RELEASE_MAP);
+free_pkt:
+   i915_vma_unpin_and_release(_res->pkt_vma, I915_VMA_RELEASE_MAP);
+   memset(exec_res, 0, sizeof(*exec_res));
+
+   return err;
  }
  
  void intel_pxp_gsccs_fini(struct intel_pxp *pxp)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h
index 354ea9a8f940..bd1c028bc80f 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h
@@ -10,6 +10,10 @@
  
  struct intel_pxp;
  
+#define GSC_REPLY_LATENCY_MS 200

+#define GSC_PENDING_RETRY_MAXCOUNT 40
+#define GSC_PENDING_RETRY_PAUSE_MS 50
+
  #ifdef CONFIG_DRM_I915_PXP
  void intel_pxp_gsccs_fini(struct intel_p

Re: [Intel-gfx] [PATCH v7 3/8] drm/i915/pxp: Add MTL helpers to submit Heci-Cmd-Packet to GSC

2023-04-10 Thread Ceraolo Spurio, Daniele




On 4/6/2023 10:44 AM, Alan Previn wrote:

Add helper functions into a new file for heci-packet-submission.
The helpers will handle generating the MTL GSC-CS Memory-Header
and submission of the Heci-Cmd-Packet instructions to the engine.

NOTE1: These common functions for heci-packet-submission will be used
by different i915 callers:
  1- GSC-SW-Proxy: This is pending upstream publication awaiting
 a few remaining opens
  2- MTL-HDCP: An equivalent patch has also been published at:
 https://patchwork.freedesktop.org/series/111876/. (Patch 1)
  3- PXP: This series.

NOTE2: A difference in this patch vs what is appearing is in bullet 2
above is that HDCP (and SW-Proxy) will be using priveleged submission
(GGTT and common gsc-uc-context) while PXP will be using non-priveleged
PPGTT, context and batch buffer. Therefore this patch will only slightly
overlap with the MTL-HDCP patches despite have very similar function
names (emit_foo vs emit_nonpriv_foo). This is because HECI_CMD_PKT
instructions require different flows and hw-specific code when done
via PPGTT based submission (not different from other engines). MTL-HDCP
contains the same intel_gsc_mtl_header_t structures as this but the
helpers there are different. Both add the same new file names.

NOTE3: Additional clarity about the heci-cmd-pkt layout and where the
common helpers come in:
  - On MTL, when an i915 subsystem needs to send a command request
to the security firmware, it will send that via the GSC-
engine-command-streamer.
  - However those commands, (lets call them "gsc_specific_fw_api"
calls), are not understood by the GSC command streamer hw.
  - The GSC CS only looks at the GSC_HECI_CMD_PKT instruction and
passes it along to the GSC firmware.
  - The GSC FW on the other hand needs additional metadata to know
which usage service is being called (PXP, HDCP, proxy, etc) along
with session specific info. Thus an extra header called GSC-CS
HECI Memory Header, (C) in below diagram is prepended before
the FW specific API, (D).
  - Thus, the structural layout of the request submitted would
need to look like the diagram below (for non-priv PXP).
  - In the diagram, the common helper for HDCP, (GSC-Sw-Proxy) and
PXP (i.e. new function intel_gsc_uc_heci_cmd_emit_mtl_header)
will populate blob (C) while additional helpers, different for
PPGGTT (this patch) vs GGTT (HDCP series) will populate
blobs (A) and (B) below.
   ___
  (A)  |  MI_BATCH_BUFFER_START (ppgtt, batchbuff-addr, ...) |
   | |   |
   |_|   |
   | (B)| GSC_HECI_CMD_PKT (pkt-addr-in, pkt-size-in,|   |
   ||   pkt-addr-out, pkt-size-out)  |
   || MI_BATCH_BUFFER_END|   |   |
   |||   |   |
   | |   |
   |_|   |
 |
 -
 |
\|/
   __V___
   |   _|
   |(C)|   ||
   |   | struct intel_gsc_mtl_header { ||
   |   |   validity marker ||
   |   |   heci_clent_id   ||
   |   |   ... ||
   |   |  }||
   |   |___||
   |(D)|   ||
   |   | struct gsc_fw_specific_api_foobar {   ||
   |   | ...   ||
   |   | For an example, see   ||
   |   | 'struct pxp43_create_arb_in' at   ||
   |   | intel_pxp_cmd_interface_43.h  ||
   |   |   ||
   |   | } ||
   |   |  Struture depends on command type ||
   |   | struct gsc_fw_specific_api_foobar {   ||
   |   |___||
   ||

That said, this patch provides basic helpers but leaves the
PXP subsystem (i.e. the caller) to handle (D) and everything
else such as input/output size verification or handling the
responses from security firmware (for example, requiring a retry).

Signed-off-by: Alan Previn 
---
  .../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c | 102 

Re: [Intel-gfx] [PATCH v5] drm/i915/pxp: limit drm-errors or warning on firmware API failures

2023-03-23 Thread Ceraolo Spurio, Daniele




On 3/23/2023 11:41 AM, Alan Previn wrote:

MESA driver is creating protected context on every driver handle
creation to query caps bits for app. So when running CI tests,
they are observing hundreds of drm_errors when enabling PXP
in .config but using SOC fusing or BIOS configuration that cannot
support PXP sessions.

The fixes tag referenced below was to resolve a related issue
where we wanted to silence error messages, but that case was due
to outdated IFWI (firmware) that definitely needed an upgrade and
was, at that point, considered a one-off case as opposed to today's
realization that default CI was enabling PXP in kernel config for
all testing.

So with this patch, let's strike a balance between issues that is
critical but are root-caused from HW/platform gaps (louder drm-warn
but just ONCE) vs other cases where it could also come from session
state machine (which cannot be a WARN_ONCE since it can be triggered
due to runtime operation events).

Let's use helpers for these so as more functions are added in future
features / HW (or as FW designers continue to bless upstreaming of
the error codes and meanings), we only need to update the helpers.

NOTE: Don't completely remove FW errors (via drm_debug) or else cusomer
apps that really needs to know that content protection failed won't
be aware of it.

v2: - Add fixes tag (Trvtko)
v3: - Break multi-line drm_dbg strings into separate drm_dbg (Daniele)
 - Fix couple of typecasting nits (Daniele)
v4: - Unsuccessful PXP FW cmd due to platform configuration shouldn't
   use drm_WARN_once (Tvrtko), Switched to use drm_info_once.
v5: - Added "reported-and-tested" by Eero.

Reported-and-tested-by: Eero Tamminen 


checkpatch seems to not like this tag. Maybe have 2 lines?

Reported-by: ...
Tested-by: ...

Can be fixed while merging.


Fixes: b762787bf767 ("drm/i915/pxp: Use drm_dbg if arb session failed due to fw 
version")
Signed-off-by: Alan Previn 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  .../i915/pxp/intel_pxp_cmd_interface_cmn.h|  3 +
  drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  2 +-
  drivers/gpu/drm/i915/pxp/intel_pxp_tee.c  | 77 +++
  3 files changed, 67 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h
index ae9b151b7cb7..6f6541d5e49a 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h
@@ -18,6 +18,9 @@
  enum pxp_status {
PXP_STATUS_SUCCESS = 0x0,
PXP_STATUS_ERROR_API_VERSION = 0x1002,
+   PXP_STATUS_NOT_READY = 0x100e,
+   PXP_STATUS_PLATFCONFIG_KF1_NOVERIF = 0x101a,
+   PXP_STATUS_PLATFCONFIG_KF1_BAD = 0x101f,
PXP_STATUS_OP_NOT_PERMITTED = 0x4013
  };
  
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c

index 448cacb0465d..7de849cb6c47 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -74,7 +74,7 @@ static int pxp_create_arb_session(struct intel_pxp *pxp)
  
  	ret = pxp_wait_for_session_state(pxp, ARB_SESSION, true);

if (ret) {
-   drm_err(>i915->drm, "arb session failed to go in play\n");
+   drm_dbg(>i915->drm, "arb session failed to go in play\n");
return ret;
}
drm_dbg(>i915->drm, "PXP ARB session is alive\n");
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index d9d248b48093..a2846b1dbbee 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -19,6 +19,37 @@
  #include "intel_pxp_tee.h"
  #include "intel_pxp_types.h"
  
+static bool

+is_fw_err_platform_config(u32 type)
+{
+   switch (type) {
+   case PXP_STATUS_ERROR_API_VERSION:
+   case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:
+   case PXP_STATUS_PLATFCONFIG_KF1_BAD:
+   return true;
+   default:
+   break;
+   }
+   return false;
+}
+
+static const char *
+fw_err_to_string(u32 type)
+{
+   switch (type) {
+   case PXP_STATUS_ERROR_API_VERSION:
+   return "ERR_API_VERSION";
+   case PXP_STATUS_NOT_READY:
+   return "ERR_NOT_READY";
+   case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:
+   case PXP_STATUS_PLATFCONFIG_KF1_BAD:
+   return "ERR_PLATFORM_CONFIG";
+   default:
+   break;
+   }
+   return NULL;
+}
+
  static int intel_pxp_tee_io_message(struct intel_pxp *pxp,
void *msg_in, u32 msg_in_size,
void *msg_out, u32 msg_out_max_size,
@@ -307,15 +338,22 @@ int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp 
*pxp,
  

Re: [Intel-gfx] [PATCH v2 2/2] drm/i915/guc: Allow for very slow GuC loading

2023-03-22 Thread Ceraolo Spurio, Daniele




On 3/16/2023 3:06 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

A failure to load the GuC is occasionally observed where the GuC log
actually showed that the GuC had loaded just fine. The implication
being that the load just took ever so slightly longer than the 200ms
timeout. Given that the actual time should be tens of milliseconds at
the slowest, this should never happen. So far the issue has generally
been caused by a bad IFWI resulting in low frequencies during boot
(depsite the KMD requesting max frequency). However, the issue seems
to happen more often than one would like.

So a) increase the timeout so that the user still gets a working
system even in the case of slow load. And b) report the frequency
during the load to see if that is the case of the slow down.

v2: Reduce timeout in non-debug builds, add references (Daniele)

References: https://gitlab.freedesktop.org/drm/intel/-/issues/7931
References: https://gitlab.freedesktop.org/drm/intel/-/issues/8060
References: https://gitlab.freedesktop.org/drm/intel/-/issues/8083
References: https://gitlab.freedesktop.org/drm/intel/-/issues/8136
References: https://gitlab.freedesktop.org/drm/intel/-/issues/8137
Signed-off-by: John Harrison 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 50 +--
  1 file changed, 47 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
index 0b49d84a8a9c2..6fda3aec5c66a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -12,6 +12,7 @@
  #include "gt/intel_gt.h"
  #include "gt/intel_gt_mcr.h"
  #include "gt/intel_gt_regs.h"
+#include "gt/intel_rps.h"
  #include "intel_guc_fw.h"
  #include "intel_guc_print.h"
  #include "i915_drv.h"
@@ -135,13 +136,29 @@ static inline bool guc_load_done(struct intel_uncore 
*uncore, u32 *status, bool
return false;
  }
  
+/*

+ * Use a longer timeout for debug builds so that problems can be detected
+ * and analysed. But a shorter timeout for releases so that user's don't
+ * wait forever to find out there is a problem. Note that the only reason
+ * an end user should hit the timeout is in case of extreme thermal throttling.
+ * And a system that is that hot during boot is probably dead anyway!
+ */
+#if defined(CONFIG_DRM_I915_DEBUG_GEM)
+#define GUC_LOAD_RETRY_LIMIT   20
+#else
+#define GUC_LOAD_RETRY_LIMIT   3
+#endif
+
  static int guc_wait_ucode(struct intel_guc *guc)
  {
struct intel_gt *gt = guc_to_gt(guc);
struct intel_uncore *uncore = gt->uncore;
+   ktime_t before, after, delta;
bool success;
u32 status;
-   int ret;
+   int ret, count;
+   u64 delta_ms;
+   u32 before_freq;
  
  	/*

 * Wait for the GuC to start up.
@@ -159,13 +176,32 @@ static int guc_wait_ucode(struct intel_guc *guc)
 * issues to be resolved. In the meantime bump the timeout to
 * 200ms. Even at slowest clock, this should be sufficient. And
 * in the working case, a larger timeout makes no difference.
+*
+* IFWI updates have also been seen to cause sporadic failures due to
+* the requested frequency not being granted and thus the firmware
+* load is attempted at minimum frequency. That can lead to load times
+* in the seconds range. However, there is a limit on how long an
+* individual wait_for() can wait. So wrap it in a loop.
 */
-   ret = wait_for(guc_load_done(uncore, , ), 200);
+   before_freq = intel_rps_read_actual_frequency(>gt->rps);
+   before = ktime_get();
+   for (count = 0; count < GUC_LOAD_RETRY_LIMIT; count++) {
+   ret = wait_for(guc_load_done(uncore, , ), 1000);
+   if (!ret || !success)
+   break;
+
+   guc_dbg(guc, "load still in progress, count = %d, freq = 
%dMHz\n",
+   count, 
intel_rps_read_actual_frequency(>gt->rps));
+   }
+   after = ktime_get();
+   delta = ktime_sub(after, before);
+   delta_ms = ktime_to_ms(delta);
if (ret || !success) {
u32 ukernel = REG_FIELD_GET(GS_UKERNEL_MASK, status);
u32 bootrom = REG_FIELD_GET(GS_BOOTROM_MASK, status);
  
-		guc_info(guc, "load failed: status = 0x%08X, ret = %d\n", status, ret);

+   guc_info(guc, "load failed: status = 0x%08X, time = %lldms, freq = 
%dMHz, ret = %d\n",
+status, delta_ms, 
intel_rps_read_actual_frequency(>gt->rps), ret);
guc_info(guc, "load failed: status: Reset = %d, BootROM = 0x%02X, 
UKernel = 0x%02X, MIA = 0x%02X, Auth = 0x%02X\n",
 REG_FIELD_GET(GS_MIA_IN_RESET, status),
 boo

Re: [Intel-gfx] [PATCH 1/2] drm/i915: limit double GT reset to pre-MTL

2023-03-22 Thread Ceraolo Spurio, Daniele




On 3/22/2023 12:44 PM, John Harrison wrote:

On 3/20/2023 14:10, Daniele Ceraolo Spurio wrote:

Commit 3db9d590557d ("drm/i915/gt: Reset twice") modified the code to
always hit the GDRST register twice when doing a reset, with the
reported aim to fix invalid post-reset engine state on some platforms
(Jasperlake being the only one actually mentioned).
It still concerns me that there are no actual details about this issue 
from a hardware perspective as to what/why it goes wrong, the comment 
is fully of non-definitive language - 'appears to', 'should', 'is 
still a concern that'. And there is no w/a number associated with it. 
It all feels extremely suspect and warrants a great big FIXME tag as a 
minimum.


I agree that the whole thing is unclear and we could add a FIXME, but 
IMO that is outside the scope of this patch as I'm not adding the code 
in question. This should be discussed with the original author/reviewers.


Daniele



John.




This is a problem on MTL, due to the fact that we have to apply a time
consuming WA (coming in the next patch) every time we hit the GDRST
register in a way that can include the GSC engine. Even post MTL, the
expectation is that we'll have some work to do before and after hitting
the GDRST if the GSC is involved.

Since the issue requiring the double reset seems to be limited to older
platforms, instead of trying to handle the double-reset on MTL and
future platforms it is just easier to turn it off. The default on MTL is
also for GuC to own engine reset, with i915 only covering full-GT reset.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Chris Wilson 
Cc: Andi Shyti 
Cc: Mika Kuoppala 
Cc: Gwan-gyeong Mun 
Cc: John Harrison 
---
  drivers/gpu/drm/i915/gt/intel_reset.c | 35 +++
  1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c 
b/drivers/gpu/drm/i915/gt/intel_reset.c

index 0bb9094fdacd..2c3463f77e5c 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -268,9 +268,27 @@ static int ilk_do_reset(struct intel_gt *gt, 
intel_engine_mask_t engine_mask,
  static int gen6_hw_domain_reset(struct intel_gt *gt, u32 
hw_domain_mask)

  {
  struct intel_uncore *uncore = gt->uncore;
-    int loops = 2;
+    int loops;
  int err;
  +    /*
+ * On some platforms, e.g. Jasperlake, we see that the engine 
register
+ * state is not cleared until shortly after GDRST reports 
completion,
+ * causing a failure as we try to immediately resume while the 
internal

+ * state is still in flux. If we immediately repeat the reset, the
+ * second reset appears to serialise with the first, and since 
it is a
+ * no-op, the registers should retain their reset value. 
However, there
+ * is still a concern that upon leaving the second reset, the 
internal

+ * engine state is still in flux and not ready for resuming.
+ *
+ * Starting on MTL, there are some prep steps that we need to do 
when
+ * resetting some engines that need to be applied every time we 
write to
+ * GEN6_GDRST. As those are time consuming (tens of ms), we 
don't want
+ * to perform that twice, so, since the Jasperlake issue hasn't 
been
+ * observed on MTL, we avoid repeating the reset on newer 
platforms.

+ */
+    loops = GRAPHICS_VER_FULL(gt->i915) < IP_VER(12, 70) ? 2 : 1;
+
  /*
   * GEN6_GDRST is not in the gt power well, no need to check
   * for fifo space for the write or forcewake the chip for
@@ -279,20 +297,7 @@ static int gen6_hw_domain_reset(struct intel_gt 
*gt, u32 hw_domain_mask)

  do {
  intel_uncore_write_fw(uncore, GEN6_GDRST, hw_domain_mask);
  -    /*
- * Wait for the device to ack the reset requests.
- *
- * On some platforms, e.g. Jasperlake, we see that the
- * engine register state is not cleared until shortly after
- * GDRST reports completion, causing a failure as we try
- * to immediately resume while the internal state is still
- * in flux. If we immediately repeat the reset, the second
- * reset appears to serialise with the first, and since
- * it is a no-op, the registers should retain their reset
- * value. However, there is still a concern that upon
- * leaving the second reset, the internal engine state
- * is still in flux and not ready for resuming.
- */
+    /* Wait for the device to ack the reset requests. */
  err = __intel_wait_for_register_fw(uncore, GEN6_GDRST,
 hw_domain_mask, 0,
 2000, 0,






Re: [Intel-gfx] [PATCH 2/2] drm/i915/gsc: implement wa 14015076503

2023-03-22 Thread Ceraolo Spurio, Daniele




On 3/22/2023 12:44 PM, John Harrison wrote:

On 3/20/2023 14:10, Daniele Ceraolo Spurio wrote:

The WA states that we need to alert the GSC FW before doing a GSC engine
reset and then wait for 200ms. The GuC owns engine reset, so on the i915
side we only need to apply this for full GT reset.

Given that we do full GT resets in the resume paths to cleanup the HW
state and that a long wait in those scenarios would not be acceptable,
a faster path has been introduced where, if the GSC is idle, we try 
first
to individually reset the GuC and all engines except the GSC and only 
fall

back to full reset if that fails.
I'm confused. If the code path is a resume then surely all engines are 
idle. But, there is presumably a reason why we do a full GT reset on 
the resume - because the hardware state is not guaranteed to be 
sensible at that point. So how is it safe to skip the GSC reset?


Differently from other engines, the GSCCS only role is to forward the 
commands to the GSC FW, so it doesn't have any HW outside of the CS 
itself and therefore it has no state that we don't explicitly re-init on 
resume or on context switch (LRC or power context). The HW for the GSC 
uC is managed by the GSC FW so we don't need to care about that. I can 
add this to the commit message if it makes things clearer


Daniele





Note: according to the WA specs, if the GSC is idle it should be 
possible

to only wait for the uC wakeup time (~15ms) instead of the whole 200ms.
However, the GSC FW team have mentioned that the wakeup time can change
based on other things going on in the HW and pcode, so a good security
margin would be required. Given that when the GSC is idle we already
skip the wait & reset entirely and that this reduced wait would still
likely be too long to use in resume paths, it's not worth adding support
for this reduced wait.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Matt Roper 
Cc: John Harrison 
Cc: Rodrigo Vivi 
---
  drivers/gpu/drm/i915/gt/intel_reset.c | 77 +--
  drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h |  2 +
  drivers/gpu/drm/i915/i915_reg.h   | 14 -
  3 files changed, 86 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c 
b/drivers/gpu/drm/i915/gt/intel_reset.c

index 2c3463f77e5c..5f75f59122cf 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -14,6 +14,8 @@
    #include "gt/intel_gt_regs.h"
  +#include "gt/uc/intel_gsc_fw.h"
+
  #include "i915_drv.h"
  #include "i915_file_private.h"
  #include "i915_gpu_error.h"
@@ -695,6 +697,67 @@ static reset_func intel_get_gpu_reset(const 
struct intel_gt *gt)

  return NULL;
  }
  +static int __reset_guc(struct intel_gt *gt)
+{
+    u32 guc_domain =
+    GRAPHICS_VER(gt->i915) >= 11 ? GEN11_GRDOM_GUC : 
GEN9_GRDOM_GUC;

+
+    return gen6_hw_domain_reset(gt, guc_domain);
+}
+
+static bool needs_wa_14015076503(struct intel_gt *gt, 
intel_engine_mask_t engine_mask)

+{
+    if (!IS_METEORLAKE(gt->i915) || !HAS_ENGINE(gt, GSC0))
+    return false;
+
+    if (!__HAS_ENGINE(engine_mask, GSC0))
+    return false;
+
+    return intel_gsc_uc_fw_init_done(>uc.gsc);
+}
+
+static intel_engine_mask_t
+wa_14015076503_start(struct intel_gt *gt, intel_engine_mask_t 
engine_mask, bool first)

+{
+    if (!needs_wa_14015076503(gt, engine_mask))
+    return engine_mask;
+
+    /*
+ * wa_14015076503: if the GSC FW is loaded, we need to alert it 
that
+ * we're going to do a GSC engine reset and then wait for 200ms 
for the
+ * FW to get ready for it. However, if this the first 
ALL_ENGINES reset

if this is

John.

+ * attempt and the GSC is not busy, we can try to instead reset 
the GuC

+ * and all the other engines individually to avoid the 200ms wait.
+ */
+    if (engine_mask == ALL_ENGINES && first && 
intel_engine_is_idle(gt->engine[GSC0])) {

+    __reset_guc(gt);
+    engine_mask = gt->info.engine_mask & ~BIT(GSC0);
+    } else {
+    intel_uncore_rmw(gt->uncore,
+ HECI_H_GS1(MTL_GSC_HECI2_BASE),
+ 0, HECI_H_GS1_ER_PREP);
+
+    /* make sure the reset bit is clear when writing the CSR reg */
+    intel_uncore_rmw(gt->uncore,
+ HECI_H_CSR(MTL_GSC_HECI2_BASE),
+ HECI_H_CSR_RST, HECI_H_CSR_IG);
+    msleep(200);
+    }
+
+    return engine_mask;
+}
+
+static void
+wa_14015076503_end(struct intel_gt *gt, intel_engine_mask_t 
engine_mask)

+{
+    if (!needs_wa_14015076503(gt, engine_mask))
+    return;
+
+    intel_uncore_rmw(gt->uncore,
+ HECI_H_GS1(MTL_GSC_HECI2_BASE),
+ HECI_H_GS1_ER_PREP, 0);
+}
+
  int __intel_gt_reset(struct intel_gt *gt, intel_engine_mask_t 
engine_mask)

  {
  const int retries = engine_mask == ALL_ENGINES ? 
RESET_MAX_RETRIES : 1;
@@ -712,10 +775,16 @@ int __intel_gt_reset(struct intel_gt *gt, 
intel_engine_mask_t engine_mask)

   */
  

Re: [Intel-gfx] [PATCH 2/2] drm/i915/guc: Allow for very slow GuC loading

2023-03-15 Thread Ceraolo Spurio, Daniele




On 3/10/2023 5:01 PM, John Harrison wrote:

On 3/3/2023 11:20, Ceraolo Spurio, Daniele wrote:

On 2/17/2023 3:47 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

A failure to load the GuC is occasionally observed where the GuC log
actually showed that the GuC had loaded just fine. The implication
being that the load just took ever so slightly longer than the 200ms
timeout. Given that the actual time should be tens of milliseconds at
the slowest, this should never happen. So far the issue has generally
been caused by a bad IFWI resulting in low frequencies during boot
(depsite the KMD requesting max frequency). However, the issue seems
to happen more often than one would like.

So a) increase the timeout so that the user still gets a working
system even in the case of slow load. And b) report the frequency
during the load to see if that is the case of the slow down.


Some refs would be good here. From a quick search, these seems to match:

https://gitlab.freedesktop.org/drm/intel/-/issues/7931
https://gitlab.freedesktop.org/drm/intel/-/issues/8060
https://gitlab.freedesktop.org/drm/intel/-/issues/8083
https://gitlab.freedesktop.org/drm/intel/-/issues/8136
https://gitlab.freedesktop.org/drm/intel/-/issues/8137
Should these have a prefix tag? If so, what? 'closes' is not entirely 
accurate. This patch is just to help with debug of the underlying 
issue. And if the timeout is reduced then it won't necessarily allow a 
slow system to work. See below.




For bugs we usually use either "References:" or "Closes:". I think the 
former fits more for this case.








Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 37 
+--

  1 file changed, 34 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c

index 2f5942606913d..72e003f50617d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -12,6 +12,7 @@
  #include "gt/intel_gt.h"
  #include "gt/intel_gt_mcr.h"
  #include "gt/intel_gt_regs.h"
+#include "gt/intel_rps.h"
  #include "intel_guc_fw.h"
  #include "intel_guc_print.h"
  #include "i915_drv.h"
@@ -139,9 +140,12 @@ static int guc_wait_ucode(struct intel_guc *guc)
  {
  struct intel_gt *gt = guc_to_gt(guc);
  struct intel_uncore *uncore = gt->uncore;
+    ktime_t before, after, delta;
  bool success;
  u32 status;
-    int ret;
+    int ret, count;
+    u64 delta_ms;
+    u32 before_freq;
    /*
   * Wait for the GuC to start up.
@@ -159,13 +163,32 @@ static int guc_wait_ucode(struct intel_guc *guc)
   * issues to be resolved. In the meantime bump the timeout to
   * 200ms. Even at slowest clock, this should be sufficient. And
   * in the working case, a larger timeout makes no difference.
+ *
+ * IFWI updates have also been seen to cause sporadic failures 
due to

+ * the requested frequency not being granted and thus the firmware
+ * load is attempted at minimum frequency. That can lead to 
load times

+ * in the seconds range. However, there is a limit on how long an
+ * individual wait_for() can wait. So wrap it in a loop.
   */
-    ret = wait_for(guc_load_done(uncore, , ), 200);
+    before_freq = intel_rps_read_actual_frequency(>gt->rps);
+    before = ktime_get();
+    for (count = 0; count < 20; count++) {
+    ret = wait_for(guc_load_done(uncore, , ), 
1000);


Isn't 20 secs a bit too long for an in-place wait? I get that if the 
GuC doesn't load (or fail to) within a few secs the HW is likely 
toast, but still that seems a bit too long to me. What's the worst 
case load time ever observed? I suggest reducing the wait to 3 secs 
as a compromise, if that's bigger than the worst case.
I can drop it to 3 for normal builds and keep 20 for 
CONFIG_DRM_I915_DEBUG_GEM builds. However, that won't actually be long 
enough for all slow situations. We have seen times of at least 11s 
when the GPU is running at minimum frequency. So, for CI runs we 
definitely want to keep the 20s limit. For end users? Is it better to 
wait for up to 20s or to boot in display only fallback mode? And note 
that this is a timeout only. A functional system will still complete 
in tens of milliseconds.


I'd argue that the only way for us to go to multiple seconds is if the 
frequency goes below the efficient levels, which normally should only 
happen if the card cooling fails and the temperature goes out of 
control, in which case there are more pressing issues than a GuC load 
failure. I agree that having 3 secs normal and 20 for CI is a good 
compromise and if we ever see a very long timeout in CI we can 
investigate more.


Daniele



John.



The patch LGTM apart from this point.

Daniele


+    if (!ret || !success)
+    break;
+
+    guc_dbg(guc, "

Re: [Intel-gfx] ✗ Fi.CI.IGT: failure for Fix a couple of issues with the GSC worker timing (rev2)

2023-03-09 Thread Ceraolo Spurio, Daniele



On 3/9/2023 9:32 AM, Patchwork wrote:

Project List - Patchwork *Patch Details*
*Series:*   Fix a couple of issues with the GSC worker timing (rev2)
*URL:*  https://patchwork.freedesktop.org/series/114306/
*State:*failure
*Details:* 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_114306v2/index.html



  CI Bug Log - changes from CI_DRM_12827_full -> Patchwork_114306v2_full


Summary

*FAILURE*

Serious unknown changes coming with Patchwork_114306v2_full absolutely 
need to be

verified manually.

If you think the reported changes have nothing to do with the changes
introduced in Patchwork_114306v2_full, please notify your bug team to 
allow them
to document this new failure mode, which will reduce false positives 
in CI.



Participating hosts (8 -> 9)

Additional (1): shard-tglu-9


Possible new issues

Here are the unknown changes that may have been introduced in 
Patchwork_114306v2_full:



  IGT changes


Possible regressions

  * igt@kms_cursor_legacy@cursor-vs-flip-varying-size:
  o shard-glk: PASS


-> FAIL




Suppressed

The following results come from untrusted machines, tests, or statuses.
They do not affect the overall result.

  * igt@i915_suspend@basic-s3-without-i915:
  o {shard-dg1}: NOTRUN -> DMESG-WARN





Both failures are unrelated, as they're both display related and on 
machine where the modified code wouldn't run.

Patches pushed.

Daniele


 *


Known issues

Here are the changes found in Patchwork_114306v2_full that come from 
known issues:



  IGT changes


Issues hit

 *

igt@debugfs_test@basic-hwmon:

  o shard-tglu-9: NOTRUN -> SKIP


(i915#7456 )
 *

igt@drm_buddy@all-tests:

  o shard-tglu-9: NOTRUN -> SKIP


(i915#6433 )
 *

igt@feature_discovery@display-3x:

  o shard-tglu-9: NOTRUN -> SKIP


(i915#1839 )
 *

igt@feature_discovery@psr1:

  o shard-tglu-9: NOTRUN -> SKIP


(i915#658
) +2
similar issues
 *

igt@feature_discovery@psr2:

  o shard-tglu-10: NOTRUN -> SKIP


(i915#658 )
 *

igt@gem_ccs@block-multicopy-compressed:

  o shard-tglu-10: NOTRUN -> SKIP


(i915#5325 )
 *

igt@gem_ccs@suspend-resume:

  o shard-tglu-9: NOTRUN -> SKIP


(i915#5325 )
 *

igt@gem_create@create-ext-cpu-access-big:

  o shard-tglu-9: NOTRUN -> SKIP


(i915#6335 )
 *

igt@gem_exec_fair@basic-none-solo@rcs0:

  o shard-tglu-10: NOTRUN -> FAIL


(i915#2842 )
 *

igt@gem_exec_fair@basic-none@bcs0:

  o shard-tglu-9: NOTRUN -> FAIL


(i915#2842
) +4
similar issues
 *

igt@gem_exec_fair@basic-pace@rcs0:

  o shard-glk: PASS



Re: [Intel-gfx] [PATCH v3 3/5] drm/i915/mtl: make IRQ reset and postinstall multi-gt aware

2023-03-06 Thread Ceraolo Spurio, Daniele




On 3/6/2023 4:24 PM, Matt Roper wrote:

On Mon, Mar 06, 2023 at 04:14:49PM -0800, Sripada, Radhakrishna wrote:

+Daniele,

Hi Matt,


-Original Message-
From: Roper, Matthew D 
Sent: Monday, March 6, 2023 2:55 PM
To: Sripada, Radhakrishna 
Cc: intel-gfx@lists.freedesktop.org; De Marchi, Lucas
; Zanoni, Paulo R 
Subject: Re: [Intel-gfx] [PATCH v3 3/5] drm/i915/mtl: make IRQ reset and
postinstall multi-gt aware

On Wed, Mar 01, 2023 at 12:10:51PM -0800, Radhakrishna Sripada wrote:

Irq reset and post install are to be made multi-gt aware for the
interrupts to work for the media tile on Meteorlake. Iterate through
all the gts to process irq reset for each gt.

I think I mentioned on the previous version, but this isn't right.  MTL
does not have separate interrupt registers for each GT the way
multi-tile platforms like PVC do.  The GT interrupt registers you're
handling here are in the sgunit so there's only a single copy of them;
iterating over them multiple times in a row doesn't accomplish anything.

The media engine bits are still on the same registers as the primary GT
and the GSC and media GuC are new additional bits that need to be
handled.  The necessary handling for the GSC and media GuC should have
already landed in a187f13d51fa ("drm/i915/guc: handle interrupts from
media GuC") and c07ee636901d ("drm/i915/mtl: add GSC CS interrupt
support"), but if there's another bit that was missed somewhere (or if
we were doing something like looking at the wrong intel_gt's engine mask
somewhere), that would need to be addressed directly rather than just
looping over the same IRQ registers multiple times.

This patch is needed to handle media interrupts. Without this patch we observed
GuC not loading/communication errors on media gt.

My understanding is that Sgunit is embedded into the SAMedia block and hence 
need
To be iterated over separately.

No, the sgunit is not replicated.  You can confirm by just going to the
various IRQ register pages in the bspec...there's only a single register
offset rather than (offset) and (offset+0x38) like there are for GT
GSI registers.  The i915 code also only adds the GSI offset to register
operations in the 0x0 - 0x4 range.


I agree with Matt that this is how the HW works. The issue here is that 
the gen11_gt_irq_* functions only program the interrupts for GuC and 
engines on the given GT, so when calling them for the root GT they will 
only program the interrupts for RCS, BCS, CCS and the root GuC. We could 
modify the functions to program all registers from the root GT, but IMO 
that doesn't work very well with how other parts of the driver implement 
the MTL multi-gt flow.


Daniele




Matt


Daniele,
Can you confirm if that is accurate.

Thanks,
RK


Matt


Based on original version by Paulo and Tvrtko

Cc: Paulo Zanoni 
Cc: Tvrtko Ursulin 
Reviewed-by: Lucas De Marchi 
Signed-off-by: Radhakrishna Sripada 
---
  drivers/gpu/drm/i915/i915_irq.c | 30 ++
  1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 417c981e4968..9377f59c1ac2 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2759,16 +2759,19 @@ static void gen11_irq_reset(struct

drm_i915_private *dev_priv)

  static void dg1_irq_reset(struct drm_i915_private *dev_priv)
  {
-   struct intel_gt *gt = to_gt(dev_priv);
-   struct intel_uncore *uncore = gt->uncore;
+   struct intel_gt *gt;
+   unsigned int i;

dg1_master_intr_disable(dev_priv->uncore.regs);

-   gen11_gt_irq_reset(gt);
-   gen11_display_irq_reset(dev_priv);
+   for_each_gt(gt, dev_priv, i) {
+   gen11_gt_irq_reset(gt);

-   GEN3_IRQ_RESET(uncore, GEN11_GU_MISC_);
-   GEN3_IRQ_RESET(uncore, GEN8_PCU_);
+   GEN3_IRQ_RESET(gt->uncore, GEN11_GU_MISC_);
+   GEN3_IRQ_RESET(gt->uncore, GEN8_PCU_);
+   }
+
+   gen11_display_irq_reset(dev_priv);
  }

  void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
@@ -3422,13 +3425,16 @@ static void gen11_irq_postinstall(struct

drm_i915_private *dev_priv)

  static void dg1_irq_postinstall(struct drm_i915_private *dev_priv)
  {
-   struct intel_gt *gt = to_gt(dev_priv);
-   struct intel_uncore *uncore = gt->uncore;
u32 gu_misc_masked = GEN11_GU_MISC_GSE;
+   struct intel_gt *gt;
+   unsigned int i;

-   gen11_gt_irq_postinstall(gt);
+   for_each_gt(gt, dev_priv, i) {
+   gen11_gt_irq_postinstall(gt);

-   GEN3_IRQ_INIT(uncore, GEN11_GU_MISC_, ~gu_misc_masked,

gu_misc_masked);

+   GEN3_IRQ_INIT(gt->uncore, GEN11_GU_MISC_,

~gu_misc_masked,

+ gu_misc_masked);
+   }

if (HAS_DISPLAY(dev_priv)) {
icp_irq_postinstall(dev_priv);
@@ -3437,8 +3443,8 @@ static void dg1_irq_postinstall(struct

drm_i915_private *dev_priv)

   

Re: [Intel-gfx] [PATCH v2 2/2] drm/i915/guc: Fix missing return code checks in submission init

2023-03-06 Thread Ceraolo Spurio, Daniele




On 2/17/2023 2:33 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

The CI results for the 'fast request' patch set (enables error return
codes for fire-and-forget H2G messages) hit an issue with the KMD
sending context submission requests on an invalid context. That was
caused by a fault injection probe failing the context creation of a
kernel context. However, there was no return code checking on any of
the kernel context registration paths. So the driver kept going and
tried to use the kernel context for the record defaults process.

This would not cause any actual problems. The invalid requests would
be rejected by GuC and ultimately the start up sequence would
correctly wedge due to the context creation failure. But fixing the
issue correctly rather ignoring it means we won't get CI complaining
when the fast request patch lands and enables the extra error checking.

So fix it by checking for errors and aborting as appropriate when
creating kernel contexts. While at it, clean up some other submission
init related failure cleanup paths. Also, rename guc_init_lrc_mapping
to guc_init_submission as the former name hasn't been valid in a long
time.

v2: Add another wrapper to keep the flow balanced (Daniele)

Signed-off-by: John Harrison 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 97 ++-
  .../gpu/drm/i915/gt/uc/intel_guc_submission.h |  2 +-
  drivers/gpu/drm/i915/gt/uc/intel_uc.c |  7 +-
  3 files changed, 80 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index a04d7049a2c2f..88e881b100cf0 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1441,7 +1441,7 @@ static int guc_action_enable_usage_stats(struct intel_guc 
*guc)
return intel_guc_send(guc, action, ARRAY_SIZE(action));
  }
  
-static void guc_init_engine_stats(struct intel_guc *guc)

+static int guc_init_engine_stats(struct intel_guc *guc)
  {
struct intel_gt *gt = guc_to_gt(guc);
intel_wakeref_t wakeref;
@@ -1454,6 +1454,13 @@ static void guc_init_engine_stats(struct intel_guc *guc)
guc_err(guc, "Failed to enable usage stats: %pe\n", 
ERR_PTR(ret));
else
guc_enable_busyness_worker(guc);
+
+   return ret;
+}
+
+static void guc_fini_engine_stats(struct intel_guc *guc)
+{
+   guc_cancel_busyness_worker(guc);
  }
  
  void intel_guc_busyness_park(struct intel_gt *gt)

@@ -4109,9 +4116,11 @@ static void guc_set_default_submission(struct 
intel_engine_cs *engine)
engine->submit_request = guc_submit_request;
  }
  
-static inline void guc_kernel_context_pin(struct intel_guc *guc,

- struct intel_context *ce)
+static inline int guc_kernel_context_pin(struct intel_guc *guc,
+struct intel_context *ce)
  {
+   int ret;
+
/*
 * Note: we purposefully do not check the returns below because
 * the registration can only fail if a reset is just starting.
@@ -4119,16 +4128,24 @@ static inline void guc_kernel_context_pin(struct 
intel_guc *guc,
 * isn't happening and even it did this code would be run again.
 */
  
-	if (context_guc_id_invalid(ce))

-   pin_guc_id(guc, ce);
+   if (context_guc_id_invalid(ce)) {
+   ret = pin_guc_id(guc, ce);
+
+   if (ret < 0)
+   return ret;
+   }
  
  	if (!test_bit(CONTEXT_GUC_INIT, >flags))

guc_context_init(ce);
  
-	try_context_registration(ce, true);

+   ret = try_context_registration(ce, true);
+   if (ret)
+   unpin_guc_id(guc, ce);
+
+   return ret;
  }
  
-static inline void guc_init_lrc_mapping(struct intel_guc *guc)

+static inline int guc_init_submission(struct intel_guc *guc)
  {
struct intel_gt *gt = guc_to_gt(guc);
struct intel_engine_cs *engine;
@@ -4155,9 +4172,17 @@ static inline void guc_init_lrc_mapping(struct intel_guc 
*guc)
struct intel_context *ce;
  
  		list_for_each_entry(ce, >pinned_contexts_list,

-   pinned_contexts_link)
-   guc_kernel_context_pin(guc, ce);
+   pinned_contexts_link) {
+   int ret = guc_kernel_context_pin(guc, ce);
+
+   if (ret) {
+   /* No point in trying to clean up as i915 will 
wedge on failure */
+   return ret;
+   }
+   }
}
+
+   return 0;
  }
  
  static void guc_release(struct intel_engine_cs *engine)

@@ -4400,31 +4425,57 @@ static int guc_init_global_schedule_policy(struct 
intel_guc *guc)
return ret;
  }
  
-void intel

Re: [Intel-gfx] [PATCH v2 1/2] drm/i915/guc: Improve clean up of busyness stats worker

2023-03-06 Thread Ceraolo Spurio, Daniele




On 2/17/2023 2:33 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

The stats worker thread management was mis-matched between
enable/disable call sites. Fix those up. Also, abstract the
cancel/enable code into a helper function rather than replicating in
multiple places.

v2: Rename the helpers and wrap the enable as well as the cancel
(review feedback from Daniele).

Signed-off-by: John Harrison 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 38 +++
  1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index be495e657d66b..a04d7049a2c2f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1352,6 +1352,16 @@ static ktime_t guc_engine_busyness(struct 
intel_engine_cs *engine, ktime_t *now)
return ns_to_ktime(total);
  }
  
+static void guc_enable_busyness_worker(struct intel_guc *guc)

+{
+   mod_delayed_work(system_highpri_wq, >timestamp.work, 
guc->timestamp.ping_delay);
+}
+
+static void guc_cancel_busyness_worker(struct intel_guc *guc)
+{
+   cancel_delayed_work_sync(>timestamp.work);
+}
+
  static void __reset_guc_busyness_stats(struct intel_guc *guc)
  {
struct intel_gt *gt = guc_to_gt(guc);
@@ -1360,7 +1370,7 @@ static void __reset_guc_busyness_stats(struct intel_guc 
*guc)
unsigned long flags;
ktime_t unused;
  
-	cancel_delayed_work_sync(>timestamp.work);

+   guc_cancel_busyness_worker(guc);
  
  	spin_lock_irqsave(>timestamp.lock, flags);
  
@@ -1416,8 +1426,7 @@ static void guc_timestamp_ping(struct work_struct *wrk)
  
  	intel_gt_reset_unlock(gt, srcu);
  
-	mod_delayed_work(system_highpri_wq, >timestamp.work,

-guc->timestamp.ping_delay);
+   guc_enable_busyness_worker(guc);
  }
  
  static int guc_action_enable_usage_stats(struct intel_guc *guc)

@@ -1436,16 +1445,15 @@ static void guc_init_engine_stats(struct intel_guc *guc)
  {
struct intel_gt *gt = guc_to_gt(guc);
intel_wakeref_t wakeref;
+   int ret;
  
-	mod_delayed_work(system_highpri_wq, >timestamp.work,

-guc->timestamp.ping_delay);
-
-   with_intel_runtime_pm(>i915->runtime_pm, wakeref) {
-   int ret = guc_action_enable_usage_stats(guc);
+   with_intel_runtime_pm(>i915->runtime_pm, wakeref)
+   ret = guc_action_enable_usage_stats(guc);
  
-		if (ret)

-   guc_err(guc, "Failed to enable usage stats: %pe\n", 
ERR_PTR(ret));
-   }
+   if (ret)
+   guc_err(guc, "Failed to enable usage stats: %pe\n", 
ERR_PTR(ret));
+   else
+   guc_enable_busyness_worker(guc);
  }
  
  void intel_guc_busyness_park(struct intel_gt *gt)

@@ -1460,7 +1468,7 @@ void intel_guc_busyness_park(struct intel_gt *gt)
 * and causes an unclaimed register access warning. Cancel the worker
 * synchronously here.
 */
-   cancel_delayed_work_sync(>timestamp.work);
+   guc_cancel_busyness_worker(guc);
  
  	/*

 * Before parking, we should sample engine busyness stats if we need to.
@@ -1487,8 +1495,7 @@ void intel_guc_busyness_unpark(struct intel_gt *gt)
spin_lock_irqsave(>timestamp.lock, flags);
guc_update_pm_timestamp(guc, );
spin_unlock_irqrestore(>timestamp.lock, flags);
-   mod_delayed_work(system_highpri_wq, >timestamp.work,
-guc->timestamp.ping_delay);
+   guc_enable_busyness_worker(guc);
  }
  
  static inline bool

@@ -4408,11 +4415,12 @@ void intel_guc_submission_enable(struct intel_guc *guc)
guc_init_global_schedule_policy(guc);
  }
  
+/* Note: By the time we're here, GuC may have already been reset */

  void intel_guc_submission_disable(struct intel_guc *guc)
  {
struct intel_gt *gt = guc_to_gt(guc);
  
-	/* Note: By the time we're here, GuC may have already been reset */

+   guc_cancel_busyness_worker(guc);
  
  	/* Disable and route to host */

if (GRAPHICS_VER(gt->i915) >= 12)




Re: [Intel-gfx] [PATCH v6 8/8] drm/i915/pxp: Enable PXP with MTL-GSC-CS

2023-03-03 Thread Ceraolo Spurio, Daniele




On 2/27/2023 6:21 PM, Alan Previn wrote:

Enable PXP with MTL-GSC-CS: add the has_pxp into device info
and increase the debugfs teardown timeouts to align with
new GSC-CS + firmware specs.

Signed-off-by: Alan Previn 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/i915_pci.c  | 1 +
  drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c | 9 -
  drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 2 +-
  3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index a8d942b16223..4ecf0f2ab6ec 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -1150,6 +1150,7 @@ static const struct intel_device_info mtl_info = {
.has_guc_deprivilege = 1,
.has_mslice_steering = 0,
.has_snoop = 1,
+   .has_pxp = 1,
.__runtime.memory_regions = REGION_SMEM | REGION_STOLEN_LMEM,
.__runtime.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(CCS0),
.require_force_probe = 1,
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
index 9f6e300486b4..ddf9f8bb7791 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
@@ -14,6 +14,7 @@
  
  #include "intel_pxp.h"

  #include "intel_pxp_debugfs.h"
+#include "intel_pxp_gsccs.h"
  #include "intel_pxp_irq.h"
  #include "intel_pxp_types.h"
  
@@ -45,6 +46,7 @@ static int pxp_terminate_set(void *data, u64 val)

  {
struct intel_pxp *pxp = data;
struct intel_gt *gt = intel_pxp_get_irq_gt(pxp);
+   int timeout_ms;
  
  	if (!intel_pxp_is_active(pxp))

return -ENODEV;
@@ -54,8 +56,13 @@ static int pxp_terminate_set(void *data, u64 val)
intel_pxp_irq_handler(pxp, 
GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT);
spin_unlock_irq(gt->irq_lock);
  
+	if (HAS_ENGINE(pxp->ctrl_gt, GSC0))

+   timeout_ms = GSC_PENDING_RETRY_LATENCY_MS;
+   else
+   timeout_ms = 250;
+
if (!wait_for_completion_timeout(>termination,
-msecs_to_jiffies(100)))
+msecs_to_jiffies(timeout_ms)))
return -ETIMEDOUT;
  
  	return 0;

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
index 4ddf2ee60222..03f006f9dc2e 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -44,7 +44,7 @@ static int pxp_wait_for_session_state(struct intel_pxp *pxp, 
u32 id, bool in_pla
  KCR_SIP(pxp->kcr_base),
  mask,
  in_play ? mask : 0,
- 100);
+ 250);
  
  	intel_runtime_pm_put(uncore->rpm, wakeref);
  




Re: [Intel-gfx] [PATCH v6 7/8] drm/i915/pxp: On MTL, KCR enabling doesn't wait on tee component

2023-03-03 Thread Ceraolo Spurio, Daniele




On 2/27/2023 6:21 PM, Alan Previn wrote:

On legacy platforms, KCR HW enabling is done at the time the mei
component interface is bound. It's also disabled during unbind.
However, for MTL onwards, we don't depend on a tee component
to start sending GSC-CS firmware messages.

Thus, immediately enable (or disable) KCR HW on PXP's init,
fini and resume.

Signed-off-by: Alan Previn 
---
  drivers/gpu/drm/i915/pxp/intel_pxp.c| 19 +++
  drivers/gpu/drm/i915/pxp/intel_pxp_pm.c |  3 ++-
  2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 61041277be24..e2f2cc5f6a6e 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -119,6 +119,7 @@ static void destroy_vcs_context(struct intel_pxp *pxp)
  static void pxp_init_full(struct intel_pxp *pxp)
  {
struct intel_gt *gt = pxp->ctrl_gt;
+   intel_wakeref_t wakeref;
int ret;
  
  	/*

@@ -140,10 +141,15 @@ static void pxp_init_full(struct intel_pxp *pxp)
if (ret)
return;
  
-	if (HAS_ENGINE(pxp->ctrl_gt, GSC0))

+   if (HAS_ENGINE(pxp->ctrl_gt, GSC0)) {
ret = intel_pxp_gsccs_init(pxp);
-   else
+   if (!ret) {
+   with_intel_runtime_pm(>ctrl_gt->i915->runtime_pm, 
wakeref)
+   intel_pxp_init_hw(pxp);


personal preference: I'd move this (and the matching call in fini) 
inside intel_pxp_gsccs_init/fini. That way we can see this as more 
back-end specific: the gsccs initialize everything immediately, while 
the tee back-end follows a 2-step approach with the component.
Not a blocker since it is a personal preference, so with or without the 
change:


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


+   }
+   } else {
ret = intel_pxp_tee_component_init(pxp);
+   }
if (ret)
goto out_context;
  
@@ -239,15 +245,20 @@ int intel_pxp_init(struct drm_i915_private *i915)
  
  void intel_pxp_fini(struct drm_i915_private *i915)

  {
+   intel_wakeref_t wakeref;
+
if (!i915->pxp)
return;
  
  	i915->pxp->arb_is_valid = false;
  
-	if (HAS_ENGINE(i915->pxp->ctrl_gt, GSC0))

+   if (HAS_ENGINE(i915->pxp->ctrl_gt, GSC0)) {
+   with_intel_runtime_pm(>pxp->ctrl_gt->i915->runtime_pm, 
wakeref)
+   intel_pxp_fini_hw(i915->pxp);
intel_pxp_gsccs_fini(i915->pxp);
-   else
+   } else {
intel_pxp_tee_component_fini(i915->pxp);
+   }
  
  	destroy_vcs_context(i915->pxp);
  
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c

index 4f836b317424..1a04067f61fc 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
@@ -43,8 +43,9 @@ void intel_pxp_resume_complete(struct intel_pxp *pxp)
 * The PXP component gets automatically unbound when we go into S3 and
 * re-bound after we come out, so in that scenario we can defer the
 * hw init to the bind call.
+* NOTE: GSC-CS backend doesn't rely on components.
 */
-   if (!pxp->pxp_component)
+   if (!HAS_ENGINE(pxp->ctrl_gt, GSC0) && !pxp->pxp_component)
return;
  
  	intel_pxp_init_hw(pxp);




Re: [Intel-gfx] [PATCH v6 6/8] drm/i915/pxp: MTL-KCR interrupt ctrl's are in GT-0

2023-03-03 Thread Ceraolo Spurio, Daniele




On 2/27/2023 6:21 PM, Alan Previn wrote:

Despite KCR subsystem being in the media-tile (close to the
GSC-CS), the IRQ controls for it are on GT-0 with other global
IRQ controls. Thus, add a helper for KCR hw interrupt
enable/disable functions to get the correct gt structure (for
uncore) for MTL.


This is not correct. On MTL, the interrupts logic isn't on any 
particular GT, it is in a shared area. The fact that we handle all 
interrupts as if they were triggered on the root GT is an i915 
implementation decision. Both uncores have access to the irq regs and 
the 2 GTs share the irq lock. A comparable example is the media GuC, 
where the interrupts enable/disable functions are called with the media 
GT structure.



In the helper, we get GT-0's handle for uncore when touching
IRQ registers despite the pxp->ctrl_gt being the media-tile.
No difference for legacy of course.

Signed-off-by: Alan Previn 
---
  drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c |  2 +-
  drivers/gpu/drm/i915/pxp/intel_pxp_irq.c | 24 +---
  drivers/gpu/drm/i915/pxp/intel_pxp_irq.h |  8 +++
  3 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
index 4b8e70caa3ad..9f6e300486b4 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
@@ -44,7 +44,7 @@ static int pxp_terminate_get(void *data, u64 *val)
  static int pxp_terminate_set(void *data, u64 val)
  {
struct intel_pxp *pxp = data;
-   struct intel_gt *gt = pxp->ctrl_gt;
+   struct intel_gt *gt = intel_pxp_get_irq_gt(pxp);


In this function the only use you have of the GT is to take 
gt->irq_lock, but that's shared between the GTs so it is ok to use the 
media GT for it.


  
  	if (!intel_pxp_is_active(pxp))

return -ENODEV;
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
index 91e9622c07d0..3a725397349f 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
@@ -4,10 +4,12 @@
   */
  #include 
  
+#include "gt/intel_gt.h"

  #include "gt/intel_gt_irq.h"
  #include "gt/intel_gt_regs.h"
  #include "gt/intel_gt_types.h"
  
+#include "i915_drv.h"

  #include "i915_irq.h"
  #include "i915_reg.h"
  
@@ -17,6 +19,22 @@

  #include "intel_pxp_types.h"
  #include "intel_runtime_pm.h"
  
+/**

+ * intel_pxp_get_irq_gt - Find the correct GT that owns KCR interrupts
+ * @pxp: pointer to pxp struct
+ *
+ * For platforms with a single GT, we return the pxp->ctrl_gt (as expected)
+ * but for MTL+ that has a media-tile, although the KCR engine is in the
+ * media-tile (i.e. pxp->ctrl_gt), the IRQ controls are on the root tile.
+ * In the end, we don't use pxp->ctrl_gt for IRQ, we always return root gt.
+ */
+struct intel_gt *intel_pxp_get_irq_gt(struct intel_pxp *pxp)
+{
+   WARN_ON_ONCE(!pxp->ctrl_gt->i915->media_gt && 
!gt_is_root(pxp->ctrl_gt));
+
+   return to_gt(pxp->ctrl_gt->i915);
+}
+
  /**
   * intel_pxp_irq_handler - Handles PXP interrupts.
   * @pxp: pointer to pxp struct
@@ -29,7 +47,7 @@ void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir)
if (GEM_WARN_ON(!intel_pxp_is_enabled(pxp)))
return;
  
-	gt = pxp->ctrl_gt;

+   gt = intel_pxp_get_irq_gt(pxp);


same as above, only use here is the lock.

  
  	lockdep_assert_held(gt->irq_lock);
  
@@ -68,7 +86,7 @@ static inline void pxp_irq_reset(struct intel_gt *gt)
  
  void intel_pxp_irq_enable(struct intel_pxp *pxp)

  {
-   struct intel_gt *gt = pxp->ctrl_gt;
+   struct intel_gt *gt = intel_pxp_get_irq_gt(pxp);


in this function we use the gt for:

1 - the lock: see above about this

2 - gen11_gt_reset_one_iir(): this should work with the media GT (we use 
it for media GuC)


3 - writes to the GEN11_CRYPTO_* regs: those should also work with the 
media GT uncore as these regs are in the same range as the GuC scratch 
regs and we use the media uncore for those accesses.


  
  	spin_lock_irq(gt->irq_lock);
  
@@ -83,7 +101,7 @@ void intel_pxp_irq_enable(struct intel_pxp *pxp)
  
  void intel_pxp_irq_disable(struct intel_pxp *pxp)

  {
-   struct intel_gt *gt = pxp->ctrl_gt;
+   struct intel_gt *gt = intel_pxp_get_irq_gt(pxp);
  


AFAICS this functions uses the same 3 cases as above.

Overall, I am not sure this patch is required. Am I missing something?

Daniele


/*
 * We always need to submit a global termination when we re-enable the
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
index 8c292dc86f68..eea87c9eb62b 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
@@ -9,6 +9,7 @@
  #include 
  
  struct intel_pxp;

+struct intel_gt;
  
  #define GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT BIT(1)

  #define 

Re: [Intel-gfx] [PATCH v6 5/8] drm/i915/pxp: Add ARB session creation and cleanup

2023-03-03 Thread Ceraolo Spurio, Daniele




On 2/27/2023 6:21 PM, Alan Previn wrote:

Add MTL's function for ARB session creation using PXP firmware
version 4.3 ABI structure format.

Also add MTL's function for ARB session invalidation but this
reuses PXP firmware version 4.2 ABI structure format.

Before checking the return status, look at the GSC-CS-Mem-Header's
pending-bit which means the GSC firmware is busy and we should
resubmit.

Signed-off-by: Alan Previn 
---
  drivers/gpu/drm/i915/pxp/intel_pxp.c  | 34 --
  .../drm/i915/pxp/intel_pxp_cmd_interface_43.h | 21 +++
  drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c| 62 +++
  drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h|  4 ++
  drivers/gpu/drm/i915/pxp/intel_pxp_session.c  | 11 +++-
  5 files changed, 126 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index aecc65b5da70..61041277be24 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -290,6 +290,8 @@ static bool pxp_component_bound(struct intel_pxp *pxp)
  
  static int __pxp_global_teardown_final(struct intel_pxp *pxp)

  {
+   int timeout;
+
if (!pxp->arb_is_valid)
return 0;
/*
@@ -299,7 +301,12 @@ static int __pxp_global_teardown_final(struct intel_pxp 
*pxp)
intel_pxp_mark_termination_in_progress(pxp);
intel_pxp_terminate(pxp, false);
  
-	if (!wait_for_completion_timeout(>termination, msecs_to_jiffies(250)))

+   if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
+   timeout = GSC_PENDING_RETRY_LATENCY_MS;
+   else
+   timeout = 250;
+
+   if (!wait_for_completion_timeout(>termination, 
msecs_to_jiffies(timeout)))
return -ETIMEDOUT;
  
  	return 0;

@@ -307,6 +314,8 @@ static int __pxp_global_teardown_final(struct intel_pxp 
*pxp)
  
  static int __pxp_global_teardown_restart(struct intel_pxp *pxp)

  {
+   int timeout;
+
if (pxp->arb_is_valid)
return 0;
/*
@@ -315,7 +324,12 @@ static int __pxp_global_teardown_restart(struct intel_pxp 
*pxp)
 */
pxp_queue_termination(pxp);
  
-	if (!wait_for_completion_timeout(>termination, msecs_to_jiffies(250)))

+   if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
+   timeout = GSC_PENDING_RETRY_LATENCY_MS;
+   else
+   timeout = 250;
+
+   if (!wait_for_completion_timeout(>termination, 
msecs_to_jiffies(timeout)))
return -ETIMEDOUT;
  
  	return 0;

@@ -353,8 +367,20 @@ int intel_pxp_start(struct intel_pxp *pxp)
if (!intel_pxp_is_enabled(pxp))
return -ENODEV;
  
-	if (wait_for(pxp_component_bound(pxp), 250))

-   return -ENXIO;
+   if (HAS_ENGINE(pxp->ctrl_gt, GSC0)) {
+   /*
+* GSC-fw loading, GSC-proxy init (requiring an mei component 
driver) and
+* HuC-fw loading must all occur first before we start 
requesting for PXP
+* sessions. Checking HuC authentication (the last dependency)  
will suffice.
+* Let's use a much larger 8 second timeout considering all the 
types of
+* dependencies prior to that.
+*/
+   if (wait_for(intel_huc_is_authenticated(>ctrl_gt->uc.huc), 
8000))


This big timeout needs an ack from userspace drivers, as intel_pxp_start 
is called during context creation and the current way to query if the 
feature is supported is to create a protected context. Unfortunately, we 
do need to wait to confirm that PXP is available (although in most cases 
it shouldn't take even close to 8 secs), because until everything is 
setup we're not sure if things will work as expected. I see 2 potential 
mitigations in case the timeout doesn't work as-is:


1) we return -EAGAIN (or another dedicated error code) to userspace if 
the prerequisite steps aren't done yet. This would indicate that the 
feature is there, but that we haven't completed the setup yet. The 
caller can then decide if they want to retry immediately or later. Pro: 
more flexibility for userspace; Cons: new interface return code.


2) we add a getparam to say if PXP is supported in HW and the support is 
compiled in i915. Userspace can query this as a way to check the feature 
support and only create the context if they actually need it for PXP 
operations. Pro: simpler kernel implementation; Cons: new getparam, plus 
even if the getparam returns true the pxp_start could later fail, so 
userspace needs to handle that case.



+   return -ENXIO;
+   } else {
+   if (wait_for(pxp_component_bound(pxp), 250))
+   return -ENXIO;
+   }
  
  	mutex_lock(>arb_mutex);
  
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 b2523d6918c7..9089e02a8c2d 100644
--- 

Re: [Intel-gfx] [PATCH v6 4/8] drm/i915/pxp: Add GSC-CS backend to send GSC fw messages

2023-03-03 Thread Ceraolo Spurio, Daniele




On 2/27/2023 6:21 PM, Alan Previn wrote:

Add GSC engine based method for sending PXP firmware packets
to the GSC firmware for MTL (and future) products.

Use the newly added helpers to populate the GSC-CS memory
header and send the message packet to the FW by dispatching
the GSC_HECI_CMD_PKT instruction on the GSC engine.

We use non-priveleged batches for submission to GSC engine
which require two buffers for the request:
  - a buffer for the HECI packet that contains PXP FW commands
  - a batch-buffer that contains the engine instruction for
sending the HECI packet to the GSC firmware.

Thus, add the allocation and freeing of these buffers in gsccs
init and fini.

The GSC-fw may reply to commands with a SUCCESS but with an
additional pending-bit set in the reply packet. This bit
means the GSC-FW is currently busy and the caller needs to
try again with the gsc_message_handle the fw gave. The
GSC-fw requires a non-zero host_session_handle provided
by the caller to enable gsc_message_handle tracking.

Thus, allocate the host_session_handle at init and destroy it
at fini (the latter requiring an FYI to the gsc-firmware).
Also ensure the send-message function allows replay of the
gsc_message_handle.

Signed-off-by: Alan Previn 
---
  .../drm/i915/pxp/intel_pxp_cmd_interface_43.h |   4 +
  drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c| 239 +-
  drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h|   4 +
  drivers/gpu/drm/i915/pxp/intel_pxp_types.h|   6 +
  4 files changed, 251 insertions(+), 2 deletions(-)

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..b2523d6918c7 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
@@ -12,6 +12,10 @@
  /* PXP-Cmd-Op definitions */
  #define PXP43_CMDID_START_HUC_AUTH 0x003A
  
+/* PXP-Packet sizes for MTL's GSCCS-HECI instruction */

+#define PXP43_MAX_HECI_IN_SIZE (SZ_32K)
+#define PXP43_MAX_HECI_OUT_SIZE (SZ_32K)
+
  /* PXP-Input-Packet: HUC-Authentication */
  struct pxp43_start_huc_auth_in {
struct pxp_cmd_header header;
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c
index 13693e78b57e..30aa660a975f 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c
@@ -6,19 +6,226 @@
  #include "gem/i915_gem_internal.h"
  
  #include "gt/intel_context.h"

+#include "gt/uc/intel_gsc_uc_heci_cmd_submit.h"
  
  #include "i915_drv.h"

  #include "intel_pxp_cmd_interface_43.h"
  #include "intel_pxp_gsccs.h"
  #include "intel_pxp_types.h"
  
+static int

+gsccs_send_message(struct intel_pxp *pxp,
+  void *msg_in, size_t msg_in_size,
+  void *msg_out, size_t msg_out_size_max,
+  size_t *msg_out_len,
+  u64 *gsc_msg_handle_retry)
+{
+   struct intel_gt *gt = pxp->ctrl_gt;
+   struct drm_i915_private *i915 = gt->i915;
+   struct gsccs_session_resources *exec =  >gsccs_res;


in the alloc/free functions you called this object *strm_res; IMO better 
to use a consistent naming so it is clear they're the same object



+   struct intel_gsc_mtl_header *header = exec->pkt_vaddr;
+   struct intel_gsc_heci_non_priv_pkt pkt;
+   bool null_pkt = !msg_in && !msg_out;
+   size_t max_msg_size;
+   u32 reply_size;
+   int ret;
+
+   if (!exec->ce)
+   return -ENODEV;
+
+   max_msg_size = PXP43_MAX_HECI_IN_SIZE - sizeof(*header);


Using the same max_msg_size for both in and out only works if 
PXP43_MAX_HECI_IN_SIZE == PXP43_MAX_HECI_OUT_SIZE. This is true now, but 
I'd add a:


BUILD_BUG_ON(PXP43_MAX_HECI_IN_SIZE  != PXP43_MAX_HECI_OUT_SIZE);

just to be safe. Potentially also a:

GEM_BUG_ON(exec->pkt_vma->size < (PXP43_MAX_HECI_IN_SIZE + 
PXP43_MAX_HECI_OUT_SIZE));


After checking that exec->pkt_vma exists.


+
+   if (msg_in_size > max_msg_size || msg_out_size_max > max_msg_size)
+   return -ENOSPC;
+
+   if (!exec->pkt_vma || !exec->bb_vma)
+   return -ENOENT;
+
+   mutex_lock(>tee_mutex);
+
+   memset(header, 0, sizeof(*header));
+   intel_gsc_uc_heci_cmd_emit_mtl_header(header, GSC_HECI_MEADDRESS_PXP,
+ msg_in_size + sizeof(*header),
+ exec->host_session_handle);
+
+   /* check if this is a host-session-handle cleanup call */
+   if (null_pkt)


nit: can't you just use if (!msg_in && !msg_out) instead of a local var? 
not a blocker.



+   header->flags |= GSC_HECI_FLAG_MSG_CLEANUP;
+
+   /* copy caller provided gsc message handle if this is polling for a 
prior msg completion */
+   header->gsc_message_handle = *gsc_msg_handle_retry;
+
+   /* NOTE: zero size packets are used for session-cleanups */
+ 

Re: [Intel-gfx] [PATCH] drm/i915: Set wedged if enable guc communication failed

2023-03-03 Thread Ceraolo Spurio, Daniele




On 3/2/2023 1:50 PM, Zhanjun Dong wrote:

Add err code check for enable_communication on resume path. When resume failed, 
we can no longer use the GPU, marking the GPU as wedged.


This is slightly incorrect. If we fail to enable communication, the 
consequence is that we can't use the GuC. That translates to a failure 
to use the GT only if GuC submission is enabled; in execlists submission 
mode we can keep going, although we might end up losing HuC 
functionality (which is not considered a fatal error). Therefore, the 
code below should be updated to reflect this.




Signed-off-by: Zhanjun Dong 
---
  drivers/gpu/drm/i915/gt/intel_gt_pm.c | 7 ++-
  drivers/gpu/drm/i915/gt/uc/intel_uc.c | 9 +++--
  2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c 
b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
index cef3d6f5c34e..42a7d75ce39e 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
@@ -401,8 +401,13 @@ int intel_gt_runtime_resume(struct intel_gt *gt)
intel_ggtt_restore_fences(gt->ggtt);
  
  	ret = intel_uc_runtime_resume(>uc);

-   if (ret)
+   if (ret) {
+   /* Resume failed, we can no longer use the GPU, marking the GPU
+* as wedged.
+*/
+   intel_gt_set_wedged(gt);


intel_gt_set_wedged calls intel_runtime_pm_get, so it will deadlock if 
you call if from within the runtime_resume flow.



return ret;
+   }
  
  	return 0;

  }
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index 6648691bd645..d4f428acf20a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -698,8 +698,13 @@ static int __uc_resume(struct intel_uc *uc, bool 
enable_communication)
/* Make sure we enable communication if and only if it's disabled */
GEM_BUG_ON(enable_communication == intel_guc_ct_enabled(>ct));
  
-	if (enable_communication)

-   guc_enable_communication(guc);
+   if (enable_communication) {
+   err = guc_enable_communication(guc);
+   if (err) {
+   guc_dbg(guc, "Failed to resume, %pe", ERR_PTR(err));


nit: this isn't exactly a failure to resume because the GuC is running. 
It's more a failure to re-establish communication with the GuC.


Daniele


+   return err;
+   }
+   }
  
  	/* If we are only resuming GuC communication but not reloading

 * GuC, we need to ensure the ARAT timer interrupt is enabled




Re: [Intel-gfx] [PATCH] drm/i915/pxp: limit drm-errors or warning on firmware API failures

2023-03-03 Thread Ceraolo Spurio, Daniele




On 2/3/2023 9:48 PM, Alan Previn wrote:

MESA driver is creating protected context on every driver handle
creation to query caps bits for app. So when running CI tests,
they are observing hundreds of drm_errors when enabling PXP
in .config but using SOC fusing or BIOS configuration that cannot
support PXP sessions.

The fixes tag referenced below was to resolve a related issue
where we wanted to silence error messages, but that case was due
to outdated IFWI (firmware) that definitely needed an upgrade and
was, at that point, considered a one-off case as opposed to today's
realization that default CI was enabling PXP in kernel config for
all testing.

So with this patch, let's strike a balance between issues that is
critical but are root-caused from HW/platform gaps (louder drm-warn
but just ONCE) vs other cases where it could also come from session
state machine (which cannot be a WARN_ONCE since it can be triggered
due to runtime operation events).

Let's use helpers for these so as more functions are added in future
features / HW (or as FW designers continue to bless upstreaming of
the error codes and meanings), we only need to update the helpers.

NOTE: Don't completely remove FW errors (via drm_debug) or else cusomer
apps that really needs to know that content protection failed won't
be aware of it.

Fixes: b762787bf767 ("drm/i915/pxp: Use drm_dbg if arb session failed due to fw 
version")
Signed-off-by: Alan Previn 
---
  .../i915/pxp/intel_pxp_cmd_interface_cmn.h|  3 +
  drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  2 +-
  drivers/gpu/drm/i915/pxp/intel_pxp_tee.c  | 73 +++
  3 files changed, 64 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h
index ae9b151b7cb7..6f6541d5e49a 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h
@@ -18,6 +18,9 @@
  enum pxp_status {
PXP_STATUS_SUCCESS = 0x0,
PXP_STATUS_ERROR_API_VERSION = 0x1002,
+   PXP_STATUS_NOT_READY = 0x100e,
+   PXP_STATUS_PLATFCONFIG_KF1_NOVERIF = 0x101a,
+   PXP_STATUS_PLATFCONFIG_KF1_BAD = 0x101f,
PXP_STATUS_OP_NOT_PERMITTED = 0x4013
  };
  
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c

index 448cacb0465d..7de849cb6c47 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -74,7 +74,7 @@ static int pxp_create_arb_session(struct intel_pxp *pxp)
  
  	ret = pxp_wait_for_session_state(pxp, ARB_SESSION, true);

if (ret) {
-   drm_err(>i915->drm, "arb session failed to go in play\n");
+   drm_dbg(>i915->drm, "arb session failed to go in play\n");
return ret;
}
drm_dbg(>i915->drm, "PXP ARB session is alive\n");
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index d9d248b48093..2d3bcff93da3 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -19,6 +19,37 @@
  #include "intel_pxp_tee.h"
  #include "intel_pxp_types.h"
  
+static bool

+is_fw_err_platform_config(u32 type)
+{
+   switch (type) {
+   case PXP_STATUS_ERROR_API_VERSION:
+   case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:
+   case PXP_STATUS_PLATFCONFIG_KF1_BAD:
+   return true;
+   default:
+   break;
+   }
+   return false;
+}
+
+static const char *
+fw_err_to_string(u32 type)
+{
+   switch (type) {
+   case PXP_STATUS_ERROR_API_VERSION:
+   return "ERR_API_VERSION";
+   case PXP_STATUS_NOT_READY:
+   return "ERR_NOT_READY";
+   case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:
+   case PXP_STATUS_PLATFCONFIG_KF1_BAD:
+   return "ERR_PLATFORM_CONFIG";
+   default:
+   break;
+   }
+   return NULL;
+}
+
  static int intel_pxp_tee_io_message(struct intel_pxp *pxp,
void *msg_in, u32 msg_in_size,
void *msg_out, u32 msg_out_max_size,
@@ -307,15 +338,21 @@ int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp 
*pxp,
   _out, sizeof(msg_out),
   NULL);
  
-	if (ret)

-   drm_err(>drm, "Failed to send tee msg ret=[%d]\n", ret);
-   else if (msg_out.header.status == PXP_STATUS_ERROR_API_VERSION)
-   drm_dbg(>drm, "PXP firmware version unsupported, requested: 
"
-   "CMD-ID-[0x%08x] on API-Ver-[0x%08x]\n",
-   msg_in.header.command_id, msg_in.header.api_version);
-   else if (msg_out.header.status != 0x0)
-   drm_warn(>drm, "PXP firmware failed arb session init request 
ret=[0x%08x]\n",
-

Re: [Intel-gfx] [PATCH 2/2] drm/i915/guc: Allow for very slow GuC loading

2023-03-03 Thread Ceraolo Spurio, Daniele




On 2/17/2023 3:47 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

A failure to load the GuC is occasionally observed where the GuC log
actually showed that the GuC had loaded just fine. The implication
being that the load just took ever so slightly longer than the 200ms
timeout. Given that the actual time should be tens of milliseconds at
the slowest, this should never happen. So far the issue has generally
been caused by a bad IFWI resulting in low frequencies during boot
(depsite the KMD requesting max frequency). However, the issue seems
to happen more often than one would like.

So a) increase the timeout so that the user still gets a working
system even in the case of slow load. And b) report the frequency
during the load to see if that is the case of the slow down.


Some refs would be good here. From a quick search, these seems to match:

https://gitlab.freedesktop.org/drm/intel/-/issues/7931
https://gitlab.freedesktop.org/drm/intel/-/issues/8060
https://gitlab.freedesktop.org/drm/intel/-/issues/8083
https://gitlab.freedesktop.org/drm/intel/-/issues/8136
https://gitlab.freedesktop.org/drm/intel/-/issues/8137



Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 37 +--
  1 file changed, 34 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
index 2f5942606913d..72e003f50617d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -12,6 +12,7 @@
  #include "gt/intel_gt.h"
  #include "gt/intel_gt_mcr.h"
  #include "gt/intel_gt_regs.h"
+#include "gt/intel_rps.h"
  #include "intel_guc_fw.h"
  #include "intel_guc_print.h"
  #include "i915_drv.h"
@@ -139,9 +140,12 @@ static int guc_wait_ucode(struct intel_guc *guc)
  {
struct intel_gt *gt = guc_to_gt(guc);
struct intel_uncore *uncore = gt->uncore;
+   ktime_t before, after, delta;
bool success;
u32 status;
-   int ret;
+   int ret, count;
+   u64 delta_ms;
+   u32 before_freq;
  
  	/*

 * Wait for the GuC to start up.
@@ -159,13 +163,32 @@ static int guc_wait_ucode(struct intel_guc *guc)
 * issues to be resolved. In the meantime bump the timeout to
 * 200ms. Even at slowest clock, this should be sufficient. And
 * in the working case, a larger timeout makes no difference.
+*
+* IFWI updates have also been seen to cause sporadic failures due to
+* the requested frequency not being granted and thus the firmware
+* load is attempted at minimum frequency. That can lead to load times
+* in the seconds range. However, there is a limit on how long an
+* individual wait_for() can wait. So wrap it in a loop.
 */
-   ret = wait_for(guc_load_done(uncore, , ), 200);
+   before_freq = intel_rps_read_actual_frequency(>gt->rps);
+   before = ktime_get();
+   for (count = 0; count < 20; count++) {
+   ret = wait_for(guc_load_done(uncore, , ), 1000);


Isn't 20 secs a bit too long for an in-place wait? I get that if the GuC 
doesn't load (or fail to) within a few secs the HW is likely toast, but 
still that seems a bit too long to me. What's the worst case load time 
ever observed? I suggest reducing the wait to 3 secs as a compromise, if 
that's bigger than the worst case.


The patch LGTM apart from this point.

Daniele


+   if (!ret || !success)
+   break;
+
+   guc_dbg(guc, "load still in progress, count = %d, freq = 
%dMHz\n",
+   count, 
intel_rps_read_actual_frequency(>gt->rps));
+   }
+   after = ktime_get();
+   delta = ktime_sub(after, before);
+   delta_ms = ktime_to_ms(delta);
if (ret || !success) {
u32 ukernel = REG_FIELD_GET(GS_UKERNEL_MASK, status);
u32 bootrom = REG_FIELD_GET(GS_BOOTROM_MASK, status);
  
-		guc_info(guc, "load failed: status = 0x%08X, ret = %d\n", status, ret);

+   guc_info(guc, "load failed: status = 0x%08X, time = %lldms, freq = 
%dMHz, ret = %d\n",
+status, delta_ms, 
intel_rps_read_actual_frequency(>gt->rps), ret);
guc_info(guc, "load failed: status: Reset = %d, BootROM = 0x%02X, 
UKernel = 0x%02X, MIA = 0x%02X, Auth = 0x%02X\n",
 REG_FIELD_GET(GS_MIA_IN_RESET, status),
 bootrom, ukernel,
@@ -206,6 +229,14 @@ static int guc_wait_ucode(struct intel_guc *guc)
/* Uncommon/unexpected error, see earlier status code print for 
details */
if (ret == 0)
ret = -ENXIO;
+   } else if (delta_ms > 200) {
+   guc_warn(guc, "excessive init time: %lldms! [freq = %dMHz, before = 
%dMHz, status = 0x%08X, count = %d, ret = %d]\n",
+delta_ms, 
intel_rps_read_actual_frequency(>gt->rps),
+ 

Re: [Intel-gfx] [PATCH 1/2] drm/i915/guc: Improve GuC load error reporting

2023-03-03 Thread Ceraolo Spurio, Daniele




On 2/17/2023 3:47 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

There are multiple ways in which the GuC load can fail. The driver was
reporting the status register as is, but not everyone can read the
matrix unfiltered. So add decoding of the common error cases.

Also, remove the comment about interrupt based load completion
checking being not recommended. The interrupt was removed from the GuC
firmware some time ago so it is no longer an option anyway. While at
it, also abort the timeout if a known error code is reported. No need
to keep waiting if the GuC has already given up the load.

Signed-off-by: John Harrison 
---
  .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   | 17 
  drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 95 +++
  drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h|  4 +-
  3 files changed, 95 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h 
b/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
index 8085fb1812748..750fe0c6d8529 100644
--- a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
@@ -21,6 +21,9 @@ enum intel_guc_load_status {
INTEL_GUC_LOAD_STATUS_ERROR_DEVID_BUILD_MISMATCH   = 0x02,
INTEL_GUC_LOAD_STATUS_GUC_PREPROD_BUILD_MISMATCH   = 0x03,
INTEL_GUC_LOAD_STATUS_ERROR_DEVID_INVALID_GUCTYPE  = 0x04,
+   INTEL_GUC_LOAD_STATUS_HWCONFIG_START   = 0x05,
+   INTEL_GUC_LOAD_STATUS_HWCONFIG_DONE= 0x06,
+   INTEL_GUC_LOAD_STATUS_HWCONFIG_ERROR   = 0x07,
INTEL_GUC_LOAD_STATUS_GDT_DONE = 0x10,
INTEL_GUC_LOAD_STATUS_IDT_DONE = 0x20,
INTEL_GUC_LOAD_STATUS_LAPIC_DONE   = 0x30,
@@ -38,4 +41,18 @@ enum intel_guc_load_status {
INTEL_GUC_LOAD_STATUS_READY= 0xF0,
  };
  
+enum intel_bootrom_load_status {

+   INTEL_BOOTROM_STATUS_NO_KEY_FOUND = 0x13,
+   INTEL_BOOTROM_STATUS_AES_PROD_KEY_FOUND   = 0x1A,
+   INTEL_BOOTROM_STATUS_RSA_FAILED   = 0x50,
+   INTEL_BOOTROM_STATUS_PAVPC_FAILED = 0x73,
+   INTEL_BOOTROM_STATUS_WOPCM_FAILED = 0x74,
+   INTEL_BOOTROM_STATUS_LOADLOC_FAILED   = 0x75,
+   INTEL_BOOTROM_STATUS_JUMP_PASSED  = 0x76,
+   INTEL_BOOTROM_STATUS_JUMP_FAILED  = 0x77,
+   INTEL_BOOTROM_STATUS_RC6CTXCONFIG_FAILED  = 0x79,
+   INTEL_BOOTROM_STATUS_MPUMAP_INCORRECT = 0x7a,


nit: you've used uppercase for the other hex characters, while only this 
one has a lowercase "a"



+   INTEL_BOOTROM_STATUS_EXCEPTION= 0x7E,
+};


I've double checked the defines against the specs and they all match.


+
  #endif /* _ABI_GUC_ERRORS_ABI_H */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
index 69133420c78b2..2f5942606913d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -88,31 +88,64 @@ static int guc_xfer_rsa(struct intel_uc_fw *guc_fw,
  /*
   * Read the GuC status register (GUC_STATUS) and store it in the
   * specified location; then return a boolean indicating whether
- * the value matches either of two values representing completion
- * of the GuC boot process.
+ * the value matches either completion or a known failure code.
   *
   * This is used for polling the GuC status in a wait_for()
   * loop below.
   */
-static inline bool guc_ready(struct intel_uncore *uncore, u32 *status)
+static inline bool guc_load_done(struct intel_uncore *uncore, u32 *status, 
bool *success)
  {
u32 val = intel_uncore_read(uncore, GUC_STATUS);
u32 uk_val = REG_FIELD_GET(GS_UKERNEL_MASK, val);
+   u32 br_val = REG_FIELD_GET(GS_BOOTROM_MASK, val);
  
  	*status = val;

-   return uk_val == INTEL_GUC_LOAD_STATUS_READY;
+   *success = true;


It feels a bit weird to default this to true. If we don't return true 
from one of the switches below, we can end up returning false from the 
wait but leaving success to true. I understand that this is used more as 
a "not failed" flag rather than a success one, so it is functionally 
correct, but maybe rename it? not a blocker.


Apart from the nits, the patch LGTM:

Reviewed-by: Daniele Ceraolo Spurio 

Daniele


+   switch (uk_val) {
+   case INTEL_GUC_LOAD_STATUS_READY:
+   return true;
+
+   case INTEL_GUC_LOAD_STATUS_ERROR_DEVID_BUILD_MISMATCH:
+   case INTEL_GUC_LOAD_STATUS_GUC_PREPROD_BUILD_MISMATCH:
+   case INTEL_GUC_LOAD_STATUS_ERROR_DEVID_INVALID_GUCTYPE:
+   case INTEL_GUC_LOAD_STATUS_HWCONFIG_ERROR:
+   case INTEL_GUC_LOAD_STATUS_DPC_ERROR:
+   case INTEL_GUC_LOAD_STATUS_EXCEPTION:
+   case INTEL_GUC_LOAD_STAT

Re: [Intel-gfx] [PATCH] drm/i915/gsc: Fix the Driver-FLR completion

2023-02-23 Thread Ceraolo Spurio, Daniele




On 2/22/2023 1:01 PM, Alan Previn wrote:

The Driver-FLR flow may inadvertently exit early before the full
completion of the re-init of the internal HW state if we only poll
GU_DEBUG Bit31 (polling for it to toggle from 0 -> 1). Instead
we need a two-step completion wait-for-completion flow that also
involves GU_CNTL. See the patch and new code comments for detail.
This is new direction from HW architecture folks.

v2: - Add error message for the teardown timeout (Anshuman)
- Don't duplicate code in comments (Jani)

Signed-off-by: Alan Previn 
Fixes: 5a44fcd73498 ("drm/i915/gsc: Do a driver-FLR on unload if GSC was 
loaded")


I'm not sure if we need a fixes tag, given that this is MTL specific 
code and that's still under force probe.



---
  drivers/gpu/drm/i915/intel_uncore.c | 13 -
  1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
b/drivers/gpu/drm/i915/intel_uncore.c
index f018da7ebaac..f3c46352db89 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -2749,14 +2749,25 @@ static void driver_initiated_flr(struct intel_uncore 
*uncore)
/* Trigger the actual Driver-FLR */
intel_uncore_rmw_fw(uncore, GU_CNTL, 0, DRIVERFLR);
  
+	/* Wait for hardware teardown to complete */

+   ret = intel_wait_for_register_fw(uncore, GU_CNTL,
+DRIVERFLR_STATUS, 0,


shouldn't this bit be DRIVERFLR instead of DRIVERFLR_STATUS ? I know 
they're both BIT(31), but DRIVERFLR_STATUS is the definition for the 
GU_DEBUG bit, while this wait is on GU_CNTL.



+flr_timeout_ms);
+   if (ret) {
+   drm_err(>drm, "Driver-FLR-teardown wait completion failed! 
%d\n", ret);
+   return;
+   }
+
+   /* Wait for hardware/firmware re-init to complete */
ret = intel_wait_for_register_fw(uncore, GU_DEBUG,
 DRIVERFLR_STATUS, DRIVERFLR_STATUS,
 flr_timeout_ms);


I was wondering if we could reduce the timing here to avoid 2 waits of 3 
seconds, as the 3 seconds should be for the full process. However, the 
specs don't say how much each step can take, so I agree that to be safe 
is better to have both timeouts at 3 seconds. If the FLR fails the HW is 
toast anyway, so waiting a few seconds more to detect it on driver 
unload is not going to have additional consequences that we wouldn't 
already have.


With the bit in the wait above fixed:
Reviewed-by: Daniele Ceraolo Spurio 

Daniele


if (ret) {
-   drm_err(>drm, "wait for Driver-FLR completion failed! 
%d\n", ret);
+   drm_err(>drm, "Driver-FLR-reinit wait completion failed! 
%d\n", ret);
return;
}
  
+	/* Clear sticky completion status */

intel_uncore_write_fw(uncore, GU_DEBUG, DRIVERFLR_STATUS);
  }
  




Re: [Intel-gfx] [PATCH] drm/i915/gsc: Fix the Driver-FLR completion

2023-02-23 Thread Ceraolo Spurio, Daniele




On 2/23/2023 2:04 PM, Alan Previn wrote:

The Driver-FLR flow may inadvertently exit early before the full
completion of the re-init of the internal HW state if we only poll
GU_DEBUG Bit31 (polling for it to toggle from 0 -> 1). Instead
we need a two-step completion wait-for-completion flow that also
involves GU_CNTL. See the patch and new code comments for detail.
This is new direction from HW architecture folks.

v2: - Add error message for the teardown timeout (Anshuman)
- Don't duplicate code in comments (Jani)
v3: - Add get/put runtime-pm for this function. Though
  not functionally required during unload, its so the uncore
 doesn't complain.


I think my comment applied to an older version of this code. The FLR is 
done after we've already disabled rpm (from driver_unregister), so we 
shouldn't need to take a ref here. If this ever changes, then the rpm 
get/put should be added to the caller (uncore_fini_mmio) because there 
are other register accesses performed by that function and we should 
cover them all.
Given this, IMO we should revert back to the v2 version of this patch, 
so I'm going to review that one.


Daniele



Signed-off-by: Alan Previn 
Fixes: 5a44fcd73498 ("drm/i915/gsc: Do a driver-FLR on unload if GSC was 
loaded")
---
  drivers/gpu/drm/i915/intel_uncore.c | 23 ---
  1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
b/drivers/gpu/drm/i915/intel_uncore.c
index f018da7ebaac..9832b8ac8b1a 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -2724,10 +2724,13 @@ static void driver_initiated_flr(struct intel_uncore 
*uncore)
  {
struct drm_i915_private *i915 = uncore->i915;
const unsigned int flr_timeout_ms = 3000; /* specs recommend a 3s wait 
*/
+   intel_wakeref_t wakeref;
int ret;
  
  	drm_dbg(>drm, "Triggering Driver-FLR\n");
  
+	wakeref = intel_runtime_pm_get(>runtime_pm);

+
/*
 * Make sure any pending FLR requests have cleared by waiting for the
 * FLR trigger bit to go to zero. Also clear GU_DEBUG's DRIVERFLR_STATUS
@@ -2742,22 +2745,36 @@ static void driver_initiated_flr(struct intel_uncore 
*uncore)
drm_err(>drm,
"Failed to wait for Driver-FLR bit to clear! %d\n",
ret);
-   return;
+   goto out;
}
intel_uncore_write_fw(uncore, GU_DEBUG, DRIVERFLR_STATUS);
  
  	/* Trigger the actual Driver-FLR */

intel_uncore_rmw_fw(uncore, GU_CNTL, 0, DRIVERFLR);
  
+	/* Wait for hardware teardown to complete */

+   ret = intel_wait_for_register_fw(uncore, GU_CNTL,
+DRIVERFLR_STATUS, 0,
+flr_timeout_ms);
+   if (ret) {
+   drm_err(>drm, "Driver-FLR-teardown wait completion failed! 
%d\n", ret);
+   goto out;
+   }
+
+   /* Wait for hardware/firmware re-init to complete */
ret = intel_wait_for_register_fw(uncore, GU_DEBUG,
 DRIVERFLR_STATUS, DRIVERFLR_STATUS,
 flr_timeout_ms);
if (ret) {
-   drm_err(>drm, "wait for Driver-FLR completion failed! 
%d\n", ret);
-   return;
+   drm_err(>drm, "Driver-FLR-reinit wait completion failed! 
%d\n", ret);
+   goto out;
}
  
+	/* Clear sticky completion status */

intel_uncore_write_fw(uncore, GU_DEBUG, DRIVERFLR_STATUS);
+
+out:
+   intel_runtime_pm_put(>runtime_pm, wakeref);
  }
  
  /* Called via drm-managed action */




Re: [Intel-gfx] [PATCH v3 2/2] drm/i915: Don't use BAR mappings for ring buffers with LLC

2023-02-17 Thread Ceraolo Spurio, Daniele




On 2/15/2023 5:11 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

Direction from hardware is that ring buffers should never be mapped
via the BAR on systems with LLC. There are too many caching pitfalls
due to the way BAR accesses are routed. So it is safest to just not
use it.

Signed-off-by: John Harrison 
Fixes: 9d80841ea4c9 ("drm/i915: Allow ringbuffers to be bound anywhere")
Cc: Chris Wilson 
Cc: Joonas Lahtinen 
Cc: Jani Nikula 
Cc: Rodrigo Vivi 
Cc: Tvrtko Ursulin 
Cc: intel-gfx@lists.freedesktop.org
Cc:  # v4.9+


I've double-checked the original patches to make sure the 4.9 fixes tag 
was correct for both (which dim confirmed), because if we backport this 
fix without the previous one then the driver would break. Also, the 
original patches were merged as part of the same series 
(https://patchwork.freedesktop.org/series/11278/), so we should be 
guaranteed that they're always there as a pair.


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/intel_ring.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_ring.c 
b/drivers/gpu/drm/i915/gt/intel_ring.c
index fb1d2595392ed..fb99143be98e7 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring.c
@@ -53,7 +53,7 @@ int intel_ring_pin(struct intel_ring *ring, struct 
i915_gem_ww_ctx *ww)
if (unlikely(ret))
goto err_unpin;
  
-	if (i915_vma_is_map_and_fenceable(vma)) {

+   if (i915_vma_is_map_and_fenceable(vma) && !HAS_LLC(vma->vm->i915)) {
addr = (void __force *)i915_vma_pin_iomap(vma);
} else {
int type = i915_coherent_map_type(vma->vm->i915, vma->obj, 
false);
@@ -98,7 +98,7 @@ void intel_ring_unpin(struct intel_ring *ring)
return;
  
  	i915_vma_unset_ggtt_write(vma);

-   if (i915_vma_is_map_and_fenceable(vma))
+   if (i915_vma_is_map_and_fenceable(vma) && !HAS_LLC(vma->vm->i915))
i915_vma_unpin_iomap(vma);
else
i915_gem_object_unpin_map(vma->obj);




Re: [Intel-gfx] [PATCH v3 1/2] drm/i915: Don't use stolen memory for ring buffers with LLC

2023-02-17 Thread Ceraolo Spurio, Daniele




On 2/15/2023 5:11 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

Direction from hardware is that stolen memory should never be used for
ring buffer allocations on platforms with LLC. There are too many
caching pitfalls due to the way stolen memory accesses are routed. So
it is safest to just not use it.

Signed-off-by: John Harrison 
Fixes: c58b735fc762 ("drm/i915: Allocate rings from stolen")
Cc: Chris Wilson 
Cc: Joonas Lahtinen 
Cc: Jani Nikula 
Cc: Rodrigo Vivi 
Cc: Tvrtko Ursulin 
Cc: intel-gfx@lists.freedesktop.org
Cc:  # v4.9+


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/intel_ring.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_ring.c 
b/drivers/gpu/drm/i915/gt/intel_ring.c
index 15ec64d881c44..fb1d2595392ed 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring.c
@@ -116,7 +116,7 @@ static struct i915_vma *create_ring_vma(struct i915_ggtt 
*ggtt, int size)
  
  	obj = i915_gem_object_create_lmem(i915, size, I915_BO_ALLOC_VOLATILE |

  I915_BO_ALLOC_PM_VOLATILE);
-   if (IS_ERR(obj) && i915_ggtt_has_aperture(ggtt))
+   if (IS_ERR(obj) && i915_ggtt_has_aperture(ggtt) && !HAS_LLC(i915))
obj = i915_gem_object_create_stolen(i915, size);
if (IS_ERR(obj))
obj = i915_gem_object_create_internal(i915, size);




Re: [Intel-gfx] [PATCH] drm/i915: Don't use stolen memory for ring buffers

2023-02-14 Thread Ceraolo Spurio, Daniele




On 2/14/2023 3:48 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

Direction from hardware is that stolen memory should never be used for
ring buffer allocations. There are too many caching pitfalls due to the
way stolen memory accesses are routed. So it is safest to just not use
it.


I'm wondering if this applies to machines in ringbuffer mode as well, as 
some of the caching stuff that according to the HW team may not work 
properly with stolen mem accesses from the CS (mocs, ppat) came with 
gen8/gen9.
Maybe limit this change to gen8+, to avoid changing the behavior for 
very old platforms?




Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/intel_ring.c | 2 --
  1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_ring.c 
b/drivers/gpu/drm/i915/gt/intel_ring.c
index 15ec64d881c44..d1a47e1ae6452 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring.c
@@ -116,8 +116,6 @@ static struct i915_vma *create_ring_vma(struct i915_ggtt 
*ggtt, int size)
  
  	obj = i915_gem_object_create_lmem(i915, size, I915_BO_ALLOC_VOLATILE |

  I915_BO_ALLOC_PM_VOLATILE);
-   if (IS_ERR(obj) && i915_ggtt_has_aperture(ggtt))
-   obj = i915_gem_object_create_stolen(i915, size);


There is code in ring_pin/unpin() that only applies to rings in stolen 
memory, so you need to remove that as well if you drop stolen for rings 
on all platforms.


Daniele


if (IS_ERR(obj))
obj = i915_gem_object_create_internal(i915, size);
if (IS_ERR(obj))




Re: [Intel-gfx] [PATCH v2] drm/i915/huc: Add and use HuC oriented print macros

2023-02-06 Thread Ceraolo Spurio, Daniele




On 2/3/2023 12:59 AM, Michal Wajdeczko wrote:

Like we did it for GuC, introduce some helper print macros for
HuC to have unified format of messages that also include GT#.

While around improve some messages and use %pe if possible.

v2: update GSC/PXP timeout message

Signed-off-by: Michal Wajdeczko 
Cc: John Harrison 
Cc: Daniele Ceraolo Spurio 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/uc/intel_huc.c | 44 ++
  1 file changed, 23 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 410905da8e97..72884e21470b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -6,6 +6,7 @@
  #include 
  
  #include "gt/intel_gt.h"

+#include "gt/intel_gt_print.h"
  #include "intel_guc_reg.h"
  #include "intel_huc.h"
  #include "i915_drv.h"
@@ -13,6 +14,15 @@
  #include 
  #include 
  
+#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
   *
@@ -107,11 +117,9 @@ static enum hrtimer_restart 
huc_delayed_load_timer_callback(struct hrtimer *hrti
  
  	if (!intel_huc_is_authenticated(huc)) {

if (huc->delayed_load.status == INTEL_HUC_WAITING_ON_GSC)
-   drm_notice(_to_gt(huc)->i915->drm,
-  "timed out waiting for MEI GSC init to load 
HuC\n");
+   huc_notice(huc, "timed out waiting for MEI GSC\n");
else if (huc->delayed_load.status == INTEL_HUC_WAITING_ON_PXP)
-   drm_notice(_to_gt(huc)->i915->drm,
-  "timed out waiting for MEI PXP init to load 
HuC\n");
+   huc_notice(huc, "timed out waiting for MEI PXP\n");
else
MISSING_CASE(huc->delayed_load.status);
  
@@ -174,8 +182,7 @@ static int gsc_notifier(struct notifier_block *nb, unsigned long action, void *d
  
  	case BUS_NOTIFY_DRIVER_NOT_BOUND: /* mei driver fails to be bound */

case BUS_NOTIFY_UNBIND_DRIVER: /* mei driver about to be unbound */
-   drm_info(_to_gt(huc)->i915->drm,
-"mei driver not bound, disabling HuC load\n");
+   huc_info(huc, "MEI driver not bound, disabling load\n");
gsc_init_error(huc);
break;
}
@@ -193,8 +200,7 @@ void intel_huc_register_gsc_notifier(struct intel_huc *huc, 
struct bus_type *bus
huc->delayed_load.nb.notifier_call = gsc_notifier;
ret = bus_register_notifier(bus, >delayed_load.nb);
if (ret) {
-   drm_err(_to_gt(huc)->i915->drm,
-   "failed to register GSC notifier\n");
+   huc_err(huc, "failed to register GSC notifier %pe\n", 
ERR_PTR(ret));
huc->delayed_load.nb.notifier_call = NULL;
gsc_init_error(huc);
}
@@ -306,29 +312,25 @@ static int check_huc_loading_mode(struct intel_huc *huc)
  GSC_LOADS_HUC;
  
  	if (fw_needs_gsc != hw_uses_gsc) {

-   drm_err(>i915->drm,
-   "mismatch between HuC FW (%s) and HW (%s) load modes\n",
-   HUC_LOAD_MODE_STRING(fw_needs_gsc),
-   HUC_LOAD_MODE_STRING(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));
return -ENOEXEC;
}
  
  	/* make sure we can access the GSC via the mei driver if we need it */

if (!(IS_ENABLED(CONFIG_INTEL_MEI_PXP) && IS_ENABLED(CONFIG_INTEL_MEI_GSC)) 
&&
fw_needs_gsc) {
-   drm_info(>i915->drm,
-"Can't load HuC due to missing MEI modules\n");
+   huc_info(huc, "can't load due to missing MEI modules\n");
return -EIO;
}
  
-	drm_dbg(>i915->drm, "GSC loads huc=%s\n", str_yes_no(fw_needs_gsc));

+   huc_dbg(huc, "loaded by GSC = %s\n", str_yes_no(fw_n

Re: [Intel-gfx] [PATCH] drm/i915/huc: Add and use HuC oriented print macros

2023-02-02 Thread Ceraolo Spurio, Daniele




On 1/31/2023 2:28 PM, Michal Wajdeczko wrote:

Like we did it for GuC, introduce some helper print macros for
HuC to have unified format of messages that also include GT#.

While around improve some messages and use %pe if possible.

Signed-off-by: Michal Wajdeczko 
Cc: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_huc.c | 44 ++
  1 file changed, 23 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 410905da8e97..834e3b5b8f4b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -6,6 +6,7 @@
  #include 
  
  #include "gt/intel_gt.h"

+#include "gt/intel_gt_print.h"
  #include "intel_guc_reg.h"
  #include "intel_huc.h"
  #include "i915_drv.h"
@@ -13,6 +14,15 @@
  #include 
  #include 
  
+#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
   *
@@ -107,11 +117,9 @@ static enum hrtimer_restart 
huc_delayed_load_timer_callback(struct hrtimer *hrti
  
  	if (!intel_huc_is_authenticated(huc)) {

if (huc->delayed_load.status == INTEL_HUC_WAITING_ON_GSC)
-   drm_notice(_to_gt(huc)->i915->drm,
-  "timed out waiting for MEI GSC init to load 
HuC\n");
+   huc_notice(huc, "load timed out waiting for MEI GSC\n");


I think this rewording makes the error message less clear. We didn't 
time out loading HuC, we timed out waiting for the required components 
to be ready before we even started the load process. Same for the one below.

Apart from this the patch LGTM.

Daniele


else if (huc->delayed_load.status == INTEL_HUC_WAITING_ON_PXP)
-   drm_notice(_to_gt(huc)->i915->drm,
-  "timed out waiting for MEI PXP init to load 
HuC\n");
+   huc_notice(huc, "load timed out waiting for MEI PXP\n");
else
MISSING_CASE(huc->delayed_load.status);
  
@@ -174,8 +182,7 @@ static int gsc_notifier(struct notifier_block *nb, unsigned long action, void *d
  
  	case BUS_NOTIFY_DRIVER_NOT_BOUND: /* mei driver fails to be bound */

case BUS_NOTIFY_UNBIND_DRIVER: /* mei driver about to be unbound */
-   drm_info(_to_gt(huc)->i915->drm,
-"mei driver not bound, disabling HuC load\n");
+   huc_info(huc, "MEI driver not bound, disabling load\n");
gsc_init_error(huc);
break;
}
@@ -193,8 +200,7 @@ void intel_huc_register_gsc_notifier(struct intel_huc *huc, 
struct bus_type *bus
huc->delayed_load.nb.notifier_call = gsc_notifier;
ret = bus_register_notifier(bus, >delayed_load.nb);
if (ret) {
-   drm_err(_to_gt(huc)->i915->drm,
-   "failed to register GSC notifier\n");
+   huc_err(huc, "failed to register GSC notifier %pe\n", 
ERR_PTR(ret));
huc->delayed_load.nb.notifier_call = NULL;
gsc_init_error(huc);
}
@@ -306,29 +312,25 @@ static int check_huc_loading_mode(struct intel_huc *huc)
  GSC_LOADS_HUC;
  
  	if (fw_needs_gsc != hw_uses_gsc) {

-   drm_err(>i915->drm,
-   "mismatch between HuC FW (%s) and HW (%s) load modes\n",
-   HUC_LOAD_MODE_STRING(fw_needs_gsc),
-   HUC_LOAD_MODE_STRING(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));
return -ENOEXEC;
}
  
  	/* make sure we can access the GSC via the mei driver if we need it */

if (!(IS_ENABLED(CONFIG_INTEL_MEI_PXP) && IS_ENABLED(CONFIG_INTEL_MEI_GSC)) 
&&
fw_needs_gsc) {
-   drm_info(>i915->drm,
-"Can't load HuC due to missing MEI modules\n");
+   huc_info(huc, "can't load due to missing MEI modules\n");
return -EIO;
}
  
-	drm_dbg(>i915->drm, "GSC loads huc=%s\n", str_yes_no(fw_needs_gsc));

+   huc_dbg(huc, "loaded by GSC = %s\n", str_yes_no(fw_needs_gsc));
  
  	return 0;

  }
  
  int intel_huc_init(struct intel_huc *huc)

  {
-   struct drm_i915_private 

Re: [Intel-gfx] [PATCH v3 2/8] drm/i915/pxp: Add MTL hw-plumbing enabling for KCR operation

2023-01-26 Thread Ceraolo Spurio, Daniele




On 1/25/2023 12:06 AM, Alan Previn wrote:

Add MTL hw-plumbing enabling for KCR operation under PXP
which includes:

1. Updating 'pick-gt' to get the media tile for
KCR interrupt handling
2. Adding MTL's KCR registers for PXP operation
(init, status-checking, etc.).

While doing #2, lets create a separate registers header file for PXP
to be consistent with other i915 global subsystems.

Signed-off-by: Alan Previn 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/intel_gt_irq.c   |  3 +-
  drivers/gpu/drm/i915/pxp/intel_pxp.c | 32 
  drivers/gpu/drm/i915/pxp/intel_pxp_regs.h| 27 +
  drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 12 +++-
  drivers/gpu/drm/i915/pxp/intel_pxp_types.h   |  6 
  5 files changed, 58 insertions(+), 22 deletions(-)
  create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_regs.h

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c 
b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
index 1b25a6039152..c360776a98b5 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
@@ -100,7 +100,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_INSTANCE && HAS_ENGINE(media_gt, 
GSC0))
+   if ((instance == OTHER_GSC_INSTANCE || instance == OTHER_KCR_INSTANCE) 
&&
+   HAS_ENGINE(media_gt, GSC0))
return media_gt;
fallthrough;
default:
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 22280408156e..4350921e40c4 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -14,6 +14,7 @@
  #include "intel_pxp.h"
  #include "intel_pxp_gsccs.h"
  #include "intel_pxp_irq.h"
+#include "intel_pxp_regs.h"
  #include "intel_pxp_session.h"
  #include "intel_pxp_tee.h"
  #include "intel_pxp_types.h"
@@ -61,21 +62,22 @@ bool intel_pxp_is_active(const struct intel_pxp *pxp)
return IS_ENABLED(CONFIG_DRM_I915_PXP) && pxp && pxp->arb_is_valid;
  }
  
-/* KCR register definitions */

-#define KCR_INIT _MMIO(0x320f0)
-/* Setting KCR Init bit is required after system boot */
-#define KCR_INIT_ALLOW_DISPLAY_ME_WRITES REG_BIT(14)
+static void kcr_pxp_set_status(const struct intel_pxp *pxp, bool enable)
+{
+   u32 val = enable ? _MASKED_BIT_ENABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES) 
:
+ _MASKED_BIT_DISABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES);
+
+   intel_uncore_write(pxp->ctrl_gt->uncore, KCR_INIT(pxp->kcr_base), val);
+}
  
-static void kcr_pxp_enable(struct intel_gt *gt)

+static void kcr_pxp_enable(const struct intel_pxp *pxp)
  {
-   intel_uncore_write(gt->uncore, KCR_INIT,
-  
_MASKED_BIT_ENABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES));
+   kcr_pxp_set_status(pxp, true);
  }
  
-static void kcr_pxp_disable(struct intel_gt *gt)

+static void kcr_pxp_disable(const struct intel_pxp *pxp)
  {
-   intel_uncore_write(gt->uncore, KCR_INIT,
-  
_MASKED_BIT_DISABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES));
+   kcr_pxp_set_status(pxp, false);
  }
  
  static int create_vcs_context(struct intel_pxp *pxp)

@@ -127,6 +129,11 @@ static void pxp_init_full(struct intel_pxp *pxp)
init_completion(>termination);
complete_all(>termination);
  
+	if (pxp->ctrl_gt->type == GT_MEDIA)

+   pxp->kcr_base = MTL_KCR_BASE;
+   else
+   pxp->kcr_base = GEN12_KCR_BASE;
+
intel_pxp_session_management_init(pxp);
  
  	ret = create_vcs_context(pxp);

@@ -319,14 +326,13 @@ int intel_pxp_start(struct intel_pxp *pxp)
  
  void intel_pxp_init_hw(struct intel_pxp *pxp)

  {
-   kcr_pxp_enable(pxp->ctrl_gt);
+   kcr_pxp_enable(pxp);
intel_pxp_irq_enable(pxp);
  }
  
  void intel_pxp_fini_hw(struct intel_pxp *pxp)

  {
-   kcr_pxp_disable(pxp->ctrl_gt);
-
+   kcr_pxp_disable(pxp);
intel_pxp_irq_disable(pxp);
  }
  
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_regs.h b/drivers/gpu/drm/i915/pxp/intel_pxp_regs.h

new file mode 100644
index ..a9e7e6efa4c7
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_regs.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2023, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_REGS_H__
+#define __INTEL_PXP_REGS_H__
+
+#include "i915_reg_defs.h"
+
+/* KCR subsystem register base address */
+#define GEN12_KCR_BASE 0x32000
+#define MTL_KCR_BASE 0x386000
+
+/* KCR enable/disable control */
+#define KCR_INIT(base) _MMIO((base) + 0xf0)
+
+/* Setting KCR Init bit is required after system boot */
+

Re: [Intel-gfx] [PATCH v3 1/8] drm/i915/pxp: Add GSC-CS back-end resource init and cleanup

2023-01-26 Thread Ceraolo Spurio, Daniele
would only be called with the correct gt.
+*/
+   if (!engine)
+   return -ENODEV;
+
+   mutex_init(>tee_mutex);


We init this mutex in all paths, so I wonder if it is worth pulling the 
init to the pxp_init func, immediately after we set pxp->ctrl_gt and 
before we select what sub-component to init. not a blocker.



+
+   /* Finally, create an intel_context to be used during the submission */
+   ce = intel_context_create(engine);
+   if (IS_ERR(ce)) {
+   drm_err(>i915->drm, "Failed creating gsccs backend ctx\n");
+   return PTR_ERR(ce);
+   }
+   i915_vm_put(ce->vm);
+   ce->vm = i915_vm_get(pxp->ctrl_gt->vm);


Intel_context_init (inside intel_context_create) is already doing:

ce->vm = i915_vm_get(engine->gt->vm);

so you shouldn't need the put & get here


+
+   strm_res->ce = ce;
+
+   return 0;
+}
+
+void intel_pxp_gsccs_fini(struct intel_pxp *pxp)
+{
+   gsccs_destroy_execution_resource(pxp);
+}
+
+int intel_pxp_gsccs_init(struct intel_pxp *pxp)
+{
+   return gsccs_allocate_execution_resource(pxp);
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h
new file mode 100644
index ..354ea9a8f940
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2022, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_GSCCS_H__
+#define __INTEL_PXP_GSCCS_H__
+
+#include 
+
+struct intel_pxp;
+
+#ifdef CONFIG_DRM_I915_PXP
+void intel_pxp_gsccs_fini(struct intel_pxp *pxp);
+int intel_pxp_gsccs_init(struct intel_pxp *pxp);
+
+#else
+static inline void intel_pxp_gsccs_fini(struct intel_pxp *pxp)
+{
+}
+
+static inline int intel_pxp_gsccs_init(struct intel_pxp *pxp)
+{
+   return 0;
+}
+
+#endif
+
+#endif /*__INTEL_PXP_GSCCS_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index 7dc5f08d1583..326bd8414407 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -26,6 +26,14 @@ struct intel_pxp {
 */
struct intel_gt *ctrl_gt;
  
+	/**

+* @gsccs_res: resources for request submission for platforms that have 
a GSC engine.
+    */
+   struct gsccs_session_resources {
+   u64 host_session_handle; /* used by firmware to link commands 
to sessions */


Can you move the addition of this variable to the patch that uses it?
with these nits addressed:

Reviewed-by: Daniele Ceraolo Spurio 

Daniele


+   struct intel_context *ce; /* context for gsc command submission 
*/
+   } gsccs_res;
+
/**
 * @pxp_component: i915_pxp_component struct of the bound mei_pxp
 * module. Only set and cleared inside component bind/unbind functions,




Re: [Intel-gfx] [PATCH v5 1/8] drm/i915/guc: Fix locking when searching for a hung request

2023-01-26 Thread Ceraolo Spurio, Daniele




On 1/25/2023 4:54 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

intel_guc_find_hung_context() was not acquiring the correct spinlock
before searching the request list. So fix that up. While at it, add
some extra whitespace padding for readability.

Fixes: dc0dad365c5e ("drm/i915/guc: Fix for error capture after full GPU reset with 
GuC")
Cc: John Harrison 
Cc: Matthew Brost 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: Tvrtko Ursulin 
Cc: Daniele Ceraolo Spurio 
Cc: Matt Roper 
Cc: Umesh Nerlige Ramappa 
Cc: Michael Cheng 
Cc: Lucas De Marchi 
Cc: Tejas Upadhyay 
Cc: Chris Wilson 
Cc: Bruce Chang 
Cc: Alan Previn 
Cc: Matthew Auld 
Cc: intel-gfx@lists.freedesktop.org
Signed-off-by: John Harrison 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 11 +++
  1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index b436dd7f12e42..3b34a82d692be 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -4820,6 +4820,8 @@ void intel_guc_find_hung_context(struct intel_engine_cs 
*engine)
  
  	xa_lock_irqsave(>context_lookup, flags);

xa_for_each(>context_lookup, index, ce) {
+   bool found;
+
if (!kref_get_unless_zero(>ref))
continue;
  
@@ -4836,10 +4838,18 @@ void intel_guc_find_hung_context(struct intel_engine_cs *engine)

goto next;
}
  
+		found = false;

+   spin_lock(>guc_state.lock);
list_for_each_entry(rq, >guc_state.requests, sched.link) {
if (i915_test_request_state(rq) != I915_REQUEST_ACTIVE)
continue;
  
+			found = true;

+   break;
+   }
+   spin_unlock(>guc_state.lock);
+
+   if (found) {
intel_engine_set_hung_context(engine, ce);
  
  			/* Can only cope with one hang at a time... */

@@ -4847,6 +4857,7 @@ void intel_guc_find_hung_context(struct intel_engine_cs 
*engine)
xa_lock(>context_lookup);
goto done;
}
+
  next:
intel_context_put(ce);
xa_lock(>context_lookup);




Re: [Intel-gfx] [PATCH 2/2] drm/i915/guc: Fix missing return code checks in submission init

2023-01-24 Thread Ceraolo Spurio, Daniele




On 1/11/2023 5:54 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

The CI results for the 'fast request' patch set (enables error return
codes for fire-and-forget H2G messages) hit an issue with the KMD
sending context submission requests on an invalid context. That was
caused by a fault injection probe failing the context creation of a
kernel context. However, there was no return code checking on any of
the kernel context registration paths. So the driver kept going and
tried to use the kernel context for the record defaults process.

This would not cause any actual problems. The invalid requests would
be rejected by GuC and ultimately the start up sequence would
correctly wedge due to the context creation failure. But fixing the
issue correctly rather ignoring it means we won't get CI complaining
when the fast request patch lands and enables the extra error checking.

So fix it by checking for errors and aborting as appropriate when
creating kernel contexts. While at it, clean up some other submission
init related failure cleanup paths. Also, rename guc_init_lrc_mapping
to guc_init_submission as the former name hasn't been valid in a long
time.

Signed-off-by: John Harrison 
---
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 91 ++-
  .../gpu/drm/i915/gt/uc/intel_guc_submission.h |  2 +-
  drivers/gpu/drm/i915/gt/uc/intel_uc.c |  7 +-
  3 files changed, 75 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 982364777d0c6..dd856fd92945b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1431,7 +1431,7 @@ static int guc_action_enable_usage_stats(struct intel_guc 
*guc)
return intel_guc_send(guc, action, ARRAY_SIZE(action));
  }
  
-static void guc_init_engine_stats(struct intel_guc *guc)

+static int guc_init_engine_stats(struct intel_guc *guc)
  {
struct intel_gt *gt = guc_to_gt(guc);
intel_wakeref_t wakeref;
@@ -1447,6 +1447,8 @@ static void guc_init_engine_stats(struct intel_guc *guc)
cancel_delayed_work_sync(>timestamp.work);
drm_err(>i915->drm, "Failed to enable usage stats: %d!\n", 
ret);
}
+
+   return ret;
  }
  
  static void guc_park_engine_stats(struct intel_guc *guc)

@@ -4108,9 +4110,11 @@ static void guc_set_default_submission(struct 
intel_engine_cs *engine)
engine->submit_request = guc_submit_request;
  }
  
-static inline void guc_kernel_context_pin(struct intel_guc *guc,

- struct intel_context *ce)
+static inline int guc_kernel_context_pin(struct intel_guc *guc,
+struct intel_context *ce)
  {
+   int ret;
+
/*
 * Note: we purposefully do not check the returns below because
 * the registration can only fail if a reset is just starting.
@@ -4118,16 +4122,24 @@ static inline void guc_kernel_context_pin(struct 
intel_guc *guc,
 * isn't happening and even it did this code would be run again.
 */
  
-	if (context_guc_id_invalid(ce))

-   pin_guc_id(guc, ce);
+   if (context_guc_id_invalid(ce)) {
+   int ret = pin_guc_id(guc, ce);


Why do you need a local ret variable inside this if statement, when you 
already have a function-level one? or is it just a cut & paste error?



+
+   if (ret < 0)
+   return ret;
+   }
  
  	if (!test_bit(CONTEXT_GUC_INIT, >flags))

guc_context_init(ce);
  
-	try_context_registration(ce, true);

+   ret = try_context_registration(ce, true);
+   if (ret)
+   unpin_guc_id(guc, ce);
+
+   return ret;
  }
  
-static inline void guc_init_lrc_mapping(struct intel_guc *guc)

+static inline int guc_init_submission(struct intel_guc *guc)
  {
struct intel_gt *gt = guc_to_gt(guc);
struct intel_engine_cs *engine;
@@ -4154,9 +4166,17 @@ static inline void guc_init_lrc_mapping(struct intel_guc 
*guc)
struct intel_context *ce;
  
  		list_for_each_entry(ce, >pinned_contexts_list,

-   pinned_contexts_link)
-   guc_kernel_context_pin(guc, ce);
+   pinned_contexts_link) {
+   int ret = guc_kernel_context_pin(guc, ce);
+
+   if (ret) {
+   /* No point in trying to clean up as i915 will 
wedge on failure */
+   return ret;
+   }
+   }
}
+
+   return 0;
  }
  
  static void guc_release(struct intel_engine_cs *engine)

@@ -4400,30 +4420,57 @@ static int guc_init_global_schedule_policy(struct 
intel_guc *guc)
return ret;
  }
  
-void intel_guc_submission_enable(struct intel_guc *guc)

+static void 

Re: [Intel-gfx] [PATCH 1/2] drm/i915/guc: Improve clean up of busyness stats worker

2023-01-24 Thread Ceraolo Spurio, Daniele




On 1/11/2023 5:54 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

The stats worker thread management was mis-matched between
enable/disable call sites. Fix those up. Also, abstract the cancel
code into a helper function rather than replicating in multiple places.

Signed-off-by: John Harrison 
---
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 22 ---
  1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index b436dd7f12e42..982364777d0c6 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1435,19 +1435,25 @@ static void guc_init_engine_stats(struct intel_guc *guc)
  {
struct intel_gt *gt = guc_to_gt(guc);
intel_wakeref_t wakeref;
+   int ret;
  
  	mod_delayed_work(system_highpri_wq, >timestamp.work,

 guc->timestamp.ping_delay);
  
-	with_intel_runtime_pm(>i915->runtime_pm, wakeref) {

-   int ret = guc_action_enable_usage_stats(guc);
+   with_intel_runtime_pm(>i915->runtime_pm, wakeref)
+   ret = guc_action_enable_usage_stats(guc);
  
-		if (ret)

-   drm_err(>i915->drm,
-   "Failed to enable usage stats: %d!\n", ret);
+   if (ret) {
+   cancel_delayed_work_sync(>timestamp.work);


Wouldn't it be easier to just call mod_delayed_work after the H2G if 
ret==0, instead of having it before and cancelling if we get a failure?



+   drm_err(>i915->drm, "Failed to enable usage stats: %d!\n", 
ret);
}
  }
  
+static void guc_park_engine_stats(struct intel_guc *guc)

+{
+   cancel_delayed_work_sync(>timestamp.work);
+}
+


Now you're asymmetric with the park/unpark, because on the park side you 
have this wrapper, while on the unpark side you directly call 
mod_delayed_work.


Daniele


  void intel_guc_busyness_park(struct intel_gt *gt)
  {
struct intel_guc *guc = >uc.guc;
@@ -1460,7 +1466,7 @@ void intel_guc_busyness_park(struct intel_gt *gt)
 * and causes an unclaimed register access warning. Cancel the worker
 * synchronously here.
 */
-   cancel_delayed_work_sync(>timestamp.work);
+   guc_park_engine_stats(guc);
  
  	/*

 * Before parking, we should sample engine busyness stats if we need to.
@@ -4409,11 +4415,11 @@ void intel_guc_submission_enable(struct intel_guc *guc)
guc_init_global_schedule_policy(guc);
  }
  
+/* Note: By the time we're here, GuC may have already been reset */

  void intel_guc_submission_disable(struct intel_guc *guc)
  {
struct intel_gt *gt = guc_to_gt(guc);
-
-   /* Note: By the time we're here, GuC may have already been reset */
+   guc_park_engine_stats(guc);
  
  	/* Disable and route to host */

if (GRAPHICS_VER(gt->i915) >= 12)




Re: [Intel-gfx] [PATCH v4 7/7] drm/i915/guc: Rename GuC register state capture node to be more obvious

2023-01-24 Thread Ceraolo Spurio, Daniele




On 1/20/2023 3:28 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

The GuC specific register state entry in the error capture object was
just called 'capture'. Although the companion 'node' entry was called
'guc_capture_node'. Rename the base entry to be 'guc_capture' instead
so that it is a) more consistent and b) more obvious what it is.

Signed-off-by: John Harrison 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c | 8 
  drivers/gpu/drm/i915/i915_gpu_error.h  | 2 +-
  2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
index 1c1b85073b4bd..fc3b994626a4f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
@@ -1506,7 +1506,7 @@ int intel_guc_capture_print_engine_node(struct 
drm_i915_error_state_buf *ebuf,
  
  	if (!ebuf || !ee)

return -EINVAL;
-   cap = ee->capture;
+   cap = ee->guc_capture;
if (!cap || !ee->engine)
return -ENODEV;
  
@@ -1576,8 +1576,8 @@ void intel_guc_capture_free_node(struct intel_engine_coredump *ee)

if (!ee || !ee->guc_capture_node)
return;
  
-	guc_capture_add_node_to_cachelist(ee->capture, ee->guc_capture_node);

-   ee->capture = NULL;
+   guc_capture_add_node_to_cachelist(ee->guc_capture, 
ee->guc_capture_node);
+   ee->guc_capture = NULL;
ee->guc_capture_node = NULL;
  }
  
@@ -1611,7 +1611,7 @@ void intel_guc_capture_get_matching_node(struct intel_gt *gt,

(ce->lrc.lrca & CTX_GTT_ADDRESS_MASK)) {
list_del(>link);
ee->guc_capture_node = n;
-   ee->capture = guc->capture;
+   ee->guc_capture = guc->capture;
return;
}
}
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h 
b/drivers/gpu/drm/i915/i915_gpu_error.h
index efc75cc2ffdb9..56027ffbce51f 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.h
+++ b/drivers/gpu/drm/i915/i915_gpu_error.h
@@ -94,7 +94,7 @@ struct intel_engine_coredump {
struct intel_instdone instdone;
  
  	/* GuC matched capture-lists info */

-   struct intel_guc_state_capture *capture;
+   struct intel_guc_state_capture *guc_capture;
struct __guc_capture_parsed_output *guc_capture_node;
  
  	struct i915_gem_context_coredump {




Re: [Intel-gfx] [PATCH v4 3/7] drm/i915: Allow error capture without a request

2023-01-24 Thread Ceraolo Spurio, Daniele




On 1/20/2023 3:28 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

There was a report of error captures occurring without any hung
context being indicated despite the capture being initiated by a 'hung
context notification' from GuC. The problem was not reproducible.
However, it is possible to happen if the context in question has no
active requests. For example, if the hang was in the context switch
itself then the breadcrumb write would have occurred and the KMD would
see an idle context.

In the interests of attempting to provide as much information as
possible about a hang, it seems wise to include the engine info
regardless of whether a request was found or not. As opposed to just
prentending there was no hang at all.

So update the error capture code to always record engine information
if a context is given. Which means updating record_context() to take a
context instead of a request (which it only ever used to find the
context anyway). And split the request agnostic parts of
intel_engine_coredump_add_request() out into a seaprate function.

v2: Remove a duplicate 'if' statement (Umesh) and fix a put of a null
pointer.
v3: Tidy up request locking code flow (Tvrtko)
v4: Pull in improved info message from next patch and fix up potential
leak of GuC register state (Daniele)


In the very unlikely case that the capture fails, we're leaving the data 
inside the GuC buffer. This is not new with this patch and not a bug 
(that buffer is a ring and the stale data will be overwritten if it gets 
full), but maybe something that can be improved as a follow-up.


Reviewed-by: Daniele Ceraolo Spurio 

Daniele



Signed-off-by: John Harrison 
Reviewed-by: Umesh Nerlige Ramappa 
Acked-by: Tvrtko Ursulin 
---
  drivers/gpu/drm/i915/i915_gpu_error.c | 74 ++-
  1 file changed, 50 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
b/drivers/gpu/drm/i915/i915_gpu_error.c
index b20bd6365615b..225f1b11a6b93 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1370,14 +1370,14 @@ static void engine_record_execlists(struct 
intel_engine_coredump *ee)
  }
  
  static bool record_context(struct i915_gem_context_coredump *e,

-  const struct i915_request *rq)
+  struct intel_context *ce)
  {
struct i915_gem_context *ctx;
struct task_struct *task;
bool simulated;
  
  	rcu_read_lock();

-   ctx = rcu_dereference(rq->context->gem_context);
+   ctx = rcu_dereference(ce->gem_context);
if (ctx && !kref_get_unless_zero(>ref))
ctx = NULL;
rcu_read_unlock();
@@ -1396,8 +1396,8 @@ static bool record_context(struct 
i915_gem_context_coredump *e,
e->guilty = atomic_read(>guilty_count);
e->active = atomic_read(>active_count);
  
-	e->total_runtime = intel_context_get_total_runtime_ns(rq->context);

-   e->avg_runtime = intel_context_get_avg_runtime_ns(rq->context);
+   e->total_runtime = intel_context_get_total_runtime_ns(ce);
+   e->avg_runtime = intel_context_get_avg_runtime_ns(ce);
  
  	simulated = i915_gem_context_no_error_capture(ctx);
  
@@ -1532,15 +1532,37 @@ intel_engine_coredump_alloc(struct intel_engine_cs *engine, gfp_t gfp, u32 dump_

return ee;
  }
  
+static struct intel_engine_capture_vma *

+engine_coredump_add_context(struct intel_engine_coredump *ee,
+   struct intel_context *ce,
+   gfp_t gfp)
+{
+   struct intel_engine_capture_vma *vma = NULL;
+
+   ee->simulated |= record_context(>context, ce);
+   if (ee->simulated)
+   return NULL;
+
+   /*
+* We need to copy these to an anonymous buffer
+* as the simplest method to avoid being overwritten
+* by userspace.
+*/
+   vma = capture_vma(vma, ce->ring->vma, "ring", gfp);
+   vma = capture_vma(vma, ce->state, "HW context", gfp);
+
+   return vma;
+}
+
  struct intel_engine_capture_vma *
  intel_engine_coredump_add_request(struct intel_engine_coredump *ee,
  struct i915_request *rq,
  gfp_t gfp)
  {
-   struct intel_engine_capture_vma *vma = NULL;
+   struct intel_engine_capture_vma *vma;
  
-	ee->simulated |= record_context(>context, rq);

-   if (ee->simulated)
+   vma = engine_coredump_add_context(ee, rq->context, gfp);
+   if (!vma)
return NULL;
  
  	/*

@@ -1550,8 +1572,6 @@ intel_engine_coredump_add_request(struct 
intel_engine_coredump *ee,
 */
vma = capture_vma_snapshot(vma, rq->batch_res, gfp, "batch");
vma = capture_user(vma, rq, gfp);
-   vma = capture_vma(vma, rq->ring->vma, "ring", gfp);
-   vma = capture_vma(vm

Re: [Intel-gfx] [PATCH v4 2/7] drm/i915: Fix up locking around dumping requests lists

2023-01-24 Thread Ceraolo Spurio, Daniele
 i915_reset_count(error));
print_properties(engine, m);
  
-	spin_lock_irqsave(>sched_engine->lock, flags);

engine_dump_active_requests(engine, m);
  
-	drm_printf(m, "\tOn hold?: %lu\n",

-  list_count(>sched_engine->hold));
-   spin_unlock_irqrestore(>sched_engine->lock, flags);
-
drm_printf(m, "\tMMIO base:  0x%08x\n", engine->mmio_base);
wakeref = intel_runtime_pm_get_if_in_use(engine->uncore->rpm);
if (wakeref) {
@@ -2352,8 +2326,7 @@ intel_engine_create_virtual(struct intel_engine_cs 
**siblings,
return siblings[0]->cops->create_virtual(siblings, count, flags);
  }
  
-struct i915_request *

-intel_engine_execlist_find_hung_request(struct intel_engine_cs *engine)
+static struct i915_request *engine_execlist_find_hung_request(struct 
intel_engine_cs *engine)
  {
struct i915_request *request, *active = NULL;
  
@@ -2405,6 +2378,33 @@ intel_engine_execlist_find_hung_request(struct intel_engine_cs *engine)

return active;
  }
  
+void intel_engine_get_hung_entity(struct intel_engine_cs *engine,

+ struct intel_context **ce, struct 
i915_request **rq)
+{
+   unsigned long flags;
+
+   *ce = intel_engine_get_hung_context(engine);
+   if (*ce) {
+   intel_engine_clear_hung_context(engine);
+
+   *rq = intel_context_find_active_request_get(*ce);
+   return;
+   }
+
+   /*
+* Getting here with GuC enabled means it is a forced error capture
+* with no actual hang. So, no need to attempt the execlist search.
+*/
+   if (intel_uc_uses_guc_submission(>gt->uc))
+   return;
+
+   spin_lock_irqsave(>sched_engine->lock, flags);
+   *rq = engine_execlist_find_hung_request(engine);
+   if (*rq)
+   *rq = i915_request_get_rcu(*rq);
+   spin_unlock_irqrestore(>sched_engine->lock, flags);
+}
+
  void xehp_enable_ccs_engines(struct intel_engine_cs *engine)
  {
/*
diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c 
b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
index 18ffe55282e59..05995c8577bef 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -4150,6 +4150,33 @@ void intel_execlists_show_requests(struct 
intel_engine_cs *engine,
spin_unlock_irqrestore(_engine->lock, flags);
  }
  
+static unsigned long list_count(struct list_head *list)

+{
+   struct list_head *pos;
+   unsigned long count = 0;
+
+   list_for_each(pos, list)
+   count++;
+
+   return count;
+}
+
+void intel_execlist_dump_active_requests(struct intel_engine_cs *engine,


nit: we usually use "execlists" and not "execlist".
Apart from this the patch LGTM.

Reviewed-by: Daniele Ceraolo Spurio 

Daniele


+struct i915_request *hung_rq,
+struct drm_printer *m)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(>sched_engine->lock, flags);
+
+   intel_engine_dump_active_requests(>sched_engine->requests, 
hung_rq, m);
+
+   drm_printf(m, "\tOn hold?: %lu\n",
+  list_count(>sched_engine->hold));
+
+   spin_unlock_irqrestore(>sched_engine->lock, flags);
+}
+
  #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
  #include "selftest_execlists.c"
  #endif
diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.h 
b/drivers/gpu/drm/i915/gt/intel_execlists_submission.h
index a1aa92c983a51..cb07488a03764 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.h
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.h
@@ -32,6 +32,10 @@ void intel_execlists_show_requests(struct intel_engine_cs 
*engine,
int indent),
   unsigned int max);
  
+void intel_execlist_dump_active_requests(struct intel_engine_cs *engine,

+struct i915_request *hung_rq,
+struct drm_printer *m);
+
  bool
  intel_engine_in_execlists_submission_mode(const struct intel_engine_cs 
*engine);
  
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c

index 5c73dfa2fb3f6..b20bd6365615b 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1596,35 +1596,15 @@ capture_engine(struct intel_engine_cs *engine,
  {
struct intel_engine_capture_vma *capture = NULL;
struct intel_engine_coredump *ee;
-   struct intel_context *ce;
+   struct intel_context *ce = NULL;
struct i915_request *rq = NULL;
-   unsigned long flags;
  
  	ee = intel_engine_coredump_alloc(engine, ALLOW_FAIL, du

  1   2   3   4   >