[Intel-gfx] [RFC-v6 18/21] drm/i915/pxp: Implement ioctl action to query PXP tag

Huang, Sean Z sean.z.huang at intel.com
Thu Dec 10 22:38:56 UTC 2020


Enable the PXP ioctl action to allow userspace driver to query the
PXP tag, which is a 32-bit bitwise value indicating the current
session info, including protection type, session id, and whether
the session is enabled.

Signed-off-by: Huang, Sean Z <sean.z.huang at intel.com>
---
 drivers/gpu/drm/i915/pxp/intel_pxp.c         |  20 +++
 drivers/gpu/drm/i915/pxp/intel_pxp.h         |   6 -
 drivers/gpu/drm/i915/pxp/intel_pxp_context.h |   9 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_sm.c      | 130 ++++++++++++++++++-
 drivers/gpu/drm/i915/pxp/intel_pxp_sm.h      |   2 +
 5 files changed, 160 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 2445af5f763c..46ad2ab229c1 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -17,6 +17,7 @@
 #define KCR_INIT_ALLOW_DISPLAY_ME_WRITES (BIT(14) | (BIT(14) << KCR_INIT_MASK_SHIFT))
 
 enum pxp_ioctl_action {
+	PXP_ACTION_QUERY_PXP_TAG = 0,
 	PXP_ACTION_SET_SESSION_STATUS = 1,
 	PXP_ACTION_TEE_IO_MESSAGE = 4,
 };
@@ -30,6 +31,15 @@ enum pxp_session_req {
 	PXP_REQ_SESSION_TERMINATE
 };
 
+/*
+ * struct pxp_sm_query_pxp_tag - Params to query the PXP tag of specified
+ * session id and whether the session is alive from PXP state machine.
+ */
+struct pxp_sm_query_pxp_tag {
+	u32 session_is_alive;
+	u32 pxp_tag; /* in  - Session ID, out pxp tag */
+};
+
 /*
  * struct pxp_set_session_status_params - Params to reserved, set or destroy
  * the session from the PXP state machine.
@@ -58,6 +68,8 @@ struct pxp_info {
 	u32 sm_status; /* out - status output for this operation */
 
 	union {
+		/* in - action params to query PXP tag */
+		struct pxp_sm_query_pxp_tag query_pxp_tag;
 		/* in - action params to set the PXP session state */
 		struct pxp_set_session_status_params set_session_status;
 		/* in - action params to send TEE commands */
@@ -272,6 +284,14 @@ int i915_pxp_ops_ioctl(struct drm_device *dev, void *data, struct drm_file *drmf
 		}
 		break;
 	}
