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@xxxxxxxxx> --- 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, ¶ms->session_is_alive, + ¶ms->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 e8adafa58a0e..4338d893088c 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_context.h +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_context.h @@ -8,6 +8,12 @@ #include <linux/mutex.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 */ @@ -19,6 +25,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 d9cf1c6e9ddf..003499aa9385 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_sm.h +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_sm.h @@ -45,6 +45,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 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx