Skip to content

Commit d4f1920

Browse files
committed
Merge tag 'scmi-fixes-6.0' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/fixes
Arm SCMI fixes for v6.0 Few fixes addressing possible out of bound access violations by hardening them, incorrect asynchronous resets by restricting them, incorrect SCMI tracing message format by harmonizing them, missing kernel-doc in optee transport, missing SCMI PM driver remove routine by adding it to avoid warning when scmi driver is unloaded and finally improve checks in the info_get operations. * tag 'scmi-fixes-6.0' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux: firmware: arm_scmi: Harmonize SCMI tracing message format firmware: arm_scmi: Add SCMI PM driver remove routine firmware: arm_scmi: Fix the asynchronous reset requests firmware: arm_scmi: Harden accesses to the reset domains firmware: arm_scmi: Harden accesses to the sensor domains firmware: arm_scmi: Improve checks in the info_get operations firmware: arm_scmi: Fix missing kernel-doc in optee Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnd Bergmann <[email protected]>
2 parents 12f0923 + 40d30cf commit d4f1920

File tree

7 files changed

+71
-25
lines changed

7 files changed

+71
-25
lines changed

drivers/firmware/arm_scmi/clock.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,9 +450,13 @@ static int scmi_clock_count_get(const struct scmi_protocol_handle *ph)
450450
static const struct scmi_clock_info *
451451
scmi_clock_info_get(const struct scmi_protocol_handle *ph, u32 clk_id)
452452
{
453+
struct scmi_clock_info *clk;
453454
struct clock_info *ci = ph->get_priv(ph);
454-
struct scmi_clock_info *clk = ci->clk + clk_id;
455455

456+
if (clk_id >= ci->num_clocks)
457+
return NULL;
458+
459+
clk = ci->clk + clk_id;
456460
if (!clk->name[0])
457461
return NULL;
458462

drivers/firmware/arm_scmi/optee.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ enum scmi_optee_pta_cmd {
106106
* @channel_id: OP-TEE channel ID used for this transport
107107
* @tee_session: TEE session identifier
108108
* @caps: OP-TEE SCMI channel capabilities
109+
* @rx_len: Response size
109110
* @mu: Mutex protection on channel access
110111
* @cinfo: SCMI channel information
111112
* @shmem: Virtual base address of the shared memory

drivers/firmware/arm_scmi/reset.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,13 @@ static int scmi_domain_reset(const struct scmi_protocol_handle *ph, u32 domain,
166166
struct scmi_xfer *t;
167167
struct scmi_msg_reset_domain_reset *dom;
168168
struct scmi_reset_info *pi = ph->get_priv(ph);
169-
struct reset_dom_info *rdom = pi->dom_info + domain;
169+
struct reset_dom_info *rdom;
170170

171-
if (rdom->async_reset)
171+
if (domain >= pi->num_domains)
172+
return -EINVAL;
173+
174+
rdom = pi->dom_info + domain;
175+
if (rdom->async_reset && flags & AUTONOMOUS_RESET)
172176
flags |= ASYNCHRONOUS_RESET;
173177

174178
ret = ph->xops->xfer_get_init(ph, RESET, sizeof(*dom), 0, &t);
@@ -180,7 +184,7 @@ static int scmi_domain_reset(const struct scmi_protocol_handle *ph, u32 domain,
180184
dom->flags = cpu_to_le32(flags);
181185
dom->reset_state = cpu_to_le32(state);
182186

183-
if (rdom->async_reset)
187+
if (flags & ASYNCHRONOUS_RESET)
184188
ret = ph->xops->do_xfer_with_response(ph, t);
185189
else
186190
ret = ph->xops->do_xfer(ph, t);

drivers/firmware/arm_scmi/scmi_pm_domain.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,28 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev)
138138
scmi_pd_data->domains = domains;
139139
scmi_pd_data->num_domains = num_domains;
140140

141+
dev_set_drvdata(dev, scmi_pd_data);
142+
141143
return of_genpd_add_provider_onecell(np, scmi_pd_data);
142144
}
143145

146+
static void scmi_pm_domain_remove(struct scmi_device *sdev)
147+
{
148+
int i;
149+
struct genpd_onecell_data *scmi_pd_data;
150+
struct device *dev = &sdev->dev;
151+
struct device_node *np = dev->of_node;
152+
153+
of_genpd_del_provider(np);
154+
155+
scmi_pd_data = dev_get_drvdata(dev);
156+
for (i = 0; i < scmi_pd_data->num_domains; i++) {
157+
if (!scmi_pd_data->domains[i])
158+
continue;
159+
pm_genpd_remove(scmi_pd_data->domains[i]);
160+
}
161+
}
162+
144163
static const struct scmi_device_id scmi_id_table[] = {
145164
{ SCMI_PROTOCOL_POWER, "genpd" },
146165
{ },
@@ -150,6 +169,7 @@ MODULE_DEVICE_TABLE(scmi, scmi_id_table);
150169
static struct scmi_driver scmi_power_domain_driver = {
151170
.name = "scmi-power-domain",
152171
.probe = scmi_pm_domain_probe,
172+
.remove = scmi_pm_domain_remove,
153173
.id_table = scmi_id_table,
154174
};
155175
module_scmi_driver(scmi_power_domain_driver);

drivers/firmware/arm_scmi/sensors.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,10 @@ static int scmi_sensor_config_get(const struct scmi_protocol_handle *ph,
762762
{
763763
int ret;
764764
struct scmi_xfer *t;
765+
struct sensors_info *si = ph->get_priv(ph);
766+
767+
if (sensor_id >= si->num_sensors)
768+
return -EINVAL;
765769

766770
ret = ph->xops->xfer_get_init(ph, SENSOR_CONFIG_GET,
767771
sizeof(__le32), sizeof(__le32), &t);
@@ -771,7 +775,6 @@ static int scmi_sensor_config_get(const struct scmi_protocol_handle *ph,
771775
put_unaligned_le32(sensor_id, t->tx.buf);
772776
ret = ph->xops->do_xfer(ph, t);
773777
if (!ret) {
774-
struct sensors_info *si = ph->get_priv(ph);
775778
struct scmi_sensor_info *s = si->sensors + sensor_id;
776779

777780
*sensor_config = get_unaligned_le64(t->rx.buf);
@@ -788,6 +791,10 @@ static int scmi_sensor_config_set(const struct scmi_protocol_handle *ph,
788791
int ret;
789792
struct scmi_xfer *t;
790793
struct scmi_msg_sensor_config_set *msg;
794+
struct sensors_info *si = ph->get_priv(ph);
795+
796+
if (sensor_id >= si->num_sensors)
797+
return -EINVAL;
791798

792799
ret = ph->xops->xfer_get_init(ph, SENSOR_CONFIG_SET,
793800
sizeof(*msg), 0, &t);
@@ -800,7 +807,6 @@ static int scmi_sensor_config_set(const struct scmi_protocol_handle *ph,
800807

801808
ret = ph->xops->do_xfer(ph, t);
802809
if (!ret) {
803-
struct sensors_info *si = ph->get_priv(ph);
804810
struct scmi_sensor_info *s = si->sensors + sensor_id;
805811

806812
s->sensor_config = sensor_config;
@@ -831,8 +837,11 @@ static int scmi_sensor_reading_get(const struct scmi_protocol_handle *ph,
831837
int ret;
832838
struct scmi_xfer *t;
833839
struct scmi_msg_sensor_reading_get *sensor;
840+
struct scmi_sensor_info *s;
834841
struct sensors_info *si = ph->get_priv(ph);
835-
struct scmi_sensor_info *s = si->sensors + sensor_id;
842+
843+
if (sensor_id >= si->num_sensors)
844+
return -EINVAL;
836845

837846
ret = ph->xops->xfer_get_init(ph, SENSOR_READING_GET,
838847
sizeof(*sensor), 0, &t);
@@ -841,6 +850,7 @@ static int scmi_sensor_reading_get(const struct scmi_protocol_handle *ph,
841850

842851
sensor = t->tx.buf;
843852
sensor->id = cpu_to_le32(sensor_id);
853+
s = si->sensors + sensor_id;
844854
if (s->async) {
845855
sensor->flags = cpu_to_le32(SENSOR_READ_ASYNC);
846856
ret = ph->xops->do_xfer_with_response(ph, t);
@@ -895,9 +905,13 @@ scmi_sensor_reading_get_timestamped(const struct scmi_protocol_handle *ph,
895905
int ret;
896906
struct scmi_xfer *t;
897907
struct scmi_msg_sensor_reading_get *sensor;
908+
struct scmi_sensor_info *s;
898909
struct sensors_info *si = ph->get_priv(ph);
899-
struct scmi_sensor_info *s = si->sensors + sensor_id;
900910

911+
if (sensor_id >= si->num_sensors)
912+
return -EINVAL;
913+
914+
s = si->sensors + sensor_id;
901915
if (!count || !readings ||
902916
(!s->num_axis && count > 1) || (s->num_axis && count > s->num_axis))
903917
return -EINVAL;
@@ -948,6 +962,9 @@ scmi_sensor_info_get(const struct scmi_protocol_handle *ph, u32 sensor_id)
948962
{
949963
struct sensors_info *si = ph->get_priv(ph);
950964

965+
if (sensor_id >= si->num_sensors)
966+
return NULL;
967+
951968
return si->sensors + sensor_id;
952969
}
953970

include/linux/scmi_protocol.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ struct scmi_protocol_handle;
8484
struct scmi_clk_proto_ops {
8585
int (*count_get)(const struct scmi_protocol_handle *ph);
8686

87-
const struct scmi_clock_info *(*info_get)
87+
const struct scmi_clock_info __must_check *(*info_get)
8888
(const struct scmi_protocol_handle *ph, u32 clk_id);
8989
int (*rate_get)(const struct scmi_protocol_handle *ph, u32 clk_id,
9090
u64 *rate);
@@ -466,7 +466,7 @@ enum scmi_sensor_class {
466466
*/
467467
struct scmi_sensor_proto_ops {
468468
int (*count_get)(const struct scmi_protocol_handle *ph);
469-
const struct scmi_sensor_info *(*info_get)
469+
const struct scmi_sensor_info __must_check *(*info_get)
470470
(const struct scmi_protocol_handle *ph, u32 sensor_id);
471471
int (*trip_point_config)(const struct scmi_protocol_handle *ph,
472472
u32 sensor_id, u8 trip_id, u64 trip_value);

include/trace/events/scmi.h

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ TRACE_EVENT(scmi_fc_call,
2727
__entry->val2 = val2;
2828
),
2929

30-
TP_printk("[0x%02X]:[0x%02X]:[%08X]:%u:%u",
31-
__entry->protocol_id, __entry->msg_id,
32-
__entry->res_id, __entry->val1, __entry->val2)
30+
TP_printk("pt=%02X msg_id=%02X res_id:%u vals=%u:%u",
31+
__entry->protocol_id, __entry->msg_id,
32+
__entry->res_id, __entry->val1, __entry->val2)
3333
);
3434

3535
TRACE_EVENT(scmi_xfer_begin,
@@ -53,9 +53,9 @@ TRACE_EVENT(scmi_xfer_begin,
5353
__entry->poll = poll;
5454
),
5555

56-
TP_printk("transfer_id=%d msg_id=%u protocol_id=%u seq=%u poll=%u",
57-
__entry->transfer_id, __entry->msg_id, __entry->protocol_id,
58-
__entry->seq, __entry->poll)
56+
TP_printk("pt=%02X msg_id=%02X seq=%04X transfer_id=%X poll=%u",
57+
__entry->protocol_id, __entry->msg_id, __entry->seq,
58+
__entry->transfer_id, __entry->poll)
5959
);
6060

6161
TRACE_EVENT(scmi_xfer_response_wait,
@@ -81,9 +81,9 @@ TRACE_EVENT(scmi_xfer_response_wait,
8181
__entry->poll = poll;
8282
),
8383

84-
TP_printk("transfer_id=%d msg_id=%u protocol_id=%u seq=%u tmo_ms=%u poll=%u",
85-
__entry->transfer_id, __entry->msg_id, __entry->protocol_id,
86-
__entry->seq, __entry->timeout, __entry->poll)
84+
TP_printk("pt=%02X msg_id=%02X seq=%04X transfer_id=%X tmo_ms=%u poll=%u",
85+
__entry->protocol_id, __entry->msg_id, __entry->seq,
86+
__entry->transfer_id, __entry->timeout, __entry->poll)
8787
);
8888

8989
TRACE_EVENT(scmi_xfer_end,
@@ -107,9 +107,9 @@ TRACE_EVENT(scmi_xfer_end,
107107
__entry->status = status;
108108
),
109109

110-
TP_printk("transfer_id=%d msg_id=%u protocol_id=%u seq=%u status=%d",
111-
__entry->transfer_id, __entry->msg_id, __entry->protocol_id,
112-
__entry->seq, __entry->status)
110+
TP_printk("pt=%02X msg_id=%02X seq=%04X transfer_id=%X s=%d",
111+
__entry->protocol_id, __entry->msg_id, __entry->seq,
112+
__entry->transfer_id, __entry->status)
113113
);
114114

115115
TRACE_EVENT(scmi_rx_done,
@@ -133,9 +133,9 @@ TRACE_EVENT(scmi_rx_done,
133133
__entry->msg_type = msg_type;
134134
),
135135

136-
TP_printk("transfer_id=%d msg_id=%u protocol_id=%u seq=%u msg_type=%u",
137-
__entry->transfer_id, __entry->msg_id, __entry->protocol_id,
138-
__entry->seq, __entry->msg_type)
136+
TP_printk("pt=%02X msg_id=%02X seq=%04X transfer_id=%X msg_type=%u",
137+
__entry->protocol_id, __entry->msg_id, __entry->seq,
138+
__entry->transfer_id, __entry->msg_type)
139139
);
140140

141141
TRACE_EVENT(scmi_msg_dump,

0 commit comments

Comments
 (0)