109c434b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2707cc728SRasmus Villemoes /* 3707cc728SRasmus Villemoes * Test cases for printf facility. 4707cc728SRasmus Villemoes */ 5707cc728SRasmus Villemoes 6707cc728SRasmus Villemoes #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 7707cc728SRasmus Villemoes 8707cc728SRasmus Villemoes #include <linux/init.h> 9707cc728SRasmus Villemoes #include <linux/kernel.h> 10707cc728SRasmus Villemoes #include <linux/module.h> 11707cc728SRasmus Villemoes #include <linux/printk.h> 12707cc728SRasmus Villemoes #include <linux/random.h> 134d42c447SAndy Shevchenko #include <linux/rtc.h> 14707cc728SRasmus Villemoes #include <linux/slab.h> 15707cc728SRasmus Villemoes #include <linux/string.h> 16707cc728SRasmus Villemoes 17857cca4dSRasmus Villemoes #include <linux/bitmap.h> 18251c7234SRasmus Villemoes #include <linux/dcache.h> 19707cc728SRasmus Villemoes #include <linux/socket.h> 20707cc728SRasmus Villemoes #include <linux/in.h> 21707cc728SRasmus Villemoes 22edf14cdbSVlastimil Babka #include <linux/gfp.h> 23edf14cdbSVlastimil Babka #include <linux/mm.h> 24edf14cdbSVlastimil Babka 25f1ce39dfSSakari Ailus #include <linux/property.h> 26f1ce39dfSSakari Ailus 276b1a4d5bSTobin C. Harding #include "../tools/testing/selftests/kselftest_module.h" 286b1a4d5bSTobin C. Harding 29707cc728SRasmus Villemoes #define BUF_SIZE 256 30331e4debSRasmus Villemoes #define PAD_SIZE 16 31707cc728SRasmus Villemoes #define FILL_CHAR '$' 32707cc728SRasmus Villemoes 33*4e89a787STimur Tabi KSTM_MODULE_GLOBALS(); 34*4e89a787STimur Tabi 35707cc728SRasmus Villemoes static char *test_buffer __initdata; 36331e4debSRasmus Villemoes static char *alloced_buffer __initdata; 37707cc728SRasmus Villemoes 38707cc728SRasmus Villemoes static int __printf(4, 0) __init 39707cc728SRasmus Villemoes do_test(int bufsize, const char *expect, int elen, 40707cc728SRasmus Villemoes const char *fmt, va_list ap) 41707cc728SRasmus Villemoes { 42707cc728SRasmus Villemoes va_list aq; 43707cc728SRasmus Villemoes int ret, written; 44707cc728SRasmus Villemoes 45707cc728SRasmus Villemoes total_tests++; 46707cc728SRasmus Villemoes 47331e4debSRasmus Villemoes memset(alloced_buffer, FILL_CHAR, BUF_SIZE + 2*PAD_SIZE); 48707cc728SRasmus Villemoes va_copy(aq, ap); 49707cc728SRasmus Villemoes ret = vsnprintf(test_buffer, bufsize, fmt, aq); 50707cc728SRasmus Villemoes va_end(aq); 51707cc728SRasmus Villemoes 52707cc728SRasmus Villemoes if (ret != elen) { 53707cc728SRasmus Villemoes pr_warn("vsnprintf(buf, %d, \"%s\", ...) returned %d, expected %d\n", 54707cc728SRasmus Villemoes bufsize, fmt, ret, elen); 55707cc728SRasmus Villemoes return 1; 56707cc728SRasmus Villemoes } 57707cc728SRasmus Villemoes 58331e4debSRasmus Villemoes if (memchr_inv(alloced_buffer, FILL_CHAR, PAD_SIZE)) { 59331e4debSRasmus Villemoes pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote before buffer\n", bufsize, fmt); 60331e4debSRasmus Villemoes return 1; 61331e4debSRasmus Villemoes } 62331e4debSRasmus Villemoes 63707cc728SRasmus Villemoes if (!bufsize) { 64331e4debSRasmus Villemoes if (memchr_inv(test_buffer, FILL_CHAR, BUF_SIZE + PAD_SIZE)) { 65707cc728SRasmus Villemoes pr_warn("vsnprintf(buf, 0, \"%s\", ...) wrote to buffer\n", 66707cc728SRasmus Villemoes fmt); 67707cc728SRasmus Villemoes return 1; 68707cc728SRasmus Villemoes } 69707cc728SRasmus Villemoes return 0; 70707cc728SRasmus Villemoes } 71707cc728SRasmus Villemoes 72707cc728SRasmus Villemoes written = min(bufsize-1, elen); 73707cc728SRasmus Villemoes if (test_buffer[written]) { 74707cc728SRasmus Villemoes pr_warn("vsnprintf(buf, %d, \"%s\", ...) did not nul-terminate buffer\n", 75707cc728SRasmus Villemoes bufsize, fmt); 76707cc728SRasmus Villemoes return 1; 77707cc728SRasmus Villemoes } 78707cc728SRasmus Villemoes 79331e4debSRasmus Villemoes if (memchr_inv(test_buffer + written + 1, FILL_CHAR, BUF_SIZE + PAD_SIZE - (written + 1))) { 80331e4debSRasmus Villemoes pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote beyond the nul-terminator\n", 81331e4debSRasmus Villemoes bufsize, fmt); 82331e4debSRasmus Villemoes return 1; 83331e4debSRasmus Villemoes } 84331e4debSRasmus Villemoes 85707cc728SRasmus Villemoes if (memcmp(test_buffer, expect, written)) { 86707cc728SRasmus Villemoes pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote '%s', expected '%.*s'\n", 87707cc728SRasmus Villemoes bufsize, fmt, test_buffer, written, expect); 88707cc728SRasmus Villemoes return 1; 89707cc728SRasmus Villemoes } 90707cc728SRasmus Villemoes return 0; 91707cc728SRasmus Villemoes } 92707cc728SRasmus Villemoes 93707cc728SRasmus Villemoes static void __printf(3, 4) __init 94707cc728SRasmus Villemoes __test(const char *expect, int elen, const char *fmt, ...) 95707cc728SRasmus Villemoes { 96707cc728SRasmus Villemoes va_list ap; 97707cc728SRasmus Villemoes int rand; 98707cc728SRasmus Villemoes char *p; 99707cc728SRasmus Villemoes 100fd0515d5SRasmus Villemoes if (elen >= BUF_SIZE) { 101fd0515d5SRasmus Villemoes pr_err("error in test suite: expected output length %d too long. Format was '%s'.\n", 102fd0515d5SRasmus Villemoes elen, fmt); 103fd0515d5SRasmus Villemoes failed_tests++; 104fd0515d5SRasmus Villemoes return; 105fd0515d5SRasmus Villemoes } 106707cc728SRasmus Villemoes 107707cc728SRasmus Villemoes va_start(ap, fmt); 108707cc728SRasmus Villemoes 109707cc728SRasmus Villemoes /* 110707cc728SRasmus Villemoes * Every fmt+args is subjected to four tests: Three where we 111707cc728SRasmus Villemoes * tell vsnprintf varying buffer sizes (plenty, not quite 112707cc728SRasmus Villemoes * enough and 0), and then we also test that kvasprintf would 113707cc728SRasmus Villemoes * be able to print it as expected. 114707cc728SRasmus Villemoes */ 115707cc728SRasmus Villemoes failed_tests += do_test(BUF_SIZE, expect, elen, fmt, ap); 116707cc728SRasmus Villemoes rand = 1 + prandom_u32_max(elen+1); 117707cc728SRasmus Villemoes /* Since elen < BUF_SIZE, we have 1 <= rand <= BUF_SIZE. */ 118707cc728SRasmus Villemoes failed_tests += do_test(rand, expect, elen, fmt, ap); 119707cc728SRasmus Villemoes failed_tests += do_test(0, expect, elen, fmt, ap); 120707cc728SRasmus Villemoes 121707cc728SRasmus Villemoes p = kvasprintf(GFP_KERNEL, fmt, ap); 122707cc728SRasmus Villemoes if (p) { 123b79a7db3SRasmus Villemoes total_tests++; 124707cc728SRasmus Villemoes if (memcmp(p, expect, elen+1)) { 125707cc728SRasmus Villemoes pr_warn("kvasprintf(..., \"%s\", ...) returned '%s', expected '%s'\n", 126707cc728SRasmus Villemoes fmt, p, expect); 127707cc728SRasmus Villemoes failed_tests++; 128707cc728SRasmus Villemoes } 129707cc728SRasmus Villemoes kfree(p); 130707cc728SRasmus Villemoes } 131707cc728SRasmus Villemoes va_end(ap); 132707cc728SRasmus Villemoes } 133707cc728SRasmus Villemoes 134707cc728SRasmus Villemoes #define test(expect, fmt, ...) \ 135707cc728SRasmus Villemoes __test(expect, strlen(expect), fmt, ##__VA_ARGS__) 136707cc728SRasmus Villemoes 137707cc728SRasmus Villemoes static void __init 138707cc728SRasmus Villemoes test_basic(void) 139707cc728SRasmus Villemoes { 140707cc728SRasmus Villemoes /* Work around annoying "warning: zero-length gnu_printf format string". */ 141707cc728SRasmus Villemoes char nul = '\0'; 142707cc728SRasmus Villemoes 143707cc728SRasmus Villemoes test("", &nul); 144707cc728SRasmus Villemoes test("100%", "100%%"); 145707cc728SRasmus Villemoes test("xxx%yyy", "xxx%cyyy", '%'); 146707cc728SRasmus Villemoes __test("xxx\0yyy", 7, "xxx%cyyy", '\0'); 147707cc728SRasmus Villemoes } 148707cc728SRasmus Villemoes 149707cc728SRasmus Villemoes static void __init 150707cc728SRasmus Villemoes test_number(void) 151707cc728SRasmus Villemoes { 152707cc728SRasmus Villemoes test("0x1234abcd ", "%#-12x", 0x1234abcd); 153707cc728SRasmus Villemoes test(" 0x1234abcd", "%#12x", 0x1234abcd); 154707cc728SRasmus Villemoes test("0|001| 12|+123| 1234|-123|-1234", "%d|%03d|%3d|%+d|% d|%+d|% d", 0, 1, 12, 123, 1234, -123, -1234); 1551ca8e8ebSRasmus Villemoes test("0|1|1|128|255", "%hhu|%hhu|%hhu|%hhu|%hhu", 0, 1, 257, 128, -1); 1561ca8e8ebSRasmus Villemoes test("0|1|1|-128|-1", "%hhd|%hhd|%hhd|%hhd|%hhd", 0, 1, 257, 128, -1); 1571ca8e8ebSRasmus Villemoes test("2015122420151225", "%ho%ho%#ho", 1037, 5282, -11627); 1581ca8e8ebSRasmus Villemoes /* 1591ca8e8ebSRasmus Villemoes * POSIX/C99: »The result of converting zero with an explicit 1601ca8e8ebSRasmus Villemoes * precision of zero shall be no characters.« Hence the output 1611ca8e8ebSRasmus Villemoes * from the below test should really be "00|0||| ". However, 1621ca8e8ebSRasmus Villemoes * the kernel's printf also produces a single 0 in that 1631ca8e8ebSRasmus Villemoes * case. This test case simply documents the current 1641ca8e8ebSRasmus Villemoes * behaviour. 1651ca8e8ebSRasmus Villemoes */ 1661ca8e8ebSRasmus Villemoes test("00|0|0|0|0", "%.2d|%.1d|%.0d|%.*d|%1.0d", 0, 0, 0, 0, 0, 0); 1671ca8e8ebSRasmus Villemoes #ifndef __CHAR_UNSIGNED__ 1681ca8e8ebSRasmus Villemoes { 1691ca8e8ebSRasmus Villemoes /* 1701ca8e8ebSRasmus Villemoes * Passing a 'char' to a %02x specifier doesn't do 1711ca8e8ebSRasmus Villemoes * what was presumably the intention when char is 1721ca8e8ebSRasmus Villemoes * signed and the value is negative. One must either & 1731ca8e8ebSRasmus Villemoes * with 0xff or cast to u8. 1741ca8e8ebSRasmus Villemoes */ 1751ca8e8ebSRasmus Villemoes char val = -16; 1761ca8e8ebSRasmus Villemoes test("0xfffffff0|0xf0|0xf0", "%#02x|%#02x|%#02x", val, val & 0xff, (u8)val); 1771ca8e8ebSRasmus Villemoes } 1781ca8e8ebSRasmus Villemoes #endif 179707cc728SRasmus Villemoes } 180707cc728SRasmus Villemoes 181707cc728SRasmus Villemoes static void __init 182707cc728SRasmus Villemoes test_string(void) 183707cc728SRasmus Villemoes { 184707cc728SRasmus Villemoes test("", "%s%.0s", "", "123"); 185707cc728SRasmus Villemoes test("ABCD|abc|123", "%s|%.3s|%.*s", "ABCD", "abcdef", 3, "123456"); 186707cc728SRasmus Villemoes test("1 | 2|3 | 4|5 ", "%-3s|%3s|%-*s|%*s|%*s", "1", "2", 3, "3", 3, "4", -3, "5"); 187f176eb4cSRasmus Villemoes test("1234 ", "%-10.4s", "123456"); 188f176eb4cSRasmus Villemoes test(" 1234", "%10.4s", "123456"); 189707cc728SRasmus Villemoes /* 190f176eb4cSRasmus Villemoes * POSIX and C99 say that a negative precision (which is only 191f176eb4cSRasmus Villemoes * possible to pass via a * argument) should be treated as if 192f176eb4cSRasmus Villemoes * the precision wasn't present, and that if the precision is 193f176eb4cSRasmus Villemoes * omitted (as in %.s), the precision should be taken to be 194f176eb4cSRasmus Villemoes * 0. However, the kernel's printf behave exactly opposite, 195f176eb4cSRasmus Villemoes * treating a negative precision as 0 and treating an omitted 196f176eb4cSRasmus Villemoes * precision specifier as if no precision was given. 197f176eb4cSRasmus Villemoes * 198f176eb4cSRasmus Villemoes * These test cases document the current behaviour; should 199f176eb4cSRasmus Villemoes * anyone ever feel the need to follow the standards more 200f176eb4cSRasmus Villemoes * closely, this can be revisited. 201707cc728SRasmus Villemoes */ 202f176eb4cSRasmus Villemoes test(" ", "%4.*s", -5, "123456"); 203f176eb4cSRasmus Villemoes test("123456", "%.s", "123456"); 204707cc728SRasmus Villemoes test("a||", "%.s|%.0s|%.*s", "a", "b", 0, "c"); 205707cc728SRasmus Villemoes test("a | | ", "%-3.s|%-3.0s|%-3.*s", "a", "b", 0, "c"); 206707cc728SRasmus Villemoes } 207707cc728SRasmus Villemoes 208ad67b74dSTobin C. Harding #define PLAIN_BUF_SIZE 64 /* leave some space so we don't oops */ 209ad67b74dSTobin C. Harding 210ad67b74dSTobin C. Harding #if BITS_PER_LONG == 64 211ad67b74dSTobin C. Harding 212ad67b74dSTobin C. Harding #define PTR_WIDTH 16 213c604b407SAndy Shevchenko #define PTR ((void *)0xffff0123456789abUL) 214ad67b74dSTobin C. Harding #define PTR_STR "ffff0123456789ab" 215ce041c43SThierry Escande #define PTR_VAL_NO_CRNG "(____ptrval____)" 216ad67b74dSTobin C. Harding #define ZEROS "00000000" /* hex 32 zero bits */ 2177bd57fbcSIlya Dryomov #define ONES "ffffffff" /* hex 32 one bits */ 218ad67b74dSTobin C. Harding 219ad67b74dSTobin C. Harding static int __init 220ad67b74dSTobin C. Harding plain_format(void) 221ad67b74dSTobin C. Harding { 222ad67b74dSTobin C. Harding char buf[PLAIN_BUF_SIZE]; 223ad67b74dSTobin C. Harding int nchars; 224ad67b74dSTobin C. Harding 225ad67b74dSTobin C. Harding nchars = snprintf(buf, PLAIN_BUF_SIZE, "%p", PTR); 226ad67b74dSTobin C. Harding 227ce041c43SThierry Escande if (nchars != PTR_WIDTH) 228ce041c43SThierry Escande return -1; 229ce041c43SThierry Escande 230ce041c43SThierry Escande if (strncmp(buf, PTR_VAL_NO_CRNG, PTR_WIDTH) == 0) { 231ce041c43SThierry Escande pr_warn("crng possibly not yet initialized. plain 'p' buffer contains \"%s\"", 232ce041c43SThierry Escande PTR_VAL_NO_CRNG); 233ce041c43SThierry Escande return 0; 234ce041c43SThierry Escande } 235ce041c43SThierry Escande 236ce041c43SThierry Escande if (strncmp(buf, ZEROS, strlen(ZEROS)) != 0) 237ad67b74dSTobin C. Harding return -1; 238ad67b74dSTobin C. Harding 239ad67b74dSTobin C. Harding return 0; 240ad67b74dSTobin C. Harding } 241ad67b74dSTobin C. Harding 242ad67b74dSTobin C. Harding #else 243ad67b74dSTobin C. Harding 244ad67b74dSTobin C. Harding #define PTR_WIDTH 8 245ad67b74dSTobin C. Harding #define PTR ((void *)0x456789ab) 246ad67b74dSTobin C. Harding #define PTR_STR "456789ab" 247ce041c43SThierry Escande #define PTR_VAL_NO_CRNG "(ptrval)" 2483e5903ebSPetr Mladek #define ZEROS "" 2497bd57fbcSIlya Dryomov #define ONES "" 250ad67b74dSTobin C. Harding 251ad67b74dSTobin C. Harding static int __init 252ad67b74dSTobin C. Harding plain_format(void) 253ad67b74dSTobin C. Harding { 254ad67b74dSTobin C. Harding /* Format is implicitly tested for 32 bit machines by plain_hash() */ 255ad67b74dSTobin C. Harding return 0; 256ad67b74dSTobin C. Harding } 257ad67b74dSTobin C. Harding 258ad67b74dSTobin C. Harding #endif /* BITS_PER_LONG == 64 */ 259ad67b74dSTobin C. Harding 260ad67b74dSTobin C. Harding static int __init 2614d42c447SAndy Shevchenko plain_hash_to_buffer(const void *p, char *buf, size_t len) 262ad67b74dSTobin C. Harding { 263ad67b74dSTobin C. Harding int nchars; 264ad67b74dSTobin C. Harding 2654d42c447SAndy Shevchenko nchars = snprintf(buf, len, "%p", p); 266ad67b74dSTobin C. Harding 267ce041c43SThierry Escande if (nchars != PTR_WIDTH) 268ce041c43SThierry Escande return -1; 269ce041c43SThierry Escande 270ce041c43SThierry Escande if (strncmp(buf, PTR_VAL_NO_CRNG, PTR_WIDTH) == 0) { 271ce041c43SThierry Escande pr_warn("crng possibly not yet initialized. plain 'p' buffer contains \"%s\"", 272ce041c43SThierry Escande PTR_VAL_NO_CRNG); 273ce041c43SThierry Escande return 0; 274ce041c43SThierry Escande } 275ce041c43SThierry Escande 2764d42c447SAndy Shevchenko return 0; 2774d42c447SAndy Shevchenko } 2784d42c447SAndy Shevchenko 2794d42c447SAndy Shevchenko static int __init 2804d42c447SAndy Shevchenko plain_hash(void) 2814d42c447SAndy Shevchenko { 2824d42c447SAndy Shevchenko char buf[PLAIN_BUF_SIZE]; 2834d42c447SAndy Shevchenko int ret; 2844d42c447SAndy Shevchenko 2854d42c447SAndy Shevchenko ret = plain_hash_to_buffer(PTR, buf, PLAIN_BUF_SIZE); 2864d42c447SAndy Shevchenko if (ret) 2874d42c447SAndy Shevchenko return ret; 2884d42c447SAndy Shevchenko 289ce041c43SThierry Escande if (strncmp(buf, PTR_STR, PTR_WIDTH) == 0) 290ad67b74dSTobin C. Harding return -1; 291ad67b74dSTobin C. Harding 292ad67b74dSTobin C. Harding return 0; 293ad67b74dSTobin C. Harding } 294ad67b74dSTobin C. Harding 295ad67b74dSTobin C. Harding /* 296ad67b74dSTobin C. Harding * We can't use test() to test %p because we don't know what output to expect 297ad67b74dSTobin C. Harding * after an address is hashed. 298ad67b74dSTobin C. Harding */ 299707cc728SRasmus Villemoes static void __init 300707cc728SRasmus Villemoes plain(void) 301707cc728SRasmus Villemoes { 302ad67b74dSTobin C. Harding int err; 303707cc728SRasmus Villemoes 304ad67b74dSTobin C. Harding err = plain_hash(); 305ad67b74dSTobin C. Harding if (err) { 306ad67b74dSTobin C. Harding pr_warn("plain 'p' does not appear to be hashed\n"); 307ad67b74dSTobin C. Harding failed_tests++; 308ad67b74dSTobin C. Harding return; 309ad67b74dSTobin C. Harding } 310ad67b74dSTobin C. Harding 311ad67b74dSTobin C. Harding err = plain_format(); 312ad67b74dSTobin C. Harding if (err) { 313ad67b74dSTobin C. Harding pr_warn("hashing plain 'p' has unexpected format\n"); 314ad67b74dSTobin C. Harding failed_tests++; 315ad67b74dSTobin C. Harding } 316707cc728SRasmus Villemoes } 317707cc728SRasmus Villemoes 318707cc728SRasmus Villemoes static void __init 3194d42c447SAndy Shevchenko test_hashed(const char *fmt, const void *p) 3204d42c447SAndy Shevchenko { 3214d42c447SAndy Shevchenko char buf[PLAIN_BUF_SIZE]; 3224d42c447SAndy Shevchenko int ret; 3234d42c447SAndy Shevchenko 3244d42c447SAndy Shevchenko /* 3254d42c447SAndy Shevchenko * No need to increase failed test counter since this is assumed 3264d42c447SAndy Shevchenko * to be called after plain(). 3274d42c447SAndy Shevchenko */ 3284d42c447SAndy Shevchenko ret = plain_hash_to_buffer(p, buf, PLAIN_BUF_SIZE); 3294d42c447SAndy Shevchenko if (ret) 3304d42c447SAndy Shevchenko return; 3314d42c447SAndy Shevchenko 3324d42c447SAndy Shevchenko test(buf, fmt, p); 3334d42c447SAndy Shevchenko } 3344d42c447SAndy Shevchenko 3357bd57fbcSIlya Dryomov /* 3367bd57fbcSIlya Dryomov * NULL pointers aren't hashed. 3377bd57fbcSIlya Dryomov */ 3384d42c447SAndy Shevchenko static void __init 3393e5903ebSPetr Mladek null_pointer(void) 3403e5903ebSPetr Mladek { 3417bd57fbcSIlya Dryomov test(ZEROS "00000000", "%p", NULL); 3423e5903ebSPetr Mladek test(ZEROS "00000000", "%px", NULL); 3433e5903ebSPetr Mladek test("(null)", "%pE", NULL); 3443e5903ebSPetr Mladek } 3453e5903ebSPetr Mladek 3467bd57fbcSIlya Dryomov /* 3477bd57fbcSIlya Dryomov * Error pointers aren't hashed. 3487bd57fbcSIlya Dryomov */ 3497bd57fbcSIlya Dryomov static void __init 3507bd57fbcSIlya Dryomov error_pointer(void) 3517bd57fbcSIlya Dryomov { 3527bd57fbcSIlya Dryomov test(ONES "fffffff5", "%p", ERR_PTR(-11)); 3537bd57fbcSIlya Dryomov test(ONES "fffffff5", "%px", ERR_PTR(-11)); 3547bd57fbcSIlya Dryomov test("(efault)", "%pE", ERR_PTR(-11)); 3557bd57fbcSIlya Dryomov } 3567bd57fbcSIlya Dryomov 3573e5903ebSPetr Mladek #define PTR_INVALID ((void *)0x000000ab) 3583e5903ebSPetr Mladek 3593e5903ebSPetr Mladek static void __init 3603e5903ebSPetr Mladek invalid_pointer(void) 3613e5903ebSPetr Mladek { 3623e5903ebSPetr Mladek test_hashed("%p", PTR_INVALID); 3633e5903ebSPetr Mladek test(ZEROS "000000ab", "%px", PTR_INVALID); 3643e5903ebSPetr Mladek test("(efault)", "%pE", PTR_INVALID); 3653e5903ebSPetr Mladek } 3663e5903ebSPetr Mladek 3673e5903ebSPetr Mladek static void __init 368707cc728SRasmus Villemoes symbol_ptr(void) 369707cc728SRasmus Villemoes { 370707cc728SRasmus Villemoes } 371707cc728SRasmus Villemoes 372707cc728SRasmus Villemoes static void __init 373707cc728SRasmus Villemoes kernel_ptr(void) 374707cc728SRasmus Villemoes { 375ad67b74dSTobin C. Harding /* We can't test this without access to kptr_restrict. */ 376707cc728SRasmus Villemoes } 377707cc728SRasmus Villemoes 378707cc728SRasmus Villemoes static void __init 379707cc728SRasmus Villemoes struct_resource(void) 380707cc728SRasmus Villemoes { 381707cc728SRasmus Villemoes } 382707cc728SRasmus Villemoes 383707cc728SRasmus Villemoes static void __init 384707cc728SRasmus Villemoes addr(void) 385707cc728SRasmus Villemoes { 386707cc728SRasmus Villemoes } 387707cc728SRasmus Villemoes 388707cc728SRasmus Villemoes static void __init 389707cc728SRasmus Villemoes escaped_str(void) 390707cc728SRasmus Villemoes { 391707cc728SRasmus Villemoes } 392707cc728SRasmus Villemoes 393707cc728SRasmus Villemoes static void __init 394707cc728SRasmus Villemoes hex_string(void) 395707cc728SRasmus Villemoes { 396707cc728SRasmus Villemoes const char buf[3] = {0xc0, 0xff, 0xee}; 397707cc728SRasmus Villemoes 398707cc728SRasmus Villemoes test("c0 ff ee|c0:ff:ee|c0-ff-ee|c0ffee", 399707cc728SRasmus Villemoes "%3ph|%3phC|%3phD|%3phN", buf, buf, buf, buf); 400707cc728SRasmus Villemoes test("c0 ff ee|c0:ff:ee|c0-ff-ee|c0ffee", 401707cc728SRasmus Villemoes "%*ph|%*phC|%*phD|%*phN", 3, buf, 3, buf, 3, buf, 3, buf); 402707cc728SRasmus Villemoes } 403707cc728SRasmus Villemoes 404707cc728SRasmus Villemoes static void __init 405707cc728SRasmus Villemoes mac(void) 406707cc728SRasmus Villemoes { 407707cc728SRasmus Villemoes const u8 addr[6] = {0x2d, 0x48, 0xd6, 0xfc, 0x7a, 0x05}; 408707cc728SRasmus Villemoes 409707cc728SRasmus Villemoes test("2d:48:d6:fc:7a:05", "%pM", addr); 410707cc728SRasmus Villemoes test("05:7a:fc:d6:48:2d", "%pMR", addr); 411707cc728SRasmus Villemoes test("2d-48-d6-fc-7a-05", "%pMF", addr); 412707cc728SRasmus Villemoes test("2d48d6fc7a05", "%pm", addr); 413707cc728SRasmus Villemoes test("057afcd6482d", "%pmR", addr); 414707cc728SRasmus Villemoes } 415707cc728SRasmus Villemoes 416707cc728SRasmus Villemoes static void __init 417707cc728SRasmus Villemoes ip4(void) 418707cc728SRasmus Villemoes { 419707cc728SRasmus Villemoes struct sockaddr_in sa; 420707cc728SRasmus Villemoes 421707cc728SRasmus Villemoes sa.sin_family = AF_INET; 422707cc728SRasmus Villemoes sa.sin_port = cpu_to_be16(12345); 423707cc728SRasmus Villemoes sa.sin_addr.s_addr = cpu_to_be32(0x7f000001); 424707cc728SRasmus Villemoes 425707cc728SRasmus Villemoes test("127.000.000.001|127.0.0.1", "%pi4|%pI4", &sa.sin_addr, &sa.sin_addr); 426707cc728SRasmus Villemoes test("127.000.000.001|127.0.0.1", "%piS|%pIS", &sa, &sa); 427707cc728SRasmus Villemoes sa.sin_addr.s_addr = cpu_to_be32(0x01020304); 428707cc728SRasmus Villemoes test("001.002.003.004:12345|1.2.3.4:12345", "%piSp|%pISp", &sa, &sa); 429707cc728SRasmus Villemoes } 430707cc728SRasmus Villemoes 431707cc728SRasmus Villemoes static void __init 432707cc728SRasmus Villemoes ip6(void) 433707cc728SRasmus Villemoes { 434707cc728SRasmus Villemoes } 435707cc728SRasmus Villemoes 436707cc728SRasmus Villemoes static void __init 437707cc728SRasmus Villemoes ip(void) 438707cc728SRasmus Villemoes { 439707cc728SRasmus Villemoes ip4(); 440707cc728SRasmus Villemoes ip6(); 441707cc728SRasmus Villemoes } 442707cc728SRasmus Villemoes 443707cc728SRasmus Villemoes static void __init 444707cc728SRasmus Villemoes uuid(void) 445707cc728SRasmus Villemoes { 446707cc728SRasmus Villemoes const char uuid[16] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 447707cc728SRasmus Villemoes 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}; 448707cc728SRasmus Villemoes 449707cc728SRasmus Villemoes test("00010203-0405-0607-0809-0a0b0c0d0e0f", "%pUb", uuid); 450707cc728SRasmus Villemoes test("00010203-0405-0607-0809-0A0B0C0D0E0F", "%pUB", uuid); 451707cc728SRasmus Villemoes test("03020100-0504-0706-0809-0a0b0c0d0e0f", "%pUl", uuid); 452707cc728SRasmus Villemoes test("03020100-0504-0706-0809-0A0B0C0D0E0F", "%pUL", uuid); 453707cc728SRasmus Villemoes } 454707cc728SRasmus Villemoes 455251c7234SRasmus Villemoes static struct dentry test_dentry[4] __initdata = { 456251c7234SRasmus Villemoes { .d_parent = &test_dentry[0], 457251c7234SRasmus Villemoes .d_name = QSTR_INIT(test_dentry[0].d_iname, 3), 458251c7234SRasmus Villemoes .d_iname = "foo" }, 459251c7234SRasmus Villemoes { .d_parent = &test_dentry[0], 460251c7234SRasmus Villemoes .d_name = QSTR_INIT(test_dentry[1].d_iname, 5), 461251c7234SRasmus Villemoes .d_iname = "bravo" }, 462251c7234SRasmus Villemoes { .d_parent = &test_dentry[1], 463251c7234SRasmus Villemoes .d_name = QSTR_INIT(test_dentry[2].d_iname, 4), 464251c7234SRasmus Villemoes .d_iname = "alfa" }, 465251c7234SRasmus Villemoes { .d_parent = &test_dentry[2], 466251c7234SRasmus Villemoes .d_name = QSTR_INIT(test_dentry[3].d_iname, 5), 467251c7234SRasmus Villemoes .d_iname = "romeo" }, 468251c7234SRasmus Villemoes }; 469251c7234SRasmus Villemoes 470707cc728SRasmus Villemoes static void __init 471707cc728SRasmus Villemoes dentry(void) 472707cc728SRasmus Villemoes { 473251c7234SRasmus Villemoes test("foo", "%pd", &test_dentry[0]); 474251c7234SRasmus Villemoes test("foo", "%pd2", &test_dentry[0]); 475251c7234SRasmus Villemoes 476cf6b7921SJia He test("(null)", "%pd", NULL); 477cf6b7921SJia He test("(efault)", "%pd", PTR_INVALID); 478cf6b7921SJia He test("(null)", "%pD", NULL); 479cf6b7921SJia He test("(efault)", "%pD", PTR_INVALID); 480cf6b7921SJia He 481251c7234SRasmus Villemoes test("romeo", "%pd", &test_dentry[3]); 482251c7234SRasmus Villemoes test("alfa/romeo", "%pd2", &test_dentry[3]); 483251c7234SRasmus Villemoes test("bravo/alfa/romeo", "%pd3", &test_dentry[3]); 484251c7234SRasmus Villemoes test("/bravo/alfa/romeo", "%pd4", &test_dentry[3]); 485251c7234SRasmus Villemoes test("/bravo/alfa", "%pd4", &test_dentry[2]); 486251c7234SRasmus Villemoes 487251c7234SRasmus Villemoes test("bravo/alfa |bravo/alfa ", "%-12pd2|%*pd2", &test_dentry[2], -12, &test_dentry[2]); 488251c7234SRasmus Villemoes test(" bravo/alfa| bravo/alfa", "%12pd2|%*pd2", &test_dentry[2], 12, &test_dentry[2]); 489707cc728SRasmus Villemoes } 490707cc728SRasmus Villemoes 491707cc728SRasmus Villemoes static void __init 492707cc728SRasmus Villemoes struct_va_format(void) 493707cc728SRasmus Villemoes { 494707cc728SRasmus Villemoes } 495707cc728SRasmus Villemoes 496707cc728SRasmus Villemoes static void __init 4977daac5b2SAndy Shevchenko time_and_date(void) 4984d42c447SAndy Shevchenko { 4994d42c447SAndy Shevchenko /* 1543210543 */ 5004d42c447SAndy Shevchenko const struct rtc_time tm = { 5014d42c447SAndy Shevchenko .tm_sec = 43, 5024d42c447SAndy Shevchenko .tm_min = 35, 5034d42c447SAndy Shevchenko .tm_hour = 5, 5044d42c447SAndy Shevchenko .tm_mday = 26, 5054d42c447SAndy Shevchenko .tm_mon = 10, 5064d42c447SAndy Shevchenko .tm_year = 118, 5074d42c447SAndy Shevchenko }; 5087daac5b2SAndy Shevchenko /* 2019-01-04T15:32:23 */ 5097daac5b2SAndy Shevchenko time64_t t = 1546615943; 5104d42c447SAndy Shevchenko 5117daac5b2SAndy Shevchenko test("(%pt?)", "%pt", &tm); 5124d42c447SAndy Shevchenko test("2018-11-26T05:35:43", "%ptR", &tm); 5134d42c447SAndy Shevchenko test("0118-10-26T05:35:43", "%ptRr", &tm); 5144d42c447SAndy Shevchenko test("05:35:43|2018-11-26", "%ptRt|%ptRd", &tm, &tm); 5154d42c447SAndy Shevchenko test("05:35:43|0118-10-26", "%ptRtr|%ptRdr", &tm, &tm); 5164d42c447SAndy Shevchenko test("05:35:43|2018-11-26", "%ptRttr|%ptRdtr", &tm, &tm); 5174d42c447SAndy Shevchenko test("05:35:43 tr|2018-11-26 tr", "%ptRt tr|%ptRd tr", &tm, &tm); 5187daac5b2SAndy Shevchenko 5197daac5b2SAndy Shevchenko test("2019-01-04T15:32:23", "%ptT", &t); 5207daac5b2SAndy Shevchenko test("0119-00-04T15:32:23", "%ptTr", &t); 5217daac5b2SAndy Shevchenko test("15:32:23|2019-01-04", "%ptTt|%ptTd", &t, &t); 5227daac5b2SAndy Shevchenko test("15:32:23|0119-00-04", "%ptTtr|%ptTdr", &t, &t); 5234d42c447SAndy Shevchenko } 5244d42c447SAndy Shevchenko 5254d42c447SAndy Shevchenko static void __init 526707cc728SRasmus Villemoes struct_clk(void) 527707cc728SRasmus Villemoes { 528707cc728SRasmus Villemoes } 529707cc728SRasmus Villemoes 530707cc728SRasmus Villemoes static void __init 531857cca4dSRasmus Villemoes large_bitmap(void) 532857cca4dSRasmus Villemoes { 533857cca4dSRasmus Villemoes const int nbits = 1 << 16; 5342821fd0cSAndy Shevchenko unsigned long *bits = bitmap_zalloc(nbits, GFP_KERNEL); 535857cca4dSRasmus Villemoes if (!bits) 536857cca4dSRasmus Villemoes return; 537857cca4dSRasmus Villemoes 538857cca4dSRasmus Villemoes bitmap_set(bits, 1, 20); 539857cca4dSRasmus Villemoes bitmap_set(bits, 60000, 15); 540857cca4dSRasmus Villemoes test("1-20,60000-60014", "%*pbl", nbits, bits); 5412821fd0cSAndy Shevchenko bitmap_free(bits); 542857cca4dSRasmus Villemoes } 543857cca4dSRasmus Villemoes 544857cca4dSRasmus Villemoes static void __init 545707cc728SRasmus Villemoes bitmap(void) 546707cc728SRasmus Villemoes { 547707cc728SRasmus Villemoes DECLARE_BITMAP(bits, 20); 548707cc728SRasmus Villemoes const int primes[] = {2,3,5,7,11,13,17,19}; 549707cc728SRasmus Villemoes int i; 550707cc728SRasmus Villemoes 551707cc728SRasmus Villemoes bitmap_zero(bits, 20); 552707cc728SRasmus Villemoes test("00000|00000", "%20pb|%*pb", bits, 20, bits); 553707cc728SRasmus Villemoes test("|", "%20pbl|%*pbl", bits, 20, bits); 554707cc728SRasmus Villemoes 555707cc728SRasmus Villemoes for (i = 0; i < ARRAY_SIZE(primes); ++i) 556707cc728SRasmus Villemoes set_bit(primes[i], bits); 557707cc728SRasmus Villemoes test("a28ac|a28ac", "%20pb|%*pb", bits, 20, bits); 558707cc728SRasmus Villemoes test("2-3,5,7,11,13,17,19|2-3,5,7,11,13,17,19", "%20pbl|%*pbl", bits, 20, bits); 559707cc728SRasmus Villemoes 560707cc728SRasmus Villemoes bitmap_fill(bits, 20); 561707cc728SRasmus Villemoes test("fffff|fffff", "%20pb|%*pb", bits, 20, bits); 562707cc728SRasmus Villemoes test("0-19|0-19", "%20pbl|%*pbl", bits, 20, bits); 563857cca4dSRasmus Villemoes 564857cca4dSRasmus Villemoes large_bitmap(); 565707cc728SRasmus Villemoes } 566707cc728SRasmus Villemoes 567707cc728SRasmus Villemoes static void __init 568707cc728SRasmus Villemoes netdev_features(void) 569707cc728SRasmus Villemoes { 570707cc728SRasmus Villemoes } 571707cc728SRasmus Villemoes 572707cc728SRasmus Villemoes static void __init 573edf14cdbSVlastimil Babka flags(void) 574edf14cdbSVlastimil Babka { 575edf14cdbSVlastimil Babka unsigned long flags; 576edf14cdbSVlastimil Babka gfp_t gfp; 577edf14cdbSVlastimil Babka char *cmp_buffer; 578edf14cdbSVlastimil Babka 579edf14cdbSVlastimil Babka flags = 0; 580edf14cdbSVlastimil Babka test("", "%pGp", &flags); 581edf14cdbSVlastimil Babka 582edf14cdbSVlastimil Babka /* Page flags should filter the zone id */ 583edf14cdbSVlastimil Babka flags = 1UL << NR_PAGEFLAGS; 584edf14cdbSVlastimil Babka test("", "%pGp", &flags); 585edf14cdbSVlastimil Babka 586edf14cdbSVlastimil Babka flags |= 1UL << PG_uptodate | 1UL << PG_dirty | 1UL << PG_lru 587edf14cdbSVlastimil Babka | 1UL << PG_active | 1UL << PG_swapbacked; 588edf14cdbSVlastimil Babka test("uptodate|dirty|lru|active|swapbacked", "%pGp", &flags); 589edf14cdbSVlastimil Babka 590edf14cdbSVlastimil Babka 591edf14cdbSVlastimil Babka flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC 592edf14cdbSVlastimil Babka | VM_DENYWRITE; 593edf14cdbSVlastimil Babka test("read|exec|mayread|maywrite|mayexec|denywrite", "%pGv", &flags); 594edf14cdbSVlastimil Babka 595edf14cdbSVlastimil Babka gfp = GFP_TRANSHUGE; 596edf14cdbSVlastimil Babka test("GFP_TRANSHUGE", "%pGg", &gfp); 597edf14cdbSVlastimil Babka 598edf14cdbSVlastimil Babka gfp = GFP_ATOMIC|__GFP_DMA; 599edf14cdbSVlastimil Babka test("GFP_ATOMIC|GFP_DMA", "%pGg", &gfp); 600edf14cdbSVlastimil Babka 601edf14cdbSVlastimil Babka gfp = __GFP_ATOMIC; 602edf14cdbSVlastimil Babka test("__GFP_ATOMIC", "%pGg", &gfp); 603edf14cdbSVlastimil Babka 604edf14cdbSVlastimil Babka cmp_buffer = kmalloc(BUF_SIZE, GFP_KERNEL); 605edf14cdbSVlastimil Babka if (!cmp_buffer) 606edf14cdbSVlastimil Babka return; 607edf14cdbSVlastimil Babka 608edf14cdbSVlastimil Babka /* Any flags not translated by the table should remain numeric */ 609edf14cdbSVlastimil Babka gfp = ~__GFP_BITS_MASK; 610edf14cdbSVlastimil Babka snprintf(cmp_buffer, BUF_SIZE, "%#lx", (unsigned long) gfp); 611edf14cdbSVlastimil Babka test(cmp_buffer, "%pGg", &gfp); 612edf14cdbSVlastimil Babka 613edf14cdbSVlastimil Babka snprintf(cmp_buffer, BUF_SIZE, "__GFP_ATOMIC|%#lx", 614edf14cdbSVlastimil Babka (unsigned long) gfp); 615edf14cdbSVlastimil Babka gfp |= __GFP_ATOMIC; 616edf14cdbSVlastimil Babka test(cmp_buffer, "%pGg", &gfp); 617edf14cdbSVlastimil Babka 618edf14cdbSVlastimil Babka kfree(cmp_buffer); 619edf14cdbSVlastimil Babka } 620edf14cdbSVlastimil Babka 621f1ce39dfSSakari Ailus static void __init fwnode_pointer(void) 622f1ce39dfSSakari Ailus { 623f1ce39dfSSakari Ailus const struct software_node softnodes[] = { 624f1ce39dfSSakari Ailus { .name = "first", }, 625f1ce39dfSSakari Ailus { .name = "second", .parent = &softnodes[0], }, 626f1ce39dfSSakari Ailus { .name = "third", .parent = &softnodes[1], }, 627f1ce39dfSSakari Ailus { NULL /* Guardian */ } 628f1ce39dfSSakari Ailus }; 629f1ce39dfSSakari Ailus const char * const full_name = "first/second/third"; 630f1ce39dfSSakari Ailus const char * const full_name_second = "first/second"; 631f1ce39dfSSakari Ailus const char * const second_name = "second"; 632f1ce39dfSSakari Ailus const char * const third_name = "third"; 633f1ce39dfSSakari Ailus int rval; 634f1ce39dfSSakari Ailus 635f1ce39dfSSakari Ailus rval = software_node_register_nodes(softnodes); 636f1ce39dfSSakari Ailus if (rval) { 637f1ce39dfSSakari Ailus pr_warn("cannot register softnodes; rval %d\n", rval); 638f1ce39dfSSakari Ailus return; 639f1ce39dfSSakari Ailus } 640f1ce39dfSSakari Ailus 641f1ce39dfSSakari Ailus test(full_name_second, "%pfw", software_node_fwnode(&softnodes[1])); 642f1ce39dfSSakari Ailus test(full_name, "%pfw", software_node_fwnode(&softnodes[2])); 643f1ce39dfSSakari Ailus test(full_name, "%pfwf", software_node_fwnode(&softnodes[2])); 644f1ce39dfSSakari Ailus test(second_name, "%pfwP", software_node_fwnode(&softnodes[1])); 645f1ce39dfSSakari Ailus test(third_name, "%pfwP", software_node_fwnode(&softnodes[2])); 646f1ce39dfSSakari Ailus 64746d26819SGreg Kroah-Hartman software_node_unregister(&softnodes[2]); 64846d26819SGreg Kroah-Hartman software_node_unregister(&softnodes[1]); 64946d26819SGreg Kroah-Hartman software_node_unregister(&softnodes[0]); 650f1ce39dfSSakari Ailus } 651f1ce39dfSSakari Ailus 652edf14cdbSVlastimil Babka static void __init 65357f5677eSRasmus Villemoes errptr(void) 65457f5677eSRasmus Villemoes { 65557f5677eSRasmus Villemoes test("-1234", "%pe", ERR_PTR(-1234)); 65657f5677eSRasmus Villemoes 65757f5677eSRasmus Villemoes /* Check that %pe with a non-ERR_PTR gets treated as ordinary %p. */ 65857f5677eSRasmus Villemoes BUILD_BUG_ON(IS_ERR(PTR)); 65957f5677eSRasmus Villemoes test_hashed("%pe", PTR); 66057f5677eSRasmus Villemoes 66157f5677eSRasmus Villemoes #ifdef CONFIG_SYMBOLIC_ERRNAME 66257f5677eSRasmus Villemoes test("(-ENOTSOCK)", "(%pe)", ERR_PTR(-ENOTSOCK)); 66357f5677eSRasmus Villemoes test("(-EAGAIN)", "(%pe)", ERR_PTR(-EAGAIN)); 66457f5677eSRasmus Villemoes BUILD_BUG_ON(EAGAIN != EWOULDBLOCK); 66557f5677eSRasmus Villemoes test("(-EAGAIN)", "(%pe)", ERR_PTR(-EWOULDBLOCK)); 66657f5677eSRasmus Villemoes test("[-EIO ]", "[%-8pe]", ERR_PTR(-EIO)); 66757f5677eSRasmus Villemoes test("[ -EIO]", "[%8pe]", ERR_PTR(-EIO)); 66857f5677eSRasmus Villemoes test("-EPROBE_DEFER", "%pe", ERR_PTR(-EPROBE_DEFER)); 66957f5677eSRasmus Villemoes #endif 67057f5677eSRasmus Villemoes } 67157f5677eSRasmus Villemoes 67257f5677eSRasmus Villemoes static void __init 673707cc728SRasmus Villemoes test_pointer(void) 674707cc728SRasmus Villemoes { 675707cc728SRasmus Villemoes plain(); 6763e5903ebSPetr Mladek null_pointer(); 6777bd57fbcSIlya Dryomov error_pointer(); 6783e5903ebSPetr Mladek invalid_pointer(); 679707cc728SRasmus Villemoes symbol_ptr(); 680707cc728SRasmus Villemoes kernel_ptr(); 681707cc728SRasmus Villemoes struct_resource(); 682707cc728SRasmus Villemoes addr(); 683707cc728SRasmus Villemoes escaped_str(); 684707cc728SRasmus Villemoes hex_string(); 685707cc728SRasmus Villemoes mac(); 686707cc728SRasmus Villemoes ip(); 687707cc728SRasmus Villemoes uuid(); 688707cc728SRasmus Villemoes dentry(); 689707cc728SRasmus Villemoes struct_va_format(); 6907daac5b2SAndy Shevchenko time_and_date(); 691707cc728SRasmus Villemoes struct_clk(); 692707cc728SRasmus Villemoes bitmap(); 693707cc728SRasmus Villemoes netdev_features(); 694edf14cdbSVlastimil Babka flags(); 69557f5677eSRasmus Villemoes errptr(); 696f1ce39dfSSakari Ailus fwnode_pointer(); 697707cc728SRasmus Villemoes } 698707cc728SRasmus Villemoes 6996b1a4d5bSTobin C. Harding static void __init selftest(void) 700707cc728SRasmus Villemoes { 701331e4debSRasmus Villemoes alloced_buffer = kmalloc(BUF_SIZE + 2*PAD_SIZE, GFP_KERNEL); 702331e4debSRasmus Villemoes if (!alloced_buffer) 7036b1a4d5bSTobin C. Harding return; 704331e4debSRasmus Villemoes test_buffer = alloced_buffer + PAD_SIZE; 705707cc728SRasmus Villemoes 706707cc728SRasmus Villemoes test_basic(); 707707cc728SRasmus Villemoes test_number(); 708707cc728SRasmus Villemoes test_string(); 709707cc728SRasmus Villemoes test_pointer(); 710707cc728SRasmus Villemoes 711331e4debSRasmus Villemoes kfree(alloced_buffer); 712707cc728SRasmus Villemoes } 713707cc728SRasmus Villemoes 7146b1a4d5bSTobin C. Harding KSTM_MODULE_LOADERS(test_printf); 715707cc728SRasmus Villemoes MODULE_AUTHOR("Rasmus Villemoes <linux@rasmusvillemoes.dk>"); 716707cc728SRasmus Villemoes MODULE_LICENSE("GPL"); 717