On 6/17/2024 3:41 PM, Jane Jian wrote: > [WHY] > sriov has the higher bit violation when flushing tlb > > [HOW] > normalize the registers to keep lower 16-bit(dword aligned) to aviod higher bit violation > RLCG will mask xcd out and always assume it's accessing its own xcd > > also fix the typo in sriov_w/rreg: > for KIQ case, use xcc with xcc_id to read and write > > v2 > amend some typos > > Signed-off-by: Jane Jian <Jane.Jian@xxxxxxx> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 12 ++++++++++-- > drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 8 ++++++-- > drivers/gpu/drm/amd/amdgpu/soc15_common.h | 2 ++ > 3 files changed, 18 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c > index 63f2286858c4..d43652a38484 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c > @@ -1075,6 +1075,10 @@ void amdgpu_sriov_wreg(struct amdgpu_device *adev, > if (amdgpu_device_skip_hw_access(adev)) > return; > > + /* Select lower 16 bits to write in local xcc */ > + if ((hwip == GC_HWIP) && !(acc_flags & AMDGPU_REGS_NO_KIQ)) > + offset = NORMALIZE_XCC_REG_OFFSET(offset); This cannot be generalized. Instead use a similar approach of having an soc specific function => adev->asic_funcs->encode_ext_smn_addressing > + > if (!amdgpu_sriov_runtime(adev) && > amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags, hwip, true, &rlcg_flag)) { > amdgpu_virt_rlcg_reg_rw(adev, offset, value, rlcg_flag, xcc_id); > @@ -1084,7 +1088,7 @@ void amdgpu_sriov_wreg(struct amdgpu_device *adev, > if (acc_flags & AMDGPU_REGS_NO_KIQ) > WREG32_NO_KIQ(offset, value); > else > - WREG32(offset, value); > + WREG32_XCC(offset, value, xcc_id); This doesn't look correct. AFAIU, this macro is specifically for XCC registers. amdgpu_sriov_wreg can have registers other than hwip == GC_HWIP. > } > > u32 amdgpu_sriov_rreg(struct amdgpu_device *adev, > @@ -1095,6 +1099,10 @@ u32 amdgpu_sriov_rreg(struct amdgpu_device *adev, > if (amdgpu_device_skip_hw_access(adev)) > return 0; > > + /* Select lower 16 bits to read in local xcc */ > + if ((hwip == GC_HWIP) && !(acc_flags & AMDGPU_REGS_NO_KIQ)) > + offset = NORMALIZE_XCC_REG_OFFSET(offset); > + > if (!amdgpu_sriov_runtime(adev) && > amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags, hwip, false, &rlcg_flag)) > return amdgpu_virt_rlcg_reg_rw(adev, offset, 0, rlcg_flag, xcc_id); > @@ -1102,7 +1110,7 @@ u32 amdgpu_sriov_rreg(struct amdgpu_device *adev, > if (acc_flags & AMDGPU_REGS_NO_KIQ) > return RREG32_NO_KIQ(offset); > else > - return RREG32(offset); > + return RREG32_XCC(offset, xcc_id);> } > > bool amdgpu_sriov_xnack_support(struct amdgpu_device *adev) > diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c > index 88b4644f8e96..5bb275b96e6a 100644 > --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c > @@ -853,8 +853,12 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, > */ > if (adev->gfx.kiq[inst].ring.sched.ready && > (amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev))) { > - uint32_t req = hub->vm_inv_eng0_req + hub->eng_distance * eng; > - uint32_t ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng; > + > + /* Select lower 16 bits to write in local xcc */ > + if (AMDGPU_IS_GFXHUB(vmhub)) { > + req = NORMALIZE_XCC_REG_OFFSET(req); > + ack = NORMALIZE_XCC_REG_OFFSET(ack); > + } Not sure if there are other things to check like cross AID register offsets for MMHUB. Thanks, Lijo > > amdgpu_gmc_fw_reg_write_reg_wait(adev, req, ack, inv_req, > 1 << vmid, inst); > diff --git a/drivers/gpu/drm/amd/amdgpu/soc15_common.h b/drivers/gpu/drm/amd/amdgpu/soc15_common.h > index 242b24f73c17..9ddf68e7d06e 100644 > --- a/drivers/gpu/drm/amd/amdgpu/soc15_common.h > +++ b/drivers/gpu/drm/amd/amdgpu/soc15_common.h > @@ -210,4 +210,6 @@ > #define WREG64_MCA(ext, mca_base, idx, val) \ > WREG64_PCIE_EXT(adev->asic_funcs->encode_ext_smn_addressing(ext) + mca_base + (idx * 8), val) > > +#define NORMALIZE_XCC_REG_OFFSET(offset) (offset & 0xffff) > + > #endif