All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Huang, Sean Z" <sean.z.huang@intel.com>
To: Intel-gfx@lists.freedesktop.org
Subject: [Intel-gfx] [RFC-v8 16/23] drm/i915/pxp: Implement ioctl action to terminate the session
Date: Fri, 11 Dec 2020 01:04:50 -0800	[thread overview]
Message-ID: <20201211090457.32674-17-sean.z.huang@intel.com> (raw)
In-Reply-To: <20201211090457.32674-1-sean.z.huang@intel.com>

Implement the PXP ioctl action to allow userspace driver to
terminate the hardware session and cleanup its software session
state. PXP sends the session termination command to GPU once
receves this ioctl action.

Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com>
---
 drivers/gpu/drm/i915/pxp/intel_pxp.c     |  10 +++
 drivers/gpu/drm/i915/pxp/intel_pxp.h     |   6 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c |  56 ++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h |   2 +
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.c  |   7 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_sm.c  | 109 ++++++++++++++++++++---
 drivers/gpu/drm/i915/pxp/intel_pxp_sm.h  |   6 ++
 7 files changed, 186 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index e000a78b782e..c35011b84f5a 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -8,6 +8,7 @@
 #include "intel_pxp_tee.h"
 #include "intel_pxp_arb.h"
 #include "intel_pxp_sm.h"
+#include "intel_pxp_cmd.h"
 
 /* KCR register definitions */
 #define KCR_INIT            _MMIO(0x320f0)
@@ -22,6 +23,8 @@ enum pxp_session_req {
 	PXP_REQ_SESSION_ID_INIT = 0x0,
 	/* Inform KMD that UMD has completed the initialization */
 	PXP_REQ_SESSION_IN_PLAY,
+	/* Request KMD to terminate the session */
+	PXP_REQ_SESSION_TERMINATE
 };
 
 /*
@@ -68,7 +71,11 @@ static int intel_pxp_teardown_required_callback(struct intel_pxp *pxp)
 	pxp->ctx.flag_display_hm_surface_keys = false;
 
 	ret = intel_pxp_arb_terminate_session(pxp);
+	if (ret)
+		goto end;
 
+	ret = intel_pxp_sm_terminate_all_sessions(pxp, SESSION_TYPE_TYPE0);
+end:
 	mutex_unlock(&pxp->ctx.mutex);
 
 	return ret;
@@ -237,6 +244,9 @@ int i915_pxp_ops_ioctl(struct drm_device *dev, void *data, struct drm_file *drmf
 		} else if (params->req_session_state == PXP_REQ_SESSION_IN_PLAY) {
 			ret = intel_pxp_sm_ioctl_mark_session_in_play(pxp, params->session_type,
 								      params->pxp_tag);
+		} else if (params->req_session_state == PXP_REQ_SESSION_TERMINATE) {
+			ret = intel_pxp_sm_ioctl_terminate_session(pxp, params->session_type,
+								   params->pxp_tag);
 		} else {
 			ret = -EINVAL;
 		}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index 461b9321441f..e68c035d8448 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -53,6 +53,12 @@ struct intel_pxp {
 	struct pxp_context ctx;
 };
 
+static inline int pxp_session_max(int session_type)
+{
+	return (session_type == SESSION_TYPE_TYPE0) ?
+		PXP_MAX_NORMAL_TYPE0_SESSIONS : PXP_MAX_TYPE1_SESSIONS;
+}
+
 struct drm_i915_private;
 
 #ifdef CONFIG_DRM_I915_PXP
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
index 17ff6bd61d20..3a4c8022a5d0 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
@@ -7,6 +7,7 @@
 #include "i915_drv.h"
 #include "gt/intel_context.h"
 #include "gt/intel_engine_pm.h"
+#include "intel_pxp_sm.h"
 
 /* PXP GPU command definitions */
 
@@ -270,3 +271,58 @@ int intel_pxp_cmd_add_inline_termination(u32 *cmd)
 	increased_size_in_dw = (cmd_termin - cmd);
 	return increased_size_in_dw;
 }
