Re: [PATCH v1 2/4] media: bpf: allow raw IR decoder bpf programs to be used

2018-05-14 Thread Y Song
On Mon, May 14, 2018 at 2:10 PM, Sean Young  wrote:
> This implements attaching, detaching, querying and execution. The target
> fd has to be the /dev/lircN device.
>
> Signed-off-by: Sean Young 
> ---
>  drivers/media/rc/ir-bpf-decoder.c | 191 ++
>  drivers/media/rc/lirc_dev.c   |  30 +
>  drivers/media/rc/rc-core-priv.h   |  15 +++
>  drivers/media/rc/rc-ir-raw.c  |   5 +
>  include/uapi/linux/bpf.h  |   1 +
>  kernel/bpf/syscall.c  |   7 ++
>  6 files changed, 249 insertions(+)
>
> diff --git a/drivers/media/rc/ir-bpf-decoder.c 
> b/drivers/media/rc/ir-bpf-decoder.c
> index aaa5e208b1a5..651590a14772 100644
> --- a/drivers/media/rc/ir-bpf-decoder.c
> +++ b/drivers/media/rc/ir-bpf-decoder.c
> @@ -91,3 +91,194 @@ const struct bpf_verifier_ops ir_decoder_verifier_ops = {
> .get_func_proto  = ir_decoder_func_proto,
> .is_valid_access = ir_decoder_is_valid_access
>  };
> +
> +#define BPF_MAX_PROGS 64
> +
> +int rc_dev_bpf_attach(struct rc_dev *rcdev, struct bpf_prog *prog, u32 flags)

flags is not used in this function.

> +{
> +   struct ir_raw_event_ctrl *raw;
> +   struct bpf_prog_array __rcu *old_array;
> +   struct bpf_prog_array *new_array;
> +   int ret;
> +
> +   if (rcdev->driver_type != RC_DRIVER_IR_RAW)
> +   return -EINVAL;
> +
> +   ret = mutex_lock_interruptible(>lock);
> +   if (ret)
> +   return ret;
> +
> +   raw = rcdev->raw;
> +
> +   if (raw->progs && bpf_prog_array_length(raw->progs) >= BPF_MAX_PROGS) 
> {
> +   ret = -E2BIG;
> +   goto out;
> +   }
> +
> +   old_array = raw->progs;
> +   ret = bpf_prog_array_copy(old_array, NULL, prog, _array);
> +   if (ret < 0)
> +   goto out;
> +
> +   rcu_assign_pointer(raw->progs, new_array);
> +   bpf_prog_array_free(old_array);
> +out:
> +   mutex_unlock(>lock);
> +   return ret;
> +}
> +
> +int rc_dev_bpf_detach(struct rc_dev *rcdev, struct bpf_prog *prog, u32 flags)

flags is not used in this function.

> +{
> +   struct ir_raw_event_ctrl *raw;
> +   struct bpf_prog_array __rcu *old_array;
> +   struct bpf_prog_array *new_array;
> +   int ret;
> +
> +   if (rcdev->driver_type != RC_DRIVER_IR_RAW)
> +   return -EINVAL;
> +
> +   ret = mutex_lock_interruptible(>lock);
> +   if (ret)
> +   return ret;
> +
> +   raw = rcdev->raw;
> +
> +   old_array = raw->progs;
> +   ret = bpf_prog_array_copy(old_array, prog, NULL, _array);
> +   if (ret < 0) {
> +   bpf_prog_array_delete_safe(old_array, prog);
> +   } else {
> +   rcu_assign_pointer(raw->progs, new_array);
> +   bpf_prog_array_free(old_array);
> +   }
> +
> +   bpf_prog_put(prog);
> +   mutex_unlock(>lock);
> +   return 0;
> +}
> +
> +void rc_dev_bpf_run(struct rc_dev *rcdev)
> +{
> +   struct ir_raw_event_ctrl *raw = rcdev->raw;
> +
> +   if (raw->progs)
> +   BPF_PROG_RUN_ARRAY(raw->progs, >prev_ev, BPF_PROG_RUN);
> +}
> +
> +void rc_dev_bpf_put(struct rc_dev *rcdev)
> +{
> +   struct bpf_prog_array *progs = rcdev->raw->progs;
> +   int i, size;
> +
> +   if (!progs)
> +   return;
> +
> +   size = bpf_prog_array_length(progs);
> +   for (i = 0; i < size; i++)
> +   bpf_prog_put(progs->progs[i]);
> +
> +   bpf_prog_array_free(rcdev->raw->progs);
> +}
> +
> +int rc_dev_prog_attach(const union bpf_attr *attr)
> +{
> +   struct bpf_prog *prog;
> +   struct rc_dev *rcdev;
> +   int ret;
> +
> +   if (attr->attach_flags & BPF_F_ALLOW_OVERRIDE)
> +   return -EINVAL;

Looks like you really did not use flags except here.
BPF_F_ALLOW_OVERRIDE is originally used for
cgroup type of attachment and the comment explicits
saying so.

In the query below, the flags value "0" is copied to userspace.

In your case, I think you can just disallow any value, i.g.,
attr->attach_flags must be 0, and then you further down
check that if the prog is already in the array, you just return an error.

> +
> +   prog = bpf_prog_get_type(attr->attach_bpf_fd,
> +BPF_PROG_TYPE_RAWIR_DECODER);
> +   if (IS_ERR(prog))
> +   return PTR_ERR(prog);
> +
> +   rcdev = rc_dev_get_from_fd(attr->target_fd);
> +   if (IS_ERR(rcdev)) {
> +   bpf_prog_put(prog);
> +   return PTR_ERR(rcdev);
> +   }
> +
> +   ret = rc_dev_bpf_attach(rcdev, prog, attr->attach_flags);
> +   if (ret)
> +   bpf_prog_put(prog);
> +
> +   put_device(>dev);
> +
> +   return ret;
> +}
> +
> +int rc_dev_prog_detach(const union bpf_attr *attr)
> +{
> +   struct bpf_prog *prog;
> +   struct rc_dev *rcdev;
> +   int ret;
> +
> +   if (attr->attach_flags & BPF_F_ALLOW_OVERRIDE)
> +   

Re: [PATCH v1 2/4] media: bpf: allow raw IR decoder bpf programs to be used

2018-05-14 Thread kbuild test robot
Hi Sean,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.17-rc5]
[cannot apply to next-20180514]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Sean-Young/media-rc-introduce-BPF_PROG_IR_DECODER/20180515-093234
config: i386-allmodconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

All errors (new ones prefixed by >>):

>> drivers/media/rc/lirc_dev.c:32:10: fatal error: linux/bpf-rcdev.h: No such 
>> file or directory
#include 
 ^~~
   compilation terminated.
--
>> kernel/bpf/syscall.c:30:10: fatal error: linux/bpf-rcdev.h: No such file or 
>> directory
#include 
 ^~~
   compilation terminated.

vim +32 drivers/media/rc/lirc_dev.c

31  
  > 32  #include 
33  

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip