hwmon fixes for v6.8-rc4

- coretemp: Various fixes, and increase number of supported CPU cores
 
 - aspeed-pwm-tacho: Add missing mutex protection
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEiHPvMQj9QTOCiqgVyx8mb86fmYEFAmXGPr0ACgkQyx8mb86f
 mYFcOw//ZxUrvtW450TbP6PaNYZMI1BRVyjp10gWd8IyCfvqhdRZfPagj4l66mmJ
 J3wA0iYIzZU+AAOMkftnwXiO1NJU45cQnvSXbRZOk6bD8GruVCJ6yly87TkjTNnB
 9zaCBhp2LjZUjB3NpVF8+SlQYxAjPJiv/RG3qQcYxpq57tMm621k47b/macAF4HA
 k/Matr/ZCKU2oJ9lge7Qcxpm/Sr5szmJLIZlTDev/pB2KC1bG9KEHGtvif2tLvzj
 DmgCZBniTIB/iZEW2U1o9otn0d11BsFvFV+8sszYekKXoK7Y7utWQ+t90NY1PjX+
 BNym1v/FSKa2nzC4UOGZ0QvVK3ydUu79Pn+OfXnWCHB6C8oIeeH7PmyiZCp0S+8s
 3xu5tDyDrG+pxnnoOxX3+GderL3SqGMEnNRpIOf1W5bfO2ea0gRRVM0ACt7ox4JF
 j9VqffwNw99OM7os4YLxp1QOGpFUGsyDp1MyrPLonCHqHOar+Knj/bIvAt874wZU
 cJvd/ntlmVN34cgl85YBR1L6YbyKJlafiv26o3mx8hpvGVXARC+UcCjQuzb+o/8v
 czYMPReTEe6TJbUwzaebD9J97e42H9lWJn0cA0h8ItGeZK+M1+lY+r6rgLb2DelJ
 FOJ0I6Ee8BlKGqGLBhzMPFGhgTdXqxsVacsrfzYKZmaK9tlkTR0=
 =HRcF
 -----END PGP SIGNATURE-----

Merge tag 'hwmon-for-v6.8-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging

Pull hwmon fixes from Guenter Roeck:

 - coretemp: Various fixes, and increase number of supported CPU cores

 - aspeed-pwm-tacho: Add missing mutex protection

* tag 'hwmon-for-v6.8-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging:
  hwmon: (coretemp) Enlarge per package core count limit
  hwmon: (coretemp) Fix bogus core_id to attr name mapping
  hwmon: (coretemp) Fix out-of-bounds memory access
  hwmon: (aspeed-pwm-tacho) mutex for tach reading
This commit is contained in:
Linus Torvalds 2024-02-09 10:35:39 -08:00
commit 5ca243c23e
2 changed files with 29 additions and 20 deletions

View File

@ -195,6 +195,8 @@ struct aspeed_pwm_tacho_data {
u8 fan_tach_ch_source[MAX_ASPEED_FAN_TACH_CHANNELS];
struct aspeed_cooling_device *cdev[8];
const struct attribute_group *groups[3];
/* protects access to shared ASPEED_PTCR_RESULT */
struct mutex tach_lock;
};
enum type { TYPEM, TYPEN, TYPEO };
@ -529,6 +531,8 @@ static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tacho_data *priv,
u8 fan_tach_ch_source, type, mode, both;
int ret;
mutex_lock(&priv->tach_lock);
regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0);
regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0x1 << fan_tach_ch);
@ -546,6 +550,8 @@ static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tacho_data *priv,
ASPEED_RPM_STATUS_SLEEP_USEC,
usec);
mutex_unlock(&priv->tach_lock);
/* return -ETIMEDOUT if we didn't get an answer. */
if (ret)
return ret;
@ -915,6 +921,7 @@ static int aspeed_pwm_tacho_probe(struct platform_device *pdev)
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
mutex_init(&priv->tach_lock);
priv->regmap = devm_regmap_init(dev, NULL, (__force void *)regs,
&aspeed_pwm_tacho_regmap_config);
if (IS_ERR(priv->regmap))

View File