+
+int intel_pxp_cmd_terminate_all_hw_session(struct intel_pxp *pxp,
+					   int session_type)
+{
+	u32 *cmd = NULL;
+	u32 *cmd_ptr = NULL;
+	int cmd_size_in_dw = 0;
+	int ret;
+	int idx;
+	struct intel_gt *gt = container_of(pxp, struct intel_gt, pxp);
+
+	/* Calculate how many bytes need to be alloc */
+	for (idx = 0; idx < pxp_session_max(session_type); idx++) {
+		if (intel_pxp_sm_is_hw_session_in_play(pxp, session_type, idx)) {
+			cmd_size_in_dw += intel_pxp_cmd_add_prolog(pxp, NULL, session_type, idx);
+			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;
+	for (idx = 0; idx < pxp_session_max(session_type); idx++) {
+		if (intel_pxp_sm_is_hw_session_in_play(pxp, session_type, idx)) {
+			cmd_ptr += intel_pxp_cmd_add_prolog(pxp, cmd_ptr, session_type, idx);
+			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 pxp_submit_cmd()\n");
+		goto end;
+	}
+
+end:
+	kfree(cmd);
+	return ret;
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
index 087f260034c4..ba008aa5df4e 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
@@ -16,5 +16,7 @@ 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_terminate_all_hw_session(struct intel_pxp *pxp,
+					   int session_type);
 
 #endif /* __INTEL_PXP_SM_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
index 0da2ecbf3b4d..73ec5e47b485 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
@@ -6,6 +6,7 @@
 #include "intel_pxp_context.h"
 #include "intel_pxp_arb.h"
 #include "intel_pxp_pm.h"
+#include "intel_pxp_sm.h"
 
 void intel_pxp_pm_prepare_suspend(struct intel_pxp *pxp)
 {
@@ -55,6 +56,12 @@ int intel_pxp_pm_resume(struct intel_pxp *pxp)
 			goto end;
 		}
 
+		ret = intel_pxp_sm_terminate_all_sessions(pxp, SESSION_TYPE_TYPE0);
+		if (ret) {
+			drm_err(&gt->i915->drm, "Failed to terminate the sessions\n");
+			goto end;
+		}
+
 		pxp->ctx.global_state_in_suspend = false;
 	}
 
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_sm.c b/drivers/gpu/drm/i915/pxp/intel_pxp_sm.c
index a657c5c7f013..a94897768c41 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_sm.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_sm.c
@@ -6,6 +6,7 @@
 #include "gt/intel_engine_pm.h"
 #include "intel_pxp_sm.h"
 #include "intel_pxp.h"
+#include "intel_pxp_cmd.h"
 
 #define KCR_STATUS_1   _MMIO(0x320f4)
 #define KCR_STATUS_1_ATTACK_MASK 0x80000000
@@ -15,12 +16,6 @@
 #define SESSION_TYPE_MASK BIT(7)
 #define SESSION_ID_MASK (BIT(7) - 1)
 
-static inline int session_max(int session_type)
-{
-	return (session_type == SESSION_TYPE_TYPE0) ?
-		PXP_MAX_NORMAL_TYPE0_SESSIONS : PXP_MAX_TYPE1_SESSIONS;
-}
-
 static inline struct list_head *session_list(struct intel_pxp *pxp,
 					     int session_type)
 {
@@ -59,8 +54,8 @@ static bool is_sw_session_active(struct intel_pxp *pxp, int session_type,
 	return false;
 }
 
-static bool is_hw_session_in_play(struct intel_pxp *pxp,
-				  int session_type, int session_index)
+bool intel_pxp_sm_is_hw_session_in_play(struct intel_pxp *pxp,
+					int session_type, int session_index)
 {
 	u64 regval_sip = 0;
 	intel_wakeref_t wakeref;
@@ -83,7 +78,7 @@ static int wait_hw_sw_state(struct intel_pxp *pxp, int session_index, int sessio
 	int retry = 0;
 
 	for (retry = 0; retry < max_retry; retry++) {
-		if (is_hw_session_in_play(pxp, session_type, session_index) ==
+		if (intel_pxp_sm_is_hw_session_in_play(pxp, session_type, session_index) ==
 		    is_sw_session_active(pxp, session_type, session_index, true))
 			return 0;
 
@@ -162,6 +157,45 @@ static int pxp_get_session_index(u32 session_id, int *index_out, int *type_out)
 	return 0;
 }
 
+static int pxp_terminate_hw_session(struct intel_pxp *pxp, int session_type,
+				    int session_index)
+{
+	u32 *cmd = NULL;
+	u32 *cmd_ptr = NULL;
+	int cmd_size_in_dw = 0;
+	int ret;
+	struct intel_gt *gt = container_of(pxp, struct intel_gt, pxp);
+
+	cmd_size_in_dw += intel_pxp_cmd_add_prolog(pxp, NULL, session_type, 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;
+
+	cmd_ptr = cmd;
+	cmd_ptr += intel_pxp_cmd_add_prolog(pxp, cmd_ptr, session_type, 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;
+	}
+
+	ret = intel_pxp_cmd_submit(pxp, cmd, cmd_size_in_dw);
+	if (ret) {
+		drm_err(&gt->i915->drm, "Failed to submit cmd()\n");
+		goto end;
+	}
+
+end:
+	kfree(cmd);
+	return ret;
+}
+
 /**
  * intel_pxp_sm_ioctl_reserve_session - To reserve an available protected session.
  * @pxp: pointer to pxp struct
@@ -190,7 +224,7 @@ int intel_pxp_sm_ioctl_reserve_session(struct intel_pxp *pxp, struct drm_file *d
 	    is_type0_session_attacked(pxp))
 		return -EPERM;
 
-	for (idx = 0; idx < session_max(session_type); idx++) {
+	for (idx = 0; idx < pxp_session_max(session_type); idx++) {
 		if (!is_sw_session_active(pxp, session_type, idx, false)) {
 			ret = wait_hw_sw_state(pxp, idx, session_type);
 			if (ret)
@@ -243,3 +277,58 @@ int intel_pxp_sm_ioctl_mark_session_in_play(struct intel_pxp *pxp, int session_t
 	drm_err(&gt->i915->drm, "Failed to %s couldn't find active session\n", __func__);
 	return -EINVAL;
 }
+
+/**
+ * intel_pxp_sm_ioctl_terminate_session - To terminate an active HW session and free its entry.
+ * @pxp: pointer to pxp struct.
+ * @session_type: type of the session to be terminated. One of enum pxp_session_types.
+ * @session_id: Session identifier of the session, containing type and index info
+ *
+ * Return: 0 means terminate is successful, or didn't find the desired session.
+ */
+int intel_pxp_sm_ioctl_terminate_session(struct intel_pxp *pxp, int session_type,
+					 int session_id)
+{
+	int ret;
+	struct intel_pxp_sm_session *curr, *n;
+	int session_type_in_id;
+	int session_index;
+
+	lockdep_assert_held(&pxp->ctx.mutex);
+
+	ret = pxp_get_session_index(session_id, &session_index, &session_type_in_id);
+	if (ret)
+		return ret;
+
+	list_for_each_entry_safe(curr, n, session_list(pxp, session_type), list) {
+		if (curr->index == session_index) {
+			ret = pxp_terminate_hw_session(pxp, session_type, session_index);
+			if (ret)
+				return ret;
+
+			list_del(&curr->list);
+			kfree(curr);
+			return 0;
+		}
+	}
+	return 0;
+}
+
+int intel_pxp_sm_terminate_all_sessions(struct intel_pxp *pxp, int session_type)
+{
+	int ret;
+	struct intel_pxp_sm_session *curr, *n;
+
+	lockdep_assert_held(&pxp->ctx.mutex);
+
+	ret = intel_pxp_cmd_terminate_all_hw_session(pxp, session_type);
+	if (ret)
+		return ret;
+
+	list_for_each_entry_safe(curr, n, session_list(pxp, session_type), list) {
+		list_del(&curr->list);
+		kfree(curr);
+	}
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_sm.h b/drivers/gpu/drm/i915/pxp/intel_pxp_sm.h
index aaa44d365f39..e242b7566021 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_sm.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_sm.h
@@ -42,4 +42,10 @@ int intel_pxp_sm_ioctl_reserve_session(struct intel_pxp *pxp, struct drm_file *d
 				       u32 *pxp_tag);
 int intel_pxp_sm_ioctl_mark_session_in_play(struct intel_pxp *pxp, int session_type,
 					    u32 session_id);
+int intel_pxp_sm_ioctl_terminate_session(struct intel_pxp *pxp, int session_type,
+					 int session_id);
+
+bool intel_pxp_sm_is_hw_session_in_play(struct intel_pxp *pxp,
+					int session_type, int session_index);
+int intel_pxp_sm_terminate_all_sessions(struct intel_pxp *pxp, int session_type);
 #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

  parent reply	other threads:[~2020-12-11  9:05 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-11  9:04 [Intel-gfx] [RFC-v8 00/23] Introduce Intel PXP component - Mesa single session Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 01/23] drm/i915/pxp: Introduce Intel PXP component Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 02/23] drm/i915/pxp: set KCR reg init during the boot time Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 03/23] drm/i915/pxp: Implement funcs to create the TEE channel Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 04/23] drm/i915/pxp: Create the arbitrary session after boot Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 05/23] drm/i915/pxp: Func to send hardware session termination Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 06/23] drm/i915/pxp: Enable PXP irq worker and callback stub Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 07/23] drm/i915/pxp: Destroy arb session upon teardown Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 08/23] drm/i915/pxp: Enable PXP power management Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 09/23] drm/i915/pxp: Expose session state for display protection flip Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 10/23] mei: pxp: export pavp client to me client bus Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 11/23] drm/i915/uapi: introduce drm_i915_gem_create_ext Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 12/23] drm/i915/pxp: User interface for Protected buffer Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 13/23] drm/i915/pxp: Add plane decryption support Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 14/23] drm/i915/pxp: Implement ioctl action to reserve session slots Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 15/23] drm/i915/pxp: Implement ioctl action to set session in play Huang, Sean Z
2020-12-11  9:04 ` Huang, Sean Z [this message]
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 17/23] drm/i915/pxp: Implement ioctl action to send TEE commands Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 18/23] drm/i915/pxp: Implement ioctl action to query PXP tag Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 19/23] drm/i915/pxp: Termiante the session upon app crash Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 20/23] drm/i915/pxp: Add PXP-related registers into allowlist Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 21/23] mei: bus: add vtag support Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 22/23] mei: pxp: add vtag parameter to mei_pxp_send/receive interface Huang, Sean Z
2020-12-11  9:04 ` [Intel-gfx] [RFC-v8 23/23] drm/i915/pxp: Enable the PXP ioctl for protected session Huang, Sean Z
2020-12-11  9:36 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Introduce Intel PXP component - Mesa single session (rev8) Patchwork
2020-12-11  9:41 ` [Intel-gfx] ✗ Fi.CI.DOCS: " Patchwork
2020-12-11 10:05 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-12-11 11:12 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201211090457.32674-17-sean.z.huang@intel.com \
    --to=sean.z.huang@intel.com \
    --cc=Intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.