⬢ DragonFlyBSD Kernel Audit
DF-3666 / fix.diff
← back to finding ↓ download raw
fix.diff — DF-3666: size the RLC save/restore BO for the packed format (evergreen.c:4155)

sumo_rlc_init() allocates dws*4 bytes for the save/restore list, but the pre-TAHITI
packing loop (evergreen.c:4197-4206) writes ceil(dws/2)*3 + 1 dwords (2 source regs
packed into 3 dest dwords plus the end marker): 496 bytes into a 324-byte BO for the
in-tree 81-entry list - a 172-byte overrun contained today only by TTM page rounding.

SI+ path unchanged (linear copy bounded by reg_list_size).

Validated with 'git apply --check' against this tree. NOT applied (sys/ is a
read-only audit target).

--- a/sys/dev/drm/radeon/evergreen.c
+++ b/sys/dev/drm/radeon/evergreen.c
@@ -4151,10 +4151,17 @@
 
 	if (src_ptr) {
 		/* save restore block */
+		/* SI+ copies the list verbatim (bounded by reg_list_size);
+		 * ON/LN/TN pack 2 source registers into 3 destination
+		 * dwords and append an end marker, so the buffer needs
+		 * ceil(dws/2)*3 + 1 dwords, not dws. */
+		u32 sr_dws = (rdev->family >= CHIP_TAHITI) ? dws :
+			(((dws + 1) / 2) * 3 + 1);
 		if (rdev->rlc.save_restore_obj == NULL) {
-			r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true,
-					     RADEON_GEM_DOMAIN_VRAM, 0, NULL,
-					     NULL, &rdev->rlc.save_restore_obj);
+			r = radeon_bo_create(rdev, sr_dws * 4, PAGE_SIZE,
+					     true, RADEON_GEM_DOMAIN_VRAM, 0,
+					     NULL, NULL,
+					     &rdev->rlc.save_restore_obj);
 			if (r) {
 				dev_warn(rdev->dev, "(%d) create RLC sr bo failed\n", r);
 				return r;