diff mbox series

[20/27] drm/i915/pxp: Create the arbitrary session after boot

Message ID 20201115210815.5272-20-sean.z.huang@intel.com (mailing list archive)
State New, archived
Headers show
Series [01/27] drm/i915/pxp: Introduce Intel PXP component | expand

Commit Message

Huang, Sean Z Nov. 15, 2020, 9:08 p.m. UTC
Create the arbitrary session, with the fixed session id 0xf, after
system boot, for the case that application allocates the protected
buffer without establishing any protection session. Because the
hardware requires at least one alive session for protected buffer
creation.  This arbitrary session needs to be re-created after
teardown or power event because hardware encryption key won't be
valid after such cases.

Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com>
---
 drivers/gpu/drm/i915/pxp/intel_pxp.c     | 50 +++++++++++++++++++++++-
 drivers/gpu/drm/i915/pxp/intel_pxp.h     |  2 +
 drivers/gpu/drm/i915/pxp/intel_pxp_sm.c  | 33 ++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_sm.h  |  6 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 34 ++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h |  6 +++
 6 files changed, 130 insertions(+), 1 deletion(-)

Comments

Joonas Lahtinen Nov. 16, 2020, 10:54 a.m. UTC | #1
Quoting Huang, Sean Z (2020-11-15 23:08:08)
> Create the arbitrary session, with the fixed session id 0xf, after
> system boot, for the case that application allocates the protected
> buffer without establishing any protection session. Because the
> hardware requires at least one alive session for protected buffer
> creation.  This arbitrary session needs to be re-created after
> teardown or power event because hardware encryption key won't be
> valid after such cases.
> 
> Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com>

<SNIP>

> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h
> @@ -16,4 +16,10 @@ int pxp_tee_ioctl_io_message(struct drm_i915_private *i915,
>                              void __user *msg_out_user_ptr, u32 *msg_out_size_ptr,
>                              u32 msg_out_buf_size);
>  
> +int intel_pxp_tee_cmd_create_arb_session(struct drm_i915_private *i915);
> +
> +/* TEE command to create the arbitrary session */
> +#define PXP_TEE_ARB_CMD_BIN  {0x00040000, 0x0000001e, 0x00000000, 0x00000008, 0x00000002, 0x0000000f}
> +#define PXP_TEE_ARB_CMD_DW_LEN (6)

This is a BLOB so it doesn't belong to kernel source code. It could be
considered in linux-firmware. As it's only an init sequence I'm not sure
how that will be perceived.

Probably best to ask.

Regards, Joonas
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index d0df35d99e37..5251cc628fb0 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -133,6 +133,46 @@  int intel_pxp_close(struct drm_i915_private *i915, struct drm_file *drmfile)
 	return ret;
 }
 
+int intel_pxp_create_arb_session(struct drm_i915_private *i915)
+{
+	struct pxp_tag pxptag;
+	int ret;
+
+	drm_dbg(&i915->drm, ">>> %s\n", __func__);
+
+	lockdep_assert_held(&i915->pxp.r0ctx->ctx_mutex);
+
+	if (i915->pxp.r0ctx->flag_display_hm_surface_keys) {
+		drm_dbg(&i915->drm, "%s: arb session is alive so skipping the creation\n",
+			__func__);
+		return 0;
+	}
+
+	ret = intel_pxp_sm_reserve_arb_session(i915, &pxptag.value);
+	if (ret) {
+		drm_dbg(&i915->drm, "Failed to reserve session\n");
+		goto end;
+	}
+
+	ret = intel_pxp_tee_cmd_create_arb_session(i915);
+	if (ret) {
+		drm_dbg(&i915->drm, "Failed to send tee cmd for arb session creation\n");
+		goto end;
+	}
+
+	ret = pxp_sm_mark_protected_session_in_play(i915, ARB_SESSION_TYPE, pxptag.session_id);
+	if (ret) {
+		drm_dbg(&i915->drm, "Failed to mark session status in play\n");
+		goto end;
+	}
+
+	i915->pxp.r0ctx->flag_display_hm_surface_keys = true;
+
+end:
+	drm_dbg(&i915->drm, "<<< %s ret=[%d]\n", __func__, ret);
+	return ret;
+}
+
 static void intel_pxp_write_irq_mask_reg(struct drm_i915_private *i915, u32 mask)
 {
 	WARN_ON(INTEL_GEN(i915) < 11);
@@ -183,9 +223,17 @@  static int intel_pxp_global_terminate_complete_callback(struct drm_i915_private
 
 	mutex_lock(&i915->pxp.r0ctx->ctx_mutex);
 
-	if (i915->pxp.r0ctx->global_state_attacked)
+	if (i915->pxp.r0ctx->global_state_attacked) {
 		i915->pxp.r0ctx->global_state_attacked = false;
 
+		/* Re-create the arb session after teardown handle complete */
+		ret = intel_pxp_create_arb_session(i915);
+		if (ret) {
+			drm_dbg(&i915->drm, "Failed to create arb session\n");
+			goto end;
+		}
+	}
+end:
 	mutex_unlock(&i915->pxp.r0ctx->ctx_mutex);
 
 	drm_dbg(&i915->drm, "<<< %s ret=[%d]\n", __func__, ret);
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index 2c16ed0b5c0b..c0119ccdab08 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -102,6 +102,8 @@  struct drm_i915_private;
 
 int i915_pxp_ops_ioctl(struct drm_device *dev, void *data, struct drm_file *drmfile);
 int intel_pxp_close(struct drm_i915_private *i915, struct drm_file *drmfile);
+int intel_pxp_create_arb_session(struct drm_i915_private *i915);
+
 void intel_pxp_irq_handler(struct intel_gt *gt, u16 iir);
 int i915_pxp_teardown_required_callback(struct drm_i915_private *i915);
 int i915_pxp_global_terminate_complete_callback(struct drm_i915_private *i915);
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_sm.c b/drivers/gpu/drm/i915/pxp/intel_pxp_sm.c
index ec28eb5d77e5..5777e5550871 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_sm.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_sm.c
@@ -656,6 +656,39 @@  int intel_pxp_sm_reserve_session(struct drm_i915_private *i915, struct drm_file
 	return ret;
 }
 
+int intel_pxp_sm_reserve_arb_session(struct drm_i915_private *i915, u32 *pxp_tag)
+{
+	int ret;
+
+	drm_dbg(&i915->drm, ">>> %s\n", __func__);
+
+	lockdep_assert_held(&i915->pxp.r0ctx->ctx_mutex);
+
+	if (!pxp_tag || !i915) {
+		ret = -EINVAL;
+		drm_dbg(&i915->drm, "Failed to %s, bad params\n", __func__);
+		goto end;
+	}
+
+	ret = sync_hw_sw_state(i915, ARB_SESSION_INDEX, ARB_SESSION_TYPE);
+	if (unlikely(ret))
+		goto end;
+
+	ret = create_new_session_entry(i915, NULL, 0, ARB_SESSION_TYPE,
+				       ARB_PROTECTION_MODE, ARB_SESSION_INDEX);
+	if (unlikely(ret))
+		goto end;
+
+	ret = pxp_set_pxp_tag(i915, ARB_SESSION_TYPE, ARB_SESSION_INDEX, ARB_PROTECTION_MODE);
+
+end:
+	if (ret == 0)
+		*pxp_tag = intel_pxp_get_pxp_tag(i915, ARB_SESSION_INDEX, ARB_SESSION_TYPE, NULL);
+
+	drm_dbg(&i915->drm, "<<< %s ret=[%d]\n", __func__, ret);
+	return ret;
+}
+
 /**
  * pxp_sm_mark_protected_session_in_play - To put an reserved protected session to "in_play" state
  * @i915: i915 device handle.
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_sm.h b/drivers/gpu/drm/i915/pxp/intel_pxp_sm.h
index 143f024bb0d2..f715e348ded1 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_sm.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_sm.h
@@ -39,6 +39,11 @@ 
 /* CRYPTO_KEY_EXCHANGE */
 #define CRYPTO_KEY_EXCHANGE ((0x3 << 29) | (0x01609 << 16))
 
+/* Arbitrary session */
+#define ARB_SESSION_INDEX 0xf
+#define ARB_SESSION_TYPE SESSION_TYPE_TYPE0
+#define ARB_PROTECTION_MODE PROTECTION_MODE_HM
+
 enum pxp_session_types {
 	SESSION_TYPE_TYPE0 = 0,
 	SESSION_TYPE_TYPE1 = 1,
@@ -103,6 +108,7 @@  struct pxp_protected_session {
 int intel_pxp_sm_reserve_session(struct drm_i915_private *i915, struct drm_file *drmfile,
 				 int context_id, int session_type, int protection_mode,
 				 u32 *pxp_tag);
+int intel_pxp_sm_reserve_arb_session(struct drm_i915_private *i915, u32 *pxp_tag);
 int pxp_sm_mark_protected_session_in_play(struct drm_i915_private *i915, int session_type,
 					  u32 session_id);
 int pxp_sm_terminate_protected_session_safe(struct drm_i915_private *i915, int context_id,
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index 65ca495a6242..78f9cd6e0a10 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -138,6 +138,7 @@  int pxp_tee_ioctl_io_message(struct drm_i915_private *i915,
 static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 				       struct device *tee_kdev, void *data)
 {
+	int ret;
 	struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
 
 	drm_dbg(&i915->drm, "i915 PXP TEE component bind\n");
@@ -150,6 +151,16 @@  static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 	i915->pxp_tee_master->tee_dev = tee_kdev;
 	mutex_unlock(&i915->pxp_tee_comp_mutex);
 
+	mutex_lock(&i915->pxp.r0ctx->ctx_mutex);
+	/* Create arb session only if tee is ready, during system boot or sleep/resume */
+	ret = intel_pxp_create_arb_session(i915);
+	mutex_unlock(&i915->pxp.r0ctx->ctx_mutex);
+
+	if (ret) {
+		drm_dbg(&i915->drm, "Failed to create arb session ret=[%d]\n", ret);
+		return ret;
+	}
+
 	return 0;
 }
 
@@ -199,3 +210,26 @@  void intel_pxp_tee_component_fini(struct drm_i915_private *i915)
 
 	component_del(i915->drm.dev, &i915_pxp_tee_component_ops);
 }
+
+int intel_pxp_tee_cmd_create_arb_session(struct drm_i915_private *i915)
+{
+	int ret;
+	u32 msg_out_size_received = 0;
+	u32 msg_in[PXP_TEE_ARB_CMD_DW_LEN] = PXP_TEE_ARB_CMD_BIN;
+	u32 msg_out[PXP_TEE_ARB_CMD_DW_LEN] = {0};
+
+	mutex_lock(&i915->pxp_tee_comp_mutex);
+
+	ret = intel_pxp_tee_io_message(i915,
+				       &msg_in,
+				       sizeof(msg_in),
+				       &msg_out, &msg_out_size_received,
+				       sizeof(msg_out));
+
+	mutex_unlock(&i915->pxp_tee_comp_mutex);
+
+	if (ret)
+		drm_dbg(&i915->drm, "Failed to send/receive tee message\n");
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h
index 8b1581c2f50f..77403bdd4484 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h
@@ -16,4 +16,10 @@  int pxp_tee_ioctl_io_message(struct drm_i915_private *i915,
 			     void __user *msg_out_user_ptr, u32 *msg_out_size_ptr,
 			     u32 msg_out_buf_size);
 
+int intel_pxp_tee_cmd_create_arb_session(struct drm_i915_private *i915);
+
+/* TEE command to create the arbitrary session */
+#define PXP_TEE_ARB_CMD_BIN  {0x00040000, 0x0000001e, 0x00000000, 0x00000008, 0x00000002, 0x0000000f}
+#define PXP_TEE_ARB_CMD_DW_LEN (6)
+
 #endif /* __INTEL_PXP_TEE_H__ */