placements.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
        r = ttm_bo_mem_space(bo, &placement, &tmp_mem, ctx);
        if (unlikely(r)) {
+               pr_err("Failed to find GTT space for blit from VRAM\n");
                return r;
        }
 
        placements.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
        r = ttm_bo_mem_space(bo, &placement, &tmp_mem, ctx);
        if (unlikely(r)) {
+               pr_err("Failed to find GTT space for blit to VRAM\n");
                return r;
        }
 
        return r;
 }
 
+/**
+ * amdgpu_mem_visible - Check that memory can be accessed by ttm_bo_move_memcpy
+ *
+ * Called by amdgpu_bo_move()
+ */
+static bool amdgpu_mem_visible(struct amdgpu_device *adev,
+                              struct ttm_mem_reg *mem)
+{
+       struct drm_mm_node *nodes = mem->mm_node;
+
+       if (mem->mem_type == TTM_PL_SYSTEM ||
+           mem->mem_type == TTM_PL_TT)
+               return true;
+       if (mem->mem_type != TTM_PL_VRAM)
+               return false;
+
+       /* ttm_mem_reg_ioremap only supports contiguous memory */
+       if (nodes->size != mem->num_pages)
+               return false;
+
+       return ((nodes->start + nodes->size) << PAGE_SHIFT)
+               <= adev->gmc.visible_vram_size;
+}
+
 /**
  * amdgpu_bo_move - Move a buffer object to a new memory location
  *
                return 0;
        }
 
-       if (!adev->mman.buffer_funcs_enabled)
+       if (!adev->mman.buffer_funcs_enabled) {
+               r = -ENODEV;
                goto memcpy;
+       }
 
        if (old_mem->mem_type == TTM_PL_VRAM &&
            new_mem->mem_type == TTM_PL_SYSTEM) {
 
        if (r) {
 memcpy:
-               r = ttm_bo_move_memcpy(bo, ctx, new_mem);
-               if (r) {
+               /* Check that all memory is CPU accessible */
+               if (!amdgpu_mem_visible(adev, old_mem) ||
+                   !amdgpu_mem_visible(adev, new_mem)) {
+                       pr_err("Move buffer fallback to memcpy unavailable\n");
                        return r;
                }
+
+               r = ttm_bo_move_memcpy(bo, ctx, new_mem);
+               if (r)
+                       return r;
        }
 
        if (bo->type == ttm_bo_type_device &&