Skip to content

Commit 99afb7c

Browse files
aalteresRadhakrishna Sripada
authored andcommitted
drm/i915/pxp: Add ARB session creation and cleanup
Add MTL's function for ARB session creation using PXP firmware version 4.3 ABI structure format. While relooking at the ARB session creation flow in intel_pxp_start, let's address missing UAPI documentation. Without actually changing backward compatible behavior, update i915's drm-uapi comments that describe the possible error values when creating a context with I915_CONTEXT_PARAM_PROTECTED_CONTENT: Since the first merge of PXP support on ADL, i915 returns -ENXIO if a dependency such as firmware or component driver was yet to be loaded or returns -EIO if the creation attempt failed when requested by the PXP firmware (specific firmware error responses are reported in dmesg). Add MTL's function for ARB session invalidation but this reuses PXP firmware version 4.2 ABI structure format. For both cases, in the back-end gsccs functions for sending messages to the firmware inspect the GSC-CS-Mem-Header's pending-bit which means the GSC firmware is busy and we should retry. Given the last hw requirement, lets also update functions in front-end layer that wait for session creation or teardown completion to use new worst case timeout periods. Signed-off-by: Alan Previn <alan.previn.teres.alexis@intel.com> Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Signed-off-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230511231738.1077674-6-alan.previn.teres.alexis@intel.com
1 parent dc9ac12 commit 99afb7c

6 files changed

Lines changed: 209 additions & 7 deletions

File tree

drivers/gpu/drm/i915/pxp/intel_pxp.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,8 @@ static bool pxp_component_bound(struct intel_pxp *pxp)
291291

