1#include "bpf_experimental.h" 2#include "bpf_misc.h" 3 4struct val_t { 5 long b, c, d; 6}; 7 8struct val2_t { 9 long b; 10}; 11 12struct val_with_ptr_t { 13 char *p; 14}; 15 16struct val_with_rb_root_t { 17 struct bpf_spin_lock lock; 18}; 19 20struct val_600b_t { 21 char b[600]; 22}; 23 24struct elem { 25 long sum; 26 struct val_t __percpu_kptr *pc; 27}; 28 29struct { 30 __uint(type, BPF_MAP_TYPE_ARRAY); 31 __uint(max_entries, 1); 32 __type(key, int); 33 __type(value, struct elem); 34} array SEC(".maps"); 35 36long ret; 37 38SEC("?fentry/bpf_fentry_test1") 39__failure __msg("store to referenced kptr disallowed") 40int BPF_PROG(test_array_map_1) 41{ 42 struct val_t __percpu_kptr *p; 43 struct elem *e; 44 int index = 0; 45 46 e = bpf_map_lookup_elem(&array, &index); 47 if (!e) 48 return 0; 49 50 p = bpf_percpu_obj_new(struct val_t); 51 if (!p) 52 return 0; 53 54 p = bpf_kptr_xchg(&e->pc, p); 55 if (p) 56 bpf_percpu_obj_drop(p); 57 58 e->pc = (struct val_t __percpu_kptr *)ret; 59 return 0; 60} 61 62SEC("?fentry/bpf_fentry_test1") 63__failure __msg("invalid kptr access, R2 type=percpu_ptr_val2_t expected=ptr_val_t") 64int BPF_PROG(test_array_map_2) 65{ 66 struct val2_t __percpu_kptr *p2; 67 struct val_t __percpu_kptr *p; 68 struct elem *e; 69 int index = 0; 70 71 e = bpf_map_lookup_elem(&array, &index); 72 if (!e) 73 return 0; 74 75 p2 = bpf_percpu_obj_new(struct val2_t); 76 if (!p2) 77 return 0; 78 79 p = bpf_kptr_xchg(&e->pc, p2); 80 if (p) 81 bpf_percpu_obj_drop(p); 82 83 return 0; 84} 85 86SEC("?fentry.s/bpf_fentry_test1") 87__failure __msg("R1 type=scalar expected=percpu_ptr_, percpu_rcu_ptr_, percpu_trusted_ptr_") 88int BPF_PROG(test_array_map_3) 89{ 90 struct val_t __percpu_kptr *p, *p1; 91 struct val_t *v; 92 struct elem *e; 93 int index = 0; 94 95 e = bpf_map_lookup_elem(&array, &index); 96 if (!e) 97 return 0; 98 99 p = bpf_percpu_obj_new(struct val_t); 100 if (!p) 101 return 0; 102 103 p1 = bpf_kptr_xchg(&e->pc, p); 104 if (p1) 105 bpf_percpu_obj_drop(p1); 106 107 v = bpf_this_cpu_ptr(p); 108 ret = v->b; 109 return 0; 110} 111 112SEC("?fentry.s/bpf_fentry_test1") 113__failure __msg("arg#0 expected for bpf_percpu_obj_drop_impl()") 114int BPF_PROG(test_array_map_4) 115{ 116 struct val_t __percpu_kptr *p; 117 118 p = bpf_percpu_obj_new(struct val_t); 119 if (!p) 120 return 0; 121 122 bpf_obj_drop(p); 123 return 0; 124} 125 126SEC("?fentry.s/bpf_fentry_test1") 127__failure __msg("arg#0 expected for bpf_obj_drop_impl()") 128int BPF_PROG(test_array_map_5) 129{ 130 struct val_t *p; 131 132 p = bpf_obj_new(struct val_t); 133 if (!p) 134 return 0; 135 136 bpf_percpu_obj_drop(p); 137 return 0; 138} 139 140SEC("?fentry.s/bpf_fentry_test1") 141__failure __msg("bpf_percpu_obj_new type ID argument must be of a struct of scalars") 142int BPF_PROG(test_array_map_6) 143{ 144 struct val_with_ptr_t __percpu_kptr *p; 145 146 p = bpf_percpu_obj_new(struct val_with_ptr_t); 147 if (!p) 148 return 0; 149 150 bpf_percpu_obj_drop(p); 151 return 0; 152} 153 154SEC("?fentry.s/bpf_fentry_test1") 155__failure __msg("bpf_percpu_obj_new type ID argument must not contain special fields") 156int BPF_PROG(test_array_map_7) 157{ 158 struct val_with_rb_root_t __percpu_kptr *p; 159 160 p = bpf_percpu_obj_new(struct val_with_rb_root_t); 161 if (!p) 162 return 0; 163 164 bpf_percpu_obj_drop(p); 165 return 0; 166} 167 168SEC("?fentry.s/bpf_fentry_test1") 169__failure __msg("bpf_percpu_obj_new type size (600) is greater than 512") 170int BPF_PROG(test_array_map_8) 171{ 172 struct val_600b_t __percpu_kptr *p; 173 174 p = bpf_percpu_obj_new(struct val_600b_t); 175 if (!p) 176 return 0; 177 178 bpf_percpu_obj_drop(p); 179 return 0; 180} 181 182char _license[] SEC("license") = "GPL"; 183