From: Benjamin Tissoires <bentiss@kernel.org>
To: Jiri Kosina <jikos@kernel.org>,
Alexei Starovoitov <ast@kernel.org>,
Shuah Khan <shuah@kernel.org>, Jonathan Corbet <corbet@lwn.net>
Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
bpf@vger.kernel.org, linux-kselftest@vger.kernel.org,
linux-doc@vger.kernel.org,
Benjamin Tissoires <bentiss@kernel.org>
Subject: [PATCH HID v2 03/13] HID: bpf: protect HID-BPF prog_list access by a SRCU
Date: Wed, 26 Jun 2024 15:46:24 +0200 [thread overview]
Message-ID: <20240626-hid_hw_req_bpf-v2-3-cfd60fb6c79f@kernel.org> (raw)
In-Reply-To: <20240626-hid_hw_req_bpf-v2-0-cfd60fb6c79f@kernel.org>
We want to add sleepable callbacks for hid_hw_raw_request() and
hid_hw_output_report(), but we can not use a plain RCU for those.
Prepare for a SRCU so we can extend HID-BPF.
This changes a little bit how hid_bpf_device_init() behaves, as it may
now fail, so there is a tiny hid-core.c change to accommodate for this.
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
new in v2
---
drivers/hid/bpf/hid_bpf_dispatch.c | 6 +++++-
drivers/hid/bpf/hid_bpf_struct_ops.c | 2 ++
drivers/hid/hid-core.c | 8 +++++++-
include/linux/hid_bpf.h | 6 ++++--
4 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
index 2df31decaac3..c026248e3d73 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.c
+++ b/drivers/hid/bpf/hid_bpf_dispatch.c
@@ -506,13 +506,17 @@ void hid_bpf_destroy_device(struct hid_device *hdev)
hdev->bpf.destroyed = true;
__hid_bpf_ops_destroy_device(hdev);
+
+ synchronize_srcu(&hdev->bpf.srcu);
+ cleanup_srcu_struct(&hdev->bpf.srcu);
}
EXPORT_SYMBOL_GPL(hid_bpf_destroy_device);
-void hid_bpf_device_init(struct hid_device *hdev)
+int hid_bpf_device_init(struct hid_device *hdev)
{
INIT_LIST_HEAD(&hdev->bpf.prog_list);
mutex_init(&hdev->bpf.prog_list_lock);
+ return init_srcu_struct(&hdev->bpf.srcu);
}
EXPORT_SYMBOL_GPL(hid_bpf_device_init);
diff --git a/drivers/hid/bpf/hid_bpf_struct_ops.c b/drivers/hid/bpf/hid_bpf_struct_ops.c
index 8063db1c8d62..d34731a1b457 100644
--- a/drivers/hid/bpf/hid_bpf_struct_ops.c
+++ b/drivers/hid/bpf/hid_bpf_struct_ops.c
@@ -214,6 +214,7 @@ static int hid_bpf_reg(void *kdata)
list_add_rcu(&ops->list, &hdev->bpf.prog_list);
else
list_add_tail_rcu(&ops->list, &hdev->bpf.prog_list);
+ synchronize_srcu(&hdev->bpf.srcu);
out_unlock:
mutex_unlock(&hdev->bpf.prog_list_lock);
@@ -244,6 +245,7 @@ static void hid_bpf_unreg(void *kdata)
mutex_lock(&hdev->bpf.prog_list_lock);
list_del_rcu(&ops->list);
+ synchronize_srcu(&hdev->bpf.srcu);
reconnect = hdev->bpf.rdesc_ops == ops;
if (reconnect)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 0775a32f5272..ad08289752da 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2875,9 +2875,15 @@ struct hid_device *hid_allocate_device(void)
mutex_init(&hdev->ll_open_lock);
kref_init(&hdev->ref);
- hid_bpf_device_init(hdev);
+ ret = hid_bpf_device_init(hdev);
+ if (ret)
+ goto out_err;
return hdev;
+
+out_err:
+ hid_destroy_device(hdev);
+ return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(hid_allocate_device);
diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h
index a54741db0415..f93845de5cac 100644
--- a/include/linux/hid_bpf.h
+++ b/include/linux/hid_bpf.h
@@ -5,6 +5,7 @@
#include <linux/bpf.h>
#include <linux/mutex.h>
+#include <linux/srcu.h>
#include <uapi/linux/hid.h>
struct hid_device;
@@ -145,6 +146,7 @@ struct hid_bpf {
struct hid_bpf_ops *rdesc_ops;
struct list_head prog_list;
struct mutex prog_list_lock; /* protects prog_list update */
+ struct srcu_struct srcu; /* protects prog_list read-only access */
};
#ifdef CONFIG_HID_BPF
@@ -153,7 +155,7 @@ u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, enum hid_report_type t
int hid_bpf_connect_device(struct hid_device *hdev);
void hid_bpf_disconnect_device(struct hid_device *hdev);
void hid_bpf_destroy_device(struct hid_device *hid);
-void hid_bpf_device_init(struct hid_device *hid);
+int hid_bpf_device_init(struct hid_device *hid);
u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *size);
#else /* CONFIG_HID_BPF */
static inline u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, enum hid_report_type type,
@@ -162,7 +164,7 @@ static inline u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, enum hid
static inline int hid_bpf_connect_device(struct hid_device *hdev) { return 0; }
static inline void hid_bpf_disconnect_device(struct hid_device *hdev) {}
static inline void hid_bpf_destroy_device(struct hid_device *hid) {}
-static inline void hid_bpf_device_init(struct hid_device *hid) {}
+static inline int hid_bpf_device_init(struct hid_device *hid) { return 0; }
#define call_hid_bpf_rdesc_fixup(_hdev, _rdesc, _size) \
((u8 *)kmemdup(_rdesc, *(_size), GFP_KERNEL))
--
2.44.0
next prev parent reply other threads:[~2024-06-26 13:46 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-26 13:46 [PATCH HID v2 00/13] HID: bpf_struct_ops, part 2 Benjamin Tissoires
2024-06-26 13:46 ` [PATCH HID v2 01/13] HID: bpf: fix dispatch_hid_bpf_device_event uninitialized ret value Benjamin Tissoires
2024-06-26 13:46 ` [PATCH HID v2 02/13] HID: add source argument to HID low level functions Benjamin Tissoires
2024-06-26 13:46 ` Benjamin Tissoires [this message]
2024-06-26 13:46 ` [PATCH HID v2 04/13] HID: bpf: add HID-BPF hooks for hid_hw_raw_requests Benjamin Tissoires
2024-06-26 16:29 ` Alexei Starovoitov
2024-06-27 9:45 ` Benjamin Tissoires
2024-06-26 13:46 ` [PATCH HID v2 05/13] HID: bpf: prevent infinite recursions with hid_hw_raw_requests hooks Benjamin Tissoires
2024-06-26 13:46 ` [PATCH HID v2 06/13] selftests/hid: add tests for hid_hw_raw_request HID-BPF hooks Benjamin Tissoires
2024-06-26 13:46 ` [PATCH HID v2 07/13] HID: bpf: add HID-BPF hooks for hid_hw_output_report Benjamin Tissoires
2024-06-26 13:46 ` [PATCH HID v2 08/13] selftests/hid: add tests for hid_hw_output_report HID-BPF hooks Benjamin Tissoires
2024-06-26 13:46 ` [PATCH HID v2 09/13] HID: bpf: make hid_bpf_input_report() sleep until the device is ready Benjamin Tissoires
2024-06-26 13:46 ` [PATCH HID v2 10/13] selftests/hid: add wq test for hid_bpf_input_report() Benjamin Tissoires
2024-06-26 13:46 ` [PATCH HID v2 11/13] HID: bpf: allow hid_device_event hooks to inject input reports on self Benjamin Tissoires
2024-06-26 13:46 ` [PATCH HID v2 12/13] selftests/hid: add another test for injecting an event from an event hook Benjamin Tissoires
2024-06-26 13:46 ` [PATCH HID v2 13/13] selftests/hid: add an infinite loop test for hid_bpf_try_input_report Benjamin Tissoires
2024-06-27 9:44 ` [PATCH HID v2 00/13] HID: bpf_struct_ops, part 2 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=20240626-hid_hw_req_bpf-v2-3-cfd60fb6c79f@kernel.org \
--to=bentiss@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=corbet@lwn.net \
--cc=jikos@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=shuah@kernel.org \
/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).