0001
0002
0003
0004
0005
0006 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0007
0008 #include <linux/init.h>
0009 #include <linux/kernel.h>
0010 #include <linux/module.h>
0011 #include <linux/printk.h>
0012 #include <linux/random.h>
0013 #include <linux/rtc.h>
0014 #include <linux/slab.h>
0015 #include <linux/string.h>
0016
0017 #include <linux/bitmap.h>
0018 #include <linux/dcache.h>
0019 #include <linux/socket.h>
0020 #include <linux/in.h>
0021
0022 #include <linux/gfp.h>
0023 #include <linux/mm.h>
0024
0025 #include <linux/property.h>
0026
0027 #include "../tools/testing/selftests/kselftest_module.h"
0028
0029 #define BUF_SIZE 256
0030 #define PAD_SIZE 16
0031 #define FILL_CHAR '$'
0032
0033 #define NOWARN(option, comment, block) \
0034 __diag_push(); \
0035 __diag_ignore_all(#option, comment); \
0036 block \
0037 __diag_pop();
0038
0039 KSTM_MODULE_GLOBALS();
0040
0041 static char *test_buffer __initdata;
0042 static char *alloced_buffer __initdata;
0043
0044 extern bool no_hash_pointers;
0045
0046 static int __printf(4, 0) __init
0047 do_test(int bufsize, const char *expect, int elen,
0048 const char *fmt, va_list ap)
0049 {
0050 va_list aq;
0051 int ret, written;
0052
0053 total_tests++;
0054
0055 memset(alloced_buffer, FILL_CHAR, BUF_SIZE + 2*PAD_SIZE);
0056 va_copy(aq, ap);
0057 ret = vsnprintf(test_buffer, bufsize, fmt, aq);
0058 va_end(aq);
0059
0060 if (ret != elen) {
0061 pr_warn("vsnprintf(buf, %d, \"%s\", ...) returned %d, expected %d\n",
0062 bufsize, fmt, ret, elen);
0063 return 1;
0064 }
0065
0066 if (memchr_inv(alloced_buffer, FILL_CHAR, PAD_SIZE)) {
0067 pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote before buffer\n", bufsize, fmt);
0068 return 1;
0069 }
0070
0071 if (!bufsize) {
0072 if (memchr_inv(test_buffer, FILL_CHAR, BUF_SIZE + PAD_SIZE)) {
0073 pr_warn("vsnprintf(buf, 0, \"%s\", ...) wrote to buffer\n",
0074 fmt);
0075 return 1;
0076 }
0077 return 0;
0078 }
0079
0080 written = min(bufsize-1, elen);
0081 if (test_buffer[written]) {
0082 pr_warn("vsnprintf(buf, %d, \"%s\", ...) did not nul-terminate buffer\n",
0083 bufsize, fmt);
0084 return 1;
0085 }
0086
0087 if (memchr_inv(test_buffer + written + 1, FILL_CHAR, bufsize - (written + 1))) {
0088 pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote beyond the nul-terminator\n",
0089 bufsize, fmt);
0090 return 1;
0091 }
0092
0093 if (memchr_inv(test_buffer + bufsize, FILL_CHAR, BUF_SIZE + PAD_SIZE - bufsize)) {
0094 pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote beyond buffer\n", bufsize, fmt);
0095 return 1;
0096 }
0097
0098 if (memcmp(test_buffer, expect, written)) {
0099 pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote '%s', expected '%.*s'\n",
0100 bufsize, fmt, test_buffer, written, expect);
0101 return 1;
0102 }
0103 return 0;
0104 }
0105
0106 static void __printf(3, 4) __init
0107 __test(const char *expect, int elen, const char *fmt, ...)
0108 {
0109 va_list ap;
0110 int rand;
0111 char *p;
0112
0113 if (elen >= BUF_SIZE) {
0114 pr_err("error in test suite: expected output length %d too long. Format was '%s'.\n",
0115 elen, fmt);
0116 failed_tests++;
0117 return;
0118 }
0119
0120 va_start(ap, fmt);
0121
0122
0123
0124
0125
0126
0127
0128 failed_tests += do_test(BUF_SIZE, expect, elen, fmt, ap);
0129 rand = 1 + prandom_u32_max(elen+1);
0130
0131 failed_tests += do_test(rand, expect, elen, fmt, ap);
0132 failed_tests += do_test(0, expect, elen, fmt, ap);
0133
0134 p = kvasprintf(GFP_KERNEL, fmt, ap);
0135 if (p) {
0136 total_tests++;
0137 if (memcmp(p, expect, elen+1)) {
0138 pr_warn("kvasprintf(..., \"%s\", ...) returned '%s', expected '%s'\n",
0139 fmt, p, expect);
0140 failed_tests++;
0141 }
0142 kfree(p);
0143 }
0144 va_end(ap);
0145 }
0146
0147 #define test(expect, fmt, ...) \
0148 __test(expect, strlen(expect), fmt, ##__VA_ARGS__)
0149
0150 static void __init
0151 test_basic(void)
0152 {
0153
0154 char nul = '\0';
0155
0156 test("", &nul);
0157 test("100%", "100%%");
0158 test("xxx%yyy", "xxx%cyyy", '%');
0159 __test("xxx\0yyy", 7, "xxx%cyyy", '\0');
0160 }
0161
0162 static void __init
0163 test_number(void)
0164 {
0165 test("0x1234abcd ", "%#-12x", 0x1234abcd);
0166 test(" 0x1234abcd", "%#12x", 0x1234abcd);
0167 test("0|001| 12|+123| 1234|-123|-1234", "%d|%03d|%3d|%+d|% d|%+d|% d", 0, 1, 12, 123, 1234, -123, -1234);
0168 NOWARN(-Wformat, "Intentionally test narrowing conversion specifiers.", {
0169 test("0|1|1|128|255", "%hhu|%hhu|%hhu|%hhu|%hhu", 0, 1, 257, 128, -1);
0170 test("0|1|1|-128|-1", "%hhd|%hhd|%hhd|%hhd|%hhd", 0, 1, 257, 128, -1);
0171 test("2015122420151225", "%ho%ho%#ho", 1037, 5282, -11627);
0172 })
0173
0174
0175
0176
0177
0178
0179
0180
0181 test("00|0|0|0|0", "%.2d|%.1d|%.0d|%.*d|%1.0d", 0, 0, 0, 0, 0, 0);
0182 #ifndef __CHAR_UNSIGNED__
0183 {
0184
0185
0186
0187
0188
0189
0190 char val = -16;
0191 test("0xfffffff0|0xf0|0xf0", "%#02x|%#02x|%#02x", val, val & 0xff, (u8)val);
0192 }
0193 #endif
0194 }
0195
0196 static void __init
0197 test_string(void)
0198 {
0199 test("", "%s%.0s", "", "123");
0200 test("ABCD|abc|123", "%s|%.3s|%.*s", "ABCD", "abcdef", 3, "123456");
0201 test("1 | 2|3 | 4|5 ", "%-3s|%3s|%-*s|%*s|%*s", "1", "2", 3, "3", 3, "4", -3, "5");
0202 test("1234 ", "%-10.4s", "123456");
0203 test(" 1234", "%10.4s", "123456");
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217 test(" ", "%4.*s", -5, "123456");
0218 test("123456", "%.s", "123456");
0219 test("a||", "%.s|%.0s|%.*s", "a", "b", 0, "c");
0220 test("a | | ", "%-3.s|%-3.0s|%-3.*s", "a", "b", 0, "c");
0221 }
0222
0223 #define PLAIN_BUF_SIZE 64
0224
0225 #if BITS_PER_LONG == 64
0226
0227 #define PTR_WIDTH 16
0228 #define PTR ((void *)0xffff0123456789abUL)
0229 #define PTR_STR "ffff0123456789ab"
0230 #define PTR_VAL_NO_CRNG "(____ptrval____)"
0231 #define ZEROS "00000000"
0232 #define ONES "ffffffff"
0233
0234 static int __init
0235 plain_format(void)
0236 {
0237 char buf[PLAIN_BUF_SIZE];
0238 int nchars;
0239
0240 nchars = snprintf(buf, PLAIN_BUF_SIZE, "%p", PTR);
0241
0242 if (nchars != PTR_WIDTH)
0243 return -1;
0244
0245 if (strncmp(buf, PTR_VAL_NO_CRNG, PTR_WIDTH) == 0) {
0246 pr_warn("crng possibly not yet initialized. plain 'p' buffer contains \"%s\"",
0247 PTR_VAL_NO_CRNG);
0248 return 0;
0249 }
0250
0251 if (strncmp(buf, ZEROS, strlen(ZEROS)) != 0)
0252 return -1;
0253
0254 return 0;
0255 }
0256
0257 #else
0258
0259 #define PTR_WIDTH 8
0260 #define PTR ((void *)0x456789ab)
0261 #define PTR_STR "456789ab"
0262 #define PTR_VAL_NO_CRNG "(ptrval)"
0263 #define ZEROS ""
0264 #define ONES ""
0265
0266 static int __init
0267 plain_format(void)
0268 {
0269
0270 return 0;
0271 }
0272
0273 #endif
0274
0275 static int __init
0276 plain_hash_to_buffer(const void *p, char *buf, size_t len)
0277 {
0278 int nchars;
0279
0280 nchars = snprintf(buf, len, "%p", p);
0281
0282 if (nchars != PTR_WIDTH)
0283 return -1;
0284
0285 if (strncmp(buf, PTR_VAL_NO_CRNG, PTR_WIDTH) == 0) {
0286 pr_warn("crng possibly not yet initialized. plain 'p' buffer contains \"%s\"",
0287 PTR_VAL_NO_CRNG);
0288 return 0;
0289 }
0290
0291 return 0;
0292 }
0293
0294 static int __init
0295 plain_hash(void)
0296 {
0297 char buf[PLAIN_BUF_SIZE];
0298 int ret;
0299
0300 ret = plain_hash_to_buffer(PTR, buf, PLAIN_BUF_SIZE);
0301 if (ret)
0302 return ret;
0303
0304 if (strncmp(buf, PTR_STR, PTR_WIDTH) == 0)
0305 return -1;
0306
0307 return 0;
0308 }
0309
0310
0311
0312
0313
0314 static void __init
0315 plain(void)
0316 {
0317 int err;
0318
0319 if (no_hash_pointers) {
0320 pr_warn("skipping plain 'p' tests");
0321 skipped_tests += 2;
0322 return;
0323 }
0324
0325 err = plain_hash();
0326 if (err) {
0327 pr_warn("plain 'p' does not appear to be hashed\n");
0328 failed_tests++;
0329 return;
0330 }
0331
0332 err = plain_format();
0333 if (err) {
0334 pr_warn("hashing plain 'p' has unexpected format\n");
0335 failed_tests++;
0336 }
0337 }
0338
0339 static void __init
0340 test_hashed(const char *fmt, const void *p)
0341 {
0342 char buf[PLAIN_BUF_SIZE];
0343 int ret;
0344
0345
0346
0347
0348
0349 ret = plain_hash_to_buffer(p, buf, PLAIN_BUF_SIZE);
0350 if (ret)
0351 return;
0352
0353 test(buf, fmt, p);
0354 }
0355
0356
0357
0358
0359 static void __init
0360 null_pointer(void)
0361 {
0362 test(ZEROS "00000000", "%p", NULL);
0363 test(ZEROS "00000000", "%px", NULL);
0364 test("(null)", "%pE", NULL);
0365 }
0366
0367
0368
0369
0370 static void __init
0371 error_pointer(void)
0372 {
0373 test(ONES "fffffff5", "%p", ERR_PTR(-11));
0374 test(ONES "fffffff5", "%px", ERR_PTR(-11));
0375 test("(efault)", "%pE", ERR_PTR(-11));
0376 }
0377
0378 #define PTR_INVALID ((void *)0x000000ab)
0379
0380 static void __init
0381 invalid_pointer(void)
0382 {
0383 test_hashed("%p", PTR_INVALID);
0384 test(ZEROS "000000ab", "%px", PTR_INVALID);
0385 test("(efault)", "%pE", PTR_INVALID);
0386 }
0387
0388 static void __init
0389 symbol_ptr(void)
0390 {
0391 }
0392
0393 static void __init
0394 kernel_ptr(void)
0395 {
0396
0397 }
0398
0399 static void __init
0400 struct_resource(void)
0401 {
0402 }
0403
0404 static void __init
0405 addr(void)
0406 {
0407 }
0408
0409 static void __init
0410 escaped_str(void)
0411 {
0412 }
0413
0414 static void __init
0415 hex_string(void)
0416 {
0417 const char buf[3] = {0xc0, 0xff, 0xee};
0418
0419 test("c0 ff ee|c0:ff:ee|c0-ff-ee|c0ffee",
0420 "%3ph|%3phC|%3phD|%3phN", buf, buf, buf, buf);
0421 test("c0 ff ee|c0:ff:ee|c0-ff-ee|c0ffee",
0422 "%*ph|%*phC|%*phD|%*phN", 3, buf, 3, buf, 3, buf, 3, buf);
0423 }
0424
0425 static void __init
0426 mac(void)
0427 {
0428 const u8 addr[6] = {0x2d, 0x48, 0xd6, 0xfc, 0x7a, 0x05};
0429
0430 test("2d:48:d6:fc:7a:05", "%pM", addr);
0431 test("05:7a:fc:d6:48:2d", "%pMR", addr);
0432 test("2d-48-d6-fc-7a-05", "%pMF", addr);
0433 test("2d48d6fc7a05", "%pm", addr);
0434 test("057afcd6482d", "%pmR", addr);
0435 }
0436
0437 static void __init
0438 ip4(void)
0439 {
0440 struct sockaddr_in sa;
0441
0442 sa.sin_family = AF_INET;
0443 sa.sin_port = cpu_to_be16(12345);
0444 sa.sin_addr.s_addr = cpu_to_be32(0x7f000001);
0445
0446 test("127.000.000.001|127.0.0.1", "%pi4|%pI4", &sa.sin_addr, &sa.sin_addr);
0447 test("127.000.000.001|127.0.0.1", "%piS|%pIS", &sa, &sa);
0448 sa.sin_addr.s_addr = cpu_to_be32(0x01020304);
0449 test("001.002.003.004:12345|1.2.3.4:12345", "%piSp|%pISp", &sa, &sa);
0450 }
0451
0452 static void __init
0453 ip6(void)
0454 {
0455 }
0456
0457 static void __init
0458 ip(void)
0459 {
0460 ip4();
0461 ip6();
0462 }
0463
0464 static void __init
0465 uuid(void)
0466 {
0467 const char uuid[16] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0468 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
0469
0470 test("00010203-0405-0607-0809-0a0b0c0d0e0f", "%pUb", uuid);
0471 test("00010203-0405-0607-0809-0A0B0C0D0E0F", "%pUB", uuid);
0472 test("03020100-0504-0706-0809-0a0b0c0d0e0f", "%pUl", uuid);
0473 test("03020100-0504-0706-0809-0A0B0C0D0E0F", "%pUL", uuid);
0474 }
0475
0476 static struct dentry test_dentry[4] __initdata = {
0477 { .d_parent = &test_dentry[0],
0478 .d_name = QSTR_INIT(test_dentry[0].d_iname, 3),
0479 .d_iname = "foo" },
0480 { .d_parent = &test_dentry[0],
0481 .d_name = QSTR_INIT(test_dentry[1].d_iname, 5),
0482 .d_iname = "bravo" },
0483 { .d_parent = &test_dentry[1],
0484 .d_name = QSTR_INIT(test_dentry[2].d_iname, 4),
0485 .d_iname = "alfa" },
0486 { .d_parent = &test_dentry[2],
0487 .d_name = QSTR_INIT(test_dentry[3].d_iname, 5),
0488 .d_iname = "romeo" },
0489 };
0490
0491 static void __init
0492 dentry(void)
0493 {
0494 test("foo", "%pd", &test_dentry[0]);
0495 test("foo", "%pd2", &test_dentry[0]);
0496
0497 test("(null)", "%pd", NULL);
0498 test("(efault)", "%pd", PTR_INVALID);
0499 test("(null)", "%pD", NULL);
0500 test("(efault)", "%pD", PTR_INVALID);
0501
0502 test("romeo", "%pd", &test_dentry[3]);
0503 test("alfa/romeo", "%pd2", &test_dentry[3]);
0504 test("bravo/alfa/romeo", "%pd3", &test_dentry[3]);
0505 test("/bravo/alfa/romeo", "%pd4", &test_dentry[3]);
0506 test("/bravo/alfa", "%pd4", &test_dentry[2]);
0507
0508 test("bravo/alfa |bravo/alfa ", "%-12pd2|%*pd2", &test_dentry[2], -12, &test_dentry[2]);
0509 test(" bravo/alfa| bravo/alfa", "%12pd2|%*pd2", &test_dentry[2], 12, &test_dentry[2]);
0510 }
0511
0512 static void __init
0513 struct_va_format(void)
0514 {
0515 }
0516
0517 static void __init
0518 time_and_date(void)
0519 {
0520
0521 const struct rtc_time tm = {
0522 .tm_sec = 43,
0523 .tm_min = 35,
0524 .tm_hour = 5,
0525 .tm_mday = 26,
0526 .tm_mon = 10,
0527 .tm_year = 118,
0528 };
0529
0530 time64_t t = 1546615943;
0531
0532 test("(%pt?)", "%pt", &tm);
0533 test("2018-11-26T05:35:43", "%ptR", &tm);
0534 test("0118-10-26T05:35:43", "%ptRr", &tm);
0535 test("05:35:43|2018-11-26", "%ptRt|%ptRd", &tm, &tm);
0536 test("05:35:43|0118-10-26", "%ptRtr|%ptRdr", &tm, &tm);
0537 test("05:35:43|2018-11-26", "%ptRttr|%ptRdtr", &tm, &tm);
0538 test("05:35:43 tr|2018-11-26 tr", "%ptRt tr|%ptRd tr", &tm, &tm);
0539
0540 test("2019-01-04T15:32:23", "%ptT", &t);
0541 test("0119-00-04T15:32:23", "%ptTr", &t);
0542 test("15:32:23|2019-01-04", "%ptTt|%ptTd", &t, &t);
0543 test("15:32:23|0119-00-04", "%ptTtr|%ptTdr", &t, &t);
0544
0545 test("2019-01-04 15:32:23", "%ptTs", &t);
0546 test("0119-00-04 15:32:23", "%ptTsr", &t);
0547 test("15:32:23|2019-01-04", "%ptTts|%ptTds", &t, &t);
0548 test("15:32:23|0119-00-04", "%ptTtrs|%ptTdrs", &t, &t);
0549 }
0550
0551 static void __init
0552 struct_clk(void)
0553 {
0554 }
0555
0556 static void __init
0557 large_bitmap(void)
0558 {
0559 const int nbits = 1 << 16;
0560 unsigned long *bits = bitmap_zalloc(nbits, GFP_KERNEL);
0561 if (!bits)
0562 return;
0563
0564 bitmap_set(bits, 1, 20);
0565 bitmap_set(bits, 60000, 15);
0566 test("1-20,60000-60014", "%*pbl", nbits, bits);
0567 bitmap_free(bits);
0568 }
0569
0570 static void __init
0571 bitmap(void)
0572 {
0573 DECLARE_BITMAP(bits, 20);
0574 const int primes[] = {2,3,5,7,11,13,17,19};
0575 int i;
0576
0577 bitmap_zero(bits, 20);
0578 test("00000|00000", "%20pb|%*pb", bits, 20, bits);
0579 test("|", "%20pbl|%*pbl", bits, 20, bits);
0580
0581 for (i = 0; i < ARRAY_SIZE(primes); ++i)
0582 set_bit(primes[i], bits);
0583 test("a28ac|a28ac", "%20pb|%*pb", bits, 20, bits);
0584 test("2-3,5,7,11,13,17,19|2-3,5,7,11,13,17,19", "%20pbl|%*pbl", bits, 20, bits);
0585
0586 bitmap_fill(bits, 20);
0587 test("fffff|fffff", "%20pb|%*pb", bits, 20, bits);
0588 test("0-19|0-19", "%20pbl|%*pbl", bits, 20, bits);
0589
0590 large_bitmap();
0591 }
0592
0593 static void __init
0594 netdev_features(void)
0595 {
0596 }
0597
0598 struct page_flags_test {
0599 int width;
0600 int shift;
0601 int mask;
0602 const char *fmt;
0603 const char *name;
0604 };
0605
0606 static const struct page_flags_test pft[] = {
0607 {SECTIONS_WIDTH, SECTIONS_PGSHIFT, SECTIONS_MASK,
0608 "%d", "section"},
0609 {NODES_WIDTH, NODES_PGSHIFT, NODES_MASK,
0610 "%d", "node"},
0611 {ZONES_WIDTH, ZONES_PGSHIFT, ZONES_MASK,
0612 "%d", "zone"},
0613 {LAST_CPUPID_WIDTH, LAST_CPUPID_PGSHIFT, LAST_CPUPID_MASK,
0614 "%#x", "lastcpupid"},
0615 {KASAN_TAG_WIDTH, KASAN_TAG_PGSHIFT, KASAN_TAG_MASK,
0616 "%#x", "kasantag"},
0617 };
0618
0619 static void __init
0620 page_flags_test(int section, int node, int zone, int last_cpupid,
0621 int kasan_tag, unsigned long flags, const char *name,
0622 char *cmp_buf)
0623 {
0624 unsigned long values[] = {section, node, zone, last_cpupid, kasan_tag};
0625 unsigned long size;
0626 bool append = false;
0627 int i;
0628
0629 for (i = 0; i < ARRAY_SIZE(values); i++)
0630 flags |= (values[i] & pft[i].mask) << pft[i].shift;
0631
0632 size = scnprintf(cmp_buf, BUF_SIZE, "%#lx(", flags);
0633 if (flags & PAGEFLAGS_MASK) {
0634 size += scnprintf(cmp_buf + size, BUF_SIZE - size, "%s", name);
0635 append = true;
0636 }
0637
0638 for (i = 0; i < ARRAY_SIZE(pft); i++) {
0639 if (!pft[i].width)
0640 continue;
0641
0642 if (append)
0643 size += scnprintf(cmp_buf + size, BUF_SIZE - size, "|");
0644
0645 size += scnprintf(cmp_buf + size, BUF_SIZE - size, "%s=",
0646 pft[i].name);
0647 size += scnprintf(cmp_buf + size, BUF_SIZE - size, pft[i].fmt,
0648 values[i] & pft[i].mask);
0649 append = true;
0650 }
0651
0652 snprintf(cmp_buf + size, BUF_SIZE - size, ")");
0653
0654 test(cmp_buf, "%pGp", &flags);
0655 }
0656
0657 static void __init
0658 flags(void)
0659 {
0660 unsigned long flags;
0661 char *cmp_buffer;
0662 gfp_t gfp;
0663
0664 cmp_buffer = kmalloc(BUF_SIZE, GFP_KERNEL);
0665 if (!cmp_buffer)
0666 return;
0667
0668 flags = 0;
0669 page_flags_test(0, 0, 0, 0, 0, flags, "", cmp_buffer);
0670
0671 flags = 1UL << NR_PAGEFLAGS;
0672 page_flags_test(0, 0, 0, 0, 0, flags, "", cmp_buffer);
0673
0674 flags |= 1UL << PG_uptodate | 1UL << PG_dirty | 1UL << PG_lru
0675 | 1UL << PG_active | 1UL << PG_swapbacked;
0676 page_flags_test(1, 1, 1, 0x1fffff, 1, flags,
0677 "uptodate|dirty|lru|active|swapbacked",
0678 cmp_buffer);
0679
0680 flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
0681 test("read|exec|mayread|maywrite|mayexec", "%pGv", &flags);
0682
0683 gfp = GFP_TRANSHUGE;
0684 test("GFP_TRANSHUGE", "%pGg", &gfp);
0685
0686 gfp = GFP_ATOMIC|__GFP_DMA;
0687 test("GFP_ATOMIC|GFP_DMA", "%pGg", &gfp);
0688
0689 gfp = __GFP_ATOMIC;
0690 test("__GFP_ATOMIC", "%pGg", &gfp);
0691
0692
0693 gfp = ~__GFP_BITS_MASK;
0694 snprintf(cmp_buffer, BUF_SIZE, "%#lx", (unsigned long) gfp);
0695 test(cmp_buffer, "%pGg", &gfp);
0696
0697 snprintf(cmp_buffer, BUF_SIZE, "__GFP_ATOMIC|%#lx",
0698 (unsigned long) gfp);
0699 gfp |= __GFP_ATOMIC;
0700 test(cmp_buffer, "%pGg", &gfp);
0701
0702 kfree(cmp_buffer);
0703 }
0704
0705 static void __init fwnode_pointer(void)
0706 {
0707 const struct software_node softnodes[] = {
0708 { .name = "first", },
0709 { .name = "second", .parent = &softnodes[0], },
0710 { .name = "third", .parent = &softnodes[1], },
0711 { NULL }
0712 };
0713 const char * const full_name = "first/second/third";
0714 const char * const full_name_second = "first/second";
0715 const char * const second_name = "second";
0716 const char * const third_name = "third";
0717 int rval;
0718
0719 rval = software_node_register_nodes(softnodes);
0720 if (rval) {
0721 pr_warn("cannot register softnodes; rval %d\n", rval);
0722 return;
0723 }
0724
0725 test(full_name_second, "%pfw", software_node_fwnode(&softnodes[1]));
0726 test(full_name, "%pfw", software_node_fwnode(&softnodes[2]));
0727 test(full_name, "%pfwf", software_node_fwnode(&softnodes[2]));
0728 test(second_name, "%pfwP", software_node_fwnode(&softnodes[1]));
0729 test(third_name, "%pfwP", software_node_fwnode(&softnodes[2]));
0730
0731 software_node_unregister_nodes(softnodes);
0732 }
0733
0734 static void __init fourcc_pointer(void)
0735 {
0736 struct {
0737 u32 code;
0738 char *str;
0739 } const try[] = {
0740 { 0x3231564e, "NV12 little-endian (0x3231564e)", },
0741 { 0xb231564e, "NV12 big-endian (0xb231564e)", },
0742 { 0x10111213, ".... little-endian (0x10111213)", },
0743 { 0x20303159, "Y10 little-endian (0x20303159)", },
0744 };
0745 unsigned int i;
0746
0747 for (i = 0; i < ARRAY_SIZE(try); i++)
0748 test(try[i].str, "%p4cc", &try[i].code);
0749 }
0750
0751 static void __init
0752 errptr(void)
0753 {
0754 test("-1234", "%pe", ERR_PTR(-1234));
0755
0756
0757 BUILD_BUG_ON(IS_ERR(PTR));
0758 test_hashed("%pe", PTR);
0759
0760 #ifdef CONFIG_SYMBOLIC_ERRNAME
0761 test("(-ENOTSOCK)", "(%pe)", ERR_PTR(-ENOTSOCK));
0762 test("(-EAGAIN)", "(%pe)", ERR_PTR(-EAGAIN));
0763 BUILD_BUG_ON(EAGAIN != EWOULDBLOCK);
0764 test("(-EAGAIN)", "(%pe)", ERR_PTR(-EWOULDBLOCK));
0765 test("[-EIO ]", "[%-8pe]", ERR_PTR(-EIO));
0766 test("[ -EIO]", "[%8pe]", ERR_PTR(-EIO));
0767 test("-EPROBE_DEFER", "%pe", ERR_PTR(-EPROBE_DEFER));
0768 #endif
0769 }
0770
0771 static void __init
0772 test_pointer(void)
0773 {
0774 plain();
0775 null_pointer();
0776 error_pointer();
0777 invalid_pointer();
0778 symbol_ptr();
0779 kernel_ptr();
0780 struct_resource();
0781 addr();
0782 escaped_str();
0783 hex_string();
0784 mac();
0785 ip();
0786 uuid();
0787 dentry();
0788 struct_va_format();
0789 time_and_date();
0790 struct_clk();
0791 bitmap();
0792 netdev_features();
0793 flags();
0794 errptr();
0795 fwnode_pointer();
0796 fourcc_pointer();
0797 }
0798
0799 static void __init selftest(void)
0800 {
0801 alloced_buffer = kmalloc(BUF_SIZE + 2*PAD_SIZE, GFP_KERNEL);
0802 if (!alloced_buffer)
0803 return;
0804 test_buffer = alloced_buffer + PAD_SIZE;
0805
0806 test_basic();
0807 test_number();
0808 test_string();
0809 test_pointer();
0810
0811 kfree(alloced_buffer);
0812 }
0813
0814 KSTM_MODULE_LOADERS(test_printf);
0815 MODULE_AUTHOR("Rasmus Villemoes <linux@rasmusvillemoes.dk>");
0816 MODULE_LICENSE("GPL");