From: Philip Yang Date: Fri, 25 Apr 2025 14:55:07 +0000 (-0400) Subject: drm/amdgpu: GPU vm support 5-level page table X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f6b1c1f5fd7237f77fc3880603ea54dcf0371a20;p=thirdparty%2Fkernel%2Flinux.git drm/amdgpu: GPU vm support 5-level page table If GPU supports 5-level page table, but CPU disable 5-level page table by using boot option no5lvl or CPU feature not available, the virtual address will be 48bit, not needed to enable 5-level page table on GPU vm. If adev->vm_manager.num_level, number of pde levels, set to 4, then gfxhub and mmhub register VM_CONTEXTx_CNTL/PAGE_TABLE_DEPTH will set to 4 to enable 5-level page table in page table walker. Set vm_manager.root_level to AMDGPU_VM_PDE3, then update GPU mapping will allocate and update PDE3/PDE2/PDE1/PDE0/PTB 5-level page tables. If max_level is not 4, no change for the logic to support features needed by old ASICs. v2: squash in CONFIG fix Signed-off-by: Philip Yang Acked-by: Felix Kuehling Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 3b002e37b55b..6a2ea200d90c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -2360,9 +2360,26 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size, unsigned max_bits) { unsigned int max_size = 1 << (max_bits - 30); + bool sys_5level_pgtable = false; unsigned int vm_size; uint64_t tmp; +#ifdef CONFIG_X86_64 + /* + * Refer to function configure_5level_paging() for details. + */ + sys_5level_pgtable = (native_read_cr4() & X86_CR4_LA57); +#endif + + /* + * If GPU supports 5-level page table, but system uses 4-level page table, + * then use 4-level page table on GPU + */ + if (max_level == 4 && !sys_5level_pgtable) { + min_vm_size = 256 * 1024; + max_level = 3; + } + /* adjust vm size first */ if (amdgpu_vm_size != -1) { vm_size = amdgpu_vm_size; @@ -2405,6 +2422,9 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size, tmp = DIV_ROUND_UP(fls64(tmp) - 1, 9) - 1; adev->vm_manager.num_level = min_t(unsigned int, max_level, tmp); switch (adev->vm_manager.num_level) { + case 4: + adev->vm_manager.root_level = AMDGPU_VM_PDB3; + break; case 3: adev->vm_manager.root_level = AMDGPU_VM_PDB2; break; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index d83c2a95ebea..139642eacdd0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -186,9 +186,10 @@ struct amdgpu_bo_vm; #define AMDGPU_VM_USE_CPU_FOR_COMPUTE (1 << 1) /* VMPT level enumerate, and the hiberachy is: - * PDB2->PDB1->PDB0->PTB + * PDB3->PDB2->PDB1->PDB0->PTB */ enum amdgpu_vm_level { + AMDGPU_VM_PDB3, AMDGPU_VM_PDB2, AMDGPU_VM_PDB1, AMDGPU_VM_PDB0, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c index f794fb1cc06e..c7a7d51080a8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c @@ -51,6 +51,7 @@ static unsigned int amdgpu_vm_pt_level_shift(struct amdgpu_device *adev, unsigned int level) { switch (level) { + case AMDGPU_VM_PDB3: case AMDGPU_VM_PDB2: case AMDGPU_VM_PDB1: case AMDGPU_VM_PDB0: