All of lore.kernel.org
 help / color / mirror / Atom feed
From: Benjamin Tissoires <benjamin.tissoires@redhat.com>
To: 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>
Cc: Tero Kristo <tero.kristo@linux.intel.com>,
	linux-kernel@vger.kernel.org, linux-input@vger.kernel.org,
	bpf@vger.kernel.org,
	Benjamin Tissoires <benjamin.tissoires@redhat.com>
Subject: [RFC bpf-next v4 5/7] HID: initial BPF new way implementation
Date: Thu, 21 Apr 2022 16:07:38 +0200	[thread overview]
Message-ID: <20220421140740.459558-6-benjamin.tissoires@redhat.com> (raw)
In-Reply-To: <20220421140740.459558-1-benjamin.tissoires@redhat.com>

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;
+}
+
+noinline void
+hid_bpf_kfunc_data_release(__u8 *data)
+{
+}
+
+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,
+	};
 
 	if (!hid)
 		return -ENODEV;
@@ -2039,6 +2146,10 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, u32 size, int i
 	report_enum = hid->report_enum + type;
 	hdrv = hid->driver;
 
+	ret = hid_bpf_device_event(&ctx_kern.ctx, type);
+	if (ret)
+		goto unlock;
+
 	if (!size) {
 		dbg_hid("empty report\n");
 		ret = -1;
@@ -2914,6 +3025,10 @@ static int __init hid_init(void)
 
 	hid_debug_init();
 
+	ret = hid_bpf_init();
+	if (ret)
+		pr_err("%s error in bpf_init: %d %s:%d", __func__, ret, __FILE__, __LINE__);
+
 	return 0;
 err_bus:
 	bus_unregister(&hid_bus_type);
diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h
new file mode 100644
index 000000000000..100909b27cd8
--- /dev/null
+++ b/include/linux/hid_bpf.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
+
+#ifndef __HID_BPF_H
+#define __HID_BPF_H
+
+/*
+ * 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 */
+};
+
+/* Following functions are tracepoints that BPF programs can attach to */
+int hid_bpf_device_event(struct hid_bpf_ctx *ctx, __s64 type);
+
+/* Following functions are kfunc that we export to BPF programs */
+__u8 *hid_bpf_kfunc_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t __sz);
+void hid_bpf_kfunc_data_release(__u8 *data);
+int hid_bpf_kfunc_hw_request(struct hid_bpf_ctx *ctx);
+
+#endif /* __HID_BPF_H */
-- 
2.35.1


  parent reply	other threads:[~2022-04-21 14:08 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 ` Benjamin Tissoires [this message]
2022-04-26  4:19   ` [RFC bpf-next v4 5/7] HID: initial BPF new way implementation Alexei Starovoitov
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=20220421140740.459558-6-benjamin.tissoires@redhat.com \
    --to=benjamin.tissoires@redhat.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --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.