drm/xe/pxp: Add VCS inline termination support
The key termination is done with a specific submission to the VCS engine. This flow will be triggered in response to a termination interrupt, whose handling is coming in a follow-up patch in the series. v2: clean up defines and command emission code. (John) Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Reviewed-by: John Harrison <John.C.Harrison@Intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20250129174140.948829-4-daniele.ceraolospurio@intel.com
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#define XE_INSTR_CMD_TYPE GENMASK(31, 29)
|
||||
#define XE_INSTR_MI REG_FIELD_PREP(XE_INSTR_CMD_TYPE, 0x0)
|
||||
#define XE_INSTR_GSC REG_FIELD_PREP(XE_INSTR_CMD_TYPE, 0x2)
|
||||
#define XE_INSTR_VIDEOPIPE REG_FIELD_PREP(XE_INSTR_CMD_TYPE, 0x3)
|
||||
#define XE_INSTR_GFXPIPE REG_FIELD_PREP(XE_INSTR_CMD_TYPE, 0x3)
|
||||
#define XE_INSTR_GFX_STATE REG_FIELD_PREP(XE_INSTR_CMD_TYPE, 0x4)
|
||||
|
||||
|
||||
28
drivers/gpu/drm/xe/instructions/xe_mfx_commands.h
Normal file
28
drivers/gpu/drm/xe/instructions/xe_mfx_commands.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright © 2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef _XE_MFX_COMMANDS_H_
|
||||
#define _XE_MFX_COMMANDS_H_
|
||||
|
||||
#include "instructions/xe_instr_defs.h"
|
||||
|
||||
#define MFX_CMD_SUBTYPE REG_GENMASK(28, 27) /* A.K.A cmd pipe */
|
||||
#define MFX_CMD_OPCODE REG_GENMASK(26, 24)
|
||||
#define MFX_CMD_SUB_OPCODE REG_GENMASK(23, 16)
|
||||
#define MFX_FLAGS_AND_LEN REG_GENMASK(15, 0)
|
||||
|
||||
#define XE_MFX_INSTR(subtype, op, sub_op) \
|
||||
(XE_INSTR_VIDEOPIPE | \
|
||||
REG_FIELD_PREP(MFX_CMD_SUBTYPE, subtype) | \
|
||||
REG_FIELD_PREP(MFX_CMD_OPCODE, op) | \
|
||||
REG_FIELD_PREP(MFX_CMD_SUB_OPCODE, sub_op))
|
||||
|
||||
#define MFX_WAIT XE_MFX_INSTR(1, 0, 0)
|
||||
#define MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG REG_BIT(9)
|
||||
#define MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG REG_BIT(8)
|
||||
|
||||
#define CRYPTO_KEY_EXCHANGE XE_MFX_INSTR(2, 6, 9)
|
||||
|
||||
#endif
|
||||
@@ -48,6 +48,7 @@
|
||||
#define MI_LRI_LEN(x) (((x) & 0xff) + 1)
|
||||
|
||||
#define MI_FLUSH_DW __MI_INSTR(0x26)
|
||||
#define MI_FLUSH_DW_PROTECTED_MEM_EN REG_BIT(22)
|
||||
#define MI_FLUSH_DW_STORE_INDEX REG_BIT(21)
|
||||
#define MI_INVALIDATE_TLB REG_BIT(18)
|
||||
#define MI_FLUSH_DW_CCS REG_BIT(16)
|
||||
@@ -66,4 +67,8 @@
|
||||
|
||||
#define MI_BATCH_BUFFER_START __MI_INSTR(0x31)
|
||||
|
||||
#define MI_SET_APPID __MI_INSTR(0x0e)
|
||||
#define MI_SET_APPID_SESSION_ID_MASK REG_GENMASK(6, 0)
|
||||
#define MI_SET_APPID_SESSION_ID(x) REG_FIELD_PREP(MI_SET_APPID_SESSION_ID_MASK, x)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -39,7 +39,8 @@ struct xe_lrc_snapshot {
|
||||
u32 ctx_job_timestamp;
|
||||
};
|
||||
|
||||
#define LRC_PPHWSP_SCRATCH_ADDR (0x34 * 4)
|
||||
#define LRC_PPHWSP_FLUSH_INVAL_SCRATCH_ADDR (0x34 * 4)
|
||||
#define LRC_PPHWSP_PXP_INVAL_SCRATCH_ADDR (0x40 * 4)
|
||||
|
||||
struct xe_lrc *xe_lrc_create(struct xe_hw_engine *hwe, struct xe_vm *vm,
|
||||
u32 ring_size, u16 msix_vec);
|
||||
|
||||
@@ -5,15 +5,21 @@
|
||||
|
||||
#include "xe_pxp_submit.h"
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <uapi/drm/xe_drm.h>
|
||||
|
||||
#include "xe_device_types.h"
|
||||
#include "xe_bb.h"
|
||||
#include "xe_bo.h"
|
||||
#include "xe_exec_queue.h"
|
||||
#include "xe_gsc_submit.h"
|
||||
#include "xe_gt.h"
|
||||
#include "xe_lrc.h"
|
||||
#include "xe_pxp_types.h"
|
||||
#include "xe_sched_job.h"
|
||||
#include "xe_vm.h"
|
||||
#include "instructions/xe_mfx_commands.h"
|
||||
#include "instructions/xe_mi_commands.h"
|
||||
|
||||
/*
|
||||
* The VCS is used for kernel-owned GGTT submissions to issue key termination.
|
||||
@@ -197,3 +203,111 @@ void xe_pxp_destroy_execution_resources(struct xe_pxp *pxp)
|
||||
destroy_gsc_client_resources(&pxp->gsc_res);
|
||||
destroy_vcs_execution_resources(pxp);
|
||||
}
|
||||
|
||||
#define emit_cmd(xe_, map_, offset_, val_) \
|
||||
xe_map_wr(xe_, map_, (offset_) * sizeof(u32), u32, val_)
|
||||
|
||||
/* stall until prior PXP and MFX/HCP/HUC objects are completed */
|
||||
#define MFX_WAIT_PXP (MFX_WAIT | \
|
||||
MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG | \
|
||||
MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG)
|
||||
static u32 pxp_emit_wait(struct xe_device *xe, struct iosys_map *batch, u32 offset)
|
||||
{
|
||||
/* wait for cmds to go through */
|
||||
emit_cmd(xe, batch, offset++, MFX_WAIT_PXP);
|
||||
emit_cmd(xe, batch, offset++, 0);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static u32 pxp_emit_session_selection(struct xe_device *xe, struct iosys_map *batch,
|
||||
u32 offset, u32 idx)
|
||||
{
|
||||
offset = pxp_emit_wait(xe, batch, offset);
|
||||
|
||||
/* pxp off */
|
||||
emit_cmd(xe, batch, offset++, MI_FLUSH_DW | MI_FLUSH_IMM_DW);
|
||||
emit_cmd(xe, batch, offset++, 0);
|
||||
emit_cmd(xe, batch, offset++, 0);
|
||||
emit_cmd(xe, batch, offset++, 0);
|
||||
|
||||
/* select session */
|
||||
emit_cmd(xe, batch, offset++, MI_SET_APPID | MI_SET_APPID_SESSION_ID(idx));
|
||||
emit_cmd(xe, batch, offset++, 0);
|
||||
|
||||
offset = pxp_emit_wait(xe, batch, offset);
|
||||
|
||||
/* pxp on */
|
||||
emit_cmd(xe, batch, offset++, MI_FLUSH_DW |
|
||||
MI_FLUSH_DW_PROTECTED_MEM_EN |
|
||||
MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_DW_STORE_INDEX |
|
||||
MI_FLUSH_IMM_DW);
|
||||
emit_cmd(xe, batch, offset++, LRC_PPHWSP_PXP_INVAL_SCRATCH_ADDR |
|
||||
MI_FLUSH_DW_USE_GTT);
|
||||
emit_cmd(xe, batch, offset++, 0);
|
||||
emit_cmd(xe, batch, offset++, 0);
|
||||
|
||||
offset = pxp_emit_wait(xe, batch, offset);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static u32 pxp_emit_inline_termination(struct xe_device *xe,
|
||||
struct iosys_map *batch, u32 offset)
|
||||
{
|
||||
/* session inline termination */
|
||||
emit_cmd(xe, batch, offset++, CRYPTO_KEY_EXCHANGE);
|
||||
emit_cmd(xe, batch, offset++, 0);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static u32 pxp_emit_session_termination(struct xe_device *xe, struct iosys_map *batch,
|
||||
u32 offset, u32 idx)
|
||||
{
|
||||
offset = pxp_emit_session_selection(xe, batch, offset, idx);
|
||||
offset = pxp_emit_inline_termination(xe, batch, offset);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_pxp_submit_session_termination - submits a PXP inline termination
|
||||
* @pxp: the xe_pxp structure
|
||||
* @id: the session to terminate
|
||||
*
|
||||
* Emit an inline termination via the VCS engine to terminate a session.
|
||||
*
|
||||
* Returns 0 if the submission is successful, an errno value otherwise.
|
||||
*/
|
||||
int xe_pxp_submit_session_termination(struct xe_pxp *pxp, u32 id)
|
||||
{
|
||||
struct xe_sched_job *job;
|
||||
struct dma_fence *fence;
|
||||
long timeout;
|
||||
u32 offset = 0;
|
||||
u64 addr = xe_bo_ggtt_addr(pxp->vcs_exec.bo);
|
||||
|
||||
offset = pxp_emit_session_termination(pxp->xe, &pxp->vcs_exec.bo->vmap, offset, id);
|
||||
offset = pxp_emit_wait(pxp->xe, &pxp->vcs_exec.bo->vmap, offset);
|
||||
emit_cmd(pxp->xe, &pxp->vcs_exec.bo->vmap, offset, MI_BATCH_BUFFER_END);
|
||||
|
||||
job = xe_sched_job_create(pxp->vcs_exec.q, &addr);
|
||||
if (IS_ERR(job))
|
||||
return PTR_ERR(job);
|
||||
|
||||
xe_sched_job_arm(job);
|
||||
fence = dma_fence_get(&job->drm.s_fence->finished);
|
||||
xe_sched_job_push(job);
|
||||
|
||||
timeout = dma_fence_wait_timeout(fence, false, HZ);
|
||||
|
||||
dma_fence_put(fence);
|
||||
|
||||
if (!timeout)
|
||||
return -ETIMEDOUT;
|
||||
else if (timeout < 0)
|
||||
return timeout;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6,9 +6,13 @@
|
||||
#ifndef __XE_PXP_SUBMIT_H__
|
||||
#define __XE_PXP_SUBMIT_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct xe_pxp;
|
||||
|
||||
int xe_pxp_allocate_execution_resources(struct xe_pxp *pxp);
|
||||
void xe_pxp_destroy_execution_resources(struct xe_pxp *pxp);
|
||||
|
||||
int xe_pxp_submit_session_termination(struct xe_pxp *pxp, u32 id);
|
||||
|
||||
#endif /* __XE_PXP_SUBMIT_H__ */
|
||||
|
||||
@@ -118,7 +118,7 @@ static int emit_flush_invalidate(u32 flag, u32 *dw, int i)
|
||||
dw[i++] |= MI_INVALIDATE_TLB | MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_IMM_DW |
|
||||
MI_FLUSH_DW_STORE_INDEX;
|
||||
|
||||
dw[i++] = LRC_PPHWSP_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT;
|
||||
dw[i++] = LRC_PPHWSP_FLUSH_INVAL_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT;
|
||||
dw[i++] = 0;
|
||||
dw[i++] = ~0U;
|
||||
|
||||
@@ -156,7 +156,7 @@ static int emit_pipe_invalidate(u32 mask_flags, bool invalidate_tlb, u32 *dw,
|
||||
|
||||
flags &= ~mask_flags;
|
||||
|
||||
return emit_pipe_control(dw, i, 0, flags, LRC_PPHWSP_SCRATCH_ADDR, 0);
|
||||
return emit_pipe_control(dw, i, 0, flags, LRC_PPHWSP_FLUSH_INVAL_SCRATCH_ADDR, 0);
|
||||
}
|
||||
|
||||
static int emit_store_imm_ppgtt_posted(u64 addr, u64 value,
|
||||
|
||||
Reference in New Issue
Block a user