11bb76ff1Sjsg // SPDX-License-Identifier: MIT
21bb76ff1Sjsg /*
31bb76ff1Sjsg * Copyright(c) 2020 Intel Corporation.
41bb76ff1Sjsg */
51bb76ff1Sjsg
61bb76ff1Sjsg #include <linux/component.h>
71bb76ff1Sjsg
81bb76ff1Sjsg #include <drm/i915_pxp_tee_interface.h>
91bb76ff1Sjsg #include <drm/i915_component.h>
101bb76ff1Sjsg
11*f005ef32Sjsg #include "gem/i915_gem_lmem.h"
12*f005ef32Sjsg
131bb76ff1Sjsg #include "i915_drv.h"
14*f005ef32Sjsg #include "gt/intel_gt.h"
15*f005ef32Sjsg
161bb76ff1Sjsg #include "intel_pxp.h"
17*f005ef32Sjsg #include "intel_pxp_cmd_interface_42.h"
18*f005ef32Sjsg #include "intel_pxp_huc.h"
191bb76ff1Sjsg #include "intel_pxp_session.h"
201bb76ff1Sjsg #include "intel_pxp_tee.h"
21*f005ef32Sjsg #include "intel_pxp_types.h"
221bb76ff1Sjsg
23*f005ef32Sjsg static bool
is_fw_err_platform_config(u32 type)24*f005ef32Sjsg is_fw_err_platform_config(u32 type)
251bb76ff1Sjsg {
26*f005ef32Sjsg switch (type) {
27*f005ef32Sjsg case PXP_STATUS_ERROR_API_VERSION:
28*f005ef32Sjsg case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:
29*f005ef32Sjsg case PXP_STATUS_PLATFCONFIG_KF1_BAD:
30*f005ef32Sjsg return true;
31*f005ef32Sjsg default:
32*f005ef32Sjsg break;
33*f005ef32Sjsg }
34*f005ef32Sjsg return false;
35*f005ef32Sjsg }
361bb76ff1Sjsg
37*f005ef32Sjsg static const char *
fw_err_to_string(u32 type)38*f005ef32Sjsg fw_err_to_string(u32 type)
39*f005ef32Sjsg {
40*f005ef32Sjsg switch (type) {
41*f005ef32Sjsg case PXP_STATUS_ERROR_API_VERSION:
42*f005ef32Sjsg return "ERR_API_VERSION";
43*f005ef32Sjsg case PXP_STATUS_NOT_READY:
44*f005ef32Sjsg return "ERR_NOT_READY";
45*f005ef32Sjsg case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:
46*f005ef32Sjsg case PXP_STATUS_PLATFCONFIG_KF1_BAD:
47*f005ef32Sjsg return "ERR_PLATFORM_CONFIG";
48*f005ef32Sjsg default:
49*f005ef32Sjsg break;
50*f005ef32Sjsg }
51*f005ef32Sjsg return NULL;
521bb76ff1Sjsg }
531bb76ff1Sjsg
intel_pxp_tee_io_message(struct intel_pxp * pxp,void * msg_in,u32 msg_in_size,void * msg_out,u32 msg_out_max_size,u32 * msg_out_rcv_size)541bb76ff1Sjsg static int intel_pxp_tee_io_message(struct intel_pxp *pxp,
551bb76ff1Sjsg void *msg_in, u32 msg_in_size,
561bb76ff1Sjsg void *msg_out, u32 msg_out_max_size,
571bb76ff1Sjsg u32 *msg_out_rcv_size)
581bb76ff1Sjsg {
59*f005ef32Sjsg struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
601bb76ff1Sjsg struct i915_pxp_component *pxp_component = pxp->pxp_component;
611bb76ff1Sjsg int ret = 0;
621bb76ff1Sjsg
631bb76ff1Sjsg mutex_lock(&pxp->tee_mutex);
641bb76ff1Sjsg
651bb76ff1Sjsg /*
661bb76ff1Sjsg * The binding of the component is asynchronous from i915 probe, so we
671bb76ff1Sjsg * can't be sure it has happened.
681bb76ff1Sjsg */
691bb76ff1Sjsg if (!pxp_component) {
701bb76ff1Sjsg ret = -ENODEV;
711bb76ff1Sjsg goto unlock;
721bb76ff1Sjsg }
731bb76ff1Sjsg
741bb76ff1Sjsg ret = pxp_component->ops->send(pxp_component->tee_dev, msg_in, msg_in_size);
751bb76ff1Sjsg if (ret) {
761bb76ff1Sjsg drm_err(&i915->drm, "Failed to send PXP TEE message\n");
771bb76ff1Sjsg goto unlock;
781bb76ff1Sjsg }
791bb76ff1Sjsg
801bb76ff1Sjsg ret = pxp_component->ops->recv(pxp_component->tee_dev, msg_out, msg_out_max_size);
811bb76ff1Sjsg if (ret < 0) {
821bb76ff1Sjsg drm_err(&i915->drm, "Failed to receive PXP TEE message\n");
831bb76ff1Sjsg goto unlock;
841bb76ff1Sjsg }
851bb76ff1Sjsg
861bb76ff1Sjsg if (ret > msg_out_max_size) {
871bb76ff1Sjsg drm_err(&i915->drm,
881bb76ff1Sjsg "Failed to receive PXP TEE message due to unexpected output size\n");
891bb76ff1Sjsg ret = -ENOSPC;
901bb76ff1Sjsg goto unlock;
911bb76ff1Sjsg }
921bb76ff1Sjsg
931bb76ff1Sjsg if (msg_out_rcv_size)
941bb76ff1Sjsg *msg_out_rcv_size = ret;
951bb76ff1Sjsg
961bb76ff1Sjsg ret = 0;
971bb76ff1Sjsg unlock:
981bb76ff1Sjsg mutex_unlock(&pxp->tee_mutex);
991bb76ff1Sjsg return ret;
1001bb76ff1Sjsg }
1011bb76ff1Sjsg
intel_pxp_tee_stream_message(struct intel_pxp * pxp,u8 client_id,u32 fence_id,void * msg_in,size_t msg_in_len,void * msg_out,size_t msg_out_len)102*f005ef32Sjsg int intel_pxp_tee_stream_message(struct intel_pxp *pxp,
103*f005ef32Sjsg u8 client_id, u32 fence_id,
104*f005ef32Sjsg void *msg_in, size_t msg_in_len,
105*f005ef32Sjsg void *msg_out, size_t msg_out_len)
106*f005ef32Sjsg {
107*f005ef32Sjsg /* TODO: for bigger objects we need to use a sg of 4k pages */
108*f005ef32Sjsg const size_t max_msg_size = PAGE_SIZE;
109*f005ef32Sjsg struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
110*f005ef32Sjsg struct i915_pxp_component *pxp_component = pxp->pxp_component;
111*f005ef32Sjsg unsigned int offset = 0;
112*f005ef32Sjsg struct scatterlist *sg;
113*f005ef32Sjsg int ret;
114*f005ef32Sjsg
115*f005ef32Sjsg if (msg_in_len > max_msg_size || msg_out_len > max_msg_size)
116*f005ef32Sjsg return -ENOSPC;
117*f005ef32Sjsg
118*f005ef32Sjsg mutex_lock(&pxp->tee_mutex);
119*f005ef32Sjsg
120*f005ef32Sjsg if (unlikely(!pxp_component || !pxp_component->ops->gsc_command)) {
121*f005ef32Sjsg ret = -ENODEV;
122*f005ef32Sjsg goto unlock;
123*f005ef32Sjsg }
124*f005ef32Sjsg
125*f005ef32Sjsg GEM_BUG_ON(!pxp->stream_cmd.obj);
126*f005ef32Sjsg
127*f005ef32Sjsg sg = i915_gem_object_get_sg_dma(pxp->stream_cmd.obj, 0, &offset);
128*f005ef32Sjsg
129*f005ef32Sjsg memcpy(pxp->stream_cmd.vaddr, msg_in, msg_in_len);
130*f005ef32Sjsg
131*f005ef32Sjsg ret = pxp_component->ops->gsc_command(pxp_component->tee_dev, client_id,
132*f005ef32Sjsg fence_id, sg, msg_in_len, sg);
133*f005ef32Sjsg if (ret < 0)
134*f005ef32Sjsg drm_err(&i915->drm, "Failed to send PXP TEE gsc command\n");
135*f005ef32Sjsg else
136*f005ef32Sjsg memcpy(msg_out, pxp->stream_cmd.vaddr, msg_out_len);
137*f005ef32Sjsg
138*f005ef32Sjsg unlock:
139*f005ef32Sjsg mutex_unlock(&pxp->tee_mutex);
140*f005ef32Sjsg return ret;
141*f005ef32Sjsg }
142*f005ef32Sjsg
1431bb76ff1Sjsg /**
1441bb76ff1Sjsg * i915_pxp_tee_component_bind - bind function to pass the function pointers to pxp_tee
1451bb76ff1Sjsg * @i915_kdev: pointer to i915 kernel device
1461bb76ff1Sjsg * @tee_kdev: pointer to tee kernel device
1471bb76ff1Sjsg * @data: pointer to pxp_tee_master containing the function pointers
1481bb76ff1Sjsg *
1491bb76ff1Sjsg * This bind function is called during the system boot or resume from system sleep.
1501bb76ff1Sjsg *
1511bb76ff1Sjsg * Return: return 0 if successful.
1521bb76ff1Sjsg */
i915_pxp_tee_component_bind(struct device * i915_kdev,struct device * tee_kdev,void * data)1531bb76ff1Sjsg static int i915_pxp_tee_component_bind(struct device *i915_kdev,
1541bb76ff1Sjsg struct device *tee_kdev, void *data)
1551bb76ff1Sjsg {
1561bb76ff1Sjsg struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
157*f005ef32Sjsg struct intel_pxp *pxp = i915->pxp;
158*f005ef32Sjsg struct intel_uc *uc = &pxp->ctrl_gt->uc;
1591bb76ff1Sjsg intel_wakeref_t wakeref;
160*f005ef32Sjsg int ret = 0;
161*f005ef32Sjsg
162*f005ef32Sjsg if (!HAS_HECI_PXP(i915)) {
163*f005ef32Sjsg STUB();
164*f005ef32Sjsg pxp->dev_link = NULL;
165*f005ef32Sjsg #ifdef notyet
166*f005ef32Sjsg pxp->dev_link = device_link_add(i915_kdev, tee_kdev, DL_FLAG_STATELESS);
167*f005ef32Sjsg if (drm_WARN_ON(&i915->drm, !pxp->dev_link))
168*f005ef32Sjsg return -ENODEV;
169*f005ef32Sjsg #endif
170*f005ef32Sjsg }
1711bb76ff1Sjsg
1721bb76ff1Sjsg mutex_lock(&pxp->tee_mutex);
1731bb76ff1Sjsg pxp->pxp_component = data;
1741bb76ff1Sjsg pxp->pxp_component->tee_dev = tee_kdev;
1751bb76ff1Sjsg mutex_unlock(&pxp->tee_mutex);
1761bb76ff1Sjsg
177*f005ef32Sjsg if (intel_uc_uses_huc(uc) && intel_huc_is_loaded_by_gsc(&uc->huc)) {
178*f005ef32Sjsg with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
179*f005ef32Sjsg /* load huc via pxp */
180*f005ef32Sjsg ret = intel_huc_fw_load_and_auth_via_gsc(&uc->huc);
181*f005ef32Sjsg if (ret < 0)
182*f005ef32Sjsg drm_err(&i915->drm, "failed to load huc via gsc %d\n", ret);
183*f005ef32Sjsg }
184*f005ef32Sjsg }
185*f005ef32Sjsg
1861bb76ff1Sjsg /* if we are suspended, the HW will be re-initialized on resume */
1871bb76ff1Sjsg wakeref = intel_runtime_pm_get_if_in_use(&i915->runtime_pm);
1881bb76ff1Sjsg if (!wakeref)
1891bb76ff1Sjsg return 0;
1901bb76ff1Sjsg
1911bb76ff1Sjsg /* the component is required to fully start the PXP HW */
192*f005ef32Sjsg if (intel_pxp_is_enabled(pxp))
1931bb76ff1Sjsg intel_pxp_init_hw(pxp);
1941bb76ff1Sjsg
1951bb76ff1Sjsg intel_runtime_pm_put(&i915->runtime_pm, wakeref);
1961bb76ff1Sjsg
197*f005ef32Sjsg return ret;
1981bb76ff1Sjsg }
1991bb76ff1Sjsg
i915_pxp_tee_component_unbind(struct device * i915_kdev,struct device * tee_kdev,void * data)2001bb76ff1Sjsg static void i915_pxp_tee_component_unbind(struct device *i915_kdev,
2011bb76ff1Sjsg struct device *tee_kdev, void *data)
2021bb76ff1Sjsg {
2031bb76ff1Sjsg struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
204*f005ef32Sjsg struct intel_pxp *pxp = i915->pxp;
2051bb76ff1Sjsg intel_wakeref_t wakeref;
2061bb76ff1Sjsg
207*f005ef32Sjsg if (intel_pxp_is_enabled(pxp))
2081bb76ff1Sjsg with_intel_runtime_pm_if_in_use(&i915->runtime_pm, wakeref)
2091bb76ff1Sjsg intel_pxp_fini_hw(pxp);
2101bb76ff1Sjsg
2111bb76ff1Sjsg mutex_lock(&pxp->tee_mutex);
2121bb76ff1Sjsg pxp->pxp_component = NULL;
2131bb76ff1Sjsg mutex_unlock(&pxp->tee_mutex);
214*f005ef32Sjsg
215*f005ef32Sjsg if (pxp->dev_link) {
216*f005ef32Sjsg STUB();
217*f005ef32Sjsg #ifdef notyet
218*f005ef32Sjsg device_link_del(pxp->dev_link);
219*f005ef32Sjsg #endif
220*f005ef32Sjsg pxp->dev_link = NULL;
221*f005ef32Sjsg }
2221bb76ff1Sjsg }
2231bb76ff1Sjsg
2241bb76ff1Sjsg static const struct component_ops i915_pxp_tee_component_ops = {
2251bb76ff1Sjsg .bind = i915_pxp_tee_component_bind,
2261bb76ff1Sjsg .unbind = i915_pxp_tee_component_unbind,
2271bb76ff1Sjsg };
2281bb76ff1Sjsg
alloc_streaming_command(struct intel_pxp * pxp)229*f005ef32Sjsg static int alloc_streaming_command(struct intel_pxp *pxp)
230*f005ef32Sjsg {
231*f005ef32Sjsg struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
232*f005ef32Sjsg struct drm_i915_gem_object *obj = NULL;
233*f005ef32Sjsg void *cmd;
234*f005ef32Sjsg int err;
235*f005ef32Sjsg
236*f005ef32Sjsg pxp->stream_cmd.obj = NULL;
237*f005ef32Sjsg pxp->stream_cmd.vaddr = NULL;
238*f005ef32Sjsg
239*f005ef32Sjsg if (!IS_DGFX(i915))
240*f005ef32Sjsg return 0;
241*f005ef32Sjsg
242*f005ef32Sjsg /* allocate lmem object of one page for PXP command memory and store it */
243*f005ef32Sjsg obj = i915_gem_object_create_lmem(i915, PAGE_SIZE, I915_BO_ALLOC_CONTIGUOUS);
244*f005ef32Sjsg if (IS_ERR(obj)) {
245*f005ef32Sjsg drm_err(&i915->drm, "Failed to allocate pxp streaming command!\n");
246*f005ef32Sjsg return PTR_ERR(obj);
247*f005ef32Sjsg }
248*f005ef32Sjsg
249*f005ef32Sjsg err = i915_gem_object_pin_pages_unlocked(obj);
250*f005ef32Sjsg if (err) {
251*f005ef32Sjsg drm_err(&i915->drm, "Failed to pin gsc message page!\n");
252*f005ef32Sjsg goto out_put;
253*f005ef32Sjsg }
254*f005ef32Sjsg
255*f005ef32Sjsg /* map the lmem into the virtual memory pointer */
256*f005ef32Sjsg cmd = i915_gem_object_pin_map_unlocked(obj,
257*f005ef32Sjsg intel_gt_coherent_map_type(pxp->ctrl_gt,
258*f005ef32Sjsg obj, true));
259*f005ef32Sjsg if (IS_ERR(cmd)) {
260*f005ef32Sjsg drm_err(&i915->drm, "Failed to map gsc message page!\n");
261*f005ef32Sjsg err = PTR_ERR(cmd);
262*f005ef32Sjsg goto out_unpin;
263*f005ef32Sjsg }
264*f005ef32Sjsg
265*f005ef32Sjsg memset(cmd, 0, obj->base.size);
266*f005ef32Sjsg
267*f005ef32Sjsg pxp->stream_cmd.obj = obj;
268*f005ef32Sjsg pxp->stream_cmd.vaddr = cmd;
269*f005ef32Sjsg
270*f005ef32Sjsg return 0;
271*f005ef32Sjsg
272*f005ef32Sjsg out_unpin:
273*f005ef32Sjsg i915_gem_object_unpin_pages(obj);
274*f005ef32Sjsg out_put:
275*f005ef32Sjsg i915_gem_object_put(obj);
276*f005ef32Sjsg return err;
277*f005ef32Sjsg }
278*f005ef32Sjsg
free_streaming_command(struct intel_pxp * pxp)279*f005ef32Sjsg static void free_streaming_command(struct intel_pxp *pxp)
280*f005ef32Sjsg {
281*f005ef32Sjsg struct drm_i915_gem_object *obj = fetch_and_zero(&pxp->stream_cmd.obj);
282*f005ef32Sjsg
283*f005ef32Sjsg if (!obj)
284*f005ef32Sjsg return;
285*f005ef32Sjsg
286*f005ef32Sjsg i915_gem_object_unpin_map(obj);
287*f005ef32Sjsg i915_gem_object_unpin_pages(obj);
288*f005ef32Sjsg i915_gem_object_put(obj);
289*f005ef32Sjsg }
290*f005ef32Sjsg
intel_pxp_tee_component_init(struct intel_pxp * pxp)2911bb76ff1Sjsg int intel_pxp_tee_component_init(struct intel_pxp *pxp)
2921bb76ff1Sjsg {
2931bb76ff1Sjsg int ret;
294*f005ef32Sjsg struct intel_gt *gt = pxp->ctrl_gt;
2951bb76ff1Sjsg struct drm_i915_private *i915 = gt->i915;
2961bb76ff1Sjsg
297*f005ef32Sjsg ret = alloc_streaming_command(pxp);
298*f005ef32Sjsg if (ret)
299*f005ef32Sjsg return ret;
300*f005ef32Sjsg
3011bb76ff1Sjsg ret = component_add_typed(i915->drm.dev, &i915_pxp_tee_component_ops,
3021bb76ff1Sjsg I915_COMPONENT_PXP);
3031bb76ff1Sjsg if (ret < 0) {
3041bb76ff1Sjsg drm_err(&i915->drm, "Failed to add PXP component (%d)\n", ret);
305*f005ef32Sjsg goto out_free;
3061bb76ff1Sjsg }
3071bb76ff1Sjsg
3081bb76ff1Sjsg pxp->pxp_component_added = true;
3091bb76ff1Sjsg
3101bb76ff1Sjsg return 0;
311*f005ef32Sjsg
312*f005ef32Sjsg out_free:
313*f005ef32Sjsg free_streaming_command(pxp);
314*f005ef32Sjsg return ret;
3151bb76ff1Sjsg }
3161bb76ff1Sjsg
intel_pxp_tee_component_fini(struct intel_pxp * pxp)3171bb76ff1Sjsg void intel_pxp_tee_component_fini(struct intel_pxp *pxp)
3181bb76ff1Sjsg {
319*f005ef32Sjsg struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
3201bb76ff1Sjsg
3211bb76ff1Sjsg if (!pxp->pxp_component_added)
3221bb76ff1Sjsg return;
3231bb76ff1Sjsg
3241bb76ff1Sjsg component_del(i915->drm.dev, &i915_pxp_tee_component_ops);
3251bb76ff1Sjsg pxp->pxp_component_added = false;
326*f005ef32Sjsg
327*f005ef32Sjsg free_streaming_command(pxp);
3281bb76ff1Sjsg }
3291bb76ff1Sjsg
intel_pxp_tee_cmd_create_arb_session(struct intel_pxp * pxp,int arb_session_id)3301bb76ff1Sjsg int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp *pxp,
3311bb76ff1Sjsg int arb_session_id)
3321bb76ff1Sjsg {
333*f005ef32Sjsg struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
334*f005ef32Sjsg struct pxp42_create_arb_in msg_in = {0};
335*f005ef32Sjsg struct pxp42_create_arb_out msg_out = {0};
3361bb76ff1Sjsg int ret;
3371bb76ff1Sjsg
338*f005ef32Sjsg msg_in.header.api_version = PXP_APIVER(4, 2);
339*f005ef32Sjsg msg_in.header.command_id = PXP42_CMDID_INIT_SESSION;
3401bb76ff1Sjsg msg_in.header.buffer_len = sizeof(msg_in) - sizeof(msg_in.header);
341*f005ef32Sjsg msg_in.protection_mode = PXP42_ARB_SESSION_MODE_HEAVY;
3421bb76ff1Sjsg msg_in.session_id = arb_session_id;
3431bb76ff1Sjsg
3441bb76ff1Sjsg ret = intel_pxp_tee_io_message(pxp,
3451bb76ff1Sjsg &msg_in, sizeof(msg_in),
3461bb76ff1Sjsg &msg_out, sizeof(msg_out),
3471bb76ff1Sjsg NULL);
3481bb76ff1Sjsg
349*f005ef32Sjsg if (ret) {
350*f005ef32Sjsg drm_err(&i915->drm, "Failed to send tee msg init arb session, ret=[%d]\n", ret);
351*f005ef32Sjsg } else if (msg_out.header.status != 0) {
352*f005ef32Sjsg if (is_fw_err_platform_config(msg_out.header.status)) {
353*f005ef32Sjsg drm_info_once(&i915->drm,
354*f005ef32Sjsg "PXP init-arb-session-%d failed due to BIOS/SOC:0x%08x:%s\n",
355*f005ef32Sjsg arb_session_id, msg_out.header.status,
356*f005ef32Sjsg fw_err_to_string(msg_out.header.status));
357*f005ef32Sjsg } else {
358*f005ef32Sjsg drm_dbg(&i915->drm, "PXP init-arb-session--%d failed 0x%08x:%st:\n",
359*f005ef32Sjsg arb_session_id, msg_out.header.status,
360*f005ef32Sjsg fw_err_to_string(msg_out.header.status));
361*f005ef32Sjsg drm_dbg(&i915->drm, " cmd-detail: ID=[0x%08x],API-Ver-[0x%08x]\n",
362*f005ef32Sjsg msg_in.header.command_id, msg_in.header.api_version);
363*f005ef32Sjsg }
364*f005ef32Sjsg }
3651bb76ff1Sjsg
3661bb76ff1Sjsg return ret;
3671bb76ff1Sjsg }
368*f005ef32Sjsg
intel_pxp_tee_end_arb_fw_session(struct intel_pxp * pxp,u32 session_id)369*f005ef32Sjsg void intel_pxp_tee_end_arb_fw_session(struct intel_pxp *pxp, u32 session_id)
370*f005ef32Sjsg {
371*f005ef32Sjsg struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
372*f005ef32Sjsg struct pxp42_inv_stream_key_in msg_in = {0};
373*f005ef32Sjsg struct pxp42_inv_stream_key_out msg_out = {0};
374*f005ef32Sjsg int ret, trials = 0;
375*f005ef32Sjsg
376*f005ef32Sjsg try_again:
377*f005ef32Sjsg memset(&msg_in, 0, sizeof(msg_in));
378*f005ef32Sjsg memset(&msg_out, 0, sizeof(msg_out));
379*f005ef32Sjsg msg_in.header.api_version = PXP_APIVER(4, 2);
380*f005ef32Sjsg msg_in.header.command_id = PXP42_CMDID_INVALIDATE_STREAM_KEY;
381*f005ef32Sjsg msg_in.header.buffer_len = sizeof(msg_in) - sizeof(msg_in.header);
382*f005ef32Sjsg
383*f005ef32Sjsg msg_in.header.stream_id = FIELD_PREP(PXP_CMDHDR_EXTDATA_SESSION_VALID, 1);
384*f005ef32Sjsg msg_in.header.stream_id |= FIELD_PREP(PXP_CMDHDR_EXTDATA_APP_TYPE, 0);
385*f005ef32Sjsg msg_in.header.stream_id |= FIELD_PREP(PXP_CMDHDR_EXTDATA_SESSION_ID, session_id);
386*f005ef32Sjsg
387*f005ef32Sjsg ret = intel_pxp_tee_io_message(pxp,
388*f005ef32Sjsg &msg_in, sizeof(msg_in),
389*f005ef32Sjsg &msg_out, sizeof(msg_out),
390*f005ef32Sjsg NULL);
391*f005ef32Sjsg
392*f005ef32Sjsg /* Cleanup coherency between GT and Firmware is critical, so try again if it fails */
393*f005ef32Sjsg if ((ret || msg_out.header.status != 0x0) && ++trials < 3)
394*f005ef32Sjsg goto try_again;
395*f005ef32Sjsg
396*f005ef32Sjsg if (ret) {
397*f005ef32Sjsg drm_err(&i915->drm, "Failed to send tee msg for inv-stream-key-%u, ret=[%d]\n",
398*f005ef32Sjsg session_id, ret);
399*f005ef32Sjsg } else if (msg_out.header.status != 0) {
400*f005ef32Sjsg if (is_fw_err_platform_config(msg_out.header.status)) {
401*f005ef32Sjsg drm_info_once(&i915->drm,
402*f005ef32Sjsg "PXP inv-stream-key-%u failed due to BIOS/SOC :0x%08x:%s\n",
403*f005ef32Sjsg session_id, msg_out.header.status,
404*f005ef32Sjsg fw_err_to_string(msg_out.header.status));
405*f005ef32Sjsg } else {
406*f005ef32Sjsg drm_dbg(&i915->drm, "PXP inv-stream-key-%u failed 0x%08x:%s:\n",
407*f005ef32Sjsg session_id, msg_out.header.status,
408*f005ef32Sjsg fw_err_to_string(msg_out.header.status));
409*f005ef32Sjsg drm_dbg(&i915->drm, " cmd-detail: ID=[0x%08x],API-Ver-[0x%08x]\n",
410*f005ef32Sjsg msg_in.header.command_id, msg_in.header.api_version);
411*f005ef32Sjsg }
412*f005ef32Sjsg }
413*f005ef32Sjsg }
414