Merge tag 'char-misc-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull char/misc/IIO/etc driver updates from Greg KH:
 "Here is the big set of char, misc, iio, counter, fpga, and other small
  driver subsystems for 7.3-rc1.

  Overall, due to some driver removals we only added a bit more code
  than removed, which was a nice change. Highlights in this merge
  request are:

   - Loads of IIO driver updates and additions

   - binder driver updates (more on that below...)

   - Removal of the SGI XP and GRU drivers as they are not used anymore
     and turn out to be pretty insecure overall

   - Removal of the obsolete ibmasm driver as it's not being used
     anymore

   - Coresight driver updates and additions

   - Mei driver udpates

   - Counter driver updates

   - FPGA driver updates

   - ICC driver updates

   - lots and lots of other tiny driver updates to resolve reported
     issues

  All of these have been in linux-next for a while"

* tag 'char-misc-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (513 commits)
  iio: chemical: atlas-sensor: use iio_trigger_poll_nested() to fix remove UAF
  iio: adc: pac1921: fix wrong channel used in trigger handler read
  iio: light: gp2ap002: re-enable irq if runtime suspend fails
  iio: light: gp2ap002: Fix unbalanced runtime PM on repeated event writes
  iio: light: apds9306: fix PM reference leak in apds9306_read_data()
  iio: gyro: mpu3050: fix sign of raw angular velocity readings
  iio: srf04: fix pm_runtime handling on probe error path
  iio: adc: ad4080: configure backend data size
  iio: adc: adi-axi-adc: add data size support for AD408X backend
  iio: chemical: atlas-sensor: fix PM reference leak in buffer postenable
  iio: dac: ad5446: fix OF module device table
  iio: light: opt4001: Fix reversed GENMASK() arguments in fault count mask
  iio: light: opt4001: Reject integration times with a non-zero seconds part
  iio: light: opt4001: Fix incompatible pointer type passed to div_u64_rem()
  iio: light: opt4001: Fix power down clearing bits of the wrong register
  iio: light: opt4060: Fix incorrect register name in threshold read error message
  iio: light: opt4060: Fix pointer type passed to div_u64_rem()
  iio: light: opt4060: Reject integration times with a non-zero seconds part
  iio: light: ltrf216a: fix runtime PM reference leak in error path
  iio: pressure: dps310: fix NULL pointer dereference on ACPI probe
  ...
