162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Test cases for printf facility. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/init.h> 962306a36Sopenharmony_ci#include <linux/kernel.h> 1062306a36Sopenharmony_ci#include <linux/module.h> 1162306a36Sopenharmony_ci#include <linux/printk.h> 1262306a36Sopenharmony_ci#include <linux/random.h> 1362306a36Sopenharmony_ci#include <linux/rtc.h> 1462306a36Sopenharmony_ci#include <linux/slab.h> 1562306a36Sopenharmony_ci#include <linux/sprintf.h> 1662306a36Sopenharmony_ci#include <linux/string.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#include <linux/bitmap.h> 1962306a36Sopenharmony_ci#include <linux/dcache.h> 2062306a36Sopenharmony_ci#include <linux/socket.h> 2162306a36Sopenharmony_ci#include <linux/in.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#include <linux/gfp.h> 2462306a36Sopenharmony_ci#include <linux/mm.h> 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#include <linux/property.h> 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#include "../tools/testing/selftests/kselftest_module.h" 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#define BUF_SIZE 256 3162306a36Sopenharmony_ci#define PAD_SIZE 16 3262306a36Sopenharmony_ci#define FILL_CHAR '$' 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci#define NOWARN(option, comment, block) \ 3562306a36Sopenharmony_ci __diag_push(); \ 3662306a36Sopenharmony_ci __diag_ignore_all(#option, comment); \ 3762306a36Sopenharmony_ci block \ 3862306a36Sopenharmony_ci __diag_pop(); 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ciKSTM_MODULE_GLOBALS(); 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_cistatic char *test_buffer __initdata; 4362306a36Sopenharmony_cistatic char *alloced_buffer __initdata; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cistatic int __printf(4, 0) __init 4662306a36Sopenharmony_cido_test(int bufsize, const char *expect, int elen, 4762306a36Sopenharmony_ci const char *fmt, va_list ap) 4862306a36Sopenharmony_ci{ 4962306a36Sopenharmony_ci va_list aq; 5062306a36Sopenharmony_ci int ret, written; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci total_tests++; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci memset(alloced_buffer, FILL_CHAR, BUF_SIZE + 2*PAD_SIZE); 5562306a36Sopenharmony_ci va_copy(aq, ap); 5662306a36Sopenharmony_ci ret = vsnprintf(test_buffer, bufsize, fmt, aq); 5762306a36Sopenharmony_ci va_end(aq); 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci if (ret != elen) { 6062306a36Sopenharmony_ci pr_warn("vsnprintf(buf, %d, \"%s\", ...) returned %d, expected %d\n", 6162306a36Sopenharmony_ci bufsize, fmt, ret, elen); 6262306a36Sopenharmony_ci return 1; 6362306a36Sopenharmony_ci } 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci if (memchr_inv(alloced_buffer, FILL_CHAR, PAD_SIZE)) { 6662306a36Sopenharmony_ci pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote before buffer\n", bufsize, fmt); 6762306a36Sopenharmony_ci return 1; 6862306a36Sopenharmony_ci } 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci if (!bufsize) { 7162306a36Sopenharmony_ci if (memchr_inv(test_buffer, FILL_CHAR, BUF_SIZE + PAD_SIZE)) { 7262306a36Sopenharmony_ci pr_warn("vsnprintf(buf, 0, \"%s\", ...) wrote to buffer\n", 7362306a36Sopenharmony_ci fmt); 7462306a36Sopenharmony_ci return 1; 7562306a36Sopenharmony_ci } 7662306a36Sopenharmony_ci return 0; 7762306a36Sopenharmony_ci } 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci written = min(bufsize-1, elen); 8062306a36Sopenharmony_ci if (test_buffer[written]) { 8162306a36Sopenharmony_ci pr_warn("vsnprintf(buf, %d, \"%s\", ...) did not nul-terminate buffer\n", 8262306a36Sopenharmony_ci bufsize, fmt); 8362306a36Sopenharmony_ci return 1; 8462306a36Sopenharmony_ci } 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci if (memchr_inv(test_buffer + written + 1, FILL_CHAR, bufsize - (written + 1))) { 8762306a36Sopenharmony_ci pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote beyond the nul-terminator\n", 8862306a36Sopenharmony_ci bufsize, fmt); 8962306a36Sopenharmony_ci return 1; 9062306a36Sopenharmony_ci } 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci if (memchr_inv(test_buffer + bufsize, FILL_CHAR, BUF_SIZE + PAD_SIZE - bufsize)) { 9362306a36Sopenharmony_ci pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote beyond buffer\n", bufsize, fmt); 9462306a36Sopenharmony_ci return 1; 9562306a36Sopenharmony_ci } 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci if (memcmp(test_buffer, expect, written)) { 9862306a36Sopenharmony_ci pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote '%s', expected '%.*s'\n", 9962306a36Sopenharmony_ci bufsize, fmt, test_buffer, written, expect); 10062306a36Sopenharmony_ci return 1; 10162306a36Sopenharmony_ci } 10262306a36Sopenharmony_ci return 0; 10362306a36Sopenharmony_ci} 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_cistatic void __printf(3, 4) __init 10662306a36Sopenharmony_ci__test(const char *expect, int elen, const char *fmt, ...) 10762306a36Sopenharmony_ci{ 10862306a36Sopenharmony_ci va_list ap; 10962306a36Sopenharmony_ci int rand; 11062306a36Sopenharmony_ci char *p; 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci if (elen >= BUF_SIZE) { 11362306a36Sopenharmony_ci pr_err("error in test suite: expected output length %d too long. Format was '%s'.\n", 11462306a36Sopenharmony_ci elen, fmt); 11562306a36Sopenharmony_ci failed_tests++; 11662306a36Sopenharmony_ci return; 11762306a36Sopenharmony_ci } 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci va_start(ap, fmt); 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci /* 12262306a36Sopenharmony_ci * Every fmt+args is subjected to four tests: Three where we 12362306a36Sopenharmony_ci * tell vsnprintf varying buffer sizes (plenty, not quite 12462306a36Sopenharmony_ci * enough and 0), and then we also test that kvasprintf would 12562306a36Sopenharmony_ci * be able to print it as expected. 12662306a36Sopenharmony_ci */ 12762306a36Sopenharmony_ci failed_tests += do_test(BUF_SIZE, expect, elen, fmt, ap); 12862306a36Sopenharmony_ci rand = get_random_u32_inclusive(1, elen + 1); 12962306a36Sopenharmony_ci /* Since elen < BUF_SIZE, we have 1 <= rand <= BUF_SIZE. */ 13062306a36Sopenharmony_ci failed_tests += do_test(rand, expect, elen, fmt, ap); 13162306a36Sopenharmony_ci failed_tests += do_test(0, expect, elen, fmt, ap); 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci p = kvasprintf(GFP_KERNEL, fmt, ap); 13462306a36Sopenharmony_ci if (p) { 13562306a36Sopenharmony_ci total_tests++; 13662306a36Sopenharmony_ci if (memcmp(p, expect, elen+1)) { 13762306a36Sopenharmony_ci pr_warn("kvasprintf(..., \"%s\", ...) returned '%s', expected '%s'\n", 13862306a36Sopenharmony_ci fmt, p, expect); 13962306a36Sopenharmony_ci failed_tests++; 14062306a36Sopenharmony_ci } 14162306a36Sopenharmony_ci kfree(p); 14262306a36Sopenharmony_ci } 14362306a36Sopenharmony_ci va_end(ap); 14462306a36Sopenharmony_ci} 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci#define test(expect, fmt, ...) \ 14762306a36Sopenharmony_ci __test(expect, strlen(expect), fmt, ##__VA_ARGS__) 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_cistatic void __init 15062306a36Sopenharmony_citest_basic(void) 15162306a36Sopenharmony_ci{ 15262306a36Sopenharmony_ci /* Work around annoying "warning: zero-length gnu_printf format string". */ 15362306a36Sopenharmony_ci char nul = '\0'; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci test("", &nul); 15662306a36Sopenharmony_ci test("100%", "100%%"); 15762306a36Sopenharmony_ci test("xxx%yyy", "xxx%cyyy", '%'); 15862306a36Sopenharmony_ci __test("xxx\0yyy", 7, "xxx%cyyy", '\0'); 15962306a36Sopenharmony_ci} 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_cistatic void __init 16262306a36Sopenharmony_citest_number(void) 16362306a36Sopenharmony_ci{ 16462306a36Sopenharmony_ci test("0x1234abcd ", "%#-12x", 0x1234abcd); 16562306a36Sopenharmony_ci test(" 0x1234abcd", "%#12x", 0x1234abcd); 16662306a36Sopenharmony_ci test("0|001| 12|+123| 1234|-123|-1234", "%d|%03d|%3d|%+d|% d|%+d|% d", 0, 1, 12, 123, 1234, -123, -1234); 16762306a36Sopenharmony_ci NOWARN(-Wformat, "Intentionally test narrowing conversion specifiers.", { 16862306a36Sopenharmony_ci test("0|1|1|128|255", "%hhu|%hhu|%hhu|%hhu|%hhu", 0, 1, 257, 128, -1); 16962306a36Sopenharmony_ci test("0|1|1|-128|-1", "%hhd|%hhd|%hhd|%hhd|%hhd", 0, 1, 257, 128, -1); 17062306a36Sopenharmony_ci test("2015122420151225", "%ho%ho%#ho", 1037, 5282, -11627); 17162306a36Sopenharmony_ci }) 17262306a36Sopenharmony_ci /* 17362306a36Sopenharmony_ci * POSIX/C99: »The result of converting zero with an explicit 17462306a36Sopenharmony_ci * precision of zero shall be no characters.« Hence the output 17562306a36Sopenharmony_ci * from the below test should really be "00|0||| ". However, 17662306a36Sopenharmony_ci * the kernel's printf also produces a single 0 in that 17762306a36Sopenharmony_ci * case. This test case simply documents the current 17862306a36Sopenharmony_ci * behaviour. 17962306a36Sopenharmony_ci */ 18062306a36Sopenharmony_ci test("00|0|0|0|0", "%.2d|%.1d|%.0d|%.*d|%1.0d", 0, 0, 0, 0, 0, 0); 18162306a36Sopenharmony_ci} 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_cistatic void __init 18462306a36Sopenharmony_citest_string(void) 18562306a36Sopenharmony_ci{ 18662306a36Sopenharmony_ci test("", "%s%.0s", "", "123"); 18762306a36Sopenharmony_ci test("ABCD|abc|123", "%s|%.3s|%.*s", "ABCD", "abcdef", 3, "123456"); 18862306a36Sopenharmony_ci test("1 | 2|3 | 4|5 ", "%-3s|%3s|%-*s|%*s|%*s", "1", "2", 3, "3", 3, "4", -3, "5"); 18962306a36Sopenharmony_ci test("1234 ", "%-10.4s", "123456"); 19062306a36Sopenharmony_ci test(" 1234", "%10.4s", "123456"); 19162306a36Sopenharmony_ci /* 19262306a36Sopenharmony_ci * POSIX and C99 say that a negative precision (which is only 19362306a36Sopenharmony_ci * possible to pass via a * argument) should be treated as if 19462306a36Sopenharmony_ci * the precision wasn't present, and that if the precision is 19562306a36Sopenharmony_ci * omitted (as in %.s), the precision should be taken to be 19662306a36Sopenharmony_ci * 0. However, the kernel's printf behave exactly opposite, 19762306a36Sopenharmony_ci * treating a negative precision as 0 and treating an omitted 19862306a36Sopenharmony_ci * precision specifier as if no precision was given. 19962306a36Sopenharmony_ci * 20062306a36Sopenharmony_ci * These test cases document the current behaviour; should 20162306a36Sopenharmony_ci * anyone ever feel the need to follow the standards more 20262306a36Sopenharmony_ci * closely, this can be revisited. 20362306a36Sopenharmony_ci */ 20462306a36Sopenharmony_ci test(" ", "%4.*s", -5, "123456"); 20562306a36Sopenharmony_ci test("123456", "%.s", "123456"); 20662306a36Sopenharmony_ci test("a||", "%.s|%.0s|%.*s", "a", "b", 0, "c"); 20762306a36Sopenharmony_ci test("a | | ", "%-3.s|%-3.0s|%-3.*s", "a", "b", 0, "c"); 20862306a36Sopenharmony_ci} 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci#define PLAIN_BUF_SIZE 64 /* leave some space so we don't oops */ 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci#if BITS_PER_LONG == 64 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci#define PTR_WIDTH 16 21562306a36Sopenharmony_ci#define PTR ((void *)0xffff0123456789abUL) 21662306a36Sopenharmony_ci#define PTR_STR "ffff0123456789ab" 21762306a36Sopenharmony_ci#define PTR_VAL_NO_CRNG "(____ptrval____)" 21862306a36Sopenharmony_ci#define ZEROS "00000000" /* hex 32 zero bits */ 21962306a36Sopenharmony_ci#define ONES "ffffffff" /* hex 32 one bits */ 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_cistatic int __init 22262306a36Sopenharmony_ciplain_format(void) 22362306a36Sopenharmony_ci{ 22462306a36Sopenharmony_ci char buf[PLAIN_BUF_SIZE]; 22562306a36Sopenharmony_ci int nchars; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci nchars = snprintf(buf, PLAIN_BUF_SIZE, "%p", PTR); 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci if (nchars != PTR_WIDTH) 23062306a36Sopenharmony_ci return -1; 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci if (strncmp(buf, PTR_VAL_NO_CRNG, PTR_WIDTH) == 0) { 23362306a36Sopenharmony_ci pr_warn("crng possibly not yet initialized. plain 'p' buffer contains \"%s\"", 23462306a36Sopenharmony_ci PTR_VAL_NO_CRNG); 23562306a36Sopenharmony_ci return 0; 23662306a36Sopenharmony_ci } 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci if (strncmp(buf, ZEROS, strlen(ZEROS)) != 0) 23962306a36Sopenharmony_ci return -1; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci return 0; 24262306a36Sopenharmony_ci} 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci#else 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci#define PTR_WIDTH 8 24762306a36Sopenharmony_ci#define PTR ((void *)0x456789ab) 24862306a36Sopenharmony_ci#define PTR_STR "456789ab" 24962306a36Sopenharmony_ci#define PTR_VAL_NO_CRNG "(ptrval)" 25062306a36Sopenharmony_ci#define ZEROS "" 25162306a36Sopenharmony_ci#define ONES "" 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_cistatic int __init 25462306a36Sopenharmony_ciplain_format(void) 25562306a36Sopenharmony_ci{ 25662306a36Sopenharmony_ci /* Format is implicitly tested for 32 bit machines by plain_hash() */ 25762306a36Sopenharmony_ci return 0; 25862306a36Sopenharmony_ci} 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci#endif /* BITS_PER_LONG == 64 */ 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_cistatic int __init 26362306a36Sopenharmony_ciplain_hash_to_buffer(const void *p, char *buf, size_t len) 26462306a36Sopenharmony_ci{ 26562306a36Sopenharmony_ci int nchars; 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci nchars = snprintf(buf, len, "%p", p); 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci if (nchars != PTR_WIDTH) 27062306a36Sopenharmony_ci return -1; 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci if (strncmp(buf, PTR_VAL_NO_CRNG, PTR_WIDTH) == 0) { 27362306a36Sopenharmony_ci pr_warn("crng possibly not yet initialized. plain 'p' buffer contains \"%s\"", 27462306a36Sopenharmony_ci PTR_VAL_NO_CRNG); 27562306a36Sopenharmony_ci return 0; 27662306a36Sopenharmony_ci } 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci return 0; 27962306a36Sopenharmony_ci} 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_cistatic int __init 28262306a36Sopenharmony_ciplain_hash(void) 28362306a36Sopenharmony_ci{ 28462306a36Sopenharmony_ci char buf[PLAIN_BUF_SIZE]; 28562306a36Sopenharmony_ci int ret; 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci ret = plain_hash_to_buffer(PTR, buf, PLAIN_BUF_SIZE); 28862306a36Sopenharmony_ci if (ret) 28962306a36Sopenharmony_ci return ret; 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci if (strncmp(buf, PTR_STR, PTR_WIDTH) == 0) 29262306a36Sopenharmony_ci return -1; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci return 0; 29562306a36Sopenharmony_ci} 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci/* 29862306a36Sopenharmony_ci * We can't use test() to test %p because we don't know what output to expect 29962306a36Sopenharmony_ci * after an address is hashed. 30062306a36Sopenharmony_ci */ 30162306a36Sopenharmony_cistatic void __init 30262306a36Sopenharmony_ciplain(void) 30362306a36Sopenharmony_ci{ 30462306a36Sopenharmony_ci int err; 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci if (no_hash_pointers) { 30762306a36Sopenharmony_ci pr_warn("skipping plain 'p' tests"); 30862306a36Sopenharmony_ci skipped_tests += 2; 30962306a36Sopenharmony_ci return; 31062306a36Sopenharmony_ci } 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci err = plain_hash(); 31362306a36Sopenharmony_ci if (err) { 31462306a36Sopenharmony_ci pr_warn("plain 'p' does not appear to be hashed\n"); 31562306a36Sopenharmony_ci failed_tests++; 31662306a36Sopenharmony_ci return; 31762306a36Sopenharmony_ci } 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci err = plain_format(); 32062306a36Sopenharmony_ci if (err) { 32162306a36Sopenharmony_ci pr_warn("hashing plain 'p' has unexpected format\n"); 32262306a36Sopenharmony_ci failed_tests++; 32362306a36Sopenharmony_ci } 32462306a36Sopenharmony_ci} 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_cistatic void __init 32762306a36Sopenharmony_citest_hashed(const char *fmt, const void *p) 32862306a36Sopenharmony_ci{ 32962306a36Sopenharmony_ci char buf[PLAIN_BUF_SIZE]; 33062306a36Sopenharmony_ci int ret; 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci /* 33362306a36Sopenharmony_ci * No need to increase failed test counter since this is assumed 33462306a36Sopenharmony_ci * to be called after plain(). 33562306a36Sopenharmony_ci */ 33662306a36Sopenharmony_ci ret = plain_hash_to_buffer(p, buf, PLAIN_BUF_SIZE); 33762306a36Sopenharmony_ci if (ret) 33862306a36Sopenharmony_ci return; 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci test(buf, fmt, p); 34162306a36Sopenharmony_ci} 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci/* 34462306a36Sopenharmony_ci * NULL pointers aren't hashed. 34562306a36Sopenharmony_ci */ 34662306a36Sopenharmony_cistatic void __init 34762306a36Sopenharmony_cinull_pointer(void) 34862306a36Sopenharmony_ci{ 34962306a36Sopenharmony_ci test(ZEROS "00000000", "%p", NULL); 35062306a36Sopenharmony_ci test(ZEROS "00000000", "%px", NULL); 35162306a36Sopenharmony_ci test("(null)", "%pE", NULL); 35262306a36Sopenharmony_ci} 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci/* 35562306a36Sopenharmony_ci * Error pointers aren't hashed. 35662306a36Sopenharmony_ci */ 35762306a36Sopenharmony_cistatic void __init 35862306a36Sopenharmony_cierror_pointer(void) 35962306a36Sopenharmony_ci{ 36062306a36Sopenharmony_ci test(ONES "fffffff5", "%p", ERR_PTR(-11)); 36162306a36Sopenharmony_ci test(ONES "fffffff5", "%px", ERR_PTR(-11)); 36262306a36Sopenharmony_ci test("(efault)", "%pE", ERR_PTR(-11)); 36362306a36Sopenharmony_ci} 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci#define PTR_INVALID ((void *)0x000000ab) 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_cistatic void __init 36862306a36Sopenharmony_ciinvalid_pointer(void) 36962306a36Sopenharmony_ci{ 37062306a36Sopenharmony_ci test_hashed("%p", PTR_INVALID); 37162306a36Sopenharmony_ci test(ZEROS "000000ab", "%px", PTR_INVALID); 37262306a36Sopenharmony_ci test("(efault)", "%pE", PTR_INVALID); 37362306a36Sopenharmony_ci} 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_cistatic void __init 37662306a36Sopenharmony_cisymbol_ptr(void) 37762306a36Sopenharmony_ci{ 37862306a36Sopenharmony_ci} 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_cistatic void __init 38162306a36Sopenharmony_cikernel_ptr(void) 38262306a36Sopenharmony_ci{ 38362306a36Sopenharmony_ci /* We can't test this without access to kptr_restrict. */ 38462306a36Sopenharmony_ci} 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_cistatic void __init 38762306a36Sopenharmony_cistruct_resource(void) 38862306a36Sopenharmony_ci{ 38962306a36Sopenharmony_ci} 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_cistatic void __init 39262306a36Sopenharmony_ciaddr(void) 39362306a36Sopenharmony_ci{ 39462306a36Sopenharmony_ci} 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_cistatic void __init 39762306a36Sopenharmony_ciescaped_str(void) 39862306a36Sopenharmony_ci{ 39962306a36Sopenharmony_ci} 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_cistatic void __init 40262306a36Sopenharmony_cihex_string(void) 40362306a36Sopenharmony_ci{ 40462306a36Sopenharmony_ci const char buf[3] = {0xc0, 0xff, 0xee}; 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci test("c0 ff ee|c0:ff:ee|c0-ff-ee|c0ffee", 40762306a36Sopenharmony_ci "%3ph|%3phC|%3phD|%3phN", buf, buf, buf, buf); 40862306a36Sopenharmony_ci test("c0 ff ee|c0:ff:ee|c0-ff-ee|c0ffee", 40962306a36Sopenharmony_ci "%*ph|%*phC|%*phD|%*phN", 3, buf, 3, buf, 3, buf, 3, buf); 41062306a36Sopenharmony_ci} 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_cistatic void __init 41362306a36Sopenharmony_cimac(void) 41462306a36Sopenharmony_ci{ 41562306a36Sopenharmony_ci const u8 addr[6] = {0x2d, 0x48, 0xd6, 0xfc, 0x7a, 0x05}; 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci test("2d:48:d6:fc:7a:05", "%pM", addr); 41862306a36Sopenharmony_ci test("05:7a:fc:d6:48:2d", "%pMR", addr); 41962306a36Sopenharmony_ci test("2d-48-d6-fc-7a-05", "%pMF", addr); 42062306a36Sopenharmony_ci test("2d48d6fc7a05", "%pm", addr); 42162306a36Sopenharmony_ci test("057afcd6482d", "%pmR", addr); 42262306a36Sopenharmony_ci} 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_cistatic void __init 42562306a36Sopenharmony_ciip4(void) 42662306a36Sopenharmony_ci{ 42762306a36Sopenharmony_ci struct sockaddr_in sa; 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci sa.sin_family = AF_INET; 43062306a36Sopenharmony_ci sa.sin_port = cpu_to_be16(12345); 43162306a36Sopenharmony_ci sa.sin_addr.s_addr = cpu_to_be32(0x7f000001); 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_ci test("127.000.000.001|127.0.0.1", "%pi4|%pI4", &sa.sin_addr, &sa.sin_addr); 43462306a36Sopenharmony_ci test("127.000.000.001|127.0.0.1", "%piS|%pIS", &sa, &sa); 43562306a36Sopenharmony_ci sa.sin_addr.s_addr = cpu_to_be32(0x01020304); 43662306a36Sopenharmony_ci test("001.002.003.004:12345|1.2.3.4:12345", "%piSp|%pISp", &sa, &sa); 43762306a36Sopenharmony_ci} 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_cistatic void __init 44062306a36Sopenharmony_ciip6(void) 44162306a36Sopenharmony_ci{ 44262306a36Sopenharmony_ci} 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_cistatic void __init 44562306a36Sopenharmony_ciip(void) 44662306a36Sopenharmony_ci{ 44762306a36Sopenharmony_ci ip4(); 44862306a36Sopenharmony_ci ip6(); 44962306a36Sopenharmony_ci} 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_cistatic void __init 45262306a36Sopenharmony_ciuuid(void) 45362306a36Sopenharmony_ci{ 45462306a36Sopenharmony_ci const char uuid[16] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 45562306a36Sopenharmony_ci 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}; 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci test("00010203-0405-0607-0809-0a0b0c0d0e0f", "%pUb", uuid); 45862306a36Sopenharmony_ci test("00010203-0405-0607-0809-0A0B0C0D0E0F", "%pUB", uuid); 45962306a36Sopenharmony_ci test("03020100-0504-0706-0809-0a0b0c0d0e0f", "%pUl", uuid); 46062306a36Sopenharmony_ci test("03020100-0504-0706-0809-0A0B0C0D0E0F", "%pUL", uuid); 46162306a36Sopenharmony_ci} 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_cistatic struct dentry test_dentry[4] __initdata = { 46462306a36Sopenharmony_ci { .d_parent = &test_dentry[0], 46562306a36Sopenharmony_ci .d_name = QSTR_INIT(test_dentry[0].d_iname, 3), 46662306a36Sopenharmony_ci .d_iname = "foo" }, 46762306a36Sopenharmony_ci { .d_parent = &test_dentry[0], 46862306a36Sopenharmony_ci .d_name = QSTR_INIT(test_dentry[1].d_iname, 5), 46962306a36Sopenharmony_ci .d_iname = "bravo" }, 47062306a36Sopenharmony_ci { .d_parent = &test_dentry[1], 47162306a36Sopenharmony_ci .d_name = QSTR_INIT(test_dentry[2].d_iname, 4), 47262306a36Sopenharmony_ci .d_iname = "alfa" }, 47362306a36Sopenharmony_ci { .d_parent = &test_dentry[2], 47462306a36Sopenharmony_ci .d_name = QSTR_INIT(test_dentry[3].d_iname, 5), 47562306a36Sopenharmony_ci .d_iname = "romeo" }, 47662306a36Sopenharmony_ci}; 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_cistatic void __init 47962306a36Sopenharmony_cidentry(void) 48062306a36Sopenharmony_ci{ 48162306a36Sopenharmony_ci test("foo", "%pd", &test_dentry[0]); 48262306a36Sopenharmony_ci test("foo", "%pd2", &test_dentry[0]); 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_ci test("(null)", "%pd", NULL); 48562306a36Sopenharmony_ci test("(efault)", "%pd", PTR_INVALID); 48662306a36Sopenharmony_ci test("(null)", "%pD", NULL); 48762306a36Sopenharmony_ci test("(efault)", "%pD", PTR_INVALID); 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci test("romeo", "%pd", &test_dentry[3]); 49062306a36Sopenharmony_ci test("alfa/romeo", "%pd2", &test_dentry[3]); 49162306a36Sopenharmony_ci test("bravo/alfa/romeo", "%pd3", &test_dentry[3]); 49262306a36Sopenharmony_ci test("/bravo/alfa/romeo", "%pd4", &test_dentry[3]); 49362306a36Sopenharmony_ci test("/bravo/alfa", "%pd4", &test_dentry[2]); 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_ci test("bravo/alfa |bravo/alfa ", "%-12pd2|%*pd2", &test_dentry[2], -12, &test_dentry[2]); 49662306a36Sopenharmony_ci test(" bravo/alfa| bravo/alfa", "%12pd2|%*pd2", &test_dentry[2], 12, &test_dentry[2]); 49762306a36Sopenharmony_ci} 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_cistatic void __init 50062306a36Sopenharmony_cistruct_va_format(void) 50162306a36Sopenharmony_ci{ 50262306a36Sopenharmony_ci} 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_cistatic void __init 50562306a36Sopenharmony_citime_and_date(void) 50662306a36Sopenharmony_ci{ 50762306a36Sopenharmony_ci /* 1543210543 */ 50862306a36Sopenharmony_ci const struct rtc_time tm = { 50962306a36Sopenharmony_ci .tm_sec = 43, 51062306a36Sopenharmony_ci .tm_min = 35, 51162306a36Sopenharmony_ci .tm_hour = 5, 51262306a36Sopenharmony_ci .tm_mday = 26, 51362306a36Sopenharmony_ci .tm_mon = 10, 51462306a36Sopenharmony_ci .tm_year = 118, 51562306a36Sopenharmony_ci }; 51662306a36Sopenharmony_ci /* 2019-01-04T15:32:23 */ 51762306a36Sopenharmony_ci time64_t t = 1546615943; 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_ci test("(%pt?)", "%pt", &tm); 52062306a36Sopenharmony_ci test("2018-11-26T05:35:43", "%ptR", &tm); 52162306a36Sopenharmony_ci test("0118-10-26T05:35:43", "%ptRr", &tm); 52262306a36Sopenharmony_ci test("05:35:43|2018-11-26", "%ptRt|%ptRd", &tm, &tm); 52362306a36Sopenharmony_ci test("05:35:43|0118-10-26", "%ptRtr|%ptRdr", &tm, &tm); 52462306a36Sopenharmony_ci test("05:35:43|2018-11-26", "%ptRttr|%ptRdtr", &tm, &tm); 52562306a36Sopenharmony_ci test("05:35:43 tr|2018-11-26 tr", "%ptRt tr|%ptRd tr", &tm, &tm); 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci test("2019-01-04T15:32:23", "%ptT", &t); 52862306a36Sopenharmony_ci test("0119-00-04T15:32:23", "%ptTr", &t); 52962306a36Sopenharmony_ci test("15:32:23|2019-01-04", "%ptTt|%ptTd", &t, &t); 53062306a36Sopenharmony_ci test("15:32:23|0119-00-04", "%ptTtr|%ptTdr", &t, &t); 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci test("2019-01-04 15:32:23", "%ptTs", &t); 53362306a36Sopenharmony_ci test("0119-00-04 15:32:23", "%ptTsr", &t); 53462306a36Sopenharmony_ci test("15:32:23|2019-01-04", "%ptTts|%ptTds", &t, &t); 53562306a36Sopenharmony_ci test("15:32:23|0119-00-04", "%ptTtrs|%ptTdrs", &t, &t); 53662306a36Sopenharmony_ci} 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_cistatic void __init 53962306a36Sopenharmony_cistruct_clk(void) 54062306a36Sopenharmony_ci{ 54162306a36Sopenharmony_ci} 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_cistatic void __init 54462306a36Sopenharmony_cilarge_bitmap(void) 54562306a36Sopenharmony_ci{ 54662306a36Sopenharmony_ci const int nbits = 1 << 16; 54762306a36Sopenharmony_ci unsigned long *bits = bitmap_zalloc(nbits, GFP_KERNEL); 54862306a36Sopenharmony_ci if (!bits) 54962306a36Sopenharmony_ci return; 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_ci bitmap_set(bits, 1, 20); 55262306a36Sopenharmony_ci bitmap_set(bits, 60000, 15); 55362306a36Sopenharmony_ci test("1-20,60000-60014", "%*pbl", nbits, bits); 55462306a36Sopenharmony_ci bitmap_free(bits); 55562306a36Sopenharmony_ci} 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_cistatic void __init 55862306a36Sopenharmony_cibitmap(void) 55962306a36Sopenharmony_ci{ 56062306a36Sopenharmony_ci DECLARE_BITMAP(bits, 20); 56162306a36Sopenharmony_ci const int primes[] = {2,3,5,7,11,13,17,19}; 56262306a36Sopenharmony_ci int i; 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_ci bitmap_zero(bits, 20); 56562306a36Sopenharmony_ci test("00000|00000", "%20pb|%*pb", bits, 20, bits); 56662306a36Sopenharmony_ci test("|", "%20pbl|%*pbl", bits, 20, bits); 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(primes); ++i) 56962306a36Sopenharmony_ci set_bit(primes[i], bits); 57062306a36Sopenharmony_ci test("a28ac|a28ac", "%20pb|%*pb", bits, 20, bits); 57162306a36Sopenharmony_ci test("2-3,5,7,11,13,17,19|2-3,5,7,11,13,17,19", "%20pbl|%*pbl", bits, 20, bits); 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ci bitmap_fill(bits, 20); 57462306a36Sopenharmony_ci test("fffff|fffff", "%20pb|%*pb", bits, 20, bits); 57562306a36Sopenharmony_ci test("0-19|0-19", "%20pbl|%*pbl", bits, 20, bits); 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_ci large_bitmap(); 57862306a36Sopenharmony_ci} 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_cistatic void __init 58162306a36Sopenharmony_cinetdev_features(void) 58262306a36Sopenharmony_ci{ 58362306a36Sopenharmony_ci} 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_cistruct page_flags_test { 58662306a36Sopenharmony_ci int width; 58762306a36Sopenharmony_ci int shift; 58862306a36Sopenharmony_ci int mask; 58962306a36Sopenharmony_ci const char *fmt; 59062306a36Sopenharmony_ci const char *name; 59162306a36Sopenharmony_ci}; 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_cistatic const struct page_flags_test pft[] = { 59462306a36Sopenharmony_ci {SECTIONS_WIDTH, SECTIONS_PGSHIFT, SECTIONS_MASK, 59562306a36Sopenharmony_ci "%d", "section"}, 59662306a36Sopenharmony_ci {NODES_WIDTH, NODES_PGSHIFT, NODES_MASK, 59762306a36Sopenharmony_ci "%d", "node"}, 59862306a36Sopenharmony_ci {ZONES_WIDTH, ZONES_PGSHIFT, ZONES_MASK, 59962306a36Sopenharmony_ci "%d", "zone"}, 60062306a36Sopenharmony_ci {LAST_CPUPID_WIDTH, LAST_CPUPID_PGSHIFT, LAST_CPUPID_MASK, 60162306a36Sopenharmony_ci "%#x", "lastcpupid"}, 60262306a36Sopenharmony_ci {KASAN_TAG_WIDTH, KASAN_TAG_PGSHIFT, KASAN_TAG_MASK, 60362306a36Sopenharmony_ci "%#x", "kasantag"}, 60462306a36Sopenharmony_ci}; 60562306a36Sopenharmony_ci 60662306a36Sopenharmony_cistatic void __init 60762306a36Sopenharmony_cipage_flags_test(int section, int node, int zone, int last_cpupid, 60862306a36Sopenharmony_ci int kasan_tag, unsigned long flags, const char *name, 60962306a36Sopenharmony_ci char *cmp_buf) 61062306a36Sopenharmony_ci{ 61162306a36Sopenharmony_ci unsigned long values[] = {section, node, zone, last_cpupid, kasan_tag}; 61262306a36Sopenharmony_ci unsigned long size; 61362306a36Sopenharmony_ci bool append = false; 61462306a36Sopenharmony_ci int i; 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(values); i++) 61762306a36Sopenharmony_ci flags |= (values[i] & pft[i].mask) << pft[i].shift; 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_ci size = scnprintf(cmp_buf, BUF_SIZE, "%#lx(", flags); 62062306a36Sopenharmony_ci if (flags & PAGEFLAGS_MASK) { 62162306a36Sopenharmony_ci size += scnprintf(cmp_buf + size, BUF_SIZE - size, "%s", name); 62262306a36Sopenharmony_ci append = true; 62362306a36Sopenharmony_ci } 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(pft); i++) { 62662306a36Sopenharmony_ci if (!pft[i].width) 62762306a36Sopenharmony_ci continue; 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci if (append) 63062306a36Sopenharmony_ci size += scnprintf(cmp_buf + size, BUF_SIZE - size, "|"); 63162306a36Sopenharmony_ci 63262306a36Sopenharmony_ci size += scnprintf(cmp_buf + size, BUF_SIZE - size, "%s=", 63362306a36Sopenharmony_ci pft[i].name); 63462306a36Sopenharmony_ci size += scnprintf(cmp_buf + size, BUF_SIZE - size, pft[i].fmt, 63562306a36Sopenharmony_ci values[i] & pft[i].mask); 63662306a36Sopenharmony_ci append = true; 63762306a36Sopenharmony_ci } 63862306a36Sopenharmony_ci 63962306a36Sopenharmony_ci snprintf(cmp_buf + size, BUF_SIZE - size, ")"); 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_ci test(cmp_buf, "%pGp", &flags); 64262306a36Sopenharmony_ci} 64362306a36Sopenharmony_ci 64462306a36Sopenharmony_cistatic void __init page_type_test(unsigned int page_type, const char *name, 64562306a36Sopenharmony_ci char *cmp_buf) 64662306a36Sopenharmony_ci{ 64762306a36Sopenharmony_ci unsigned long size; 64862306a36Sopenharmony_ci 64962306a36Sopenharmony_ci size = scnprintf(cmp_buf, BUF_SIZE, "%#x(", page_type); 65062306a36Sopenharmony_ci if (page_type_has_type(page_type)) 65162306a36Sopenharmony_ci size += scnprintf(cmp_buf + size, BUF_SIZE - size, "%s", name); 65262306a36Sopenharmony_ci 65362306a36Sopenharmony_ci snprintf(cmp_buf + size, BUF_SIZE - size, ")"); 65462306a36Sopenharmony_ci test(cmp_buf, "%pGt", &page_type); 65562306a36Sopenharmony_ci} 65662306a36Sopenharmony_ci 65762306a36Sopenharmony_cistatic void __init 65862306a36Sopenharmony_ciflags(void) 65962306a36Sopenharmony_ci{ 66062306a36Sopenharmony_ci unsigned long flags; 66162306a36Sopenharmony_ci char *cmp_buffer; 66262306a36Sopenharmony_ci gfp_t gfp; 66362306a36Sopenharmony_ci unsigned int page_type; 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_ci cmp_buffer = kmalloc(BUF_SIZE, GFP_KERNEL); 66662306a36Sopenharmony_ci if (!cmp_buffer) 66762306a36Sopenharmony_ci return; 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_ci flags = 0; 67062306a36Sopenharmony_ci page_flags_test(0, 0, 0, 0, 0, flags, "", cmp_buffer); 67162306a36Sopenharmony_ci 67262306a36Sopenharmony_ci flags = 1UL << NR_PAGEFLAGS; 67362306a36Sopenharmony_ci page_flags_test(0, 0, 0, 0, 0, flags, "", cmp_buffer); 67462306a36Sopenharmony_ci 67562306a36Sopenharmony_ci flags |= 1UL << PG_uptodate | 1UL << PG_dirty | 1UL << PG_lru 67662306a36Sopenharmony_ci | 1UL << PG_active | 1UL << PG_swapbacked; 67762306a36Sopenharmony_ci page_flags_test(1, 1, 1, 0x1fffff, 1, flags, 67862306a36Sopenharmony_ci "uptodate|dirty|lru|active|swapbacked", 67962306a36Sopenharmony_ci cmp_buffer); 68062306a36Sopenharmony_ci 68162306a36Sopenharmony_ci flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; 68262306a36Sopenharmony_ci test("read|exec|mayread|maywrite|mayexec", "%pGv", &flags); 68362306a36Sopenharmony_ci 68462306a36Sopenharmony_ci gfp = GFP_TRANSHUGE; 68562306a36Sopenharmony_ci test("GFP_TRANSHUGE", "%pGg", &gfp); 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_ci gfp = GFP_ATOMIC|__GFP_DMA; 68862306a36Sopenharmony_ci test("GFP_ATOMIC|GFP_DMA", "%pGg", &gfp); 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci gfp = __GFP_HIGH; 69162306a36Sopenharmony_ci test("__GFP_HIGH", "%pGg", &gfp); 69262306a36Sopenharmony_ci 69362306a36Sopenharmony_ci /* Any flags not translated by the table should remain numeric */ 69462306a36Sopenharmony_ci gfp = ~__GFP_BITS_MASK; 69562306a36Sopenharmony_ci snprintf(cmp_buffer, BUF_SIZE, "%#lx", (unsigned long) gfp); 69662306a36Sopenharmony_ci test(cmp_buffer, "%pGg", &gfp); 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_ci snprintf(cmp_buffer, BUF_SIZE, "__GFP_HIGH|%#lx", 69962306a36Sopenharmony_ci (unsigned long) gfp); 70062306a36Sopenharmony_ci gfp |= __GFP_HIGH; 70162306a36Sopenharmony_ci test(cmp_buffer, "%pGg", &gfp); 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci page_type = ~0; 70462306a36Sopenharmony_ci page_type_test(page_type, "", cmp_buffer); 70562306a36Sopenharmony_ci 70662306a36Sopenharmony_ci page_type = 10; 70762306a36Sopenharmony_ci page_type_test(page_type, "", cmp_buffer); 70862306a36Sopenharmony_ci 70962306a36Sopenharmony_ci page_type = ~PG_buddy; 71062306a36Sopenharmony_ci page_type_test(page_type, "buddy", cmp_buffer); 71162306a36Sopenharmony_ci 71262306a36Sopenharmony_ci page_type = ~(PG_table | PG_buddy); 71362306a36Sopenharmony_ci page_type_test(page_type, "table|buddy", cmp_buffer); 71462306a36Sopenharmony_ci 71562306a36Sopenharmony_ci kfree(cmp_buffer); 71662306a36Sopenharmony_ci} 71762306a36Sopenharmony_ci 71862306a36Sopenharmony_cistatic void __init fwnode_pointer(void) 71962306a36Sopenharmony_ci{ 72062306a36Sopenharmony_ci const struct software_node first = { .name = "first" }; 72162306a36Sopenharmony_ci const struct software_node second = { .name = "second", .parent = &first }; 72262306a36Sopenharmony_ci const struct software_node third = { .name = "third", .parent = &second }; 72362306a36Sopenharmony_ci const struct software_node *group[] = { &first, &second, &third, NULL }; 72462306a36Sopenharmony_ci const char * const full_name_second = "first/second"; 72562306a36Sopenharmony_ci const char * const full_name_third = "first/second/third"; 72662306a36Sopenharmony_ci const char * const second_name = "second"; 72762306a36Sopenharmony_ci const char * const third_name = "third"; 72862306a36Sopenharmony_ci int rval; 72962306a36Sopenharmony_ci 73062306a36Sopenharmony_ci rval = software_node_register_node_group(group); 73162306a36Sopenharmony_ci if (rval) { 73262306a36Sopenharmony_ci pr_warn("cannot register softnodes; rval %d\n", rval); 73362306a36Sopenharmony_ci return; 73462306a36Sopenharmony_ci } 73562306a36Sopenharmony_ci 73662306a36Sopenharmony_ci test(full_name_second, "%pfw", software_node_fwnode(&second)); 73762306a36Sopenharmony_ci test(full_name_third, "%pfw", software_node_fwnode(&third)); 73862306a36Sopenharmony_ci test(full_name_third, "%pfwf", software_node_fwnode(&third)); 73962306a36Sopenharmony_ci test(second_name, "%pfwP", software_node_fwnode(&second)); 74062306a36Sopenharmony_ci test(third_name, "%pfwP", software_node_fwnode(&third)); 74162306a36Sopenharmony_ci 74262306a36Sopenharmony_ci software_node_unregister_node_group(group); 74362306a36Sopenharmony_ci} 74462306a36Sopenharmony_ci 74562306a36Sopenharmony_cistatic void __init fourcc_pointer(void) 74662306a36Sopenharmony_ci{ 74762306a36Sopenharmony_ci struct { 74862306a36Sopenharmony_ci u32 code; 74962306a36Sopenharmony_ci char *str; 75062306a36Sopenharmony_ci } const try[] = { 75162306a36Sopenharmony_ci { 0x3231564e, "NV12 little-endian (0x3231564e)", }, 75262306a36Sopenharmony_ci { 0xb231564e, "NV12 big-endian (0xb231564e)", }, 75362306a36Sopenharmony_ci { 0x10111213, ".... little-endian (0x10111213)", }, 75462306a36Sopenharmony_ci { 0x20303159, "Y10 little-endian (0x20303159)", }, 75562306a36Sopenharmony_ci }; 75662306a36Sopenharmony_ci unsigned int i; 75762306a36Sopenharmony_ci 75862306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(try); i++) 75962306a36Sopenharmony_ci test(try[i].str, "%p4cc", &try[i].code); 76062306a36Sopenharmony_ci} 76162306a36Sopenharmony_ci 76262306a36Sopenharmony_cistatic void __init 76362306a36Sopenharmony_cierrptr(void) 76462306a36Sopenharmony_ci{ 76562306a36Sopenharmony_ci test("-1234", "%pe", ERR_PTR(-1234)); 76662306a36Sopenharmony_ci 76762306a36Sopenharmony_ci /* Check that %pe with a non-ERR_PTR gets treated as ordinary %p. */ 76862306a36Sopenharmony_ci BUILD_BUG_ON(IS_ERR(PTR)); 76962306a36Sopenharmony_ci test_hashed("%pe", PTR); 77062306a36Sopenharmony_ci 77162306a36Sopenharmony_ci#ifdef CONFIG_SYMBOLIC_ERRNAME 77262306a36Sopenharmony_ci test("(-ENOTSOCK)", "(%pe)", ERR_PTR(-ENOTSOCK)); 77362306a36Sopenharmony_ci test("(-EAGAIN)", "(%pe)", ERR_PTR(-EAGAIN)); 77462306a36Sopenharmony_ci BUILD_BUG_ON(EAGAIN != EWOULDBLOCK); 77562306a36Sopenharmony_ci test("(-EAGAIN)", "(%pe)", ERR_PTR(-EWOULDBLOCK)); 77662306a36Sopenharmony_ci test("[-EIO ]", "[%-8pe]", ERR_PTR(-EIO)); 77762306a36Sopenharmony_ci test("[ -EIO]", "[%8pe]", ERR_PTR(-EIO)); 77862306a36Sopenharmony_ci test("-EPROBE_DEFER", "%pe", ERR_PTR(-EPROBE_DEFER)); 77962306a36Sopenharmony_ci#endif 78062306a36Sopenharmony_ci} 78162306a36Sopenharmony_ci 78262306a36Sopenharmony_cistatic void __init 78362306a36Sopenharmony_citest_pointer(void) 78462306a36Sopenharmony_ci{ 78562306a36Sopenharmony_ci plain(); 78662306a36Sopenharmony_ci null_pointer(); 78762306a36Sopenharmony_ci error_pointer(); 78862306a36Sopenharmony_ci invalid_pointer(); 78962306a36Sopenharmony_ci symbol_ptr(); 79062306a36Sopenharmony_ci kernel_ptr(); 79162306a36Sopenharmony_ci struct_resource(); 79262306a36Sopenharmony_ci addr(); 79362306a36Sopenharmony_ci escaped_str(); 79462306a36Sopenharmony_ci hex_string(); 79562306a36Sopenharmony_ci mac(); 79662306a36Sopenharmony_ci ip(); 79762306a36Sopenharmony_ci uuid(); 79862306a36Sopenharmony_ci dentry(); 79962306a36Sopenharmony_ci struct_va_format(); 80062306a36Sopenharmony_ci time_and_date(); 80162306a36Sopenharmony_ci struct_clk(); 80262306a36Sopenharmony_ci bitmap(); 80362306a36Sopenharmony_ci netdev_features(); 80462306a36Sopenharmony_ci flags(); 80562306a36Sopenharmony_ci errptr(); 80662306a36Sopenharmony_ci fwnode_pointer(); 80762306a36Sopenharmony_ci fourcc_pointer(); 80862306a36Sopenharmony_ci} 80962306a36Sopenharmony_ci 81062306a36Sopenharmony_cistatic void __init selftest(void) 81162306a36Sopenharmony_ci{ 81262306a36Sopenharmony_ci alloced_buffer = kmalloc(BUF_SIZE + 2*PAD_SIZE, GFP_KERNEL); 81362306a36Sopenharmony_ci if (!alloced_buffer) 81462306a36Sopenharmony_ci return; 81562306a36Sopenharmony_ci test_buffer = alloced_buffer + PAD_SIZE; 81662306a36Sopenharmony_ci 81762306a36Sopenharmony_ci test_basic(); 81862306a36Sopenharmony_ci test_number(); 81962306a36Sopenharmony_ci test_string(); 82062306a36Sopenharmony_ci test_pointer(); 82162306a36Sopenharmony_ci 82262306a36Sopenharmony_ci kfree(alloced_buffer); 82362306a36Sopenharmony_ci} 82462306a36Sopenharmony_ci 82562306a36Sopenharmony_ciKSTM_MODULE_LOADERS(test_printf); 82662306a36Sopenharmony_ciMODULE_AUTHOR("Rasmus Villemoes <linux@rasmusvillemoes.dk>"); 82762306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 828