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
next prev 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®