All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexei Starovoitov <alexei.starovoitov@gmail.com>
To: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Cc: Greg KH <gregkh@linuxfoundation.org>,
	Jiri Kosina <jikos@kernel.org>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Andrii Nakryiko <andrii@kernel.org>,
	Martin KaFai Lau <kafai@fb.com>, Song Liu <songliubraving@fb.com>,
	Yonghong Song <yhs@fb.com>,
	John Fastabend <john.fastabend@gmail.com>,
	KP Singh <kpsingh@kernel.org>,
	Tero Kristo <tero.kristo@linux.intel.com>,
	linux-kernel@vger.kernel.org, linux-input@vger.kernel.org,
	bpf@vger.kernel.org
Subject: Re: [RFC bpf-next v4 5/7] HID: initial BPF new way implementation
Date: Mon, 25 Apr 2022 21:19:50 -0700	[thread overview]
Message-ID: <20220426041950.j37velutd2ckj3s5@MBP-98dd607d3435.dhcp.thefacebook.com> (raw)
In-Reply-To: <20220421140740.459558-6-benjamin.tissoires@redhat.com>

On Thu, Apr 21, 2022 at 04:07:38PM +0200, Benjamin Tissoires wrote:
> Declare an entry point that can use fmod_ret BPF programs, and
> also an API to access and change the incoming data.
> 
> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> 
> ---
> 
> new-ish in v4:
> - far from complete, but gives an overview of what we can do now.
> ---
>  drivers/hid/hid-core.c  | 115 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/hid_bpf.h |  29 ++++++++++
>  2 files changed, 144 insertions(+)
>  create mode 100644 include/linux/hid_bpf.h
> 
> diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
> index db925794fbe6..ff4e1b47d2fb 100644
> --- a/drivers/hid/hid-core.c
> +++ b/drivers/hid/hid-core.c
> @@ -32,6 +32,9 @@
>  #include <linux/hiddev.h>
>  #include <linux/hid-debug.h>
>  #include <linux/hidraw.h>
> +#include <linux/btf.h>
> +#include <linux/btf_ids.h>
> +#include <linux/hid_bpf.h>
>  
>  #include "hid-ids.h"
>  
> @@ -2008,6 +2011,99 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
>  }
>  EXPORT_SYMBOL_GPL(hid_report_raw_event);
>  
> +struct hid_bpf_ctx_kern {
> +	struct hid_device *hdev;
> +	struct hid_bpf_ctx ctx;
> +	u8 *data;
> +	size_t size;
> +};
> +
> +__weak int hid_bpf_device_event(struct hid_bpf_ctx *ctx, s64 type)
> +{
> +	return 0;
> +}
> +ALLOW_ERROR_INJECTION(hid_bpf_device_event, NS_ERRNO);
> +
> +noinline __u8 *
> +hid_bpf_kfunc_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t __sz)
> +{
> +	struct hid_bpf_ctx_kern *ctx_kern;
> +
> +	if (!ctx)
> +		return NULL;
> +
> +	ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
> +
> +	return ctx_kern->data;
> +}

It probably needs to check that "rdonly_buf_sz" or "__sz" constant passed
by the program is less than what was allocated in hid_bpf_ctx_kern->data.
Right?

> +
> +noinline void
> +hid_bpf_kfunc_data_release(__u8 *data)
> +{
> +}

Not clear what release() is for.
hid_bpf_kfunc_get_data() will return PTR_TO_MEM.
There is no need to release it.

