Check poison injection address whether in vbios or data exchange region to aviod hitting vf critical region in SRIOV.
Signed-off-by: Xiang Liu <xiang....@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 38 +++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index b00cbb927ca8..158aa4ac9327 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -212,6 +212,31 @@ static int amdgpu_reserve_page_direct(struct amdgpu_device *adev, uint64_t addre return 0; } +static int amdgpu_check_vf_critical_region(struct amdgpu_device *adev, u64 pa) +{ + u64 offset, size; + + if (!amdgpu_sriov_vf(adev)) + return 0; + + /* check pa whether in vbios and data exchange region */ + offset = adev->gmc.mc_vram_size + (AMD_SRIOV_MSG_VBIOS_OFFSET << 10); + size = (AMD_SRIOV_MSG_DATAEXCHANGE_OFFSET_KB << 10) + + (AMD_SRIOV_MSG_DATAEXCHANGE_SIZE_KB << 10); + + /* + * Add an additional 4MB to critical range as we cannot reserve allocations + * done during guest sw init + */ + if (amdgpu_ip_version(adev, UMC_HWIP, 0) == IP_VERSION(6, 7, 0)) + size += (0x1000 << 10); + + if (pa >= offset && pa < offset + size) + return -EACCES; + + return 0; +} + static int amdgpu_check_address_validity(struct amdgpu_device *adev, uint64_t address, uint64_t flags) { @@ -223,16 +248,25 @@ static int amdgpu_check_address_validity(struct amdgpu_device *adev, if (amdgpu_ip_version(adev, UMC_HWIP, 0) < IP_VERSION(12, 0, 0)) return 0; - if ((address >= adev->gmc.mc_vram_size) || - (address >= RAS_UMC_INJECT_ADDR_LIMIT)) + if (!amdgpu_sriov_vf(adev) && ((address >= adev->gmc.mc_vram_size) || + (address >= RAS_UMC_INJECT_ADDR_LIMIT))) return -EFAULT; + if (amdgpu_sriov_vf(adev) && adev->umc.ras && adev->umc.ras->get_retire_flip_bits) + adev->umc.ras->get_retire_flip_bits(adev); + count = amdgpu_umc_lookup_bad_pages_in_a_row(adev, address, page_pfns, ARRAY_SIZE(page_pfns)); if (count <= 0) return -EPERM; for (i = 0; i < count; i++) { + if (amdgpu_sriov_vf(adev)) { + ret = amdgpu_check_vf_critical_region(adev, address); + if (ret) + return ret; + } + memset(&blk_info, 0, sizeof(blk_info)); ret = amdgpu_vram_mgr_query_address_block_info(&adev->mman.vram_mgr, page_pfns[i] << AMDGPU_GPU_PAGE_SHIFT, &blk_info); -- 2.34.1