diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 41 | 
1 files changed, 30 insertions, 11 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index 7a4eae36778a..54ab51a4ada7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -32,6 +32,7 @@  #include "amdgpu.h"  #include "amdgpu_ras.h" +#include "amdgpu_reset.h"  #include "vi.h"  #include "soc15.h"  #include "nv.h" @@ -424,7 +425,7 @@ static int amdgpu_virt_read_pf2vf_data(struct amdgpu_device *adev)  		return -EINVAL;  	if (pf2vf_info->size > 1024) { -		DRM_ERROR("invalid pf2vf message size\n"); +		dev_err(adev->dev, "invalid pf2vf message size: 0x%x\n", pf2vf_info->size);  		return -EINVAL;  	} @@ -435,7 +436,9 @@ static int amdgpu_virt_read_pf2vf_data(struct amdgpu_device *adev)  			adev->virt.fw_reserve.p_pf2vf, pf2vf_info->size,  			adev->virt.fw_reserve.checksum_key, checksum);  		if (checksum != checkval) { -			DRM_ERROR("invalid pf2vf message\n"); +			dev_err(adev->dev, +				"invalid pf2vf message: header checksum=0x%x calculated checksum=0x%x\n", +				checksum, checkval);  			return -EINVAL;  		} @@ -449,7 +452,9 @@ static int amdgpu_virt_read_pf2vf_data(struct amdgpu_device *adev)  			adev->virt.fw_reserve.p_pf2vf, pf2vf_info->size,  			0, checksum);  		if (checksum != checkval) { -			DRM_ERROR("invalid pf2vf message\n"); +			dev_err(adev->dev, +				"invalid pf2vf message: header checksum=0x%x calculated checksum=0x%x\n", +				checksum, checkval);  			return -EINVAL;  		} @@ -485,7 +490,7 @@ static int amdgpu_virt_read_pf2vf_data(struct amdgpu_device *adev)  			((struct amd_sriov_msg_pf2vf_info *)pf2vf_info)->uuid;  		break;  	default: -		DRM_ERROR("invalid pf2vf version\n"); +		dev_err(adev->dev, "invalid pf2vf version: 0x%x\n", pf2vf_info->version);  		return -EINVAL;  	} @@ -571,6 +576,11 @@ static int amdgpu_virt_write_vf2pf_data(struct amdgpu_device *adev)  	vf2pf_info->decode_usage = 0;  	vf2pf_info->dummy_page_addr = (uint64_t)adev->dummy_page_addr; +	vf2pf_info->mes_info_addr = (uint64_t)adev->mes.resource_1_gpu_addr; + +	if (adev->mes.resource_1) { +		vf2pf_info->mes_info_size = adev->mes.resource_1->tbo.base.size; +	}  	vf2pf_info->checksum =  		amd_sriov_msg_checksum(  		vf2pf_info, vf2pf_info->header.size, 0, 0); @@ -584,8 +594,22 @@ static void amdgpu_virt_update_vf2pf_work_item(struct work_struct *work)  	int ret;  	ret = amdgpu_virt_read_pf2vf_data(adev); -	if (ret) +	if (ret) { +		adev->virt.vf2pf_update_retry_cnt++; +		if ((adev->virt.vf2pf_update_retry_cnt >= AMDGPU_VF2PF_UPDATE_MAX_RETRY_LIMIT) && +		    amdgpu_sriov_runtime(adev) && !amdgpu_in_reset(adev)) { +			amdgpu_ras_set_fed(adev, true); +			if (amdgpu_reset_domain_schedule(adev->reset_domain, +							  &adev->virt.flr_work)) +				return; +			else +				dev_err(adev->dev, "Failed to queue work! at %s", __func__); +		} +  		goto out; +	} + +	adev->virt.vf2pf_update_retry_cnt = 0;  	amdgpu_virt_write_vf2pf_data(adev);  out: @@ -606,6 +630,7 @@ void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev)  	adev->virt.fw_reserve.p_pf2vf = NULL;  	adev->virt.fw_reserve.p_vf2pf = NULL;  	adev->virt.vf2pf_update_interval_ms = 0; +	adev->virt.vf2pf_update_retry_cnt = 0;  	if (adev->mman.fw_vram_usage_va && adev->mman.drv_vram_usage_va) {  		DRM_WARN("Currently fw_vram and drv_vram should not have values at the same time!"); @@ -705,12 +730,6 @@ void amdgpu_detect_virtualization(struct amdgpu_device *adev)  			adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;  	} -	if (amdgpu_sriov_vf(adev) && adev->asic_type == CHIP_SIENNA_CICHLID) -		/* VF MMIO access (except mailbox range) from CPU -		 * will be blocked during sriov runtime -		 */ -		adev->virt.caps |= AMDGPU_VF_MMIO_ACCESS_PROTECT; -  	/* we have the ability to check now */  	if (amdgpu_sriov_vf(adev)) {  		switch (adev->asic_type) { |