Commit f59548c8 authored by Monk Liu's avatar Monk Liu Committed by Alex Deucher
Browse files

drm/amdgpu:fix NULL pointer access during drv remove



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: default avatarMonk Liu <Monk.Liu@amd.com>
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent c79ee7d8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+0 −1
Original line number Diff line number Diff line
@@ -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);
+1 −8
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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");
+1 −1
Original line number Diff line number Diff line
@@ -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;
Loading