From: Greg Kroah-Hartman Date: Fri, 2 Feb 2024 01:39:33 +0000 (-0800) Subject: 6.6-stable patches X-Git-Tag: v6.1.77~59 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d1fc4f59721b79377e6c8b683f1f556bfa56319c;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: minmax-add-umin-a-b-and-umax-a-b.patch minmax-allow-comparisons-of-int-against-unsigned-char-short.patch minmax-allow-min-max-clamp-if-the-arguments-have-the-same-signedness.patch minmax-deduplicate-__unconst_integer_typeof.patch minmax-fix-header-inclusions.patch minmax-fix-indentation-of-__cmp_once-and-__clamp_once.patch minmax-relax-check-to-allow-comparison-between-unsigned-arguments-and-signed-constants.patch --- diff --git a/queue-6.6/minmax-add-umin-a-b-and-umax-a-b.patch b/queue-6.6/minmax-add-umin-a-b-and-umax-a-b.patch new file mode 100644 index 00000000000..7ebb638ef1f --- /dev/null +++ b/queue-6.6/minmax-add-umin-a-b-and-umax-a-b.patch @@ -0,0 +1,137 @@ +From 80fcac55385ccb710d33a20dc1caaef29bd5a921 Mon Sep 17 00:00:00 2001 +From: David Laight +Date: Mon, 18 Sep 2023 08:16:30 +0000 +Subject: minmax: add umin(a, b) and umax(a, b) + +From: David Laight + +commit 80fcac55385ccb710d33a20dc1caaef29bd5a921 upstream. + +Patch series "minmax: Relax type checks in min() and max()", v4. + +The min() (etc) functions in minmax.h require that the arguments have +exactly the same types. + +However when the type check fails, rather than look at the types and fix +the type of a variable/constant, everyone seems to jump on min_t(). In +reality min_t() ought to be rare - when something unusual is being done, +not normality. + +The orginal min() (added in 2.4.9) replaced several inline functions and +included the type - so matched the implicit casting of the function call. +This was renamed min_t() in 2.4.10 and the current min() added. There is +no actual indication that the conversion of negatve values to large +unsigned values has ever been an actual problem. + +A quick grep shows 5734 min() and 4597 min_t(). Having the casts on +almost half of the calls shows that something is clearly wrong. + +If the wrong type is picked (and it is far too easy to pick the type of +the result instead of the larger input) then significant bits can get +discarded. + +Pretty much the worst example is in the derived clamp_val(), consider: + unsigned char x = 200u; + y = clamp_val(x, 10u, 300u); + +I also suspect that many of the min_t(u16, ...) are actually wrong. For +example copy_data() in printk_ringbuffer.c contains: + + data_size = min_t(u16, buf_size, len); + +Here buf_size is 'unsigned int' and len 'u16', pass a 64k buffer (can you +prove that doesn't happen?) and no data is returned. Apparantly it did - +and has since been fixed. + +The only reason that most of the min_t() are 'fine' is that pretty much +all the values in the kernel are between 0 and INT_MAX. + +Patch 1 adds umin(), this uses integer promotions to convert both +arguments to 'unsigned long long'. It can be used to compare a signed +type that is known to contain a non-negative value with an unsigned type. +The compiler typically optimises it all away. Added first so that it can +be referred to in patch 2. + +Patch 2 replaces the 'same type' check with a 'same signedness' one. This +makes min(unsigned_int_var, sizeof()) be ok. The error message is also +improved and will contain the expanded form of both arguments (useful for +seeing how constants are defined). + +Patch 3 just fixes some whitespace. + +Patch 4 allows comparisons of 'unsigned char' and 'unsigned short' to +signed types. The integer promotion rules convert them both to 'signed +int' prior to the comparison so they can never cause a negative value be +converted to a large positive one. + +Patch 5 (rewritted for v4) allows comparisons of unsigned values against +non-negative constant integer expressions. This makes +min(unsigned_int_var, 4) be ok. + +The only common case that is still errored is the comparison of signed +values against unsigned constant integer expressions below __INT_MAX__. +Typcally min(int_val, sizeof (foo)), the real fix for this is casting the +constant: min(int_var, (int)sizeof (foo)). + +With all the patches applied pretty much all the min_t() could be replaced +by min(), and most of the rest by umin(). However they all need careful +inspection due to code like: + + sz = min_t(unsigned char, sz - 1, LIM - 1) + 1; + +which converts 0 to LIM. + + +This patch (of 6): + +umin() and umax() can be used when min()/max() errors a signed v unsigned +compare when the signed value is known to be non-negative. + +Unlike min_t(some_unsigned_type, a, b) umin() will never mask off high +bits if an inappropriate type is selected. + +The '+ 0u + 0ul + 0ull' may look strange. +The '+ 0u' is needed for 'signed int' on 64bit systems. +The '+ 0ul' is needed for 'signed long' on 32bit systems. +The '+ 0ull' is needed for 'signed long long'. + +Link: https://lkml.kernel.org/r/b97faef60ad24922b530241c5d7c933c@AcuMS.aculab.com +Link: https://lkml.kernel.org/r/41d93ca827a248698ec64bf57e0c05a5@AcuMS.aculab.com +Signed-off-by: David Laight +Cc: Andy Shevchenko +Cc: Christoph Hellwig +Cc: Jason A. Donenfeld +Cc: Linus Torvalds +Cc: Matthew Wilcox (Oracle) +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -77,6 +77,23 @@ + #define max(x, y) __careful_cmp(x, y, >) + + /** ++ * umin - return minimum of two non-negative values ++ * Signed types are zero extended to match a larger unsigned type. ++ * @x: first value ++ * @y: second value ++ */ ++#define umin(x, y) \ ++ __careful_cmp((x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull, <) ++ ++/** ++ * umax - return maximum of two non-negative values ++ * @x: first value ++ * @y: second value ++ */ ++#define umax(x, y) \ ++ __careful_cmp((x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull, >) ++ ++/** + * min3 - return minimum of three values + * @x: first value + * @y: second value diff --git a/queue-6.6/minmax-allow-comparisons-of-int-against-unsigned-char-short.patch b/queue-6.6/minmax-allow-comparisons-of-int-against-unsigned-char-short.patch new file mode 100644 index 00000000000..12200876bc0 --- /dev/null +++ b/queue-6.6/minmax-allow-comparisons-of-int-against-unsigned-char-short.patch @@ -0,0 +1,39 @@ +From 4ead534fba42fc4fd41163297528d2aa731cd121 Mon Sep 17 00:00:00 2001 +From: David Laight +Date: Mon, 18 Sep 2023 08:18:40 +0000 +Subject: minmax: allow comparisons of 'int' against 'unsigned char/short' + +From: David Laight + +commit 4ead534fba42fc4fd41163297528d2aa731cd121 upstream. + +Since 'unsigned char/short' get promoted to 'signed int' it is safe to +compare them against an 'int' value. + +Link: https://lkml.kernel.org/r/8732ef5f809c47c28a7be47c938b28d4@AcuMS.aculab.com +Signed-off-by: David Laight +Cc: Andy Shevchenko +Cc: Christoph Hellwig +Cc: Jason A. Donenfeld +Cc: Linus Torvalds +Cc: Matthew Wilcox (Oracle) +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -26,8 +26,9 @@ + __builtin_choose_expr(__is_constexpr(is_signed_type(typeof(x))), \ + is_signed_type(typeof(x)), 0) + +-#define __types_ok(x, y) \ +- (__is_signed(x) == __is_signed(y)) ++#define __types_ok(x, y) \ ++ (__is_signed(x) == __is_signed(y) || \ ++ __is_signed((x) + 0) == __is_signed((y) + 0)) + + #define __cmp_op_min < + #define __cmp_op_max > diff --git a/queue-6.6/minmax-allow-min-max-clamp-if-the-arguments-have-the-same-signedness.patch b/queue-6.6/minmax-allow-min-max-clamp-if-the-arguments-have-the-same-signedness.patch new file mode 100644 index 00000000000..34a79086ba5 --- /dev/null +++ b/queue-6.6/minmax-allow-min-max-clamp-if-the-arguments-have-the-same-signedness.patch @@ -0,0 +1,170 @@ +From d03eba99f5bf7cbc6e2fdde3b6fa36954ad58e09 Mon Sep 17 00:00:00 2001 +From: David Laight +Date: Mon, 18 Sep 2023 08:17:15 +0000 +Subject: minmax: allow min()/max()/clamp() if the arguments have the same signedness. + +From: David Laight + +commit d03eba99f5bf7cbc6e2fdde3b6fa36954ad58e09 upstream. + +The type-check in min()/max() is there to stop unexpected results if a +negative value gets converted to a large unsigned value. However it also +rejects 'unsigned int' v 'unsigned long' compares which are common and +never problematc. + +Replace the 'same type' check with a 'same signedness' check. + +The new test isn't itself a compile time error, so use static_assert() to +report the error and give a meaningful error message. + +Due to the way builtin_choose_expr() works detecting the error in the +'non-constant' side (where static_assert() can be used) also detects +errors when the arguments are constant. + +Link: https://lkml.kernel.org/r/fe7e6c542e094bfca655abcd323c1c98@AcuMS.aculab.com +Signed-off-by: David Laight +Cc: Andy Shevchenko +Cc: Christoph Hellwig +Cc: Jason A. Donenfeld +Cc: Linus Torvalds +Cc: Matthew Wilcox (Oracle) +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 62 ++++++++++++++++++++++++++----------------------- + 1 file changed, 33 insertions(+), 29 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -12,9 +12,8 @@ + * + * - avoid multiple evaluations of the arguments (so side-effects like + * "x++" happen only once) when non-constant. +- * - perform strict type-checking (to generate warnings instead of +- * nasty runtime surprises). See the "unnecessary" pointer comparison +- * in __typecheck(). ++ * - perform signed v unsigned type-checking (to generate compile ++ * errors instead of nasty runtime surprises). + * - retain result as a constant expressions when called with only + * constant expressions (to avoid tripping VLA warnings in stack + * allocation usage). +@@ -22,23 +21,30 @@ + #define __typecheck(x, y) \ + (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1))) + +-#define __no_side_effects(x, y) \ +- (__is_constexpr(x) && __is_constexpr(y)) ++/* is_signed_type() isn't a constexpr for pointer types */ ++#define __is_signed(x) \ ++ __builtin_choose_expr(__is_constexpr(is_signed_type(typeof(x))), \ ++ is_signed_type(typeof(x)), 0) + +-#define __safe_cmp(x, y) \ +- (__typecheck(x, y) && __no_side_effects(x, y)) ++#define __types_ok(x, y) \ ++ (__is_signed(x) == __is_signed(y)) + +-#define __cmp(x, y, op) ((x) op (y) ? (x) : (y)) ++#define __cmp_op_min < ++#define __cmp_op_max > + +-#define __cmp_once(x, y, unique_x, unique_y, op) ({ \ ++#define __cmp(op, x, y) ((x) __cmp_op_##op (y) ? (x) : (y)) ++ ++#define __cmp_once(op, x, y, unique_x, unique_y) ({ \ + typeof(x) unique_x = (x); \ + typeof(y) unique_y = (y); \ +- __cmp(unique_x, unique_y, op); }) +- +-#define __careful_cmp(x, y, op) \ +- __builtin_choose_expr(__safe_cmp(x, y), \ +- __cmp(x, y, op), \ +- __cmp_once(x, y, __UNIQUE_ID(__x), __UNIQUE_ID(__y), op)) ++ static_assert(__types_ok(x, y), \ ++ #op "(" #x ", " #y ") signedness error, fix types or consider u" #op "() before " #op "_t()"); \ ++ __cmp(op, unique_x, unique_y); }) ++ ++#define __careful_cmp(op, x, y) \ ++ __builtin_choose_expr(__is_constexpr((x) - (y)), \ ++ __cmp(op, x, y), \ ++ __cmp_once(op, x, y, __UNIQUE_ID(__x), __UNIQUE_ID(__y))) + + #define __clamp(val, lo, hi) \ + ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val))) +@@ -47,17 +53,15 @@ + typeof(val) unique_val = (val); \ + typeof(lo) unique_lo = (lo); \ + typeof(hi) unique_hi = (hi); \ ++ static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \ ++ (lo) <= (hi), true), \ ++ "clamp() low limit " #lo " greater than high limit " #hi); \ ++ static_assert(__types_ok(val, lo), "clamp() 'lo' signedness error"); \ ++ static_assert(__types_ok(val, hi), "clamp() 'hi' signedness error"); \ + __clamp(unique_val, unique_lo, unique_hi); }) + +-#define __clamp_input_check(lo, hi) \ +- (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \ +- __is_constexpr((lo) > (hi)), (lo) > (hi), false))) +- + #define __careful_clamp(val, lo, hi) ({ \ +- __clamp_input_check(lo, hi) + \ +- __builtin_choose_expr(__typecheck(val, lo) && __typecheck(val, hi) && \ +- __typecheck(hi, lo) && __is_constexpr(val) && \ +- __is_constexpr(lo) && __is_constexpr(hi), \ ++ __builtin_choose_expr(__is_constexpr((val) - (lo) + (hi)), \ + __clamp(val, lo, hi), \ + __clamp_once(val, lo, hi, __UNIQUE_ID(__val), \ + __UNIQUE_ID(__lo), __UNIQUE_ID(__hi))); }) +@@ -67,14 +71,14 @@ + * @x: first value + * @y: second value + */ +-#define min(x, y) __careful_cmp(x, y, <) ++#define min(x, y) __careful_cmp(min, x, y) + + /** + * max - return maximum of two values of the same or compatible types + * @x: first value + * @y: second value + */ +-#define max(x, y) __careful_cmp(x, y, >) ++#define max(x, y) __careful_cmp(max, x, y) + + /** + * umin - return minimum of two non-negative values +@@ -83,7 +87,7 @@ + * @y: second value + */ + #define umin(x, y) \ +- __careful_cmp((x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull, <) ++ __careful_cmp(min, (x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull) + + /** + * umax - return maximum of two non-negative values +@@ -91,7 +95,7 @@ + * @y: second value + */ + #define umax(x, y) \ +- __careful_cmp((x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull, >) ++ __careful_cmp(max, (x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull) + + /** + * min3 - return minimum of three values +@@ -143,7 +147,7 @@ + * @x: first value + * @y: second value + */ +-#define min_t(type, x, y) __careful_cmp((type)(x), (type)(y), <) ++#define min_t(type, x, y) __careful_cmp(min, (type)(x), (type)(y)) + + /** + * max_t - return maximum of two values, using the specified type +@@ -151,7 +155,7 @@ + * @x: first value + * @y: second value + */ +-#define max_t(type, x, y) __careful_cmp((type)(x), (type)(y), >) ++#define max_t(type, x, y) __careful_cmp(max, (type)(x), (type)(y)) + + /* + * Do not check the array parameter using __must_be_array(). diff --git a/queue-6.6/minmax-deduplicate-__unconst_integer_typeof.patch b/queue-6.6/minmax-deduplicate-__unconst_integer_typeof.patch new file mode 100644 index 00000000000..0ac777ead6c --- /dev/null +++ b/queue-6.6/minmax-deduplicate-__unconst_integer_typeof.patch @@ -0,0 +1,76 @@ +From 5e57418a2031cd5e1863efdf3d7447a16a368172 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Mon, 11 Sep 2023 18:49:13 +0300 +Subject: minmax: deduplicate __unconst_integer_typeof() + +From: Andy Shevchenko + +commit 5e57418a2031cd5e1863efdf3d7447a16a368172 upstream. + +It appears that compiler_types.h already have an implementation of the +__unconst_integer_typeof() called __unqual_scalar_typeof(). Use it +instead of the copy. + +Link: https://lkml.kernel.org/r/20230911154913.4176033-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Andy Shevchenko +Acked-by: Herve Codina +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 26 +++----------------------- + 1 file changed, 3 insertions(+), 23 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -2,6 +2,7 @@ + #ifndef _LINUX_MINMAX_H + #define _LINUX_MINMAX_H + ++#include + #include + #include + +@@ -135,27 +136,6 @@ + #define max_t(type, x, y) __careful_cmp((type)(x), (type)(y), >) + + /* +- * Remove a const qualifier from integer types +- * _Generic(foo, type-name: association, ..., default: association) performs a +- * comparison against the foo type (not the qualified type). +- * Do not use the const keyword in the type-name as it will not match the +- * unqualified type of foo. +- */ +-#define __unconst_integer_type_cases(type) \ +- unsigned type: (unsigned type)0, \ +- signed type: (signed type)0 +- +-#define __unconst_integer_typeof(x) typeof( \ +- _Generic((x), \ +- char: (char)0, \ +- __unconst_integer_type_cases(char), \ +- __unconst_integer_type_cases(short), \ +- __unconst_integer_type_cases(int), \ +- __unconst_integer_type_cases(long), \ +- __unconst_integer_type_cases(long long), \ +- default: (x))) +- +-/* + * Do not check the array parameter using __must_be_array(). + * In the following legit use-case where the "array" passed is a simple pointer, + * __must_be_array() will return a failure. +@@ -169,13 +149,13 @@ + * 'int *buff' and 'int buff[N]' types. + * + * The array can be an array of const items. +- * typeof() keeps the const qualifier. Use __unconst_integer_typeof() in order ++ * typeof() keeps the const qualifier. Use __unqual_scalar_typeof() in order + * to discard the const qualifier for the __element variable. + */ + #define __minmax_array(op, array, len) ({ \ + typeof(&(array)[0]) __array = (array); \ + typeof(len) __len = (len); \ +- __unconst_integer_typeof(__array[0]) __element = __array[--__len]; \ ++ __unqual_scalar_typeof(__array[0]) __element = __array[--__len];\ + while (__len--) \ + __element = op(__element, __array[__len]); \ + __element; }) diff --git a/queue-6.6/minmax-fix-header-inclusions.patch b/queue-6.6/minmax-fix-header-inclusions.patch new file mode 100644 index 00000000000..f638b4cd966 --- /dev/null +++ b/queue-6.6/minmax-fix-header-inclusions.patch @@ -0,0 +1,36 @@ +From f6e9d38f8eb00ac8b52e6d15f6aa9bcecacb081b Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Tue, 12 Sep 2023 12:23:55 +0300 +Subject: minmax: fix header inclusions + +From: Andy Shevchenko + +commit f6e9d38f8eb00ac8b52e6d15f6aa9bcecacb081b upstream. + +BUILD_BUG_ON*() macros are defined in build_bug.h. Include it. Replace +compiler_types.h by compiler.h, which provides the former, to have a +definition of the __UNIQUE_ID(). + +Link: https://lkml.kernel.org/r/20230912092355.79280-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Andy Shevchenko +Reviewed-by: Herve Codina +Cc: Rasmus Villemoes +Signed-off-by: Greg Kroah-Hartman + +Signed-off-by: Andrew Morton +--- + include/linux/minmax.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -2,7 +2,8 @@ + #ifndef _LINUX_MINMAX_H + #define _LINUX_MINMAX_H + +-#include ++#include ++#include + #include + #include + diff --git a/queue-6.6/minmax-fix-indentation-of-__cmp_once-and-__clamp_once.patch b/queue-6.6/minmax-fix-indentation-of-__cmp_once-and-__clamp_once.patch new file mode 100644 index 00000000000..054a26581eb --- /dev/null +++ b/queue-6.6/minmax-fix-indentation-of-__cmp_once-and-__clamp_once.patch @@ -0,0 +1,70 @@ +From f4b84b2ff851f01d0fac619eadef47eb41648534 Mon Sep 17 00:00:00 2001 +From: David Laight +Date: Mon, 18 Sep 2023 08:17:57 +0000 +Subject: minmax: fix indentation of __cmp_once() and __clamp_once() + +From: David Laight + +commit f4b84b2ff851f01d0fac619eadef47eb41648534 upstream. + +Remove the extra indentation and align continuation markers. + +Link: https://lkml.kernel.org/r/bed41317a05c498ea0209eafbcab45a5@AcuMS.aculab.com +Signed-off-by: David Laight +Cc: Andy Shevchenko +Cc: Christoph Hellwig +Cc: Jason A. Donenfeld +Cc: Linus Torvalds +Cc: Matthew Wilcox (Oracle) +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 30 +++++++++++++++--------------- + 1 file changed, 15 insertions(+), 15 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -35,11 +35,11 @@ + #define __cmp(op, x, y) ((x) __cmp_op_##op (y) ? (x) : (y)) + + #define __cmp_once(op, x, y, unique_x, unique_y) ({ \ +- typeof(x) unique_x = (x); \ +- typeof(y) unique_y = (y); \ +- static_assert(__types_ok(x, y), \ +- #op "(" #x ", " #y ") signedness error, fix types or consider u" #op "() before " #op "_t()"); \ +- __cmp(op, unique_x, unique_y); }) ++ typeof(x) unique_x = (x); \ ++ typeof(y) unique_y = (y); \ ++ static_assert(__types_ok(x, y), \ ++ #op "(" #x ", " #y ") signedness error, fix types or consider u" #op "() before " #op "_t()"); \ ++ __cmp(op, unique_x, unique_y); }) + + #define __careful_cmp(op, x, y) \ + __builtin_choose_expr(__is_constexpr((x) - (y)), \ +@@ -49,16 +49,16 @@ + #define __clamp(val, lo, hi) \ + ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val))) + +-#define __clamp_once(val, lo, hi, unique_val, unique_lo, unique_hi) ({ \ +- typeof(val) unique_val = (val); \ +- typeof(lo) unique_lo = (lo); \ +- typeof(hi) unique_hi = (hi); \ +- static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \ +- (lo) <= (hi), true), \ +- "clamp() low limit " #lo " greater than high limit " #hi); \ +- static_assert(__types_ok(val, lo), "clamp() 'lo' signedness error"); \ +- static_assert(__types_ok(val, hi), "clamp() 'hi' signedness error"); \ +- __clamp(unique_val, unique_lo, unique_hi); }) ++#define __clamp_once(val, lo, hi, unique_val, unique_lo, unique_hi) ({ \ ++ typeof(val) unique_val = (val); \ ++ typeof(lo) unique_lo = (lo); \ ++ typeof(hi) unique_hi = (hi); \ ++ static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \ ++ (lo) <= (hi), true), \ ++ "clamp() low limit " #lo " greater than high limit " #hi); \ ++ static_assert(__types_ok(val, lo), "clamp() 'lo' signedness error"); \ ++ static_assert(__types_ok(val, hi), "clamp() 'hi' signedness error"); \ ++ __clamp(unique_val, unique_lo, unique_hi); }) + + #define __careful_clamp(val, lo, hi) ({ \ + __builtin_choose_expr(__is_constexpr((val) - (lo) + (hi)), \ diff --git a/queue-6.6/minmax-relax-check-to-allow-comparison-between-unsigned-arguments-and-signed-constants.patch b/queue-6.6/minmax-relax-check-to-allow-comparison-between-unsigned-arguments-and-signed-constants.patch new file mode 100644 index 00000000000..384e5699c27 --- /dev/null +++ b/queue-6.6/minmax-relax-check-to-allow-comparison-between-unsigned-arguments-and-signed-constants.patch @@ -0,0 +1,72 @@ +From 867046cc7027703f60a46339ffde91a1970f2901 Mon Sep 17 00:00:00 2001 +From: David Laight +Date: Mon, 18 Sep 2023 08:19:25 +0000 +Subject: minmax: relax check to allow comparison between unsigned arguments and signed constants + +From: David Laight + +commit 867046cc7027703f60a46339ffde91a1970f2901 upstream. + +Allow (for example) min(unsigned_var, 20). + +The opposite min(signed_var, 20u) is still errored. + +Since a comparison between signed and unsigned never makes the unsigned +value negative it is only necessary to adjust the __types_ok() test. + +Link: https://lkml.kernel.org/r/633b64e2f39e46bb8234809c5595b8c7@AcuMS.aculab.com +Signed-off-by: David Laight +Cc: Andy Shevchenko +Cc: Christoph Hellwig +Cc: Jason A. Donenfeld +Cc: Linus Torvalds +Cc: Matthew Wilcox (Oracle) +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 24 +++++++++++++++++------- + 1 file changed, 17 insertions(+), 7 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -10,13 +10,18 @@ + /* + * min()/max()/clamp() macros must accomplish three things: + * +- * - avoid multiple evaluations of the arguments (so side-effects like ++ * - Avoid multiple evaluations of the arguments (so side-effects like + * "x++" happen only once) when non-constant. +- * - perform signed v unsigned type-checking (to generate compile +- * errors instead of nasty runtime surprises). +- * - retain result as a constant expressions when called with only ++ * - Retain result as a constant expressions when called with only + * constant expressions (to avoid tripping VLA warnings in stack + * allocation usage). ++ * - Perform signed v unsigned type-checking (to generate compile ++ * errors instead of nasty runtime surprises). ++ * - Unsigned char/short are always promoted to signed int and can be ++ * compared against signed or unsigned arguments. ++ * - Unsigned arguments can be compared against non-negative signed constants. ++ * - Comparison of a signed argument against an unsigned constant fails ++ * even if the constant is below __INT_MAX__ and could be cast to int. + */ + #define __typecheck(x, y) \ + (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1))) +@@ -26,9 +31,14 @@ + __builtin_choose_expr(__is_constexpr(is_signed_type(typeof(x))), \ + is_signed_type(typeof(x)), 0) + +-#define __types_ok(x, y) \ +- (__is_signed(x) == __is_signed(y) || \ +- __is_signed((x) + 0) == __is_signed((y) + 0)) ++/* True for a non-negative signed int constant */ ++#define __is_noneg_int(x) \ ++ (__builtin_choose_expr(__is_constexpr(x) && __is_signed(x), x, -1) >= 0) ++ ++#define __types_ok(x, y) \ ++ (__is_signed(x) == __is_signed(y) || \ ++ __is_signed((x) + 0) == __is_signed((y) + 0) || \ ++ __is_noneg_int(x) || __is_noneg_int(y)) + + #define __cmp_op_min < + #define __cmp_op_max > diff --git a/queue-6.6/series b/queue-6.6/series index 097f7de2902..989c1ab6813 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -95,6 +95,13 @@ bpf-set-need_defer-as-false-when-clearing-fd-array-d.patch wifi-ath12k-fix-and-enable-ap-mode-for-wcn7850.patch scsi-libfc-don-t-schedule-abort-twice.patch scsi-libfc-fix-up-timeout-error-in-fc_fcp_rec_error.patch +minmax-deduplicate-__unconst_integer_typeof.patch +minmax-fix-header-inclusions.patch +minmax-add-umin-a-b-and-umax-a-b.patch +minmax-allow-min-max-clamp-if-the-arguments-have-the-same-signedness.patch +minmax-fix-indentation-of-__cmp_once-and-__clamp_once.patch +minmax-allow-comparisons-of-int-against-unsigned-char-short.patch +minmax-relax-check-to-allow-comparison-between-unsigned-arguments-and-signed-constants.patch net-mvmdio-avoid-excessive-sleeps-in-polled-mode.patch arm64-dts-qcom-sm8550-fix-soundwire-controllers-node.patch arm64-dts-qcom-sm8450-fix-soundwire-controllers-node.patch