diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-15 19:39:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-15 19:39:15 -0400 |
commit | eea3a00264cf243a28e4331566ce67b86059339d (patch) | |
tree | 487f16389e0dfa32e9caa7604d1274a7dcda8f04 /lib | |
parent | e7c82412433a8039616c7314533a0a1c025d99bf (diff) | |
parent | e693d73c20ffdb06840c9378f367bad849ac0d5d (diff) |
Merge branch 'akpm' (patches from Andrew)
Merge second patchbomb from Andrew Morton:
- the rest of MM
- various misc bits
- add ability to run /sbin/reboot at reboot time
- printk/vsprintf changes
- fiddle with seq_printf() return value
* akpm: (114 commits)
parisc: remove use of seq_printf return value
lru_cache: remove use of seq_printf return value
tracing: remove use of seq_printf return value
cgroup: remove use of seq_printf return value
proc: remove use of seq_printf return value
s390: remove use of seq_printf return value
cris fasttimer: remove use of seq_printf return value
cris: remove use of seq_printf return value
openrisc: remove use of seq_printf return value
ARM: plat-pxa: remove use of seq_printf return value
nios2: cpuinfo: remove use of seq_printf return value
microblaze: mb: remove use of seq_printf return value
ipc: remove use of seq_printf return value
rtc: remove use of seq_printf return value
power: wakeup: remove use of seq_printf return value
x86: mtrr: if: remove use of seq_printf return value
linux/bitmap.h: improve BITMAP_{LAST,FIRST}_WORD_MASK
MAINTAINERS: CREDITS: remove Stefano Brivio from B43
.mailmap: add Ricardo Ribalda
CREDITS: add Ricardo Ribalda Delgado
...
Diffstat (limited to 'lib')
-rw-r--r-- | lib/lru_cache.c | 9 | ||||
-rw-r--r-- | lib/string_helpers.c | 193 | ||||
-rw-r--r-- | lib/test-hexdump.c | 8 | ||||
-rw-r--r-- | lib/test-string_helpers.c | 40 | ||||
-rw-r--r-- | lib/vsprintf.c | 110 |
5 files changed, 181 insertions, 179 deletions
diff --git a/lib/lru_cache.c b/lib/lru_cache.c index 852c81e3ba9a..028f5d996eef 100644 --- a/lib/lru_cache.c +++ b/lib/lru_cache.c | |||
@@ -247,10 +247,11 @@ size_t lc_seq_printf_stats(struct seq_file *seq, struct lru_cache *lc) | |||
247 | * progress) and "changed", when this in fact lead to an successful | 247 | * progress) and "changed", when this in fact lead to an successful |
248 | * update of the cache. | 248 | * update of the cache. |
249 | */ | 249 | */ |
250 | return seq_printf(seq, "\t%s: used:%u/%u " | 250 | seq_printf(seq, "\t%s: used:%u/%u hits:%lu misses:%lu starving:%lu locked:%lu changed:%lu\n", |
251 | "hits:%lu misses:%lu starving:%lu locked:%lu changed:%lu\n", | 251 | lc->name, lc->used, lc->nr_elements, |
252 | lc->name, lc->used, lc->nr_elements, | 252 | lc->hits, lc->misses, lc->starving, lc->locked, lc->changed); |
253 | lc->hits, lc->misses, lc->starving, lc->locked, lc->changed); | 253 | |
254 | return 0; | ||
254 | } | 255 | } |
255 | 256 | ||
256 | static struct hlist_head *lc_hash_slot(struct lru_cache *lc, unsigned int enr) | 257 | static struct hlist_head *lc_hash_slot(struct lru_cache *lc, unsigned int enr) |
diff --git a/lib/string_helpers.c b/lib/string_helpers.c index 8f8c4417f228..1826c7407258 100644 --- a/lib/string_helpers.c +++ b/lib/string_helpers.c | |||
@@ -239,29 +239,21 @@ int string_unescape(char *src, char *dst, size_t size, unsigned int flags) | |||
239 | } | 239 | } |
240 | EXPORT_SYMBOL(string_unescape); | 240 | EXPORT_SYMBOL(string_unescape); |
241 | 241 | ||
242 | static int escape_passthrough(unsigned char c, char **dst, size_t *osz) | 242 | static bool escape_passthrough(unsigned char c, char **dst, char *end) |
243 | { | 243 | { |
244 | char *out = *dst; | 244 | char *out = *dst; |
245 | 245 | ||
246 | if (*osz < 1) | 246 | if (out < end) |
247 | return -ENOMEM; | 247 | *out = c; |
248 | 248 | *dst = out + 1; | |
249 | *out++ = c; | 249 | return true; |
250 | |||
251 | *dst = out; | ||
252 | *osz -= 1; | ||
253 | |||
254 | return 1; | ||
255 | } | 250 | } |
256 | 251 | ||
257 | static int escape_space(unsigned char c, char **dst, size_t *osz) | 252 | static bool escape_space(unsigned char c, char **dst, char *end) |
258 | { | 253 | { |
259 | char *out = *dst; | 254 | char *out = *dst; |
260 | unsigned char to; | 255 | unsigned char to; |
261 | 256 | ||
262 | if (*osz < 2) | ||
263 | return -ENOMEM; | ||
264 | |||
265 | switch (c) { | 257 | switch (c) { |
266 | case '\n': | 258 | case '\n': |
267 | to = 'n'; | 259 | to = 'n'; |
@@ -279,26 +271,25 @@ static int escape_space(unsigned char c, char **dst, size_t *osz) | |||
279 | to = 'f'; | 271 | to = 'f'; |
280 | break; | 272 | break; |
281 | default: | 273 | default: |
282 | return 0; | 274 | return false; |
283 | } | 275 | } |
284 | 276 | ||
285 | *out++ = '\\'; | 277 | if (out < end) |
286 | *out++ = to; | 278 | *out = '\\'; |
279 | ++out; | ||
280 | if (out < end) | ||
281 | *out = to; | ||
282 | ++out; | ||
287 | 283 | ||
288 | *dst = out; | 284 | *dst = out; |
289 | *osz -= 2; | 285 | return true; |
290 | |||
291 | return 1; | ||
292 | } | 286 | } |
293 | 287 | ||
294 | static int escape_special(unsigned char c, char **dst, size_t *osz) | 288 | static bool escape_special(unsigned char c, char **dst, char *end) |
295 | { | 289 | { |
296 | char *out = *dst; | 290 | char *out = *dst; |
297 | unsigned char to; | 291 | unsigned char to; |
298 | 292 | ||
299 | if (*osz < 2) | ||
300 | return -ENOMEM; | ||
301 | |||
302 | switch (c) { | 293 | switch (c) { |
303 | case '\\': | 294 | case '\\': |
304 | to = '\\'; | 295 | to = '\\'; |
@@ -310,71 +301,78 @@ static int escape_special(unsigned char c, char **dst, size_t *osz) | |||
310 | to = 'e'; | 301 | to = 'e'; |
311 | break; | 302 | break; |
312 | default: | 303 | default: |
313 | return 0; | 304 | return false; |
314 | } | 305 | } |
315 | 306 | ||
316 | *out++ = '\\'; | 307 | if (out < end) |
317 | *out++ = to; | 308 | *out = '\\'; |
309 | ++out; | ||
310 | if (out < end) | ||
311 | *out = to; | ||
312 | ++out; | ||
318 | 313 | ||
319 | *dst = out; | 314 | *dst = out; |
320 | *osz -= 2; | 315 | return true; |
321 | |||
322 | return 1; | ||
323 | } | 316 | } |
324 | 317 | ||
325 | static int escape_null(unsigned char c, char **dst, size_t *osz) | 318 | static bool escape_null(unsigned char c, char **dst, char *end) |
326 | { | 319 | { |
327 | char *out = *dst; | 320 | char *out = *dst; |
328 | 321 | ||
329 | if (*osz < 2) | ||
330 | return -ENOMEM; | ||
331 | |||
332 | if (c) | 322 | if (c) |
333 | return 0; | 323 | return false; |
334 | 324 | ||
335 | *out++ = '\\'; | 325 | if (out < end) |
336 | *out++ = '0'; | 326 | *out = '\\'; |
327 | ++out; | ||
328 | if (out < end) | ||
329 | *out = '0'; | ||
330 | ++out; | ||
337 | 331 | ||
338 | *dst = out; | 332 | *dst = out; |
339 | *osz -= 2; | 333 | return true; |
340 | |||
341 | return 1; | ||
342 | } | 334 | } |
343 | 335 | ||
344 | static int escape_octal(unsigned char c, char **dst, size_t *osz) | 336 | static bool escape_octal(unsigned char c, char **dst, char *end) |
345 | { | 337 | { |
346 | char *out = *dst; | 338 | char *out = *dst; |
347 | 339 | ||
348 | if (*osz < 4) | 340 | if (out < end) |
349 | return -ENOMEM; | 341 | *out = '\\'; |
350 | 342 | ++out; | |
351 | *out++ = '\\'; | 343 | if (out < end) |
352 | *out++ = ((c >> 6) & 0x07) + '0'; | 344 | *out = ((c >> 6) & 0x07) + '0'; |
353 | *out++ = ((c >> 3) & 0x07) + '0'; | 345 | ++out; |
354 | *out++ = ((c >> 0) & 0x07) + '0'; | 346 | if (out < end) |
347 | *out = ((c >> 3) & 0x07) + '0'; | ||
348 | ++out; | ||
349 | if (out < end) | ||
350 | *out = ((c >> 0) & 0x07) + '0'; | ||
351 | ++out; | ||
355 | 352 | ||
356 | *dst = out; | 353 | *dst = out; |
357 | *osz -= 4; | 354 | return true; |
358 | |||
359 | return 1; | ||
360 | } | 355 | } |
361 | 356 | ||
362 | static int escape_hex(unsigned char c, char **dst, size_t *osz) | 357 | static bool escape_hex(unsigned char c, char **dst, char *end) |
363 | { | 358 | { |
364 | char *out = *dst; | 359 | char *out = *dst; |
365 | 360 | ||
366 | if (*osz < 4) | 361 | if (out < end) |
367 | return -ENOMEM; | 362 | *out = '\\'; |
368 | 363 | ++out; | |
369 | *out++ = '\\'; | 364 | if (out < end) |
370 | *out++ = 'x'; | 365 | *out = 'x'; |
371 | *out++ = hex_asc_hi(c); | 366 | ++out; |
372 | *out++ = hex_asc_lo(c); | 367 | if (out < end) |
368 | *out = hex_asc_hi(c); | ||
369 | ++out; | ||
370 | if (out < end) | ||
371 | *out = hex_asc_lo(c); | ||
372 | ++out; | ||
373 | 373 | ||
374 | *dst = out; | 374 | *dst = out; |
375 | *osz -= 4; | 375 | return true; |
376 | |||
377 | return 1; | ||
378 | } | 376 | } |
379 | 377 | ||
380 | /** | 378 | /** |
@@ -426,19 +424,17 @@ static int escape_hex(unsigned char c, char **dst, size_t *osz) | |||
426 | * it if needs. | 424 | * it if needs. |
427 | * | 425 | * |
428 | * Return: | 426 | * Return: |
429 | * The amount of the characters processed to the destination buffer, or | 427 | * The total size of the escaped output that would be generated for |
430 | * %-ENOMEM if the size of buffer is not enough to put an escaped character is | 428 | * the given input and flags. To check whether the output was |
431 | * returned. | 429 | * truncated, compare the return value to osz. There is room left in |
432 | * | 430 | * dst for a '\0' terminator if and only if ret < osz. |
433 | * Even in the case of error @dst pointer will be updated to point to the byte | ||
434 | * after the last processed character. | ||
435 | */ | 431 | */ |
436 | int string_escape_mem(const char *src, size_t isz, char **dst, size_t osz, | 432 | int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz, |
437 | unsigned int flags, const char *esc) | 433 | unsigned int flags, const char *esc) |
438 | { | 434 | { |
439 | char *out = *dst, *p = out; | 435 | char *p = dst; |
436 | char *end = p + osz; | ||
440 | bool is_dict = esc && *esc; | 437 | bool is_dict = esc && *esc; |
441 | int ret = 0; | ||
442 | 438 | ||
443 | while (isz--) { | 439 | while (isz--) { |
444 | unsigned char c = *src++; | 440 | unsigned char c = *src++; |
@@ -458,55 +454,26 @@ int string_escape_mem(const char *src, size_t isz, char **dst, size_t osz, | |||
458 | (is_dict && !strchr(esc, c))) { | 454 | (is_dict && !strchr(esc, c))) { |
459 | /* do nothing */ | 455 | /* do nothing */ |
460 | } else { | 456 | } else { |
461 | if (flags & ESCAPE_SPACE) { | 457 | if (flags & ESCAPE_SPACE && escape_space(c, &p, end)) |
462 | ret = escape_space(c, &p, &osz); | 458 | continue; |
463 | if (ret < 0) | 459 | |
464 | break; | 460 | if (flags & ESCAPE_SPECIAL && escape_special(c, &p, end)) |
465 | if (ret > 0) | 461 | continue; |
466 | continue; | 462 | |
467 | } | 463 | if (flags & ESCAPE_NULL && escape_null(c, &p, end)) |
468 | 464 | continue; | |
469 | if (flags & ESCAPE_SPECIAL) { | ||
470 | ret = escape_special(c, &p, &osz); | ||
471 | if (ret < 0) | ||
472 | break; | ||
473 | if (ret > 0) | ||
474 | continue; | ||
475 | } | ||
476 | |||
477 | if (flags & ESCAPE_NULL) { | ||
478 | ret = escape_null(c, &p, &osz); | ||
479 | if (ret < 0) | ||
480 | break; | ||
481 | if (ret > 0) | ||
482 | continue; | ||
483 | } | ||
484 | 465 | ||
485 | /* ESCAPE_OCTAL and ESCAPE_HEX always go last */ | 466 | /* ESCAPE_OCTAL and ESCAPE_HEX always go last */ |
486 | if (flags & ESCAPE_OCTAL) { | 467 | if (flags & ESCAPE_OCTAL && escape_octal(c, &p, end)) |
487 | ret = escape_octal(c, &p, &osz); | ||
488 | if (ret < 0) | ||
489 | break; | ||
490 | continue; | 468 | continue; |
491 | } | 469 | |
492 | if (flags & ESCAPE_HEX) { | 470 | if (flags & ESCAPE_HEX && escape_hex(c, &p, end)) |
493 | ret = escape_hex(c, &p, &osz); | ||
494 | if (ret < 0) | ||
495 | break; | ||
496 | continue; | 471 | continue; |
497 | } | ||
498 | } | 472 | } |
499 | 473 | ||
500 | ret = escape_passthrough(c, &p, &osz); | 474 | escape_passthrough(c, &p, end); |
501 | if (ret < 0) | ||
502 | break; | ||
503 | } | 475 | } |
504 | 476 | ||
505 | *dst = p; | 477 | return p - dst; |
506 | |||
507 | if (ret < 0) | ||
508 | return ret; | ||
509 | |||
510 | return p - out; | ||
511 | } | 478 | } |
512 | EXPORT_SYMBOL(string_escape_mem); | 479 | EXPORT_SYMBOL(string_escape_mem); |
diff --git a/lib/test-hexdump.c b/lib/test-hexdump.c index daf29a390a89..9846ff7428b3 100644 --- a/lib/test-hexdump.c +++ b/lib/test-hexdump.c | |||
@@ -18,26 +18,26 @@ static const unsigned char data_b[] = { | |||
18 | 18 | ||
19 | static const unsigned char data_a[] = ".2.{....p..$}.4...1.....L...C..."; | 19 | static const unsigned char data_a[] = ".2.{....p..$}.4...1.....L...C..."; |
20 | 20 | ||
21 | static const char *test_data_1_le[] __initconst = { | 21 | static const char * const test_data_1_le[] __initconst = { |
22 | "be", "32", "db", "7b", "0a", "18", "93", "b2", | 22 | "be", "32", "db", "7b", "0a", "18", "93", "b2", |
23 | "70", "ba", "c4", "24", "7d", "83", "34", "9b", | 23 | "70", "ba", "c4", "24", "7d", "83", "34", "9b", |
24 | "a6", "9c", "31", "ad", "9c", "0f", "ac", "e9", | 24 | "a6", "9c", "31", "ad", "9c", "0f", "ac", "e9", |
25 | "4c", "d1", "19", "99", "43", "b1", "af", "0c", | 25 | "4c", "d1", "19", "99", "43", "b1", "af", "0c", |
26 | }; | 26 | }; |
27 | 27 | ||
28 | static const char *test_data_2_le[] __initconst = { | 28 | static const char *test_data_2_le[] __initdata = { |
29 | "32be", "7bdb", "180a", "b293", | 29 | "32be", "7bdb", "180a", "b293", |
30 | "ba70", "24c4", "837d", "9b34", | 30 | "ba70", "24c4", "837d", "9b34", |
31 | "9ca6", "ad31", "0f9c", "e9ac", | 31 | "9ca6", "ad31", "0f9c", "e9ac", |
32 | "d14c", "9919", "b143", "0caf", | 32 | "d14c", "9919", "b143", "0caf", |
33 | }; | 33 | }; |
34 | 34 | ||
35 | static const char *test_data_4_le[] __initconst = { | 35 | static const char *test_data_4_le[] __initdata = { |
36 | "7bdb32be", "b293180a", "24c4ba70", "9b34837d", | 36 | "7bdb32be", "b293180a", "24c4ba70", "9b34837d", |
37 | "ad319ca6", "e9ac0f9c", "9919d14c", "0cafb143", | 37 | "ad319ca6", "e9ac0f9c", "9919d14c", "0cafb143", |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static const char *test_data_8_le[] __initconst = { | 40 | static const char *test_data_8_le[] __initdata = { |
41 | "b293180a7bdb32be", "9b34837d24c4ba70", | 41 | "b293180a7bdb32be", "9b34837d24c4ba70", |
42 | "e9ac0f9cad319ca6", "0cafb1439919d14c", | 42 | "e9ac0f9cad319ca6", "0cafb1439919d14c", |
43 | }; | 43 | }; |
diff --git a/lib/test-string_helpers.c b/lib/test-string_helpers.c index ab0d30e1e18f..8e376efd88a4 100644 --- a/lib/test-string_helpers.c +++ b/lib/test-string_helpers.c | |||
@@ -260,16 +260,28 @@ static __init const char *test_string_find_match(const struct test_string_2 *s2, | |||
260 | return NULL; | 260 | return NULL; |
261 | } | 261 | } |
262 | 262 | ||
263 | static __init void | ||
264 | test_string_escape_overflow(const char *in, int p, unsigned int flags, const char *esc, | ||
265 | int q_test, const char *name) | ||
266 | { | ||
267 | int q_real; | ||
268 | |||
269 | q_real = string_escape_mem(in, p, NULL, 0, flags, esc); | ||
270 | if (q_real != q_test) | ||
271 | pr_warn("Test '%s' failed: flags = %u, osz = 0, expected %d, got %d\n", | ||
272 | name, flags, q_test, q_real); | ||
273 | } | ||
274 | |||
263 | static __init void test_string_escape(const char *name, | 275 | static __init void test_string_escape(const char *name, |
264 | const struct test_string_2 *s2, | 276 | const struct test_string_2 *s2, |
265 | unsigned int flags, const char *esc) | 277 | unsigned int flags, const char *esc) |
266 | { | 278 | { |
267 | int q_real = 512; | 279 | size_t out_size = 512; |
268 | char *out_test = kmalloc(q_real, GFP_KERNEL); | 280 | char *out_test = kmalloc(out_size, GFP_KERNEL); |
269 | char *out_real = kmalloc(q_real, GFP_KERNEL); | 281 | char *out_real = kmalloc(out_size, GFP_KERNEL); |
270 | char *in = kmalloc(256, GFP_KERNEL); | 282 | char *in = kmalloc(256, GFP_KERNEL); |
271 | char *buf = out_real; | ||
272 | int p = 0, q_test = 0; | 283 | int p = 0, q_test = 0; |
284 | int q_real; | ||
273 | 285 | ||
274 | if (!out_test || !out_real || !in) | 286 | if (!out_test || !out_real || !in) |
275 | goto out; | 287 | goto out; |
@@ -301,29 +313,19 @@ static __init void test_string_escape(const char *name, | |||
301 | q_test += len; | 313 | q_test += len; |
302 | } | 314 | } |
303 | 315 | ||
304 | q_real = string_escape_mem(in, p, &buf, q_real, flags, esc); | 316 | q_real = string_escape_mem(in, p, out_real, out_size, flags, esc); |
305 | 317 | ||
306 | test_string_check_buf(name, flags, in, p, out_real, q_real, out_test, | 318 | test_string_check_buf(name, flags, in, p, out_real, q_real, out_test, |
307 | q_test); | 319 | q_test); |
320 | |||
321 | test_string_escape_overflow(in, p, flags, esc, q_test, name); | ||
322 | |||
308 | out: | 323 | out: |
309 | kfree(in); | 324 | kfree(in); |
310 | kfree(out_real); | 325 | kfree(out_real); |
311 | kfree(out_test); | 326 | kfree(out_test); |
312 | } | 327 | } |
313 | 328 | ||
314 | static __init void test_string_escape_nomem(void) | ||
315 | { | ||
316 | char *in = "\eb \\C\007\"\x90\r]"; | ||
317 | char out[64], *buf = out; | ||
318 | int rc = -ENOMEM, ret; | ||
319 | |||
320 | ret = string_escape_str_any_np(in, &buf, strlen(in), NULL); | ||
321 | if (ret == rc) | ||
322 | return; | ||
323 | |||
324 | pr_err("Test 'escape nomem' failed: got %d instead of %d\n", ret, rc); | ||
325 | } | ||
326 | |||
327 | static int __init test_string_helpers_init(void) | 329 | static int __init test_string_helpers_init(void) |
328 | { | 330 | { |
329 | unsigned int i; | 331 | unsigned int i; |
@@ -342,8 +344,6 @@ static int __init test_string_helpers_init(void) | |||
342 | for (i = 0; i < (ESCAPE_ANY_NP | ESCAPE_HEX) + 1; i++) | 344 | for (i = 0; i < (ESCAPE_ANY_NP | ESCAPE_HEX) + 1; i++) |
343 | test_string_escape("escape 1", escape1, i, TEST_STRING_2_DICT_1); | 345 | test_string_escape("escape 1", escape1, i, TEST_STRING_2_DICT_1); |
344 | 346 | ||
345 | test_string_escape_nomem(); | ||
346 | |||
347 | return -EINVAL; | 347 | return -EINVAL; |
348 | } | 348 | } |
349 | module_init(test_string_helpers_init); | 349 | module_init(test_string_helpers_init); |
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index b235c96167d3..3a1e0843f9a2 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -17,6 +17,7 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <stdarg.h> | 19 | #include <stdarg.h> |
20 | #include <linux/clk-provider.h> | ||
20 | #include <linux/module.h> /* for KSYM_SYMBOL_LEN */ | 21 | #include <linux/module.h> /* for KSYM_SYMBOL_LEN */ |
21 | #include <linux/types.h> | 22 | #include <linux/types.h> |
22 | #include <linux/string.h> | 23 | #include <linux/string.h> |
@@ -340,11 +341,11 @@ int num_to_str(char *buf, int size, unsigned long long num) | |||
340 | return len; | 341 | return len; |
341 | } | 342 | } |
342 | 343 | ||
343 | #define ZEROPAD 1 /* pad with zero */ | 344 | #define SIGN 1 /* unsigned/signed, must be 1 */ |
344 | #define SIGN 2 /* unsigned/signed long */ | 345 | #define LEFT 2 /* left justified */ |
345 | #define PLUS 4 /* show plus */ | 346 | #define PLUS 4 /* show plus */ |
346 | #define SPACE 8 /* space if plus */ | 347 | #define SPACE 8 /* space if plus */ |
347 | #define LEFT 16 /* left justified */ | 348 | #define ZEROPAD 16 /* pad with zero, must be 16 == '0' - ' ' */ |
348 | #define SMALL 32 /* use lowercase in hex (must be 32 == 0x20) */ | 349 | #define SMALL 32 /* use lowercase in hex (must be 32 == 0x20) */ |
349 | #define SPECIAL 64 /* prefix hex with "0x", octal with "0" */ | 350 | #define SPECIAL 64 /* prefix hex with "0x", octal with "0" */ |
350 | 351 | ||
@@ -383,10 +384,7 @@ static noinline_for_stack | |||
383 | char *number(char *buf, char *end, unsigned long long num, | 384 | char *number(char *buf, char *end, unsigned long long num, |
384 | struct printf_spec spec) | 385 | struct printf_spec spec) |
385 | { | 386 | { |
386 | /* we are called with base 8, 10 or 16, only, thus don't need "G..." */ | 387 | char tmp[3 * sizeof(num)]; |
387 | static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */ | ||
388 | |||
389 | char tmp[66]; | ||
390 | char sign; | 388 | char sign; |
391 | char locase; | 389 | char locase; |
392 | int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10); | 390 | int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10); |
@@ -422,12 +420,7 @@ char *number(char *buf, char *end, unsigned long long num, | |||
422 | /* generate full string in tmp[], in reverse order */ | 420 | /* generate full string in tmp[], in reverse order */ |
423 | i = 0; | 421 | i = 0; |
424 | if (num < spec.base) | 422 | if (num < spec.base) |
425 | tmp[i++] = digits[num] | locase; | 423 | tmp[i++] = hex_asc_upper[num] | locase; |
426 | /* Generic code, for any base: | ||
427 | else do { | ||
428 | tmp[i++] = (digits[do_div(num,base)] | locase); | ||
429 | } while (num != 0); | ||
430 | */ | ||
431 | else if (spec.base != 10) { /* 8 or 16 */ | 424 | else if (spec.base != 10) { /* 8 or 16 */ |
432 | int mask = spec.base - 1; | 425 | int mask = spec.base - 1; |
433 | int shift = 3; | 426 | int shift = 3; |
@@ -435,7 +428,7 @@ char *number(char *buf, char *end, unsigned long long num, | |||
435 | if (spec.base == 16) | 428 | if (spec.base == 16) |
436 | shift = 4; | 429 | shift = 4; |
437 | do { | 430 | do { |
438 | tmp[i++] = (digits[((unsigned char)num) & mask] | locase); | 431 | tmp[i++] = (hex_asc_upper[((unsigned char)num) & mask] | locase); |
439 | num >>= shift; | 432 | num >>= shift; |
440 | } while (num); | 433 | } while (num); |
441 | } else { /* base 10 */ | 434 | } else { /* base 10 */ |
@@ -447,7 +440,7 @@ char *number(char *buf, char *end, unsigned long long num, | |||
447 | spec.precision = i; | 440 | spec.precision = i; |
448 | /* leading space padding */ | 441 | /* leading space padding */ |
449 | spec.field_width -= spec.precision; | 442 | spec.field_width -= spec.precision; |
450 | if (!(spec.flags & (ZEROPAD+LEFT))) { | 443 | if (!(spec.flags & (ZEROPAD | LEFT))) { |
451 | while (--spec.field_width >= 0) { | 444 | while (--spec.field_width >= 0) { |
452 | if (buf < end) | 445 | if (buf < end) |
453 | *buf = ' '; | 446 | *buf = ' '; |
@@ -475,7 +468,8 @@ char *number(char *buf, char *end, unsigned long long num, | |||
475 | } | 468 | } |
476 | /* zero or space padding */ | 469 | /* zero or space padding */ |
477 | if (!(spec.flags & LEFT)) { | 470 | if (!(spec.flags & LEFT)) { |
478 | char c = (spec.flags & ZEROPAD) ? '0' : ' '; | 471 | char c = ' ' + (spec.flags & ZEROPAD); |
472 | BUILD_BUG_ON(' ' + ZEROPAD != '0'); | ||
479 | while (--spec.field_width >= 0) { | 473 | while (--spec.field_width >= 0) { |
480 | if (buf < end) | 474 | if (buf < end) |
481 | *buf = c; | 475 | *buf = c; |
@@ -783,11 +777,19 @@ char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec, | |||
783 | if (spec.field_width > 0) | 777 | if (spec.field_width > 0) |
784 | len = min_t(int, spec.field_width, 64); | 778 | len = min_t(int, spec.field_width, 64); |
785 | 779 | ||
786 | for (i = 0; i < len && buf < end - 1; i++) { | 780 | for (i = 0; i < len; ++i) { |
787 | buf = hex_byte_pack(buf, addr[i]); | 781 | if (buf < end) |
782 | *buf = hex_asc_hi(addr[i]); | ||
783 | ++buf; | ||
784 | if (buf < end) | ||
785 | *buf = hex_asc_lo(addr[i]); | ||
786 | ++buf; | ||
788 | 787 | ||
789 | if (buf < end && separator && i != len - 1) | 788 | if (separator && i != len - 1) { |
790 | *buf++ = separator; | 789 | if (buf < end) |
790 | *buf = separator; | ||
791 | ++buf; | ||
792 | } | ||
791 | } | 793 | } |
792 | 794 | ||
793 | return buf; | 795 | return buf; |
@@ -1233,8 +1235,12 @@ char *escaped_string(char *buf, char *end, u8 *addr, struct printf_spec spec, | |||
1233 | 1235 | ||
1234 | len = spec.field_width < 0 ? 1 : spec.field_width; | 1236 | len = spec.field_width < 0 ? 1 : spec.field_width; |
1235 | 1237 | ||
1236 | /* Ignore the error. We print as many characters as we can */ | 1238 | /* |
1237 | string_escape_mem(addr, len, &buf, end - buf, flags, NULL); | 1239 | * string_escape_mem() writes as many characters as it can to |
1240 | * the given buffer, and returns the total size of the output | ||
1241 | * had the buffer been big enough. | ||
1242 | */ | ||
1243 | buf += string_escape_mem(addr, len, buf, buf < end ? end - buf : 0, flags, NULL); | ||
1238 | 1244 | ||
1239 | return buf; | 1245 | return buf; |
1240 | } | 1246 | } |
@@ -1322,6 +1328,30 @@ char *address_val(char *buf, char *end, const void *addr, | |||
1322 | return number(buf, end, num, spec); | 1328 | return number(buf, end, num, spec); |
1323 | } | 1329 | } |
1324 | 1330 | ||
1331 | static noinline_for_stack | ||
1332 | char *clock(char *buf, char *end, struct clk *clk, struct printf_spec spec, | ||
1333 | const char *fmt) | ||
1334 | { | ||
1335 | if (!IS_ENABLED(CONFIG_HAVE_CLK) || !clk) | ||
1336 | return string(buf, end, NULL, spec); | ||
1337 | |||
1338 | switch (fmt[1]) { | ||
1339 | case 'r': | ||
1340 | return number(buf, end, clk_get_rate(clk), spec); | ||
1341 | |||
1342 | case 'n': | ||
1343 | default: | ||
1344 | #ifdef CONFIG_COMMON_CLK | ||
1345 | return string(buf, end, __clk_get_name(clk), spec); | ||
1346 | #else | ||
1347 | spec.base = 16; | ||
1348 | spec.field_width = sizeof(unsigned long) * 2 + 2; | ||
1349 | spec.flags |= SPECIAL | SMALL | ZEROPAD; | ||
1350 | return number(buf, end, (unsigned long)clk, spec); | ||
1351 | #endif | ||
1352 | } | ||
1353 | } | ||
1354 | |||
1325 | int kptr_restrict __read_mostly; | 1355 | int kptr_restrict __read_mostly; |
1326 | 1356 | ||
1327 | /* | 1357 | /* |
@@ -1404,6 +1434,11 @@ int kptr_restrict __read_mostly; | |||
1404 | * (default assumed to be phys_addr_t, passed by reference) | 1434 | * (default assumed to be phys_addr_t, passed by reference) |
1405 | * - 'd[234]' For a dentry name (optionally 2-4 last components) | 1435 | * - 'd[234]' For a dentry name (optionally 2-4 last components) |
1406 | * - 'D[234]' Same as 'd' but for a struct file | 1436 | * - 'D[234]' Same as 'd' but for a struct file |
1437 | * - 'C' For a clock, it prints the name (Common Clock Framework) or address | ||
1438 | * (legacy clock framework) of the clock | ||
1439 | * - 'Cn' For a clock, it prints the name (Common Clock Framework) or address | ||
1440 | * (legacy clock framework) of the clock | ||
1441 | * - 'Cr' For a clock, it prints the current rate of the clock | ||
1407 | * | 1442 | * |
1408 | * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 | 1443 | * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 |
1409 | * function pointers are really function descriptors, which contain a | 1444 | * function pointers are really function descriptors, which contain a |
@@ -1548,6 +1583,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
1548 | return address_val(buf, end, ptr, spec, fmt); | 1583 | return address_val(buf, end, ptr, spec, fmt); |
1549 | case 'd': | 1584 | case 'd': |
1550 | return dentry_name(buf, end, ptr, spec, fmt); | 1585 | return dentry_name(buf, end, ptr, spec, fmt); |
1586 | case 'C': | ||
1587 | return clock(buf, end, ptr, spec, fmt); | ||
1551 | case 'D': | 1588 | case 'D': |
1552 | return dentry_name(buf, end, | 1589 | return dentry_name(buf, end, |
1553 | ((const struct file *)ptr)->f_path.dentry, | 1590 | ((const struct file *)ptr)->f_path.dentry, |
@@ -1738,29 +1775,21 @@ qualifier: | |||
1738 | if (spec->qualifier == 'L') | 1775 | if (spec->qualifier == 'L') |
1739 | spec->type = FORMAT_TYPE_LONG_LONG; | 1776 | spec->type = FORMAT_TYPE_LONG_LONG; |
1740 | else if (spec->qualifier == 'l') { | 1777 | else if (spec->qualifier == 'l') { |
1741 | if (spec->flags & SIGN) | 1778 | BUILD_BUG_ON(FORMAT_TYPE_ULONG + SIGN != FORMAT_TYPE_LONG); |
1742 | spec->type = FORMAT_TYPE_LONG; | 1779 | spec->type = FORMAT_TYPE_ULONG + (spec->flags & SIGN); |
1743 | else | ||
1744 | spec->type = FORMAT_TYPE_ULONG; | ||
1745 | } else if (_tolower(spec->qualifier) == 'z') { | 1780 | } else if (_tolower(spec->qualifier) == 'z') { |
1746 | spec->type = FORMAT_TYPE_SIZE_T; | 1781 | spec->type = FORMAT_TYPE_SIZE_T; |
1747 | } else if (spec->qualifier == 't') { | 1782 | } else if (spec->qualifier == 't') { |
1748 | spec->type = FORMAT_TYPE_PTRDIFF; | 1783 | spec->type = FORMAT_TYPE_PTRDIFF; |
1749 | } else if (spec->qualifier == 'H') { | 1784 | } else if (spec->qualifier == 'H') { |
1750 | if (spec->flags & SIGN) | 1785 | BUILD_BUG_ON(FORMAT_TYPE_UBYTE + SIGN != FORMAT_TYPE_BYTE); |
1751 | spec->type = FORMAT_TYPE_BYTE; | 1786 | spec->type = FORMAT_TYPE_UBYTE + (spec->flags & SIGN); |
1752 | else | ||
1753 | spec->type = FORMAT_TYPE_UBYTE; | ||
1754 | } else if (spec->qualifier == 'h') { | 1787 | } else if (spec->qualifier == 'h') { |
1755 | if (spec->flags & SIGN) | 1788 | BUILD_BUG_ON(FORMAT_TYPE_USHORT + SIGN != FORMAT_TYPE_SHORT); |
1756 | spec->type = FORMAT_TYPE_SHORT; | 1789 | spec->type = FORMAT_TYPE_USHORT + (spec->flags & SIGN); |
1757 | else | ||
1758 | spec->type = FORMAT_TYPE_USHORT; | ||
1759 | } else { | 1790 | } else { |
1760 | if (spec->flags & SIGN) | 1791 | BUILD_BUG_ON(FORMAT_TYPE_UINT + SIGN != FORMAT_TYPE_INT); |
1761 | spec->type = FORMAT_TYPE_INT; | 1792 | spec->type = FORMAT_TYPE_UINT + (spec->flags & SIGN); |
1762 | else | ||
1763 | spec->type = FORMAT_TYPE_UINT; | ||
1764 | } | 1793 | } |
1765 | 1794 | ||
1766 | return ++fmt - start; | 1795 | return ++fmt - start; |
@@ -1800,6 +1829,11 @@ qualifier: | |||
1800 | * %*pE[achnops] print an escaped buffer | 1829 | * %*pE[achnops] print an escaped buffer |
1801 | * %*ph[CDN] a variable-length hex string with a separator (supports up to 64 | 1830 | * %*ph[CDN] a variable-length hex string with a separator (supports up to 64 |
1802 | * bytes of the input) | 1831 | * bytes of the input) |
1832 | * %pC output the name (Common Clock Framework) or address (legacy clock | ||
1833 | * framework) of a clock | ||
1834 | * %pCn output the name (Common Clock Framework) or address (legacy clock | ||
1835 | * framework) of a clock | ||
1836 | * %pCr output the current rate of a clock | ||
1803 | * %n is ignored | 1837 | * %n is ignored |
1804 | * | 1838 | * |
1805 | * ** Please update Documentation/printk-formats.txt when making changes ** | 1839 | * ** Please update Documentation/printk-formats.txt when making changes ** |