[PATCH] drm/amdgpu: Fix UBSAN shift-out-of-bounds for gfx v9_0

Candice Li candice.li at amd.com
Mon Aug 15 10:04:37 UTC 2022


Check shift number to avoid doing a shift operation when the number
of bits shifted equal to or greater than number of bits in the operand.

Signed-off-by: Candice Li <candice.li at amd.com>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index 7f187558220e9a..0b9215b6e4b316 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -2494,7 +2494,7 @@ static u32 gfx_v9_0_get_rb_active_bitmap(struct amdgpu_device *adev)
 static void gfx_v9_0_setup_rb(struct amdgpu_device *adev)
 {
 	int i, j;
-	u32 data;
+	u32 data, shift_num;
 	u32 active_rbs = 0;
 	u32 rb_bitmap_width_per_sh = adev->gfx.config.max_backends_per_se /
 					adev->gfx.config.max_sh_per_se;
@@ -2504,8 +2504,10 @@ static void gfx_v9_0_setup_rb(struct amdgpu_device *adev)
 		for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) {
 			gfx_v9_0_select_se_sh(adev, i, j, 0xffffffff);
 			data = gfx_v9_0_get_rb_active_bitmap(adev);
-			active_rbs |= data << ((i * adev->gfx.config.max_sh_per_se + j) *
-					       rb_bitmap_width_per_sh);
+			shift_num = min(((i * adev->gfx.config.max_sh_per_se + j) *
+						  rb_bitmap_width_per_sh), __builtin_clz(data));
+			if (data)
+				active_rbs |= data << shift_num;
 		}
 	}
 	gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
-- 
2.17.1



More information about the amd-gfx mailing list