@ -41,7 +41,7 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius");
#define PKG_SYSFS_ATTR_NO 1 /* Sysfs attribute for package temp */
#define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */
#define NUM_REAL_CORES 128 /* Number of Real cores per cpu */
#define NUM_REAL_CORES 512 /* Number of Real cores per cpu */
#define CORETEMP_NAME_LENGTH 28 /* String Length of attrs */
#define MAX_CORE_ATTRS 4 /* Maximum no of basic attrs */
#define TOTAL_ATTRS (MAX_CORE_ATTRS + 1)
@ -419,7 +419,7 @@ static ssize_t show_temp(struct device *dev,
}
static int create_core_attrs(struct temp_data *tdata, struct device *dev,
int attr_no)
int index)
{
int i;
static ssize_t (*const rd_ptr[TOTAL_ATTRS]) (struct device *dev,
@ -431,13 +431,20 @@ static int create_core_attrs(struct temp_data *tdata, struct device *dev,
};
for (i = 0; i < tdata->attr_size; i++) {
/*
* We map the attr number to core id of the CPU
* The attr number is always core id + 2
* The Pkgtemp will always show up as temp1_*, if available
*/
int attr_no = tdata->is_pkg_data ? 1 : tdata->cpu_core_id + 2;
snprintf(tdata->attr_name[i], CORETEMP_NAME_LENGTH,
"temp%d_%s", attr_no, suffixes[i]);
sysfs_attr_init(&tdata->sd_attrs[i].dev_attr.attr);
tdata->sd_attrs[i].dev_attr.attr.name = tdata->attr_name[i];
tdata->sd_attrs[i].dev_attr.attr.mode = 0444;
tdata->sd_attrs[i].dev_attr.show = rd_ptr[i];
tdata->sd_attrs[i].index = attr_no;
tdata->sd_attrs[i].index = index;
tdata->attrs[i] = &tdata->sd_attrs[i].dev_attr.attr;
}
tdata->attr_group.attrs = tdata->attrs;
@ -495,30 +502,25 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu,
struct platform_data *pdata = platform_get_drvdata(pdev);
struct cpuinfo_x86 *c = &cpu_data(cpu);
u32 eax, edx;
int err, index, attr_no;
int err, index;
if (!housekeeping_cpu(cpu, HK_TYPE_MISC))
return 0;
/*
* Find attr number for sysfs:
* We map the attr number to core id of the CPU
* The attr number is always core id + 2
* The Pkgtemp will always show up as temp1_*, if available
* Get the index of tdata in pdata->core_data[]
* tdata for package: pdata->core_data[1]
* tdata for core: pdata->core_data[2] .. pdata->core_data[NUM_REAL_CORES + 1]
*/
if (pkg_flag) {
attr_no = PKG_SYSFS_ATTR_NO;
index = PKG_SYSFS_ATTR_NO;
} else {
index = ida_alloc(&pdata->ida, GFP_KERNEL);
index = ida_alloc_max(&pdata->ida, NUM_REAL_CORES - 1, GFP_KERNEL);
if (index < 0)
return index;
pdata->cpu_map[index] = topology_core_id(cpu);
attr_no = index + BASE_SYSFS_ATTR_NO;
}
if (attr_no > MAX_CORE_DATA - 1) {
err = -ERANGE;
goto ida_free;
pdata->cpu_map[index] = topology_core_id(cpu);
index += BASE_SYSFS_ATTR_NO;
}
tdata = init_temp_data(cpu, pkg_flag);
@ -544,20 +546,20 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu,
if (get_ttarget(tdata, &pdev->dev) >= 0)
tdata->attr_size++;
pdata->core_data[attr_no] = tdata;
pdata->core_data[index] = tdata;
/* Create sysfs interfaces */
err = create_core_attrs(tdata, pdata->hwmon_dev, attr_no);
err = create_core_attrs(tdata, pdata->hwmon_dev, index);
if (err)
goto exit_free;
return 0;
exit_free:
pdata->core_data[attr_no] = NULL;
pdata->core_data[index] = NULL;
kfree(tdata);
ida_free:
if (!pkg_flag)
ida_free(&pdata->ida, index);
ida_free(&pdata->ida, index - BASE_SYSFS_ATTR_NO);
return err;
}