diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-30 20:25:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-30 20:25:34 -0400 |
commit | 27c1ee3f929555b71fa39ec0d81a7e7185de1b16 (patch) | |
tree | 42e40bdfe4efac660d650658019391536ce67a42 /lib/vsprintf.c | |
parent | 37cd9600a9e20359b0283983c9e3a55d84347168 (diff) | |
parent | 086ff4b3a7fb9cdf41e6a5d0ccd99b86d84633a1 (diff) |
Merge branch 'akpm' (Andrew's patch-bomb)
Merge Andrew's first set of patches:
"Non-MM patches:
- lots of misc bits
- tree-wide have_clk() cleanups
- quite a lot of printk tweaks. I draw your attention to "printk:
convert the format for KERN_<LEVEL> to a 2 byte pattern" which
looks a bit scary. But afaict it's solid.
- backlight updates
- lib/ feature work (notably the addition and use of memweight())
- checkpatch updates
- rtc updates
- nilfs updates
- fatfs updates (partial, still waiting for acks)
- kdump, proc, fork, IPC, sysctl, taskstats, pps, etc
- new fault-injection feature work"
* Merge emailed patches from Andrew Morton <akpm@linux-foundation.org>: (128 commits)
drivers/misc/lkdtm.c: fix missing allocation failure check
lib/scatterlist: do not re-write gfp_flags in __sg_alloc_table()
fault-injection: add tool to run command with failslab or fail_page_alloc
fault-injection: add selftests for cpu and memory hotplug
powerpc: pSeries reconfig notifier error injection module
memory: memory notifier error injection module
PM: PM notifier error injection module
cpu: rewrite cpu-notifier-error-inject module
fault-injection: notifier error injection
c/r: fcntl: add F_GETOWNER_UIDS option
resource: make sure requested range is included in the root range
include/linux/aio.h: cpp->C conversions
fs: cachefiles: add support for large files in filesystem caching
pps: return PTR_ERR on error in device_create
taskstats: check nla_reserve() return
sysctl: suppress kmemleak messages
ipc: use Kconfig options for __ARCH_WANT_[COMPAT_]IPC_PARSE_VERSION
ipc: compat: use signed size_t types for msgsnd and msgrcv
ipc: allow compat IPC version field parsing if !ARCH_WANT_OLD_COMPAT_IPC
ipc: add COMPAT_SHMLBA support
...
Diffstat (limited to 'lib/vsprintf.c')
-rw-r--r-- | lib/vsprintf.c | 83 |
1 files changed, 78 insertions, 5 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index c3f36d415bdf..0e337541f005 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -655,6 +655,50 @@ char *resource_string(char *buf, char *end, struct resource *res, | |||
655 | } | 655 | } |
656 | 656 | ||
657 | static noinline_for_stack | 657 | static noinline_for_stack |
658 | char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec, | ||
659 | const char *fmt) | ||
660 | { | ||
661 | int i, len = 1; /* if we pass '%ph[CDN]', field witdh remains | ||
662 | negative value, fallback to the default */ | ||
663 | char separator; | ||
664 | |||
665 | if (spec.field_width == 0) | ||
666 | /* nothing to print */ | ||
667 | return buf; | ||
668 | |||
669 | if (ZERO_OR_NULL_PTR(addr)) | ||
670 | /* NULL pointer */ | ||
671 | return string(buf, end, NULL, spec); | ||
672 | |||
673 | switch (fmt[1]) { | ||
674 | case 'C': | ||
675 | separator = ':'; | ||
676 | break; | ||
677 | case 'D': | ||
678 | separator = '-'; | ||
679 | break; | ||
680 | case 'N': | ||
681 | separator = 0; | ||
682 | break; | ||
683 | default: | ||
684 | separator = ' '; | ||
685 | break; | ||
686 | } | ||
687 | |||
688 | if (spec.field_width > 0) | ||
689 | len = min_t(int, spec.field_width, 64); | ||
690 | |||
691 | for (i = 0; i < len && buf < end - 1; i++) { | ||
692 | buf = hex_byte_pack(buf, addr[i]); | ||
693 | |||
694 | if (buf < end && separator && i != len - 1) | ||
695 | *buf++ = separator; | ||
696 | } | ||
697 | |||
698 | return buf; | ||
699 | } | ||
700 | |||
701 | static noinline_for_stack | ||
658 | char *mac_address_string(char *buf, char *end, u8 *addr, | 702 | char *mac_address_string(char *buf, char *end, u8 *addr, |
659 | struct printf_spec spec, const char *fmt) | 703 | struct printf_spec spec, const char *fmt) |
660 | { | 704 | { |
@@ -662,15 +706,28 @@ char *mac_address_string(char *buf, char *end, u8 *addr, | |||
662 | char *p = mac_addr; | 706 | char *p = mac_addr; |
663 | int i; | 707 | int i; |
664 | char separator; | 708 | char separator; |
709 | bool reversed = false; | ||
665 | 710 | ||
666 | if (fmt[1] == 'F') { /* FDDI canonical format */ | 711 | switch (fmt[1]) { |
712 | case 'F': | ||
667 | separator = '-'; | 713 | separator = '-'; |
668 | } else { | 714 | break; |
715 | |||
716 | case 'R': | ||
717 | reversed = true; | ||
718 | /* fall through */ | ||
719 | |||
720 | default: | ||
669 | separator = ':'; | 721 | separator = ':'; |
722 | break; | ||
670 | } | 723 | } |
671 | 724 | ||
672 | for (i = 0; i < 6; i++) { | 725 | for (i = 0; i < 6; i++) { |
673 | p = hex_byte_pack(p, addr[i]); | 726 | if (reversed) |
727 | p = hex_byte_pack(p, addr[5 - i]); | ||
728 | else | ||
729 | p = hex_byte_pack(p, addr[i]); | ||
730 | |||
674 | if (fmt[0] == 'M' && i != 5) | 731 | if (fmt[0] == 'M' && i != 5) |
675 | *p++ = separator; | 732 | *p++ = separator; |
676 | } | 733 | } |
@@ -933,6 +990,7 @@ int kptr_restrict __read_mostly; | |||
933 | * - 'm' For a 6-byte MAC address, it prints the hex address without colons | 990 | * - 'm' For a 6-byte MAC address, it prints the hex address without colons |
934 | * - 'MF' For a 6-byte MAC FDDI address, it prints the address | 991 | * - 'MF' For a 6-byte MAC FDDI address, it prints the address |
935 | * with a dash-separated hex notation | 992 | * with a dash-separated hex notation |
993 | * - '[mM]R For a 6-byte MAC address, Reverse order (Bluetooth) | ||
936 | * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way | 994 | * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way |
937 | * IPv4 uses dot-separated decimal without leading 0's (1.2.3.4) | 995 | * IPv4 uses dot-separated decimal without leading 0's (1.2.3.4) |
938 | * IPv6 uses colon separated network-order 16 bit hex with leading 0's | 996 | * IPv6 uses colon separated network-order 16 bit hex with leading 0's |
@@ -960,6 +1018,13 @@ int kptr_restrict __read_mostly; | |||
960 | * correctness of the format string and va_list arguments. | 1018 | * correctness of the format string and va_list arguments. |
961 | * - 'K' For a kernel pointer that should be hidden from unprivileged users | 1019 | * - 'K' For a kernel pointer that should be hidden from unprivileged users |
962 | * - 'NF' For a netdev_features_t | 1020 | * - 'NF' For a netdev_features_t |
1021 | * - 'h[CDN]' For a variable-length buffer, it prints it as a hex string with | ||
1022 | * a certain separator (' ' by default): | ||
1023 | * C colon | ||
1024 | * D dash | ||
1025 | * N no separator | ||
1026 | * The maximum supported length is 64 bytes of the input. Consider | ||
1027 | * to use print_hex_dump() for the larger input. | ||
963 | * | 1028 | * |
964 | * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 | 1029 | * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 |
965 | * function pointers are really function descriptors, which contain a | 1030 | * function pointers are really function descriptors, which contain a |
@@ -993,9 +1058,12 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
993 | case 'R': | 1058 | case 'R': |
994 | case 'r': | 1059 | case 'r': |
995 | return resource_string(buf, end, ptr, spec, fmt); | 1060 | return resource_string(buf, end, ptr, spec, fmt); |
1061 | case 'h': | ||
1062 | return hex_string(buf, end, ptr, spec, fmt); | ||
996 | case 'M': /* Colon separated: 00:01:02:03:04:05 */ | 1063 | case 'M': /* Colon separated: 00:01:02:03:04:05 */ |
997 | case 'm': /* Contiguous: 000102030405 */ | 1064 | case 'm': /* Contiguous: 000102030405 */ |
998 | /* [mM]F (FDDI, bit reversed) */ | 1065 | /* [mM]F (FDDI) */ |
1066 | /* [mM]R (Reverse order; Bluetooth) */ | ||
999 | return mac_address_string(buf, end, ptr, spec, fmt); | 1067 | return mac_address_string(buf, end, ptr, spec, fmt); |
1000 | case 'I': /* Formatted IP supported | 1068 | case 'I': /* Formatted IP supported |
1001 | * 4: 1.2.3.4 | 1069 | * 4: 1.2.3.4 |
@@ -1030,7 +1098,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
1030 | * %pK cannot be used in IRQ context because its test | 1098 | * %pK cannot be used in IRQ context because its test |
1031 | * for CAP_SYSLOG would be meaningless. | 1099 | * for CAP_SYSLOG would be meaningless. |
1032 | */ | 1100 | */ |
1033 | if (in_irq() || in_serving_softirq() || in_nmi()) { | 1101 | if (kptr_restrict && (in_irq() || in_serving_softirq() || |
1102 | in_nmi())) { | ||
1034 | if (spec.field_width == -1) | 1103 | if (spec.field_width == -1) |
1035 | spec.field_width = default_width; | 1104 | spec.field_width = default_width; |
1036 | return string(buf, end, "pK-error", spec); | 1105 | return string(buf, end, "pK-error", spec); |
@@ -1280,8 +1349,12 @@ qualifier: | |||
1280 | * %pI6c print an IPv6 address as specified by RFC 5952 | 1349 | * %pI6c print an IPv6 address as specified by RFC 5952 |
1281 | * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper | 1350 | * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper |
1282 | * case. | 1351 | * case. |
1352 | * %*ph[CDN] a variable-length hex string with a separator (supports up to 64 | ||
1353 | * bytes of the input) | ||
1283 | * %n is ignored | 1354 | * %n is ignored |
1284 | * | 1355 | * |
1356 | * ** Please update Documentation/printk-formats.txt when making changes ** | ||
1357 | * | ||
1285 | * The return value is the number of characters which would | 1358 | * The return value is the number of characters which would |
1286 | * be generated for the given input, excluding the trailing | 1359 | * be generated for the given input, excluding the trailing |
1287 | * '\0', as per ISO C99. If you want to have the exact | 1360 | * '\0', as per ISO C99. If you want to have the exact |