Teardown is triggered when the display topology changes and no
long meets the secure playback requirement, and hardware trashes
all the encryption keys for display. So as a result, PXP should
handle such case and terminate the type0 sessions, which including
arb session

Signed-off-by: Huang, Sean Z <sean.z.hu...@intel.com>
---
 drivers/gpu/drm/i915/pxp/intel_pxp.c     |   3 +
 drivers/gpu/drm/i915/pxp/intel_pxp_arb.c |  76 +++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_arb.h |   1 +
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c | 130 ++++++++++++++++++++++-
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h |  12 ++-
 5 files changed, 212 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index f1bcfdc716ec..884e9c367911 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -28,6 +28,9 @@ static int intel_pxp_teardown_required_callback(struct 
intel_pxp *pxp)
        mutex_lock(&pxp->ctx.mutex);
 
        pxp->ctx.global_state_attacked = true;
+       pxp->ctx.flag_display_hm_surface_keys = false;
+
+       ret = intel_pxp_arb_terminate_session(pxp);
 
        mutex_unlock(&pxp->ctx.mutex);
 
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_arb.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_arb.c
index d3da72969349..54a5d7c26e4b 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_arb.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_arb.c
@@ -10,6 +10,7 @@
 #include "intel_pxp_arb.h"
 #include "intel_pxp.h"
 #include "intel_pxp_tee.h"
+#include "intel_pxp_cmd.h"
 
 #define GEN12_KCR_SIP _MMIO(0x32260) /* KCR type0 session in play 0-31 */
 
@@ -131,3 +132,78 @@ int intel_pxp_arb_create_session(struct intel_pxp *pxp)
 end:
        return ret;
 }
+
+static int intel_pxp_arb_session_with_global_termination(struct intel_pxp *pxp)
+{
+       u32 *cmd = NULL;
+       u32 *cmd_ptr = NULL;
+       int cmd_size_in_dw = 0;
+       int ret;
+       struct intel_gt *gt = container_of(pxp, typeof(*gt), pxp);
+
+       /* Calculate how many bytes need to be alloc */
+       cmd_size_in_dw += intel_pxp_cmd_add_prolog(pxp, NULL, ARB_SESSION_TYPE, 
ARB_SESSION_INDEX);
+       cmd_size_in_dw += intel_pxp_cmd_add_inline_termination(NULL);
+       cmd_size_in_dw += intel_pxp_cmd_add_epilog(NULL);
+
+       cmd = kzalloc(cmd_size_in_dw * 4, GFP_KERNEL);
+       if (!cmd)
+               return -ENOMEM;
+
+       /* Program the command */
+       cmd_ptr = cmd;
+       cmd_ptr += intel_pxp_cmd_add_prolog(pxp, cmd_ptr, ARB_SESSION_TYPE, 
ARB_SESSION_INDEX);
+       cmd_ptr += intel_pxp_cmd_add_inline_termination(cmd_ptr);
+       cmd_ptr += intel_pxp_cmd_add_epilog(cmd_ptr);
+
+       if (cmd_size_in_dw != (cmd_ptr - cmd)) {
+               ret = -EINVAL;
+               drm_err(&gt->i915->drm, "Failed to %s\n", __func__);
+               goto end;
+       }
+
+       if (drm_debug_enabled(DRM_UT_DRIVER)) {
+               print_hex_dump(KERN_DEBUG, "global termination cmd binaries:",
+                              DUMP_PREFIX_OFFSET, 4, 4, cmd, cmd_size_in_dw * 
4, true);
+       }
+
+       ret = intel_pxp_cmd_submit(pxp, cmd, cmd_size_in_dw);
+       if (ret) {
+               drm_err(&gt->i915->drm, "Failed to intel_pxp_cmd_submit()\n");
+               goto end;
+       }
+
+end:
+       kfree(cmd);
+       return ret;
+}
+
+/**
+ * intel_pxp_arb_terminate_session - Terminate the arb hw session and its 
entries.
+ * @pxp: pointer to pxp struct.
+ *
+ * This function is NOT intended to be called from the ioctl, and need to be 
protected by
+ * ctx.mutex to ensure no SIP change during the call.
+ *
+ * Return: status. 0 means terminate is successful.
+ */
+int intel_pxp_arb_terminate_session(struct intel_pxp *pxp)
+{
+       int ret;
+       struct intel_gt *gt = container_of(pxp, struct intel_gt, pxp);
+       struct pxp_protected_session *arb = &pxp->ctx.arb_session;
+
+       lockdep_assert_held(&pxp->ctx.mutex);
+
+       /* terminate the hw sessions */
+       ret = intel_pxp_arb_session_with_global_termination(pxp);
+       if (ret) {
+               drm_err(&gt->i915->drm, "Failed to 
intel_pxp_arb_session_with_global_termination\n");
+               return ret;
+       }
+
+       arb->is_in_play = false;
+
+       return ret;
+}
+
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_arb.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_arb.h
index 1eb8db6deb0e..c1ed4ab176aa 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_arb.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_arb.h
@@ -11,5 +11,6 @@
 struct intel_pxp;
 
 int intel_pxp_arb_create_session(struct intel_pxp *pxp);
+int intel_pxp_arb_terminate_session(struct intel_pxp *pxp);
 
 #endif /* __INTEL_PXP_ARB_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
index e86d914e7629..57eca04963a9 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
@@ -5,13 +5,33 @@
 
 #include "intel_pxp_cmd.h"
 #include "i915_drv.h"
+#include "gt/intel_gpu_commands.h"
 #include "gt/intel_context.h"
 #include "gt/intel_engine_pm.h"
 
-struct i915_vma *intel_pxp_cmd_get_batch(struct intel_pxp *pxp,
-                                        struct intel_context *ce,
-                                        struct intel_gt_buffer_pool_node *pool,
-                                        u32 *cmd_buf, int cmd_size_in_dw)
+/* PXP GPU command definitions */
+
+/* MI_SET_APPID */
+#define   MI_SET_APPID_TYPE1_APP        BIT(7)
+#define   MI_SET_APPID_SESSION_ID(x)    ((x) << 0)
+
+/* MI_FLUSH_DW */
+#define   MI_FLUSH_DW_DW0_PROTECTED_MEMORY_ENABLE   BIT(22)
+
+/* MI_WAIT */
+#define   MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG BIT(9)
+#define   MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG  BIT(8)
+
+/* CRYPTO_KEY_EXCHANGE */
+#define CRYPTO_KEY_EXCHANGE ((0x3 << 29) | (0x01609 << 16))
+
+#define PXP_MAX_TYPE0_SESSIONS 16
+#define PXP_MAX_TYPE1_SESSIONS 6
+
+static struct i915_vma *intel_pxp_cmd_get_batch(struct intel_pxp *pxp,
+                                               struct intel_context *ce,
+                                               struct 
intel_gt_buffer_pool_node *pool,
+                                               u32 *cmd_buf, int 
cmd_size_in_dw)
 {
        struct i915_vma *batch = ERR_PTR(-EINVAL);
        struct intel_gt *gt = container_of(pxp, struct intel_gt, pxp);
@@ -50,7 +70,8 @@ struct i915_vma *intel_pxp_cmd_get_batch(struct intel_pxp 
*pxp,
        return batch;
 }
 
-int intel_pxp_cmd_submit(struct intel_pxp *pxp, u32 *cmd, int cmd_size_in_dw)
+int intel_pxp_cmd_submit(struct intel_pxp *pxp, u32 *cmd,
+                        int cmd_size_in_dw)
 {
        int err = -EINVAL;
        struct i915_vma *batch;
@@ -157,3 +178,102 @@ int intel_pxp_cmd_submit(struct intel_pxp *pxp, u32 *cmd, 
int cmd_size_in_dw)
 
        return err;
 }
+
+int intel_pxp_cmd_add_prolog(struct intel_pxp *pxp, u32 *cmd,
+                            int session_type,
+                            int session_index)
+{
+       u32 increased_size_in_dw = 0;
+       u32 *cmd_prolog = cmd;
+       const int cmd_prolog_size_in_dw = 10;
+       struct intel_gt *gt = container_of(pxp, typeof(*gt), pxp);
+
+       if (!cmd)
+               return cmd_prolog_size_in_dw;
+
+       /* MFX_WAIT - stall until prior PXP and MFX/HCP/HUC objects are 
cmopleted */
+       *cmd_prolog++ = (MFX_WAIT | MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG |
+                        MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG);
+
+       /* MI_FLUSH_DW - pxp off */
+       *cmd_prolog++ = MI_FLUSH_DW;  /* DW0 */
+       *cmd_prolog++ = 0;            /* DW1 */
+       *cmd_prolog++ = 0;            /* DW2 */
+
+       /* MI_SET_APPID */
+       if (session_type == SESSION_TYPE_TYPE1) {
+               if (session_index >= PXP_MAX_TYPE1_SESSIONS) {
+                       drm_err(&gt->i915->drm, "Failed to %s invalid 
session_index\n", __func__);
+                       goto end;
+               }
+
+               *cmd_prolog++ = (MI_SET_APPID | MI_SET_APPID_TYPE1_APP |
+                                MI_SET_APPID_SESSION_ID(session_index));
+       } else {
+               if (session_index >= PXP_MAX_TYPE0_SESSIONS) {
+                       drm_err(&gt->i915->drm, "Failed to %s invalid 
session_index\n", __func__);
+                       goto end;
+               }
+
+               *cmd_prolog++ = (MI_SET_APPID | 
MI_SET_APPID_SESSION_ID(session_index));
+       }
+
+       /* MFX_WAIT */
+       *cmd_prolog++ = (MFX_WAIT | MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG |
+                        MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG);
+
+       /* MI_FLUSH_DW - pxp on */
+       *cmd_prolog++ = (MI_FLUSH_DW | 
MI_FLUSH_DW_DW0_PROTECTED_MEMORY_ENABLE); /* DW0 */
+       *cmd_prolog++ = 0;                                                      
 /* DW1 */
+       *cmd_prolog++ = 0;                                                      
 /* DW2 */
+
+       /* MFX_WAIT */
+       *cmd_prolog++ = (MFX_WAIT | MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG |
+                        MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG);
+
+       increased_size_in_dw = (cmd_prolog - cmd);
+end:
+       return increased_size_in_dw;
+}
+
+int intel_pxp_cmd_add_epilog(u32 *cmd)
+{
+       u32 increased_size_in_dw = 0;
+       u32 *cmd_epilog = cmd;
+       const int cmd_epilog_size_in_dw = 5;
+
+       if (!cmd)
+               return cmd_epilog_size_in_dw;
+
+       /* MI_FLUSH_DW - pxp off */
+       *cmd_epilog++ = MI_FLUSH_DW;  /* DW0 */
+       *cmd_epilog++ = 0;            /* DW1 */
+       *cmd_epilog++ = 0;            /* DW2 */
+
+       /* MFX_WAIT - stall until prior PXP and MFX/HCP/HUC objects are 
cmopleted */
+       *cmd_epilog++ = (MFX_WAIT | MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG |
+                        MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG);
+
+       /* MI_BATCH_BUFFER_END */
+       *cmd_epilog++ = MI_BATCH_BUFFER_END;
+
+       increased_size_in_dw = (cmd_epilog - cmd);
+       return increased_size_in_dw;
+}
+
+int intel_pxp_cmd_add_inline_termination(u32 *cmd)
+{
+       u32 increased_size_in_dw = 0;
+       u32 *cmd_termin = cmd;
+       const int cmd_termin_size_in_dw = 2;
+
+       if (!cmd)
+               return cmd_termin_size_in_dw;
+
+       /* CRYPTO_KEY_EXCHANGE - session inline termination */
+       *cmd_termin++ = CRYPTO_KEY_EXCHANGE; /* DW0 */
+       *cmd_termin++ = 0;                   /* DW1 */
+
+       increased_size_in_dw = (cmd_termin - cmd);
+       return increased_size_in_dw;
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
index d04463962421..087f260034c4 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
@@ -9,10 +9,12 @@
 #include "gt/intel_gt_buffer_pool.h"
 #include "intel_pxp.h"
 
-struct i915_vma *intel_pxp_cmd_get_batch(struct intel_pxp *pxp,
-                                        struct intel_context *ce,
-                                        struct intel_gt_buffer_pool_node *pool,
-                                        u32 *cmd_buf, int cmd_size_in_dw);
+int intel_pxp_cmd_submit(struct intel_pxp *pxp, u32 *cmd,
+                        int cmd_size_in_dw);
+int intel_pxp_cmd_add_prolog(struct intel_pxp *pxp, u32 *cmd,
+                            int session_type,
+                            int session_index);
+int intel_pxp_cmd_add_epilog(u32 *cmd);
+int intel_pxp_cmd_add_inline_termination(u32 *cmd);
 
-int intel_pxp_cmd_submit(struct intel_pxp *pxp, u32 *cmd, int cmd_size_in_dw);
 #endif /* __INTEL_PXP_SM_H__ */
-- 
2.17.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to