AMD General Thanks Perry, I confirmed it requires MEC195. New patch incoming with the requested changes.
Kent > -----Original Message----- > From: Yuan, Perry <[email protected]> > Sent: October 13, 2026 11:09 PM > To: Russell, Kent <[email protected]>; [email protected] > Cc: Russell, Kent <[email protected]> > Subject: RE: [PATCH] drm/amdgpu: Add log when register access is blocked in > PTL > > AMD General > > Hi Kent, > > > -----Original Message----- > > From: amd-gfx <[email protected]> On Behalf Of Kent > > Russell > > Sent: Tuesday, October 13, 2026 11:02 PM > > To: [email protected] > > Cc: Russell, Kent <[email protected]> > > Subject: [PATCH] drm/amdgpu: Add log when register access is blocked in PTL > > > > PTL will limit access to specific registers. Instead of silently dropping > > these > attempts, > > log them in dmesg for reference. Also add a dev_debug option to show what > > pasid/addr/packet type failed. > > > > Signed-off-by: Kent Russell <[email protected]> > > --- > > drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 34 +++++++++ > > .../gpu/drm/amd/amdkfd/kfd_int_process_v9.c | 76 +++++++++++++++++++ > > drivers/gpu/drm/amd/amdkfd/soc15_int.h | 1 + > > 3 files changed, 111 insertions(+) > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c > > b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c > > index 3572eb9b5758..1ce8313e3c26 100644 > > --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c > > +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c > > @@ -171,6 +171,7 @@ static int gfx_v9_4_3_get_cu_info(struct > amdgpu_device > > *adev, > > struct amdgpu_cu_info *cu_info); > > static void gfx_v9_4_3_xcc_set_safe_mode(struct amdgpu_device *adev, int > > xcc_id); static void gfx_v9_4_3_xcc_unset_safe_mode(struct amdgpu_device > > *adev, int xcc_id); > > +static void gfx_v9_4_3_enable_ptl_skip_interrupt(struct amdgpu_device > > +*adev); > > > > static void gfx_v9_4_3_kiq_set_resources(struct amdgpu_ring *kiq_ring, > > uint64_t queue_mask) > > @@ -2661,6 +2662,7 @@ static int gfx_v9_4_3_early_init(struct > amdgpu_ip_block > > *ip_block) static int gfx_v9_4_3_late_init(struct amdgpu_ip_block > > *ip_block) { > > struct amdgpu_device *adev = ip_block->adev; > > + struct amdgpu_ptl *ptl = &adev->psp.ptl; > > > > if (adev->gfx.ras && > > adev->gfx.ras->enable_watchdog_timer) > > @@ -2668,6 +2670,10 @@ static int gfx_v9_4_3_late_init(struct > amdgpu_ip_block > > *ip_block) > > > > gfx_v9_4_3_ptl_hw_init(adev); > > Could this be moved into gfx_v9_4_3_ptl_hw_init()? That function already > owns the PTL control flow, so the interrupt enable would sit with the > rest of the PTL setup and follow the same PTL state checks. > > > > > + /* Enable PTL register skip notifications if PTL is supported */ > > + if (ptl->hw_supported_state == AMDGPU_PTL_HW_SUPPORTED) > > + gfx_v9_4_3_enable_ptl_skip_interrupt(adev); > > + > > Also, older MEC firmware doesn't support the PTL register-skip > notification. Please gate the enable on a minimum MEC firmware version > (e.g. adev->gfx.mec_fw_version), so we don't turn on GENERIC1 or decode > src_id 177 as a PTL event on firmware that doesn't send it. > > Thanks. > > Perry. > > > return 0; > > } > > > > @@ -3327,6 +3333,34 @@ static int > gfx_v9_4_3_set_bad_op_fault_state(struct > > amdgpu_device *adev, > > return 0; > > } > > > > +/* > > + * Enable GENERIC1 interrupt (bit 30) for PTL register skip notifications. > > + * When FW skips a privileged register access due to PTL, it signals > > +via > > + * GENERIC1 and KFD receives interrupt source 177 with skip details. > > + */ > > +static void gfx_v9_4_3_enable_ptl_skip_interrupt(struct amdgpu_device > > +*adev) { > > + u32 mec_int_cntl_reg, mec_int_cntl; > > + int i, j, k, num_xcc; > > + > > + num_xcc = NUM_XCC(adev->gfx.xcc_mask); > > + for (i = 0; i < num_xcc; i++) { > > + for (j = 0; j < adev->gfx.mec.num_mec; j++) { > > + for (k = 0; k < adev->gfx.mec.num_pipe_per_mec; k++) { > > + mec_int_cntl_reg = > > gfx_v9_4_3_get_cpc_int_cntl(adev, i, j + 1, k); > > + > > + if (mec_int_cntl_reg) { > > + mec_int_cntl = > > RREG32_XCC(mec_int_cntl_reg, i); > > + mec_int_cntl = > > REG_SET_FIELD(mec_int_cntl, > > + CP_ME1_PIPE0_INT_CNTL, > > + GENERIC1_INT_ENABLE, > > 1); > > + WREG32_XCC(mec_int_cntl_reg, > > mec_int_cntl, i); > > + } > > + } > > + } > > + } > > +} > > + > > static int gfx_v9_4_3_set_priv_inst_fault_state(struct amdgpu_device *adev, > > struct amdgpu_irq_src *source, > > unsigned type, > > diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c > > b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c > > index e241ad7d55df..8dee8c43824d 100644 > > --- a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c > > +++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c > > @@ -123,6 +123,28 @@ enum SQ_INTERRUPT_ERROR_TYPE { #define > > KFD_SQ_INT_DATA__ERR_TYPE_MASK 0xF00000 #define > > KFD_SQ_INT_DATA__ERR_TYPE__SHIFT 20 > > > > +/* > > + * PTL (Peak TOPS Limiter) register skip notification. > > + * When FW skips a privileged register access, it sends interrupt 177 > > + * with GENERIC1 and provides packet type info in CPC_INT_CNTX_ID[31:28]. > > + */ > > +#define CPC_PTL_PACKET_TYPE_SET_UCONFIG_REG 1 > > +#define CPC_PTL_PACKET_TYPE_SET_SH_REG 2 > > +#define CPC_PTL_PACKET_TYPE_COPY_DATA_READ 3 > > +#define CPC_PTL_PACKET_TYPE_COPY_DATA_WRITE 4 > > +#define CPC_PTL_PACKET_TYPE_WRITE_DATA 5 > > +#define CPC_PTL_PACKET_TYPE_COND_WRITE 6 > > +#define CPC_PTL_PACKET_TYPE_WAIT_REG_MEM 7 > > +#define CPC_PTL_PACKET_TYPE_WAIT_REG_MEM64 8 > > + > > +/* CPC_INT_CNTX_ID[31:28]: packet type that was skipped */ > > +#define CPC_INT_CNTX_ID__PACKET_TYPE__SHIFT 28 > > +#define CPC_INT_CNTX_ID__PACKET_TYPE_MASK 0xF0000000 > > + > > +/* CPC_INT_INFO[30:28]: queue ID */ > > +#define CPC_INT_INFO__QUEUE_ID__SHIFT 28 > > +#define CPC_INT_INFO__QUEUE_ID_MASK 0x70000000 > > + > > /* > > * The debugger will send user data(m0) with PRIV=1 to indicate it requires > > * notification from the KFD with the following queue id (DOORBELL_ID) and > @@ - > > 142,6 +164,30 @@ enum SQ_INTERRUPT_ERROR_TYPE { > > KFD_DEBUG_CP_BAD_OP_ECODE_MASK) > > \ > > >> KFD_DEBUG_CP_BAD_OP_ECODE_SHIFT) > > > > +static const char *cpc_packet_type_name(uint32_t packet_type) { > > + switch (packet_type) { > > + case CPC_PTL_PACKET_TYPE_SET_UCONFIG_REG: > > + return "SET_UCONFIG_REG"; > > + case CPC_PTL_PACKET_TYPE_SET_SH_REG: > > + return "SET_SH_REG"; > > + case CPC_PTL_PACKET_TYPE_COPY_DATA_READ: > > + return "COPY_DATA_READ"; > > + case CPC_PTL_PACKET_TYPE_COPY_DATA_WRITE: > > + return "COPY_DATA_WRITE"; > > + case CPC_PTL_PACKET_TYPE_WRITE_DATA: > > + return "WRITE_DATA"; > > + case CPC_PTL_PACKET_TYPE_COND_WRITE: > > + return "COND_WRITE"; > > + case CPC_PTL_PACKET_TYPE_WAIT_REG_MEM: > > + return "WAIT_REG_MEM"; > > + case CPC_PTL_PACKET_TYPE_WAIT_REG_MEM64: > > + return "WAIT_REG_MEM64"; > > + default: > > + return "UNKNOWN"; > > + } > > +} > > + > > static void event_interrupt_poison_consumption_v9(struct kfd_node *dev, > > uint16_t pasid, uint16_t client_id) { @@ > > -352,6 +398,8 > > @@ static bool event_interrupt_isr_v9(struct kfd_node *dev, > > source_id == SOC15_INTSRC_SDMA_ECC || > > source_id == SOC15_INTSRC_SQ_INTERRUPT_MSG || > > source_id == SOC15_INTSRC_CP_BAD_OPCODE || > > + (client_id == SOC15_IH_CLIENTID_GRBM_CP && > > + source_id == SOC15_INTSRC_CP_PTL_REG_SKIP) || > > KFD_IRQ_IS_FENCE(client_id, source_id) || > > ((client_id == SOC15_IH_CLIENTID_VMC || > > client_id == SOC15_IH_CLIENTID_VMC1 || @@ -538,6 +586,34 > > @@ static void event_interrupt_wq_v9(struct kfd_node *dev, > > KFD_DEBUG_DOORBELL_ID(context_id0), > > > > KFD_EC_MASK(KFD_DEBUG_CP_BAD_OP_ECODE(context_id0)), > > NULL, 0); > > + } else if (source_id == SOC15_INTSRC_CP_PTL_REG_SKIP) { > > + uint32_t packet_type, queue_id; > > + uint32_t skipped_addr; > > + > > + /* > > + * PTL (Peak TOPS Limiter) register skip notification. > > + * FW skipped a privileged register access and is > > notifying > > KFD. > > + * Data from IH entry (not registers): > > + * - context_id0 contains CPC_INT_CNTX_ID with packet > > type in [31:28] > > + * - context_id1 contains CPC_INT_INFO with queue ID > > in > > [30:28] > > + * - context_id2 contains CPC_INT_ADDR (skipped > > register > > address) > > + * - PASID comes from CPC_INT_PASID (already extracted > > from IH entry) > > + */ > > + skipped_addr = > > SOC15_CONTEXT_ID2_FROM_IH_ENTRY(ih_ring_entry); > > + > > + /* Extract packet type from CPC_INT_CNTX_ID[31:28] */ > > + packet_type = (context_id0 & > > CPC_INT_CNTX_ID__PACKET_TYPE_MASK) >> > > + > > CPC_INT_CNTX_ID__PACKET_TYPE__SHIFT; > > + > > + /* Extract queue ID from CPC_INT_INFO[30:28] */ > > + queue_id = (context_id1 & > > CPC_INT_INFO__QUEUE_ID_MASK) >> > > + CPC_INT_INFO__QUEUE_ID__SHIFT; > > + > > + dev_info_ratelimited(dev->adev->dev, > > + "PTL: AQL request was rejected due to > > incompatible > > user input; please verify your PTL configuration."); > > + dev_dbg_ratelimited(dev->adev->dev, > > + "PTL: register access skipped - pasid 0x%x, > > queue %u, packet %s, addr 0x%x\n", > > + pasid, queue_id, > > cpc_packet_type_name(packet_type), skipped_addr); > > } > > } else if (client_id == SOC15_IH_CLIENTID_SDMA0 || > > client_id == SOC15_IH_CLIENTID_SDMA1 || diff --git > > a/drivers/gpu/drm/amd/amdkfd/soc15_int.h > > b/drivers/gpu/drm/amd/amdkfd/soc15_int.h > > index e5c0205f2618..736b02ccdefb 100644 > > --- a/drivers/gpu/drm/amd/amdkfd/soc15_int.h > > +++ b/drivers/gpu/drm/amd/amdkfd/soc15_int.h > > @@ -25,6 +25,7 @@ > > > > #include "soc15_ih_clientid.h" > > > > +#define SOC15_INTSRC_CP_PTL_REG_SKIP 177 > > #define SOC15_INTSRC_CP_END_OF_PIPE 181 > > #define SOC15_INTSRC_CP_BAD_OPCODE 183 > > #define SOC15_INTSRC_SQ_INTERRUPT_MSG 239 > > -- > > 2.43.0 >
