From 7042e498bc4040d1b4f8489b98f9b5faba91e140 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Thu, 11 Jun 2026 14:31:03 +0100 Subject: [PATCH 1/3] ams: copy the payload struct size into the message slot The slot copy length came from a macro that adds the message length, which over-read past the payload struct since the message data is referenced by pointer, not stored inline. Copy exactly the struct size, which is what the slot stores and the consumer reads back. Signed-off-by: Liam Girdwood --- src/lib/ams.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lib/ams.c b/src/lib/ams.c index 31bca13ce833..fb1843960959 100644 --- a/src/lib/ams.c +++ b/src/lib/ams.c @@ -285,9 +285,14 @@ static uint32_t ams_push_slot(struct ams_shared_context __sparse_cache *ctx_shar for (uint32_t i = 0; i < ARRAY_SIZE(ctx_shared->slots); ++i) { if (ctx_shared->slot_uses[i] == 0) { + /* the slot stores the payload struct (read back via + * u.msg); AMS_MESSAGE_SIZE() adds message_length, which + * over-reads past the struct since message is a pointer, + * not inline data + */ err = memcpy_s((__sparse_force void *)ctx_shared->slots[i].u.msg_raw, sizeof(ctx_shared->slots[i].u.msg_raw), - msg, AMS_MESSAGE_SIZE(msg)); + msg, sizeof(*msg)); if (err != 0) return AMS_INVALID_SLOT; From 9d815b47af6919b5f92443d5ec27e65e878c705e Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Thu, 11 Jun 2026 14:31:03 +0100 Subject: [PATCH 2/3] clk: clamp frequency index when no threshold matches When the requested frequency was at least every table entry, the search index ran off the end of the table and the following access read one element past it. Clamp the index to the last valid entry. Signed-off-by: Liam Girdwood --- src/lib/cpu-clk-manager.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lib/cpu-clk-manager.c b/src/lib/cpu-clk-manager.c index 59744063e4b9..df917fab4f9d 100644 --- a/src/lib/cpu-clk-manager.c +++ b/src/lib/cpu-clk-manager.c @@ -28,6 +28,13 @@ static int request_freq_change(unsigned int core, int freq) break; } + /* if no entry was larger than the requested frequency the loop ends with + * selected_freq_id == clk->freqs_num; clamp to the last valid entry + * before indexing + */ + if (selected_freq_id == clk->freqs_num) + selected_freq_id = clk->freqs_num - 1; + /* don't change clock frequency if already using proper clock */ current_freq = clock_get_freq(core); if (clk->freqs[selected_freq_id].freq != current_freq) From 4d39bb097e4332c50d22182b5bd26fda7bedb722 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Fri, 12 Jun 2026 15:20:58 +0100 Subject: [PATCH 3/3] ams: remove unused message-size macros AMS_MESSAGE_SIZE() and AMS_SLOT_SIZE() assumed the message payload was stored inline after the header, but ams_message_payload.message is a pointer to a caller-owned buffer (set in ams_helper_prepare_payload) and the slot only carries the fixed-size struct. The last use of AMS_MESSAGE_SIZE() was replaced by sizeof(*msg); AMS_SLOT_SIZE() had no users. Remove both as dead and misleading. Signed-off-by: Liam Girdwood --- src/include/sof/lib/ams.h | 4 ---- src/lib/ams.c | 7 +++---- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/include/sof/lib/ams.h b/src/include/sof/lib/ams.h index 8cb3ae217400..e43d6208f875 100644 --- a/src/include/sof/lib/ams.h +++ b/src/include/sof/lib/ams.h @@ -29,10 +29,6 @@ /* Space allocated for async message content*/ #define AMS_MAX_MSG_SIZE 0x1000 -/* Size of slots message, module id and instance id */ -#define AMS_SLOT_SIZE(msg) (AMS_MESSAGE_SIZE(msg) + sizeof(uint16_t) * 2) -#define AMS_MESSAGE_SIZE(msg) (sizeof(*msg) - sizeof(char) + (sizeof(char) * (msg->message_length))) - /** * \brief IXC message payload * diff --git a/src/lib/ams.c b/src/lib/ams.c index fb1843960959..b1752976e0c5 100644 --- a/src/lib/ams.c +++ b/src/lib/ams.c @@ -285,10 +285,9 @@ static uint32_t ams_push_slot(struct ams_shared_context __sparse_cache *ctx_shar for (uint32_t i = 0; i < ARRAY_SIZE(ctx_shared->slots); ++i) { if (ctx_shared->slot_uses[i] == 0) { - /* the slot stores the payload struct (read back via - * u.msg); AMS_MESSAGE_SIZE() adds message_length, which - * over-reads past the struct since message is a pointer, - * not inline data + /* the slot only carries the payload struct (read back + * via u.msg); message points to a caller-owned buffer + * rather than inline data, so copy exactly the struct */ err = memcpy_s((__sparse_force void *)ctx_shared->slots[i].u.msg_raw, sizeof(ctx_shared->slots[i].u.msg_raw),