⬢ DragonFlyBSD Kernel Audit
DF-5163 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/amd/amdgpu/atom.h	2026-06-29 12:51:18.000000000 +0000
+++ b/sys/dev/drm/amd/amdgpu/atom.h	2026-09-30 15:10:29.748667971 +0000
@@ -140,6 +140,7 @@
 	int io_mode;
 	uint32_t *scratch;
 	int scratch_size_bytes;
+	struct lock scratch_mutex;
 	char vbios_version[20];
 };
 
--- a/sys/dev/drm/amd/amdgpu/atom.c	2026-06-29 12:51:18.000000000 +0000
+++ b/sys/dev/drm/amd/amdgpu/atom.c	2026-09-30 15:10:29.760667818 +0000
@@ -1256,7 +1256,8 @@
 	return ret;
 }
 
-int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
+static int amdgpu_atom_execute_table_scratch_unlocked(struct atom_context *ctx,
+						       int index, uint32_t * params)
 {
 	int r;
 
@@ -1277,6 +1278,20 @@
 	return r;
 }
 
+/* DF-5163: serialize all scratch users across the interpreter execution,
+ * mirroring radeon's scratch_mutex (radeon/atom.c:1247-1252). Callers that
+ * read atom_context->scratch after the table has run (atombios_i2c.c) must
+ * hold scratch_mutex across execute+read. */
+int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
+{
+	int r;
+
+	mutex_lock(&ctx->scratch_mutex);
+	r = amdgpu_atom_execute_table_scratch_unlocked(ctx, index, params);
+	mutex_unlock(&ctx->scratch_mutex);
+	return r;
+}
+
 static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 };
 
 static void atom_index_iio(struct atom_context *ctx, int base)
--- a/sys/dev/drm/amd/amdgpu/atombios_i2c.c	2026-06-29 12:51:18.000000000 +0000
+++ b/sys/dev/drm/amd/amdgpu/atombios_i2c.c	2026-09-30 15:10:29.760667818 +0000
@@ -50,6 +50,7 @@
 	memset(&args, 0, sizeof(args));
 
 	mutex_lock(&chan->mutex);
+	mutex_lock(&adev->mode_info.atom_context->scratch_mutex);
 
 	base = (unsigned char *)adev->mode_info.atom_context->scratch;
 
@@ -104,6 +105,7 @@
 		amdgpu_atombios_copy_swap(buf, base, num, false);
 
 done:
+	mutex_unlock(&adev->mode_info.atom_context->scratch_mutex);
 	mutex_unlock(&chan->mutex);
 
 	return r;
--- a/sys/dev/drm/amd/amdgpu/amdgpu_atombios.c	2026-06-29 12:51:18.000000000 +0000
+++ b/sys/dev/drm/amd/amdgpu/amdgpu_atombios.c	2026-09-30 15:10:29.764667768 +0000
@@ -2041,6 +2041,7 @@
 	}
 
 	lockinit(&adev->mode_info.atom_context->mutex, "agmiacm", 0, LK_CANRECURSE);
+	lockinit(&adev->mode_info.atom_context->scratch_mutex, "agmiacsm", 0, LK_CANRECURSE);
 	if (adev->is_atom_fw) {
 		amdgpu_atomfirmware_scratch_regs_init(adev);
 		amdgpu_atomfirmware_allocate_fb_scratch(adev);