* [PATCH 0/2] hwmon: (macsmc) Various fixes hwmon driver
@ 2026-01-29 17:51 Guenter Roeck
2026-01-29 17:51 ` [PATCH 1/2] hwmon: (macsmc) Fix regressions in Apple Silicon SMC " Guenter Roeck
2026-01-29 17:51 ` [PATCH 2/2] hwmon: (macsmc) Fix overflows, underflows, and sign extension Guenter Roeck
0 siblings, 2 replies; 6+ messages in thread
From: Guenter Roeck @ 2026-01-29 17:51 UTC (permalink / raw)
To: Hardware Monitoring; +Cc: Guenter Roeck
Nathan reported a problem with FIELD_PREP in the macmsc driver.
Repeated analysis using Gemini 3 exposed a number of additional problems.
This patch series fixes all identified problems.
----------------------------------------------------------------
Guenter Roeck (2):
hwmon: (macsmc) Fix regressions in Apple Silicon SMC hwmon driver
hwmon: (macsmc) Fix overflows, underflows, and sign extension
drivers/hwmon/macsmc-hwmon.c | 51 ++++++++++++++++++++++----------------------
1 file changed, 26 insertions(+), 25 deletions(-)
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 1/2] hwmon: (macsmc) Fix regressions in Apple Silicon SMC hwmon driver 2026-01-29 17:51 [PATCH 0/2] hwmon: (macsmc) Various fixes hwmon driver Guenter Roeck @ 2026-01-29 17:51 ` Guenter Roeck 2026-02-03 8:06 ` Nathan Chancellor 2026-02-20 10:20 ` James Calligeros 2026-01-29 17:51 ` [PATCH 2/2] hwmon: (macsmc) Fix overflows, underflows, and sign extension Guenter Roeck 1 sibling, 2 replies; 6+ messages in thread From: Guenter Roeck @ 2026-01-29 17:51 UTC (permalink / raw) To: Hardware Monitoring Cc: Guenter Roeck, Nathan Chancellor, James Calligeros, Neal Gompa, Janne Grunau The recently added macsmc-hwmon driver contained several critical bugs in its sensor population logic and float conversion routines. Specifically: - The voltage sensor population loop used the wrong prefix ("volt-" instead of "voltage-") and incorrectly assigned sensors to the temperature sensor array (hwmon->temp.sensors) instead of the voltage sensor array (hwmon->volt.sensors). This would lead to out-of-bounds memory access or data corruption when both temperature and voltage sensors were present. - The float conversion in macsmc_hwmon_write_f32() had flawed exponent logic for values >= 2^24 and lacked masking for the mantissa, which could lead to incorrect values being written to the SMC. Fix these issues to ensure correct sensor registration and reliable manual fan control. Confirm that the reported overflow in FIELD_PREP is fixed by declaring macsmc_hwmon_write_f32() as __always_inline for a compile test. Fixes: 785205fd8139 ("hwmon: Add Apple Silicon SMC hwmon driver") Reported-by: Nathan Chancellor <nathan@kernel.org> Closes: https://lore.kernel.org/linux-hwmon/20260119195817.GA1035354@ax162/ Cc: James Calligeros <jcalligeros99@gmail.com> Cc: Nathan Chancellor <nathan@kernel.org> Cc: Neal Gompa <neal@gompa.dev> Cc: Janne Grunau <j@jannau.net> Signed-off-by: Guenter Roeck <linux@roeck-us.net> --- drivers/hwmon/macsmc-hwmon.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/hwmon/macsmc-hwmon.c b/drivers/hwmon/macsmc-hwmon.c index 1c0bbec7e8eb..40d25c81b443 100644 --- a/drivers/hwmon/macsmc-hwmon.c +++ b/drivers/hwmon/macsmc-hwmon.c @@ -228,25 +228,22 @@ static int macsmc_hwmon_write_f32(struct apple_smc *smc, smc_key key, int value) { u64 val; u32 fval = 0; - int exp = 0, neg; + int exp, neg; + neg = value < 0; val = abs(value); - neg = val != value; if (val) { - int msb = __fls(val) - exp; + exp = __fls(val); - if (msb > 23) { - val >>= msb - FLT_MANT_BIAS; - exp -= msb - FLT_MANT_BIAS; - } else if (msb < 23) { - val <<= FLT_MANT_BIAS - msb; - exp += msb; - } + if (exp > 23) + val >>= exp - 23; + else + val <<= 23 - exp; fval = FIELD_PREP(FLT_SIGN_MASK, neg) | FIELD_PREP(FLT_EXP_MASK, exp + FLT_EXP_BIAS) | - FIELD_PREP(FLT_MANT_MASK, val); + FIELD_PREP(FLT_MANT_MASK, val & FLT_MANT_MASK); } return apple_smc_write_u32(smc, key, fval); @@ -663,8 +660,8 @@ static int macsmc_hwmon_populate_sensors(struct macsmc_hwmon *hwmon, if (!hwmon->volt.sensors) return -ENOMEM; - for_each_child_of_node_with_prefix(hwmon_node, key_node, "volt-") { - sensor = &hwmon->temp.sensors[hwmon->temp.count]; + for_each_child_of_node_with_prefix(hwmon_node, key_node, "voltage-") { + sensor = &hwmon->volt.sensors[hwmon->volt.count]; if (!macsmc_hwmon_create_sensor(hwmon->dev, hwmon->smc, key_node, sensor)) { sensor->attrs = HWMON_I_INPUT; -- 2.45.2 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] hwmon: (macsmc) Fix regressions in Apple Silicon SMC hwmon driver 2026-01-29 17:51 ` [PATCH 1/2] hwmon: (macsmc) Fix regressions in Apple Silicon SMC " Guenter Roeck @ 2026-02-03 8:06 ` Nathan Chancellor 2026-02-12 6:18 ` Guenter Roeck 2026-02-20 10:20 ` James Calligeros 1 sibling, 1 reply; 6+ messages in thread From: Nathan Chancellor @ 2026-02-03 8:06 UTC (permalink / raw) To: Guenter Roeck Cc: Hardware Monitoring, James Calligeros, Neal Gompa, Janne Grunau On Thu, Jan 29, 2026 at 09:51:10AM -0800, Guenter Roeck wrote: > The recently added macsmc-hwmon driver contained several critical > bugs in its sensor population logic and float conversion routines. > > Specifically: > - The voltage sensor population loop used the wrong prefix ("volt-" > instead of "voltage-") and incorrectly assigned sensors to the > temperature sensor array (hwmon->temp.sensors) instead of the > voltage sensor array (hwmon->volt.sensors). This would lead to > out-of-bounds memory access or data corruption when both temperature > and voltage sensors were present. > - The float conversion in macsmc_hwmon_write_f32() had flawed exponent > logic for values >= 2^24 and lacked masking for the mantissa, which > could lead to incorrect values being written to the SMC. > > Fix these issues to ensure correct sensor registration and reliable > manual fan control. > > Confirm that the reported overflow in FIELD_PREP is fixed by declaring > macsmc_hwmon_write_f32() as __always_inline for a compile test. > > Fixes: 785205fd8139 ("hwmon: Add Apple Silicon SMC hwmon driver") > Reported-by: Nathan Chancellor <nathan@kernel.org> > Closes: https://lore.kernel.org/linux-hwmon/20260119195817.GA1035354@ax162/ > Cc: James Calligeros <jcalligeros99@gmail.com> > Cc: Nathan Chancellor <nathan@kernel.org> > Cc: Neal Gompa <neal@gompa.dev> > Cc: Janne Grunau <j@jannau.net> > Signed-off-by: Guenter Roeck <linux@roeck-us.net> Thanks, I build tested this with all affected clang versions and saw no errors. I cannot say if it is correct from a hardware perspective though. Tested-by: Nathan Chancellor <nathan@kernel.org> # build only > --- > drivers/hwmon/macsmc-hwmon.c | 23 ++++++++++------------- > 1 file changed, 10 insertions(+), 13 deletions(-) > > diff --git a/drivers/hwmon/macsmc-hwmon.c b/drivers/hwmon/macsmc-hwmon.c > index 1c0bbec7e8eb..40d25c81b443 100644 > --- a/drivers/hwmon/macsmc-hwmon.c > +++ b/drivers/hwmon/macsmc-hwmon.c > @@ -228,25 +228,22 @@ static int macsmc_hwmon_write_f32(struct apple_smc *smc, smc_key key, int value) > { > u64 val; > u32 fval = 0; > - int exp = 0, neg; > + int exp, neg; > > + neg = value < 0; > val = abs(value); > - neg = val != value; > > if (val) { > - int msb = __fls(val) - exp; > + exp = __fls(val); > > - if (msb > 23) { > - val >>= msb - FLT_MANT_BIAS; > - exp -= msb - FLT_MANT_BIAS; > - } else if (msb < 23) { > - val <<= FLT_MANT_BIAS - msb; > - exp += msb; > - } > + if (exp > 23) > + val >>= exp - 23; > + else > + val <<= 23 - exp; > > fval = FIELD_PREP(FLT_SIGN_MASK, neg) | > FIELD_PREP(FLT_EXP_MASK, exp + FLT_EXP_BIAS) | > - FIELD_PREP(FLT_MANT_MASK, val); > + FIELD_PREP(FLT_MANT_MASK, val & FLT_MANT_MASK); > } > > return apple_smc_write_u32(smc, key, fval); > @@ -663,8 +660,8 @@ static int macsmc_hwmon_populate_sensors(struct macsmc_hwmon *hwmon, > if (!hwmon->volt.sensors) > return -ENOMEM; > > - for_each_child_of_node_with_prefix(hwmon_node, key_node, "volt-") { > - sensor = &hwmon->temp.sensors[hwmon->temp.count]; > + for_each_child_of_node_with_prefix(hwmon_node, key_node, "voltage-") { > + sensor = &hwmon->volt.sensors[hwmon->volt.count]; > if (!macsmc_hwmon_create_sensor(hwmon->dev, hwmon->smc, key_node, sensor)) { > sensor->attrs = HWMON_I_INPUT; > > -- > 2.45.2 > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] hwmon: (macsmc) Fix regressions in Apple Silicon SMC hwmon driver 2026-02-03 8:06 ` Nathan Chancellor @ 2026-02-12 6:18 ` Guenter Roeck 0 siblings, 0 replies; 6+ messages in thread From: Guenter Roeck @ 2026-02-12 6:18 UTC (permalink / raw) To: Nathan Chancellor Cc: Hardware Monitoring, James Calligeros, Neal Gompa, Janne Grunau On 2/3/26 00:06, Nathan Chancellor wrote: > On Thu, Jan 29, 2026 at 09:51:10AM -0800, Guenter Roeck wrote: >> The recently added macsmc-hwmon driver contained several critical >> bugs in its sensor population logic and float conversion routines. >> >> Specifically: >> - The voltage sensor population loop used the wrong prefix ("volt-" >> instead of "voltage-") and incorrectly assigned sensors to the >> temperature sensor array (hwmon->temp.sensors) instead of the >> voltage sensor array (hwmon->volt.sensors). This would lead to >> out-of-bounds memory access or data corruption when both temperature >> and voltage sensors were present. >> - The float conversion in macsmc_hwmon_write_f32() had flawed exponent >> logic for values >= 2^24 and lacked masking for the mantissa, which >> could lead to incorrect values being written to the SMC. >> >> Fix these issues to ensure correct sensor registration and reliable >> manual fan control. >> >> Confirm that the reported overflow in FIELD_PREP is fixed by declaring >> macsmc_hwmon_write_f32() as __always_inline for a compile test. >> >> Fixes: 785205fd8139 ("hwmon: Add Apple Silicon SMC hwmon driver") >> Reported-by: Nathan Chancellor <nathan@kernel.org> >> Closes: https://lore.kernel.org/linux-hwmon/20260119195817.GA1035354@ax162/ >> Cc: James Calligeros <jcalligeros99@gmail.com> >> Cc: Nathan Chancellor <nathan@kernel.org> >> Cc: Neal Gompa <neal@gompa.dev> >> Cc: Janne Grunau <j@jannau.net> >> Signed-off-by: Guenter Roeck <linux@roeck-us.net> > > Thanks, I build tested this with all affected clang versions and saw no > errors. I cannot say if it is correct from a hardware perspective > though. > > Tested-by: Nathan Chancellor <nathan@kernel.org> # build only > I would have liked to get some feedback from the driver author, but it looks like that won't happen. I will queue up the patches for v7.0. Guenter ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] hwmon: (macsmc) Fix regressions in Apple Silicon SMC hwmon driver 2026-01-29 17:51 ` [PATCH 1/2] hwmon: (macsmc) Fix regressions in Apple Silicon SMC " Guenter Roeck 2026-02-03 8:06 ` Nathan Chancellor @ 2026-02-20 10:20 ` James Calligeros 1 sibling, 0 replies; 6+ messages in thread From: James Calligeros @ 2026-02-20 10:20 UTC (permalink / raw) To: Hardware Monitoring, Guenter Roeck Cc: Guenter Roeck, Nathan Chancellor, Neal Gompa, Janne Grunau On Friday, 30 January 2026 3:51:10 am Australian Eastern Standard Time Guenter Roeck wrote: > The recently added macsmc-hwmon driver contained several critical > bugs in its sensor population logic and float conversion routines. > > Specifically: > - The voltage sensor population loop used the wrong prefix ("volt-" > instead of "voltage-") and incorrectly assigned sensors to the > temperature sensor array (hwmon->temp.sensors) instead of the > voltage sensor array (hwmon->volt.sensors). This would lead to > out-of-bounds memory access or data corruption when both temperature > and voltage sensors were present. > - The float conversion in macsmc_hwmon_write_f32() had flawed exponent > logic for values >= 2^24 and lacked masking for the mantissa, which > could lead to incorrect values being written to the SMC. > > Fix these issues to ensure correct sensor registration and reliable > manual fan control. > > Confirm that the reported overflow in FIELD_PREP is fixed by declaring > macsmc_hwmon_write_f32() as __always_inline for a compile test. > > Fixes: 785205fd8139 ("hwmon: Add Apple Silicon SMC hwmon driver") > Reported-by: Nathan Chancellor <nathan@kernel.org> > Closes: https://lore.kernel.org/linux-hwmon/20260119195817.GA1035354@ax162/ > Cc: James Calligeros <jcalligeros99@gmail.com> > Cc: Nathan Chancellor <nathan@kernel.org> > Cc: Neal Gompa <neal@gompa.dev> > Cc: Janne Grunau <j@jannau.net> > Signed-off-by: Guenter Roeck <linux@roeck-us.net> > --- > drivers/hwmon/macsmc-hwmon.c | 23 ++++++++++------------- > 1 file changed, 10 insertions(+), 13 deletions(-) > Reviewed-by: James Calligeros <jcalligeros99@gmail.com> for the series. It would be helpful to Cc the Asahi list as per MAINTAINERS in the future; any one of us could have reviewed and tested these two patches while I had been unable to[1]. Regards, James [1] https://lore.kernel.org/asahi/CAHgNfTynZHNt3=JY82-WPR1b_1JyoJ=hnazcPwJtSStOZsA1=g@mail.gmail.com/ ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] hwmon: (macsmc) Fix overflows, underflows, and sign extension 2026-01-29 17:51 [PATCH 0/2] hwmon: (macsmc) Various fixes hwmon driver Guenter Roeck 2026-01-29 17:51 ` [PATCH 1/2] hwmon: (macsmc) Fix regressions in Apple Silicon SMC " Guenter Roeck @ 2026-01-29 17:51 ` Guenter Roeck 1 sibling, 0 replies; 6+ messages in thread From: Guenter Roeck @ 2026-01-29 17:51 UTC (permalink / raw) To: Hardware Monitoring Cc: Guenter Roeck, James Calligeros, Nathan Chancellor, Neal Gompa, Janne Grunau The macsmc-hwmon driver experienced several issues related to value scaling and type conversion: 1. macsmc_hwmon_read_f32_scaled() clipped values to INT_MAX/INT_MIN. On 64-bit systems, hwmon supports long values, so clipping to 32-bit range was premature and caused loss of range for high-power sensors. Changed it to use long and clip to LONG_MAX/LONG_MIN. 2. The overflow check in macsmc_hwmon_read_f32_scaled() used 1UL, which is 32-bit on some platforms. Switched to 1ULL. 3. macsmc_hwmon_read_key() used a u32 temporary variable for f32 values. When assigned to a 64-bit long, negative values were zero-extended instead of sign-extended, resulting in large positive numbers. 4. macsmc_hwmon_read_ioft_scaled() used mult_frac() which could overflow during intermediate multiplication. Switched to mul_u64_u32_div() to handle the 64-bit multiplication safely. 5. ioft values (unsigned 48.16) could overflow long when scaled by 1,000,000. Added explicit clipping to LONG_MAX in the caller. 6. macsmc_hwmon_write_f32() truncated its long argument to int, potentially causing issues for large values. Fix these issues by using appropriate types and helper functions. Fixes: 785205fd8139 ("hwmon: Add Apple Silicon SMC hwmon driver") Cc: James Calligeros <jcalligeros99@gmail.com> Cc: Nathan Chancellor <nathan@kernel.org> Cc: Neal Gompa <neal@gompa.dev> Cc: Janne Grunau <j@jannau.net> Signed-off-by: Guenter Roeck <linux@roeck-us.net> --- drivers/hwmon/macsmc-hwmon.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/hwmon/macsmc-hwmon.c b/drivers/hwmon/macsmc-hwmon.c index 40d25c81b443..1500ec2cc9f8 100644 --- a/drivers/hwmon/macsmc-hwmon.c +++ b/drivers/hwmon/macsmc-hwmon.c @@ -22,6 +22,7 @@ #include <linux/bitfield.h> #include <linux/hwmon.h> +#include <linux/math64.h> #include <linux/mfd/macsmc.h> #include <linux/module.h> #include <linux/of.h> @@ -130,7 +131,7 @@ static int macsmc_hwmon_read_ioft_scaled(struct apple_smc *smc, smc_key key, if (ret < 0) return ret; - *p = mult_frac(val, scale, 65536); + *p = mul_u64_u32_div(val, scale, 65536); return 0; } @@ -140,7 +141,7 @@ static int macsmc_hwmon_read_ioft_scaled(struct apple_smc *smc, smc_key key, * them. */ static int macsmc_hwmon_read_f32_scaled(struct apple_smc *smc, smc_key key, - int *p, int scale) + long *p, int scale) { u32 fval; u64 val; @@ -162,21 +163,21 @@ static int macsmc_hwmon_read_f32_scaled(struct apple_smc *smc, smc_key key, val = 0; else if (exp < 0) val >>= -exp; - else if (exp != 0 && (val & ~((1UL << (64 - exp)) - 1))) /* overflow */ + else if (exp != 0 && (val & ~((1ULL << (64 - exp)) - 1))) /* overflow */ val = U64_MAX; else val <<= exp; if (fval & FLT_SIGN_MASK) { - if (val > (-(s64)INT_MIN)) - *p = INT_MIN; + if (val > (u64)LONG_MAX + 1) + *p = LONG_MIN; else - *p = -val; + *p = -(long)val; } else { - if (val > INT_MAX) - *p = INT_MAX; + if (val > (u64)LONG_MAX) + *p = LONG_MAX; else - *p = val; + *p = (long)val; } return 0; @@ -195,7 +196,7 @@ static int macsmc_hwmon_read_key(struct apple_smc *smc, switch (sensor->info.type_code) { /* 32-bit IEEE 754 float */ case __SMC_KEY('f', 'l', 't', ' '): { - u32 flt_ = 0; + long flt_ = 0; ret = macsmc_hwmon_read_f32_scaled(smc, sensor->macsmc_key, &flt_, scale); @@ -214,7 +215,10 @@ static int macsmc_hwmon_read_key(struct apple_smc *smc, if (ret) return ret; - *val = (long)ioft; + if (ioft > LONG_MAX) + *val = LONG_MAX; + else + *val = (long)ioft; break; } default: @@ -224,7 +228,7 @@ static int macsmc_hwmon_read_key(struct apple_smc *smc, return 0; } -static int macsmc_hwmon_write_f32(struct apple_smc *smc, smc_key key, int value) +static int macsmc_hwmon_write_f32(struct apple_smc *smc, smc_key key, long value) { u64 val; u32 fval = 0; -- 2.45.2 ^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-02-20 10:25 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-01-29 17:51 [PATCH 0/2] hwmon: (macsmc) Various fixes hwmon driver Guenter Roeck 2026-01-29 17:51 ` [PATCH 1/2] hwmon: (macsmc) Fix regressions in Apple Silicon SMC " Guenter Roeck 2026-02-03 8:06 ` Nathan Chancellor 2026-02-12 6:18 ` Guenter Roeck 2026-02-20 10:20 ` James Calligeros 2026-01-29 17:51 ` [PATCH 2/2] hwmon: (macsmc) Fix overflows, underflows, and sign extension Guenter Roeck
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox