Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: MIT
0002 /*
0003  * Copyright(c) 2020, Intel Corporation. All rights reserved.
0004  */
0005 
0006 #include "intel_pxp.h"
0007 #include "intel_pxp_cmd.h"
0008 #include "intel_pxp_session.h"
0009 #include "gt/intel_context.h"
0010 #include "gt/intel_engine_pm.h"
0011 #include "gt/intel_gpu_commands.h"
0012 #include "gt/intel_ring.h"
0013 
0014 #include "i915_trace.h"
0015 
0016 /* stall until prior PXP and MFX/HCP/HUC objects are cmopleted */
0017 #define MFX_WAIT_PXP (MFX_WAIT | \
0018               MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG | \
0019               MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG)
0020 
0021 static u32 *pxp_emit_session_selection(u32 *cs, u32 idx)
0022 {
0023     *cs++ = MFX_WAIT_PXP;
0024 
0025     /* pxp off */
0026     *cs++ = MI_FLUSH_DW;
0027     *cs++ = 0;
0028     *cs++ = 0;
0029 
0030     /* select session */
0031     *cs++ = MI_SET_APPID | MI_SET_APPID_SESSION_ID(idx);
0032 
0033     *cs++ = MFX_WAIT_PXP;
0034 
0035     /* pxp on */
0036     *cs++ = MI_FLUSH_DW | MI_FLUSH_DW_PROTECTED_MEM_EN |
0037         MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_DW_STORE_INDEX;
0038     *cs++ = I915_GEM_HWS_PXP_ADDR | MI_FLUSH_DW_USE_GTT;
0039     *cs++ = 0;
0040 
0041     *cs++ = MFX_WAIT_PXP;
0042 
0043     return cs;
0044 }
0045 
0046 static u32 *pxp_emit_inline_termination(u32 *cs)
0047 {
0048     /* session inline termination */
0049     *cs++ = CRYPTO_KEY_EXCHANGE;
0050     *cs++ = 0;
0051 
0052     return cs;
0053 }
0054 
0055 static u32 *pxp_emit_session_termination(u32 *cs, u32 idx)
0056 {
0057     cs = pxp_emit_session_selection(cs, idx);
0058     cs = pxp_emit_inline_termination(cs);
0059 
0060     return cs;
0061 }
0062 
0063 static u32 *pxp_emit_wait(u32 *cs)
0064 {
0065     /* wait for cmds to go through */
0066     *cs++ = MFX_WAIT_PXP;
0067     *cs++ = 0;
0068 
0069     return cs;
0070 }
0071 
0072 /*
0073  * if we ever need to terminate more than one session, we can submit multiple
0074  * selections and terminations back-to-back with a single wait at the end
0075  */
0076 #define SELECTION_LEN 10
0077 #define TERMINATION_LEN 2
0078 #define SESSION_TERMINATION_LEN(x) ((SELECTION_LEN + TERMINATION_LEN) * (x))
0079 #define WAIT_LEN 2
0080 
0081 static void pxp_request_commit(struct i915_request *rq)
0082 {
0083     struct i915_sched_attr attr = { .priority = I915_PRIORITY_MAX };
0084     struct intel_timeline * const tl = i915_request_timeline(rq);
0085 
0086     lockdep_unpin_lock(&tl->mutex, rq->cookie);
0087 
0088     trace_i915_request_add(rq);
0089     __i915_request_commit(rq);
0090     __i915_request_queue(rq, &attr);
0091 
0092     mutex_unlock(&tl->mutex);
0093 }
0094 
0095 int intel_pxp_terminate_session(struct intel_pxp *pxp, u32 id)
0096 {
0097     struct i915_request *rq;
0098     struct intel_context *ce = pxp->ce;
0099     u32 *cs;
0100     int err = 0;
0101 
0102     if (!intel_pxp_is_enabled(pxp))
0103         return 0;
0104 
0105     rq = i915_request_create(ce);
0106     if (IS_ERR(rq))
0107         return PTR_ERR(rq);
0108 
0109     if (ce->engine->emit_init_breadcrumb) {
0110         err = ce->engine->emit_init_breadcrumb(rq);
0111         if (err)
0112             goto out_rq;
0113     }
0114 
0115     cs = intel_ring_begin(rq, SESSION_TERMINATION_LEN(1) + WAIT_LEN);
0116     if (IS_ERR(cs)) {
0117         err = PTR_ERR(cs);
0118         goto out_rq;
0119     }
0120 
0121     cs = pxp_emit_session_termination(cs, id);
0122     cs = pxp_emit_wait(cs);
0123 
0124     intel_ring_advance(rq, cs);
0125 
0126 out_rq:
0127     i915_request_get(rq);
0128 
0129     if (unlikely(err))
0130         i915_request_set_error_once(rq, err);
0131 
0132     pxp_request_commit(rq);
0133 
0134     if (!err && i915_request_wait(rq, 0, HZ / 5) < 0)
0135         err = -ETIME;
0136 
0137     i915_request_put(rq);
0138 
0139     return err;
0140 }
0141