From 9c5a49bc2ac831165da58f83dc4ec7194a1f19db Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Fri, 19 Nov 2010 15:53:47 -0500 Subject: [PATCH] drm/radeon/kms: forbid big bo allocation (fdo 31708) Forbid allocating buffer bigger than visible VRAM or GTT, also properly set lpfn field. Signed-off-by: Jerome Glisse --- 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