hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/arch/x86/boot/string.c
....@@ -1,10 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /* -*- linux-c -*- ------------------------------------------------------- *
23 *
34 * Copyright (C) 1991, 1992 Linus Torvalds
45 * Copyright 2007 rPath, Inc. - All Rights Reserved
5
- *
6
- * This file is part of the Linux kernel, and is made available under
7
- * the terms of the GNU General Public License version 2.
86 *
97 * ----------------------------------------------------------------------- */
108
....@@ -13,9 +11,14 @@
1311 */
1412
1513 #include <linux/types.h>
14
+#include <linux/compiler.h>
15
+#include <linux/errno.h>
16
+#include <linux/limits.h>
1617 #include <asm/asm.h>
1718 #include "ctype.h"
1819 #include "string.h"
20
+
21
+#define KSTRTOX_OVERFLOW (1U << 31)
1922
2023 /*
2124 * Undef these macros so that the functions that we provide
....@@ -114,7 +117,6 @@
114117 * @endp: A pointer to the end of the parsed string will be placed here
115118 * @base: The number base to use
116119 */
117
-
118120 unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
119121 {
120122 unsigned long long result = 0;
....@@ -195,3 +197,182 @@
195197 return NULL;
196198 return (char *)s;
197199 }
200
+
201
+static inline u64 __div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
202
+{
203
+ union {
204
+ u64 v64;
205
+ u32 v32[2];
206
+ } d = { dividend };
207
+ u32 upper;
208
+
209
+ upper = d.v32[1];
210
+ d.v32[1] = 0;
211
+ if (upper >= divisor) {
212
+ d.v32[1] = upper / divisor;
213
+ upper %= divisor;
214
+ }
215
+ asm ("divl %2" : "=a" (d.v32[0]), "=d" (*remainder) :
216
+ "rm" (divisor), "0" (d.v32[0]), "1" (upper));
217
+ return d.v64;
218
+}
219
+
220
+static inline u64 __div_u64(u64 dividend, u32 divisor)
221
+{
222
+ u32 remainder;
223
+
224
+ return __div_u64_rem(dividend, divisor, &remainder);
225
+}
226
+
227
+static inline char _tolower(const char c)
228
+{
229
+ return c | 0x20;
230
+}
231
+
232
+static const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
233
+{
234
+ if (*base == 0) {
235
+ if (s[0] == '0') {
236
+ if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
237
+ *base = 16;
238
+ else
239
+ *base = 8;
240
+ } else
241
+ *base = 10;
242
+ }
243
+ if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
244
+ s += 2;
245
+ return s;
246
+}
247
+
248
+/*
249
+ * Convert non-negative integer string representation in explicitly given radix
250
+ * to an integer.
251
+ * Return number of characters consumed maybe or-ed with overflow bit.
252
+ * If overflow occurs, result integer (incorrect) is still returned.
253
+ *
254
+ * Don't you dare use this function.
255
+ */
256
+static unsigned int _parse_integer(const char *s,
257
+ unsigned int base,
258
+ unsigned long long *p)
259
+{
260
+ unsigned long long res;
261
+ unsigned int rv;
262
+
263
+ res = 0;
264
+ rv = 0;
265
+ while (1) {
266
+ unsigned int c = *s;
267
+ unsigned int lc = c | 0x20; /* don't tolower() this line */
268
+ unsigned int val;
269
+
270
+ if ('0' <= c && c <= '9')
271
+ val = c - '0';
272
+ else if ('a' <= lc && lc <= 'f')
273
+ val = lc - 'a' + 10;
274
+ else
275
+ break;
276
+
277
+ if (val >= base)
278
+ break;
279
+ /*
280
+ * Check for overflow only if we are within range of
281
+ * it in the max base we support (16)
282
+ */
283
+ if (unlikely(res & (~0ull << 60))) {
284
+ if (res > __div_u64(ULLONG_MAX - val, base))
285
+ rv |= KSTRTOX_OVERFLOW;
286
+ }
287
+ res = res * base + val;
288
+ rv++;
289
+ s++;
290
+ }
291
+ *p = res;
292
+ return rv;
293
+}
294
+
295
+static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
296
+{
297
+ unsigned long long _res;
298
+ unsigned int rv;
299
+
300
+ s = _parse_integer_fixup_radix(s, &base);
301
+ rv = _parse_integer(s, base, &_res);
302
+ if (rv & KSTRTOX_OVERFLOW)
303
+ return -ERANGE;
304
+ if (rv == 0)
305
+ return -EINVAL;
306
+ s += rv;
307
+ if (*s == '\n')
308
+ s++;
309
+ if (*s)
310
+ return -EINVAL;
311
+ *res = _res;
312
+ return 0;
313
+}
314
+
315
+/**
316
+ * kstrtoull - convert a string to an unsigned long long
317
+ * @s: The start of the string. The string must be null-terminated, and may also
318
+ * include a single newline before its terminating null. The first character
319
+ * may also be a plus sign, but not a minus sign.
320
+ * @base: The number base to use. The maximum supported base is 16. If base is
321
+ * given as 0, then the base of the string is automatically detected with the
322
+ * conventional semantics - If it begins with 0x the number will be parsed as a
323
+ * hexadecimal (case insensitive), if it otherwise begins with 0, it will be
324
+ * parsed as an octal number. Otherwise it will be parsed as a decimal.
325
+ * @res: Where to write the result of the conversion on success.
326
+ *
327
+ * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
328
+ * Used as a replacement for the obsolete simple_strtoull. Return code must
329
+ * be checked.
330
+ */
331
+int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
332
+{
333
+ if (s[0] == '+')
334
+ s++;
335
+ return _kstrtoull(s, base, res);
336
+}
337
+
338
+static int _kstrtoul(const char *s, unsigned int base, unsigned long *res)
339
+{
340
+ unsigned long long tmp;
341
+ int rv;
342
+
343
+ rv = kstrtoull(s, base, &tmp);
344
+ if (rv < 0)
345
+ return rv;
346
+ if (tmp != (unsigned long)tmp)
347
+ return -ERANGE;
348
+ *res = tmp;
349
+ return 0;
350
+}
351
+
352
+/**
353
+ * kstrtoul - convert a string to an unsigned long
354
+ * @s: The start of the string. The string must be null-terminated, and may also
355
+ * include a single newline before its terminating null. The first character
356
+ * may also be a plus sign, but not a minus sign.
357
+ * @base: The number base to use. The maximum supported base is 16. If base is
358
+ * given as 0, then the base of the string is automatically detected with the
359
+ * conventional semantics - If it begins with 0x the number will be parsed as a
360
+ * hexadecimal (case insensitive), if it otherwise begins with 0, it will be
361
+ * parsed as an octal number. Otherwise it will be parsed as a decimal.
362
+ * @res: Where to write the result of the conversion on success.
363
+ *
364
+ * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
365
+ * Used as a replacement for the simple_strtoull.
366
+ */
367
+int boot_kstrtoul(const char *s, unsigned int base, unsigned long *res)
368
+{
369
+ /*
370
+ * We want to shortcut function call, but
371
+ * __builtin_types_compatible_p(unsigned long, unsigned long long) = 0.
372
+ */
373
+ if (sizeof(unsigned long) == sizeof(unsigned long long) &&
374
+ __alignof__(unsigned long) == __alignof__(unsigned long long))
375
+ return kstrtoull(s, base, (unsigned long long *)res);
376
+ else
377
+ return _kstrtoul(s, base, res);
378
+}