diff options
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_gem.c')
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_gem.c | 45 | 
1 files changed, 36 insertions, 9 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index fa1aa94a3d8..26d51979116 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -56,9 +56,28 @@ static unsigned int convert_to_vm_err_msg(int msg)  	return out_msg;  } -static unsigned int mask_gem_flags(unsigned int flags) +static int check_gem_flags(unsigned int flags)  { -	return flags &= EXYNOS_BO_NONCONTIG; +	if (flags & ~(EXYNOS_BO_MASK)) { +		DRM_ERROR("invalid flags.\n"); +		return -EINVAL; +	} + +	return 0; +} + +static unsigned long roundup_gem_size(unsigned long size, unsigned int flags) +{ +	if (!IS_NONCONTIG_BUFFER(flags)) { +		if (size >= SZ_1M) +			return roundup(size, SECTION_SIZE); +		else if (size >= SZ_64K) +			return roundup(size, SZ_64K); +		else +			goto out; +	} +out: +	return roundup(size, PAGE_SIZE);  }  static struct page **exynos_gem_get_pages(struct drm_gem_object *obj, @@ -319,10 +338,17 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,  	struct exynos_drm_gem_buf *buf;  	int ret; -	size = roundup(size, PAGE_SIZE); -	DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size); +	if (!size) { +		DRM_ERROR("invalid size.\n"); +		return ERR_PTR(-EINVAL); +	} -	flags = mask_gem_flags(flags); +	size = roundup_gem_size(size, flags); +	DRM_DEBUG_KMS("%s\n", __FILE__); + +	ret = check_gem_flags(flags); +	if (ret) +		return ERR_PTR(ret);  	buf = exynos_drm_init_buf(dev, size);  	if (!buf) @@ -331,7 +357,7 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,  	exynos_gem_obj = exynos_drm_gem_init(dev, size);  	if (!exynos_gem_obj) {  		ret = -ENOMEM; -		goto err; +		goto err_fini_buf;  	}  	exynos_gem_obj->buffer = buf; @@ -347,18 +373,19 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,  		ret = exynos_drm_gem_get_pages(&exynos_gem_obj->base);  		if (ret < 0) {  			drm_gem_object_release(&exynos_gem_obj->base); -			goto err; +			goto err_fini_buf;  		}  	} else {  		ret = exynos_drm_alloc_buf(dev, buf, flags);  		if (ret < 0) {  			drm_gem_object_release(&exynos_gem_obj->base); -			goto err; +			goto err_fini_buf;  		}  	}  	return exynos_gem_obj; -err: + +err_fini_buf:  	exynos_drm_fini_buf(dev, buf);  	return ERR_PTR(ret);  }  |