+	case PXP_ACTION_QUERY_PXP_TAG:
+	{
+		struct pxp_sm_query_pxp_tag *params = &pxp_info.query_pxp_tag;
+
+		ret = intel_pxp_sm_ioctl_query_pxp_tag(pxp, &params->session_is_alive,
+						       &params->pxp_tag);
+		break;
+	}
 	case PXP_ACTION_TEE_IO_MESSAGE:
 	{
 		struct pxp_tee_io_message_params *params = &pxp_info.tee_io_message;
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index e68c035d8448..133e3df9b1f6 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -16,12 +16,6 @@
 
 #define GEN12_KCR_SIP _MMIO(0x32260) /* KCR type0 session in play 0-31 */
 
-#define PXP_MAX_TYPE0_SESSIONS 16
-#define PXP_MAX_TYPE1_SESSIONS 6
-
-/* we need to reserve one type0 slot for arbitrary session */
-#define PXP_MAX_NORMAL_TYPE0_SESSIONS (PXP_MAX_TYPE0_SESSIONS - 1)
-
 enum pxp_session_types {
 	SESSION_TYPE_TYPE0 = 0,
 	SESSION_TYPE_TYPE1 = 1,
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_context.h b/drivers/gpu/drm/i915/pxp/intel_pxp_context.h
index 4c583f831831..ad9e278f3fb2 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_context.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_context.h
@@ -9,6 +9,12 @@
 #include <linux/mutex.h>
 #include "intel_pxp_arb.h"
 
+#define PXP_MAX_TYPE0_SESSIONS 16
+#define PXP_MAX_TYPE1_SESSIONS 6
+
+/* we need to reserve one type0 slot for arbitrary session */
+#define PXP_MAX_NORMAL_TYPE0_SESSIONS (PXP_MAX_TYPE0_SESSIONS - 1)
+
 /* struct pxp_context - Represents combined view of driver and logical HW states. */
 struct pxp_context {
 	/** @mutex: mutex to protect the pxp context */
@@ -20,6 +26,9 @@ struct pxp_context {
 	struct list_head type0_sessions;
 	struct list_head type1_sessions;
 
+	u32 type0_pxp_tag[PXP_MAX_NORMAL_TYPE0_SESSIONS];
+	u32 type1_pxp_tag[PXP_MAX_TYPE1_SESSIONS];
+
 	int id;
 
 	bool global_state_attacked;
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_sm.c b/drivers/gpu/drm/i915/pxp/intel_pxp_sm.c
index c18802010ef6..fd1dc1269c4e 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_sm.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_sm.c
@@ -16,6 +16,21 @@
 #define SESSION_TYPE_MASK BIT(7)
 #define SESSION_ID_MASK (BIT(7) - 1)
 
+struct pxp_tag {
+	union {
+		u32 value;
+		struct {
+			u32 session_id  : 8;
+			u32 instance_id : 8;
+			u32 enable      : 1;
+			u32 hm          : 1;
+			u32 reserved_1  : 1;
+			u32 sm          : 1;
+			u32 reserved_2  : 12;
+		};
+	};
+};
+
 static inline struct list_head *session_list(struct intel_pxp *pxp,
 					     int session_type)
 {
@@ -196,6 +211,80 @@ static int pxp_terminate_hw_session(struct intel_pxp *pxp, int session_type,
 	return ret;
 }
 
+static int pxp_set_pxp_tag(struct intel_pxp *pxp, int session_type,
+			   int session_idx, int protection_mode)
+{
+	struct pxp_tag *pxp_tag;
+
+	if (session_type == SESSION_TYPE_TYPE0 && session_idx < PXP_MAX_TYPE0_SESSIONS)
+		pxp_tag = (struct pxp_tag *)&pxp->ctx.type0_pxp_tag[session_idx];
+	else if (session_type == SESSION_TYPE_TYPE1 && session_idx < PXP_MAX_TYPE1_SESSIONS)
+		pxp_tag = (struct pxp_tag *)&pxp->ctx.type1_pxp_tag[session_idx];
+	else
+		return -EINVAL;
+
+	switch (protection_mode) {
+	case PROTECTION_MODE_NONE:
+	{
+		pxp_tag->enable = false;
+		pxp_tag->hm = false;
+		pxp_tag->sm = false;
+		break;
+	}
+	case PROTECTION_MODE_LM:
+	{
+		pxp_tag->enable = true;
+		pxp_tag->hm = false;
+		pxp_tag->sm = false;
+		pxp_tag->instance_id++;
+		break;
+	}
+	case PROTECTION_MODE_HM:
+	{
+		pxp_tag->enable = true;
+		pxp_tag->hm = true;
+		pxp_tag->sm = false;
+		pxp_tag->instance_id++;
+		break;
+	}
+	case PROTECTION_MODE_SM:
+	{
+		pxp_tag->enable = true;
+		pxp_tag->hm = true;
+		pxp_tag->sm = true;
+		pxp_tag->instance_id++;
+		break;
+	}
+	default:
+		return -EINVAL;
+	}
+
+	pxp_tag->session_id = session_idx & SESSION_ID_MASK;
+
+	if (session_type == SESSION_TYPE_TYPE1)
+		pxp_tag->session_id |= SESSION_TYPE_MASK;
+
+	return 0;
+}
+
+static u32 pxp_get_pxp_tag(struct intel_pxp *pxp, int session_type,
+			   int session_idx, u32 *session_is_alive)
+{
+	struct pxp_tag *pxp_tag;
+
+	if (session_type == SESSION_TYPE_TYPE0 && session_idx < PXP_MAX_TYPE0_SESSIONS)
+		pxp_tag = (struct pxp_tag *)&pxp->ctx.type0_pxp_tag[session_idx];
+	else if (session_type == SESSION_TYPE_TYPE1 && session_idx < PXP_MAX_TYPE1_SESSIONS)
+		pxp_tag = (struct pxp_tag *)&pxp->ctx.type1_pxp_tag[session_idx];
+	else
+		return -EINVAL;
+
+	if (session_is_alive)
+		*session_is_alive = pxp_tag->enable;
+
+	return pxp_tag->value;
+}
+
 /**
  * intel_pxp_sm_ioctl_reserve_session - To reserve an available protected session.
  * @pxp: pointer to pxp struct
@@ -233,7 +322,16 @@ int intel_pxp_sm_ioctl_reserve_session(struct intel_pxp *pxp, struct drm_file *d
 			ret = create_session_entry(pxp, drmfile, pxp->ctx.id,
 						   session_type,
 						   protection_mode, idx);
-			*pxp_tag = idx;
+			if (ret)
+				return ret;
+
+			ret = pxp_set_pxp_tag(pxp, session_type, idx,
+					      protection_mode);
+			if (ret)
+				return ret;
+
+			*pxp_tag = pxp_get_pxp_tag(pxp, session_type,
+						   idx, NULL);
 			return ret;
 		}
 	}
@@ -306,6 +404,11 @@ int intel_pxp_sm_ioctl_terminate_session(struct intel_pxp *pxp, int session_type
 			if (ret)
 				return ret;
 
+			ret = pxp_set_pxp_tag(pxp, session_type, session_index,
+					      PROTECTION_MODE_NONE);
+			if (ret)
+				return ret;
+
 			list_del(&curr->list);
 			kfree(curr);
 			return 0;
@@ -326,9 +429,34 @@ int intel_pxp_sm_terminate_all_sessions(struct intel_pxp *pxp, int session_type)
 		return ret;
 
 	list_for_each_entry(curr, session_list(pxp, session_type), list) {
+		ret = pxp_set_pxp_tag(pxp, session_type,
+				      curr->index, PROTECTION_MODE_NONE);
+		if (ret)
+			return ret;
+
 		list_del(&curr->list);
 		kfree(curr);
 	}
 
 	return ret;
 }
+
+int intel_pxp_sm_ioctl_query_pxp_tag(struct intel_pxp *pxp,
+				     u32 *session_is_alive, u32 *pxp_tag)
+{
+	int session_type = 0;
+	int session_index = 0;
+	int ret;
+
+	if (!session_is_alive || !pxp_tag)
+		return -EINVAL;
+
+	ret = pxp_get_session_index(*pxp_tag, &session_index, &session_type);
+	if (ret)
+		return ret;
+
+	*pxp_tag = pxp_get_pxp_tag(pxp, session_type, session_index,
+				   session_is_alive);
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_sm.h b/drivers/gpu/drm/i915/pxp/intel_pxp_sm.h
index e242b7566021..09a26bb7a1a4 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_sm.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_sm.h
@@ -44,6 +44,8 @@ int intel_pxp_sm_ioctl_mark_session_in_play(struct intel_pxp *pxp, int session_t
 					    u32 session_id);
 int intel_pxp_sm_ioctl_terminate_session(struct intel_pxp *pxp, int session_type,
 					 int session_id);
+int intel_pxp_sm_ioctl_query_pxp_tag(struct intel_pxp *pxp,
+				     u32 *session_is_alive, u32 *pxp_tag);
 
 bool intel_pxp_sm_is_hw_session_in_play(struct intel_pxp *pxp,
 					int session_type, int session_index);
-- 
2.17.1



More information about the Intel-gfx mailing list