1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2020 Facebook */ 3 #include <linux/error-injection.h> 4 #include <linux/init.h> 5 #include <linux/module.h> 6 #include <linux/percpu-defs.h> 7 #include <linux/sysfs.h> 8 #include <linux/tracepoint.h> 9 #include "bpf_testmod.h" 10 11 #define CREATE_TRACE_POINTS 12 #include "bpf_testmod-events.h" 13 14 DEFINE_PER_CPU(int, bpf_testmod_ksym_percpu) = 123; 15 16 noinline int bpf_testmod_loop_test(int n) 17 { 18 int i, sum = 0; 19 20 /* the primary goal of this test is to test LBR. Create a lot of 21 * branches in the function, so we can catch it easily. 22 */ 23 for (i = 0; i < n; i++) 24 sum += i; 25 return sum; 26 } 27 28 noinline ssize_t 29 bpf_testmod_test_read(struct file *file, struct kobject *kobj, 30 struct bin_attribute *bin_attr, 31 char *buf, loff_t off, size_t len) 32 { 33 struct bpf_testmod_test_read_ctx ctx = { 34 .buf = buf, 35 .off = off, 36 .len = len, 37 }; 38 39 /* This is always true. Use the check to make sure the compiler 40 * doesn't remove bpf_testmod_loop_test. 41 */ 42 if (bpf_testmod_loop_test(101) > 100) 43 trace_bpf_testmod_test_read(current, &ctx); 44 45 return -EIO; /* always fail */ 46 } 47 EXPORT_SYMBOL(bpf_testmod_test_read); 48 ALLOW_ERROR_INJECTION(bpf_testmod_test_read, ERRNO); 49 50 noinline ssize_t 51 bpf_testmod_test_write(struct file *file, struct kobject *kobj, 52 struct bin_attribute *bin_attr, 53 char *buf, loff_t off, size_t len) 54 { 55 struct bpf_testmod_test_write_ctx ctx = { 56 .buf = buf, 57 .off = off, 58 .len = len, 59 }; 60 61 trace_bpf_testmod_test_write_bare(current, &ctx); 62 63 return -EIO; /* always fail */ 64 } 65 EXPORT_SYMBOL(bpf_testmod_test_write); 66 ALLOW_ERROR_INJECTION(bpf_testmod_test_write, ERRNO); 67 68 static struct bin_attribute bin_attr_bpf_testmod_file __ro_after_init = { 69 .attr = { .name = "bpf_testmod", .mode = 0666, }, 70 .read = bpf_testmod_test_read, 71 .write = bpf_testmod_test_write, 72 }; 73 74 static int bpf_testmod_init(void) 75 { 76 return sysfs_create_bin_file(kernel_kobj, &bin_attr_bpf_testmod_file); 77 } 78 79 static void bpf_testmod_exit(void) 80 { 81 return sysfs_remove_bin_file(kernel_kobj, &bin_attr_bpf_testmod_file); 82 } 83 84 module_init(bpf_testmod_init); 85 module_exit(bpf_testmod_exit); 86 87 MODULE_AUTHOR("Andrii Nakryiko"); 88 MODULE_DESCRIPTION("BPF selftests module"); 89 MODULE_LICENSE("Dual BSD/GPL"); 90