diff --git a/amdgpu/amdgpu_bo.c b/amdgpu/amdgpu_bo.c index 587c1d08..d78bb9a8 100644 --- a/amdgpu/amdgpu_bo.c +++ b/amdgpu/amdgpu_bo.c @@ -121,7 +121,14 @@ int amdgpu_bo_alloc(amdgpu_device_handle dev, memset(&va, 0, sizeof(va)); - bo->virtual_mc_base_address = amdgpu_vamgr_find_va(&dev->vamgr, alloc_buffer->alloc_size, alloc_buffer->phys_alignment); + bo->virtual_mc_base_address = amdgpu_vamgr_find_va(&dev->vamgr, + alloc_buffer->alloc_size, + alloc_buffer->phys_alignment); + + if (bo->virtual_mc_base_address == AMDGPU_INVALID_VA_ADDRESS) { + amdgpu_bo_free_internal(bo); + return -ENOSPC; + } va.in.handle = bo->handle; va.in.operation = AMDGPU_VA_OP_MAP; @@ -440,6 +447,12 @@ int amdgpu_bo_import(amdgpu_device_handle dev, bo->virtual_mc_base_address = amdgpu_vamgr_find_va(&dev->vamgr, bo->alloc_size, 1 << 20); + if (bo->virtual_mc_base_address == AMDGPU_INVALID_VA_ADDRESS) { + pthread_mutex_unlock(&dev->bo_table_mutex); + amdgpu_bo_reference(&bo, NULL); + return -ENOSPC; + } + memset(&va, 0, sizeof(va)); va.in.handle = bo->handle; va.in.operation = AMDGPU_VA_OP_MAP; @@ -615,6 +628,11 @@ int amdgpu_create_bo_from_user_mem(amdgpu_device_handle dev, bo->handle = args.handle; bo->virtual_mc_base_address = amdgpu_vamgr_find_va(&dev->vamgr, size, 4 * 1024); + if (bo->virtual_mc_base_address == AMDGPU_INVALID_VA_ADDRESS) { + amdgpu_bo_free_internal(bo); + return -ENOSPC; + } + memset(&va, 0, sizeof(va)); va.in.handle = bo->handle; va.in.operation = AMDGPU_VA_OP_MAP; diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h index cc911c5b..7910d340 100644 --- a/amdgpu/amdgpu_internal.h +++ b/amdgpu/amdgpu_internal.h @@ -40,6 +40,8 @@ #define ROUND_UP(x, y) ((((x)-1) | __round_mask(x, y))+1) #define ROUND_DOWN(x, y) ((x) & ~__round_mask(x, y)) +#define AMDGPU_INVALID_VA_ADDRESS 0xffffffffffffffff + struct amdgpu_bo_va_hole { struct list_head list; uint64_t offset; @@ -49,6 +51,7 @@ struct amdgpu_bo_va_hole { struct amdgpu_bo_va_mgr { /* the start virtual address */ uint64_t va_offset; + uint64_t va_max; struct list_head va_holes; pthread_mutex_t bo_va_mutex; uint32_t va_alignment; diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c index 23359122..070ecc47 100644 --- a/amdgpu/amdgpu_vamgr.c +++ b/amdgpu/amdgpu_vamgr.c @@ -33,6 +33,7 @@ void amdgpu_vamgr_init(struct amdgpu_device *dev) struct amdgpu_bo_va_mgr *vamgr = &dev->vamgr; vamgr->va_offset = dev->dev_info.virtual_address_offset; + vamgr->va_max = dev->dev_info.virtual_address_max; vamgr->va_alignment = dev->dev_info.virtual_address_alignment; list_inithead(&vamgr->va_holes); @@ -89,6 +90,12 @@ uint64_t amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, offset = mgr->va_offset; waste = offset % alignment; waste = waste ? alignment - waste : 0; + + if (offset + waste + size > mgr->va_max) { + pthread_mutex_unlock(&mgr->bo_va_mutex); + return AMDGPU_INVALID_VA_ADDRESS; + } + if (waste) { n = calloc(1, sizeof(struct amdgpu_bo_va_hole)); n->size = waste; diff --git a/include/drm/amdgpu_drm.h b/include/drm/amdgpu_drm.h index a27f8eb7..f61ec0cc 100644 --- a/include/drm/amdgpu_drm.h +++ b/include/drm/amdgpu_drm.h @@ -560,6 +560,8 @@ struct drm_amdgpu_info_device { uint64_t ids_flags; /** Starting virtual address for UMDs. */ uint64_t virtual_address_offset; + /** The maximum virtual address */ + uint64_t virtual_address_max; /** Required alignment of virtual addresses. */ uint32_t virtual_address_alignment; /** Page table entry - fragment size */