[Intel-gfx] [RFC-v21 07/13] drm/i915/pxp: Destroy arb session upon teardown
Huang, Sean Z
sean.z.huang at intel.com
Sun Jan 17 06:45:42 UTC 2021
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
rev21:
- Bug fixing, we need to set the PXP_GLOBAL_TERMINATE 0x320f8
register after arb session termination
- Remove enum pxp_session_types and enum pxp_protection_modes from
single session patch series.
Signed-off-by: Huang, Sean Z <sean.z.huang at intel.com>
---
drivers/gpu/drm/i915/pxp/intel_pxp.c | 3 +
drivers/gpu/drm/i915/pxp/intel_pxp_arb.c | 86 ++++++++++++++++++
drivers/gpu/drm/i915/pxp/intel_pxp_arb.h | 1 +
drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c | 109 +++++++++++++++++++++--
drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h | 11 +--
5 files changed, 200 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 99cd93e12455..e6dd57ec73f5 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -29,6 +29,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_with_global_terminate(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 dd98ca407e78..cde5ddd73da9 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_arb.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_arb.c
@@ -10,9 +10,13 @@
#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 hwdrm session in play 0-31 */
+/* PXP global terminate register for session termination */
+#define PXP_GLOBAL_TERMINATE _MMIO(0x320f8)
+
/* Arbitrary session */
#define ARB_SESSION_INDEX 0xf
@@ -120,3 +124,85 @@ int intel_pxp_arb_create_session(struct intel_pxp *pxp)
return ret;
}
+
+static int intel_pxp_arb_session_terminate(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_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_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(>->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(>->i915->drm, "Failed to intel_pxp_cmd_submit()\n");
+ goto end;
+ }
+
+end:
+ kfree(cmd);
+ return ret;
+}
+
+/**
+ * intel_pxp_arb_terminate_session_with_global_terminate - Terminate the arb hw session.
+ * @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_with_global_terminate(struct intel_pxp *pxp)
+{
+ int ret;
+ struct intel_gt *gt = container_of(pxp, struct intel_gt, pxp);
+
+ lockdep_assert_held(&pxp->ctx.mutex);
+
+ /* terminate the hw sessions */
+ ret = intel_pxp_arb_session_terminate(pxp);
+ if (ret) {
+ drm_err(>->i915->drm, "Failed to intel_pxp_arb_session_terminate\n");
+ return ret;
+ }
+
+ pxp->ctx.arb_is_in_play = false;
+
+ ret = wait_arb_hw_sw_state(pxp);
+ if (ret) {
+ drm_err(>->i915->drm, "Failed to wait_arb_hw_sw_state\n");
+ return ret;
+ }
+
+ intel_uncore_write(gt->uncore, PXP_GLOBAL_TERMINATE, 1);
+
+ 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 2196153dd879..6b0622e8ba93 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_arb.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_arb.h
@@ -11,6 +11,7 @@
struct intel_pxp;
int intel_pxp_arb_create_session(struct intel_pxp *pxp);
+int intel_pxp_arb_terminate_session_with_global_terminate(struct intel_pxp *pxp);
bool intel_pxp_arb_session_is_in_play(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 6898b8826302..6a0fe50c1aeb 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
@@ -5,13 +5,29 @@
#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_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))
+
+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);
@@ -46,7 +62,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;
@@ -122,3 +139,85 @@ 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_index)
+{
+ u32 increased_size_in_dw = 0;
+ u32 *cmd_prolog = cmd;
+ const int cmd_prolog_size_in_dw = 10;
+
+ 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 */
+ *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);
+
+ 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..efd26e4987a4 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
@@ -9,10 +9,11 @@
#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_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
More information about the Intel-gfx
mailing list