diff options
Diffstat (limited to 'kernel/bpf/syscall.c')
| -rw-r--r-- | kernel/bpf/syscall.c | 44 | 
1 files changed, 33 insertions, 11 deletions
| diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index f45ed6adc092..bf6c5f685ea2 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -385,7 +385,7 @@ void bpf_map_free_id(struct bpf_map *map)  	spin_unlock_irqrestore(&map_idr_lock, flags);  } -#ifdef CONFIG_MEMCG_KMEM +#ifdef CONFIG_MEMCG  static void bpf_map_save_memcg(struct bpf_map *map)  {  	/* Currently if a map is created by a process belonging to the root @@ -486,7 +486,7 @@ int bpf_map_alloc_pages(const struct bpf_map *map, gfp_t gfp, int nid,  	unsigned long i, j;  	struct page *pg;  	int ret = 0; -#ifdef CONFIG_MEMCG_KMEM +#ifdef CONFIG_MEMCG  	struct mem_cgroup *memcg, *old_memcg;  	memcg = bpf_map_get_memcg(map); @@ -505,7 +505,7 @@ int bpf_map_alloc_pages(const struct bpf_map *map, gfp_t gfp, int nid,  		break;  	} -#ifdef CONFIG_MEMCG_KMEM +#ifdef CONFIG_MEMCG  	set_active_memcg(old_memcg);  	mem_cgroup_put(memcg);  #endif @@ -3151,6 +3151,13 @@ static void bpf_link_show_fdinfo(struct seq_file *m, struct file *filp)  }  #endif +static __poll_t bpf_link_poll(struct file *file, struct poll_table_struct *pts) +{ +	struct bpf_link *link = file->private_data; + +	return link->ops->poll(file, pts); +} +  static const struct file_operations bpf_link_fops = {  #ifdef CONFIG_PROC_FS  	.show_fdinfo	= bpf_link_show_fdinfo, @@ -3160,6 +3167,16 @@ static const struct file_operations bpf_link_fops = {  	.write		= bpf_dummy_write,  }; +static const struct file_operations bpf_link_fops_poll = { +#ifdef CONFIG_PROC_FS +	.show_fdinfo	= bpf_link_show_fdinfo, +#endif +	.release	= bpf_link_release, +	.read		= bpf_dummy_read, +	.write		= bpf_dummy_write, +	.poll		= bpf_link_poll, +}; +  static int bpf_link_alloc_id(struct bpf_link *link)  {  	int id; @@ -3202,7 +3219,9 @@ int bpf_link_prime(struct bpf_link *link, struct bpf_link_primer *primer)  		return id;  	} -	file = anon_inode_getfile("bpf_link", &bpf_link_fops, link, O_CLOEXEC); +	file = anon_inode_getfile("bpf_link", +				  link->ops->poll ? &bpf_link_fops_poll : &bpf_link_fops, +				  link, O_CLOEXEC);  	if (IS_ERR(file)) {  		bpf_link_free_id(id);  		put_unused_fd(fd); @@ -3230,7 +3249,9 @@ int bpf_link_settle(struct bpf_link_primer *primer)  int bpf_link_new_fd(struct bpf_link *link)  { -	return anon_inode_getfd("bpf-link", &bpf_link_fops, link, O_CLOEXEC); +	return anon_inode_getfd("bpf-link", +				link->ops->poll ? &bpf_link_fops_poll : &bpf_link_fops, +				link, O_CLOEXEC);  }  struct bpf_link *bpf_link_get_from_fd(u32 ufd) @@ -3240,7 +3261,7 @@ struct bpf_link *bpf_link_get_from_fd(u32 ufd)  	if (!f.file)  		return ERR_PTR(-EBADF); -	if (f.file->f_op != &bpf_link_fops) { +	if (f.file->f_op != &bpf_link_fops && f.file->f_op != &bpf_link_fops_poll) {  		fdput(f);  		return ERR_PTR(-EINVAL);  	} @@ -4972,7 +4993,7 @@ static int bpf_obj_get_info_by_fd(const union bpf_attr *attr,  					     uattr);  	else if (f.file->f_op == &btf_fops)  		err = bpf_btf_get_info_by_fd(f.file, f.file->private_data, attr, uattr); -	else if (f.file->f_op == &bpf_link_fops) +	else if (f.file->f_op == &bpf_link_fops || f.file->f_op == &bpf_link_fops_poll)  		err = bpf_link_get_info_by_fd(f.file, f.file->private_data,  					      attr, uattr);  	else @@ -5107,7 +5128,7 @@ static int bpf_task_fd_query(const union bpf_attr *attr,  	if (!file)  		return -EBADF; -	if (file->f_op == &bpf_link_fops) { +	if (file->f_op == &bpf_link_fops || file->f_op == &bpf_link_fops_poll) {  		struct bpf_link *link = file->private_data;  		if (link->ops == &bpf_raw_tp_link_lops) { @@ -5417,10 +5438,11 @@ static int link_detach(union bpf_attr *attr)  	return ret;  } -static struct bpf_link *bpf_link_inc_not_zero(struct bpf_link *link) +struct bpf_link *bpf_link_inc_not_zero(struct bpf_link *link)  {  	return atomic64_fetch_add_unless(&link->refcnt, 1, 0) ? link : ERR_PTR(-ENOENT);  } +EXPORT_SYMBOL(bpf_link_inc_not_zero);  struct bpf_link *bpf_link_by_id(u32 id)  { @@ -5961,7 +5983,7 @@ const struct bpf_prog_ops bpf_syscall_prog_ops = {  };  #ifdef CONFIG_SYSCTL -static int bpf_stats_handler(struct ctl_table *table, int write, +static int bpf_stats_handler(const struct ctl_table *table, int write,  			     void *buffer, size_t *lenp, loff_t *ppos)  {  	struct static_key *key = (struct static_key *)table->data; @@ -5996,7 +6018,7 @@ void __weak unpriv_ebpf_notify(int new_state)  {  } -static int bpf_unpriv_handler(struct ctl_table *table, int write, +static int bpf_unpriv_handler(const struct ctl_table *table, int write,  			      void *buffer, size_t *lenp, loff_t *ppos)  {  	int ret, unpriv_enable = *(int *)table->data; |