This commit is contained in:
Linus Torvalds
2026-08-25 09:38:50 -07:00
758 changed files with 28139 additions and 21301 deletions
+107 -8
View File
@@ -17,6 +17,7 @@
#include <linux/export.h>
#include <linux/kstrtox.h>
#include <linux/math64.h>
#include <linux/overflow.h>
#include <linux/types.h>
#include <linux/uaccess.h>
@@ -45,6 +46,7 @@ const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
* @base: Radix
* @p: Where to store result
* @max_chars: Maximum amount of characters to convert
* @init: Initial value of the multiply-accumulate result
*
* Convert non-negative integer string representation in explicitly given
* radix to an integer. If overflow occurs, value at @p is set to ULLONG_MAX.
@@ -56,12 +58,12 @@ const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
*/
noinline
unsigned int _parse_integer_limit(const char *s, unsigned int base, unsigned long long *p,
size_t max_chars)
size_t max_chars, unsigned long long init)
{
unsigned int rv, overflow = 0;
unsigned long long res;
res = 0;
res = init;
for (rv = 0; rv < max_chars; rv++, s++) {
unsigned int c = *s;
unsigned int lc = _tolower(c);
@@ -94,12 +96,6 @@ unsigned int _parse_integer_limit(const char *s, unsigned int base, unsigned lon
return rv | overflow;
}
noinline
unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p)
{
return _parse_integer_limit(s, base, p, INT_MAX);
}
static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
{
unsigned long long _res;
@@ -399,6 +395,109 @@ int kstrtobool(const char *s, bool *res)
}
EXPORT_SYMBOL(kstrtobool);
static int _kstrtoudec64(const char *s, unsigned int scale, u64 *res)
{
unsigned int rv_int, rv_frac;
u64 _res = 0;
rv_int = _parse_integer(s, 10, &_res);
if (rv_int & KSTRTOX_OVERFLOW)
return -ERANGE;
s += rv_int;
if (*s == '.')
s++; /* skip decimal point */
rv_frac = _parse_integer(s, 10, &_res, scale, _res);
if (rv_frac & KSTRTOX_OVERFLOW)
return -ERANGE;
s += rv_frac;
/*
* Check input beyond rv_int and rv_frac to cover cases like ".5" with
* scale 0, which is considered a valid input, being parsed as 0.
*/
if (!rv_int && !rv_frac && !isdigit(*s))
return -EINVAL;
while (isdigit(*s)) /* truncate digits */
s++;
if (*s == '\n')
s++;
if (*s)
return -EINVAL;
if (_res && ((scale - rv_frac) > 19 /* log10(2^64) = 19.26 */ ||
check_mul_overflow(_res, int_pow(10, scale - rv_frac), &_res)))
return -ERANGE;
*res = _res;
return 0;
}
/**
* kstrtoudec64() - Convert a string to an unsigned 64-bit scaled decimal value.
* @s: The start of the string. The string must be null-terminated, and may also
* include a single newline before its terminating null. The first character
* may also be a plus sign, but not a minus sign.
* @scale: The number of digits to the right of the decimal point.
* @res: Where to write the result of the conversion on success.
*
* For example, a scale of 3 with input "123.45" results in 123450. Note that
* trailing zeros in the fractional part input to match the scale are not
* required. Also, digits beyond the specified scale are ignored.
*
* Return: 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
*/
noinline
int kstrtoudec64(const char *s, unsigned int scale, u64 *res)
{
if (s[0] == '+')
s++;
return _kstrtoudec64(s, scale, res);
}
EXPORT_SYMBOL(kstrtoudec64);
/**
* kstrtodec64() - Convert a string to a signed 64-bit scaled decimal value.
* @s: The start of the string. The string must be null-terminated, and may also
* include a single newline before its terminating null. The first character
* may also be a plus sign or a minus sign.
* @scale: The number of digits to the right of the decimal point.
* @res: Where to write the result of the conversion on success.
*
* For example, a scale of 4 with input "-3.141592" results in -31415. Note
* that digits beyond the specified scale are ignored. Also, trailing zeros in
* the fractional part input to match the scale are not required.
*
* Return: 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
*/
noinline
int kstrtodec64(const char *s, unsigned int scale, s64 *res)
{
u64 tmp;
int rv;
if (s[0] == '-') {
rv = _kstrtoudec64(s + 1, scale, &tmp);
if (rv < 0)
return rv;
if ((s64)-tmp > 0)
return -ERANGE;
*res = -tmp;
} else {
rv = kstrtoudec64(s, scale, &tmp);
if (rv < 0)
return rv;
if ((s64)tmp < 0)
return -ERANGE;
*res = tmp;
}
return 0;
}
EXPORT_SYMBOL(kstrtodec64);
/*
* Since "base" would be a nonsense argument, this open-codes the
* _from_user helper instead of using the helper macro below.
+15 -2
View File
@@ -2,10 +2,23 @@
#ifndef _LIB_KSTRTOX_H
#define _LIB_KSTRTOX_H
#include <linux/args.h>
#define KSTRTOX_OVERFLOW (1U << 31)
const char *_parse_integer_fixup_radix(const char *s, unsigned int *base);
unsigned int _parse_integer_limit(const char *s, unsigned int base, unsigned long long *res,
size_t max_chars);
unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *res);
size_t max_chars, unsigned long long init);
#define _parse_integer0(s, base, res, ...) \
_parse_integer_limit(s, base, res, INT_MAX, 0)
#define _parse_integer1(s, base, res, max_chars, ...) \
_parse_integer_limit(s, base, res, max_chars, 0)
#define _parse_integer2(s, base, res, max_chars, init, ...) \
_parse_integer_limit(s, base, res, max_chars, init)
#define _parse_integer(s, base, res, ...) \
CONCATENATE(_parse_integer, COUNT_ARGS(__VA_ARGS__))(s, base, res, __VA_ARGS__)
#endif
+15
View File
@@ -158,6 +158,21 @@ u64 div64_u64(u64 dividend, u64 divisor)
EXPORT_SYMBOL(div64_u64);
#endif
#ifndef div64_s64_rem
s64 div64_s64_rem(s64 dividend, s64 divisor, s64 *remainder)
{
s64 quot, t, rem;
quot = div64_u64_rem(abs(dividend), abs(divisor), (u64 *)&rem);
t = dividend >> 63;
*remainder = (rem ^ t) - t;
t = (dividend ^ divisor) >> 63;
return (quot ^ t) - t;
}
EXPORT_SYMBOL(div64_s64_rem);
#endif
#ifndef div64_s64
s64 div64_s64(s64 dividend, s64 divisor)
{
+1
View File
@@ -157,6 +157,7 @@ static void __exit test_exit(void)
#define __div64_32 __div64_32
#define div_s64_rem div_s64_rem
#define div64_u64_rem div64_u64_rem
#define div64_s64_rem div64_s64_rem
#define div64_u64 div64_u64
#define div64_s64 div64_s64
#define iter_div_u64_rem iter_div_u64_rem
+182
View File
@@ -709,6 +709,182 @@ static void __init test_kstrtos8_fail(void)
TEST_FAIL(kstrtos8, s8, "%hhd", test_s8_fail);
}
static void __init test_kstrtoudec64_ok(void)
{
DECLARE_TEST_OK(u64, struct test_udec64);
static DEFINE_TEST_OK(struct test_udec64, test_udec64_ok) = {
/* basic: integer.fraction, exact digits */
{"0.0", 1, 0},
{"1.5", 1, 15},
{"1.234", 3, 1234},
{"42.0", 1, 420},
/* zero */
{"0.0", 1, 0},
{"0.000", 3, 0},
/* integer only */
{"0", 1, 0},
{"42", 3, 42000},
{"123.", 2, 12300},
{"1", 1, 10},
/* fractional only (leading dot) */
{".5", 1, 5},
{".5", 0, 0},
{".123", 3, 123},
{".001", 3, 1},
/* zero padding: fewer fractional digits than scale */
{"1.2", 3, 1200},
{"1.2", 6, 1200000},
{"0.01", 3, 10},
{"0.1", 9, 100000000ULL},
{"0.01", 9, 10000000},
/* truncation: more fractional digits than scale */
{"1.23456", 3, 1234},
{"3.1415926535", 6, 3141592},
{"0.999999999", 3, 999},
{"1.99", 1, 19},
{"1.234", 0, 1},
/* trailing newline */
{"1.5\n", 1, 15},
{"42\n", 3, 42000},
/* plus sign */
{"+1.5", 1, 15},
{"+.5", 1, 5},
/* scale progression */
{"1.", 0, 1},
{"1.0", 1, 10},
{"1.00", 2, 100},
{"1.000", 3, 1000},
{"1.000000", 6, 1000000},
{"1.000000000", 9, 1000000000ULL},
/* max limit check */
{"18446744073.709551615", 9, ULLONG_MAX},
{"18446744073709.551615", 6, ULLONG_MAX},
{"0.18446744073709551615", 20, ULLONG_MAX},
/* scale > 19: representable when integer part is small */
{"0.00000000000000000001", 20, 1},
{"0.1", 20, 10000000000000000000ULL},
{"0.00000000000000000000001", 23, 1},
/* truncation with scale > 19 */
{"0.0000000000000000000012345", 23, 123},
/* truncation with many excess digits */
{"0.00000000000000000000000000000000423", 34, 42},
{"1.99999999999999999999999999999999999", 3, 1999},
};
TEST_OK(kstrtoudec64, u64, "%llu", test_udec64_ok);
}
static void __init test_kstrtoudec64_fail(void)
{
static DEFINE_TEST_FAIL(test_udec64_fail) = {
/* empty / whitespace */
{"", 3},
{"\n", 3},
/* minus sign (unsigned) */
{"-1.5", 1},
{"-0.5", 1},
/* only a decimal point */
{".", 3},
{".", 0},
/* only a sign */
{"+", 3},
/* non-digit characters */
{"abc", 3},
{"1.2x", 3},
/* leading/trailing space */
{" 1.5", 1},
{"1.5 ", 1},
/* overflow */
{"18446744073710.551615", 6},
{"99999999999999999999", 1},
/* overflow with scale > 19 */
{"1.0", 21},
{"0.2", 20},
{"0.18446744073709551616", 20},
{"1", 20},
};
TEST_FAIL(kstrtoudec64, u64, "%llu", test_udec64_fail);
}
static void __init test_kstrtodec64_ok(void)
{
DECLARE_TEST_OK(s64, struct test_dec64);
static DEFINE_TEST_OK(struct test_dec64, test_dec64_ok) = {
/* basic positive */
{"0.0", 1, 0},
{"1.5", 1, 15},
{"1.234", 3, 1234},
/* basic negative */
{"-1.5", 1, -15},
{"-1.234", 3, -1234},
{"-0.5", 1, -5},
{"-0.001", 3, -1},
/* zero (signed) */
{"-0", 1, 0},
{"-0.0", 1, 0},
{"0.000", 3, 0},
/* integer only */
{"42", 3, 42000},
{"-42", 3, -42000},
/* fractional only */
{".5", 1, 5},
{"-.5", 1, -5},
/* zero padding */
{"1.2", 3, 1200},
{"-1.2", 3, -1200},
{"0.01", 3, 10},
{"-0.01", 3, -10},
/* truncation */
{"1.23456", 3, 1234},
{"-1.23456", 3, -1234},
{"0.999999999", 3, 999},
{"-0.999999999", 3, -999},
/* trailing newline */
{"1.5\n", 1, 15},
{"-1.5\n", 1, -15},
/* plus sign */
{"+1.5", 1, 15},
/* limits */
{"9223372036.854775807", 9, LLONG_MAX},
{"-9223372036.854775808", 9, LLONG_MIN},
/* scale > 19 */
{"0.0", 20, 0},
{"-0.0", 20, 0},
{"0.00000000000000000001", 20, 1},
{"-0.00000000000000000001", 20, -1},
{"0.009223372036854775807", 21, LLONG_MAX},
{"-0.009223372036854775808", 21, LLONG_MIN},
};
TEST_OK(kstrtodec64, s64, "%lld", test_dec64_ok);
}
static void __init test_kstrtodec64_fail(void)
{
static DEFINE_TEST_FAIL(test_dec64_fail) = {
/* empty / whitespace */
{"", 3},
{"\n", 3},
/* no digits after dot */
{".", 3},
{"-.", 3},
/* no digits at all */
{"+", 3},
{"-", 3},
/* non-digit characters */
{"abc", 3},
{"-1.2x", 3},
/* signed overflow */
{"9223372036.854775808", 9},
{"-9223372036.854775809", 9},
{"99999999999999999999", 1},
/* signed overflow with scale > 19 */
{"0.1", 20},
{"-0.1", 20},
{"0.09223372036854775808", 20},
{"-0.09223372036854775809", 20},
};
TEST_FAIL(kstrtodec64, s64, "%lld", test_dec64_fail);
}
static int __init test_kstrtox_init(void)
{
test_kstrtoull_ok();
@@ -735,6 +911,12 @@ static int __init test_kstrtox_init(void)
test_kstrtou8_fail();
test_kstrtos8_ok();
test_kstrtos8_fail();
test_kstrtoudec64_ok();
test_kstrtoudec64_fail();
test_kstrtodec64_ok();
test_kstrtodec64_fail();
return -EINVAL;
}
module_init(test_kstrtox_init);
+1 -1
View File
@@ -86,7 +86,7 @@ static unsigned long long simple_strntoull(const char *startp, char **endp, unsi
cp = _parse_integer_fixup_radix(startp, &base);
prefix_chars = cp - startp;
if (prefix_chars < max_chars) {
rv = _parse_integer_limit(cp, base, &result, max_chars - prefix_chars);
rv = _parse_integer(cp, base, &result, max_chars - prefix_chars);
/* FIXME */
cp += (rv & ~KSTRTOX_OVERFLOW);
} else {