1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (c) 2020 Facebook */ 3 4 #include <linux/init.h> 5 #include <linux/namei.h> 6 #include <linux/pid_namespace.h> 7 #include <linux/fs.h> 8 #include <linux/fdtable.h> 9 #include <linux/filter.h> 10 #include <linux/btf_ids.h> 11 #include "mmap_unlock_work.h" 12 13 struct bpf_iter_seq_task_common { 14 struct pid_namespace *ns; 15 enum bpf_iter_task_type type; 16 u32 pid; 17 u32 pid_visiting; 18 }; 19 20 struct bpf_iter_seq_task_info { 21 /* The first field must be struct bpf_iter_seq_task_common. 22 * this is assumed by {init, fini}_seq_pidns() callback functions. 23 */ 24 struct bpf_iter_seq_task_common common; 25 u32 tid; 26 }; 27 28 static struct task_struct *task_group_seq_get_next(struct bpf_iter_seq_task_common *common, 29 u32 *tid, 30 bool skip_if_dup_files) 31 { 32 struct task_struct *task, *next_task; 33 struct pid *pid; 34 u32 saved_tid; 35 36 if (!*tid) { 37 /* The first time, the iterator calls this function. */ 38 pid = find_pid_ns(common->pid, common->ns); 39 if (!pid) 40 return NULL; 41 42 task = get_pid_task(pid, PIDTYPE_TGID); 43 if (!task) 44 return NULL; 45 46 *tid = common->pid; 47 common->pid_visiting = common->pid; 48 49 return task; 50 } 51 52 /* If the control returns to user space and comes back to the 53 * kernel again, *tid and common->pid_visiting should be the 54 * same for task_seq_start() to pick up the correct task. 55 */ 56 if (*tid == common->pid_visiting) { 57 pid = find_pid_ns(common->pid_visiting, common->ns); 58 task = get_pid_task(pid, PIDTYPE_PID); 59 60 return task; 61 } 62 63 pid = find_pid_ns(common->pid_visiting, common->ns); 64 if (!pid) 65 return NULL; 66 67 task = get_pid_task(pid, PIDTYPE_PID); 68 if (!task) 69 return NULL; 70 71 retry: 72 if (!pid_alive(task)) { 73 put_task_struct(task); 74 return NULL; 75 } 76 77 next_task = next_thread(task); 78 put_task_struct(task); 79 if (!next_task) 80 return NULL; 81 82 saved_tid = *tid; 83 *tid = __task_pid_nr_ns(next_task, PIDTYPE_PID, common->ns); 84 if (!*tid || *tid == common->pid) { 85 /* Run out of tasks of a process. The tasks of a 86 * thread_group are linked as circular linked list. 87 */ 88 *tid = saved_tid; 89 return NULL; 90 } 91 92 get_task_struct(next_task); 93 common->pid_visiting = *tid; 94 95 if (skip_if_dup_files && task->files == task->group_leader->files) { 96 task = next_task; 97 goto retry; 98 } 99 100 return next_task; 101 } 102 103 static struct task_struct *task_seq_get_next(struct bpf_iter_seq_task_common *common, 104 u32 *tid, 105 bool skip_if_dup_files) 106 { 107 struct task_struct *task = NULL; 108 struct pid *pid; 109 110 if (common->type == BPF_TASK_ITER_TID) { 111 if (*tid && *tid != common->pid) 112 return NULL; 113 rcu_read_lock(); 114 pid = find_pid_ns(common->pid, common->ns); 115 if (pid) { 116 task = get_pid_task(pid, PIDTYPE_TGID); 117 *tid = common->pid; 118 } 119 rcu_read_unlock(); 120 121 return task; 122 } 123 124 if (common->type == BPF_TASK_ITER_TGID) { 125 rcu_read_lock(); 126 task = task_group_seq_get_next(common, tid, skip_if_dup_files); 127 rcu_read_unlock(); 128 129 return task; 130 } 131 132 rcu_read_lock(); 133 retry: 134 pid = find_ge_pid(*tid, common->ns); 135 if (pid) { 136 *tid = pid_nr_ns(pid, common->ns); 137 task = get_pid_task(pid, PIDTYPE_PID); 138 if (!task) { 139 ++*tid; 140 goto retry; 141 } else if (skip_if_dup_files && !thread_group_leader(task) && 142 task->files == task->group_leader->files) { 143 put_task_struct(task); 144 task = NULL; 145 ++*tid; 146 goto retry; 147 } 148 } 149 rcu_read_unlock(); 150 151 return task; 152 } 153 154 static void *task_seq_start(struct seq_file *seq, loff_t *pos) 155 { 156 struct bpf_iter_seq_task_info *info = seq->private; 157 struct task_struct *task; 158 159 task = task_seq_get_next(&info->common, &info->tid, false); 160 if (!task) 161 return NULL; 162 163 if (*pos == 0) 164 ++*pos; 165 return task; 166 } 167 168 static void *task_seq_next(struct seq_file *seq, void *v, loff_t *pos) 169 { 170 struct bpf_iter_seq_task_info *info = seq->private; 171 struct task_struct *task; 172 173 ++*pos; 174 ++info->tid; 175 put_task_struct((struct task_struct *)v); 176 task = task_seq_get_next(&info->common, &info->tid, false); 177 if (!task) 178 return NULL; 179 180 return task; 181 } 182 183 struct bpf_iter__task { 184 __bpf_md_ptr(struct bpf_iter_meta *, meta); 185 __bpf_md_ptr(struct task_struct *, task); 186 }; 187 188 DEFINE_BPF_ITER_FUNC(task, struct bpf_iter_meta *meta, struct task_struct *task) 189 190 static int __task_seq_show(struct seq_file *seq, struct task_struct *task, 191 bool in_stop) 192 { 193 struct bpf_iter_meta meta; 194 struct bpf_iter__task ctx; 195 struct bpf_prog *prog; 196 197 meta.seq = seq; 198 prog = bpf_iter_get_info(&meta, in_stop); 199 if (!prog) 200 return 0; 201 202 ctx.meta = &meta; 203 ctx.task = task; 204 return bpf_iter_run_prog(prog, &ctx); 205 } 206 207 static int task_seq_show(struct seq_file *seq, void *v) 208 { 209 return __task_seq_show(seq, v, false); 210 } 211 212 static void task_seq_stop(struct seq_file *seq, void *v) 213 { 214 if (!v) 215 (void)__task_seq_show(seq, v, true); 216 else 217 put_task_struct((struct task_struct *)v); 218 } 219 220 static int bpf_iter_attach_task(struct bpf_prog *prog, 221 union bpf_iter_link_info *linfo, 222 struct bpf_iter_aux_info *aux) 223 { 224 unsigned int flags; 225 struct pid *pid; 226 pid_t tgid; 227 228 if ((!!linfo->task.tid + !!linfo->task.pid + !!linfo->task.pid_fd) > 1) 229 return -EINVAL; 230 231 aux->task.type = BPF_TASK_ITER_ALL; 232 if (linfo->task.tid != 0) { 233 aux->task.type = BPF_TASK_ITER_TID; 234 aux->task.pid = linfo->task.tid; 235 } 236 if (linfo->task.pid != 0) { 237 aux->task.type = BPF_TASK_ITER_TGID; 238 aux->task.pid = linfo->task.pid; 239 } 240 if (linfo->task.pid_fd != 0) { 241 aux->task.type = BPF_TASK_ITER_TGID; 242 243 pid = pidfd_get_pid(linfo->task.pid_fd, &flags); 244 if (IS_ERR(pid)) 245 return PTR_ERR(pid); 246 247 tgid = pid_nr_ns(pid, task_active_pid_ns(current)); 248 aux->task.pid = tgid; 249 put_pid(pid); 250 } 251 252 return 0; 253 } 254 255 static const struct seq_operations task_seq_ops = { 256 .start = task_seq_start, 257 .next = task_seq_next, 258 .stop = task_seq_stop, 259 .show = task_seq_show, 260 }; 261 262 struct bpf_iter_seq_task_file_info { 263 /* The first field must be struct bpf_iter_seq_task_common. 264 * this is assumed by {init, fini}_seq_pidns() callback functions. 265 */ 266 struct bpf_iter_seq_task_common common; 267 struct task_struct *task; 268 u32 tid; 269 u32 fd; 270 }; 271 272 static struct file * 273 task_file_seq_get_next(struct bpf_iter_seq_task_file_info *info) 274 { 275 u32 saved_tid = info->tid; 276 struct task_struct *curr_task; 277 unsigned int curr_fd = info->fd; 278 279 /* If this function returns a non-NULL file object, 280 * it held a reference to the task/file. 281 * Otherwise, it does not hold any reference. 282 */ 283 again: 284 if (info->task) { 285 curr_task = info->task; 286 curr_fd = info->fd; 287 } else { 288 curr_task = task_seq_get_next(&info->common, &info->tid, true); 289 if (!curr_task) { 290 info->task = NULL; 291 return NULL; 292 } 293 294 /* set info->task */ 295 info->task = curr_task; 296 if (saved_tid == info->tid) 297 curr_fd = info->fd; 298 else 299 curr_fd = 0; 300 } 301 302 rcu_read_lock(); 303 for (;; curr_fd++) { 304 struct file *f; 305 f = task_lookup_next_fd_rcu(curr_task, &curr_fd); 306 if (!f) 307 break; 308 if (!get_file_rcu(f)) 309 continue; 310 311 /* set info->fd */ 312 info->fd = curr_fd; 313 rcu_read_unlock(); 314 return f; 315 } 316 317 /* the current task is done, go to the next task */ 318 rcu_read_unlock(); 319 put_task_struct(curr_task); 320 321 if (info->common.type == BPF_TASK_ITER_TID) { 322 info->task = NULL; 323 return NULL; 324 } 325 326 info->task = NULL; 327 info->fd = 0; 328 saved_tid = ++(info->tid); 329 goto again; 330 } 331 332 static void *task_file_seq_start(struct seq_file *seq, loff_t *pos) 333 { 334 struct bpf_iter_seq_task_file_info *info = seq->private; 335 struct file *file; 336 337 info->task = NULL; 338 file = task_file_seq_get_next(info); 339 if (file && *pos == 0) 340 ++*pos; 341 342 return file; 343 } 344 345 static void *task_file_seq_next(struct seq_file *seq, void *v, loff_t *pos) 346 { 347 struct bpf_iter_seq_task_file_info *info = seq->private; 348 349 ++*pos; 350 ++info->fd; 351 fput((struct file *)v); 352 return task_file_seq_get_next(info); 353 } 354 355 struct bpf_iter__task_file { 356 __bpf_md_ptr(struct bpf_iter_meta *, meta); 357 __bpf_md_ptr(struct task_struct *, task); 358 u32 fd __aligned(8); 359 __bpf_md_ptr(struct file *, file); 360 }; 361 362 DEFINE_BPF_ITER_FUNC(task_file, struct bpf_iter_meta *meta, 363 struct task_struct *task, u32 fd, 364 struct file *file) 365 366 static int __task_file_seq_show(struct seq_file *seq, struct file *file, 367 bool in_stop) 368 { 369 struct bpf_iter_seq_task_file_info *info = seq->private; 370 struct bpf_iter__task_file ctx; 371 struct bpf_iter_meta meta; 372 struct bpf_prog *prog; 373 374 meta.seq = seq; 375 prog = bpf_iter_get_info(&meta, in_stop); 376 if (!prog) 377 return 0; 378 379 ctx.meta = &meta; 380 ctx.task = info->task; 381 ctx.fd = info->fd; 382 ctx.file = file; 383 return bpf_iter_run_prog(prog, &ctx); 384 } 385 386 static int task_file_seq_show(struct seq_file *seq, void *v) 387 { 388 return __task_file_seq_show(seq, v, false); 389 } 390 391 static void task_file_seq_stop(struct seq_file *seq, void *v) 392 { 393 struct bpf_iter_seq_task_file_info *info = seq->private; 394 395 if (!v) { 396 (void)__task_file_seq_show(seq, v, true); 397 } else { 398 fput((struct file *)v); 399 put_task_struct(info->task); 400 info->task = NULL; 401 } 402 } 403 404 static int init_seq_pidns(void *priv_data, struct bpf_iter_aux_info *aux) 405 { 406 struct bpf_iter_seq_task_common *common = priv_data; 407 408 common->ns = get_pid_ns(task_active_pid_ns(current)); 409 common->type = aux->task.type; 410 common->pid = aux->task.pid; 411 412 return 0; 413 } 414 415 static void fini_seq_pidns(void *priv_data) 416 { 417 struct bpf_iter_seq_task_common *common = priv_data; 418 419 put_pid_ns(common->ns); 420 } 421 422 static const struct seq_operations task_file_seq_ops = { 423 .start = task_file_seq_start, 424 .next = task_file_seq_next, 425 .stop = task_file_seq_stop, 426 .show = task_file_seq_show, 427 }; 428 429 struct bpf_iter_seq_task_vma_info { 430 /* The first field must be struct bpf_iter_seq_task_common. 431 * this is assumed by {init, fini}_seq_pidns() callback functions. 432 */ 433 struct bpf_iter_seq_task_common common; 434 struct task_struct *task; 435 struct vm_area_struct *vma; 436 u32 tid; 437 unsigned long prev_vm_start; 438 unsigned long prev_vm_end; 439 }; 440 441 enum bpf_task_vma_iter_find_op { 442 task_vma_iter_first_vma, /* use mm->mmap */ 443 task_vma_iter_next_vma, /* use curr_vma->vm_next */ 444 task_vma_iter_find_vma, /* use find_vma() to find next vma */ 445 }; 446 447 static struct vm_area_struct * 448 task_vma_seq_get_next(struct bpf_iter_seq_task_vma_info *info) 449 { 450 enum bpf_task_vma_iter_find_op op; 451 struct vm_area_struct *curr_vma; 452 struct task_struct *curr_task; 453 u32 saved_tid = info->tid; 454 455 /* If this function returns a non-NULL vma, it holds a reference to 456 * the task_struct, and holds read lock on vma->mm->mmap_lock. 457 * If this function returns NULL, it does not hold any reference or 458 * lock. 459 */ 460 if (info->task) { 461 curr_task = info->task; 462 curr_vma = info->vma; 463 /* In case of lock contention, drop mmap_lock to unblock 464 * the writer. 465 * 466 * After relock, call find(mm, prev_vm_end - 1) to find 467 * new vma to process. 468 * 469 * +------+------+-----------+ 470 * | VMA1 | VMA2 | VMA3 | 471 * +------+------+-----------+ 472 * | | | | 473 * 4k 8k 16k 400k 474 * 475 * For example, curr_vma == VMA2. Before unlock, we set 476 * 477 * prev_vm_start = 8k 478 * prev_vm_end = 16k 479 * 480 * There are a few cases: 481 * 482 * 1) VMA2 is freed, but VMA3 exists. 483 * 484 * find_vma() will return VMA3, just process VMA3. 485 * 486 * 2) VMA2 still exists. 487 * 488 * find_vma() will return VMA2, process VMA2->next. 489 * 490 * 3) no more vma in this mm. 491 * 492 * Process the next task. 493 * 494 * 4) find_vma() returns a different vma, VMA2'. 495 * 496 * 4.1) If VMA2 covers same range as VMA2', skip VMA2', 497 * because we already covered the range; 498 * 4.2) VMA2 and VMA2' covers different ranges, process 499 * VMA2'. 500 */ 501 if (mmap_lock_is_contended(curr_task->mm)) { 502 info->prev_vm_start = curr_vma->vm_start; 503 info->prev_vm_end = curr_vma->vm_end; 504 op = task_vma_iter_find_vma; 505 mmap_read_unlock(curr_task->mm); 506 if (mmap_read_lock_killable(curr_task->mm)) 507 goto finish; 508 } else { 509 op = task_vma_iter_next_vma; 510 } 511 } else { 512 again: 513 curr_task = task_seq_get_next(&info->common, &info->tid, true); 514 if (!curr_task) { 515 info->tid++; 516 goto finish; 517 } 518 519 if (saved_tid != info->tid) { 520 /* new task, process the first vma */ 521 op = task_vma_iter_first_vma; 522 } else { 523 /* Found the same tid, which means the user space 524 * finished data in previous buffer and read more. 525 * We dropped mmap_lock before returning to user 526 * space, so it is necessary to use find_vma() to 527 * find the next vma to process. 528 */ 529 op = task_vma_iter_find_vma; 530 } 531 532 if (!curr_task->mm) 533 goto next_task; 534 535 if (mmap_read_lock_killable(curr_task->mm)) 536 goto finish; 537 } 538 539 switch (op) { 540 case task_vma_iter_first_vma: 541 curr_vma = curr_task->mm->mmap; 542 break; 543 case task_vma_iter_next_vma: 544 curr_vma = curr_vma->vm_next; 545 break; 546 case task_vma_iter_find_vma: 547 /* We dropped mmap_lock so it is necessary to use find_vma 548 * to find the next vma. This is similar to the mechanism 549 * in show_smaps_rollup(). 550 */ 551 curr_vma = find_vma(curr_task->mm, info->prev_vm_end - 1); 552 /* case 1) and 4.2) above just use curr_vma */ 553 554 /* check for case 2) or case 4.1) above */ 555 if (curr_vma && 556 curr_vma->vm_start == info->prev_vm_start && 557 curr_vma->vm_end == info->prev_vm_end) 558 curr_vma = curr_vma->vm_next; 559 break; 560 } 561 if (!curr_vma) { 562 /* case 3) above, or case 2) 4.1) with vma->next == NULL */ 563 mmap_read_unlock(curr_task->mm); 564 goto next_task; 565 } 566 info->task = curr_task; 567 info->vma = curr_vma; 568 return curr_vma; 569 570 next_task: 571 if (info->common.type == BPF_TASK_ITER_TID) 572 goto finish; 573 574 put_task_struct(curr_task); 575 info->task = NULL; 576 info->tid++; 577 goto again; 578 579 finish: 580 if (curr_task) 581 put_task_struct(curr_task); 582 info->task = NULL; 583 info->vma = NULL; 584 return NULL; 585 } 586 587 static void *task_vma_seq_start(struct seq_file *seq, loff_t *pos) 588 { 589 struct bpf_iter_seq_task_vma_info *info = seq->private; 590 struct vm_area_struct *vma; 591 592 vma = task_vma_seq_get_next(info); 593 if (vma && *pos == 0) 594 ++*pos; 595 596 return vma; 597 } 598 599 static void *task_vma_seq_next(struct seq_file *seq, void *v, loff_t *pos) 600 { 601 struct bpf_iter_seq_task_vma_info *info = seq->private; 602 603 ++*pos; 604 return task_vma_seq_get_next(info); 605 } 606 607 struct bpf_iter__task_vma { 608 __bpf_md_ptr(struct bpf_iter_meta *, meta); 609 __bpf_md_ptr(struct task_struct *, task); 610 __bpf_md_ptr(struct vm_area_struct *, vma); 611 }; 612 613 DEFINE_BPF_ITER_FUNC(task_vma, struct bpf_iter_meta *meta, 614 struct task_struct *task, struct vm_area_struct *vma) 615 616 static int __task_vma_seq_show(struct seq_file *seq, bool in_stop) 617 { 618 struct bpf_iter_seq_task_vma_info *info = seq->private; 619 struct bpf_iter__task_vma ctx; 620 struct bpf_iter_meta meta; 621 struct bpf_prog *prog; 622 623 meta.seq = seq; 624 prog = bpf_iter_get_info(&meta, in_stop); 625 if (!prog) 626 return 0; 627 628 ctx.meta = &meta; 629 ctx.task = info->task; 630 ctx.vma = info->vma; 631 return bpf_iter_run_prog(prog, &ctx); 632 } 633 634 static int task_vma_seq_show(struct seq_file *seq, void *v) 635 { 636 return __task_vma_seq_show(seq, false); 637 } 638 639 static void task_vma_seq_stop(struct seq_file *seq, void *v) 640 { 641 struct bpf_iter_seq_task_vma_info *info = seq->private; 642 643 if (!v) { 644 (void)__task_vma_seq_show(seq, true); 645 } else { 646 /* info->vma has not been seen by the BPF program. If the 647 * user space reads more, task_vma_seq_get_next should 648 * return this vma again. Set prev_vm_start to ~0UL, 649 * so that we don't skip the vma returned by the next 650 * find_vma() (case task_vma_iter_find_vma in 651 * task_vma_seq_get_next()). 652 */ 653 info->prev_vm_start = ~0UL; 654 info->prev_vm_end = info->vma->vm_end; 655 mmap_read_unlock(info->task->mm); 656 put_task_struct(info->task); 657 info->task = NULL; 658 } 659 } 660 661 static const struct seq_operations task_vma_seq_ops = { 662 .start = task_vma_seq_start, 663 .next = task_vma_seq_next, 664 .stop = task_vma_seq_stop, 665 .show = task_vma_seq_show, 666 }; 667 668 static const struct bpf_iter_seq_info task_seq_info = { 669 .seq_ops = &task_seq_ops, 670 .init_seq_private = init_seq_pidns, 671 .fini_seq_private = fini_seq_pidns, 672 .seq_priv_size = sizeof(struct bpf_iter_seq_task_info), 673 }; 674 675 static struct bpf_iter_reg task_reg_info = { 676 .target = "task", 677 .attach_target = bpf_iter_attach_task, 678 .feature = BPF_ITER_RESCHED, 679 .ctx_arg_info_size = 1, 680 .ctx_arg_info = { 681 { offsetof(struct bpf_iter__task, task), 682 PTR_TO_BTF_ID_OR_NULL }, 683 }, 684 .seq_info = &task_seq_info, 685 }; 686 687 static const struct bpf_iter_seq_info task_file_seq_info = { 688 .seq_ops = &task_file_seq_ops, 689 .init_seq_private = init_seq_pidns, 690 .fini_seq_private = fini_seq_pidns, 691 .seq_priv_size = sizeof(struct bpf_iter_seq_task_file_info), 692 }; 693 694 static struct bpf_iter_reg task_file_reg_info = { 695 .target = "task_file", 696 .attach_target = bpf_iter_attach_task, 697 .feature = BPF_ITER_RESCHED, 698 .ctx_arg_info_size = 2, 699 .ctx_arg_info = { 700 { offsetof(struct bpf_iter__task_file, task), 701 PTR_TO_BTF_ID_OR_NULL }, 702 { offsetof(struct bpf_iter__task_file, file), 703 PTR_TO_BTF_ID_OR_NULL }, 704 }, 705 .seq_info = &task_file_seq_info, 706 }; 707 708 static const struct bpf_iter_seq_info task_vma_seq_info = { 709 .seq_ops = &task_vma_seq_ops, 710 .init_seq_private = init_seq_pidns, 711 .fini_seq_private = fini_seq_pidns, 712 .seq_priv_size = sizeof(struct bpf_iter_seq_task_vma_info), 713 }; 714 715 static struct bpf_iter_reg task_vma_reg_info = { 716 .target = "task_vma", 717 .attach_target = bpf_iter_attach_task, 718 .feature = BPF_ITER_RESCHED, 719 .ctx_arg_info_size = 2, 720 .ctx_arg_info = { 721 { offsetof(struct bpf_iter__task_vma, task), 722 PTR_TO_BTF_ID_OR_NULL }, 723 { offsetof(struct bpf_iter__task_vma, vma), 724 PTR_TO_BTF_ID_OR_NULL }, 725 }, 726 .seq_info = &task_vma_seq_info, 727 }; 728 729 BPF_CALL_5(bpf_find_vma, struct task_struct *, task, u64, start, 730 bpf_callback_t, callback_fn, void *, callback_ctx, u64, flags) 731 { 732 struct mmap_unlock_irq_work *work = NULL; 733 struct vm_area_struct *vma; 734 bool irq_work_busy = false; 735 struct mm_struct *mm; 736 int ret = -ENOENT; 737 738 if (flags) 739 return -EINVAL; 740 741 if (!task) 742 return -ENOENT; 743 744 mm = task->mm; 745 if (!mm) 746 return -ENOENT; 747 748 irq_work_busy = bpf_mmap_unlock_get_irq_work(&work); 749 750 if (irq_work_busy || !mmap_read_trylock(mm)) 751 return -EBUSY; 752 753 vma = find_vma(mm, start); 754 755 if (vma && vma->vm_start <= start && vma->vm_end > start) { 756 callback_fn((u64)(long)task, (u64)(long)vma, 757 (u64)(long)callback_ctx, 0, 0); 758 ret = 0; 759 } 760 bpf_mmap_unlock_mm(work, mm); 761 return ret; 762 } 763 764 const struct bpf_func_proto bpf_find_vma_proto = { 765 .func = bpf_find_vma, 766 .ret_type = RET_INTEGER, 767 .arg1_type = ARG_PTR_TO_BTF_ID, 768 .arg1_btf_id = &btf_tracing_ids[BTF_TRACING_TYPE_TASK], 769 .arg2_type = ARG_ANYTHING, 770 .arg3_type = ARG_PTR_TO_FUNC, 771 .arg4_type = ARG_PTR_TO_STACK_OR_NULL, 772 .arg5_type = ARG_ANYTHING, 773 }; 774 775 DEFINE_PER_CPU(struct mmap_unlock_irq_work, mmap_unlock_work); 776 777 static void do_mmap_read_unlock(struct irq_work *entry) 778 { 779 struct mmap_unlock_irq_work *work; 780 781 if (WARN_ON_ONCE(IS_ENABLED(CONFIG_PREEMPT_RT))) 782 return; 783 784 work = container_of(entry, struct mmap_unlock_irq_work, irq_work); 785 mmap_read_unlock_non_owner(work->mm); 786 } 787 788 static int __init task_iter_init(void) 789 { 790 struct mmap_unlock_irq_work *work; 791 int ret, cpu; 792 793 for_each_possible_cpu(cpu) { 794 work = per_cpu_ptr(&mmap_unlock_work, cpu); 795 init_irq_work(&work->irq_work, do_mmap_read_unlock); 796 } 797 798 task_reg_info.ctx_arg_info[0].btf_id = btf_tracing_ids[BTF_TRACING_TYPE_TASK]; 799 ret = bpf_iter_reg_target(&task_reg_info); 800 if (ret) 801 return ret; 802 803 task_file_reg_info.ctx_arg_info[0].btf_id = btf_tracing_ids[BTF_TRACING_TYPE_TASK]; 804 task_file_reg_info.ctx_arg_info[1].btf_id = btf_tracing_ids[BTF_TRACING_TYPE_FILE]; 805 ret = bpf_iter_reg_target(&task_file_reg_info); 806 if (ret) 807 return ret; 808 809 task_vma_reg_info.ctx_arg_info[0].btf_id = btf_tracing_ids[BTF_TRACING_TYPE_TASK]; 810 task_vma_reg_info.ctx_arg_info[1].btf_id = btf_tracing_ids[BTF_TRACING_TYPE_VMA]; 811 return bpf_iter_reg_target(&task_vma_reg_info); 812 } 813 late_initcall(task_iter_init); 814