From: Jiri Kosina jkosina@suse.cz
stable inclusion from stable-5.10.56 commit fc2756cce06f9833ebabd309b5b5080ed5c56897 bugzilla: 176004 https://gitee.com/openeuler/kernel/issues/I4DYZ4
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
commit d47255d3f87338164762ac56df1f28d751e27246 upstream.
This reverts commit 4192f7b5768912ceda82be2f83c87ea7181f9980.
It is not true (as stated in the reverted commit changelog) that we never unmap the BAR on failure; it actually does happen properly on amdgpu_driver_load_kms() -> amdgpu_driver_unload_kms() -> amdgpu_device_fini() error path.
What's worse, this commit actually completely breaks resource freeing on probe failure (like e.g. failure to load microcode), as amdgpu_driver_unload_kms() notices adev->rmmio being NULL and bails too early, leaving all the resources that'd normally be freed in amdgpu_acpi_fini() and amdgpu_device_fini() still hanging around, leading to all sorts of oopses when someone tries to, for example, access the sysfs and procfs resources which are still around while the driver is gone.
Fixes: 4192f7b57689 ("drm/amdgpu: unmap register bar on device init failure") Reported-by: Vojtech Pavlik vojtech@ucw.cz Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Chen Jun chenjun102@huawei.com Acked-by: Weilong Chen chenweilong@huawei.com Signed-off-by: Chen Jun chenjun102@huawei.com --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 6948ab3c0d99..ffd310279a69 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3322,13 +3322,13 @@ int amdgpu_device_init(struct amdgpu_device *adev, r = amdgpu_device_get_job_timeout_settings(adev); if (r) { dev_err(adev->dev, "invalid lockup_timeout parameter syntax\n"); - goto failed_unmap; + return r; }
/* early init functions */ r = amdgpu_device_ip_early_init(adev); if (r) - goto failed_unmap; + return r;
/* doorbell bar mapping and doorbell index init*/ amdgpu_device_doorbell_init(adev); @@ -3532,10 +3532,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, if (boco) vga_switcheroo_fini_domain_pm_ops(adev->dev);
-failed_unmap: - iounmap(adev->rmmio); - adev->rmmio = NULL; - return r; }