Commit ad9a5b78 authored by Christian König's avatar Christian König Committed by Alex Deucher

drm/amdgpu: correctly sign extend 48bit addresses v3

Correct sign extend the GMC addresses to 48bit.

v2: sign extending turned out easier than thought.
v3: clean up the defines and move them into amdgpu_gmc.h as well
Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarJunwei Zhang <Jerry.Zhang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent bcdc9fd6
...@@ -135,7 +135,7 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) ...@@ -135,7 +135,7 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
.num_queue_per_pipe = adev->gfx.mec.num_queue_per_pipe, .num_queue_per_pipe = adev->gfx.mec.num_queue_per_pipe,
.gpuvm_size = min(adev->vm_manager.max_pfn .gpuvm_size = min(adev->vm_manager.max_pfn
<< AMDGPU_GPU_PAGE_SHIFT, << AMDGPU_GPU_PAGE_SHIFT,
AMDGPU_VA_HOLE_START), AMDGPU_GMC_HOLE_START),
.drm_render_minor = adev->ddev->render->index .drm_render_minor = adev->ddev->render->index
}; };
......
...@@ -835,7 +835,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p) ...@@ -835,7 +835,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB) if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB)
continue; continue;
va_start = chunk_ib->va_start & AMDGPU_VA_HOLE_MASK; va_start = chunk_ib->va_start & AMDGPU_GMC_HOLE_MASK;
r = amdgpu_cs_find_mapping(p, va_start, &aobj, &m); r = amdgpu_cs_find_mapping(p, va_start, &aobj, &m);
if (r) { if (r) {
DRM_ERROR("IB va_start is invalid\n"); DRM_ERROR("IB va_start is invalid\n");
......
...@@ -572,16 +572,16 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, ...@@ -572,16 +572,16 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
return -EINVAL; return -EINVAL;
} }
if (args->va_address >= AMDGPU_VA_HOLE_START && if (args->va_address >= AMDGPU_GMC_HOLE_START &&
args->va_address < AMDGPU_VA_HOLE_END) { args->va_address < AMDGPU_GMC_HOLE_END) {
dev_dbg(&dev->pdev->dev, dev_dbg(&dev->pdev->dev,
"va_address 0x%LX is in VA hole 0x%LX-0x%LX\n", "va_address 0x%LX is in VA hole 0x%LX-0x%LX\n",
args->va_address, AMDGPU_VA_HOLE_START, args->va_address, AMDGPU_GMC_HOLE_START,
AMDGPU_VA_HOLE_END); AMDGPU_GMC_HOLE_END);
return -EINVAL; return -EINVAL;
} }
args->va_address &= AMDGPU_VA_HOLE_MASK; args->va_address &= AMDGPU_GMC_HOLE_MASK;
if ((args->flags & ~valid_flags) && (args->flags & ~prt_flags)) { if ((args->flags & ~valid_flags) && (args->flags & ~prt_flags)) {
dev_dbg(&dev->pdev->dev, "invalid flags combination 0x%08X\n", dev_dbg(&dev->pdev->dev, "invalid flags combination 0x%08X\n",
......
...@@ -30,6 +30,19 @@ ...@@ -30,6 +30,19 @@
#include "amdgpu_irq.h" #include "amdgpu_irq.h"
/* VA hole for 48bit addresses on Vega10 */
#define AMDGPU_GMC_HOLE_START 0x0000800000000000ULL
#define AMDGPU_GMC_HOLE_END 0xffff800000000000ULL
/*
* Hardware is programmed as if the hole doesn't exists with start and end
* address values.
*
* 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 0x0000ffffffffffffULL
struct firmware; struct firmware;
/* /*
...@@ -133,6 +146,19 @@ static inline bool amdgpu_gmc_vram_full_visible(struct amdgpu_gmc *gmc) ...@@ -133,6 +146,19 @@ static inline bool amdgpu_gmc_vram_full_visible(struct amdgpu_gmc *gmc)
return (gmc->real_vram_size == gmc->visible_vram_size); return (gmc->real_vram_size == gmc->visible_vram_size);
} }
/**
* amdgpu_gmc_sign_extend - sign extend the given gmc address
*
* @addr: address to extend
*/
static inline uint64_t amdgpu_gmc_sign_extend(uint64_t addr)
{
if (addr >= AMDGPU_GMC_HOLE_START)
addr |= AMDGPU_GMC_HOLE_END;
return addr;
}
void amdgpu_gmc_get_pde_for_bo(struct amdgpu_bo *bo, int level, void amdgpu_gmc_get_pde_for_bo(struct amdgpu_bo *bo, int level,
uint64_t *addr, uint64_t *flags); uint64_t *addr, uint64_t *flags);
uint64_t amdgpu_gmc_pd_addr(struct amdgpu_bo *bo); uint64_t amdgpu_gmc_pd_addr(struct amdgpu_bo *bo);
......
...@@ -655,11 +655,11 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file ...@@ -655,11 +655,11 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
dev_info.virtual_address_offset = AMDGPU_VA_RESERVED_SIZE; dev_info.virtual_address_offset = AMDGPU_VA_RESERVED_SIZE;
dev_info.virtual_address_max = dev_info.virtual_address_max =
min(vm_size, AMDGPU_VA_HOLE_START); min(vm_size, AMDGPU_GMC_HOLE_START);
if (vm_size > AMDGPU_VA_HOLE_START) { if (vm_size > AMDGPU_GMC_HOLE_START) {
dev_info.high_va_offset = AMDGPU_VA_HOLE_END; dev_info.high_va_offset = AMDGPU_GMC_HOLE_END;
dev_info.high_va_max = AMDGPU_VA_HOLE_END | vm_size; dev_info.high_va_max = AMDGPU_GMC_HOLE_END | vm_size;
} }
dev_info.virtual_address_alignment = max((int)PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE); dev_info.virtual_address_alignment = max((int)PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE);
dev_info.pte_fragment_size = (1 << adev->vm_manager.fragment_size) * AMDGPU_GPU_PAGE_SIZE; dev_info.pte_fragment_size = (1 << adev->vm_manager.fragment_size) * AMDGPU_GPU_PAGE_SIZE;
......
...@@ -1368,7 +1368,7 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo) ...@@ -1368,7 +1368,7 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)
WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM && WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM &&
!(bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)); !(bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS));
return bo->tbo.offset; return amdgpu_gmc_sign_extend(bo->tbo.offset);
} }
/** /**
......
...@@ -28,9 +28,7 @@ uint64_t amdgpu_csa_vaddr(struct amdgpu_device *adev) ...@@ -28,9 +28,7 @@ uint64_t amdgpu_csa_vaddr(struct amdgpu_device *adev)
uint64_t addr = adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT; uint64_t addr = adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT;
addr -= AMDGPU_VA_RESERVED_SIZE; addr -= AMDGPU_VA_RESERVED_SIZE;
addr = amdgpu_gmc_sign_extend(addr);
if (addr >= AMDGPU_VA_HOLE_START)
addr |= AMDGPU_VA_HOLE_END;
return addr; return addr;
} }
...@@ -73,7 +71,7 @@ void amdgpu_free_static_csa(struct amdgpu_device *adev) { ...@@ -73,7 +71,7 @@ void amdgpu_free_static_csa(struct amdgpu_device *adev) {
int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
struct amdgpu_bo_va **bo_va) struct amdgpu_bo_va **bo_va)
{ {
uint64_t csa_addr = amdgpu_csa_vaddr(adev) & AMDGPU_VA_HOLE_MASK; uint64_t csa_addr = amdgpu_csa_vaddr(adev) & AMDGPU_GMC_HOLE_MASK;
struct ww_acquire_ctx ticket; struct ww_acquire_ctx ticket;
struct list_head list; struct list_head list;
struct amdgpu_bo_list_entry pd; struct amdgpu_bo_list_entry pd;
......
...@@ -492,7 +492,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, ...@@ -492,7 +492,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
if (level == adev->vm_manager.root_level) { if (level == adev->vm_manager.root_level) {
ats_entries = amdgpu_vm_level_shift(adev, level); ats_entries = amdgpu_vm_level_shift(adev, level);
ats_entries += AMDGPU_GPU_PAGE_SHIFT; ats_entries += AMDGPU_GPU_PAGE_SHIFT;
ats_entries = AMDGPU_VA_HOLE_START >> ats_entries; ats_entries = AMDGPU_GMC_HOLE_START >> ats_entries;
ats_entries = min(ats_entries, entries); ats_entries = min(ats_entries, entries);
entries -= ats_entries; entries -= ats_entries;
} else { } else {
...@@ -722,7 +722,7 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev, ...@@ -722,7 +722,7 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
eaddr = saddr + size - 1; eaddr = saddr + size - 1;
if (vm->pte_support_ats) if (vm->pte_support_ats)
ats = saddr < AMDGPU_VA_HOLE_START; ats = saddr < AMDGPU_GMC_HOLE_START;
saddr /= AMDGPU_GPU_PAGE_SIZE; saddr /= AMDGPU_GPU_PAGE_SIZE;
eaddr /= AMDGPU_GPU_PAGE_SIZE; eaddr /= AMDGPU_GPU_PAGE_SIZE;
...@@ -2016,7 +2016,8 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, ...@@ -2016,7 +2016,8 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
struct amdgpu_bo_va_mapping, list); struct amdgpu_bo_va_mapping, list);
list_del(&mapping->list); list_del(&mapping->list);
if (vm->pte_support_ats && mapping->start < AMDGPU_VA_HOLE_START) if (vm->pte_support_ats &&
mapping->start < AMDGPU_GMC_HOLE_START)
init_pte_value = AMDGPU_PTE_DEFAULT_ATC; init_pte_value = AMDGPU_PTE_DEFAULT_ATC;
r = amdgpu_vm_bo_update_mapping(adev, NULL, NULL, vm, r = amdgpu_vm_bo_update_mapping(adev, NULL, NULL, vm,
......
...@@ -101,19 +101,6 @@ struct amdgpu_bo_list_entry; ...@@ -101,19 +101,6 @@ struct amdgpu_bo_list_entry;
/* hardcode that limit for now */ /* hardcode that limit for now */
#define AMDGPU_VA_RESERVED_SIZE (1ULL << 20) #define AMDGPU_VA_RESERVED_SIZE (1ULL << 20)
/* VA hole for 48bit addresses on Vega10 */
#define AMDGPU_VA_HOLE_START 0x0000800000000000ULL
#define AMDGPU_VA_HOLE_END 0xffff800000000000ULL
/*
* Hardware is programmed as if the hole doesn't exists with start and end
* address values.
*
* This mask is used to remove the upper 16bits of the VA and so come up with
* the linear addr value.
*/
#define AMDGPU_VA_HOLE_MASK 0x0000ffffffffffffULL
/* max vmids dedicated for process */ /* max vmids dedicated for process */
#define AMDGPU_VM_MAX_RESERVED_VMID 1 #define AMDGPU_VM_MAX_RESERVED_VMID 1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment