diff mbox series

drm/amdgpu: Fix for drm buddy memory corruption

Message ID 20220714101214.7620-1-Arunpravin.PaneerSelvam@amd.com (mailing list archive)
State New, archived
Headers show
Series drm/amdgpu: Fix for drm buddy memory corruption | expand

Commit Message

Paneer Selvam, Arunpravin July 14, 2022, 10:12 a.m. UTC
User reported gpu page fault when running graphics applications
and in some cases garbaged graphics are observed as soon as X
starts. This patch fixes all the issues.

Fixed the typecast issue for fpfn and lpfn variables, thus
preventing the overflow problem which resolves the memory
corruption.

Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
Reported-by: Mike Lothian <mike@fireburn.co.uk>
Tested-by: Mike Lothian <mike@fireburn.co.uk>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 16 ++++++++--------
 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h |  2 +-
 2 files changed, 9 insertions(+), 9 deletions(-)

Comments

Christian König July 15, 2022, 1:46 p.m. UTC | #1
Am 14.07.22 um 12:12 schrieb Arunpravin Paneer Selvam:
> User reported gpu page fault when running graphics applications
> and in some cases garbaged graphics are observed as soon as X
> starts. This patch fixes all the issues.
>
> Fixed the typecast issue for fpfn and lpfn variables, thus
> preventing the overflow problem which resolves the memory
> corruption.
>
> Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
> Reported-by: Mike Lothian <mike@fireburn.co.uk>
> Tested-by: Mike Lothian <mike@fireburn.co.uk>

Reviewed-by: Christian König <christian.koenig@amd.com>

I've re-applied the patches to drm-misc-next, solved the conflict in 
drm-tip and then pushed this to drm-misc-next-fixes.

With a little bit of luck everything should now be in place, but fingers 
crossed.

Regards,
Christian.

> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 16 ++++++++--------
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h |  2 +-
>   2 files changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
> index 49e4092f447f..34d789054ec8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
> @@ -366,11 +366,11 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
>   	unsigned long pages_per_block;
>   	int r;
>   
> -	lpfn = place->lpfn << PAGE_SHIFT;
> +	lpfn = (u64)place->lpfn << PAGE_SHIFT;
>   	if (!lpfn)
>   		lpfn = man->size;
>   
> -	fpfn = place->fpfn << PAGE_SHIFT;
> +	fpfn = (u64)place->fpfn << PAGE_SHIFT;
>   
>   	max_bytes = adev->gmc.mc_vram_size;
>   	if (tbo->type != ttm_bo_type_kernel)
> @@ -410,12 +410,12 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
>   		/* Allocate blocks in desired range */
>   		vres->flags |= DRM_BUDDY_RANGE_ALLOCATION;
>   
> -	remaining_size = vres->base.num_pages << PAGE_SHIFT;
> +	remaining_size = (u64)vres->base.num_pages << PAGE_SHIFT;
>   
>   	mutex_lock(&mgr->lock);
>   	while (remaining_size) {
>   		if (tbo->page_alignment)
> -			min_block_size = tbo->page_alignment << PAGE_SHIFT;
> +			min_block_size = (u64)tbo->page_alignment << PAGE_SHIFT;
>   		else
>   			min_block_size = mgr->default_page_size;
>   
> @@ -424,12 +424,12 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
>   		/* Limit maximum size to 2GiB due to SG table limitations */
>   		size = min(remaining_size, 2ULL << 30);
>   
> -		if (size >= pages_per_block << PAGE_SHIFT)
> -			min_block_size = pages_per_block << PAGE_SHIFT;
> +		if (size >= (u64)pages_per_block << PAGE_SHIFT)
> +			min_block_size = (u64)pages_per_block << PAGE_SHIFT;
>   
>   		cur_size = size;
>   
> -		if (fpfn + size != place->lpfn << PAGE_SHIFT) {
> +		if (fpfn + size != (u64)place->lpfn << PAGE_SHIFT) {
>   			/*
>   			 * Except for actual range allocation, modify the size and
>   			 * min_block_size conforming to continuous flag enablement
> @@ -469,7 +469,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
>   		LIST_HEAD(temp);
>   
>   		trim_list = &vres->blocks;
> -		original_size = vres->base.num_pages << PAGE_SHIFT;
> +		original_size = (u64)vres->base.num_pages << PAGE_SHIFT;
>   
>   		/*
>   		 * If size value is rounded up to min_block_size, trim the last
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h
> index 9a2db87186c7..bef0f561ba60 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h
> @@ -50,7 +50,7 @@ static inline u64 amdgpu_vram_mgr_block_start(struct drm_buddy_block *block)
>   
>   static inline u64 amdgpu_vram_mgr_block_size(struct drm_buddy_block *block)
>   {
> -	return PAGE_SIZE << drm_buddy_block_order(block);
> +	return (u64)PAGE_SIZE << drm_buddy_block_order(block);
>   }
>   
>   static inline struct drm_buddy_block *
diff mbox series

Patch

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
index 49e4092f447f..34d789054ec8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -366,11 +366,11 @@  static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
 	unsigned long pages_per_block;
 	int r;
 
-	lpfn = place->lpfn << PAGE_SHIFT;
+	lpfn = (u64)place->lpfn << PAGE_SHIFT;
 	if (!lpfn)
 		lpfn = man->size;
 
-	fpfn = place->fpfn << PAGE_SHIFT;
+	fpfn = (u64)place->fpfn << PAGE_SHIFT;
 
 	max_bytes = adev->gmc.mc_vram_size;
 	if (tbo->type != ttm_bo_type_kernel)
@@ -410,12 +410,12 @@  static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
 		/* Allocate blocks in desired range */
 		vres->flags |= DRM_BUDDY_RANGE_ALLOCATION;
 
-	remaining_size = vres->base.num_pages << PAGE_SHIFT;
+	remaining_size = (u64)vres->base.num_pages << PAGE_SHIFT;
 
 	mutex_lock(&mgr->lock);
 	while (remaining_size) {
 		if (tbo->page_alignment)
-			min_block_size = tbo->page_alignment << PAGE_SHIFT;
+			min_block_size = (u64)tbo->page_alignment << PAGE_SHIFT;
 		else
 			min_block_size = mgr->default_page_size;
 
@@ -424,12 +424,12 @@  static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
 		/* Limit maximum size to 2GiB due to SG table limitations */
 		size = min(remaining_size, 2ULL << 30);
 
-		if (size >= pages_per_block << PAGE_SHIFT)
-			min_block_size = pages_per_block << PAGE_SHIFT;
+		if (size >= (u64)pages_per_block << PAGE_SHIFT)
+			min_block_size = (u64)pages_per_block << PAGE_SHIFT;
 
 		cur_size = size;
 
-		if (fpfn + size != place->lpfn << PAGE_SHIFT) {
+		if (fpfn + size != (u64)place->lpfn << PAGE_SHIFT) {
 			/*
 			 * Except for actual range allocation, modify the size and
 			 * min_block_size conforming to continuous flag enablement
@@ -469,7 +469,7 @@  static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
 		LIST_HEAD(temp);
 
 		trim_list = &vres->blocks;
-		original_size = vres->base.num_pages << PAGE_SHIFT;
+		original_size = (u64)vres->base.num_pages << PAGE_SHIFT;
 
 		/*
 		 * If size value is rounded up to min_block_size, trim the last
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h
index 9a2db87186c7..bef0f561ba60 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h
@@ -50,7 +50,7 @@  static inline u64 amdgpu_vram_mgr_block_start(struct drm_buddy_block *block)
 
 static inline u64 amdgpu_vram_mgr_block_size(struct drm_buddy_block *block)
 {
-	return PAGE_SIZE << drm_buddy_block_order(block);
+	return (u64)PAGE_SIZE << drm_buddy_block_order(block);
 }
 
 static inline struct drm_buddy_block *