Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915/pxp: Implement arb session teardown

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. Additionally, we want to emit a
teardown operation to make sure we're clean on boot and resume

v2: emit in the ring, use high prio request (Chris)
v3: better defines, stalling flush, cleaned up and renamed submission
funcs (Chris)
v12: fix uninitialized variable bug

Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210924191452.1539378-9-alan.previn.teres.alexis@intel.com

authored by

Huang, Sean Z and committed by
Rodrigo Vivi
95c9e122 cbbd3764

+212 -4
+1
drivers/gpu/drm/i915/Makefile
··· 281 281 # Protected execution platform (PXP) support 282 282 i915-$(CONFIG_DRM_I915_PXP) += \ 283 283 pxp/intel_pxp.o \ 284 + pxp/intel_pxp_cmd.o \ 284 285 pxp/intel_pxp_session.o \ 285 286 pxp/intel_pxp_tee.o 286 287
+19 -3
drivers/gpu/drm/i915/gt/intel_gpu_commands.h
··· 28 28 #define INSTR_26_TO_24_MASK 0x7000000 29 29 #define INSTR_26_TO_24_SHIFT 24 30 30 31 + #define __INSTR(client) ((client) << INSTR_CLIENT_SHIFT) 32 + 31 33 /* 32 34 * Memory interface instructions used by the kernel 33 35 */ 34 - #define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags)) 36 + #define MI_INSTR(opcode, flags) \ 37 + (__INSTR(INSTR_MI_CLIENT) | (opcode) << 23 | (flags)) 35 38 /* Many MI commands use bit 22 of the header dword for GGTT vs PPGTT */ 36 39 #define MI_GLOBAL_GTT (1<<22) 37 40 ··· 60 57 #define MI_SUSPEND_FLUSH MI_INSTR(0x0b, 0) 61 58 #define MI_SUSPEND_FLUSH_EN (1<<0) 62 59 #define MI_SET_APPID MI_INSTR(0x0e, 0) 60 + #define MI_SET_APPID_SESSION_ID(x) ((x) << 0) 63 61 #define MI_OVERLAY_FLIP MI_INSTR(0x11, 0) 64 62 #define MI_OVERLAY_CONTINUE (0x0<<21) 65 63 #define MI_OVERLAY_ON (0x1<<21) ··· 150 146 #define MI_STORE_REGISTER_MEM_GEN8 MI_INSTR(0x24, 2) 151 147 #define MI_SRM_LRM_GLOBAL_GTT (1<<22) 152 148 #define MI_FLUSH_DW MI_INSTR(0x26, 1) /* for GEN6 */ 149 + #define MI_FLUSH_DW_PROTECTED_MEM_EN (1 << 22) 153 150 #define MI_FLUSH_DW_STORE_INDEX (1<<21) 154 151 #define MI_INVALIDATE_TLB (1<<18) 155 152 #define MI_FLUSH_DW_OP_STOREDW (1<<14) ··· 278 273 #define MI_MATH_REG_CF 0x33 279 274 280 275 /* 276 + * Media instructions used by the kernel 277 + */ 278 + #define MEDIA_INSTR(pipe, op, sub_op, flags) \ 279 + (__INSTR(INSTR_RC_CLIENT) | (pipe) << INSTR_SUBCLIENT_SHIFT | \ 280 + (op) << INSTR_26_TO_24_SHIFT | (sub_op) << 16 | (flags)) 281 + 282 + #define MFX_WAIT MEDIA_INSTR(1, 0, 0, 0) 283 + #define MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG REG_BIT(8) 284 + #define MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG REG_BIT(9) 285 + 286 + #define CRYPTO_KEY_EXCHANGE MEDIA_INSTR(2, 6, 9, 0) 287 + 288 + /* 281 289 * Commands used only by the command parser 282 290 */ 283 291 #define MI_SET_PREDICATE MI_INSTR(0x01, 0) ··· 345 327 ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x46<<16)) 346 328 #define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_PS \ 347 329 ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x47<<16)) 348 - 349 - #define MFX_WAIT ((0x3<<29)|(0x1<<27)|(0x0<<16)) 350 330 351 331 #define COLOR_BLT ((0x2<<29)|(0x40<<22)) 352 332 #define SRC_COPY_BLT ((0x2<<29)|(0x43<<22))
+6 -1
drivers/gpu/drm/i915/pxp/intel_pxp.c
··· 110 110 111 111 void intel_pxp_init_hw(struct intel_pxp *pxp) 112 112 { 113 + int ret; 114 + 113 115 kcr_pxp_enable(pxp_to_gt(pxp)); 114 116 115 - intel_pxp_create_arb_session(pxp); 117 + /* always emit a full termination to clean the state */ 118 + ret = intel_pxp_terminate_arb_session_and_global(pxp); 119 + if (!ret) 120 + intel_pxp_create_arb_session(pxp); 116 121 } 117 122 118 123 void intel_pxp_fini_hw(struct intel_pxp *pxp)
+141
drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
··· 1 + // SPDX-License-Identifier: MIT 2 + /* 3 + * Copyright(c) 2020, Intel Corporation. All rights reserved. 4 + */ 5 + 6 + #include "intel_pxp.h" 7 + #include "intel_pxp_cmd.h" 8 + #include "intel_pxp_session.h" 9 + #include "gt/intel_context.h" 10 + #include "gt/intel_engine_pm.h" 11 + #include "gt/intel_gpu_commands.h" 12 + #include "gt/intel_ring.h" 13 + 14 + #include "i915_trace.h" 15 + 16 + /* stall until prior PXP and MFX/HCP/HUC objects are cmopleted */ 17 + #define MFX_WAIT_PXP (MFX_WAIT | \ 18 + MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG | \ 19 + MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG) 20 + 21 + static u32 *pxp_emit_session_selection(u32 *cs, u32 idx) 22 + { 23 + *cs++ = MFX_WAIT_PXP; 24 + 25 + /* pxp off */ 26 + *cs++ = MI_FLUSH_DW; 27 + *cs++ = 0; 28 + *cs++ = 0; 29 + 30 + /* select session */ 31 + *cs++ = MI_SET_APPID | MI_SET_APPID_SESSION_ID(idx); 32 + 33 + *cs++ = MFX_WAIT_PXP; 34 + 35 + /* pxp on */ 36 + *cs++ = MI_FLUSH_DW | MI_FLUSH_DW_PROTECTED_MEM_EN | 37 + MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_DW_STORE_INDEX; 38 + *cs++ = I915_GEM_HWS_PXP_ADDR | MI_FLUSH_DW_USE_GTT; 39 + *cs++ = 0; 40 + 41 + *cs++ = MFX_WAIT_PXP; 42 + 43 + return cs; 44 + } 45 + 46 + static u32 *pxp_emit_inline_termination(u32 *cs) 47 + { 48 + /* session inline termination */ 49 + *cs++ = CRYPTO_KEY_EXCHANGE; 50 + *cs++ = 0; 51 + 52 + return cs; 53 + } 54 + 55 + static u32 *pxp_emit_session_termination(u32 *cs, u32 idx) 56 + { 57 + cs = pxp_emit_session_selection(cs, idx); 58 + cs = pxp_emit_inline_termination(cs); 59 + 60 + return cs; 61 + } 62 + 63 + static u32 *pxp_emit_wait(u32 *cs) 64 + { 65 + /* wait for cmds to go through */ 66 + *cs++ = MFX_WAIT_PXP; 67 + *cs++ = 0; 68 + 69 + return cs; 70 + } 71 + 72 + /* 73 + * if we ever need to terminate more than one session, we can submit multiple 74 + * selections and terminations back-to-back with a single wait at the end 75 + */ 76 + #define SELECTION_LEN 10 77 + #define TERMINATION_LEN 2 78 + #define SESSION_TERMINATION_LEN(x) ((SELECTION_LEN + TERMINATION_LEN) * (x)) 79 + #define WAIT_LEN 2 80 + 81 + static void pxp_request_commit(struct i915_request *rq) 82 + { 83 + struct i915_sched_attr attr = { .priority = I915_PRIORITY_MAX }; 84 + struct intel_timeline * const tl = i915_request_timeline(rq); 85 + 86 + lockdep_unpin_lock(&tl->mutex, rq->cookie); 87 + 88 + trace_i915_request_add(rq); 89 + __i915_request_commit(rq); 90 + __i915_request_queue(rq, &attr); 91 + 92 + mutex_unlock(&tl->mutex); 93 + } 94 + 95 + int intel_pxp_terminate_session(struct intel_pxp *pxp, u32 id) 96 + { 97 + struct i915_request *rq; 98 + struct intel_context *ce = pxp->ce; 99 + u32 *cs; 100 + int err = 0; 101 + 102 + if (!intel_pxp_is_enabled(pxp)) 103 + return 0; 104 + 105 + rq = i915_request_create(ce); 106 + if (IS_ERR(rq)) 107 + return PTR_ERR(rq); 108 + 109 + if (ce->engine->emit_init_breadcrumb) { 110 + err = ce->engine->emit_init_breadcrumb(rq); 111 + if (err) 112 + goto out_rq; 113 + } 114 + 115 + cs = intel_ring_begin(rq, SESSION_TERMINATION_LEN(1) + WAIT_LEN); 116 + if (IS_ERR(cs)) { 117 + err = PTR_ERR(cs); 118 + goto out_rq; 119 + } 120 + 121 + cs = pxp_emit_session_termination(cs, id); 122 + cs = pxp_emit_wait(cs); 123 + 124 + intel_ring_advance(rq, cs); 125 + 126 + out_rq: 127 + i915_request_get(rq); 128 + 129 + if (unlikely(err)) 130 + i915_request_set_error_once(rq, err); 131 + 132 + pxp_request_commit(rq); 133 + 134 + if (!err && i915_request_wait(rq, 0, HZ / 5) < 0) 135 + err = -ETIME; 136 + 137 + i915_request_put(rq); 138 + 139 + return err; 140 + } 141 +
+15
drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Copyright(c) 2020, Intel Corporation. All rights reserved. 4 + */ 5 + 6 + #ifndef __INTEL_PXP_CMD_H__ 7 + #define __INTEL_PXP_CMD_H__ 8 + 9 + #include <linux/types.h> 10 + 11 + struct intel_pxp; 12 + 13 + int intel_pxp_terminate_session(struct intel_pxp *pxp, u32 idx); 14 + 15 + #endif /* __INTEL_PXP_CMD_H__ */
+29
drivers/gpu/drm/i915/pxp/intel_pxp_session.c
··· 7 7 #include "i915_drv.h" 8 8 9 9 #include "intel_pxp.h" 10 + #include "intel_pxp_cmd.h" 10 11 #include "intel_pxp_session.h" 11 12 #include "intel_pxp_tee.h" 12 13 #include "intel_pxp_types.h" ··· 15 14 #define ARB_SESSION I915_PROTECTED_CONTENT_DEFAULT_SESSION /* shorter define */ 16 15 17 16 #define GEN12_KCR_SIP _MMIO(0x32260) /* KCR hwdrm session in play 0-31 */ 17 + 18 + /* PXP global terminate register for session termination */ 19 + #define PXP_GLOBAL_TERMINATE _MMIO(0x320f8) 18 20 19 21 static bool intel_pxp_session_is_in_play(struct intel_pxp *pxp, u32 id) 20 22 { ··· 75 71 pxp->arb_is_valid = true; 76 72 77 73 return 0; 74 + } 75 + 76 + int intel_pxp_terminate_arb_session_and_global(struct intel_pxp *pxp) 77 + { 78 + int ret; 79 + struct intel_gt *gt = pxp_to_gt(pxp); 80 + 81 + pxp->arb_is_valid = false; 82 + 83 + /* terminate the hw sessions */ 84 + ret = intel_pxp_terminate_session(pxp, ARB_SESSION); 85 + if (ret) { 86 + drm_err(&gt->i915->drm, "Failed to submit session termination\n"); 87 + return ret; 88 + } 89 + 90 + ret = pxp_wait_for_session_state(pxp, ARB_SESSION, false); 91 + if (ret) { 92 + drm_err(&gt->i915->drm, "Session state did not clear\n"); 93 + return ret; 94 + } 95 + 96 + intel_uncore_write(gt->uncore, PXP_GLOBAL_TERMINATE, 1); 97 + 98 + return ret; 78 99 }
+1
drivers/gpu/drm/i915/pxp/intel_pxp_session.h
··· 11 11 struct intel_pxp; 12 12 13 13 int intel_pxp_create_arb_session(struct intel_pxp *pxp); 14 + int intel_pxp_terminate_arb_session_and_global(struct intel_pxp *pxp); 14 15 15 16 #endif /* __INTEL_PXP_SESSION_H__ */