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