Commit aa25c111 authored by Christian König's avatar Christian König Committed by Alex Deucher
Browse files

drm/amdgpu: fix 4-level paging if GMC supports 57-bit VA v2



It turned that using 4 level page tables on GMC generations which support
57bit VAs actually doesn't work at all.

Background is that the GMC actually can't switch between 4 and 5 levels,
but rather just uses a subset of address space when less than 5 levels are
selected.

Philip already removed the automatically switch to 4levels, now fix it as
well should it be enabled by module parameters.

v2: fix AMDGPU_GMC_HOLE_MASK as well, fix off by one issue pointed out
    by Philip

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: default avatarPhilip Yang <philip.yang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 096bb75e
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -33,9 +33,9 @@
#include "amdgpu_ras.h"

/* VA hole for 48bit and 57bit addresses */
#define AMDGPU_GMC_HOLE_START	(adev->vm_manager.root_level == AMDGPU_VM_PDB3 ?\
#define AMDGPU_GMC_HOLE_START	(adev->vm_manager.max_level == 4 ?\
				0x0100000000000000ULL : 0x0000800000000000ULL)
#define AMDGPU_GMC_HOLE_END	(adev->vm_manager.root_level == AMDGPU_VM_PDB3 ?\
#define AMDGPU_GMC_HOLE_END	(adev->vm_manager.max_level == 4 ?\
				0xff00000000000000ULL : 0xffff800000000000ULL)

/*
@@ -45,8 +45,8 @@
 * This mask is used to remove the upper 16bits of the VA and so come up with
 * the linear addr value.
 */
#define AMDGPU_GMC_HOLE_MASK	(adev->vm_manager.root_level == AMDGPU_VM_PDB3 ?\
				0x00ffffffffffffffULL : 0x0000ffffffffffffULL)
#define AMDGPU_GMC_HOLE_MASK	(adev->vm_manager.max_level == 4 ?\
				0x01ffffffffffffffULL : 0x0000ffffffffffffULL)

/*
 * Ring size as power of two for the log of recent faults.
+1 −0
Original line number Diff line number Diff line
@@ -2400,6 +2400,7 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size,
	}

	adev->vm_manager.max_pfn = (uint64_t)vm_size << 18;
	adev->vm_manager.max_level = max_level;

	tmp = roundup_pow_of_two(adev->vm_manager.max_pfn);
	if (amdgpu_vm_block_size != -1)
+1 −0
Original line number Diff line number Diff line
@@ -456,6 +456,7 @@ struct amdgpu_vm_manager {
	bool					concurrent_flush;

	uint64_t				max_pfn;
	uint32_t				max_level;
	uint32_t				num_level;
	uint32_t				block_size;
	uint32_t				fragment_size;