[PATCH v3 03/24] firmware: arm_scmi: Allow registration of unknown-size events/reports
From: Cristian Marussi <cristian.marussi@arm.com>
Date: 2026-03-29 16:34:23
Also in:
arm-scmi, linux-arm-kernel, linux-fsdevel, lkml
Subsystem:
system control & power/management interface (scpi/scmi) message protocol drivers, the rest · Maintainers:
Sudeep Holla, Linus Torvalds
Allow protocols to register events with build-time unknown sizes: such events can be declared zero-sized and let the core SCMI stack perform the needed safe-net boundary checks based on the configured transport size. Signed-off-by: Cristian Marussi <cristian.marussi@arm.com> --- v2 --> v3 - split out of previous patch on protocol notifier - use max() instead of max_t() --- drivers/firmware/arm_scmi/notify.c | 24 +++++++++++++++++++----- drivers/firmware/arm_scmi/notify.h | 8 ++++++-- 2 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/firmware/arm_scmi/notify.c b/drivers/firmware/arm_scmi/notify.c
index 40ec184eedae..3e4c97ab7b61 100644
--- a/drivers/firmware/arm_scmi/notify.c
+++ b/drivers/firmware/arm_scmi/notify.c@@ -595,7 +595,13 @@ int scmi_notify(const struct scmi_handle *handle, u8 proto_id, u8 evt_id, if (!r_evt) return -EINVAL; - if (len > r_evt->evt->max_payld_sz) { + /* + * Events with a zero max_payld_sz are sized to be of the maximum + * size allowed by the transport: no need to be size-checked here + * since the transport layer would have already dropped such + * over-sized messages. + */ + if (r_evt->evt->max_payld_sz && len > r_evt->evt->max_payld_sz) { dev_err(handle->dev, "discard badly sized message\n"); return -EINVAL; }
@@ -754,7 +760,7 @@ int scmi_register_protocol_events(const struct scmi_handle *handle, u8 proto_id, const struct scmi_protocol_handle *ph, const struct scmi_protocol_events *ee) { - int i; + int i, max_msg_sz; unsigned int num_sources; size_t payld_sz = 0; struct scmi_registered_events_desc *pd;
@@ -769,6 +775,8 @@ int scmi_register_protocol_events(const struct scmi_handle *handle, u8 proto_id, if (!ni) return -ENOMEM; + max_msg_sz = ph->hops->get_max_msg_size(ph); + /* num_sources cannot be <= 0 */ if (ee->num_sources) { num_sources = ee->num_sources;
@@ -781,8 +789,13 @@ int scmi_register_protocol_events(const struct scmi_handle *handle, u8 proto_id, } evt = ee->evts; - for (i = 0; i < ee->num_events; i++) - payld_sz = max_t(size_t, payld_sz, evt[i].max_payld_sz); + for (i = 0; i < ee->num_events; i++) { + if (evt[i].max_payld_sz == 0) { + payld_sz = max_msg_sz; + break; + } + payld_sz = max(payld_sz, evt[i].max_payld_sz); + } payld_sz += sizeof(struct scmi_event_header); pd = scmi_allocate_registered_events_desc(ni, proto_id, ee->queue_sz,
@@ -811,7 +824,8 @@ int scmi_register_protocol_events(const struct scmi_handle *handle, u8 proto_id, mutex_init(&r_evt->sources_mtx); r_evt->report = devm_kzalloc(ni->handle->dev, - evt->max_report_sz, GFP_KERNEL); + evt->max_report_sz ?: max_msg_sz, + GFP_KERNEL); if (!r_evt->report) return -ENOMEM;
diff --git a/drivers/firmware/arm_scmi/notify.h b/drivers/firmware/arm_scmi/notify.h
index 76758a736cf4..ecfa4b746487 100644
--- a/drivers/firmware/arm_scmi/notify.h
+++ b/drivers/firmware/arm_scmi/notify.h@@ -18,8 +18,12 @@ /** * struct scmi_event - Describes an event to be supported * @id: Event ID - * @max_payld_sz: Max possible size for the payload of a notification message - * @max_report_sz: Max possible size for the report of a notification message + * @max_payld_sz: Max possible size for the payload of a notification message. + * Set to zero to use the maximum payload size allowed by the + * transport. + * @max_report_sz: Max possible size for the report of a notification message. + * Set to zero to use the maximum payload size allowed by the + * transport. * * Each SCMI protocol, during its initialization phase, can describe the events * it wishes to support in a few struct scmi_event and pass them to the core
--
2.53.0