[PATCH] drm/radeon/kms: forbid big bo allocation (fdo 31708)

jglisse at redhat.com jglisse at redhat.com
Fri Nov 19 13:01:38 PST 2010


From: Jerome Glisse <jglisse at redhat.com>

Forbid allocating buffer bigger than visible VRAM or GTT, also
properly set lpfn field.

Signed-off-by: Jerome Glisse <jglisse at redhat.com>
---
 drivers/gpu/drm/radeon/radeon_object.c |   36 ++++++++++++++++++++++++++-----
 1 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index 1d06774..7ce31be 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -64,23 +64,35 @@ bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo)
 	return false;
 }
 
+#define MAX(a,b) (((a)>(b))?(a):(b))
+
 void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
 {
 	u32 c = 0;
 
 	rbo->placement.fpfn = 0;
-	rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT;
+	rbo->placement.lpfn = 0;
 	rbo->placement.placement = rbo->placements;
 	rbo->placement.busy_placement = rbo->placements;
-	if (domain & RADEON_GEM_DOMAIN_VRAM)
+	if (domain & RADEON_GEM_DOMAIN_VRAM) {
+		rbo->placement.lpfn = MAX(rbo->placement.lpfn, rbo->rdev->mc.active_vram_size >> PAGE_SHIFT);
 		rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED |
 					TTM_PL_FLAG_VRAM;
-	if (domain & RADEON_GEM_DOMAIN_GTT)
+	}
+	if (domain & RADEON_GEM_DOMAIN_GTT) {
+		rbo->placement.lpfn = MAX(rbo->placement.lpfn, rbo->rdev->mc.gtt_size >> PAGE_SHIFT);
 		rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
-	if (domain & RADEON_GEM_DOMAIN_CPU)
+	}
+	if (domain & RADEON_GEM_DOMAIN_CPU) {
+		/* 4G limit for CPU domain */
+		rbo->placement.lpfn = MAX(rbo->placement.lpfn, 0xFFFFFFFF >> PAGE_SHIFT);
 		rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
-	if (!c)
+	}
+	if (!c) {
+		/* 4G limit for CPU domain */
+		rbo->placement.lpfn = MAX(rbo->placement.lpfn, 0xFFFFFFFF >> PAGE_SHIFT);
 		rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
+	}
 	rbo->placement.num_placement = c;
 	rbo->placement.num_busy_placement = c;
 }
@@ -91,7 +103,8 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
 {
 	struct radeon_bo *bo;
 	enum ttm_bo_type type;
-	int page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT;
+	unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT;
+	unsigned long max_size = 0;
 	int r;
 
 	if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) {
@@ -104,6 +117,17 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
 	}
 	*bo_ptr = NULL;
 
+	/* maximun bo size is the minimun btw visible vram and gtt size */
+	max_size = rdev->mc.visible_vram_size;
+	if (max_size > rdev->mc.gtt_size) {
+		max_size = rdev->mc.gtt_size;
+	}
+	if ((page_align << PAGE_SHIFT) >= max_size) {
+		printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n",
+			__func__, __LINE__, page_align  >> (20 - PAGE_SHIFT), max_size >> 20);
+		return -ENOMEM;
+	}
+
 retry:
 	bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL);
 	if (bo == NULL)
-- 
1.7.3.2



More information about the dri-devel mailing list