mirror of
https://git.proxmox.com/git/mirror_ubuntu-kernels.git
synced 2025-12-29 05:21:56 +00:00
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. -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEunHlEgbzHrJD3ZPhAEG6vDF+4pgFAmMHX00ACgkQAEG6vDF+ 4pgEQRAAxOv22MIag/QHC9CyRdgmn9x/pDvBVpCaO831VmIo53gV1QhSUl1wfadA NMH5zcs1QATz2swDyj30WAElwtMH7fbTR2KjR3TlHAVvSbM+gDqOoHRVMRFBIXd2 r3xqF06NqVRsk83ANM5MEtBMI9TJXCCWjyolHNbU2PxLgO85lsZ8SgazOql945Bi H3VSp6IrPQ2TL+GF58MEoyn5WiAEl/ZgpC0lMFl2P1kU4t1g1Rzxsr8LfmHKTpJl dyM4R51SB9G6NyJf1aeWxtybYhqkvkH8TOgwRjNGCWloidCKomXe/yTiguU2iAkm F3EF7va0Tjs0onxBEULDDPLv8GGqS1Z4rhFhpXoPEKeefx1taAZQPnzMCBNVmoxS WlSDuwC3L9jdwXExi3xLRID3zzXz7H5ESpi/FZhZ2MHYBU/ZkFx1nE+julRpb5QK p7sWQ8KjKkvGWmUv2OoI27O7K3PGfMnz46Z8fLFpfcTIein4yLgh+dh46rLO/0n1 iFwpjQeBrzKX7OXhSa3aKcXympi8LRLMXfEs0tB7XmDMQr92bSus8hkDjMcYOvDN 9JS0667RRM8LuGddPcW4jDsOXAFFpy0wNzIATMdmZRKp4IKlpsOhFyVwpDCW1Fg2 gKMQMeDxn1c0j8qEBY3xrSbjrfzVA7PE6s+6he8kXmva71Lfa/Q= =op8P -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmMZ+EoACgkQmmx57+YA GNkRAg/+PuDhY5LEJe1mDNrxzgC6/kXctJoofR2h4cZwGs3ZXdIn4apoDc3utxAS bBJ9SXZi44tIA41qs0ZkOHViP8361SKdHtGdW3v33w3wE8BzTHEV6ZezJhQiX5Qb juNQrtgCS9LAkgBfvBrp0tuFPRXIy2yQexcWARvbOvgRjqAoM79qUWPHOoL28vJw o8J5jogqrFRx5mbvvuGLGZvcu0Hp5FdDuNDyrjshzlGkQKG2ChRzQlf0iequ5ZzG vA8RHUP05tWh1doqlroyQhHL2CIxsEPw3WfqgthdBJOztrKV7kY9X7Az3jUK7LHx e1mTRgFZ3stBYagzosw4488RFUz0wEN/9o37C8Cn5B0hXPEjv3EOKtZpmS7R+CNi +Y5fugeghs4hSkJgZ6r73VXr2WVFZuuexCeOlcIoWVXaT8m79QSCb0bFndOpajIS OpduLncqSyNe7fF8/g1Ul0HpBDZH06Hf18EXvWX94jNqC368xZjJyRtvo8kb7oEu +fClemQoPL9DGYnv+RiEjTWPUsn7sIM0418oyDO0QaWrhcljuzn0tbtmZtWOeXrk ozj6CnukN40J77rXOVlMxqH16iAqZ9HDUAuolkXgo4/8uzMuNpiBwtgw8YExnzA9 o7vixof29kd1yH19TiC6enI+mmaTRZ/RT1TUPe7R4TaUW8wsdo0= =4nfv -----END PGP SIGNATURE----- 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:
commit
d4f1920d07
@ -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);
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user