diff options
Diffstat (limited to 'tools')
24 files changed, 2182 insertions, 244 deletions
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index 7e0405e1651d..412a7c82995a 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c | |||
@@ -120,7 +120,7 @@ int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns, | |||
120 | int bpf_verify_program(enum bpf_prog_type type, const struct bpf_insn *insns, | 120 | int bpf_verify_program(enum bpf_prog_type type, const struct bpf_insn *insns, |
121 | size_t insns_cnt, int strict_alignment, | 121 | size_t insns_cnt, int strict_alignment, |
122 | const char *license, __u32 kern_version, | 122 | const char *license, __u32 kern_version, |
123 | char *log_buf, size_t log_buf_sz) | 123 | char *log_buf, size_t log_buf_sz, int log_level) |
124 | { | 124 | { |
125 | union bpf_attr attr; | 125 | union bpf_attr attr; |
126 | 126 | ||
@@ -131,7 +131,7 @@ int bpf_verify_program(enum bpf_prog_type type, const struct bpf_insn *insns, | |||
131 | attr.license = ptr_to_u64(license); | 131 | attr.license = ptr_to_u64(license); |
132 | attr.log_buf = ptr_to_u64(log_buf); | 132 | attr.log_buf = ptr_to_u64(log_buf); |
133 | attr.log_size = log_buf_sz; | 133 | attr.log_size = log_buf_sz; |
134 | attr.log_level = 2; | 134 | attr.log_level = log_level; |
135 | log_buf[0] = 0; | 135 | log_buf[0] = 0; |
136 | attr.kern_version = kern_version; | 136 | attr.kern_version = kern_version; |
137 | attr.prog_flags = strict_alignment ? BPF_F_STRICT_ALIGNMENT : 0; | 137 | attr.prog_flags = strict_alignment ? BPF_F_STRICT_ALIGNMENT : 0; |
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h index 16de44a14b48..418c86e69bcb 100644 --- a/tools/lib/bpf/bpf.h +++ b/tools/lib/bpf/bpf.h | |||
@@ -38,7 +38,7 @@ int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns, | |||
38 | int bpf_verify_program(enum bpf_prog_type type, const struct bpf_insn *insns, | 38 | int bpf_verify_program(enum bpf_prog_type type, const struct bpf_insn *insns, |
39 | size_t insns_cnt, int strict_alignment, | 39 | size_t insns_cnt, int strict_alignment, |
40 | const char *license, __u32 kern_version, | 40 | const char *license, __u32 kern_version, |
41 | char *log_buf, size_t log_buf_sz); | 41 | char *log_buf, size_t log_buf_sz, int log_level); |
42 | 42 | ||
43 | int bpf_map_update_elem(int fd, const void *key, const void *value, | 43 | int bpf_map_update_elem(int fd, const void *key, const void *value, |
44 | __u64 flags); | 44 | __u64 flags); |
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 0a8a1c45af87..a1497c516d85 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c | |||
@@ -643,7 +643,7 @@ static const struct { | |||
643 | { "__GFP_FS", "F" }, | 643 | { "__GFP_FS", "F" }, |
644 | { "__GFP_COLD", "CO" }, | 644 | { "__GFP_COLD", "CO" }, |
645 | { "__GFP_NOWARN", "NWR" }, | 645 | { "__GFP_NOWARN", "NWR" }, |
646 | { "__GFP_REPEAT", "R" }, | 646 | { "__GFP_RETRY_MAYFAIL", "R" }, |
647 | { "__GFP_NOFAIL", "NF" }, | 647 | { "__GFP_NOFAIL", "NF" }, |
648 | { "__GFP_NORETRY", "NR" }, | 648 | { "__GFP_NORETRY", "NR" }, |
649 | { "__GFP_COMP", "C" }, | 649 | { "__GFP_COMP", "C" }, |
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index a4d3762cd825..83874b0e266c 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c | |||
@@ -704,7 +704,7 @@ static void __ui_browser__line_arrow_down(struct ui_browser *browser, | |||
704 | ui_browser__gotorc(browser, row, column + 1); | 704 | ui_browser__gotorc(browser, row, column + 1); |
705 | SLsmg_draw_hline(2); | 705 | SLsmg_draw_hline(2); |
706 | 706 | ||
707 | if (row++ == 0) | 707 | if (++row == 0) |
708 | goto out; | 708 | goto out; |
709 | } else | 709 | } else |
710 | row = 0; | 710 | row = 0; |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 87b431886670..413f74df08de 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -273,7 +273,7 @@ struct perf_evsel *perf_evsel__new_cycles(void) | |||
273 | struct perf_event_attr attr = { | 273 | struct perf_event_attr attr = { |
274 | .type = PERF_TYPE_HARDWARE, | 274 | .type = PERF_TYPE_HARDWARE, |
275 | .config = PERF_COUNT_HW_CPU_CYCLES, | 275 | .config = PERF_COUNT_HW_CPU_CYCLES, |
276 | .exclude_kernel = 1, | 276 | .exclude_kernel = geteuid() != 0, |
277 | }; | 277 | }; |
278 | struct perf_evsel *evsel; | 278 | struct perf_evsel *evsel; |
279 | 279 | ||
@@ -298,8 +298,10 @@ struct perf_evsel *perf_evsel__new_cycles(void) | |||
298 | goto out; | 298 | goto out; |
299 | 299 | ||
300 | /* use asprintf() because free(evsel) assumes name is allocated */ | 300 | /* use asprintf() because free(evsel) assumes name is allocated */ |
301 | if (asprintf(&evsel->name, "cycles%.*s", | 301 | if (asprintf(&evsel->name, "cycles%s%s%.*s", |
302 | attr.precise_ip ? attr.precise_ip + 1 : 0, ":ppp") < 0) | 302 | (attr.precise_ip || attr.exclude_kernel) ? ":" : "", |
303 | attr.exclude_kernel ? "u" : "", | ||
304 | attr.precise_ip ? attr.precise_ip + 1 : 0, "ppp") < 0) | ||
303 | goto error_free; | 305 | goto error_free; |
304 | out: | 306 | out: |
305 | return evsel; | 307 | return evsel; |
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 5de2b86b9880..2e9eb6aa3ce2 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -2209,7 +2209,7 @@ int machine__get_kernel_start(struct machine *machine) | |||
2209 | machine->kernel_start = 1ULL << 63; | 2209 | machine->kernel_start = 1ULL << 63; |
2210 | if (map) { | 2210 | if (map) { |
2211 | err = map__load(map); | 2211 | err = map__load(map); |
2212 | if (map->start) | 2212 | if (!err) |
2213 | machine->kernel_start = map->start; | 2213 | machine->kernel_start = map->start; |
2214 | } | 2214 | } |
2215 | return err; | 2215 | return err; |
diff --git a/tools/testing/selftests/bpf/test_align.c b/tools/testing/selftests/bpf/test_align.c index bccebd935907..29793694cbc7 100644 --- a/tools/testing/selftests/bpf/test_align.c +++ b/tools/testing/selftests/bpf/test_align.c | |||
@@ -380,7 +380,7 @@ static int do_test_single(struct bpf_align_test *test) | |||
380 | prog_len = probe_filter_length(prog); | 380 | prog_len = probe_filter_length(prog); |
381 | fd_prog = bpf_verify_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER, | 381 | fd_prog = bpf_verify_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER, |
382 | prog, prog_len, 1, "GPL", 0, | 382 | prog, prog_len, 1, "GPL", 0, |
383 | bpf_vlog, sizeof(bpf_vlog)); | 383 | bpf_vlog, sizeof(bpf_vlog), 2); |
384 | if (fd_prog < 0) { | 384 | if (fd_prog < 0) { |
385 | printf("Failed to load program.\n"); | 385 | printf("Failed to load program.\n"); |
386 | printf("%s", bpf_vlog); | 386 | printf("%s", bpf_vlog); |
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index 404aec520812..af7d173910f4 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c | |||
@@ -4969,7 +4969,7 @@ static struct bpf_test tests[] = { | |||
4969 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, | 4969 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, |
4970 | sizeof(struct test_val), 4), | 4970 | sizeof(struct test_val), 4), |
4971 | BPF_MOV64_IMM(BPF_REG_4, 0), | 4971 | BPF_MOV64_IMM(BPF_REG_4, 0), |
4972 | BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2), | 4972 | BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2), |
4973 | BPF_MOV64_IMM(BPF_REG_3, 0), | 4973 | BPF_MOV64_IMM(BPF_REG_3, 0), |
4974 | BPF_EMIT_CALL(BPF_FUNC_probe_read), | 4974 | BPF_EMIT_CALL(BPF_FUNC_probe_read), |
4975 | BPF_MOV64_IMM(BPF_REG_0, 0), | 4975 | BPF_MOV64_IMM(BPF_REG_0, 0), |
@@ -4995,7 +4995,7 @@ static struct bpf_test tests[] = { | |||
4995 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, | 4995 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, |
4996 | sizeof(struct test_val) + 1, 4), | 4996 | sizeof(struct test_val) + 1, 4), |
4997 | BPF_MOV64_IMM(BPF_REG_4, 0), | 4997 | BPF_MOV64_IMM(BPF_REG_4, 0), |
4998 | BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2), | 4998 | BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2), |
4999 | BPF_MOV64_IMM(BPF_REG_3, 0), | 4999 | BPF_MOV64_IMM(BPF_REG_3, 0), |
5000 | BPF_EMIT_CALL(BPF_FUNC_probe_read), | 5000 | BPF_EMIT_CALL(BPF_FUNC_probe_read), |
5001 | BPF_MOV64_IMM(BPF_REG_0, 0), | 5001 | BPF_MOV64_IMM(BPF_REG_0, 0), |
@@ -5023,7 +5023,7 @@ static struct bpf_test tests[] = { | |||
5023 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, | 5023 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, |
5024 | sizeof(struct test_val) - 20, 4), | 5024 | sizeof(struct test_val) - 20, 4), |
5025 | BPF_MOV64_IMM(BPF_REG_4, 0), | 5025 | BPF_MOV64_IMM(BPF_REG_4, 0), |
5026 | BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2), | 5026 | BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2), |
5027 | BPF_MOV64_IMM(BPF_REG_3, 0), | 5027 | BPF_MOV64_IMM(BPF_REG_3, 0), |
5028 | BPF_EMIT_CALL(BPF_FUNC_probe_read), | 5028 | BPF_EMIT_CALL(BPF_FUNC_probe_read), |
5029 | BPF_MOV64_IMM(BPF_REG_0, 0), | 5029 | BPF_MOV64_IMM(BPF_REG_0, 0), |
@@ -5050,7 +5050,7 @@ static struct bpf_test tests[] = { | |||
5050 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, | 5050 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, |
5051 | sizeof(struct test_val) - 19, 4), | 5051 | sizeof(struct test_val) - 19, 4), |
5052 | BPF_MOV64_IMM(BPF_REG_4, 0), | 5052 | BPF_MOV64_IMM(BPF_REG_4, 0), |
5053 | BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2), | 5053 | BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2), |
5054 | BPF_MOV64_IMM(BPF_REG_3, 0), | 5054 | BPF_MOV64_IMM(BPF_REG_3, 0), |
5055 | BPF_EMIT_CALL(BPF_FUNC_probe_read), | 5055 | BPF_EMIT_CALL(BPF_FUNC_probe_read), |
5056 | BPF_MOV64_IMM(BPF_REG_0, 0), | 5056 | BPF_MOV64_IMM(BPF_REG_0, 0), |
@@ -5510,6 +5510,476 @@ static struct bpf_test tests[] = { | |||
5510 | .errstr = "invalid bpf_context access", | 5510 | .errstr = "invalid bpf_context access", |
5511 | .prog_type = BPF_PROG_TYPE_LWT_IN, | 5511 | .prog_type = BPF_PROG_TYPE_LWT_IN, |
5512 | }, | 5512 | }, |
5513 | { | ||
5514 | "bounds checks mixing signed and unsigned, positive bounds", | ||
5515 | .insns = { | ||
5516 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5517 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5518 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5519 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5520 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
5521 | BPF_FUNC_map_lookup_elem), | ||
5522 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7), | ||
5523 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8), | ||
5524 | BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), | ||
5525 | BPF_MOV64_IMM(BPF_REG_2, 2), | ||
5526 | BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 3), | ||
5527 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 4, 2), | ||
5528 | BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), | ||
5529 | BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0), | ||
5530 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5531 | BPF_EXIT_INSN(), | ||
5532 | }, | ||
5533 | .fixup_map1 = { 3 }, | ||
5534 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
5535 | .errstr = "R0 min value is negative", | ||
5536 | .result = REJECT, | ||
5537 | .result_unpriv = REJECT, | ||
5538 | }, | ||
5539 | { | ||
5540 | "bounds checks mixing signed and unsigned", | ||
5541 | .insns = { | ||
5542 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5543 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5544 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5545 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5546 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
5547 | BPF_FUNC_map_lookup_elem), | ||
5548 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7), | ||
5549 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8), | ||
5550 | BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), | ||
5551 | BPF_MOV64_IMM(BPF_REG_2, -1), | ||
5552 | BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3), | ||
5553 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2), | ||
5554 | BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), | ||
5555 | BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0), | ||
5556 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5557 | BPF_EXIT_INSN(), | ||
5558 | }, | ||
5559 | .fixup_map1 = { 3 }, | ||
5560 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
5561 | .errstr = "R0 min value is negative", | ||
5562 | .result = REJECT, | ||
5563 | .result_unpriv = REJECT, | ||
5564 | }, | ||
5565 | { | ||
5566 | "bounds checks mixing signed and unsigned, variant 2", | ||
5567 | .insns = { | ||
5568 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5569 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5570 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5571 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5572 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
5573 | BPF_FUNC_map_lookup_elem), | ||
5574 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9), | ||
5575 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8), | ||
5576 | BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), | ||
5577 | BPF_MOV64_IMM(BPF_REG_2, -1), | ||
5578 | BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5), | ||
5579 | BPF_MOV64_IMM(BPF_REG_8, 0), | ||
5580 | BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_1), | ||
5581 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2), | ||
5582 | BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8), | ||
5583 | BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0), | ||
5584 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5585 | BPF_EXIT_INSN(), | ||
5586 | }, | ||
5587 | .fixup_map1 = { 3 }, | ||
5588 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
5589 | .errstr = "R8 invalid mem access 'inv'", | ||
5590 | .result = REJECT, | ||
5591 | .result_unpriv = REJECT, | ||
5592 | }, | ||
5593 | { | ||
5594 | "bounds checks mixing signed and unsigned, variant 3", | ||
5595 | .insns = { | ||
5596 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5597 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5598 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5599 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5600 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
5601 | BPF_FUNC_map_lookup_elem), | ||
5602 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8), | ||
5603 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8), | ||
5604 | BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), | ||
5605 | BPF_MOV64_IMM(BPF_REG_2, -1), | ||
5606 | BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 4), | ||
5607 | BPF_MOV64_REG(BPF_REG_8, BPF_REG_1), | ||
5608 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2), | ||
5609 | BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8), | ||
5610 | BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0), | ||
5611 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5612 | BPF_EXIT_INSN(), | ||
5613 | }, | ||
5614 | .fixup_map1 = { 3 }, | ||
5615 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
5616 | .errstr = "R8 invalid mem access 'inv'", | ||
5617 | .result = REJECT, | ||
5618 | .result_unpriv = REJECT, | ||
5619 | }, | ||
5620 | { | ||
5621 | "bounds checks mixing signed and unsigned, variant 4", | ||
5622 | .insns = { | ||
5623 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5624 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5625 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5626 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5627 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
5628 | BPF_FUNC_map_lookup_elem), | ||
5629 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7), | ||
5630 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8), | ||
5631 | BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), | ||
5632 | BPF_MOV64_IMM(BPF_REG_2, 1), | ||
5633 | BPF_ALU64_REG(BPF_AND, BPF_REG_1, BPF_REG_2), | ||
5634 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2), | ||
5635 | BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), | ||
5636 | BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0), | ||
5637 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5638 | BPF_EXIT_INSN(), | ||
5639 | }, | ||
5640 | .fixup_map1 = { 3 }, | ||
5641 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
5642 | .errstr = "R0 min value is negative", | ||
5643 | .result = REJECT, | ||
5644 | .result_unpriv = REJECT, | ||
5645 | }, | ||
5646 | { | ||
5647 | "bounds checks mixing signed and unsigned, variant 5", | ||
5648 | .insns = { | ||
5649 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5650 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5651 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5652 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5653 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
5654 | BPF_FUNC_map_lookup_elem), | ||
5655 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9), | ||
5656 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8), | ||
5657 | BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), | ||
5658 | BPF_MOV64_IMM(BPF_REG_2, -1), | ||
5659 | BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5), | ||
5660 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 4), | ||
5661 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 4), | ||
5662 | BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), | ||
5663 | BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0), | ||
5664 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5665 | BPF_EXIT_INSN(), | ||
5666 | }, | ||
5667 | .fixup_map1 = { 3 }, | ||
5668 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
5669 | .errstr = "R0 invalid mem access", | ||
5670 | .result = REJECT, | ||
5671 | .result_unpriv = REJECT, | ||
5672 | }, | ||
5673 | { | ||
5674 | "bounds checks mixing signed and unsigned, variant 6", | ||
5675 | .insns = { | ||
5676 | BPF_MOV64_IMM(BPF_REG_2, 0), | ||
5677 | BPF_MOV64_REG(BPF_REG_3, BPF_REG_10), | ||
5678 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, -512), | ||
5679 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8), | ||
5680 | BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -16), | ||
5681 | BPF_MOV64_IMM(BPF_REG_6, -1), | ||
5682 | BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_6, 5), | ||
5683 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_4, 1, 4), | ||
5684 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 1), | ||
5685 | BPF_MOV64_IMM(BPF_REG_5, 0), | ||
5686 | BPF_ST_MEM(BPF_H, BPF_REG_10, -512, 0), | ||
5687 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
5688 | BPF_FUNC_skb_load_bytes), | ||
5689 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5690 | BPF_EXIT_INSN(), | ||
5691 | }, | ||
5692 | .errstr_unpriv = "R4 min value is negative, either use unsigned", | ||
5693 | .errstr = "R4 min value is negative, either use unsigned", | ||
5694 | .result = REJECT, | ||
5695 | .result_unpriv = REJECT, | ||
5696 | }, | ||
5697 | { | ||
5698 | "bounds checks mixing signed and unsigned, variant 7", | ||
5699 | .insns = { | ||
5700 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5701 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5702 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5703 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5704 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
5705 | BPF_FUNC_map_lookup_elem), | ||
5706 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7), | ||
5707 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8), | ||
5708 | BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), | ||
5709 | BPF_MOV64_IMM(BPF_REG_2, 1024 * 1024 * 1024), | ||
5710 | BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3), | ||
5711 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2), | ||
5712 | BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), | ||
5713 | BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0), | ||
5714 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5715 | BPF_EXIT_INSN(), | ||
5716 | }, | ||
5717 | .fixup_map1 = { 3 }, | ||
5718 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
5719 | .errstr = "R0 min value is negative", | ||
5720 | .result = REJECT, | ||
5721 | .result_unpriv = REJECT, | ||
5722 | }, | ||
5723 | { | ||
5724 | "bounds checks mixing signed and unsigned, variant 8", | ||
5725 | .insns = { | ||
5726 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5727 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5728 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5729 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5730 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
5731 | BPF_FUNC_map_lookup_elem), | ||
5732 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7), | ||
5733 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8), | ||
5734 | BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), | ||
5735 | BPF_MOV64_IMM(BPF_REG_2, 1024 * 1024 * 1024 + 1), | ||
5736 | BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3), | ||
5737 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2), | ||
5738 | BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), | ||
5739 | BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0), | ||
5740 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5741 | BPF_EXIT_INSN(), | ||
5742 | }, | ||
5743 | .fixup_map1 = { 3 }, | ||
5744 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
5745 | .errstr = "R0 min value is negative", | ||
5746 | .result = REJECT, | ||
5747 | .result_unpriv = REJECT, | ||
5748 | }, | ||
5749 | { | ||
5750 | "bounds checks mixing signed and unsigned, variant 9", | ||
5751 | .insns = { | ||
5752 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5753 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5754 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5755 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5756 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
5757 | BPF_FUNC_map_lookup_elem), | ||
5758 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9), | ||
5759 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8), | ||
5760 | BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), | ||
5761 | BPF_MOV64_IMM(BPF_REG_2, -1), | ||
5762 | BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2), | ||
5763 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5764 | BPF_EXIT_INSN(), | ||
5765 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2), | ||
5766 | BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), | ||
5767 | BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0), | ||
5768 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5769 | BPF_EXIT_INSN(), | ||
5770 | }, | ||
5771 | .fixup_map1 = { 3 }, | ||
5772 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
5773 | .errstr = "R0 min value is negative", | ||
5774 | .result = REJECT, | ||
5775 | .result_unpriv = REJECT, | ||
5776 | }, | ||
5777 | { | ||
5778 | "bounds checks mixing signed and unsigned, variant 10", | ||
5779 | .insns = { | ||
5780 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5781 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5782 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5783 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5784 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
5785 | BPF_FUNC_map_lookup_elem), | ||
5786 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10), | ||
5787 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8), | ||
5788 | BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), | ||
5789 | BPF_LD_IMM64(BPF_REG_2, -9223372036854775808ULL), | ||
5790 | BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2), | ||
5791 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5792 | BPF_EXIT_INSN(), | ||
5793 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2), | ||
5794 | BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), | ||
5795 | BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0), | ||
5796 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5797 | BPF_EXIT_INSN(), | ||
5798 | }, | ||
5799 | .fixup_map1 = { 3 }, | ||
5800 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
5801 | .errstr = "R0 min value is negative", | ||
5802 | .result = REJECT, | ||
5803 | .result_unpriv = REJECT, | ||
5804 | }, | ||
5805 | { | ||
5806 | "bounds checks mixing signed and unsigned, variant 11", | ||
5807 | .insns = { | ||
5808 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5809 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5810 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5811 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5812 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
5813 | BPF_FUNC_map_lookup_elem), | ||
5814 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9), | ||
5815 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8), | ||
5816 | BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), | ||
5817 | BPF_MOV64_IMM(BPF_REG_2, 0), | ||
5818 | BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2), | ||
5819 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5820 | BPF_EXIT_INSN(), | ||
5821 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2), | ||
5822 | BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), | ||
5823 | BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0), | ||
5824 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5825 | BPF_EXIT_INSN(), | ||
5826 | }, | ||
5827 | .fixup_map1 = { 3 }, | ||
5828 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
5829 | .errstr = "R0 min value is negative", | ||
5830 | .result = REJECT, | ||
5831 | .result_unpriv = REJECT, | ||
5832 | }, | ||
5833 | { | ||
5834 | "bounds checks mixing signed and unsigned, variant 12", | ||
5835 | .insns = { | ||
5836 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5837 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5838 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5839 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5840 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
5841 | BPF_FUNC_map_lookup_elem), | ||
5842 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9), | ||
5843 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8), | ||
5844 | BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), | ||
5845 | BPF_MOV64_IMM(BPF_REG_2, -1), | ||
5846 | BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2), | ||
5847 | /* Dead branch. */ | ||
5848 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5849 | BPF_EXIT_INSN(), | ||
5850 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2), | ||
5851 | BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), | ||
5852 | BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0), | ||
5853 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5854 | BPF_EXIT_INSN(), | ||
5855 | }, | ||
5856 | .fixup_map1 = { 3 }, | ||
5857 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
5858 | .errstr = "R0 min value is negative", | ||
5859 | .result = REJECT, | ||
5860 | .result_unpriv = REJECT, | ||
5861 | }, | ||
5862 | { | ||
5863 | "bounds checks mixing signed and unsigned, variant 13", | ||
5864 | .insns = { | ||
5865 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5866 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5867 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5868 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5869 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
5870 | BPF_FUNC_map_lookup_elem), | ||
5871 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9), | ||
5872 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8), | ||
5873 | BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), | ||
5874 | BPF_MOV64_IMM(BPF_REG_2, -6), | ||
5875 | BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2), | ||
5876 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5877 | BPF_EXIT_INSN(), | ||
5878 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2), | ||
5879 | BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), | ||
5880 | BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0), | ||
5881 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5882 | BPF_EXIT_INSN(), | ||
5883 | }, | ||
5884 | .fixup_map1 = { 3 }, | ||
5885 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
5886 | .errstr = "R0 min value is negative", | ||
5887 | .result = REJECT, | ||
5888 | .result_unpriv = REJECT, | ||
5889 | }, | ||
5890 | { | ||
5891 | "bounds checks mixing signed and unsigned, variant 14", | ||
5892 | .insns = { | ||
5893 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5894 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5895 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5896 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5897 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
5898 | BPF_FUNC_map_lookup_elem), | ||
5899 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6), | ||
5900 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8), | ||
5901 | BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), | ||
5902 | BPF_MOV64_IMM(BPF_REG_2, 2), | ||
5903 | BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2), | ||
5904 | BPF_MOV64_IMM(BPF_REG_7, 1), | ||
5905 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 0, 2), | ||
5906 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5907 | BPF_EXIT_INSN(), | ||
5908 | BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_1), | ||
5909 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 4, 2), | ||
5910 | BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_7), | ||
5911 | BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0), | ||
5912 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5913 | BPF_EXIT_INSN(), | ||
5914 | }, | ||
5915 | .fixup_map1 = { 3 }, | ||
5916 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
5917 | .errstr = "R0 min value is negative", | ||
5918 | .result = REJECT, | ||
5919 | .result_unpriv = REJECT, | ||
5920 | }, | ||
5921 | { | ||
5922 | "bounds checks mixing signed and unsigned, variant 15", | ||
5923 | .insns = { | ||
5924 | BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_1, | ||
5925 | offsetof(struct __sk_buff, mark)), | ||
5926 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5927 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5928 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5929 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5930 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
5931 | BPF_FUNC_map_lookup_elem), | ||
5932 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8), | ||
5933 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8), | ||
5934 | BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), | ||
5935 | BPF_MOV64_IMM(BPF_REG_2, -1), | ||
5936 | BPF_MOV64_IMM(BPF_REG_8, 2), | ||
5937 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_9, 42, 6), | ||
5938 | BPF_JMP_REG(BPF_JSGT, BPF_REG_8, BPF_REG_1, 3), | ||
5939 | BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2), | ||
5940 | BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), | ||
5941 | BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0), | ||
5942 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5943 | BPF_EXIT_INSN(), | ||
5944 | BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, -3), | ||
5945 | BPF_JMP_IMM(BPF_JA, 0, 0, -7), | ||
5946 | }, | ||
5947 | .fixup_map1 = { 4 }, | ||
5948 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
5949 | .errstr = "R0 min value is negative", | ||
5950 | .result = REJECT, | ||
5951 | .result_unpriv = REJECT, | ||
5952 | }, | ||
5953 | { | ||
5954 | "bounds checks mixing signed and unsigned, variant 16", | ||
5955 | .insns = { | ||
5956 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5957 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5958 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5959 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5960 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
5961 | BPF_FUNC_map_lookup_elem), | ||
5962 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4), | ||
5963 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8), | ||
5964 | BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), | ||
5965 | BPF_MOV64_IMM(BPF_REG_2, -6), | ||
5966 | BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2), | ||
5967 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5968 | BPF_EXIT_INSN(), | ||
5969 | BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), | ||
5970 | BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 1, 2), | ||
5971 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5972 | BPF_EXIT_INSN(), | ||
5973 | BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0), | ||
5974 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
5975 | BPF_EXIT_INSN(), | ||
5976 | }, | ||
5977 | .fixup_map1 = { 3 }, | ||
5978 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
5979 | .errstr = "R0 min value is negative", | ||
5980 | .result = REJECT, | ||
5981 | .result_unpriv = REJECT, | ||
5982 | }, | ||
5513 | }; | 5983 | }; |
5514 | 5984 | ||
5515 | static int probe_filter_length(const struct bpf_insn *fp) | 5985 | static int probe_filter_length(const struct bpf_insn *fp) |
@@ -5633,7 +6103,7 @@ static void do_test_single(struct bpf_test *test, bool unpriv, | |||
5633 | 6103 | ||
5634 | fd_prog = bpf_verify_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER, | 6104 | fd_prog = bpf_verify_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER, |
5635 | prog, prog_len, test->flags & F_LOAD_WITH_STRICT_ALIGNMENT, | 6105 | prog, prog_len, test->flags & F_LOAD_WITH_STRICT_ALIGNMENT, |
5636 | "GPL", 0, bpf_vlog, sizeof(bpf_vlog)); | 6106 | "GPL", 0, bpf_vlog, sizeof(bpf_vlog), 1); |
5637 | 6107 | ||
5638 | expected_ret = unpriv && test->result_unpriv != UNDEF ? | 6108 | expected_ret = unpriv && test->result_unpriv != UNDEF ? |
5639 | test->result_unpriv : test->result; | 6109 | test->result_unpriv : test->result; |
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc new file mode 100644 index 000000000000..b9302cc82c12 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc | |||
@@ -0,0 +1,36 @@ | |||
1 | #!/bin/sh | ||
2 | # description: Kprobe event auto/manual naming | ||
3 | |||
4 | [ -f kprobe_events ] || exit_unsupported # this is configurable | ||
5 | |||
6 | disable_events | ||
7 | echo > kprobe_events | ||
8 | |||
9 | :;: "Add an event on function without name" ;: | ||
10 | |||
11 | FUNC=`grep " [tT] .*vfs_read$" /proc/kallsyms | tail -n 1 | cut -f 3 -d " "` | ||
12 | [ "x" != "x$FUNC" ] || exit_unresolved | ||
13 | echo "p $FUNC" > kprobe_events | ||
14 | PROBE_NAME=`echo $FUNC | tr ".:" "_"` | ||
15 | test -d events/kprobes/p_${PROBE_NAME}_0 || exit_failure | ||
16 | |||
17 | :;: "Add an event on function with new name" ;: | ||
18 | |||
19 | echo "p:event1 $FUNC" > kprobe_events | ||
20 | test -d events/kprobes/event1 || exit_failure | ||
21 | |||
22 | :;: "Add an event on function with new name and group" ;: | ||
23 | |||
24 | echo "p:kprobes2/event2 $FUNC" > kprobe_events | ||
25 | test -d events/kprobes2/event2 || exit_failure | ||
26 | |||
27 | :;: "Add an event on dot function without name" ;: | ||
28 | |||
29 | FUNC=`grep -m 10 " [tT] .*\.isra\..*$" /proc/kallsyms | tail -n 1 | cut -f 3 -d " "` | ||
30 | [ "x" != "x$FUNC" ] || exit_unresolved | ||
31 | echo "p $FUNC" > kprobe_events | ||
32 | EVENT=`grep $FUNC kprobe_events | cut -f 1 -d " " | cut -f 2 -d:` | ||
33 | [ "x" != "x$EVENT" ] || exit_failure | ||
34 | test -d events/$EVENT || exit_failure | ||
35 | |||
36 | echo > kprobe_events | ||
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_module.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_module.tc new file mode 100644 index 000000000000..6d634e4b7680 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_module.tc | |||
@@ -0,0 +1,28 @@ | |||
1 | #!/bin/sh | ||
2 | # description: Kprobe dynamic event - probing module | ||
3 | |||
4 | [ -f kprobe_events ] || exit_unsupported # this is configurable | ||
5 | |||
6 | disable_events | ||
7 | echo > kprobe_events | ||
8 | |||
9 | :;: "Add an event on a module function without specifying event name" ;: | ||
10 | |||
11 | MOD=`lsmod | head -n 2 | tail -n 1 | cut -f1 -d" "` | ||
12 | FUNC=`grep -m 1 ".* t .*\\[$MOD\\]" /proc/kallsyms | xargs | cut -f3 -d" "` | ||
13 | [ "x" != "x$MOD" -a "y" != "y$FUNC" ] || exit_unresolved | ||
14 | echo "p $MOD:$FUNC" > kprobe_events | ||
15 | PROBE_NAME=`echo $MOD:$FUNC | tr ".:" "_"` | ||
16 | test -d events/kprobes/p_${PROBE_NAME}_0 || exit_failure | ||
17 | |||
18 | :;: "Add an event on a module function with new event name" ;: | ||
19 | |||
20 | echo "p:event1 $MOD:$FUNC" > kprobe_events | ||
21 | test -d events/kprobes/event1 || exit_failure | ||
22 | |||
23 | :;: "Add an event on a module function with new event and group name" ;: | ||
24 | |||
25 | echo "p:kprobes1/event1 $MOD:$FUNC" > kprobe_events | ||
26 | test -d events/kprobes1/event1 || exit_failure | ||
27 | |||
28 | echo > kprobe_events | ||
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc b/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc index f4d1ff785d67..2a1cb9908746 100644 --- a/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc +++ b/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc | |||
@@ -2,10 +2,10 @@ | |||
2 | # description: Register/unregister many kprobe events | 2 | # description: Register/unregister many kprobe events |
3 | 3 | ||
4 | # ftrace fentry skip size depends on the machine architecture. | 4 | # ftrace fentry skip size depends on the machine architecture. |
5 | # Currently HAVE_KPROBES_ON_FTRACE defined on x86 and powerpc | 5 | # Currently HAVE_KPROBES_ON_FTRACE defined on x86 and powerpc64le |
6 | case `uname -m` in | 6 | case `uname -m` in |
7 | x86_64|i[3456]86) OFFS=5;; | 7 | x86_64|i[3456]86) OFFS=5;; |
8 | ppc*) OFFS=4;; | 8 | ppc64le) OFFS=8;; |
9 | *) OFFS=0;; | 9 | *) OFFS=0;; |
10 | esac | 10 | esac |
11 | 11 | ||
diff --git a/tools/testing/selftests/kmod/Makefile b/tools/testing/selftests/kmod/Makefile new file mode 100644 index 000000000000..fa2ccc5fb3de --- /dev/null +++ b/tools/testing/selftests/kmod/Makefile | |||
@@ -0,0 +1,11 @@ | |||
1 | # Makefile for kmod loading selftests | ||
2 | |||
3 | # No binaries, but make sure arg-less "make" doesn't trigger "run_tests" | ||
4 | all: | ||
5 | |||
6 | TEST_PROGS := kmod.sh | ||
7 | |||
8 | include ../lib.mk | ||
9 | |||
10 | # Nothing to clean up. | ||
11 | clean: | ||
diff --git a/tools/testing/selftests/kmod/config b/tools/testing/selftests/kmod/config new file mode 100644 index 000000000000..259f4fd6b5e2 --- /dev/null +++ b/tools/testing/selftests/kmod/config | |||
@@ -0,0 +1,7 @@ | |||
1 | CONFIG_TEST_KMOD=m | ||
2 | CONFIG_TEST_LKM=m | ||
3 | CONFIG_XFS_FS=m | ||
4 | |||
5 | # For the module parameter force_init_test is used | ||
6 | CONFIG_TUN=m | ||
7 | CONFIG_BTRFS_FS=m | ||
diff --git a/tools/testing/selftests/kmod/kmod.sh b/tools/testing/selftests/kmod/kmod.sh new file mode 100644 index 000000000000..8cecae9a8bca --- /dev/null +++ b/tools/testing/selftests/kmod/kmod.sh | |||
@@ -0,0 +1,615 @@ | |||
1 | #!/bin/bash | ||
2 | # | ||
3 | # Copyright (C) 2017 Luis R. Rodriguez <mcgrof@kernel.org> | ||
4 | # | ||
5 | # This program is free software; you can redistribute it and/or modify it | ||
6 | # under the terms of the GNU General Public License as published by the Free | ||
7 | # Software Foundation; either version 2 of the License, or at your option any | ||
8 | # later version; or, when distributed separately from the Linux kernel or | ||
9 | # when incorporated into other software packages, subject to the following | ||
10 | # license: | ||
11 | # | ||
12 | # This program is free software; you can redistribute it and/or modify it | ||
13 | # under the terms of copyleft-next (version 0.3.1 or later) as published | ||
14 | # at http://copyleft-next.org/. | ||
15 | |||
16 | # This is a stress test script for kmod, the kernel module loader. It uses | ||
17 | # test_kmod which exposes a series of knobs for the API for us so we can | ||
18 | # tweak each test in userspace rather than in kernelspace. | ||
19 | # | ||
20 | # The way kmod works is it uses the kernel's usermode helper API to eventually | ||
21 | # call /sbin/modprobe. It has a limit of the number of concurrent calls | ||
22 | # possible. The kernel interface to load modules is request_module(), however | ||
23 | # mount uses get_fs_type(). Both behave slightly differently, but the | ||
24 | # differences are important enough to test each call separately. For this | ||
25 | # reason test_kmod starts by providing tests for both calls. | ||
26 | # | ||
27 | # The test driver test_kmod assumes a series of defaults which you can | ||
28 | # override by exporting to your environment prior running this script. | ||
29 | # For instance this script assumes you do not have xfs loaded upon boot. | ||
30 | # If this is false, export DEFAULT_KMOD_FS="ext4" prior to running this | ||
31 | # script if the filesyste module you don't have loaded upon bootup | ||
32 | # is ext4 instead. Refer to allow_user_defaults() for a list of user | ||
33 | # override variables possible. | ||
34 | # | ||
35 | # You'll want at least 4 GiB of RAM to expect to run these tests | ||
36 | # without running out of memory on them. For other requirements refer | ||
37 | # to test_reqs() | ||
38 | |||
39 | set -e | ||
40 | |||
41 | TEST_NAME="kmod" | ||
42 | TEST_DRIVER="test_${TEST_NAME}" | ||
43 | TEST_DIR=$(dirname $0) | ||
44 | |||
45 | # This represents | ||
46 | # | ||
47 | # TEST_ID:TEST_COUNT:ENABLED | ||
48 | # | ||
49 | # TEST_ID: is the test id number | ||
50 | # TEST_COUNT: number of times we should run the test | ||
51 | # ENABLED: 1 if enabled, 0 otherwise | ||
52 | # | ||
53 | # Once these are enabled please leave them as-is. Write your own test, | ||
54 | # we have tons of space. | ||
55 | ALL_TESTS="0001:3:1" | ||
56 | ALL_TESTS="$ALL_TESTS 0002:3:1" | ||
57 | ALL_TESTS="$ALL_TESTS 0003:1:1" | ||
58 | ALL_TESTS="$ALL_TESTS 0004:1:1" | ||
59 | ALL_TESTS="$ALL_TESTS 0005:10:1" | ||
60 | ALL_TESTS="$ALL_TESTS 0006:10:1" | ||
61 | ALL_TESTS="$ALL_TESTS 0007:5:1" | ||
62 | ALL_TESTS="$ALL_TESTS 0008:150:1" | ||
63 | ALL_TESTS="$ALL_TESTS 0009:150:1" | ||
64 | |||
65 | test_modprobe() | ||
66 | { | ||
67 | if [ ! -d $DIR ]; then | ||
68 | echo "$0: $DIR not present" >&2 | ||
69 | echo "You must have the following enabled in your kernel:" >&2 | ||
70 | cat $TEST_DIR/config >&2 | ||
71 | exit 1 | ||
72 | fi | ||
73 | } | ||
74 | |||
75 | function allow_user_defaults() | ||
76 | { | ||
77 | if [ -z $DEFAULT_KMOD_DRIVER ]; then | ||
78 | DEFAULT_KMOD_DRIVER="test_module" | ||
79 | fi | ||
80 | |||
81 | if [ -z $DEFAULT_KMOD_FS ]; then | ||
82 | DEFAULT_KMOD_FS="xfs" | ||
83 | fi | ||
84 | |||
85 | if [ -z $PROC_DIR ]; then | ||
86 | PROC_DIR="/proc/sys/kernel/" | ||
87 | fi | ||
88 | |||
89 | if [ -z $MODPROBE_LIMIT ]; then | ||
90 | MODPROBE_LIMIT=50 | ||
91 | fi | ||
92 | |||
93 | if [ -z $DIR ]; then | ||
94 | DIR="/sys/devices/virtual/misc/${TEST_DRIVER}0/" | ||
95 | fi | ||
96 | |||
97 | if [ -z $DEFAULT_NUM_TESTS ]; then | ||
98 | DEFAULT_NUM_TESTS=150 | ||
99 | fi | ||
100 | |||
101 | MODPROBE_LIMIT_FILE="${PROC_DIR}/kmod-limit" | ||
102 | } | ||
103 | |||
104 | test_reqs() | ||
105 | { | ||
106 | if ! which modprobe 2> /dev/null > /dev/null; then | ||
107 | echo "$0: You need modprobe installed" >&2 | ||
108 | exit 1 | ||
109 | fi | ||
110 | |||
111 | if ! which kmod 2> /dev/null > /dev/null; then | ||
112 | echo "$0: You need kmod installed" >&2 | ||
113 | exit 1 | ||
114 | fi | ||
115 | |||
116 | # kmod 19 has a bad bug where it returns 0 when modprobe | ||
117 | # gets called *even* if the module was not loaded due to | ||
118 | # some bad heuristics. For details see: | ||
119 | # | ||
120 | # A work around is possible in-kernel but its rather | ||
121 | # complex. | ||
122 | KMOD_VERSION=$(kmod --version | awk '{print $3}') | ||
123 | if [[ $KMOD_VERSION -le 19 ]]; then | ||
124 | echo "$0: You need at least kmod 20" >&2 | ||
125 | echo "kmod <= 19 is buggy, for details see:" >&2 | ||
126 | echo "http://git.kernel.org/cgit/utils/kernel/kmod/kmod.git/commit/libkmod/libkmod-module.c?id=fd44a98ae2eb5eb32161088954ab21e58e19dfc4" >&2 | ||
127 | exit 1 | ||
128 | fi | ||
129 | |||
130 | uid=$(id -u) | ||
131 | if [ $uid -ne 0 ]; then | ||
132 | echo $msg must be run as root >&2 | ||
133 | exit 0 | ||
134 | fi | ||
135 | } | ||
136 | |||
137 | function load_req_mod() | ||
138 | { | ||
139 | trap "test_modprobe" EXIT | ||
140 | |||
141 | if [ ! -d $DIR ]; then | ||
142 | # Alanis: "Oh isn't it ironic?" | ||
143 | modprobe $TEST_DRIVER | ||
144 | fi | ||
145 | } | ||
146 | |||
147 | test_finish() | ||
148 | { | ||
149 | echo "Test completed" | ||
150 | } | ||
151 | |||
152 | errno_name_to_val() | ||
153 | { | ||
154 | case "$1" in | ||
155 | # kmod calls modprobe and upon of a module not found | ||
156 | # modprobe returns just 1... However in the kernel we | ||
157 | # *sometimes* see 256... | ||
158 | MODULE_NOT_FOUND) | ||
159 | echo 256;; | ||
160 | SUCCESS) | ||
161 | echo 0;; | ||
162 | -EPERM) | ||
163 | echo -1;; | ||
164 | -ENOENT) | ||
165 | echo -2;; | ||
166 | -EINVAL) | ||
167 | echo -22;; | ||
168 | -ERR_ANY) | ||
169 | echo -123456;; | ||
170 | *) | ||
171 | echo invalid;; | ||
172 | esac | ||
173 | } | ||
174 | |||
175 | errno_val_to_name() | ||
176 | case "$1" in | ||
177 | 256) | ||
178 | echo MODULE_NOT_FOUND;; | ||
179 | 0) | ||
180 | echo SUCCESS;; | ||
181 | -1) | ||
182 | echo -EPERM;; | ||
183 | -2) | ||
184 | echo -ENOENT;; | ||
185 | -22) | ||
186 | echo -EINVAL;; | ||
187 | -123456) | ||
188 | echo -ERR_ANY;; | ||
189 | *) | ||
190 | echo invalid;; | ||
191 | esac | ||
192 | |||
193 | config_set_test_case_driver() | ||
194 | { | ||
195 | if ! echo -n 1 >$DIR/config_test_case; then | ||
196 | echo "$0: Unable to set to test case to driver" >&2 | ||
197 | exit 1 | ||
198 | fi | ||
199 | } | ||
200 | |||
201 | config_set_test_case_fs() | ||
202 | { | ||
203 | if ! echo -n 2 >$DIR/config_test_case; then | ||
204 | echo "$0: Unable to set to test case to fs" >&2 | ||
205 | exit 1 | ||
206 | fi | ||
207 | } | ||
208 | |||
209 | config_num_threads() | ||
210 | { | ||
211 | if ! echo -n $1 >$DIR/config_num_threads; then | ||
212 | echo "$0: Unable to set to number of threads" >&2 | ||
213 | exit 1 | ||
214 | fi | ||
215 | } | ||
216 | |||
217 | config_get_modprobe_limit() | ||
218 | { | ||
219 | if [[ -f ${MODPROBE_LIMIT_FILE} ]] ; then | ||
220 | MODPROBE_LIMIT=$(cat $MODPROBE_LIMIT_FILE) | ||
221 | fi | ||
222 | echo $MODPROBE_LIMIT | ||
223 | } | ||
224 | |||
225 | config_num_thread_limit_extra() | ||
226 | { | ||
227 | MODPROBE_LIMIT=$(config_get_modprobe_limit) | ||
228 | let EXTRA_LIMIT=$MODPROBE_LIMIT+$1 | ||
229 | config_num_threads $EXTRA_LIMIT | ||
230 | } | ||
231 | |||
232 | # For special characters use printf directly, | ||
233 | # refer to kmod_test_0001 | ||
234 | config_set_driver() | ||
235 | { | ||
236 | if ! echo -n $1 >$DIR/config_test_driver; then | ||
237 | echo "$0: Unable to set driver" >&2 | ||
238 | exit 1 | ||
239 | fi | ||
240 | } | ||
241 | |||
242 | config_set_fs() | ||
243 | { | ||
244 | if ! echo -n $1 >$DIR/config_test_fs; then | ||
245 | echo "$0: Unable to set driver" >&2 | ||
246 | exit 1 | ||
247 | fi | ||
248 | } | ||
249 | |||
250 | config_get_driver() | ||
251 | { | ||
252 | cat $DIR/config_test_driver | ||
253 | } | ||
254 | |||
255 | config_get_test_result() | ||
256 | { | ||
257 | cat $DIR/test_result | ||
258 | } | ||
259 | |||
260 | config_reset() | ||
261 | { | ||
262 | if ! echo -n "1" >"$DIR"/reset; then | ||
263 | echo "$0: reset shuld have worked" >&2 | ||
264 | exit 1 | ||
265 | fi | ||
266 | } | ||
267 | |||
268 | config_show_config() | ||
269 | { | ||
270 | echo "----------------------------------------------------" | ||
271 | cat "$DIR"/config | ||
272 | echo "----------------------------------------------------" | ||
273 | } | ||
274 | |||
275 | config_trigger() | ||
276 | { | ||
277 | if ! echo -n "1" >"$DIR"/trigger_config 2>/dev/null; then | ||
278 | echo "$1: FAIL - loading should have worked" | ||
279 | config_show_config | ||
280 | exit 1 | ||
281 | fi | ||
282 | echo "$1: OK! - loading kmod test" | ||
283 | } | ||
284 | |||
285 | config_trigger_want_fail() | ||
286 | { | ||
287 | if echo "1" > $DIR/trigger_config 2>/dev/null; then | ||
288 | echo "$1: FAIL - test case was expected to fail" | ||
289 | config_show_config | ||
290 | exit 1 | ||
291 | fi | ||
292 | echo "$1: OK! - kmod test case failed as expected" | ||
293 | } | ||
294 | |||
295 | config_expect_result() | ||
296 | { | ||
297 | RC=$(config_get_test_result) | ||
298 | RC_NAME=$(errno_val_to_name $RC) | ||
299 | |||
300 | ERRNO_NAME=$2 | ||
301 | ERRNO=$(errno_name_to_val $ERRNO_NAME) | ||
302 | |||
303 | if [[ $ERRNO_NAME = "-ERR_ANY" ]]; then | ||
304 | if [[ $RC -ge 0 ]]; then | ||
305 | echo "$1: FAIL, test expects $ERRNO_NAME - got $RC_NAME ($RC)" >&2 | ||
306 | config_show_config | ||
307 | exit 1 | ||
308 | fi | ||
309 | elif [[ $RC != $ERRNO ]]; then | ||
310 | echo "$1: FAIL, test expects $ERRNO_NAME ($ERRNO) - got $RC_NAME ($RC)" >&2 | ||
311 | config_show_config | ||
312 | exit 1 | ||
313 | fi | ||
314 | echo "$1: OK! - Return value: $RC ($RC_NAME), expected $ERRNO_NAME" | ||
315 | } | ||
316 | |||
317 | kmod_defaults_driver() | ||
318 | { | ||
319 | config_reset | ||
320 | modprobe -r $DEFAULT_KMOD_DRIVER | ||
321 | config_set_driver $DEFAULT_KMOD_DRIVER | ||
322 | } | ||
323 | |||
324 | kmod_defaults_fs() | ||
325 | { | ||
326 | config_reset | ||
327 | modprobe -r $DEFAULT_KMOD_FS | ||
328 | config_set_fs $DEFAULT_KMOD_FS | ||
329 | config_set_test_case_fs | ||
330 | } | ||
331 | |||
332 | kmod_test_0001_driver() | ||
333 | { | ||
334 | NAME='\000' | ||
335 | |||
336 | kmod_defaults_driver | ||
337 | config_num_threads 1 | ||
338 | printf '\000' >"$DIR"/config_test_driver | ||
339 | config_trigger ${FUNCNAME[0]} | ||
340 | config_expect_result ${FUNCNAME[0]} MODULE_NOT_FOUND | ||
341 | } | ||
342 | |||
343 | kmod_test_0001_fs() | ||
344 | { | ||
345 | NAME='\000' | ||
346 | |||
347 | kmod_defaults_fs | ||
348 | config_num_threads 1 | ||
349 | printf '\000' >"$DIR"/config_test_fs | ||
350 | config_trigger ${FUNCNAME[0]} | ||
351 | config_expect_result ${FUNCNAME[0]} -EINVAL | ||
352 | } | ||
353 | |||
354 | kmod_test_0001() | ||
355 | { | ||
356 | kmod_test_0001_driver | ||
357 | kmod_test_0001_fs | ||
358 | } | ||
359 | |||
360 | kmod_test_0002_driver() | ||
361 | { | ||
362 | NAME="nope-$DEFAULT_KMOD_DRIVER" | ||
363 | |||
364 | kmod_defaults_driver | ||
365 | config_set_driver $NAME | ||
366 | config_num_threads 1 | ||
367 | config_trigger ${FUNCNAME[0]} | ||
368 | config_expect_result ${FUNCNAME[0]} MODULE_NOT_FOUND | ||
369 | } | ||
370 | |||
371 | kmod_test_0002_fs() | ||
372 | { | ||
373 | NAME="nope-$DEFAULT_KMOD_FS" | ||
374 | |||
375 | kmod_defaults_fs | ||
376 | config_set_fs $NAME | ||
377 | config_trigger ${FUNCNAME[0]} | ||
378 | config_expect_result ${FUNCNAME[0]} -EINVAL | ||
379 | } | ||
380 | |||
381 | kmod_test_0002() | ||
382 | { | ||
383 | kmod_test_0002_driver | ||
384 | kmod_test_0002_fs | ||
385 | } | ||
386 | |||
387 | kmod_test_0003() | ||
388 | { | ||
389 | kmod_defaults_fs | ||
390 | config_num_threads 1 | ||
391 | config_trigger ${FUNCNAME[0]} | ||
392 | config_expect_result ${FUNCNAME[0]} SUCCESS | ||
393 | } | ||
394 | |||
395 | kmod_test_0004() | ||
396 | { | ||
397 | kmod_defaults_fs | ||
398 | config_num_threads 2 | ||
399 | config_trigger ${FUNCNAME[0]} | ||
400 | config_expect_result ${FUNCNAME[0]} SUCCESS | ||
401 | } | ||
402 | |||
403 | kmod_test_0005() | ||
404 | { | ||
405 | kmod_defaults_driver | ||
406 | config_trigger ${FUNCNAME[0]} | ||
407 | config_expect_result ${FUNCNAME[0]} SUCCESS | ||
408 | } | ||
409 | |||
410 | kmod_test_0006() | ||
411 | { | ||
412 | kmod_defaults_fs | ||
413 | config_trigger ${FUNCNAME[0]} | ||
414 | config_expect_result ${FUNCNAME[0]} SUCCESS | ||
415 | } | ||
416 | |||
417 | kmod_test_0007() | ||
418 | { | ||
419 | kmod_test_0005 | ||
420 | kmod_test_0006 | ||
421 | } | ||
422 | |||
423 | kmod_test_0008() | ||
424 | { | ||
425 | kmod_defaults_driver | ||
426 | MODPROBE_LIMIT=$(config_get_modprobe_limit) | ||
427 | let EXTRA=$MODPROBE_LIMIT/6 | ||
428 | config_num_thread_limit_extra $EXTRA | ||
429 | config_trigger ${FUNCNAME[0]} | ||
430 | config_expect_result ${FUNCNAME[0]} SUCCESS | ||
431 | } | ||
432 | |||
433 | kmod_test_0009() | ||
434 | { | ||
435 | kmod_defaults_fs | ||
436 | MODPROBE_LIMIT=$(config_get_modprobe_limit) | ||
437 | let EXTRA=$MODPROBE_LIMIT/4 | ||
438 | config_num_thread_limit_extra $EXTRA | ||
439 | config_trigger ${FUNCNAME[0]} | ||
440 | config_expect_result ${FUNCNAME[0]} SUCCESS | ||
441 | } | ||
442 | |||
443 | list_tests() | ||
444 | { | ||
445 | echo "Test ID list:" | ||
446 | echo | ||
447 | echo "TEST_ID x NUM_TEST" | ||
448 | echo "TEST_ID: Test ID" | ||
449 | echo "NUM_TESTS: Number of recommended times to run the test" | ||
450 | echo | ||
451 | echo "0001 x $(get_test_count 0001) - Simple test - 1 thread for empty string" | ||
452 | echo "0002 x $(get_test_count 0002) - Simple test - 1 thread for modules/filesystems that do not exist" | ||
453 | echo "0003 x $(get_test_count 0003) - Simple test - 1 thread for get_fs_type() only" | ||
454 | echo "0004 x $(get_test_count 0004) - Simple test - 2 threads for get_fs_type() only" | ||
455 | echo "0005 x $(get_test_count 0005) - multithreaded tests with default setup - request_module() only" | ||
456 | echo "0006 x $(get_test_count 0006) - multithreaded tests with default setup - get_fs_type() only" | ||
457 | echo "0007 x $(get_test_count 0007) - multithreaded tests with default setup test request_module() and get_fs_type()" | ||
458 | echo "0008 x $(get_test_count 0008) - multithreaded - push kmod_concurrent over max_modprobes for request_module()" | ||
459 | echo "0009 x $(get_test_count 0009) - multithreaded - push kmod_concurrent over max_modprobes for get_fs_type()" | ||
460 | } | ||
461 | |||
462 | usage() | ||
463 | { | ||
464 | NUM_TESTS=$(grep -o ' ' <<<"$ALL_TESTS" | grep -c .) | ||
465 | let NUM_TESTS=$NUM_TESTS+1 | ||
466 | MAX_TEST=$(printf "%04d\n" $NUM_TESTS) | ||
467 | echo "Usage: $0 [ -t <4-number-digit> ] | [ -w <4-number-digit> ] |" | ||
468 | echo " [ -s <4-number-digit> ] | [ -c <4-number-digit> <test- count>" | ||
469 | echo " [ all ] [ -h | --help ] [ -l ]" | ||
470 | echo "" | ||
471 | echo "Valid tests: 0001-$MAX_TEST" | ||
472 | echo "" | ||
473 | echo " all Runs all tests (default)" | ||
474 | echo " -t Run test ID the number amount of times is recommended" | ||
475 | echo " -w Watch test ID run until it runs into an error" | ||
476 | echo " -c Run test ID once" | ||
477 | echo " -s Run test ID x test-count number of times" | ||
478 | echo " -l List all test ID list" | ||
479 | echo " -h|--help Help" | ||
480 | echo | ||
481 | echo "If an error every occurs execution will immediately terminate." | ||
482 | echo "If you are adding a new test try using -w <test-ID> first to" | ||
483 | echo "make sure the test passes a series of tests." | ||
484 | echo | ||
485 | echo Example uses: | ||
486 | echo | ||
487 | echo "${TEST_NAME}.sh -- executes all tests" | ||
488 | echo "${TEST_NAME}.sh -t 0008 -- Executes test ID 0008 number of times is recomended" | ||
489 | echo "${TEST_NAME}.sh -w 0008 -- Watch test ID 0008 run until an error occurs" | ||
490 | echo "${TEST_NAME}.sh -s 0008 -- Run test ID 0008 once" | ||
491 | echo "${TEST_NAME}.sh -c 0008 3 -- Run test ID 0008 three times" | ||
492 | echo | ||
493 | list_tests | ||
494 | exit 1 | ||
495 | } | ||
496 | |||
497 | function test_num() | ||
498 | { | ||
499 | re='^[0-9]+$' | ||
500 | if ! [[ $1 =~ $re ]]; then | ||
501 | usage | ||
502 | fi | ||
503 | } | ||
504 | |||
505 | function get_test_count() | ||
506 | { | ||
507 | test_num $1 | ||
508 | TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$1'}') | ||
509 | LAST_TWO=${TEST_DATA#*:*} | ||
510 | echo ${LAST_TWO%:*} | ||
511 | } | ||
512 | |||
513 | function get_test_enabled() | ||
514 | { | ||
515 | test_num $1 | ||
516 | TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$1'}') | ||
517 | echo ${TEST_DATA#*:*:} | ||
518 | } | ||
519 | |||
520 | function run_all_tests() | ||
521 | { | ||
522 | for i in $ALL_TESTS ; do | ||
523 | TEST_ID=${i%:*:*} | ||
524 | ENABLED=$(get_test_enabled $TEST_ID) | ||
525 | TEST_COUNT=$(get_test_count $TEST_ID) | ||
526 | if [[ $ENABLED -eq "1" ]]; then | ||
527 | test_case $TEST_ID $TEST_COUNT | ||
528 | fi | ||
529 | done | ||
530 | } | ||
531 | |||
532 | function watch_log() | ||
533 | { | ||
534 | if [ $# -ne 3 ]; then | ||
535 | clear | ||
536 | fi | ||
537 | date | ||
538 | echo "Running test: $2 - run #$1" | ||
539 | } | ||
540 | |||
541 | function watch_case() | ||
542 | { | ||
543 | i=0 | ||
544 | while [ 1 ]; do | ||
545 | |||
546 | if [ $# -eq 1 ]; then | ||
547 | test_num $1 | ||
548 | watch_log $i ${TEST_NAME}_test_$1 | ||
549 | ${TEST_NAME}_test_$1 | ||
550 | else | ||
551 | watch_log $i all | ||
552 | run_all_tests | ||
553 | fi | ||
554 | let i=$i+1 | ||
555 | done | ||
556 | } | ||
557 | |||
558 | function test_case() | ||
559 | { | ||
560 | NUM_TESTS=$DEFAULT_NUM_TESTS | ||
561 | if [ $# -eq 2 ]; then | ||
562 | NUM_TESTS=$2 | ||
563 | fi | ||
564 | |||
565 | i=0 | ||
566 | while [ $i -lt $NUM_TESTS ]; do | ||
567 | test_num $1 | ||
568 | watch_log $i ${TEST_NAME}_test_$1 noclear | ||
569 | RUN_TEST=${TEST_NAME}_test_$1 | ||
570 | $RUN_TEST | ||
571 | let i=$i+1 | ||
572 | done | ||
573 | } | ||
574 | |||
575 | function parse_args() | ||
576 | { | ||
577 | if [ $# -eq 0 ]; then | ||
578 | run_all_tests | ||
579 | else | ||
580 | if [[ "$1" = "all" ]]; then | ||
581 | run_all_tests | ||
582 | elif [[ "$1" = "-w" ]]; then | ||
583 | shift | ||
584 | watch_case $@ | ||
585 | elif [[ "$1" = "-t" ]]; then | ||
586 | shift | ||
587 | test_num $1 | ||
588 | test_case $1 $(get_test_count $1) | ||
589 | elif [[ "$1" = "-c" ]]; then | ||
590 | shift | ||
591 | test_num $1 | ||
592 | test_num $2 | ||
593 | test_case $1 $2 | ||
594 | elif [[ "$1" = "-s" ]]; then | ||
595 | shift | ||
596 | test_case $1 1 | ||
597 | elif [[ "$1" = "-l" ]]; then | ||
598 | list_tests | ||
599 | elif [[ "$1" = "-h" || "$1" = "--help" ]]; then | ||
600 | usage | ||
601 | else | ||
602 | usage | ||
603 | fi | ||
604 | fi | ||
605 | } | ||
606 | |||
607 | test_reqs | ||
608 | allow_user_defaults | ||
609 | load_req_mod | ||
610 | |||
611 | trap "test_finish" EXIT | ||
612 | |||
613 | parse_args $@ | ||
614 | |||
615 | exit 0 | ||
diff --git a/tools/testing/selftests/ntb/ntb_test.sh b/tools/testing/selftests/ntb/ntb_test.sh index 13f5198ba0ee..1c12b5855e4f 100755 --- a/tools/testing/selftests/ntb/ntb_test.sh +++ b/tools/testing/selftests/ntb/ntb_test.sh | |||
@@ -18,6 +18,7 @@ LIST_DEVS=FALSE | |||
18 | 18 | ||
19 | DEBUGFS=${DEBUGFS-/sys/kernel/debug} | 19 | DEBUGFS=${DEBUGFS-/sys/kernel/debug} |
20 | 20 | ||
21 | DB_BITMASK=0x7FFF | ||
21 | PERF_RUN_ORDER=32 | 22 | PERF_RUN_ORDER=32 |
22 | MAX_MW_SIZE=0 | 23 | MAX_MW_SIZE=0 |
23 | RUN_DMA_TESTS= | 24 | RUN_DMA_TESTS= |
@@ -38,6 +39,7 @@ function show_help() | |||
38 | echo "be highly recommended." | 39 | echo "be highly recommended." |
39 | echo | 40 | echo |
40 | echo "Options:" | 41 | echo "Options:" |
42 | echo " -b BITMASK doorbell clear bitmask for ntb_tool" | ||
41 | echo " -C don't cleanup ntb modules on exit" | 43 | echo " -C don't cleanup ntb modules on exit" |
42 | echo " -d run dma tests" | 44 | echo " -d run dma tests" |
43 | echo " -h show this help message" | 45 | echo " -h show this help message" |
@@ -52,8 +54,9 @@ function show_help() | |||
52 | function parse_args() | 54 | function parse_args() |
53 | { | 55 | { |
54 | OPTIND=0 | 56 | OPTIND=0 |
55 | while getopts "Cdhlm:r:p:w:" opt; do | 57 | while getopts "b:Cdhlm:r:p:w:" opt; do |
56 | case "$opt" in | 58 | case "$opt" in |
59 | b) DB_BITMASK=${OPTARG} ;; | ||
57 | C) DONT_CLEANUP=1 ;; | 60 | C) DONT_CLEANUP=1 ;; |
58 | d) RUN_DMA_TESTS=1 ;; | 61 | d) RUN_DMA_TESTS=1 ;; |
59 | h) show_help; exit 0 ;; | 62 | h) show_help; exit 0 ;; |
@@ -85,6 +88,10 @@ set -e | |||
85 | function _modprobe() | 88 | function _modprobe() |
86 | { | 89 | { |
87 | modprobe "$@" | 90 | modprobe "$@" |
91 | |||
92 | if [[ "$REMOTE_HOST" != "" ]]; then | ||
93 | ssh "$REMOTE_HOST" modprobe "$@" | ||
94 | fi | ||
88 | } | 95 | } |
89 | 96 | ||
90 | function split_remote() | 97 | function split_remote() |
@@ -154,7 +161,7 @@ function doorbell_test() | |||
154 | 161 | ||
155 | echo "Running db tests on: $(basename $LOC) / $(basename $REM)" | 162 | echo "Running db tests on: $(basename $LOC) / $(basename $REM)" |
156 | 163 | ||
157 | write_file "c 0xFFFFFFFF" "$REM/db" | 164 | write_file "c $DB_BITMASK" "$REM/db" |
158 | 165 | ||
159 | for ((i=1; i <= 8; i++)); do | 166 | for ((i=1; i <= 8; i++)); do |
160 | let DB=$(read_file "$REM/db") || true | 167 | let DB=$(read_file "$REM/db") || true |
diff --git a/tools/testing/selftests/sysctl/Makefile b/tools/testing/selftests/sysctl/Makefile index b3c33e071f10..95c320b354e8 100644 --- a/tools/testing/selftests/sysctl/Makefile +++ b/tools/testing/selftests/sysctl/Makefile | |||
@@ -4,8 +4,7 @@ | |||
4 | # No binaries, but make sure arg-less "make" doesn't trigger "run_tests". | 4 | # No binaries, but make sure arg-less "make" doesn't trigger "run_tests". |
5 | all: | 5 | all: |
6 | 6 | ||
7 | TEST_PROGS := run_numerictests run_stringtests | 7 | TEST_PROGS := sysctl.sh |
8 | TEST_FILES := common_tests | ||
9 | 8 | ||
10 | include ../lib.mk | 9 | include ../lib.mk |
11 | 10 | ||
diff --git a/tools/testing/selftests/sysctl/common_tests b/tools/testing/selftests/sysctl/common_tests deleted file mode 100644 index b6862322962f..000000000000 --- a/tools/testing/selftests/sysctl/common_tests +++ /dev/null | |||
@@ -1,131 +0,0 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | TEST_FILE=$(mktemp) | ||
4 | |||
5 | echo "== Testing sysctl behavior against ${TARGET} ==" | ||
6 | |||
7 | set_orig() | ||
8 | { | ||
9 | echo "${ORIG}" > "${TARGET}" | ||
10 | } | ||
11 | |||
12 | set_test() | ||
13 | { | ||
14 | echo "${TEST_STR}" > "${TARGET}" | ||
15 | } | ||
16 | |||
17 | verify() | ||
18 | { | ||
19 | local seen | ||
20 | seen=$(cat "$1") | ||
21 | if [ "${seen}" != "${TEST_STR}" ]; then | ||
22 | return 1 | ||
23 | fi | ||
24 | return 0 | ||
25 | } | ||
26 | |||
27 | exit_test() | ||
28 | { | ||
29 | if [ ! -z ${old_strict} ]; then | ||
30 | echo ${old_strict} > ${WRITES_STRICT} | ||
31 | fi | ||
32 | exit $rc | ||
33 | } | ||
34 | |||
35 | trap 'set_orig; rm -f "${TEST_FILE}"' EXIT | ||
36 | |||
37 | rc=0 | ||
38 | |||
39 | echo -n "Writing test file ... " | ||
40 | echo "${TEST_STR}" > "${TEST_FILE}" | ||
41 | if ! verify "${TEST_FILE}"; then | ||
42 | echo "FAIL" >&2 | ||
43 | exit 1 | ||
44 | else | ||
45 | echo "ok" | ||
46 | fi | ||
47 | |||
48 | echo -n "Checking sysctl is not set to test value ... " | ||
49 | if verify "${TARGET}"; then | ||
50 | echo "FAIL" >&2 | ||
51 | exit 1 | ||
52 | else | ||
53 | echo "ok" | ||
54 | fi | ||
55 | |||
56 | echo -n "Writing sysctl from shell ... " | ||
57 | set_test | ||
58 | if ! verify "${TARGET}"; then | ||
59 | echo "FAIL" >&2 | ||
60 | exit 1 | ||
61 | else | ||
62 | echo "ok" | ||
63 | fi | ||
64 | |||
65 | echo -n "Resetting sysctl to original value ... " | ||
66 | set_orig | ||
67 | if verify "${TARGET}"; then | ||
68 | echo "FAIL" >&2 | ||
69 | exit 1 | ||
70 | else | ||
71 | echo "ok" | ||
72 | fi | ||
73 | |||
74 | echo -n "Checking write strict setting ... " | ||
75 | WRITES_STRICT="${SYSCTL}/kernel/sysctl_writes_strict" | ||
76 | if [ ! -e ${WRITES_STRICT} ]; then | ||
77 | echo "FAIL, but skip in case of old kernel" >&2 | ||
78 | else | ||
79 | old_strict=$(cat ${WRITES_STRICT}) | ||
80 | if [ "$old_strict" = "1" ]; then | ||
81 | echo "ok" | ||
82 | else | ||
83 | echo "FAIL, strict value is 0 but force to 1 to continue" >&2 | ||
84 | echo "1" > ${WRITES_STRICT} | ||
85 | fi | ||
86 | fi | ||
87 | |||
88 | # Now that we've validated the sanity of "set_test" and "set_orig", | ||
89 | # we can use those functions to set starting states before running | ||
90 | # specific behavioral tests. | ||
91 | |||
92 | echo -n "Writing entire sysctl in single write ... " | ||
93 | set_orig | ||
94 | dd if="${TEST_FILE}" of="${TARGET}" bs=4096 2>/dev/null | ||
95 | if ! verify "${TARGET}"; then | ||
96 | echo "FAIL" >&2 | ||
97 | rc=1 | ||
98 | else | ||
99 | echo "ok" | ||
100 | fi | ||
101 | |||
102 | echo -n "Writing middle of sysctl after synchronized seek ... " | ||
103 | set_test | ||
104 | dd if="${TEST_FILE}" of="${TARGET}" bs=1 seek=1 skip=1 2>/dev/null | ||
105 | if ! verify "${TARGET}"; then | ||
106 | echo "FAIL" >&2 | ||
107 | rc=1 | ||
108 | else | ||
109 | echo "ok" | ||
110 | fi | ||
111 | |||
112 | echo -n "Writing beyond end of sysctl ... " | ||
113 | set_orig | ||
114 | dd if="${TEST_FILE}" of="${TARGET}" bs=20 seek=2 2>/dev/null | ||
115 | if verify "${TARGET}"; then | ||
116 | echo "FAIL" >&2 | ||
117 | rc=1 | ||
118 | else | ||
119 | echo "ok" | ||
120 | fi | ||
121 | |||
122 | echo -n "Writing sysctl with multiple long writes ... " | ||
123 | set_orig | ||
124 | (perl -e 'print "A" x 50;'; echo "${TEST_STR}") | \ | ||
125 | dd of="${TARGET}" bs=50 2>/dev/null | ||
126 | if verify "${TARGET}"; then | ||
127 | echo "FAIL" >&2 | ||
128 | rc=1 | ||
129 | else | ||
130 | echo "ok" | ||
131 | fi | ||
diff --git a/tools/testing/selftests/sysctl/config b/tools/testing/selftests/sysctl/config new file mode 100644 index 000000000000..6ca14800d755 --- /dev/null +++ b/tools/testing/selftests/sysctl/config | |||
@@ -0,0 +1 @@ | |||
CONFIG_TEST_SYSCTL=y | |||
diff --git a/tools/testing/selftests/sysctl/run_numerictests b/tools/testing/selftests/sysctl/run_numerictests deleted file mode 100755 index e6e76c93d948..000000000000 --- a/tools/testing/selftests/sysctl/run_numerictests +++ /dev/null | |||
@@ -1,10 +0,0 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | SYSCTL="/proc/sys" | ||
4 | TARGET="${SYSCTL}/vm/swappiness" | ||
5 | ORIG=$(cat "${TARGET}") | ||
6 | TEST_STR=$(( $ORIG + 1 )) | ||
7 | |||
8 | . ./common_tests | ||
9 | |||
10 | exit_test | ||
diff --git a/tools/testing/selftests/sysctl/run_stringtests b/tools/testing/selftests/sysctl/run_stringtests deleted file mode 100755 index 857ec667fb02..000000000000 --- a/tools/testing/selftests/sysctl/run_stringtests +++ /dev/null | |||
@@ -1,77 +0,0 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | SYSCTL="/proc/sys" | ||
4 | TARGET="${SYSCTL}/kernel/domainname" | ||
5 | ORIG=$(cat "${TARGET}") | ||
6 | TEST_STR="Testing sysctl" | ||
7 | |||
8 | . ./common_tests | ||
9 | |||
10 | # Only string sysctls support seeking/appending. | ||
11 | MAXLEN=65 | ||
12 | |||
13 | echo -n "Writing entire sysctl in short writes ... " | ||
14 | set_orig | ||
15 | dd if="${TEST_FILE}" of="${TARGET}" bs=1 2>/dev/null | ||
16 | if ! verify "${TARGET}"; then | ||
17 | echo "FAIL" >&2 | ||
18 | rc=1 | ||
19 | else | ||
20 | echo "ok" | ||
21 | fi | ||
22 | |||
23 | echo -n "Writing middle of sysctl after unsynchronized seek ... " | ||
24 | set_test | ||
25 | dd if="${TEST_FILE}" of="${TARGET}" bs=1 seek=1 2>/dev/null | ||
26 | if verify "${TARGET}"; then | ||
27 | echo "FAIL" >&2 | ||
28 | rc=1 | ||
29 | else | ||
30 | echo "ok" | ||
31 | fi | ||
32 | |||
33 | echo -n "Checking sysctl maxlen is at least $MAXLEN ... " | ||
34 | set_orig | ||
35 | perl -e 'print "A" x ('"${MAXLEN}"'-2), "B";' | \ | ||
36 | dd of="${TARGET}" bs="${MAXLEN}" 2>/dev/null | ||
37 | if ! grep -q B "${TARGET}"; then | ||
38 | echo "FAIL" >&2 | ||
39 | rc=1 | ||
40 | else | ||
41 | echo "ok" | ||
42 | fi | ||
43 | |||
44 | echo -n "Checking sysctl keeps original string on overflow append ... " | ||
45 | set_orig | ||
46 | perl -e 'print "A" x ('"${MAXLEN}"'-1), "B";' | \ | ||
47 | dd of="${TARGET}" bs=$(( MAXLEN - 1 )) 2>/dev/null | ||
48 | if grep -q B "${TARGET}"; then | ||
49 | echo "FAIL" >&2 | ||
50 | rc=1 | ||
51 | else | ||
52 | echo "ok" | ||
53 | fi | ||
54 | |||
55 | echo -n "Checking sysctl stays NULL terminated on write ... " | ||
56 | set_orig | ||
57 | perl -e 'print "A" x ('"${MAXLEN}"'-1), "B";' | \ | ||
58 | dd of="${TARGET}" bs="${MAXLEN}" 2>/dev/null | ||
59 | if grep -q B "${TARGET}"; then | ||
60 | echo "FAIL" >&2 | ||
61 | rc=1 | ||
62 | else | ||
63 | echo "ok" | ||
64 | fi | ||
65 | |||
66 | echo -n "Checking sysctl stays NULL terminated on overwrite ... " | ||
67 | set_orig | ||
68 | perl -e 'print "A" x ('"${MAXLEN}"'-1), "BB";' | \ | ||
69 | dd of="${TARGET}" bs=$(( $MAXLEN + 1 )) 2>/dev/null | ||
70 | if grep -q B "${TARGET}"; then | ||
71 | echo "FAIL" >&2 | ||
72 | rc=1 | ||
73 | else | ||
74 | echo "ok" | ||
75 | fi | ||
76 | |||
77 | exit_test | ||
diff --git a/tools/testing/selftests/sysctl/sysctl.sh b/tools/testing/selftests/sysctl/sysctl.sh new file mode 100644 index 000000000000..ec232c3cfcaa --- /dev/null +++ b/tools/testing/selftests/sysctl/sysctl.sh | |||
@@ -0,0 +1,774 @@ | |||
1 | #!/bin/bash | ||
2 | # Copyright (C) 2017 Luis R. Rodriguez <mcgrof@kernel.org> | ||
3 | # | ||
4 | # This program is free software; you can redistribute it and/or modify it | ||
5 | # under the terms of the GNU General Public License as published by the Free | ||
6 | # Software Foundation; either version 2 of the License, or at your option any | ||
7 | # later version; or, when distributed separately from the Linux kernel or | ||
8 | # when incorporated into other software packages, subject to the following | ||
9 | # license: | ||
10 | # | ||
11 | # This program is free software; you can redistribute it and/or modify it | ||
12 | # under the terms of copyleft-next (version 0.3.1 or later) as published | ||
13 | # at http://copyleft-next.org/. | ||
14 | |||
15 | # This performs a series tests against the proc sysctl interface. | ||
16 | |||
17 | TEST_NAME="sysctl" | ||
18 | TEST_DRIVER="test_${TEST_NAME}" | ||
19 | TEST_DIR=$(dirname $0) | ||
20 | TEST_FILE=$(mktemp) | ||
21 | |||
22 | # This represents | ||
23 | # | ||
24 | # TEST_ID:TEST_COUNT:ENABLED | ||
25 | # | ||
26 | # TEST_ID: is the test id number | ||
27 | # TEST_COUNT: number of times we should run the test | ||
28 | # ENABLED: 1 if enabled, 0 otherwise | ||
29 | # | ||
30 | # Once these are enabled please leave them as-is. Write your own test, | ||
31 | # we have tons of space. | ||
32 | ALL_TESTS="0001:1:1" | ||
33 | ALL_TESTS="$ALL_TESTS 0002:1:1" | ||
34 | ALL_TESTS="$ALL_TESTS 0003:1:1" | ||
35 | ALL_TESTS="$ALL_TESTS 0004:1:1" | ||
36 | ALL_TESTS="$ALL_TESTS 0005:3:1" | ||
37 | |||
38 | test_modprobe() | ||
39 | { | ||
40 | if [ ! -d $DIR ]; then | ||
41 | echo "$0: $DIR not present" >&2 | ||
42 | echo "You must have the following enabled in your kernel:" >&2 | ||
43 | cat $TEST_DIR/config >&2 | ||
44 | exit 1 | ||
45 | fi | ||
46 | } | ||
47 | |||
48 | function allow_user_defaults() | ||
49 | { | ||
50 | if [ -z $DIR ]; then | ||
51 | DIR="/sys/module/test_sysctl/" | ||
52 | fi | ||
53 | if [ -z $DEFAULT_NUM_TESTS ]; then | ||
54 | DEFAULT_NUM_TESTS=50 | ||
55 | fi | ||
56 | if [ -z $SYSCTL ]; then | ||
57 | SYSCTL="/proc/sys/debug/test_sysctl" | ||
58 | fi | ||
59 | if [ -z $PROD_SYSCTL ]; then | ||
60 | PROD_SYSCTL="/proc/sys" | ||
61 | fi | ||
62 | if [ -z $WRITES_STRICT ]; then | ||
63 | WRITES_STRICT="${PROD_SYSCTL}/kernel/sysctl_writes_strict" | ||
64 | fi | ||
65 | } | ||
66 | |||
67 | function check_production_sysctl_writes_strict() | ||
68 | { | ||
69 | echo -n "Checking production write strict setting ... " | ||
70 | if [ ! -e ${WRITES_STRICT} ]; then | ||
71 | echo "FAIL, but skip in case of old kernel" >&2 | ||
72 | else | ||
73 | old_strict=$(cat ${WRITES_STRICT}) | ||
74 | if [ "$old_strict" = "1" ]; then | ||
75 | echo "ok" | ||
76 | else | ||
77 | echo "FAIL, strict value is 0 but force to 1 to continue" >&2 | ||
78 | echo "1" > ${WRITES_STRICT} | ||
79 | fi | ||
80 | fi | ||
81 | |||
82 | if [ -z $PAGE_SIZE ]; then | ||
83 | PAGE_SIZE=$(getconf PAGESIZE) | ||
84 | fi | ||
85 | if [ -z $MAX_DIGITS ]; then | ||
86 | MAX_DIGITS=$(($PAGE_SIZE/8)) | ||
87 | fi | ||
88 | if [ -z $INT_MAX ]; then | ||
89 | INT_MAX=$(getconf INT_MAX) | ||
90 | fi | ||
91 | if [ -z $UINT_MAX ]; then | ||
92 | UINT_MAX=$(getconf UINT_MAX) | ||
93 | fi | ||
94 | } | ||
95 | |||
96 | test_reqs() | ||
97 | { | ||
98 | uid=$(id -u) | ||
99 | if [ $uid -ne 0 ]; then | ||
100 | echo $msg must be run as root >&2 | ||
101 | exit 0 | ||
102 | fi | ||
103 | |||
104 | if ! which perl 2> /dev/null > /dev/null; then | ||
105 | echo "$0: You need perl installed" | ||
106 | exit 1 | ||
107 | fi | ||
108 | if ! which getconf 2> /dev/null > /dev/null; then | ||
109 | echo "$0: You need getconf installed" | ||
110 | exit 1 | ||
111 | fi | ||
112 | if ! which diff 2> /dev/null > /dev/null; then | ||
113 | echo "$0: You need diff installed" | ||
114 | exit 1 | ||
115 | fi | ||
116 | } | ||
117 | |||
118 | function load_req_mod() | ||
119 | { | ||
120 | trap "test_modprobe" EXIT | ||
121 | |||
122 | if [ ! -d $DIR ]; then | ||
123 | modprobe $TEST_DRIVER | ||
124 | if [ $? -ne 0 ]; then | ||
125 | exit | ||
126 | fi | ||
127 | fi | ||
128 | } | ||
129 | |||
130 | reset_vals() | ||
131 | { | ||
132 | VAL="" | ||
133 | TRIGGER=$(basename ${TARGET}) | ||
134 | case "$TRIGGER" in | ||
135 | int_0001) | ||
136 | VAL="60" | ||
137 | ;; | ||
138 | int_0002) | ||
139 | VAL="1" | ||
140 | ;; | ||
141 | uint_0001) | ||
142 | VAL="314" | ||
143 | ;; | ||
144 | string_0001) | ||
145 | VAL="(none)" | ||
146 | ;; | ||
147 | *) | ||
148 | ;; | ||
149 | esac | ||
150 | echo -n $VAL > $TARGET | ||
151 | } | ||
152 | |||
153 | set_orig() | ||
154 | { | ||
155 | if [ ! -z $TARGET ]; then | ||
156 | echo "${ORIG}" > "${TARGET}" | ||
157 | fi | ||
158 | } | ||
159 | |||
160 | set_test() | ||
161 | { | ||
162 | echo "${TEST_STR}" > "${TARGET}" | ||
163 | } | ||
164 | |||
165 | verify() | ||
166 | { | ||
167 | local seen | ||
168 | seen=$(cat "$1") | ||
169 | if [ "${seen}" != "${TEST_STR}" ]; then | ||
170 | return 1 | ||
171 | fi | ||
172 | return 0 | ||
173 | } | ||
174 | |||
175 | verify_diff_w() | ||
176 | { | ||
177 | echo "$TEST_STR" | diff -q -w -u - $1 | ||
178 | return $? | ||
179 | } | ||
180 | |||
181 | test_rc() | ||
182 | { | ||
183 | if [[ $rc != 0 ]]; then | ||
184 | echo "Failed test, return value: $rc" >&2 | ||
185 | exit $rc | ||
186 | fi | ||
187 | } | ||
188 | |||
189 | test_finish() | ||
190 | { | ||
191 | set_orig | ||
192 | rm -f "${TEST_FILE}" | ||
193 | |||
194 | if [ ! -z ${old_strict} ]; then | ||
195 | echo ${old_strict} > ${WRITES_STRICT} | ||
196 | fi | ||
197 | exit $rc | ||
198 | } | ||
199 | |||
200 | run_numerictests() | ||
201 | { | ||
202 | echo "== Testing sysctl behavior against ${TARGET} ==" | ||
203 | |||
204 | rc=0 | ||
205 | |||
206 | echo -n "Writing test file ... " | ||
207 | echo "${TEST_STR}" > "${TEST_FILE}" | ||
208 | if ! verify "${TEST_FILE}"; then | ||
209 | echo "FAIL" >&2 | ||
210 | exit 1 | ||
211 | else | ||
212 | echo "ok" | ||
213 | fi | ||
214 | |||
215 | echo -n "Checking sysctl is not set to test value ... " | ||
216 | if verify "${TARGET}"; then | ||
217 | echo "FAIL" >&2 | ||
218 | exit 1 | ||
219 | else | ||
220 | echo "ok" | ||
221 | fi | ||
222 | |||
223 | echo -n "Writing sysctl from shell ... " | ||
224 | set_test | ||
225 | if ! verify "${TARGET}"; then | ||
226 | echo "FAIL" >&2 | ||
227 | exit 1 | ||
228 | else | ||
229 | echo "ok" | ||
230 | fi | ||
231 | |||
232 | echo -n "Resetting sysctl to original value ... " | ||
233 | set_orig | ||
234 | if verify "${TARGET}"; then | ||
235 | echo "FAIL" >&2 | ||
236 | exit 1 | ||
237 | else | ||
238 | echo "ok" | ||
239 | fi | ||
240 | |||
241 | # Now that we've validated the sanity of "set_test" and "set_orig", | ||
242 | # we can use those functions to set starting states before running | ||
243 | # specific behavioral tests. | ||
244 | |||
245 | echo -n "Writing entire sysctl in single write ... " | ||
246 | set_orig | ||
247 | dd if="${TEST_FILE}" of="${TARGET}" bs=4096 2>/dev/null | ||
248 | if ! verify "${TARGET}"; then | ||
249 | echo "FAIL" >&2 | ||
250 | rc=1 | ||
251 | else | ||
252 | echo "ok" | ||
253 | fi | ||
254 | |||
255 | echo -n "Writing middle of sysctl after synchronized seek ... " | ||
256 | set_test | ||
257 | dd if="${TEST_FILE}" of="${TARGET}" bs=1 seek=1 skip=1 2>/dev/null | ||
258 | if ! verify "${TARGET}"; then | ||
259 | echo "FAIL" >&2 | ||
260 | rc=1 | ||
261 | else | ||
262 | echo "ok" | ||
263 | fi | ||
264 | |||
265 | echo -n "Writing beyond end of sysctl ... " | ||
266 | set_orig | ||
267 | dd if="${TEST_FILE}" of="${TARGET}" bs=20 seek=2 2>/dev/null | ||
268 | if verify "${TARGET}"; then | ||
269 | echo "FAIL" >&2 | ||
270 | rc=1 | ||
271 | else | ||
272 | echo "ok" | ||
273 | fi | ||
274 | |||
275 | echo -n "Writing sysctl with multiple long writes ... " | ||
276 | set_orig | ||
277 | (perl -e 'print "A" x 50;'; echo "${TEST_STR}") | \ | ||
278 | dd of="${TARGET}" bs=50 2>/dev/null | ||
279 | if verify "${TARGET}"; then | ||
280 | echo "FAIL" >&2 | ||
281 | rc=1 | ||
282 | else | ||
283 | echo "ok" | ||
284 | fi | ||
285 | test_rc | ||
286 | } | ||
287 | |||
288 | # Your test must accept digits 3 and 4 to use this | ||
289 | run_limit_digit() | ||
290 | { | ||
291 | echo -n "Checking ignoring spaces up to PAGE_SIZE works on write ..." | ||
292 | reset_vals | ||
293 | |||
294 | LIMIT=$((MAX_DIGITS -1)) | ||
295 | TEST_STR="3" | ||
296 | (perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \ | ||
297 | dd of="${TARGET}" 2>/dev/null | ||
298 | |||
299 | if ! verify "${TARGET}"; then | ||
300 | echo "FAIL" >&2 | ||
301 | rc=1 | ||
302 | else | ||
303 | echo "ok" | ||
304 | fi | ||
305 | test_rc | ||
306 | |||
307 | echo -n "Checking passing PAGE_SIZE of spaces fails on write ..." | ||
308 | reset_vals | ||
309 | |||
310 | LIMIT=$((MAX_DIGITS)) | ||
311 | TEST_STR="4" | ||
312 | (perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \ | ||
313 | dd of="${TARGET}" 2>/dev/null | ||
314 | |||
315 | if verify "${TARGET}"; then | ||
316 | echo "FAIL" >&2 | ||
317 | rc=1 | ||
318 | else | ||
319 | echo "ok" | ||
320 | fi | ||
321 | test_rc | ||
322 | } | ||
323 | |||
324 | # You are using an int | ||
325 | run_limit_digit_int() | ||
326 | { | ||
327 | echo -n "Testing INT_MAX works ..." | ||
328 | reset_vals | ||
329 | TEST_STR="$INT_MAX" | ||
330 | echo -n $TEST_STR > $TARGET | ||
331 | |||
332 | if ! verify "${TARGET}"; then | ||
333 | echo "FAIL" >&2 | ||
334 | rc=1 | ||
335 | else | ||
336 | echo "ok" | ||
337 | fi | ||
338 | test_rc | ||
339 | |||
340 | echo -n "Testing INT_MAX + 1 will fail as expected..." | ||
341 | reset_vals | ||
342 | let TEST_STR=$INT_MAX+1 | ||
343 | echo -n $TEST_STR > $TARGET 2> /dev/null | ||
344 | |||
345 | if verify "${TARGET}"; then | ||
346 | echo "FAIL" >&2 | ||
347 | rc=1 | ||
348 | else | ||
349 | echo "ok" | ||
350 | fi | ||
351 | test_rc | ||
352 | |||
353 | echo -n "Testing negative values will work as expected..." | ||
354 | reset_vals | ||
355 | TEST_STR="-3" | ||
356 | echo -n $TEST_STR > $TARGET 2> /dev/null | ||
357 | if ! verify "${TARGET}"; then | ||
358 | echo "FAIL" >&2 | ||
359 | rc=1 | ||
360 | else | ||
361 | echo "ok" | ||
362 | fi | ||
363 | test_rc | ||
364 | } | ||
365 | |||
366 | # You used an int array | ||
367 | run_limit_digit_int_array() | ||
368 | { | ||
369 | echo -n "Testing array works as expected ... " | ||
370 | TEST_STR="4 3 2 1" | ||
371 | echo -n $TEST_STR > $TARGET | ||
372 | |||
373 | if ! verify_diff_w "${TARGET}"; then | ||
374 | echo "FAIL" >&2 | ||
375 | rc=1 | ||
376 | else | ||
377 | echo "ok" | ||
378 | fi | ||
379 | test_rc | ||
380 | |||
381 | echo -n "Testing skipping trailing array elements works ... " | ||
382 | # Do not reset_vals, carry on the values from the last test. | ||
383 | # If we only echo in two digits the last two are left intact | ||
384 | TEST_STR="100 101" | ||
385 | echo -n $TEST_STR > $TARGET | ||
386 | # After we echo in, to help diff we need to set on TEST_STR what | ||
387 | # we expect the result to be. | ||
388 | TEST_STR="100 101 2 1" | ||
389 | |||
390 | if ! verify_diff_w "${TARGET}"; then | ||
391 | echo "FAIL" >&2 | ||
392 | rc=1 | ||
393 | else | ||
394 | echo "ok" | ||
395 | fi | ||
396 | test_rc | ||
397 | |||
398 | echo -n "Testing PAGE_SIZE limit on array works ... " | ||
399 | # Do not reset_vals, carry on the values from the last test. | ||
400 | # Even if you use an int array, you are still restricted to | ||
401 | # MAX_DIGITS, this is a known limitation. Test limit works. | ||
402 | LIMIT=$((MAX_DIGITS -1)) | ||
403 | TEST_STR="9" | ||
404 | (perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \ | ||
405 | dd of="${TARGET}" 2>/dev/null | ||
406 | |||
407 | TEST_STR="9 101 2 1" | ||
408 | if ! verify_diff_w "${TARGET}"; then | ||
409 | echo "FAIL" >&2 | ||
410 | rc=1 | ||
411 | else | ||
412 | echo "ok" | ||
413 | fi | ||
414 | test_rc | ||
415 | |||
416 | echo -n "Testing exceeding PAGE_SIZE limit fails as expected ... " | ||
417 | # Do not reset_vals, carry on the values from the last test. | ||
418 | # Now go over limit. | ||
419 | LIMIT=$((MAX_DIGITS)) | ||
420 | TEST_STR="7" | ||
421 | (perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \ | ||
422 | dd of="${TARGET}" 2>/dev/null | ||
423 | |||
424 | TEST_STR="7 101 2 1" | ||
425 | if verify_diff_w "${TARGET}"; then | ||
426 | echo "FAIL" >&2 | ||
427 | rc=1 | ||
428 | else | ||
429 | echo "ok" | ||
430 | fi | ||
431 | test_rc | ||
432 | } | ||
433 | |||
434 | # You are using an unsigned int | ||
435 | run_limit_digit_uint() | ||
436 | { | ||
437 | echo -n "Testing UINT_MAX works ..." | ||
438 | reset_vals | ||
439 | TEST_STR="$UINT_MAX" | ||
440 | echo -n $TEST_STR > $TARGET | ||
441 | |||
442 | if ! verify "${TARGET}"; then | ||
443 | echo "FAIL" >&2 | ||
444 | rc=1 | ||
445 | else | ||
446 | echo "ok" | ||
447 | fi | ||
448 | test_rc | ||
449 | |||
450 | echo -n "Testing UINT_MAX + 1 will fail as expected..." | ||
451 | reset_vals | ||
452 | TEST_STR=$(($UINT_MAX+1)) | ||
453 | echo -n $TEST_STR > $TARGET 2> /dev/null | ||
454 | |||
455 | if verify "${TARGET}"; then | ||
456 | echo "FAIL" >&2 | ||
457 | rc=1 | ||
458 | else | ||
459 | echo "ok" | ||
460 | fi | ||
461 | test_rc | ||
462 | |||
463 | echo -n "Testing negative values will not work as expected ..." | ||
464 | reset_vals | ||
465 | TEST_STR="-3" | ||
466 | echo -n $TEST_STR > $TARGET 2> /dev/null | ||
467 | |||
468 | if verify "${TARGET}"; then | ||
469 | echo "FAIL" >&2 | ||
470 | rc=1 | ||
471 | else | ||
472 | echo "ok" | ||
473 | fi | ||
474 | test_rc | ||
475 | } | ||
476 | |||
477 | run_stringtests() | ||
478 | { | ||
479 | echo -n "Writing entire sysctl in short writes ... " | ||
480 | set_orig | ||
481 | dd if="${TEST_FILE}" of="${TARGET}" bs=1 2>/dev/null | ||
482 | if ! verify "${TARGET}"; then | ||
483 | echo "FAIL" >&2 | ||
484 | rc=1 | ||
485 | else | ||
486 | echo "ok" | ||
487 | fi | ||
488 | |||
489 | echo -n "Writing middle of sysctl after unsynchronized seek ... " | ||
490 | set_test | ||
491 | dd if="${TEST_FILE}" of="${TARGET}" bs=1 seek=1 2>/dev/null | ||
492 | if verify "${TARGET}"; then | ||
493 | echo "FAIL" >&2 | ||
494 | rc=1 | ||
495 | else | ||
496 | echo "ok" | ||
497 | fi | ||
498 | |||
499 | echo -n "Checking sysctl maxlen is at least $MAXLEN ... " | ||
500 | set_orig | ||
501 | perl -e 'print "A" x ('"${MAXLEN}"'-2), "B";' | \ | ||
502 | dd of="${TARGET}" bs="${MAXLEN}" 2>/dev/null | ||
503 | if ! grep -q B "${TARGET}"; then | ||
504 | echo "FAIL" >&2 | ||
505 | rc=1 | ||
506 | else | ||
507 | echo "ok" | ||
508 | fi | ||
509 | |||
510 | echo -n "Checking sysctl keeps original string on overflow append ... " | ||
511 | set_orig | ||
512 | perl -e 'print "A" x ('"${MAXLEN}"'-1), "B";' | \ | ||
513 | dd of="${TARGET}" bs=$(( MAXLEN - 1 )) 2>/dev/null | ||
514 | if grep -q B "${TARGET}"; then | ||
515 | echo "FAIL" >&2 | ||
516 | rc=1 | ||
517 | else | ||
518 | echo "ok" | ||
519 | fi | ||
520 | |||
521 | echo -n "Checking sysctl stays NULL terminated on write ... " | ||
522 | set_orig | ||
523 | perl -e 'print "A" x ('"${MAXLEN}"'-1), "B";' | \ | ||
524 | dd of="${TARGET}" bs="${MAXLEN}" 2>/dev/null | ||
525 | if grep -q B "${TARGET}"; then | ||
526 | echo "FAIL" >&2 | ||
527 | rc=1 | ||
528 | else | ||
529 | echo "ok" | ||
530 | fi | ||
531 | |||
532 | echo -n "Checking sysctl stays NULL terminated on overwrite ... " | ||
533 | set_orig | ||
534 | perl -e 'print "A" x ('"${MAXLEN}"'-1), "BB";' | \ | ||
535 | dd of="${TARGET}" bs=$(( $MAXLEN + 1 )) 2>/dev/null | ||
536 | if grep -q B "${TARGET}"; then | ||
537 | echo "FAIL" >&2 | ||
538 | rc=1 | ||
539 | else | ||
540 | echo "ok" | ||
541 | fi | ||
542 | |||
543 | test_rc | ||
544 | } | ||
545 | |||
546 | sysctl_test_0001() | ||
547 | { | ||
548 | TARGET="${SYSCTL}/int_0001" | ||
549 | reset_vals | ||
550 | ORIG=$(cat "${TARGET}") | ||
551 | TEST_STR=$(( $ORIG + 1 )) | ||
552 | |||
553 | run_numerictests | ||
554 | run_limit_digit | ||
555 | } | ||
556 | |||
557 | sysctl_test_0002() | ||
558 | { | ||
559 | TARGET="${SYSCTL}/string_0001" | ||
560 | reset_vals | ||
561 | ORIG=$(cat "${TARGET}") | ||
562 | TEST_STR="Testing sysctl" | ||
563 | # Only string sysctls support seeking/appending. | ||
564 | MAXLEN=65 | ||
565 | |||
566 | run_numerictests | ||
567 | run_stringtests | ||
568 | } | ||
569 | |||
570 | sysctl_test_0003() | ||
571 | { | ||
572 | TARGET="${SYSCTL}/int_0002" | ||
573 | reset_vals | ||
574 | ORIG=$(cat "${TARGET}") | ||
575 | TEST_STR=$(( $ORIG + 1 )) | ||
576 | |||
577 | run_numerictests | ||
578 | run_limit_digit | ||
579 | run_limit_digit_int | ||
580 | } | ||
581 | |||
582 | sysctl_test_0004() | ||
583 | { | ||
584 | TARGET="${SYSCTL}/uint_0001" | ||
585 | reset_vals | ||
586 | ORIG=$(cat "${TARGET}") | ||
587 | TEST_STR=$(( $ORIG + 1 )) | ||
588 | |||
589 | run_numerictests | ||
590 | run_limit_digit | ||
591 | run_limit_digit_uint | ||
592 | } | ||
593 | |||
594 | sysctl_test_0005() | ||
595 | { | ||
596 | TARGET="${SYSCTL}/int_0003" | ||
597 | reset_vals | ||
598 | ORIG=$(cat "${TARGET}") | ||
599 | |||
600 | run_limit_digit_int_array | ||
601 | } | ||
602 | |||
603 | list_tests() | ||
604 | { | ||
605 | echo "Test ID list:" | ||
606 | echo | ||
607 | echo "TEST_ID x NUM_TEST" | ||
608 | echo "TEST_ID: Test ID" | ||
609 | echo "NUM_TESTS: Number of recommended times to run the test" | ||
610 | echo | ||
611 | echo "0001 x $(get_test_count 0001) - tests proc_dointvec_minmax()" | ||
612 | echo "0002 x $(get_test_count 0002) - tests proc_dostring()" | ||
613 | echo "0003 x $(get_test_count 0003) - tests proc_dointvec()" | ||
614 | echo "0004 x $(get_test_count 0004) - tests proc_douintvec()" | ||
615 | echo "0005 x $(get_test_count 0005) - tests proc_douintvec() array" | ||
616 | } | ||
617 | |||
618 | test_reqs | ||
619 | |||
620 | usage() | ||
621 | { | ||
622 | NUM_TESTS=$(grep -o ' ' <<<"$ALL_TESTS" | grep -c .) | ||
623 | let NUM_TESTS=$NUM_TESTS+1 | ||
624 | MAX_TEST=$(printf "%04d\n" $NUM_TESTS) | ||
625 | echo "Usage: $0 [ -t <4-number-digit> ] | [ -w <4-number-digit> ] |" | ||
626 | echo " [ -s <4-number-digit> ] | [ -c <4-number-digit> <test- count>" | ||
627 | echo " [ all ] [ -h | --help ] [ -l ]" | ||
628 | echo "" | ||
629 | echo "Valid tests: 0001-$MAX_TEST" | ||
630 | echo "" | ||
631 | echo " all Runs all tests (default)" | ||
632 | echo " -t Run test ID the number amount of times is recommended" | ||
633 | echo " -w Watch test ID run until it runs into an error" | ||
634 | echo " -c Run test ID once" | ||
635 | echo " -s Run test ID x test-count number of times" | ||
636 | echo " -l List all test ID list" | ||
637 | echo " -h|--help Help" | ||
638 | echo | ||
639 | echo "If an error every occurs execution will immediately terminate." | ||
640 | echo "If you are adding a new test try using -w <test-ID> first to" | ||
641 | echo "make sure the test passes a series of tests." | ||
642 | echo | ||
643 | echo Example uses: | ||
644 | echo | ||
645 | echo "$TEST_NAME.sh -- executes all tests" | ||
646 | echo "$TEST_NAME.sh -t 0002 -- Executes test ID 0002 number of times is recomended" | ||
647 | echo "$TEST_NAME.sh -w 0002 -- Watch test ID 0002 run until an error occurs" | ||
648 | echo "$TEST_NAME.sh -s 0002 -- Run test ID 0002 once" | ||
649 | echo "$TEST_NAME.sh -c 0002 3 -- Run test ID 0002 three times" | ||
650 | echo | ||
651 | list_tests | ||
652 | exit 1 | ||
653 | } | ||
654 | |||
655 | function test_num() | ||
656 | { | ||
657 | re='^[0-9]+$' | ||
658 | if ! [[ $1 =~ $re ]]; then | ||
659 | usage | ||
660 | fi | ||
661 | } | ||
662 | |||
663 | function get_test_count() | ||
664 | { | ||
665 | test_num $1 | ||
666 | TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$1'}') | ||
667 | LAST_TWO=${TEST_DATA#*:*} | ||
668 | echo ${LAST_TWO%:*} | ||
669 | } | ||
670 | |||
671 | function get_test_enabled() | ||
672 | { | ||
673 | test_num $1 | ||
674 | TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$1'}') | ||
675 | echo ${TEST_DATA#*:*:} | ||
676 | } | ||
677 | |||
678 | function run_all_tests() | ||
679 | { | ||
680 | for i in $ALL_TESTS ; do | ||
681 | TEST_ID=${i%:*:*} | ||
682 | ENABLED=$(get_test_enabled $TEST_ID) | ||
683 | TEST_COUNT=$(get_test_count $TEST_ID) | ||
684 | if [[ $ENABLED -eq "1" ]]; then | ||
685 | test_case $TEST_ID $TEST_COUNT | ||
686 | fi | ||
687 | done | ||
688 | } | ||
689 | |||
690 | function watch_log() | ||
691 | { | ||
692 | if [ $# -ne 3 ]; then | ||
693 | clear | ||
694 | fi | ||
695 | date | ||
696 | echo "Running test: $2 - run #$1" | ||
697 | } | ||
698 | |||
699 | function watch_case() | ||
700 | { | ||
701 | i=0 | ||
702 | while [ 1 ]; do | ||
703 | |||
704 | if [ $# -eq 1 ]; then | ||
705 | test_num $1 | ||
706 | watch_log $i ${TEST_NAME}_test_$1 | ||
707 | ${TEST_NAME}_test_$1 | ||
708 | else | ||
709 | watch_log $i all | ||
710 | run_all_tests | ||
711 | fi | ||
712 | let i=$i+1 | ||
713 | done | ||
714 | } | ||
715 | |||
716 | function test_case() | ||
717 | { | ||
718 | NUM_TESTS=$DEFAULT_NUM_TESTS | ||
719 | if [ $# -eq 2 ]; then | ||
720 | NUM_TESTS=$2 | ||
721 | fi | ||
722 | |||
723 | i=0 | ||
724 | while [ $i -lt $NUM_TESTS ]; do | ||
725 | test_num $1 | ||
726 | watch_log $i ${TEST_NAME}_test_$1 noclear | ||
727 | RUN_TEST=${TEST_NAME}_test_$1 | ||
728 | $RUN_TEST | ||
729 | let i=$i+1 | ||
730 | done | ||
731 | } | ||
732 | |||
733 | function parse_args() | ||
734 | { | ||
735 | if [ $# -eq 0 ]; then | ||
736 | run_all_tests | ||
737 | else | ||
738 | if [[ "$1" = "all" ]]; then | ||
739 | run_all_tests | ||
740 | elif [[ "$1" = "-w" ]]; then | ||
741 | shift | ||
742 | watch_case $@ | ||
743 | elif [[ "$1" = "-t" ]]; then | ||
744 | shift | ||
745 | test_num $1 | ||
746 | test_case $1 $(get_test_count $1) | ||
747 | elif [[ "$1" = "-c" ]]; then | ||
748 | shift | ||
749 | test_num $1 | ||
750 | test_num $2 | ||
751 | test_case $1 $2 | ||
752 | elif [[ "$1" = "-s" ]]; then | ||
753 | shift | ||
754 | test_case $1 1 | ||
755 | elif [[ "$1" = "-l" ]]; then | ||
756 | list_tests | ||
757 | elif [[ "$1" = "-h" || "$1" = "--help" ]]; then | ||
758 | usage | ||
759 | else | ||
760 | usage | ||
761 | fi | ||
762 | fi | ||
763 | } | ||
764 | |||
765 | test_reqs | ||
766 | allow_user_defaults | ||
767 | check_production_sysctl_writes_strict | ||
768 | load_req_mod | ||
769 | |||
770 | trap "test_finish" EXIT | ||
771 | |||
772 | parse_args $@ | ||
773 | |||
774 | exit 0 | ||
diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index 5801bbefbe89..a9b86133b9b3 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile | |||
@@ -9,7 +9,7 @@ TEST_GEN_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \ | |||
9 | 9 | ||
10 | TEST_GEN_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex adjtick change_skew \ | 10 | TEST_GEN_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex adjtick change_skew \ |
11 | skew_consistency clocksource-switch freq-step leap-a-day \ | 11 | skew_consistency clocksource-switch freq-step leap-a-day \ |
12 | leapcrash set-tai set-2038 set-tz | 12 | leapcrash set-tai set-2038 set-tz rtctest_setdate |
13 | 13 | ||
14 | 14 | ||
15 | include ../lib.mk | 15 | include ../lib.mk |
diff --git a/tools/testing/selftests/timers/rtctest.c b/tools/testing/selftests/timers/rtctest.c index 4230d3052e5d..f61170f7b024 100644 --- a/tools/testing/selftests/timers/rtctest.c +++ b/tools/testing/selftests/timers/rtctest.c | |||
@@ -21,6 +21,9 @@ | |||
21 | #include <stdlib.h> | 21 | #include <stdlib.h> |
22 | #include <errno.h> | 22 | #include <errno.h> |
23 | 23 | ||
24 | #ifndef ARRAY_SIZE | ||
25 | # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | ||
26 | #endif | ||
24 | 27 | ||
25 | /* | 28 | /* |
26 | * This expects the new RTC class driver framework, working with | 29 | * This expects the new RTC class driver framework, working with |
@@ -29,23 +32,84 @@ | |||
29 | */ | 32 | */ |
30 | static const char default_rtc[] = "/dev/rtc0"; | 33 | static const char default_rtc[] = "/dev/rtc0"; |
31 | 34 | ||
35 | static struct rtc_time cutoff_dates[] = { | ||
36 | { | ||
37 | .tm_year = 70, /* 1970 -1900 */ | ||
38 | .tm_mday = 1, | ||
39 | }, | ||
40 | /* signed time_t 19/01/2038 3:14:08 */ | ||
41 | { | ||
42 | .tm_year = 138, | ||
43 | .tm_mday = 19, | ||
44 | }, | ||
45 | { | ||
46 | .tm_year = 138, | ||
47 | .tm_mday = 20, | ||
48 | }, | ||
49 | { | ||
50 | .tm_year = 199, /* 2099 -1900 */ | ||
51 | .tm_mday = 1, | ||
52 | }, | ||
53 | { | ||
54 | .tm_year = 200, /* 2100 -1900 */ | ||
55 | .tm_mday = 1, | ||
56 | }, | ||
57 | /* unsigned time_t 07/02/2106 7:28:15*/ | ||
58 | { | ||
59 | .tm_year = 205, | ||
60 | .tm_mon = 1, | ||
61 | .tm_mday = 7, | ||
62 | }, | ||
63 | { | ||
64 | .tm_year = 206, | ||
65 | .tm_mon = 1, | ||
66 | .tm_mday = 8, | ||
67 | }, | ||
68 | /* signed time on 64bit in nanoseconds 12/04/2262 01:47:16*/ | ||
69 | { | ||
70 | .tm_year = 362, | ||
71 | .tm_mon = 3, | ||
72 | .tm_mday = 12, | ||
73 | }, | ||
74 | { | ||
75 | .tm_year = 362, /* 2262 -1900 */ | ||
76 | .tm_mon = 3, | ||
77 | .tm_mday = 13, | ||
78 | }, | ||
79 | }; | ||
80 | |||
81 | static int compare_dates(struct rtc_time *a, struct rtc_time *b) | ||
82 | { | ||
83 | if (a->tm_year != b->tm_year || | ||
84 | a->tm_mon != b->tm_mon || | ||
85 | a->tm_mday != b->tm_mday || | ||
86 | a->tm_hour != b->tm_hour || | ||
87 | a->tm_min != b->tm_min || | ||
88 | ((b->tm_sec - a->tm_sec) > 1)) | ||
89 | return 1; | ||
90 | |||
91 | return 0; | ||
92 | } | ||
32 | 93 | ||
33 | int main(int argc, char **argv) | 94 | int main(int argc, char **argv) |
34 | { | 95 | { |
35 | int i, fd, retval, irqcount = 0; | 96 | int i, fd, retval, irqcount = 0, dangerous = 0; |
36 | unsigned long tmp, data; | 97 | unsigned long tmp, data; |
37 | struct rtc_time rtc_tm; | 98 | struct rtc_time rtc_tm; |
38 | const char *rtc = default_rtc; | 99 | const char *rtc = default_rtc; |
39 | struct timeval start, end, diff; | 100 | struct timeval start, end, diff; |
40 | 101 | ||
41 | switch (argc) { | 102 | switch (argc) { |
103 | case 3: | ||
104 | if (*argv[2] == 'd') | ||
105 | dangerous = 1; | ||
42 | case 2: | 106 | case 2: |
43 | rtc = argv[1]; | 107 | rtc = argv[1]; |
44 | /* FALLTHROUGH */ | 108 | /* FALLTHROUGH */ |
45 | case 1: | 109 | case 1: |
46 | break; | 110 | break; |
47 | default: | 111 | default: |
48 | fprintf(stderr, "usage: rtctest [rtcdev]\n"); | 112 | fprintf(stderr, "usage: rtctest [rtcdev] [d]\n"); |
49 | return 1; | 113 | return 1; |
50 | } | 114 | } |
51 | 115 | ||
@@ -202,7 +266,7 @@ test_PIE: | |||
202 | /* not all RTCs support periodic IRQs */ | 266 | /* not all RTCs support periodic IRQs */ |
203 | if (errno == EINVAL) { | 267 | if (errno == EINVAL) { |
204 | fprintf(stderr, "\nNo periodic IRQ support\n"); | 268 | fprintf(stderr, "\nNo periodic IRQ support\n"); |
205 | goto done; | 269 | goto test_DATE; |
206 | } | 270 | } |
207 | perror("RTC_IRQP_READ ioctl"); | 271 | perror("RTC_IRQP_READ ioctl"); |
208 | exit(errno); | 272 | exit(errno); |
@@ -221,7 +285,7 @@ test_PIE: | |||
221 | if (errno == EINVAL) { | 285 | if (errno == EINVAL) { |
222 | fprintf(stderr, | 286 | fprintf(stderr, |
223 | "\n...Periodic IRQ rate is fixed\n"); | 287 | "\n...Periodic IRQ rate is fixed\n"); |
224 | goto done; | 288 | goto test_DATE; |
225 | } | 289 | } |
226 | perror("RTC_IRQP_SET ioctl"); | 290 | perror("RTC_IRQP_SET ioctl"); |
227 | exit(errno); | 291 | exit(errno); |
@@ -269,6 +333,62 @@ test_PIE: | |||
269 | } | 333 | } |
270 | } | 334 | } |
271 | 335 | ||
336 | test_DATE: | ||
337 | if (!dangerous) | ||
338 | goto done; | ||
339 | |||
340 | fprintf(stderr, "\nTesting problematic dates\n"); | ||
341 | |||
342 | for (i = 0; i < ARRAY_SIZE(cutoff_dates); i++) { | ||
343 | struct rtc_time current; | ||
344 | |||
345 | /* Write the new date in RTC */ | ||
346 | retval = ioctl(fd, RTC_SET_TIME, &cutoff_dates[i]); | ||
347 | if (retval == -1) { | ||
348 | perror("RTC_SET_TIME ioctl"); | ||
349 | close(fd); | ||
350 | exit(errno); | ||
351 | } | ||
352 | |||
353 | /* Read back */ | ||
354 | retval = ioctl(fd, RTC_RD_TIME, ¤t); | ||
355 | if (retval == -1) { | ||
356 | perror("RTC_RD_TIME ioctl"); | ||
357 | exit(errno); | ||
358 | } | ||
359 | |||
360 | if(compare_dates(&cutoff_dates[i], ¤t)) { | ||
361 | fprintf(stderr,"Setting date %d failed\n", | ||
362 | cutoff_dates[i].tm_year + 1900); | ||
363 | goto done; | ||
364 | } | ||
365 | |||
366 | cutoff_dates[i].tm_sec += 5; | ||
367 | |||
368 | /* Write the new alarm in RTC */ | ||
369 | retval = ioctl(fd, RTC_ALM_SET, &cutoff_dates[i]); | ||
370 | if (retval == -1) { | ||
371 | perror("RTC_ALM_SET ioctl"); | ||
372 | close(fd); | ||
373 | exit(errno); | ||
374 | } | ||
375 | |||
376 | /* Read back */ | ||
377 | retval = ioctl(fd, RTC_ALM_READ, ¤t); | ||
378 | if (retval == -1) { | ||
379 | perror("RTC_ALM_READ ioctl"); | ||
380 | exit(errno); | ||
381 | } | ||
382 | |||
383 | if(compare_dates(&cutoff_dates[i], ¤t)) { | ||
384 | fprintf(stderr,"Setting alarm %d failed\n", | ||
385 | cutoff_dates[i].tm_year + 1900); | ||
386 | goto done; | ||
387 | } | ||
388 | |||
389 | fprintf(stderr, "Setting year %d is OK \n", | ||
390 | cutoff_dates[i].tm_year + 1900); | ||
391 | } | ||
272 | done: | 392 | done: |
273 | fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n"); | 393 | fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n"); |
274 | 394 | ||
diff --git a/tools/testing/selftests/timers/rtctest_setdate.c b/tools/testing/selftests/timers/rtctest_setdate.c new file mode 100644 index 000000000000..2cb78489eca4 --- /dev/null +++ b/tools/testing/selftests/timers/rtctest_setdate.c | |||
@@ -0,0 +1,86 @@ | |||
1 | /* Real Time Clock Driver Test | ||
2 | * by: Benjamin Gaignard (benjamin.gaignard@linaro.org) | ||
3 | * | ||
4 | * To build | ||
5 | * gcc rtctest_setdate.c -o rtctest_setdate | ||
6 | * | ||
7 | * This program is free software: you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation, either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <stdio.h> | ||
19 | #include <linux/rtc.h> | ||
20 | #include <sys/ioctl.h> | ||
21 | #include <sys/time.h> | ||
22 | #include <sys/types.h> | ||
23 | #include <fcntl.h> | ||
24 | #include <unistd.h> | ||
25 | #include <stdlib.h> | ||
26 | #include <errno.h> | ||
27 | |||
28 | static const char default_time[] = "00:00:00"; | ||
29 | |||
30 | int main(int argc, char **argv) | ||
31 | { | ||
32 | int fd, retval; | ||
33 | struct rtc_time new, current; | ||
34 | const char *rtc, *date; | ||
35 | const char *time = default_time; | ||
36 | |||
37 | switch (argc) { | ||
38 | case 4: | ||
39 | time = argv[3]; | ||
40 | /* FALLTHROUGH */ | ||
41 | case 3: | ||
42 | date = argv[2]; | ||
43 | rtc = argv[1]; | ||
44 | break; | ||
45 | default: | ||
46 | fprintf(stderr, "usage: rtctest_setdate <rtcdev> <DD-MM-YYYY> [HH:MM:SS]\n"); | ||
47 | return 1; | ||
48 | } | ||
49 | |||
50 | fd = open(rtc, O_RDONLY); | ||
51 | if (fd == -1) { | ||
52 | perror(rtc); | ||
53 | exit(errno); | ||
54 | } | ||
55 | |||
56 | sscanf(date, "%d-%d-%d", &new.tm_mday, &new.tm_mon, &new.tm_year); | ||
57 | new.tm_mon -= 1; | ||
58 | new.tm_year -= 1900; | ||
59 | sscanf(time, "%d:%d:%d", &new.tm_hour, &new.tm_min, &new.tm_sec); | ||
60 | |||
61 | fprintf(stderr, "Test will set RTC date/time to %d-%d-%d, %02d:%02d:%02d.\n", | ||
62 | new.tm_mday, new.tm_mon + 1, new.tm_year + 1900, | ||
63 | new.tm_hour, new.tm_min, new.tm_sec); | ||
64 | |||
65 | /* Write the new date in RTC */ | ||
66 | retval = ioctl(fd, RTC_SET_TIME, &new); | ||
67 | if (retval == -1) { | ||
68 | perror("RTC_SET_TIME ioctl"); | ||
69 | close(fd); | ||
70 | exit(errno); | ||
71 | } | ||
72 | |||
73 | /* Read back */ | ||
74 | retval = ioctl(fd, RTC_RD_TIME, ¤t); | ||
75 | if (retval == -1) { | ||
76 | perror("RTC_RD_TIME ioctl"); | ||
77 | exit(errno); | ||
78 | } | ||
79 | |||
80 | fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n", | ||
81 | current.tm_mday, current.tm_mon + 1, current.tm_year + 1900, | ||
82 | current.tm_hour, current.tm_min, current.tm_sec); | ||
83 | |||
84 | close(fd); | ||
85 | return 0; | ||
86 | } | ||