mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 08:15:07 -04:00
Revert "drm/amdgpu: fix aperture mapping leak"
devres teardown is LIFO. The aperture devres node was registered after
the DRM device node, so devres_release_all() unmaps the aperture before
the DRM device release callback fires amdgpu_device_fini_sw(). IP
sw_fini callbacks (e.g. vcn_v4_0_sw_fini) write to fw_shared through a
pointer derived from aper_base_kaddr, causing a kernel page fault on
probe failure / rollback:
BUG: unable to handle page fault ... PMD 0
RIP: vcn_v4_0_sw_fini+0x7b/0x170 [amdgpu]
Call Trace:
amdgpu_device_fini_sw
amdgpu_driver_release_kms
devm_drm_dev_init_release
devres_release_all
This reverts commit d871e99879.
Fixes: d871e99879 ("drm/amdgpu: fix aperture mapping leak")
Reported-by: Yuansheng Mao <yuansheng.mao@amd.com>
Signed-off-by: Asad Kamal <asad.kamal@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 336e0cd576)
Cc: stable@vger.kernel.org
This commit is contained in:
@@ -4194,6 +4194,8 @@ static void amdgpu_device_unmap_mmio(struct amdgpu_device *adev)
|
||||
|
||||
iounmap(adev->rmmio);
|
||||
adev->rmmio = NULL;
|
||||
if (adev->mman.aper_base_kaddr)
|
||||
iounmap(adev->mman.aper_base_kaddr);
|
||||
adev->mman.aper_base_kaddr = NULL;
|
||||
|
||||
/* Memory manager related */
|
||||
|
||||
@@ -2120,23 +2120,17 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
|
||||
/* Change the size here instead of the init above so only lpfn is affected */
|
||||
amdgpu_ttm_disable_buffer_funcs(adev);
|
||||
#ifdef CONFIG_64BIT
|
||||
if (adev->gmc.xgmi.connected_to_cpu) {
|
||||
void *kaddr = devm_memremap(adev->dev, adev->gmc.aper_base,
|
||||
adev->gmc.visible_vram_size,
|
||||
MEMREMAP_WB);
|
||||
if (IS_ERR(kaddr))
|
||||
return PTR_ERR(kaddr);
|
||||
adev->mman.aper_base_kaddr = (__force void __iomem *)kaddr;
|
||||
} else if (adev->gmc.is_app_apu) {
|
||||
#ifdef CONFIG_X86
|
||||
if (adev->gmc.xgmi.connected_to_cpu)
|
||||
adev->mman.aper_base_kaddr = ioremap_cache(adev->gmc.aper_base,
|
||||
adev->gmc.visible_vram_size);
|
||||
else if (adev->gmc.is_app_apu)
|
||||
DRM_DEBUG_DRIVER(
|
||||
"No need to ioremap when real vram size is 0\n");
|
||||
} else {
|
||||
adev->mman.aper_base_kaddr = devm_ioremap_wc(adev->dev,
|
||||
adev->gmc.aper_base,
|
||||
adev->gmc.visible_vram_size);
|
||||
if (!adev->mman.aper_base_kaddr)
|
||||
return -ENOMEM;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
adev->mman.aper_base_kaddr = ioremap_wc(adev->gmc.aper_base,
|
||||
adev->gmc.visible_vram_size);
|
||||
#endif
|
||||
|
||||
amdgpu_ttm_init_vram_resv_regions(adev);
|
||||
@@ -2265,6 +2259,8 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
|
||||
*/
|
||||
void amdgpu_ttm_fini(struct amdgpu_device *adev)
|
||||
{
|
||||
int idx;
|
||||
|
||||
if (!adev->mman.initialized)
|
||||
return;
|
||||
|
||||
@@ -2287,7 +2283,14 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
|
||||
amdgpu_ttm_unmark_vram_reserved(adev, AMDGPU_RESV_FW_VRAM_USAGE);
|
||||
amdgpu_ttm_unmark_vram_reserved(adev, AMDGPU_RESV_DRV_VRAM_USAGE);
|
||||
|
||||
adev->mman.aper_base_kaddr = NULL;
|
||||
if (drm_dev_enter(adev_to_drm(adev), &idx)) {
|
||||
|
||||
if (adev->mman.aper_base_kaddr)
|
||||
iounmap(adev->mman.aper_base_kaddr);
|
||||
adev->mman.aper_base_kaddr = NULL;
|
||||
|
||||
drm_dev_exit(idx);
|
||||
}
|
||||
|
||||
if (!adev->gmc.is_app_apu)
|
||||
amdgpu_vram_mgr_fini(adev);
|
||||
|
||||
Reference in New Issue
Block a user