Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

vsprintf: Use %p4chR instead of %p4cn for reading data in reversed host ordering

The generic FourCC format always prints the data using the big endian
order. It is generic because it allows to read the data using a custom
ordering.

The current code uses "n" for reading data in the reverse host ordering.
It makes the 4 variants [hnbl] consistent with the generic printing
of IPv4 addresses.

Unfortunately, it creates confusion on big endian systems. For example,
it shows the data &(u32)0x67503030 as

%p4cn 00Pg (0x30305067)

But people expect that the ordering stays the same. The network ordering
is a big-endian ordering.

The problem is that the semantic is not the same. The modifiers affect
the output ordering of IPv4 addresses while they affect the reading order
in case of FourCC code.

Avoid the confusion by replacing the "n" modifier with "hR", aka
reverse host ordering. It is inspired by the existing %p[mM]R printf
format.

Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Closes: https://lore.kernel.org/r/CAMuHMdV9tX=TG7E_CrSF=2PY206tXf+_yYRuacG48EWEtJLo-Q@mail.gmail.com
Signed-off-by: Petr Mladek <pmladek@suse.com>
Acked-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Aditya Garg <gargaditya08@live.com>
Link: https://lore.kernel.org/r/20250428123132.578771-1-pmladek@suse.com
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>

authored by

Petr Mladek and committed by
Alyssa Rosenzweig
37eed892 f2c8f90b

+15 -10
+5 -5
Documentation/core-api/printk-formats.rst
··· 652 652 ------------------- 653 653 654 654 :: 655 - %p4c[hnlb] gP00 (0x67503030) 655 + %p4c[h[R]lb] gP00 (0x67503030) 656 656 657 657 Print a generic FourCC code, as both ASCII characters and its numerical 658 658 value as hexadecimal. ··· 660 660 The generic FourCC code is always printed in the big-endian format, 661 661 the most significant byte first. This is the opposite of V4L/DRM FourCCs. 662 662 663 - The additional ``h``, ``n``, ``l``, and ``b`` specifiers define what 663 + The additional ``h``, ``hR``, ``l``, and ``b`` specifiers define what 664 664 endianness is used to load the stored bytes. The data might be interpreted 665 - using the host byte order, network byte order, little-endian, or big-endian. 665 + using the host, reversed host byte order, little-endian, or big-endian. 666 666 667 667 Passed by reference. 668 668 669 669 Examples for a little-endian machine, given &(u32)0x67503030:: 670 670 671 671 %p4ch gP00 (0x67503030) 672 - %p4cn 00Pg (0x30305067) 672 + %p4chR 00Pg (0x30305067) 673 673 %p4cl gP00 (0x67503030) 674 674 %p4cb 00Pg (0x30305067) 675 675 676 676 Examples for a big-endian machine, given &(u32)0x67503030:: 677 677 678 678 %p4ch gP00 (0x67503030) 679 - %p4cn 00Pg (0x30305067) 679 + %p4chR 00Pg (0x30305067) 680 680 %p4cl 00Pg (0x30305067) 681 681 %p4cb gP00 (0x67503030) 682 682
+2 -2
lib/tests/printf_kunit.c
··· 726 726 static const struct fourcc_struct try_ch[] = { 727 727 { 0x41424344, "ABCD (0x41424344)", }, 728 728 }; 729 - static const struct fourcc_struct try_cn[] = { 729 + static const struct fourcc_struct try_chR[] = { 730 730 { 0x41424344, "DCBA (0x44434241)", }, 731 731 }; 732 732 static const struct fourcc_struct try_cl[] = { ··· 738 738 739 739 fourcc_pointer_test(kunittest, try_cc, ARRAY_SIZE(try_cc), "%p4cc"); 740 740 fourcc_pointer_test(kunittest, try_ch, ARRAY_SIZE(try_ch), "%p4ch"); 741 - fourcc_pointer_test(kunittest, try_cn, ARRAY_SIZE(try_cn), "%p4cn"); 741 + fourcc_pointer_test(kunittest, try_chR, ARRAY_SIZE(try_chR), "%p4chR"); 742 742 fourcc_pointer_test(kunittest, try_cl, ARRAY_SIZE(try_cl), "%p4cl"); 743 743 fourcc_pointer_test(kunittest, try_cb, ARRAY_SIZE(try_cb), "%p4cb"); 744 744 }
+8 -3
lib/vsprintf.c
··· 1805 1805 orig = get_unaligned(fourcc); 1806 1806 switch (fmt[2]) { 1807 1807 case 'h': 1808 - break; 1809 - case 'n': 1810 - orig = swab32(orig); 1808 + if (fmt[3] == 'R') 1809 + orig = swab32(orig); 1811 1810 break; 1812 1811 case 'l': 1813 1812 orig = (__force u32)cpu_to_le32(orig); ··· 2396 2397 * read the documentation (path below) first. 2397 2398 * - 'NF' For a netdev_features_t 2398 2399 * - '4cc' V4L2 or DRM FourCC code, with endianness and raw numerical value. 2400 + * - '4c[h[R]lb]' For generic FourCC code with raw numerical value. Both are 2401 + * displayed in the big-endian format. This is the opposite of V4L2 or 2402 + * DRM FourCCs. 2403 + * The additional specifiers define what endianness is used to load 2404 + * the stored bytes. The data might be interpreted using the host, 2405 + * reversed host byte order, little-endian, or big-endian. 2399 2406 * - 'h[CDN]' For a variable-length buffer, it prints it as a hex string with 2400 2407 * a certain separator (' ' by default): 2401 2408 * C colon