amdgpu: validate the upper limit of virtual address v2
authorJammy Zhou <Jammy.Zhou@amd.com>
Tue, 12 May 2015 17:14:11 +0000 (01:14 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 5 Aug 2015 17:47:49 +0000 (13:47 -0400)
Only 8GB virtual address space is used by default now

v2: use -ENOSPC for the error case

Signed-off-by: Jammy Zhou <Jammy.Zhou@amd.com>
amdgpu/amdgpu_bo.c
amdgpu/amdgpu_internal.h
amdgpu/amdgpu_vamgr.c
include/drm/amdgpu_drm.h

index 587c1d0..d78bb9a 100644 (file)
@@ -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;
index cc911c5..7910d34 100644 (file)
@@ -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;
index 2335912..070ecc4 100644 (file)
@@ -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;
index a27f8eb..f61ec0c 100644 (file)
@@ -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 */