Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Fast path bpf marge for some -next work.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+119 -15
+4 -5
include/linux/bpf.h
··· 220 220 static inline void check_and_init_map_value(struct bpf_map *map, void *dst) 221 221 { 222 222 if (unlikely(map_value_has_spin_lock(map))) 223 - *(struct bpf_spin_lock *)(dst + map->spin_lock_off) = 224 - (struct bpf_spin_lock){}; 223 + memset(dst + map->spin_lock_off, 0, sizeof(struct bpf_spin_lock)); 225 224 if (unlikely(map_value_has_timer(map))) 226 - *(struct bpf_timer *)(dst + map->timer_off) = 227 - (struct bpf_timer){}; 225 + memset(dst + map->timer_off, 0, sizeof(struct bpf_timer)); 228 226 } 229 227 230 228 /* copy everything but bpf_spin_lock and bpf_timer. There could be one of each. */ ··· 233 235 if (unlikely(map_value_has_spin_lock(map))) { 234 236 s_off = map->spin_lock_off; 235 237 s_sz = sizeof(struct bpf_spin_lock); 236 - } else if (unlikely(map_value_has_timer(map))) { 238 + } 239 + if (unlikely(map_value_has_timer(map))) { 237 240 t_off = map->timer_off; 238 241 t_sz = sizeof(struct bpf_timer); 239 242 }
+3 -2
kernel/bpf/btf.c
··· 5789 5789 } 5790 5790 if (check_ptr_off_reg(env, reg, regno)) 5791 5791 return -EINVAL; 5792 - } else if (is_kfunc && (reg->type == PTR_TO_BTF_ID || reg2btf_ids[reg->type])) { 5792 + } else if (is_kfunc && (reg->type == PTR_TO_BTF_ID || 5793 + (reg2btf_ids[base_type(reg->type)] && !type_flag(reg->type)))) { 5793 5794 const struct btf_type *reg_ref_t; 5794 5795 const struct btf *reg_btf; 5795 5796 const char *reg_ref_tname; ··· 5818 5817 } 5819 5818 } else { 5820 5819 reg_btf = btf_vmlinux; 5821 - reg_ref_id = *reg2btf_ids[reg->type]; 5820 + reg_ref_id = *reg2btf_ids[base_type(reg->type)]; 5822 5821 } 5823 5822 5824 5823 reg_ref_t = btf_type_skip_modifiers(reg_btf, reg_ref_id,
+2
kernel/bpf/helpers.c
··· 2 2 /* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com 3 3 */ 4 4 #include <linux/bpf.h> 5 + #include <linux/btf.h> 5 6 #include <linux/bpf-cgroup.h> 6 7 #include <linux/rcupdate.h> 7 8 #include <linux/random.h> ··· 1110 1109 void *key; 1111 1110 u32 idx; 1112 1111 1112 + BTF_TYPE_EMIT(struct bpf_timer); 1113 1113 callback_fn = rcu_dereference_check(t->callback_fn, rcu_read_lock_bh_held()); 1114 1114 if (!callback_fn) 1115 1115 goto out;
+3
kernel/bpf/syscall.c
··· 1354 1354 maybe_wait_bpf_programs(map); 1355 1355 if (err) 1356 1356 break; 1357 + cond_resched(); 1357 1358 } 1358 1359 if (copy_to_user(&uattr->batch.count, &cp, sizeof(cp))) 1359 1360 err = -EFAULT; ··· 1412 1411 1413 1412 if (err) 1414 1413 break; 1414 + cond_resched(); 1415 1415 } 1416 1416 1417 1417 if (copy_to_user(&uattr->batch.count, &cp, sizeof(cp))) ··· 1510 1508 swap(prev_key, key); 1511 1509 retry = MAP_LOOKUP_RETRIES; 1512 1510 cp++; 1511 + cond_resched(); 1513 1512 } 1514 1513 1515 1514 if (err == -EFAULT)
+3
net/core/filter.c
··· 2710 2710 if (unlikely(flags)) 2711 2711 return -EINVAL; 2712 2712 2713 + if (unlikely(len == 0)) 2714 + return 0; 2715 + 2713 2716 /* First find the starting scatterlist element */ 2714 2717 i = msg->sg.start; 2715 2718 do {
+32
tools/testing/selftests/bpf/prog_tests/timer_crash.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include <test_progs.h> 3 + #include "timer_crash.skel.h" 4 + 5 + enum { 6 + MODE_ARRAY, 7 + MODE_HASH, 8 + }; 9 + 10 + static void test_timer_crash_mode(int mode) 11 + { 12 + struct timer_crash *skel; 13 + 14 + skel = timer_crash__open_and_load(); 15 + if (!ASSERT_OK_PTR(skel, "timer_crash__open_and_load")) 16 + return; 17 + skel->bss->pid = getpid(); 18 + skel->bss->crash_map = mode; 19 + if (!ASSERT_OK(timer_crash__attach(skel), "timer_crash__attach")) 20 + goto end; 21 + usleep(1); 22 + end: 23 + timer_crash__destroy(skel); 24 + } 25 + 26 + void test_timer_crash(void) 27 + { 28 + if (test__start_subtest("array")) 29 + test_timer_crash_mode(MODE_ARRAY); 30 + if (test__start_subtest("hash")) 31 + test_timer_crash_mode(MODE_HASH); 32 + }
+18 -8
tools/testing/selftests/bpf/progs/test_sockmap_kern.h
··· 235 235 int bpf_prog4(struct sk_msg_md *msg) 236 236 { 237 237 int *bytes, zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5; 238 - int *start, *end, *start_push, *end_push, *start_pop, *pop; 238 + int *start, *end, *start_push, *end_push, *start_pop, *pop, err = 0; 239 239 240 240 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero); 241 241 if (bytes) ··· 249 249 bpf_msg_pull_data(msg, *start, *end, 0); 250 250 start_push = bpf_map_lookup_elem(&sock_bytes, &two); 251 251 end_push = bpf_map_lookup_elem(&sock_bytes, &three); 252 - if (start_push && end_push) 253 - bpf_msg_push_data(msg, *start_push, *end_push, 0); 252 + if (start_push && end_push) { 253 + err = bpf_msg_push_data(msg, *start_push, *end_push, 0); 254 + if (err) 255 + return SK_DROP; 256 + } 254 257 start_pop = bpf_map_lookup_elem(&sock_bytes, &four); 255 258 pop = bpf_map_lookup_elem(&sock_bytes, &five); 256 259 if (start_pop && pop) ··· 266 263 { 267 264 int zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5, key = 0; 268 265 int *bytes, *start, *end, *start_push, *end_push, *start_pop, *pop, *f; 266 + int err = 0; 269 267 __u64 flags = 0; 270 268 271 269 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero); ··· 283 279 284 280 start_push = bpf_map_lookup_elem(&sock_bytes, &two); 285 281 end_push = bpf_map_lookup_elem(&sock_bytes, &three); 286 - if (start_push && end_push) 287 - bpf_msg_push_data(msg, *start_push, *end_push, 0); 282 + if (start_push && end_push) { 283 + err = bpf_msg_push_data(msg, *start_push, *end_push, 0); 284 + if (err) 285 + return SK_DROP; 286 + } 288 287 289 288 start_pop = bpf_map_lookup_elem(&sock_bytes, &four); 290 289 pop = bpf_map_lookup_elem(&sock_bytes, &five); ··· 345 338 int bpf_prog10(struct sk_msg_md *msg) 346 339 { 347 340 int *bytes, *start, *end, *start_push, *end_push, *start_pop, *pop; 348 - int zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5; 341 + int zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5, err = 0; 349 342 350 343 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero); 351 344 if (bytes) ··· 359 352 bpf_msg_pull_data(msg, *start, *end, 0); 360 353 start_push = bpf_map_lookup_elem(&sock_bytes, &two); 361 354 end_push = bpf_map_lookup_elem(&sock_bytes, &three); 362 - if (start_push && end_push) 363 - bpf_msg_push_data(msg, *start_push, *end_push, 0); 355 + if (start_push && end_push) { 356 + err = bpf_msg_push_data(msg, *start_push, *end_push, 0); 357 + if (err) 358 + return SK_PASS; 359 + } 364 360 start_pop = bpf_map_lookup_elem(&sock_bytes, &four); 365 361 pop = bpf_map_lookup_elem(&sock_bytes, &five); 366 362 if (start_pop && pop)
+54
tools/testing/selftests/bpf/progs/timer_crash.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <vmlinux.h> 4 + #include <bpf/bpf_tracing.h> 5 + #include <bpf/bpf_helpers.h> 6 + 7 + struct map_elem { 8 + struct bpf_timer timer; 9 + struct bpf_spin_lock lock; 10 + }; 11 + 12 + struct { 13 + __uint(type, BPF_MAP_TYPE_ARRAY); 14 + __uint(max_entries, 1); 15 + __type(key, int); 16 + __type(value, struct map_elem); 17 + } amap SEC(".maps"); 18 + 19 + struct { 20 + __uint(type, BPF_MAP_TYPE_HASH); 21 + __uint(max_entries, 1); 22 + __type(key, int); 23 + __type(value, struct map_elem); 24 + } hmap SEC(".maps"); 25 + 26 + int pid = 0; 27 + int crash_map = 0; /* 0 for amap, 1 for hmap */ 28 + 29 + SEC("fentry/do_nanosleep") 30 + int sys_enter(void *ctx) 31 + { 32 + struct map_elem *e, value = {}; 33 + void *map = crash_map ? (void *)&hmap : (void *)&amap; 34 + 35 + if (bpf_get_current_task_btf()->tgid != pid) 36 + return 0; 37 + 38 + *(void **)&value = (void *)0xdeadcaf3; 39 + 40 + bpf_map_update_elem(map, &(int){0}, &value, 0); 41 + /* For array map, doing bpf_map_update_elem will do a 42 + * check_and_free_timer_in_array, which will trigger the crash if timer 43 + * pointer was overwritten, for hmap we need to use bpf_timer_cancel. 44 + */ 45 + if (crash_map == 1) { 46 + e = bpf_map_lookup_elem(map, &(int){0}); 47 + if (!e) 48 + return 0; 49 + bpf_timer_cancel(&e->timer); 50 + } 51 + return 0; 52 + } 53 + 54 + char _license[] SEC("license") = "GPL";