drm/amdgpu:fix NULL pointer access during drv remove
authorMonk Liu <Monk.Liu@amd.com>
Tue, 14 Nov 2017 03:55:50 +0000 (11:55 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 6 Dec 2017 17:47:50 +0000 (12:47 -0500)
NULL pointer is because original logic will step into
set_pde_pte() even after the gart.ptr is freed due to
there are twice gart_unbind() on all gart area.

also, there are other minor fixes:
1,since gart_init only create dummy page, the corresponding
gart_fini shouldn't do more like unbinding all GART, this is
unnecessary because in driver fini stage all GART unbinding
had already been done during each IP's SW_FINI (GMC's
SW_FINI is the last one called), so remove the step
for the GART unbinding in gart_fini().

2,gart_fini() is already invoked during each GMC IP's gart_fini
routine,e.g. gmc_vx_0_gart_fini(), so no need to manually
call it during ttm_fini().

3,amdgpu_gem_force_release() should be put ahead of
amdgpu_vm_manager_fini()

Signed-off-by: Monk Liu <Monk.Liu@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c

index a7066f55fe2c348695d6c0c94ed90f27d1d800a4..ecc2e60e5f0c2cecd425cb5fab48b8ae5e092dc1 100644 (file)
@@ -1412,6 +1412,7 @@ struct amdgpu_fw_vram_usage {
 };
 
 int amdgpu_fw_reserve_vram_init(struct amdgpu_device *adev);
+void amdgpu_fw_reserve_vram_fini(struct amdgpu_device *adev);
 
 /*
  * CGS
index ee2a5f9a32f01125f0132bfaebf36a5123d65632..fc34f745f05888dbf613f2ea117e1d02a70f7718 100644 (file)
@@ -2506,7 +2506,6 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
        /* evict vram memory */
        amdgpu_bo_evict_vram(adev);
        amdgpu_ib_pool_fini(adev);
-       amdgpu_fw_reserve_vram_fini(adev);
        amdgpu_fence_driver_fini(adev);
        amdgpu_fbdev_fini(adev);
        r = amdgpu_fini(adev);
index 10eeb307700c77ed604e8d028b7a304e279f2148..707f85825996d522cb54ecfc0073e7dc0eba725b 100644 (file)
@@ -253,10 +253,8 @@ int amdgpu_gart_init(struct amdgpu_device *adev)
 #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
        /* Allocate pages table */
        adev->gart.pages = vzalloc(sizeof(void *) * adev->gart.num_cpu_pages);
-       if (adev->gart.pages == NULL) {
-               amdgpu_gart_fini(adev);
+       if (adev->gart.pages == NULL)
                return -ENOMEM;
-       }
 #endif
 
        return 0;
@@ -271,11 +269,6 @@ int amdgpu_gart_init(struct amdgpu_device *adev)
  */
 void amdgpu_gart_fini(struct amdgpu_device *adev)
 {
-       if (adev->gart.ready) {
-               /* unbind pages */
-               amdgpu_gart_unbind(adev, 0, adev->gart.num_cpu_pages);
-       }
-       adev->gart.ready = false;
 #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
        vfree(adev->gart.pages);
        adev->gart.pages = NULL;
index d49c768cf3dce16a5e1c648ee08c5fb6d1413922..07ecf721ebf91b4d24647f6b9f7c7cb62bc1939a 100644 (file)
@@ -1402,6 +1402,7 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
 
        amdgpu_ttm_debugfs_fini(adev);
        amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, NULL);
+       amdgpu_fw_reserve_vram_fini(adev);
 
        ttm_bo_clean_mm(&adev->mman.bdev, TTM_PL_VRAM);
        ttm_bo_clean_mm(&adev->mman.bdev, TTM_PL_TT);
@@ -1412,7 +1413,6 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
        if (adev->gds.oa.total_size)
                ttm_bo_clean_mm(&adev->mman.bdev, AMDGPU_PL_OA);
        ttm_bo_device_release(&adev->mman.bdev);
-       amdgpu_gart_fini(adev);
        amdgpu_ttm_global_fini(adev);
        adev->mman.initialized = false;
        DRM_INFO("amdgpu: ttm finalized\n");
index f3e5c9c6a52d1f050a54ce6a0c27bf2b61e59a47..9c672ece9f185110b22bb67f3e950f8abbf5ca7a 100644 (file)
@@ -899,9 +899,9 @@ static int gmc_v6_0_sw_fini(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+       amdgpu_gem_force_release(adev);
        amdgpu_vm_manager_fini(adev);
        gmc_v6_0_gart_fini(adev);
-       amdgpu_gem_force_release(adev);
        amdgpu_bo_fini(adev);
        release_firmware(adev->mc.fw);
        adev->mc.fw = NULL;
index 6d153fa8175cd252cc49f7759768c21ca37c048d..de7a249f0e24bc4ee3d4575d53d70b050ed67bc9 100644 (file)
@@ -1049,9 +1049,9 @@ static int gmc_v7_0_sw_fini(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+       amdgpu_gem_force_release(adev);
        amdgpu_vm_manager_fini(adev);
        gmc_v7_0_gart_fini(adev);
-       amdgpu_gem_force_release(adev);
        amdgpu_bo_fini(adev);
        release_firmware(adev->mc.fw);
        adev->mc.fw = NULL;
index 7ee5f21295d4f563b337111fc21ce081468ff32d..67778744da5a566efcf52ce5cc78ad2f6eedac87 100644 (file)
@@ -1146,9 +1146,9 @@ static int gmc_v8_0_sw_fini(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+       amdgpu_gem_force_release(adev);
        amdgpu_vm_manager_fini(adev);
        gmc_v8_0_gart_fini(adev);
-       amdgpu_gem_force_release(adev);
        amdgpu_bo_fini(adev);
        release_firmware(adev->mc.fw);
        adev->mc.fw = NULL;
index 4960805bf9899c4d0e332ef4d9b69c7768a05468..798f7fc2d4e93fc83553241d965f69a4db04076c 100644 (file)
@@ -885,9 +885,9 @@ static int gmc_v9_0_sw_fini(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+       amdgpu_gem_force_release(adev);
        amdgpu_vm_manager_fini(adev);
        gmc_v9_0_gart_fini(adev);
-       amdgpu_gem_force_release(adev);
        amdgpu_bo_fini(adev);
 
        return 0;