drm/i915/pxp: Invalidate all PXP fw sessions during teardown
authorAlan Previn <alan.previn.teres.alexis@intel.com>
Wed, 25 Jan 2023 08:26:35 +0000 (00:26 -0800)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Fri, 27 Jan 2023 20:22:24 +0000 (15:22 -0500)
A gap was recently discovered where if an application did not
invalidate all of the stream keys (intentionally or not), and the
driver did a full PXP global teardown on the GT subsystem, we
find that future session creation would fail on the security
firmware's side of the equation. i915 is the entity that needs
ensure the sessions' state across both iGT and security firmware
are at a known clean point when performing a full global teardown.

Architecturally speaking, i915 should inspect all active sessions
and submit the invalidate-stream-key PXP command to the security
firmware for each of them. However, for the upstream i915 driver
we only support the arbitration session that can be created
so that will be the only session we will cleanup.

Signed-off-by: Alan Previn <alan.previn.teres.alexis@intel.com>
Reviewed-by: Juston Li <justonli@chromium.org>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230125082637.118970-5-alan.previn.teres.alexis@intel.com
drivers/gpu/drm/i915/pxp/intel_pxp.h
drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_42.h
drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h
drivers/gpu/drm/i915/pxp/intel_pxp_session.c
drivers/gpu/drm/i915/pxp/intel_pxp_tee.c

index 04440fada711a8f4b138c904ef14d39e1bb66a5e..9658d30052224a9d531dffcfcd59f9b585824dd2 100644 (file)
@@ -24,6 +24,7 @@ void intel_pxp_init_hw(struct intel_pxp *pxp);
 void intel_pxp_fini_hw(struct intel_pxp *pxp);
 
 void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
+void intel_pxp_tee_end_arb_fw_session(struct intel_pxp *pxp, u32 arb_session_id);
 
 int intel_pxp_start(struct intel_pxp *pxp);
 
index 739f9072fa5fba67400b72013e58d8891858ea40..26f7d9f01bf3fa4e584ae659c2f9160153473399 100644 (file)
@@ -12,6 +12,9 @@
 /* PXP-Opcode for Init Session */
 #define PXP42_CMDID_INIT_SESSION 0x1e
 
+/* PXP-Opcode for Invalidate Stream Key */
+#define PXP42_CMDID_INVALIDATE_STREAM_KEY 0x00000007
+
 /* PXP-Input-Packet: Init Session (Arb-Session) */
 struct pxp42_create_arb_in {
        struct pxp_cmd_header header;
@@ -25,4 +28,16 @@ struct pxp42_create_arb_out {
        struct pxp_cmd_header header;
 } __packed;
 
+/* PXP-Input-Packet: Invalidate Stream Key */
+struct pxp42_inv_stream_key_in {
+       struct pxp_cmd_header header;
+       u32 rsvd[3];
+} __packed;
+
+/* PXP-Output-Packet: Invalidate Stream Key */
+struct pxp42_inv_stream_key_out {
+       struct pxp_cmd_header header;
+       u32 rsvd;
+} __packed;
+
 #endif /* __INTEL_PXP_FW_INTERFACE_42_H__ */
index aaa8187a0afbc40317bffff18b4652c76a4dbef0..ae9b151b7cb77bbe0e8d1f0b4d0be048a2f8d984 100644 (file)
@@ -28,6 +28,9 @@ struct pxp_cmd_header {
        union {
                u32 status; /* out */
                u32 stream_id; /* in */
+#define PXP_CMDHDR_EXTDATA_SESSION_VALID GENMASK(0, 0)
+#define PXP_CMDHDR_EXTDATA_APP_TYPE GENMASK(1, 1)
+#define PXP_CMDHDR_EXTDATA_SESSION_ID GENMASK(17, 2)
        };
        /* Length of the message (excluding the header) */
        u32 buffer_len;
index ae413580b81acb3beecdabce199ac93fd1001dd2..74ed7e16e481125f2a4c15261ca9c602db8d7603 100644 (file)
@@ -110,6 +110,8 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
 
        intel_uncore_write(gt->uncore, PXP_GLOBAL_TERMINATE, 1);
 
+       intel_pxp_tee_end_arb_fw_session(pxp, ARB_SESSION);
+
        return ret;
 }
 
index b5bc0b87a1d02f8a4bbf8fbb8983f0bd2857fb11..d9d248b48093421d34789206af253925c0ccede9 100644 (file)
@@ -319,3 +319,38 @@ int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp *pxp,
 
        return ret;
 }
+
+void intel_pxp_tee_end_arb_fw_session(struct intel_pxp *pxp, u32 session_id)
+{
+       struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
+       struct pxp42_inv_stream_key_in msg_in = {0};
+       struct pxp42_inv_stream_key_out msg_out = {0};
+       int ret, trials = 0;
+
+try_again:
+       memset(&msg_in, 0, sizeof(msg_in));
+       memset(&msg_out, 0, sizeof(msg_out));
+       msg_in.header.api_version = PXP_APIVER(4, 2);
+       msg_in.header.command_id = PXP42_CMDID_INVALIDATE_STREAM_KEY;
+       msg_in.header.buffer_len = sizeof(msg_in) - sizeof(msg_in.header);
+
+       msg_in.header.stream_id = FIELD_PREP(PXP_CMDHDR_EXTDATA_SESSION_VALID, 1);
+       msg_in.header.stream_id |= FIELD_PREP(PXP_CMDHDR_EXTDATA_APP_TYPE, 0);
+       msg_in.header.stream_id |= FIELD_PREP(PXP_CMDHDR_EXTDATA_SESSION_ID, session_id);
+
+       ret = intel_pxp_tee_io_message(pxp,
+                                      &msg_in, sizeof(msg_in),
+                                      &msg_out, sizeof(msg_out),
+                                      NULL);
+
+       /* Cleanup coherency between GT and Firmware is critical, so try again if it fails */
+       if ((ret || msg_out.header.status != 0x0) && ++trials < 3)
+               goto try_again;
+
+       if (ret)
+               drm_err(&i915->drm, "Failed to send tee msg for inv-stream-key-%d, ret=[%d]\n",
+                       session_id, ret);
+       else if (msg_out.header.status != 0x0)
+               drm_warn(&i915->drm, "PXP firmware failed inv-stream-key-%d with status 0x%08x\n",
+                        session_id, msg_out.header.status);
+}