aboutsummaryrefslogtreecommitdiffstats
path: root/lib/vsprintf.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vsprintf.c')
-rw-r--r--lib/vsprintf.c48
1 files changed, 33 insertions, 15 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index d7a708f82559..23920c5ff728 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -336,7 +336,7 @@ char *put_dec(char *buf, unsigned long long n)
336 * 336 *
337 * If speed is not important, use snprintf(). It's easy to read the code. 337 * If speed is not important, use snprintf(). It's easy to read the code.
338 */ 338 */
339int num_to_str(char *buf, int size, unsigned long long num) 339int num_to_str(char *buf, int size, unsigned long long num, unsigned int width)
340{ 340{
341 /* put_dec requires 2-byte alignment of the buffer. */ 341 /* put_dec requires 2-byte alignment of the buffer. */
342 char tmp[sizeof(num) * 3] __aligned(2); 342 char tmp[sizeof(num) * 3] __aligned(2);
@@ -350,11 +350,21 @@ int num_to_str(char *buf, int size, unsigned long long num)
350 len = put_dec(tmp, num) - tmp; 350 len = put_dec(tmp, num) - tmp;
351 } 351 }
352 352
353 if (len > size) 353 if (len > size || width > size)
354 return 0; 354 return 0;
355
356 if (width > len) {
357 width = width - len;
358 for (idx = 0; idx < width; idx++)
359 buf[idx] = ' ';
360 } else {
361 width = 0;
362 }
363
355 for (idx = 0; idx < len; ++idx) 364 for (idx = 0; idx < len; ++idx)
356 buf[idx] = tmp[len - idx - 1]; 365 buf[idx + width] = tmp[len - idx - 1];
357 return len; 366
367 return len + width;
358} 368}
359 369
360#define SIGN 1 /* unsigned/signed, must be 1 */ 370#define SIGN 1 /* unsigned/signed, must be 1 */
@@ -1659,19 +1669,22 @@ char *pointer_string(char *buf, char *end, const void *ptr,
1659 return number(buf, end, (unsigned long int)ptr, spec); 1669 return number(buf, end, (unsigned long int)ptr, spec);
1660} 1670}
1661 1671
1662static bool have_filled_random_ptr_key __read_mostly; 1672static DEFINE_STATIC_KEY_TRUE(not_filled_random_ptr_key);
1663static siphash_key_t ptr_key __read_mostly; 1673static siphash_key_t ptr_key __read_mostly;
1664 1674
1665static void fill_random_ptr_key(struct random_ready_callback *unused) 1675static void enable_ptr_key_workfn(struct work_struct *work)
1666{ 1676{
1667 get_random_bytes(&ptr_key, sizeof(ptr_key)); 1677 get_random_bytes(&ptr_key, sizeof(ptr_key));
1668 /* 1678 /* Needs to run from preemptible context */
1669 * have_filled_random_ptr_key==true is dependent on get_random_bytes(). 1679 static_branch_disable(&not_filled_random_ptr_key);
1670 * ptr_to_id() needs to see have_filled_random_ptr_key==true 1680}
1671 * after get_random_bytes() returns. 1681
1672 */ 1682static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn);
1673 smp_mb(); 1683
1674 WRITE_ONCE(have_filled_random_ptr_key, true); 1684static void fill_random_ptr_key(struct random_ready_callback *unused)
1685{
1686 /* This may be in an interrupt handler. */
1687 queue_work(system_unbound_wq, &enable_ptr_key_work);
1675} 1688}
1676 1689
1677static struct random_ready_callback random_ready = { 1690static struct random_ready_callback random_ready = {
@@ -1685,7 +1698,8 @@ static int __init initialize_ptr_random(void)
1685 if (!ret) { 1698 if (!ret) {
1686 return 0; 1699 return 0;
1687 } else if (ret == -EALREADY) { 1700 } else if (ret == -EALREADY) {
1688 fill_random_ptr_key(&random_ready); 1701 /* This is in preemptible context */
1702 enable_ptr_key_workfn(&enable_ptr_key_work);
1689 return 0; 1703 return 0;
1690 } 1704 }
1691 1705
@@ -1699,7 +1713,7 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec)
1699 unsigned long hashval; 1713 unsigned long hashval;
1700 const int default_width = 2 * sizeof(ptr); 1714 const int default_width = 2 * sizeof(ptr);
1701 1715
1702 if (unlikely(!have_filled_random_ptr_key)) { 1716 if (static_branch_unlikely(&not_filled_random_ptr_key)) {
1703 spec.field_width = default_width; 1717 spec.field_width = default_width;
1704 /* string length must be less than default_width */ 1718 /* string length must be less than default_width */
1705 return string(buf, end, "(ptrval)", spec); 1719 return string(buf, end, "(ptrval)", spec);
@@ -2591,6 +2605,8 @@ int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args)
2591 case 's': 2605 case 's':
2592 case 'F': 2606 case 'F':
2593 case 'f': 2607 case 'f':
2608 case 'x':
2609 case 'K':
2594 save_arg(void *); 2610 save_arg(void *);
2595 break; 2611 break;
2596 default: 2612 default:
@@ -2765,6 +2781,8 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
2765 case 's': 2781 case 's':
2766 case 'F': 2782 case 'F':
2767 case 'f': 2783 case 'f':
2784 case 'x':
2785 case 'K':
2768 process = true; 2786 process = true;
2769 break; 2787 break;
2770 default: 2788 default: