Merge tag 'parisc-for-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/delle...
[linux-2.6-microblaze.git] / kernel / bpf / task_iter.c
index fef1762..654601d 100644 (file)
@@ -290,11 +290,9 @@ again:
        rcu_read_lock();
        for (;; curr_fd++) {
                struct file *f;
-               f = task_lookup_next_fd_rcu(curr_task, &curr_fd);
+               f = task_lookup_next_fdget_rcu(curr_task, &curr_fd);
                if (!f)
                        break;
-               if (!get_file_rcu(f))
-                       continue;
 
                /* set info->fd */
                info->fd = curr_fd;
@@ -894,6 +892,157 @@ __bpf_kfunc void bpf_iter_task_vma_destroy(struct bpf_iter_task_vma *it)
 
 __diag_pop();
 
+struct bpf_iter_css_task {
+       __u64 __opaque[1];
+} __attribute__((aligned(8)));
+
+struct bpf_iter_css_task_kern {
+       struct css_task_iter *css_it;
+} __attribute__((aligned(8)));
+
+__diag_push();
+__diag_ignore_all("-Wmissing-prototypes",
+                 "Global functions as their definitions will be in vmlinux BTF");
+
+__bpf_kfunc int bpf_iter_css_task_new(struct bpf_iter_css_task *it,
+               struct cgroup_subsys_state *css, unsigned int flags)
+{
+       struct bpf_iter_css_task_kern *kit = (void *)it;
+
+       BUILD_BUG_ON(sizeof(struct bpf_iter_css_task_kern) != sizeof(struct bpf_iter_css_task));
+       BUILD_BUG_ON(__alignof__(struct bpf_iter_css_task_kern) !=
+                                       __alignof__(struct bpf_iter_css_task));
+       kit->css_it = NULL;
+       switch (flags) {
+       case CSS_TASK_ITER_PROCS | CSS_TASK_ITER_THREADED:
+       case CSS_TASK_ITER_PROCS:
+       case 0:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       kit->css_it = bpf_mem_alloc(&bpf_global_ma, sizeof(struct css_task_iter));
+       if (!kit->css_it)
+               return -ENOMEM;
+       css_task_iter_start(css, flags, kit->css_it);
+       return 0;
+}
+
+__bpf_kfunc struct task_struct *bpf_iter_css_task_next(struct bpf_iter_css_task *it)
+{
+       struct bpf_iter_css_task_kern *kit = (void *)it;
+
+       if (!kit->css_it)
+               return NULL;
+       return css_task_iter_next(kit->css_it);
+}
+
+__bpf_kfunc void bpf_iter_css_task_destroy(struct bpf_iter_css_task *it)
+{
+       struct bpf_iter_css_task_kern *kit = (void *)it;
+
+       if (!kit->css_it)
+               return;
+       css_task_iter_end(kit->css_it);
+       bpf_mem_free(&bpf_global_ma, kit->css_it);
+}
+
+__diag_pop();
+
+struct bpf_iter_task {
+       __u64 __opaque[3];
+} __attribute__((aligned(8)));
+
+struct bpf_iter_task_kern {
+       struct task_struct *task;
+       struct task_struct *pos;
+       unsigned int flags;
+} __attribute__((aligned(8)));
+
+enum {
+       /* all process in the system */
+       BPF_TASK_ITER_ALL_PROCS,
+       /* all threads in the system */
+       BPF_TASK_ITER_ALL_THREADS,
+       /* all threads of a specific process */
+       BPF_TASK_ITER_PROC_THREADS
+};
+
+__diag_push();
+__diag_ignore_all("-Wmissing-prototypes",
+                 "Global functions as their definitions will be in vmlinux BTF");
+
+__bpf_kfunc int bpf_iter_task_new(struct bpf_iter_task *it,
+               struct task_struct *task__nullable, unsigned int flags)
+{
+       struct bpf_iter_task_kern *kit = (void *)it;
+
+       BUILD_BUG_ON(sizeof(struct bpf_iter_task_kern) > sizeof(struct bpf_iter_task));
+       BUILD_BUG_ON(__alignof__(struct bpf_iter_task_kern) !=
+                                       __alignof__(struct bpf_iter_task));
+
+       kit->task = kit->pos = NULL;
+       switch (flags) {
+       case BPF_TASK_ITER_ALL_THREADS:
+       case BPF_TASK_ITER_ALL_PROCS:
+               break;
+       case BPF_TASK_ITER_PROC_THREADS:
+               if (!task__nullable)
+                       return -EINVAL;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (flags == BPF_TASK_ITER_PROC_THREADS)
+               kit->task = task__nullable;
+       else
+               kit->task = &init_task;
+       kit->pos = kit->task;
+       kit->flags = flags;
+       return 0;
+}
+
+__bpf_kfunc struct task_struct *bpf_iter_task_next(struct bpf_iter_task *it)
+{
+       struct bpf_iter_task_kern *kit = (void *)it;
+       struct task_struct *pos;
+       unsigned int flags;
+
+       flags = kit->flags;
+       pos = kit->pos;
+
+       if (!pos)
+               return pos;
+
+       if (flags == BPF_TASK_ITER_ALL_PROCS)
+               goto get_next_task;
+
+       kit->pos = next_thread(kit->pos);
+       if (kit->pos == kit->task) {
+               if (flags == BPF_TASK_ITER_PROC_THREADS) {
+                       kit->pos = NULL;
+                       return pos;
+               }
+       } else
+               return pos;
+
+get_next_task:
+       kit->pos = next_task(kit->pos);
+       kit->task = kit->pos;
+       if (kit->pos == &init_task)
+               kit->pos = NULL;
+
+       return pos;
+}
+
+__bpf_kfunc void bpf_iter_task_destroy(struct bpf_iter_task *it)
+{
+}
+
+__diag_pop();
+
 DEFINE_PER_CPU(struct mmap_unlock_irq_work, mmap_unlock_work);
 
 static void do_mmap_read_unlock(struct irq_work *entry)