292292
static int __pxp_global_teardown_final(struct intel_pxp *pxp)
293293
{
294+
int timeout;
295+
294296
if (!pxp->arb_is_valid)
295297
return 0;
296298
/*
@@ -300,14 +302,21 @@ static int __pxp_global_teardown_final(struct intel_pxp *pxp)
300302
intel_pxp_mark_termination_in_progress(pxp);
301303
intel_pxp_terminate(pxp, false);
302304

303-
if (!wait_for_completion_timeout(&pxp->termination, msecs_to_jiffies(250)))
305+
if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
306+
timeout = GSCFW_MAX_ROUND_TRIP_LATENCY_MS;
307+
else
308+
timeout = 250;
309+
310+
if (!wait_for_completion_timeout(&pxp->termination, msecs_to_jiffies(timeout)))
304311
return -ETIMEDOUT;
305312

306313
return 0;
307314
}
308315

309316
static int __pxp_global_teardown_restart(struct intel_pxp *pxp)
310317
{
318+
int timeout;
319+
311320
if (pxp->arb_is_valid)
312321
return 0;
313322
/*
@@ -316,7 +325,12 @@ static int __pxp_global_teardown_restart(struct intel_pxp *pxp)
316325
*/
317326
pxp_queue_termination(pxp);
318327

319-
if (!wait_for_completion_timeout(&pxp->termination, msecs_to_jiffies(250)))
328+
if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
329+
timeout = GSCFW_MAX_ROUND_TRIP_LATENCY_MS;
330+
else
331+
timeout = 250;
332+
333+
if (!wait_for_completion_timeout(&pxp->termination, msecs_to_jiffies(timeout)))
320334
return -ETIMEDOUT;
321335

322336
return 0;
@@ -354,8 +368,13 @@ int intel_pxp_start(struct intel_pxp *pxp)
354368
if (!intel_pxp_is_enabled(pxp))
355369
return -ENODEV;
356370

357-
if (wait_for(pxp_component_bound(pxp), 250))
358-
return -ENXIO;
371+
if (HAS_ENGINE(pxp->ctrl_gt, GSC0)) {
372+
if (wait_for(intel_pxp_gsccs_is_ready_for_sessions(pxp), 250))
373+
return -ENXIO;
374+
} else {
375+
if (wait_for(pxp_component_bound(pxp), 250))
376+
return -ENXIO;
377+
}
359378

360379
mutex_lock(&pxp->arb_mutex);
361380

drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
/* PXP-Cmd-Op definitions */
1313
#define PXP43_CMDID_START_HUC_AUTH 0x0000003A
14+
#define PXP43_CMDID_INIT_SESSION 0x00000036
1415

1516
/* PXP-Packet sizes for MTL's GSCCS-HECI instruction */
1617
#define PXP43_MAX_HECI_INOUT_SIZE (SZ_32K)
@@ -26,4 +27,24 @@ struct pxp43_start_huc_auth_out {
2627
struct pxp_cmd_header header;
2728
} __packed;
2829

30+
/* PXP-Input-Packet: Init PXP session */
31+
struct pxp43_create_arb_in {
32+
struct pxp_cmd_header header;
33+
/* header.stream_id fields for vesion 4.3 of Init PXP session: */
34+
#define PXP43_INIT_SESSION_VALID BIT(0)
35+
#define PXP43_INIT_SESSION_APPTYPE BIT(1)
36+
#define PXP43_INIT_SESSION_APPID GENMASK(17, 2)
37+
u32 protection_mode;
38+
#define PXP43_INIT_SESSION_PROTECTION_ARB 0x2
39+
u32 sub_session_id;
40+
u32 init_flags;
41+
u32 rsvd[12];
42+
} __packed;
43+
44+
/* PXP-Input-Packet: Init PXP session */
45+
struct pxp43_create_arb_out {
46+
struct pxp_cmd_header header;
47+
u32 rsvd[8];
48+
} __packed;
49+
2950
#endif /* __INTEL_PXP_FW_INTERFACE_43_H__ */

drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,46 @@
66
#include "gem/i915_gem_internal.h"
77

88
#include "gt/intel_context.h"
9+
#include "gt/uc/intel_gsc_fw.h"
910
#include "gt/uc/intel_gsc_uc_heci_cmd_submit.h"
1011

1112
#include "i915_drv.h"
13+
#include "intel_pxp_cmd_interface_42.h"
1214
#include "intel_pxp_cmd_interface_43.h"
1315
#include "intel_pxp_gsccs.h"
1416
#include "intel_pxp_types.h"
1517

18+
static bool
19+
is_fw_err_platform_config(u32 type)
20+
{
21+
switch (type) {
22+
case PXP_STATUS_ERROR_API_VERSION:
23+
case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:
24+
case PXP_STATUS_PLATFCONFIG_KF1_BAD:
25+
return true;
26+
default:
27+
break;
28+
}
29+
return false;
30+
}
31+
32+
static const char *
33+
fw_err_to_string(u32 type)
34+
{
35+
switch (type) {
36+
case PXP_STATUS_ERROR_API_VERSION:
37+
return "ERR_API_VERSION";
38+
case PXP_STATUS_NOT_READY:
39+
return "ERR_NOT_READY";
40+
case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:
41+
case PXP_STATUS_PLATFCONFIG_KF1_BAD:
42+
return "ERR_PLATFORM_CONFIG";
43+
default:
44+
break;
45+
}
46+
return NULL;
47+
}
48+
1649
static int
1750
gsccs_send_message(struct intel_pxp *pxp,
1851
void *msg_in, size_t msg_in_size,
@@ -152,6 +185,103 @@ gsccs_send_message_retry_complete(struct intel_pxp *pxp,
152185
return ret;
153186
}
154187

188+
bool intel_pxp_gsccs_is_ready_for_sessions(struct intel_pxp *pxp)
189+
{
190+
/*
191+
* GSC-fw loading, HuC-fw loading, HuC-fw authentication and
192+
* GSC-proxy init flow (requiring an mei component driver)
193+
* must all occur first before we can start requesting for PXP
194+
* sessions. Checking for completion on HuC authentication and
195+
* gsc-proxy init flow (the last set of dependencies that
196+
* are out of order) will suffice.
197+
*/
198+
if (intel_huc_is_authenticated(&pxp->ctrl_gt->uc.huc) &&
199+
intel_gsc_uc_fw_proxy_init_done(&pxp->ctrl_gt->uc.gsc))
200+
return true;
201+
202+
return false;
203+
}
204+
205+
int intel_pxp_gsccs_create_session(struct intel_pxp *pxp,
206+
int arb_session_id)
207+
{
208+
struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
209+
struct pxp43_create_arb_in msg_in = {0};
210+
struct pxp43_create_arb_out msg_out = {0};
211+
int ret;
212+
213+
msg_in.header.api_version = PXP_APIVER(4, 3);
214+
msg_in.header.command_id = PXP43_CMDID_INIT_SESSION;
215+
msg_in.header.stream_id = (FIELD_PREP(PXP43_INIT_SESSION_APPID, arb_session_id) |
216+
FIELD_PREP(PXP43_INIT_SESSION_VALID, 1) |
217+
FIELD_PREP(PXP43_INIT_SESSION_APPTYPE, 0));
218+
msg_in.header.buffer_len = sizeof(msg_in) - sizeof(msg_in.header);
219+
msg_in.protection_mode = PXP43_INIT_SESSION_PROTECTION_ARB;
220+
221+
ret = gsccs_send_message_retry_complete(pxp,
222+
&msg_in, sizeof(msg_in),
223+
&msg_out, sizeof(msg_out), NULL);
224+
if (ret) {
225+
drm_err(&i915->drm, "Failed to init session %d, ret=[%d]\n", arb_session_id, ret);
226+
} else if (msg_out.header.status != 0) {
227+
if (is_fw_err_platform_config(msg_out.header.status)) {
228+
drm_info_once(&i915->drm,
229+
"PXP init-session-%d failed due to BIOS/SOC:0x%08x:%s\n",
230+
arb_session_id, msg_out.header.status,
231+
fw_err_to_string(msg_out.header.status));
232+
} else {
233+
drm_dbg(&i915->drm, "PXP init-session-%d failed 0x%08x:%st:\n",
234+
arb_session_id, msg_out.header.status,
235+
fw_err_to_string(msg_out.header.status));
236+
drm_dbg(&i915->drm, " cmd-detail: ID=[0x%08x],API-Ver-[0x%08x]\n",
237+
msg_in.header.command_id, msg_in.header.api_version);
238+
}
239+
}
240+
241+
return ret;
242+
}
243+
244+
void intel_pxp_gsccs_end_arb_fw_session(struct intel_pxp *pxp, u32 session_id)
245+
{
246+
struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
247+
struct pxp42_inv_stream_key_in msg_in = {0};
248+
struct pxp42_inv_stream_key_out msg_out = {0};
249+
int ret = 0;
250+
251+
/*
252+
* Stream key invalidation reuses the same version 4.2 input/output
253+
* command format but firmware requires 4.3 API interaction
254+
*/
255+
msg_in.header.api_version = PXP_APIVER(4, 3);
256+
msg_in.header.command_id = PXP42_CMDID_INVALIDATE_STREAM_KEY;
257+
msg_in.header.buffer_len = sizeof(msg_in) - sizeof(msg_in.header);
258+
259+
msg_in.header.stream_id = FIELD_PREP(PXP_CMDHDR_EXTDATA_SESSION_VALID, 1);
260+
msg_in.header.stream_id |= FIELD_PREP(PXP_CMDHDR_EXTDATA_APP_TYPE, 0);
261+
msg_in.header.stream_id |= FIELD_PREP(PXP_CMDHDR_EXTDATA_SESSION_ID, session_id);
262+
263+
ret = gsccs_send_message_retry_complete(pxp,
264+
&msg_in, sizeof(msg_in),
265+
&msg_out, sizeof(msg_out), NULL);
266+
if (ret) {
267+
drm_err(&i915->drm, "Failed to inv-stream-key-%u, ret=[%d]\n",
268+
session_id, ret);
269+
} else if (msg_out.header.status != 0) {
270+
if (is_fw_err_platform_config(msg_out.header.status)) {
271+
drm_info_once(&i915->drm,
272+
"PXP inv-stream-key-%u failed due to BIOS/SOC :0x%08x:%s\n",
273+
session_id, msg_out.header.status,
274+
fw_err_to_string(msg_out.header.status));
275+
} else {
276+
drm_dbg(&i915->drm, "PXP inv-stream-key-%u failed 0x%08x:%s:\n",
277+
session_id, msg_out.header.status,
278+
fw_err_to_string(msg_out.header.status));
279+
drm_dbg(&i915->drm, " cmd-detail: ID=[0x%08x],API-Ver-[0x%08x]\n",
280+
msg_in.header.command_id, msg_in.header.api_version);
281+
}
282+
}
283+
}
284+
155285
static void
156286
gsccs_cleanup_fw_host_session_handle(struct intel_pxp *pxp)
157287
{

drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,22 @@
1010

1111
struct intel_pxp;
1212

13-
#define GSC_REPLY_LATENCY_MS 200
13+
#define GSC_REPLY_LATENCY_MS 210
14+
/*
15+
* Max FW response time is 200ms, to which we add 10ms to account for overhead
16+
* such as request preparation, GuC submission to hw and pipeline completion times.
17+
*/
1418
#define GSC_PENDING_RETRY_MAXCOUNT 40
1519
#define GSC_PENDING_RETRY_PAUSE_MS 50
20+
#define GSCFW_MAX_ROUND_TRIP_LATENCY_MS (GSC_PENDING_RETRY_MAXCOUNT * GSC_PENDING_RETRY_PAUSE_MS)
1621

1722
#ifdef CONFIG_DRM_I915_PXP
1823
void intel_pxp_gsccs_fini(struct intel_pxp *pxp);
1924
int intel_pxp_gsccs_init(struct intel_pxp *pxp);
2025

26+
int intel_pxp_gsccs_create_session(struct intel_pxp *pxp, int arb_session_id);
27+
void intel_pxp_gsccs_end_arb_fw_session(struct intel_pxp *pxp, u32 arb_session_id);
28+
2129
#else
2230
static inline void intel_pxp_gsccs_fini(struct intel_pxp *pxp)
2331
{
@@ -30,4 +38,6 @@ static inline int intel_pxp_gsccs_init(struct intel_pxp *pxp)
3038

3139
#endif
3240

41+
bool intel_pxp_gsccs_is_ready_for_sessions(struct intel_pxp *pxp);
42+
3343
#endif /*__INTEL_PXP_GSCCS_H__ */

drivers/gpu/drm/i915/pxp/intel_pxp_session.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include "intel_pxp.h"
99
#include "intel_pxp_cmd.h"
10+
#include "intel_pxp_gsccs.h"
1011
#include "intel_pxp_session.h"
1112
#include "intel_pxp_tee.h"
1213
#include "intel_pxp_types.h"
@@ -62,7 +63,10 @@ static int pxp_create_arb_session(struct intel_pxp *pxp)
6263
return -EEXIST;
6364
}
6465

65-
ret = intel_pxp_tee_cmd_create_arb_session(pxp, ARB_SESSION);
66+
if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
67+
ret = intel_pxp_gsccs_create_session(pxp, ARB_SESSION);
68+
else
69+
ret = intel_pxp_tee_cmd_create_arb_session(pxp, ARB_SESSION);
6670
if (ret) {
6771
drm_err(&gt->i915->drm, "tee cmd for arb session creation failed\n");
6872
return ret;
@@ -106,7 +110,10 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
106110

107111
intel_uncore_write(gt->uncore, KCR_GLOBAL_TERMINATE(pxp->kcr_base), 1);
108112

109-
intel_pxp_tee_end_arb_fw_session(pxp, ARB_SESSION);
113+
if (HAS_ENGINE(gt, GSC0))
114+
intel_pxp_gsccs_end_arb_fw_session(pxp, ARB_SESSION);
115+
else
116+
intel_pxp_tee_end_arb_fw_session(pxp, ARB_SESSION);
110117

111118
return ret;
112119
}

include/uapi/drm/i915_drm.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2096,6 +2096,21 @@ struct drm_i915_gem_context_param {
20962096
*
20972097
* -ENODEV: feature not available
20982098
* -EPERM: trying to mark a recoverable or not bannable context as protected
2099+
* -ENXIO: A dependency such as a component driver or firmware is not yet
2100+
* loaded so user space may need to attempt again. Depending on the
2101+
* device, this error may be reported if protected context creation is
2102+
* attempted very early after kernel start because the internal timeout
2103+
* waiting for such dependencies is not guaranteed to be larger than
2104+
* required (numbers differ depending on system and kernel config):
2105+
* - ADL/RPL: dependencies may take up to 3 seconds from kernel start
2106+
* while context creation internal timeout is 250 milisecs
2107+
* - MTL: dependencies may take up to 8 seconds from kernel start
2108+
* while context creation internal timeout is 250 milisecs
2109+
* NOTE: such dependencies happen once, so a subsequent call to create a
2110+
* protected context after a prior successful call will not experience
2111+
* such timeouts and will not return -ENXIO (unless the driver is reloaded,
2112+
* or, depending on the device, resumes from a suspended state).
2113+
* -EIO: The firmware did not succeed in creating the protected context.
20992114
*/
21002115
#define I915_CONTEXT_PARAM_PROTECTED_CONTENT 0xd
21012116
/* Must be kept compact -- no holes and well documented */

0 commit comments

Comments
 (0)