[PATCH 2/6] iio: adc: versal-sysmon: validate temperature hysteresis
Amit Kumar Mahapatra
amit.kumar-mahapatra at amd.com
Mon Nov 2 04:21:08 PST 2026
The hysteresis written through sysfs is only checked for being negative.
A large value makes upper_mc - hysteresis in sysmon_update_temp_lower()
overflow before it is clamped. Reject values above the full Q8.7 span of
511992 millicelsius, and name the Q8.7 temperature limits so that the
span and the existing range checks share one definition.
The cached hysteresis is seeded at probe from the threshold registers
without checking that the lower threshold is not above the upper one.
Treat that case as zero hysteresis, as negative values are rejected on
the write path.
Fixes: c7f7eb10638f ("iio: adc: versal-sysmon: add threshold event support")
Signed-off-by: Amit Kumar Mahapatra <amit.kumar-mahapatra at amd.com>
---
drivers/iio/adc/versal-sysmon-core.c | 10 +++++-----
drivers/iio/adc/versal-sysmon.h | 4 ++++
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/iio/adc/versal-sysmon-core.c b/drivers/iio/adc/versal-sysmon-core.c
index 6b9a58e19831..6595d07038c1 100644
--- a/drivers/iio/adc/versal-sysmon-core.c
+++ b/drivers/iio/adc/versal-sysmon-core.c
@@ -352,7 +352,8 @@ static int sysmon_update_temp_lower(struct sysmon *sysmon)
return ret;
sysmon_q8p7_to_millicelsius(upper_reg, &upper_mc);
- lower_mc = clamp(upper_mc - sysmon->temp_hysteresis, -256000, 255992);
+ lower_mc = clamp(upper_mc - sysmon->temp_hysteresis,
+ SYSMON_TEMP_MIN_MC, SYSMON_TEMP_MAX_MC);
sysmon_millicelsius_to_q8p7(&raw_val, lower_mc);
return regmap_write(sysmon->regmap, SYSMON_TEMP_TH_LOW, raw_val);
@@ -429,8 +430,7 @@ static int sysmon_write_event_value(struct iio_dev *indio_dev,
case IIO_TEMP:
switch (info) {
case IIO_EV_INFO_VALUE:
- /* Q8.7 signed range: -256000 to +255992 mC */
- if (val < -256000 || val > 255992)
+ if (val < SYSMON_TEMP_MIN_MC || val > SYSMON_TEMP_MAX_MC)
return -EINVAL;
sysmon_millicelsius_to_q8p7(&raw_val, val);
@@ -443,7 +443,7 @@ static int sysmon_write_event_value(struct iio_dev *indio_dev,
return sysmon_update_temp_lower(sysmon);
case IIO_EV_INFO_HYSTERESIS:
- if (val < 0)
+ if (val < 0 || val > SYSMON_TEMP_MAX_MC - SYSMON_TEMP_MIN_MC)
return -EINVAL;
sysmon->temp_hysteresis = val;
@@ -838,7 +838,7 @@ static int sysmon_init_hysteresis(struct sysmon *sysmon, int *hysteresis)
sysmon_q8p7_to_millicelsius(upper_reg, &upper_mc);
sysmon_q8p7_to_millicelsius(lower_reg, &lower_mc);
- *hysteresis = upper_mc - lower_mc;
+ *hysteresis = max(upper_mc - lower_mc, 0);
return 0;
}
diff --git a/drivers/iio/adc/versal-sysmon.h b/drivers/iio/adc/versal-sysmon.h
index 701ef9b56263..a1ac3289719c 100644
--- a/drivers/iio/adc/versal-sysmon.h
+++ b/drivers/iio/adc/versal-sysmon.h
@@ -75,6 +75,10 @@ struct regmap;
#define SYSMON_FRACTIONAL_SHIFT 7U
#define SYSMON_SUPPLY_MANTISSA_BITS 16
+/* Q8.7 signed temperature range in millicelsius */
+#define SYSMON_TEMP_MIN_MC -256000
+#define SYSMON_TEMP_MAX_MC 255992
+
/* Bits per alarm register */
#define SYSMON_ALARM_BITS_PER_REG 32
--
2.34.1
More information about the linux-arm-kernel
mailing list