@@ -140,6 +140,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);
@@ -190,9 +230,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);
@@ -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);
@@ -673,6 +673,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.
@@ -38,6 +38,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,
@@ -102,6 +107,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,
@@ -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");
@@ -152,6 +153,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;
}
@@ -203,3 +214,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;
+}
@@ -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__ */