Arm SCMI fixes for v6.7

A fix for possible truncation/overflow in the frequency computations
 as both the performance value and the multiplier are 32bit values.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEunHlEgbzHrJD3ZPhAEG6vDF+4pgFAmVtybAACgkQAEG6vDF+
 4pjohBAAoiSCkrvVfqOaEMakIzZ+xKf58u+xchVJMmFWhLDYmtRiF8FTDYYSORVv
 lW/Py9mzZWdeDX0wksiF1zl4JdnR7WuVNtEvBvs10U6KHCpnD273lsszdCam0TWD
 4XuszRgrfNtw2wdsApVJndOKwQ/+0yMLX2aYcbADi6Q1ubh7nRJoCK7wooGvgeRy
 q1zT6Uggp14auwOuJsr6eID1L2rBW/HLpVFKQX8bwlACOZFEPZ/8o+QvChmRNYl3
 Ph9P8a4ZrziM2HjnOoU/N+2pEHSFzT4VtXUj3CkTbFv5o8mCQHDLdLFJnoCTK7ZP
 50mVOgVCoTXYWvtMBlRmh4/KJrkUJGBl+eQQcwT1rJolNA1dFtlZqxNYDtPbx8Dn
 9fuVMcCmGln112ytqgoxj7ZPWxWt8ns4X7UWC4raRgC+D46A/de6c9XimH3lNWz4
 Kr/KuWObzWjcnIrZlFqndesTQwUYRSicsZwLaFPl6G3IvAcIyCB9DaFCsOeMNpAF
 kPDMHpz2KueOg1PUxElm1QEdban8CHiqX9E7Bvk5InAjN7wuaqXRl+AldW4LZ0pE
 MtwjJasW/sYZvUH7v6bdII8UlQd5LTI3xD/atiwXvieAkLfffv8jjXJc7oX+IleB
 rCNr8qKZ0odl81F8NlWcOX1YFZTscdNnwgOBTjzzcfjBegQlc74=
 =1+Km
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEiK/NIGsWEZVxh/FrYKtH/8kJUicFAmVwknYACgkQYKtH/8kJ
 Uic/XxAAnfj8Qe+zBHz2KIpCYKSyNwVMiuQ4tn7Rh8nAKMeKI5gQ586jkMhw9q6P
 jZ4XdfQqPMcFITku9u4bx3JWo/EXzQNEAvnj7/CSlDoCVqnRqXE8UeHkb5RdbfQ0
 WzP1aaTFGnHDWTbKphAyGyChOubLDcVsQg9p4jm3JT8a/8cx80DQ/Gjzr7x6tsIu
 UURKLyHdvzEsUmpFk2Y22eBCG8rihjIqNLfF4TOu0MSV6324sd96bmGrqemdyIFG
 IqX4tUqViBmjpl2JD2zneQ1GgwLoZSrcEkH0xGwM4hprStqOxTydl3gCTcTnY2J8
 IBwediez9RDL+PaUm5FU15YWw8Yimii5wcbqeh8wK6nDA+5WslZOOymwl0QvkwWc
 Qe2Of30ZrlMJj5JHn4TW7pFNiMKc5oMTBSNHoZ+n+1Yk7qG2jlZgznUuyaadruJv
 989H6xhOMd44a4/RfNjWBilCoOTUVqlZUsoa+E3l0Zpf8KHVGrTEQkhHLkvfPkzs
 PGK4f+XJudgIe0sYr34AoSMml5qCfCfyF8ytjuVkrxZssHxDQRL/5hQlnrcwzlcf
 XNW+lWN/DwwyvSfxobhZYvUhFnzN8jBZKhErR1n7maiZgt3EOkQdkvFdzzm19AnR
 Gsv+oTsNRM/1ekFiTT6zw6okb78ZL/PltCWjuHCoyQWxIojuwPQ=
 =X/Fy
 -----END PGP SIGNATURE-----

Merge tag 'scmi-fixes-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/fixes

Arm SCMI fixes for v6.7

A fix for possible truncation/overflow in the frequency computations
as both the performance value and the multiplier are 32bit values.

* tag 'scmi-fixes-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux:
  firmware: arm_scmi: Fix possible frequency truncation when using level indexing mode
  firmware: arm_scmi: Fix frequency truncation by promoting multiplier type

Link: https://lore.kernel.org/r/20231204134724.30465-1-sudeep.holla@arm.com
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2023-12-06 16:25:42 +01:00
commit 2d8781ba59

View File

@ -152,7 +152,7 @@ struct perf_dom_info {
u32 opp_count;
u32 sustained_freq_khz;
u32 sustained_perf_level;
u32 mult_factor;
unsigned long mult_factor;
struct scmi_perf_domain_info info;
struct scmi_opp opp[MAX_OPPS];
struct scmi_fc_info *fc_info;
@ -268,13 +268,14 @@ scmi_perf_domain_attributes_get(const struct scmi_protocol_handle *ph,
dom_info->sustained_perf_level =
le32_to_cpu(attr->sustained_perf_level);
if (!dom_info->sustained_freq_khz ||
!dom_info->sustained_perf_level)
!dom_info->sustained_perf_level ||
dom_info->level_indexing_mode)
/* CPUFreq converts to kHz, hence default 1000 */
dom_info->mult_factor = 1000;
else
dom_info->mult_factor =
(dom_info->sustained_freq_khz * 1000) /
dom_info->sustained_perf_level;
(dom_info->sustained_freq_khz * 1000UL)
/ dom_info->sustained_perf_level;
strscpy(dom_info->info.name, attr->name,
SCMI_SHORT_NAME_MAX_SIZE);
}
@ -798,7 +799,7 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
if (!dom->level_indexing_mode)
freq = dom->opp[idx].perf * dom->mult_factor;
else
freq = dom->opp[idx].indicative_freq * 1000;
freq = dom->opp[idx].indicative_freq * dom->mult_factor;
data.level = dom->opp[idx].perf;
data.freq = freq;
@ -845,7 +846,8 @@ static int scmi_dvfs_freq_set(const struct scmi_protocol_handle *ph, u32 domain,
} else {
struct scmi_opp *opp;
opp = LOOKUP_BY_FREQ(dom->opps_by_freq, freq / 1000);
opp = LOOKUP_BY_FREQ(dom->opps_by_freq,
freq / dom->mult_factor);
if (!opp)
return -EIO;
@ -879,7 +881,7 @@ static int scmi_dvfs_freq_get(const struct scmi_protocol_handle *ph, u32 domain,
if (!opp)
return -EIO;
*freq = opp->indicative_freq * 1000;
*freq = opp->indicative_freq * dom->mult_factor;
}
return ret;
@ -902,7 +904,7 @@ static int scmi_dvfs_est_power_get(const struct scmi_protocol_handle *ph,
if (!dom->level_indexing_mode)
opp_freq = opp->perf * dom->mult_factor;
else
opp_freq = opp->indicative_freq * 1000;
opp_freq = opp->indicative_freq * dom->mult_factor;
if (opp_freq < *freq)
continue;