diff options
Diffstat (limited to 'include/linux/overflow.h')
| -rw-r--r-- | include/linux/overflow.h | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/include/linux/overflow.h b/include/linux/overflow.h index 8712ff70995f..40b48e2133cb 100644 --- a/include/linux/overflow.h +++ b/include/linux/overflow.h | |||
| @@ -202,6 +202,37 @@ | |||
| 202 | 202 | ||
| 203 | #endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */ | 203 | #endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */ |
| 204 | 204 | ||
| 205 | /** check_shl_overflow() - Calculate a left-shifted value and check overflow | ||
| 206 | * | ||
| 207 | * @a: Value to be shifted | ||
| 208 | * @s: How many bits left to shift | ||
| 209 | * @d: Pointer to where to store the result | ||
| 210 | * | ||
| 211 | * Computes *@d = (@a << @s) | ||
| 212 | * | ||
| 213 | * Returns true if '*d' cannot hold the result or when 'a << s' doesn't | ||
| 214 | * make sense. Example conditions: | ||
| 215 | * - 'a << s' causes bits to be lost when stored in *d. | ||
| 216 | * - 's' is garbage (e.g. negative) or so large that the result of | ||
| 217 | * 'a << s' is guaranteed to be 0. | ||
| 218 | * - 'a' is negative. | ||
| 219 | * - 'a << s' sets the sign bit, if any, in '*d'. | ||
| 220 | * | ||
| 221 | * '*d' will hold the results of the attempted shift, but is not | ||
| 222 | * considered "safe for use" if false is returned. | ||
| 223 | */ | ||
| 224 | #define check_shl_overflow(a, s, d) ({ \ | ||
| 225 | typeof(a) _a = a; \ | ||
| 226 | typeof(s) _s = s; \ | ||
| 227 | typeof(d) _d = d; \ | ||
| 228 | u64 _a_full = _a; \ | ||
| 229 | unsigned int _to_shift = \ | ||
| 230 | _s >= 0 && _s < 8 * sizeof(*d) ? _s : 0; \ | ||
| 231 | *_d = (_a_full << _to_shift); \ | ||
| 232 | (_to_shift != _s || *_d < 0 || _a < 0 || \ | ||
| 233 | (*_d >> _to_shift) != _a); \ | ||
| 234 | }) | ||
| 235 | |||
| 205 | /** | 236 | /** |
| 206 | * array_size() - Calculate size of 2-dimensional array. | 237 | * array_size() - Calculate size of 2-dimensional array. |
| 207 | * | 238 | * |
