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/20220829174435.207911-1-sudeep.holla@arm.com Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
@@ -450,9 +450,13 @@ static int scmi_clock_count_get(const struct scmi_protocol_handle *ph)
|
||||
static const struct scmi_clock_info *
|
||||
scmi_clock_info_get(const struct scmi_protocol_handle *ph, u32 clk_id)
|
||||
{
|
||||
struct scmi_clock_info *clk;
|
||||
struct clock_info *ci = ph->get_priv(ph);
|
||||
struct scmi_clock_info *clk = ci->clk + clk_id;
|
||||
|
||||
if (clk_id >= ci->num_clocks)
|
||||
return NULL;
|
||||
|
||||
clk = ci->clk + clk_id;
|
||||
if (!clk->name[0])
|
||||
return NULL;
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@ enum scmi_optee_pta_cmd {
|
||||
* @channel_id: OP-TEE channel ID used for this transport
|
||||
* @tee_session: TEE session identifier
|
||||
* @caps: OP-TEE SCMI channel capabilities
|
||||
* @rx_len: Response size
|
||||
* @mu: Mutex protection on channel access
|
||||
* @cinfo: SCMI channel information
|
||||
* @shmem: Virtual base address of the shared memory
|
||||
|
||||
@@ -166,9 +166,13 @@ static int scmi_domain_reset(const struct scmi_protocol_handle *ph, u32 domain,
|
||||
struct scmi_xfer *t;
|
||||
struct scmi_msg_reset_domain_reset *dom;
|
||||
struct scmi_reset_info *pi = ph->get_priv(ph);
|
||||
struct reset_dom_info *rdom = pi->dom_info + domain;
|
||||
struct reset_dom_info *rdom;
|
||||
|
||||
if (rdom->async_reset)
|
||||
if (domain >= pi->num_domains)
|
||||
return -EINVAL;
|
||||
|
||||
rdom = pi->dom_info + domain;
|
||||
if (rdom->async_reset && flags & AUTONOMOUS_RESET)
|
||||
flags |= ASYNCHRONOUS_RESET;
|
||||
|
||||
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,
|
||||
dom->flags = cpu_to_le32(flags);
|
||||
dom->reset_state = cpu_to_le32(state);
|
||||
|
||||
if (rdom->async_reset)
|
||||
if (flags & ASYNCHRONOUS_RESET)
|
||||
ret = ph->xops->do_xfer_with_response(ph, t);
|
||||
else
|
||||
ret = ph->xops->do_xfer(ph, t);
|
||||
|
||||
@@ -138,9 +138,28 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev)
|
||||
scmi_pd_data->domains = domains;
|
||||
scmi_pd_data->num_domains = num_domains;
|
||||
|
||||
dev_set_drvdata(dev, scmi_pd_data);
|
||||
|
||||
return of_genpd_add_provider_onecell(np, scmi_pd_data);
|
||||
}
|
||||
|
||||
static void scmi_pm_domain_remove(struct scmi_device *sdev)
|
||||
{
|
||||
int i;
|
||||
struct genpd_onecell_data *scmi_pd_data;
|
||||
struct device *dev = &sdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
|
||||
of_genpd_del_provider(np);
|
||||
|
||||
scmi_pd_data = dev_get_drvdata(dev);
|
||||
for (i = 0; i < scmi_pd_data->num_domains; i++) {
|
||||
if (!scmi_pd_data->domains[i])
|
||||
continue;
|
||||
pm_genpd_remove(scmi_pd_data->domains[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct scmi_device_id scmi_id_table[] = {
|
||||
{ SCMI_PROTOCOL_POWER, "genpd" },
|
||||
{ },
|
||||
@@ -150,6 +169,7 @@ MODULE_DEVICE_TABLE(scmi, scmi_id_table);
|
||||
static struct scmi_driver scmi_power_domain_driver = {
|
||||
.name = "scmi-power-domain",
|
||||
.probe = scmi_pm_domain_probe,
|
||||
.remove = scmi_pm_domain_remove,
|
||||
.id_table = scmi_id_table,
|
||||
};
|
||||
module_scmi_driver(scmi_power_domain_driver);
|
||||
|
||||
@@ -762,6 +762,10 @@ static int scmi_sensor_config_get(const struct scmi_protocol_handle *ph,
|
||||
{
|
||||
int ret;
|
||||
struct scmi_xfer *t;
|
||||
struct sensors_info *si = ph->get_priv(ph);
|
||||
|
||||
if (sensor_id >= si->num_sensors)
|
||||
return -EINVAL;
|
||||
|
||||
ret = ph->xops->xfer_get_init(ph, SENSOR_CONFIG_GET,
|
||||
sizeof(__le32), sizeof(__le32), &t);
|
||||
@@ -771,7 +775,6 @@ static int scmi_sensor_config_get(const struct scmi_protocol_handle *ph,
|
||||
put_unaligned_le32(sensor_id, t->tx.buf);
|
||||
ret = ph->xops->do_xfer(ph, t);
|
||||
if (!ret) {
|
||||
struct sensors_info *si = ph->get_priv(ph);
|
||||
struct scmi_sensor_info *s = si->sensors + sensor_id;
|
||||
|
||||
*sensor_config = get_unaligned_le64(t->rx.buf);
|
||||
@@ -788,6 +791,10 @@ static int scmi_sensor_config_set(const struct scmi_protocol_handle *ph,
|
||||
int ret;
|
||||
struct scmi_xfer *t;
|
||||
struct scmi_msg_sensor_config_set *msg;
|
||||
struct sensors_info *si = ph->get_priv(ph);
|
||||
|
||||
if (sensor_id >= si->num_sensors)
|
||||
return -EINVAL;
|
||||
|
||||
ret = ph->xops->xfer_get_init(ph, SENSOR_CONFIG_SET,
|
||||
sizeof(*msg), 0, &t);
|
||||
@@ -800,7 +807,6 @@ static int scmi_sensor_config_set(const struct scmi_protocol_handle *ph,
|
||||
|
||||
ret = ph->xops->do_xfer(ph, t);
|
||||
if (!ret) {
|
||||
struct sensors_info *si = ph->get_priv(ph);
|
||||
struct scmi_sensor_info *s = si->sensors + sensor_id;
|
||||
|
||||
s->sensor_config = sensor_config;
|
||||
@@ -831,8 +837,11 @@ static int scmi_sensor_reading_get(const struct scmi_protocol_handle *ph,
|
||||
int ret;
|
||||
struct scmi_xfer *t;
|
||||
struct scmi_msg_sensor_reading_get *sensor;
|
||||
struct scmi_sensor_info *s;
|
||||
struct sensors_info *si = ph->get_priv(ph);
|
||||
struct scmi_sensor_info *s = si->sensors + sensor_id;
|
||||
|
||||
if (sensor_id >= si->num_sensors)
|
||||
return -EINVAL;
|
||||
|
||||
ret = ph->xops->xfer_get_init(ph, SENSOR_READING_GET,
|
||||
sizeof(*sensor), 0, &t);
|
||||
@@ -841,6 +850,7 @@ static int scmi_sensor_reading_get(const struct scmi_protocol_handle *ph,
|
||||
|
||||
sensor = t->tx.buf;
|
||||
sensor->id = cpu_to_le32(sensor_id);
|
||||
s = si->sensors + sensor_id;
|
||||
if (s->async) {
|
||||
sensor->flags = cpu_to_le32(SENSOR_READ_ASYNC);
|
||||
ret = ph->xops->do_xfer_with_response(ph, t);
|
||||
@@ -895,9 +905,13 @@ scmi_sensor_reading_get_timestamped(const struct scmi_protocol_handle *ph,
|
||||
int ret;
|
||||
struct scmi_xfer *t;
|
||||
struct scmi_msg_sensor_reading_get *sensor;
|
||||
struct scmi_sensor_info *s;
|
||||
struct sensors_info *si = ph->get_priv(ph);
|
||||
struct scmi_sensor_info *s = si->sensors + sensor_id;
|
||||
|
||||
if (sensor_id >= si->num_sensors)
|
||||
return -EINVAL;
|
||||
|
||||
s = si->sensors + sensor_id;
|
||||
if (!count || !readings ||
|
||||
(!s->num_axis && count > 1) || (s->num_axis && count > s->num_axis))
|
||||
return -EINVAL;
|
||||
@@ -948,6 +962,9 @@ scmi_sensor_info_get(const struct scmi_protocol_handle *ph, u32 sensor_id)
|
||||
{
|
||||
struct sensors_info *si = ph->get_priv(ph);
|
||||
|
||||
if (sensor_id >= si->num_sensors)
|
||||
return NULL;
|
||||
|
||||
return si->sensors + sensor_id;
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ struct scmi_protocol_handle;
|
||||
struct scmi_clk_proto_ops {
|
||||
int (*count_get)(const struct scmi_protocol_handle *ph);
|
||||
|
||||
const struct scmi_clock_info *(*info_get)
|
||||
const struct scmi_clock_info __must_check *(*info_get)
|
||||
(const struct scmi_protocol_handle *ph, u32 clk_id);
|
||||
int (*rate_get)(const struct scmi_protocol_handle *ph, u32 clk_id,
|
||||
u64 *rate);
|
||||
@@ -466,7 +466,7 @@ enum scmi_sensor_class {
|
||||
*/
|
||||
struct scmi_sensor_proto_ops {
|
||||
int (*count_get)(const struct scmi_protocol_handle *ph);
|
||||
const struct scmi_sensor_info *(*info_get)
|
||||
const struct scmi_sensor_info __must_check *(*info_get)
|
||||
(const struct scmi_protocol_handle *ph, u32 sensor_id);
|
||||
int (*trip_point_config)(const struct scmi_protocol_handle *ph,
|
||||
u32 sensor_id, u8 trip_id, u64 trip_value);
|
||||
|
||||
+15
-15
@@ -27,9 +27,9 @@ TRACE_EVENT(scmi_fc_call,
|
||||
__entry->val2 = val2;
|
||||
),
|
||||
|
||||
TP_printk("[0x%02X]:[0x%02X]:[%08X]:%u:%u",
|
||||
__entry->protocol_id, __entry->msg_id,
|
||||
__entry->res_id, __entry->val1, __entry->val2)
|
||||
TP_printk("pt=%02X msg_id=%02X res_id:%u vals=%u:%u",
|
||||
__entry->protocol_id, __entry->msg_id,
|
||||
__entry->res_id, __entry->val1, __entry->val2)
|
||||
);
|
||||
|
||||
TRACE_EVENT(scmi_xfer_begin,
|
||||
@@ -53,9 +53,9 @@ TRACE_EVENT(scmi_xfer_begin,
|
||||
__entry->poll = poll;
|
||||
),
|
||||
|
||||
TP_printk("transfer_id=%d msg_id=%u protocol_id=%u seq=%u poll=%u",
|
||||
__entry->transfer_id, __entry->msg_id, __entry->protocol_id,
|
||||
__entry->seq, __entry->poll)
|
||||
TP_printk("pt=%02X msg_id=%02X seq=%04X transfer_id=%X poll=%u",
|
||||
__entry->protocol_id, __entry->msg_id, __entry->seq,
|
||||
__entry->transfer_id, __entry->poll)
|
||||
);
|
||||
|
||||
TRACE_EVENT(scmi_xfer_response_wait,
|
||||
@@ -81,9 +81,9 @@ TRACE_EVENT(scmi_xfer_response_wait,
|
||||
__entry->poll = poll;
|
||||
),
|
||||
|
||||
TP_printk("transfer_id=%d msg_id=%u protocol_id=%u seq=%u tmo_ms=%u poll=%u",
|
||||
__entry->transfer_id, __entry->msg_id, __entry->protocol_id,
|
||||
__entry->seq, __entry->timeout, __entry->poll)
|
||||
TP_printk("pt=%02X msg_id=%02X seq=%04X transfer_id=%X tmo_ms=%u poll=%u",
|
||||
__entry->protocol_id, __entry->msg_id, __entry->seq,
|
||||
__entry->transfer_id, __entry->timeout, __entry->poll)
|
||||
);
|
||||
|
||||
TRACE_EVENT(scmi_xfer_end,
|
||||
@@ -107,9 +107,9 @@ TRACE_EVENT(scmi_xfer_end,
|
||||
__entry->status = status;
|
||||
),
|
||||
|
||||
TP_printk("transfer_id=%d msg_id=%u protocol_id=%u seq=%u status=%d",
|
||||
__entry->transfer_id, __entry->msg_id, __entry->protocol_id,
|
||||
__entry->seq, __entry->status)
|
||||
TP_printk("pt=%02X msg_id=%02X seq=%04X transfer_id=%X s=%d",
|
||||
__entry->protocol_id, __entry->msg_id, __entry->seq,
|
||||
__entry->transfer_id, __entry->status)
|
||||
);
|
||||
|
||||
TRACE_EVENT(scmi_rx_done,
|
||||
@@ -133,9 +133,9 @@ TRACE_EVENT(scmi_rx_done,
|
||||
__entry->msg_type = msg_type;
|
||||
),
|
||||
|
||||
TP_printk("transfer_id=%d msg_id=%u protocol_id=%u seq=%u msg_type=%u",
|
||||
__entry->transfer_id, __entry->msg_id, __entry->protocol_id,
|
||||
__entry->seq, __entry->msg_type)
|
||||
TP_printk("pt=%02X msg_id=%02X seq=%04X transfer_id=%X msg_type=%u",
|
||||
__entry->protocol_id, __entry->msg_id, __entry->seq,
|
||||
__entry->transfer_id, __entry->msg_type)
|
||||
);
|
||||
|
||||
TRACE_EVENT(scmi_msg_dump,
|
||||
|
||||
Reference in New Issue
Block a user