]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
Revert "drm/amdgpu: fix aperture mapping leak"
authorAsad Kamal <asad.kamal@amd.com>
Thu, 30 Jul 2026 07:00:00 +0000 (15:00 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 6 Aug 2026 18:33:46 +0000 (14:33 -0400)
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 d871e99879cb5fd1fa798b006b4888887e63a17a.

Fixes: d871e99879cb ("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 336e0cd576817ac64a4b394ca2b3680029f3e37f)
Cc: stable@vger.kernel.org
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c

index e5f26e5892bac758e0bf870d292066fb974bdc93..bff3e06a756c5217d2a8e303f483bca2aaa4a634 100644 (file)
@@ -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 */
index 5fc91f45db5b9659b7f3f77bc66309dec5584b0e..12a3b8bc58a4c9fc2863e9bbef61eec5abcec2ad 100644 (file)
@@ -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);