> +
> +noinline int
> +hid_bpf_kfunc_hw_request(struct hid_bpf_ctx *ctx)
> +{
> +	if (!ctx)
> +		return -EINVAL;
> +
> +	pr_err("%s test ctx->bus: %04x %s:%d", __func__, ctx->bus, __FILE__, __LINE__);
> +
> +	return 0;
> +}
> +
> +/*
> + * The following set contains all functions we agree BPF programs
> + * can use.
> + */
> +BTF_SET_START(hid_bpf_kfunc_ids)
> +BTF_ID(func, hid_bpf_kfunc_get_data)
> +BTF_ID(func, hid_bpf_kfunc_data_release)
> +BTF_ID(func, hid_bpf_kfunc_hw_request)
> +BTF_SET_END(hid_bpf_kfunc_ids)
> +
> +/*
> + * The following set contains all functions to provide a kernel
> + * resource to the BPF program.
> + * We need to add a counterpart release function.
> + */
> +BTF_SET_START(hid_bpf_kfunc_acquire_ids)
> +BTF_ID(func, hid_bpf_kfunc_get_data)
> +BTF_SET_END(hid_bpf_kfunc_acquire_ids)
> +
> +/*
> + * The following set is the release counterpart of the previous
> + * function set.
> + */
> +BTF_SET_START(hid_bpf_kfunc_release_ids)
> +BTF_ID(func, hid_bpf_kfunc_data_release)
> +BTF_SET_END(hid_bpf_kfunc_release_ids)
> +
> +/*
> + * The following set tells which functions are sleepable.
> + */
> +BTF_SET_START(hid_bpf_kfunc_sleepable_ids)
> +BTF_ID(func, hid_bpf_kfunc_hw_request)
> +BTF_SET_END(hid_bpf_kfunc_sleepable_ids)
> +
> +static const struct btf_kfunc_id_set hid_bpf_kfunc_set = {
> +	.owner         = THIS_MODULE,
> +	.check_set     = &hid_bpf_kfunc_ids,
> +	.acquire_set   = &hid_bpf_kfunc_acquire_ids,
> +	.release_set   = &hid_bpf_kfunc_release_ids,
> +	.ret_null_set  = &hid_bpf_kfunc_acquire_ids, /* duplicated to force BPF programs to
> +						      * check the validity of the returned pointer
> +						      * in acquire function
> +						      */
> +	.sleepable_set = &hid_bpf_kfunc_sleepable_ids,
> +};
> +
> +static int __init hid_bpf_init(void)
> +{
> +	return register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &hid_bpf_kfunc_set);
> +}
> +
>  /**
>   * hid_input_report - report data from lower layer (usb, bt...)
>   *
> @@ -2025,6 +2121,17 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, u32 size, int i
>  	struct hid_driver *hdrv;
>  	struct hid_report *report;
>  	int ret = 0;
> +	struct hid_bpf_ctx_kern ctx_kern = {
> +		.hdev = hid,
> +		.ctx = {
> +			.bus = hid->bus,
> +			.group = hid->group,
> +			.vendor = hid->vendor,
> +			.product = hid->product,
> +		},
> +		.data = data,
> +		.size = size,
> +	};

I'm not sure why hid_bpf_ctx_kern is needed.
Just to scope all args into one struct?

> +/*
> + * The following is the HID BPF API.
> + *
> + * It should be treated as UAPI, so extra care is required
> + * when making change to this file.
> + */
> +
> +struct hid_bpf_ctx {
> +	__u16 bus;							/* BUS ID */
> +	__u16 group;							/* Report group */
> +	__u32 vendor;							/* Vendor ID */
> +	__u32 product;							/* Product ID */
> +	__u32 version;							/* HID version */
> +};

Your choice of course,
but not clear why kernel has to populate it with explicit:
+			.bus = hid->bus,
+			.group = hid->group,
+			.vendor = hid->vendor,
+			.product = hid->product,
and waste cpu cycles on that while bpf program can read all these fields
on demand when necessary.

  reply	other threads:[~2022-04-26  4:20 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-21 14:07 [RFC bpf-next v4 0/7] Introduce eBPF support for HID devices (new attempt) Benjamin Tissoires
2022-04-21 14:07 ` [RFC bpf-next v4 1/7] bpf/btf: also allow kfunc in tracing programs Benjamin Tissoires
2022-04-21 14:07 ` [RFC bpf-next v4 2/7] bpf/verifier: allow kfunc to return an allocated mem Benjamin Tissoires
2022-04-26  4:08   ` Alexei Starovoitov
2022-04-26  7:30     ` Benjamin Tissoires
2022-04-30  3:25       ` Alexei Starovoitov
2022-04-30  7:17         ` Benjamin Tissoires
2022-04-21 14:07 ` [RFC bpf-next v4 3/7] error-inject: add new type that carries if the function is non sleepable Benjamin Tissoires
2022-04-26  4:11   ` Alexei Starovoitov
2022-04-26  7:52     ` Benjamin Tissoires
2022-04-30  3:29       ` Alexei Starovoitov
2022-04-30  7:24         ` Benjamin Tissoires
2022-04-21 14:07 ` [RFC bpf-next v4 4/7] btf: Add a new kfunc set which allows to mark a function to be sleepable Benjamin Tissoires
2022-04-26  4:12   ` Alexei Starovoitov
2022-04-21 14:07 ` [RFC bpf-next v4 5/7] HID: initial BPF new way implementation Benjamin Tissoires
2022-04-26  4:19   ` Alexei Starovoitov [this message]
2022-04-21 14:07 ` [RFC bpf-next v4 6/7] samples/bpf: add new hid_mouse example Benjamin Tissoires
2022-04-21 14:07 ` [RFC bpf-next v4 7/7] selftests/bpf: add tests for the HID-bpf initial implementation Benjamin Tissoires
2022-04-26  4:03 ` [RFC bpf-next v4 0/7] Introduce eBPF support for HID devices (new attempt) Alexei Starovoitov
2022-04-26  7:20   ` Benjamin Tissoires
2022-04-30  3:00     ` Alexei Starovoitov
2022-04-30  7:12       ` Benjamin Tissoires
2022-05-02 21:43         ` Benjamin Tissoires
2022-05-12  4:16           ` Alexei Starovoitov
2022-05-13 16:59             ` Benjamin Tissoires
2022-05-12  4:23         ` Alexei Starovoitov
2022-05-13 17:02           ` Benjamin Tissoires
2022-05-13 19:42             ` Alexei Starovoitov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220426041950.j37velutd2ckj3s5@MBP-98dd607d3435.dhcp.thefacebook.com \
    --to=alexei.starovoitov@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=benjamin.tissoires@redhat.com \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=jikos@kernel.org \
    --cc=john.fastabend@gmail.com \
    --cc=kafai@fb.com \
    --cc=kpsingh@kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=songliubraving@fb.com \
    --cc=tero.kristo@linux.intel.com \
    --cc=yhs@fb.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.