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>, Shuah Khan <shuah@kernel.org>,
Dave Marchevsky <davemarchevsky@fb.com>,
Joe Stringer <joe@cilium.io>, Jonathan Corbet <corbet@lwn.net>
Cc: Tero Kristo <tero.kristo@linux.intel.com>,
linux-kernel@vger.kernel.org, linux-input@vger.kernel.org,
netdev@vger.kernel.org, bpf@vger.kernel.org,
linux-kselftest@vger.kernel.org, linux-doc@vger.kernel.org,
Benjamin Tissoires <benjamin.tissoires@redhat.com>
Subject: [PATCH bpf-next v5 11/17] HID: bpf: introduce hid_hw_request()
Date: Wed, 18 May 2022 22:59:18 +0200 [thread overview]
Message-ID: <20220518205924.399291-12-benjamin.tissoires@redhat.com> (raw)
In-Reply-To: <20220518205924.399291-1-benjamin.tissoires@redhat.com>
This function can not be called under IRQ, thus it is only available
while in SEC("syscall").
This function requires a memory buffer to work with, and so we also
provide a helper to create a HID-BPF context based on the HID unique
ID.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
--
new-ish in v5
---
drivers/hid/bpf/hid_bpf_dispatch.c | 159 +++++++++++++++++++++++++++++
drivers/hid/hid-core.c | 2 +
include/linux/hid_bpf.h | 12 ++-
3 files changed, 172 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
index 87fd11539213..01158d7a14ae 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.c
+++ b/drivers/hid/bpf/hid_bpf_dispatch.c
@@ -232,14 +232,173 @@ hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags)
return __hid_bpf_attach_prog(hdev, prog_type, prog_fd, flags);
}
+/**
+ * hid_bpf_allocate_context - Allocate a context to the given HID device
+ *
+ * @hid_id: the system unique identifier of the HID device
+ *
+ * @returns A pointer to &struct hid_bpf_ctx on success, %NULL on error.
+ */
+noinline struct hid_bpf_ctx *
+hid_bpf_allocate_context(unsigned int hid_id)
+{
+ struct hid_device *hdev;
+ struct hid_bpf_ctx_kern *ctx_kern = NULL;
+ struct device *dev;
+ int err;
+
+ if (!hid_bpf_ops)
+ return NULL;
+
+ dev = bus_find_device(hid_bpf_ops->bus_type, NULL, &hid_id, device_match_id);
+ if (!dev)
+ return NULL;
+
+ hdev = to_hid_device(dev);
+
+ ctx_kern = kzalloc(sizeof(*ctx_kern), GFP_KERNEL);
+ if (!ctx_kern)
+ return NULL;
+
+ ctx_kern->ctx.hid = hdev;
+
+ err = __hid_bpf_allocate_data(hdev, &ctx_kern->data, &ctx_kern->ctx.allocated_size);
+ if (err)
+ goto out_err;
+
+ return &ctx_kern->ctx;
+
+ out_err:
+ kfree(ctx_kern);
+ return NULL;
+}
+
+/**
+ * hid_bpf_release_context - Release the previously allocated context @ctx
+ *
+ * @ctx: the HID-BPF context to release
+ *
+ */
+noinline void
+hid_bpf_release_context(struct hid_bpf_ctx *ctx)
+{
+ struct hid_bpf_ctx_kern *ctx_kern;
+
+ if (!ctx)
+ return;
+
+ ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
+
+ kfree(ctx_kern->data);
+ kfree(ctx_kern);
+}
+
+/**
+ * hid_bpf_hw_request - Communicate with a HID device
+ *
+ * @ctx: the HID-BPF context previously allocated in hid_bpf_allocate_context()
+ * @buf: a %PTR_TO_MEM buffer
+ * @size: the size of the data to transfer
+ * @rtype: the type of the report (%HID_INPUT_REPORT, %HID_FEATURE_REPORT, %HID_OUTPUT_REPORT)
+ * @reqtype: the type of the request (%HID_REQ_GET_REPORT, %HID_REQ_SET_REPORT, ...)
+ *
+ * @returns %0 on success, a negative error code otherwise.
+ */
+noinline int
+hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t size,
+ enum hid_report_type rtype, int reqtype)
+{
+ struct hid_device *hdev = (struct hid_device *)ctx->hid; /* discard const */
+ struct hid_report *report;
+ struct hid_report_enum *report_enum;
+ u8 *dma_data;
+ u32 report_len;
+ int ret;
+
+ /* check arguments */
+ if (!ctx || !hid_bpf_ops)
+ return -EINVAL;
+
+ switch (rtype) {
+ case HID_INPUT_REPORT:
+ case HID_OUTPUT_REPORT:
+ case HID_FEATURE_REPORT:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (reqtype) {
+ case HID_REQ_GET_REPORT:
+ case HID_REQ_GET_IDLE:
+ case HID_REQ_GET_PROTOCOL:
+ case HID_REQ_SET_REPORT:
+ case HID_REQ_SET_IDLE:
+ case HID_REQ_SET_PROTOCOL:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (size < 1)
+ return -EINVAL;
+
+ report_enum = hdev->report_enum + rtype;
+ report = hid_bpf_ops->hid_get_report(report_enum, buf);
+ if (!report)
+ return -EINVAL;
+
+ report_len = hid_report_len(report);
+
+ if (size > report_len)
+ size = report_len;
+
+ dma_data = kmemdup(buf, size, GFP_KERNEL);
+ if (!dma_data)
+ return -ENOMEM;
+
+ ret = hid_bpf_ops->hid_hw_raw_request(hdev,
+ dma_data[0],
+ dma_data,
+ size,
+ rtype,
+ reqtype);
+
+ if (ret > 0)
+ memcpy(buf, dma_data, ret);
+
+ kfree(dma_data);
+ return ret;
+}
+
/* for syscall HID-BPF */
BTF_SET_START(hid_bpf_syscall_kfunc_ids)
BTF_ID(func, hid_bpf_attach_prog)
+BTF_ID(func, hid_bpf_allocate_context)
+BTF_ID(func, hid_bpf_release_context)
+BTF_ID(func, hid_bpf_get_data)
+BTF_ID(func, hid_bpf_hw_request)
BTF_SET_END(hid_bpf_syscall_kfunc_ids)
+BTF_SET_START(hid_bpf_syscall_kfunc_ret_null_ids)
+BTF_ID(func, hid_bpf_get_data)
+BTF_ID(func, hid_bpf_allocate_context)
+BTF_SET_END(hid_bpf_syscall_kfunc_ret_null_ids)
+
+BTF_SET_START(hid_bpf_syscall_kfunc_alloc_ids)
+BTF_ID(func, hid_bpf_allocate_context)
+BTF_SET_END(hid_bpf_syscall_kfunc_alloc_ids)
+
+BTF_SET_START(hid_bpf_syscall_kfunc_release_ids)
+BTF_ID(func, hid_bpf_release_context)
+BTF_SET_END(hid_bpf_syscall_kfunc_release_ids)
+
static const struct btf_kfunc_id_set hid_bpf_syscall_kfunc_set = {
.owner = THIS_MODULE,
.check_set = &hid_bpf_syscall_kfunc_ids,
+ .ret_null_set = &hid_bpf_syscall_kfunc_ret_null_ids,
+ .acquire_set = &hid_bpf_syscall_kfunc_alloc_ids,
+ .release_set = &hid_bpf_syscall_kfunc_release_ids,
};
int hid_bpf_connect_device(struct hid_device *hdev)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 831ef57ddbeb..70b3790f4595 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2913,6 +2913,8 @@ int hid_check_keys_pressed(struct hid_device *hid)
EXPORT_SYMBOL_GPL(hid_check_keys_pressed);
static struct hid_bpf_ops hid_ops = {
+ .hid_get_report = hid_get_report,
+ .hid_hw_raw_request = hid_hw_raw_request,
.owner = THIS_MODULE,
.bus_type = &hid_bus_type,
};
diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h
index c9684de18f3f..62478a53af22 100644
--- a/include/linux/hid_bpf.h
+++ b/include/linux/hid_bpf.h
@@ -61,11 +61,15 @@ struct hid_bpf_ctx {
int hid_bpf_device_event(struct hid_bpf_ctx *ctx);
/* Following functions are kfunc that we export to BPF programs */
-/* only available in tracing */
+/* available everywhere in HID-BPF */
__u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t __sz);
/* only available in syscall */
int hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags);
+int hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t size,
+ enum hid_report_type rtype, int reqtype);
+struct hid_bpf_ctx *hid_bpf_allocate_context(unsigned int hid_id);
+void hid_bpf_release_context(struct hid_bpf_ctx *ctx);
/*
* Below is HID internal
@@ -81,7 +85,13 @@ enum hid_bpf_prog_type {
HID_BPF_PROG_TYPE_MAX,
};
+struct hid_report_enum;
+
struct hid_bpf_ops {
+ struct hid_report *(*hid_get_report)(struct hid_report_enum *report_enum, const u8 *data);
+ int (*hid_hw_raw_request)(struct hid_device *hdev,
+ unsigned char reportnum, __u8 *buf,
+ size_t len, unsigned char rtype, int reqtype);
struct module *owner;
struct bus_type *bus_type;
};
--
2.36.1
next prev parent reply other threads:[~2022-05-18 21:01 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-18 20:59 [PATCH bpf-next v5 00/17] Introduce eBPF support for HID devices Benjamin Tissoires
2022-05-18 20:59 ` [PATCH bpf-next v5 01/17] bpf/btf: also allow kfunc in tracing and syscall programs Benjamin Tissoires
2022-05-21 2:34 ` Alexei Starovoitov
2022-05-18 20:59 ` [PATCH bpf-next v5 02/17] bpf/verifier: allow kfunc to return an allocated mem Benjamin Tissoires
2022-05-18 21:59 ` Kumar Kartikeya Dwivedi
2022-05-19 12:05 ` Benjamin Tissoires
2022-05-19 12:40 ` Kumar Kartikeya Dwivedi
2022-05-18 20:59 ` [PATCH bpf-next v5 03/17] bpf: prepare for more bpf syscall to be used from kernel and user space Benjamin Tissoires
2022-05-18 20:59 ` [PATCH bpf-next v5 04/17] libbpf: add map_get_fd_by_id and map_delete_elem in light skeleton Benjamin Tissoires
2022-05-18 20:59 ` [PATCH bpf-next v5 05/17] HID: core: store the unique system identifier in hid_device Benjamin Tissoires
2022-05-18 20:59 ` [PATCH bpf-next v5 06/17] HID: export hid_report_type to uapi Benjamin Tissoires
2022-05-18 20:59 ` [PATCH bpf-next v5 07/17] HID: initial BPF implementation Benjamin Tissoires
2022-05-18 20:59 ` [PATCH bpf-next v5 08/17] selftests/bpf: add tests for the HID-bpf initial implementation Benjamin Tissoires
2022-05-18 20:59 ` [PATCH bpf-next v5 09/17] HID: bpf: allocate data memory for device_event BPF programs Benjamin Tissoires
2022-05-18 23:13 ` kernel test robot
2022-05-18 20:59 ` [PATCH bpf-next v5 10/17] selftests/bpf/hid: add test to change the report size Benjamin Tissoires
2022-05-18 20:59 ` Benjamin Tissoires [this message]
2022-05-18 20:59 ` [PATCH bpf-next v5 12/17] selftests/bpf: add tests for bpf_hid_hw_request Benjamin Tissoires
2022-05-18 22:20 ` Kumar Kartikeya Dwivedi
2022-05-19 12:12 ` Benjamin Tissoires
2022-05-19 12:51 ` Kumar Kartikeya Dwivedi
2022-05-19 13:13 ` Benjamin Tissoires
2022-05-19 13:44 ` Kumar Kartikeya Dwivedi
2022-05-19 15:47 ` Benjamin Tissoires
2022-05-18 20:59 ` [PATCH bpf-next v5 13/17] HID: bpf: allow to change the report descriptor Benjamin Tissoires
2022-05-21 2:46 ` Alexei Starovoitov
2022-05-18 20:59 ` [PATCH bpf-next v5 14/17] selftests/bpf: add report descriptor fixup tests Benjamin Tissoires
2022-05-18 20:59 ` [PATCH bpf-next v5 15/17] samples/bpf: add new hid_mouse example Benjamin Tissoires
2022-05-18 20:59 ` [PATCH bpf-next v5 16/17] selftests/bpf: Add a test for BPF_F_INSERT_HEAD Benjamin Tissoires
2022-05-18 20:59 ` [PATCH bpf-next v5 17/17] Documentation: add HID-BPF docs Benjamin Tissoires
2022-05-19 8:10 ` [PATCH bpf-next v5 00/17] Introduce eBPF support for HID devices Christoph Hellwig
2022-05-19 8:20 ` Greg KH
2022-05-19 8:38 ` Christoph Hellwig
2022-05-19 10:20 ` Benjamin Tissoires
2022-05-19 10:43 ` Toke Høiland-Jørgensen
2022-05-19 11:56 ` Benjamin Tissoires
2022-05-21 0:18 ` Alexei Starovoitov
2022-05-19 10:32 ` Greg KH
2022-05-19 11:46 ` Benjamin Tissoires
2022-05-21 2:40 ` patchwork-bot+netdevbpf
2022-05-27 7:26 ` Tero Kristo
2022-05-30 15:49 ` Benjamin Tissoires
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=20220518205924.399291-12-benjamin.tissoires@redhat.com \
--to=benjamin.tissoires@redhat.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=corbet@lwn.net \
--cc=daniel@iogearbox.net \
--cc=davemarchevsky@fb.com \
--cc=gregkh@linuxfoundation.org \
--cc=jikos@kernel.org \
--cc=joe@cilium.io \
--cc=john.fastabend@gmail.com \
--cc=kafai@fb.com \
--cc=kpsingh@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=shuah@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;
as well as URLs for NNTP newsgroup(s).