[Intel-gfx] [RFC-v3 07/13] drm/i915/pxp: Destroy arb session upon teardown
Joonas Lahtinen
joonas.lahtinen at linux.intel.com
Thu Dec 10 10:51:52 UTC 2020
Quoting Huang, Sean Z (2020-12-09 09:03:01)
> Teardown is triggered when the display topology changes and no
> long meets the secure playback requirement, and hardware trashes
> all the encryption keys for display. So as a result, PXP should
> handle such case and terminate the type0 sessions, which including
> arb session
We have only a single session, so this should be simplified to exactly
tear down that single session.
No need for any of the type0/type1 differentiation.
Regards, Joonas
> Signed-off-by: Huang, Sean Z <sean.z.huang at intel.com>
> ---
> drivers/gpu/drm/i915/pxp/intel_pxp.c | 3 +
> drivers/gpu/drm/i915/pxp/intel_pxp_arb.c | 76 +++++++++++++
> drivers/gpu/drm/i915/pxp/intel_pxp_arb.h | 1 +
> drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c | 129 ++++++++++++++++++++++-
> drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h | 12 ++-
> 5 files changed, 211 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> index 9bcb170b34f1..48e926363696 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> @@ -28,6 +28,9 @@ static int intel_pxp_teardown_required_callback(struct intel_pxp *pxp)
> mutex_lock(&pxp->ctx.mutex);
>
> pxp->ctx.global_state_attacked = true;
> + pxp->ctx.flag_display_hm_surface_keys = false;
> +
> + ret = intel_pxp_arb_terminate_session(pxp);
>
> mutex_unlock(&pxp->ctx.mutex);
>
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_arb.c b/drivers/gpu/drm/i915/pxp/intel_pxp_arb.c
> index c1ad45b83478..09148ca9035c 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_arb.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_arb.c
> @@ -10,6 +10,7 @@
> #include "intel_pxp.h"
> #include "intel_pxp_context.h"
> #include "intel_pxp_tee.h"
> +#include "intel_pxp_cmd.h"
>
> #define GEN12_KCR_SIP _MMIO(0x32260) /* KCR type0 session in play 0-31 */
>
> @@ -150,3 +151,78 @@ int intel_pxp_arb_create_session(struct intel_pxp *pxp)
> end:
> return ret;
> }
> +
> +static int intel_pxp_arb_session_with_global_termination(struct intel_pxp *pxp)
> +{
> + u32 *cmd = NULL;
> + u32 *cmd_ptr = NULL;
> + int cmd_size_in_dw = 0;
> + int ret;
> + struct intel_gt *gt = container_of(pxp, typeof(*gt), pxp);
> +
> + /* Calculate how many bytes need to be alloc */
> + cmd_size_in_dw += intel_pxp_cmd_add_prolog(pxp, NULL, ARB_SESSION_TYPE, ARB_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;
> +
> + /* Program the command */
> + cmd_ptr = cmd;
> + cmd_ptr += intel_pxp_cmd_add_prolog(pxp, cmd_ptr, ARB_SESSION_TYPE, ARB_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(>->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(>->i915->drm, "Failed to intel_pxp_cmd_submit()\n");
> + goto end;
> + }
> +
> +end:
> + kfree(cmd);
> + return ret;
> +}
> +
> +/**
> + * intel_pxp_arb_terminate_session - Terminate the arb hw session and its entries.
> + * @pxp: pointer to pxp struct.
> + *
> + * This function is NOT intended to be called from the ioctl, and need to be protected by
> + * ctx.mutex to ensure no SIP change during the call.
> + *
> + * Return: status. 0 means terminate is successful.
> + */
> +int intel_pxp_arb_terminate_session(struct intel_pxp *pxp)
> +{
> + int ret;
> + struct intel_gt *gt = container_of(pxp, struct intel_gt, pxp);
> + struct pxp_protected_session *arb = pxp->ctx.arb_session;
> +
> + lockdep_assert_held(&pxp->ctx.mutex);
> +
> + /* terminate the hw sessions */
> + ret = intel_pxp_arb_session_with_global_termination(pxp);
> + if (ret) {
> + drm_err(>->i915->drm, "Failed to intel_pxp_arb_session_with_global_termination\n");
> + return ret;
> + }
> +
> + kfree(arb);
> +
> + return ret;
> +}
> +
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_arb.h b/drivers/gpu/drm/i915/pxp/intel_pxp_arb.h
> index e410c0bbdcc3..d7b3b05a4314 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_arb.h
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_arb.h
> @@ -32,5 +32,6 @@ struct pxp_protected_session {
> };
>
> int intel_pxp_arb_create_session(struct intel_pxp *pxp);
> +int intel_pxp_arb_terminate_session(struct intel_pxp *pxp);
>
> #endif /* __INTEL_PXP_SM_H__ */
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
> index e531ea9f3cdc..f122c9a1f78e 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
> @@ -8,10 +8,29 @@
> #include "gt/intel_context.h"
> #include "gt/intel_engine_pm.h"
>
> -struct i915_vma *intel_pxp_cmd_get_batch(struct intel_pxp *pxp,
> - struct intel_context *ce,
> - struct intel_gt_buffer_pool_node *pool,
> - u32 *cmd_buf, int cmd_size_in_dw)
> +/* PXP GPU command definitions */
> +
> +/* MI_SET_APPID */
> +#define MI_SET_APPID_TYPE1_APP BIT(7)
> +#define MI_SET_APPID_SESSION_ID(x) ((x) << 0)
> +
> +/* MI_FLUSH_DW */
> +#define MI_FLUSH_DW_DW0_PROTECTED_MEMORY_ENABLE BIT(22)
> +
> +/* MI_WAIT */
> +#define MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG BIT(9)
> +#define MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG BIT(8)
> +
> +/* CRYPTO_KEY_EXCHANGE */
> +#define CRYPTO_KEY_EXCHANGE ((0x3 << 29) | (0x01609 << 16))
> +
> +#define MAX_TYPE0_SESSIONS 16
> +#define MAX_TYPE1_SESSIONS 6
> +
> +static struct i915_vma *intel_pxp_cmd_get_batch(struct intel_pxp *pxp,
> + struct intel_context *ce,
> + struct intel_gt_buffer_pool_node *pool,
> + u32 *cmd_buf, int cmd_size_in_dw)
> {
> struct i915_vma *batch = ERR_PTR(-EINVAL);
> struct intel_gt *gt = container_of(pxp, struct intel_gt, pxp);
> @@ -50,7 +69,8 @@ struct i915_vma *intel_pxp_cmd_get_batch(struct intel_pxp *pxp,
> return batch;
> }
>
> -int intel_pxp_cmd_submit(struct intel_pxp *pxp, u32 *cmd, int cmd_size_in_dw)
> +int intel_pxp_cmd_submit(struct intel_pxp *pxp, u32 *cmd,
> + int cmd_size_in_dw)
> {
> int err = -EINVAL;
> struct i915_vma *batch;
> @@ -154,3 +174,102 @@ int intel_pxp_cmd_submit(struct intel_pxp *pxp, u32 *cmd, int cmd_size_in_dw)
>
> return err;
> }
> +
> +int intel_pxp_cmd_add_prolog(struct intel_pxp *pxp, u32 *cmd,
> + int session_type,
> + int session_index)
> +{
> + u32 increased_size_in_dw = 0;
> + u32 *cmd_prolog = cmd;
> + const int cmd_prolog_size_in_dw = 10;
> + struct intel_gt *gt = container_of(pxp, typeof(*gt), pxp);
> +
> + if (!cmd)
> + return cmd_prolog_size_in_dw;
> +
> + /* MFX_WAIT - stall until prior PXP and MFX/HCP/HUC objects are cmopleted */
> + *cmd_prolog++ = (MFX_WAIT | MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG |
> + MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG);
> +
> + /* MI_FLUSH_DW - pxp off */
> + *cmd_prolog++ = MI_FLUSH_DW; /* DW0 */
> + *cmd_prolog++ = 0; /* DW1 */
> + *cmd_prolog++ = 0; /* DW2 */
> +
> + /* MI_SET_APPID */
> + if (session_type == SESSION_TYPE_TYPE1) {
> + if (session_index >= MAX_TYPE1_SESSIONS) {
> + drm_err(>->i915->drm, "Failed to %s invalid session_index\n", __func__);
> + goto end;
> + }
> +
> + *cmd_prolog++ = (MI_SET_APPID | MI_SET_APPID_TYPE1_APP |
> + MI_SET_APPID_SESSION_ID(session_index));
> + } else {
> + if (session_index >= MAX_TYPE0_SESSIONS) {
> + drm_err(>->i915->drm, "Failed to %s invalid session_index\n", __func__);
> + goto end;
> + }
> +
> + *cmd_prolog++ = (MI_SET_APPID | MI_SET_APPID_SESSION_ID(session_index));
> + }
> +
> + /* MFX_WAIT */
> + *cmd_prolog++ = (MFX_WAIT | MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG |
> + MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG);
> +
> + /* MI_FLUSH_DW - pxp on */
> + *cmd_prolog++ = (MI_FLUSH_DW | MI_FLUSH_DW_DW0_PROTECTED_MEMORY_ENABLE); /* DW0 */
> + *cmd_prolog++ = 0; /* DW1 */
> + *cmd_prolog++ = 0; /* DW2 */
> +
> + /* MFX_WAIT */
> + *cmd_prolog++ = (MFX_WAIT | MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG |
> + MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG);
> +
> + increased_size_in_dw = (cmd_prolog - cmd);
> +end:
> + return increased_size_in_dw;
> +}
> +
> +int intel_pxp_cmd_add_epilog(u32 *cmd)
> +{
> + u32 increased_size_in_dw = 0;
> + u32 *cmd_epilog = cmd;
> + const int cmd_epilog_size_in_dw = 5;
> +
> + if (!cmd)
> + return cmd_epilog_size_in_dw;
> +
> + /* MI_FLUSH_DW - pxp off */
> + *cmd_epilog++ = MI_FLUSH_DW; /* DW0 */
> + *cmd_epilog++ = 0; /* DW1 */
> + *cmd_epilog++ = 0; /* DW2 */
> +
> + /* MFX_WAIT - stall until prior PXP and MFX/HCP/HUC objects are cmopleted */
> + *cmd_epilog++ = (MFX_WAIT | MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG |
> + MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG);
> +
> + /* MI_BATCH_BUFFER_END */
> + *cmd_epilog++ = MI_BATCH_BUFFER_END;
> +
> + increased_size_in_dw = (cmd_epilog - cmd);
> + return increased_size_in_dw;
> +}
> +
> +int intel_pxp_cmd_add_inline_termination(u32 *cmd)
> +{
> + u32 increased_size_in_dw = 0;
> + u32 *cmd_termin = cmd;
> + const int cmd_termin_size_in_dw = 2;
> +
> + if (!cmd)
> + return cmd_termin_size_in_dw;
> +
> + /* CRYPTO_KEY_EXCHANGE - session inline termination */
> + *cmd_termin++ = CRYPTO_KEY_EXCHANGE; /* DW0 */
> + *cmd_termin++ = 0; /* DW1 */
> +
> + increased_size_in_dw = (cmd_termin - cmd);
> + return increased_size_in_dw;
> +}
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
> index d04463962421..087f260034c4 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
> @@ -9,10 +9,12 @@
> #include "gt/intel_gt_buffer_pool.h"
> #include "intel_pxp.h"
>
> -struct i915_vma *intel_pxp_cmd_get_batch(struct intel_pxp *pxp,
> - struct intel_context *ce,
> - struct intel_gt_buffer_pool_node *pool,
> - u32 *cmd_buf, int cmd_size_in_dw);
> +int intel_pxp_cmd_submit(struct intel_pxp *pxp, u32 *cmd,
> + int cmd_size_in_dw);
> +int intel_pxp_cmd_add_prolog(struct intel_pxp *pxp, u32 *cmd,
> + int session_type,
> + int session_index);
> +int intel_pxp_cmd_add_epilog(u32 *cmd);
> +int intel_pxp_cmd_add_inline_termination(u32 *cmd);
>
> -int intel_pxp_cmd_submit(struct intel_pxp *pxp, u32 *cmd, int cmd_size_in_dw);
> #endif /* __INTEL_PXP_SM_H__ */
> --
> 2.17.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
More information about the Intel-gfx
mailing list