summaryrefslogtreecommitdiff
path: root/drivers/hid/bpf
AgeCommit message (Collapse)Author
2025-05-13HID: bpf: abort dispatch if device destroyedRong Zhang
The current HID bpf implementation assumes no output report/request will go through it after hid_bpf_destroy_device() has been called. This leads to a bug that unplugging certain types of HID devices causes a cleaned- up SRCU to be accessed. The bug was previously a hidden failure until a recent x86 percpu change [1] made it access not-present pages. The bug will be triggered if the conditions below are met: A) a device under the driver has some LEDs on B) hid_ll_driver->request() is uninplemented (e.g., logitech-djreceiver) If condition A is met, hidinput_led_worker() is always scheduled *after* hid_bpf_destroy_device(). hid_destroy_device ` hid_bpf_destroy_device ` cleanup_srcu_struct(&hdev->bpf.srcu) ` hid_remove_device ` ... ` led_classdev_unregister ` led_trigger_set(led_cdev, NULL) ` led_set_brightness(led_cdev, LED_OFF) ` ... ` input_inject_event ` input_event_dispose ` hidinput_input_event ` schedule_work(&hid->led_work) [hidinput_led_worker] This is fine when condition B is not met, where hidinput_led_worker() calls hid_ll_driver->request(). This is the case for most HID drivers, which implement it or use the generic one from usbhid. The driver itself or an underlying driver will then abort processing the request. Otherwise, hidinput_led_worker() tries hid_hw_output_report() and leads to the bug. hidinput_led_worker ` hid_hw_output_report ` dispatch_hid_bpf_output_report ` srcu_read_lock(&hdev->bpf.srcu) ` srcu_read_unlock(&hdev->bpf.srcu, idx) The bug has existed since the introduction [2] of dispatch_hid_bpf_output_report(). However, the same bug also exists in dispatch_hid_bpf_raw_requests(), and I've reproduced (no visible effect because of the lack of [1], but confirmed bpf.destroyed == 1) the bug against the commit (i.e., the Fixes:) introducing the function. This is because hidinput_led_worker() falls back to hid_hw_raw_request() when hid_ll_driver->output_report() is uninplemented (e.g., logitech- djreceiver). hidinput_led_worker ` hid_hw_output_report: -ENOSYS ` hid_hw_raw_request ` dispatch_hid_bpf_raw_requests ` srcu_read_lock(&hdev->bpf.srcu) ` srcu_read_unlock(&hdev->bpf.srcu, idx) Fix the issue by returning early in the two mentioned functions if hid_bpf has been marked as destroyed. Though dispatch_hid_bpf_device_event() handles input events, and there is no evidence that it may be called after the destruction, the same check, as a safety net, is also added to it to maintain the consistency among all dispatch functions. The impact of the bug on other architectures is unclear. Even if it acts as a hidden failure, this is still dangerous because it corrupts whatever is on the address calculated by SRCU. Thus, CC'ing the stable list. [1]: commit 9d7de2aa8b41 ("x86/percpu/64: Use relative percpu offsets") [2]: commit 9286675a2aed ("HID: bpf: add HID-BPF hooks for hid_hw_output_report") Closes: https://lore.kernel.org/all/20250506145548.GGaBoi9Jzp3aeJizTR@fat_crate.local/ Fixes: 8bd0488b5ea5 ("HID: bpf: add HID-BPF hooks for hid_hw_raw_requests") Cc: stable@vger.kernel.org Signed-off-by: Rong Zhang <i@rong.moe> Tested-by: Petr Tesarik <petr@tesarici.cz> Link: https://patch.msgid.link/20250512152420.87441-1-i@rong.moe Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2025-04-24HID: bpf: fix BTN_STYLUS for the XP Pen ACK05 remotePeter Hutterer
Usage_Dig_BarrelSwitch was applied in the UsagePage_Button which incorrectly mapped to BTN_TOOL_PENCIL Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/193 Fixes: 834da375 ("bpf: add a v6.11+ compatible BPF fixup for the XPPen ACK05 remote") Link: https://patchwork.kernel.org/project/linux-input/patch/20250207-bpf-import-2025-02-07-v1-7-6048fdd5a206@kernel.org/ Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2025-02-24HID: bpf: add a v6.11+ compatible BPF fixup for the XPPen ACK05 remoteBenjamin Tissoires
With v6.11+, we can actually call hid_hw_output_report() and put the device into raw mode, thus getting accurate events without being messed up. Technically we could do the same on v6.10, but given that wayland, gnome and KDE are still not capable of handling the dial, and that v6.10 is EOL, we can safely save a little bit of compilation by only allowing v6.11+. We can easily export the battery information to userspace by adding a dedicated report. However, we need to cheat on the kernel to force it not to query the battery by making the physical collection a stylus. The kernel will then only rely on the events it gets from the device. Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/133 Acked-by: Jiri Kosina <jkosina@suse.com> Link: https://patch.msgid.link/20250207-bpf-import-2025-02-07-v1-7-6048fdd5a206@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2025-02-24HID: bpf: new hid_bpf_async.h common headerBenjamin Tissoires
The purpose is to simplify the use of bpf_wq to defer blocking operations in a sleepable context. Compared to a more "classic" async approach, there is no sync mechanism to wait for the async to finish. The "simple" API is the following: ``` static int HID_BPF_ASYNC(async_fun)(struct hid_bpf_ctx *hctx) { bpf_printk("%s", __fun__); return 0; } SEC("syscall") int probe(struct hid_bpf_probe_args *ctx) { ctx->retval = HID_BPF_ASYNC_INIT(async_fun); return 0; } SEC(HID_BPF_DEVICE_EVENT) int BPF_PROG(event_handler, struct hid_bpf_ctx *hctx) { /* async_fun() can be called now, it's not a sleepable * function in this example */ async_fun(hctx); /* but we can also delay the call by 10 ms */ HID_BPF_ASYNC_DELAYED_CALL(async_fun, hctx, 10); return 0; } HID_BPF_OPS(xppen_ack05_remote) = { .hid_device_event = (void *)event_handler, }; ``` Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/133 Acked-by: Jiri Kosina <jkosina@suse.com> Link: https://patch.msgid.link/20250207-bpf-import-2025-02-07-v1-6-6048fdd5a206@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2025-02-24HID: bpf: import new kfunc from v6.10 & v6.11Benjamin Tissoires
These kfunc are all in v6.10 except for the hid_bpf_try_input_report() which will be in v6.11. Import their definition once now so we can make use of it. Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/114 Acked-by: Jiri Kosina <jkosina@suse.com> Link: https://patch.msgid.link/20250207-bpf-import-2025-02-07-v1-5-6048fdd5a206@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2025-02-24HID: bpf: add support for the XP-Pen Artist Pro 19 (gen2)Benjamin Tissoires
The device behaves the same than the 16" and 14" models, so let's just add support for it too. Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/145 Acked-by: Jiri Kosina <jkosina@suse.com> Link: https://patch.msgid.link/20250207-bpf-import-2025-02-07-v1-4-6048fdd5a206@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2025-02-24HID: bpf: Added updated Kamvas Pro 19 descriptorBenjamin Tissoires
This adds an updated HID descriptor for the Huion Kamvas Pro 19 that is present on newer firmware revisions, while also trying to keep compat with the older versions. Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/164 Signed-off-by: Aki Van Ness <aki@lethalbit.net> Acked-by: Jiri Kosina <jkosina@suse.com> Link: https://patch.msgid.link/20250207-bpf-import-2025-02-07-v1-3-6048fdd5a206@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2025-02-24HID: bpf: Suppress bogus F13 trigger on Sirius keyboard full fan shortcutBenjamin Tissoires
The TUXEDO Sirius 16 Gen1 and the TUXEDO Sirius 16 Gen2 Notebooks have an additional "fan" key next to F12. Pressing it alone sends a F14 key press which can be bound by user space. Pressing it while holding the FN key triggers two things: - The EC firmware locks the fan speed of the internal fans at 100% - F13 key press is registered which by default is already bound in xkb and desktop environments (e.g. in KDE Plasma it launches system settings) To avoid this unexpected double duty of the FN shortcut, this bpf program suppresses the F13 key press. Signed-off-by: Werner Sembach <wse@tuxedocomputers.com> Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/166 Acked-by: Jiri Kosina <jkosina@suse.com> Link: https://patch.msgid.link/20250207-bpf-import-2025-02-07-v1-2-6048fdd5a206@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2025-02-24HID: bpf: Add support for the default firmware mode of the Huion K20Benjamin Tissoires
This re-uses the same HID report descriptor that we also use for the tablet mode after switching the device. The keys send uniquely identifyable shortcuts so we can map those to buttons. However the dial and the button inside the dial send events on a different hidraw node and they are unreliable (e.g. the button does not get released reliably). So they're ignored in this patch, it's not worth the effort getting those to work correctly. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/158 Acked-by: Jiri Kosina <jkosina@suse.com> Link: https://patch.msgid.link/20250207-bpf-import-2025-02-07-v1-1-6048fdd5a206@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-11-28HID: bpf: drop unneeded casts discarding constThomas Weißschuh
In commit 33c0fb85b571 ("HID: bpf: make part of struct hid_device writable") the const qualifier was dropped from struct hid_bpf_ctx::hid. The casts are now unnecessary. Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> Link: https://patch.msgid.link/20241127-hid-bpf-cast-v1-1-f26424960e84@weissschuh.net Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-11-28HID: bpf: constify hid_opsThomas Weißschuh
The hid_ops struct is never modified. Mark it as const. Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> Link: https://patch.msgid.link/20241127-hid-bpf-ops-v1-1-f9e41bfa3afd@weissschuh.net Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-11-25Revert "HID: bpf: allow write access to quirks field in struct hid_device"Linus Torvalds
This reverts commit 6fd47effe92b, and the related self-test update commit e14e0eaeb040 ("selftests/hid: add test for assigning a given device to hid-generic"). It results in things like the scroll wheel on Logitech mice not working after a reboot due to the kernel being confused about the state of the high-resolution mode. Quoting Benjamin Tissoires: "The idea of 6fd47effe92b was to be able to call hid_bpf_rdesc_fixup() once per reprobe of the device. However, because the bpf filter can now change the quirk value, the call had to be moved before the driver gets bound (which was previously ensuring the unicity of the call). The net effect is that now, in the case hid-generic gets loaded first and then the specific driver gets loaded once the disk is available, the value of ->quirks is not reset, but kept to the value that was set by hid-generic (HID_QUIRK_INPUT_PER_APP). Once hid-logitech-hidpp kicks in, that quirk is now set, which creates two inputs for the single mouse: one keyboard for fancy shortcuts, and one mouse node. However, hid-logitech-hidpp expects only one input node to be attached (it stores it into hidpp->input), and when a wheel event is received, because there is some processing with high-resolution wheel events, the wheel event is injected into hidpp->input. And of course, when HID_QUIRK_INPUT_PER_APP is set, hidpp->input gets the keyboard node, which doesn't have wheel event type, and the events are ignored" Reported-and-bisected-by: Mike Galbraith <efault@gmx.de> Link: https://lore.kernel.org/all/CAHk-=wiUkQM3uheit2cNM0Y0OOY5qqspJgC8LkmOkJ2p2LDxcw@mail.gmail.com/ Acked-by: Benjamin Tissoires <bentiss@kernel.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2024-10-18HID: bpf: drop use of Logical|Physical|UsageRangeBenjamin Tissoires
Replace with individual Minimum/Maximum calls to match the HID report descriptor - HID doesn't have a Range field. Abstracting this is good for hand-written descriptors but almost all tools will output min/max instead so let's stick with that. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Acked-by: Jiri Kosina <jkosina@suse.com> Link: https://patch.msgid.link/20241017-import_bpf_6-13-v2-3-6a7acb89a97f@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-10-18HID: bpf: Fix Rapoo M50 Plus Silent side buttonsBenjamin Tissoires
The Rapoo M50 Plus Silent mouse has 2 side buttons in addition to the left, right and middles buttons. However, its original HID descriptor has a Usage Maximum of 3, preventing the side buttons to work. This HID-BPF driver changes that usage to 5. Link: https://gitlab.freedesktop.org/libinput/libinput/-/issues/1015 Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/116 Signed-off-by: José Expósito <jose.exposito89@gmail.com> Acked-by: Jiri Kosina <jkosina@suse.com> Link: https://patch.msgid.link/20241017-import_bpf_6-13-v2-2-6a7acb89a97f@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-10-18HID: bpf: Fix NKRO on Mistel MD770Benjamin Tissoires
Mistel MD770 keyboard (using Holtek Semiconductor, Inc. controller) has a quirk in report descriptor in one of its interfaces (more detail in the source file). Fix up the descriptor to allow NKRO to work again. Tested by loading the BPF program and confirming that 8 simultaneous keypresses work. Link: https://bugzilla.kernel.org/show_bug.cgi?id=218495 Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/122 Signed-off-by: Tatsuyuki Ishi <ishitatsuyuki@gmail.com> Acked-by: Jiri Kosina <jkosina@suse.com> Link: https://patch.msgid.link/20241017-import_bpf_6-13-v2-1-6a7acb89a97f@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-10-04HID: bpf: allow write access to quirks field in struct hid_deviceBenjamin Tissoires
This allows to give more control from BPF during report descriptor fixup. We already reset the quirks before calling ->probe(), so now we reset it once before calling hid_bpf_rdesc_fixup(). Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Link: https://patch.msgid.link/20241001-hid-bpf-hid-generic-v3-4-2ef1019468df@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-10-04HID: bpf: move HID-BPF report descriptor fixup earlierBenjamin Tissoires
Currently, hid_bpf_rdesc_fixup() is called once the match between the HID device and the driver is done. This can be problematic in case the driver selected by the kernel would change the report descriptor after the fact. To give a chance for hid_bpf_rdesc_fixup() to provide hints on to how to select a dedicated driver or not, move the call to that BPF hook earlier in the .probe() process, when we get the first match. However, this means that we might get called more than once (typically once for hid-generic, and once for hid-vendor-specific). So we store the result of HID-BPF fixup in struct hid_device. Basically, this means that ->bpf_rdesc can replace ->dev_rdesc when it was used in the code. In order to not grow struct hid_device, some fields are re-ordered. This was the output of pahole for the first 128 bytes: struct hid_device { __u8 * dev_rdesc; /* 0 8 */ unsigned int dev_rsize; /* 8 4 */ /* XXX 4 bytes hole, try to pack */ __u8 * rdesc; /* 16 8 */ unsigned int rsize; /* 24 4 */ /* XXX 4 bytes hole, try to pack */ struct hid_collection * collection; /* 32 8 */ unsigned int collection_size; /* 40 4 */ unsigned int maxcollection; /* 44 4 */ unsigned int maxapplication; /* 48 4 */ __u16 bus; /* 52 2 */ __u16 group; /* 54 2 */ __u32 vendor; /* 56 4 */ __u32 product; /* 60 4 */ /* --- cacheline 1 boundary (64 bytes) --- */ __u32 version; /* 64 4 */ enum hid_type type; /* 68 4 */ unsigned int country; /* 72 4 */ /* XXX 4 bytes hole, try to pack */ struct hid_report_enum report_enum[3]; /* 80 6216 */ Basically, we got three holes of 4 bytes. We can reorder things a little and makes those 3 holes a continuous 12 bytes hole, which can be replaced by the new pointer and the new unsigned int we need. In terms of code allocation, when not using HID-BPF, we are back to kernel v6.2 in hid_open_report(). These multiple kmemdup() calls will be fixed in a later commit. Link: https://patch.msgid.link/20241001-hid-bpf-hid-generic-v3-1-2ef1019468df@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-09-27HID: bpf: fix cfi stubs for hid_bpf_opsBenjamin Tissoires
With the introduction of commit e42ac1418055 ("bpf: Check unsupported ops from the bpf_struct_ops's cfi_stubs"), a HID-BPF struct_ops containing a .hid_hw_request() or a .hid_hw_output_report() was failing to load as the cfi stubs were not defined. Fix that by defining those simple static functions and restore HID-BPF functionality. This was detected with the HID selftests suddenly failing on Linus' tree. Cc: stable@vger.kernel.org # v6.11+ Fixes: 9286675a2aed ("HID: bpf: add HID-BPF hooks for hid_hw_output_report") Fixes: 8bd0488b5ea5 ("HID: bpf: add HID-BPF hooks for hid_hw_raw_requests") Signed-off-by: Benjamin Tissoires <bentiss@kernel.org> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2024-08-27HID: bpf: constify parameter rdesc of call_hid_bpf_rdesc_fixup()Thomas Weißschuh
The parameter is never modified, so mark it as const. Also inline the return statement to avoid a type mismatch error. This is a prerequisite for constification changes in the HID core. Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> Link: https://patch.msgid.link/20240803-hid-const-fixup-v2-1-f53d7a7b29d8@weissschuh.net Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-07-24HID: bpf: prevent the same struct_ops to be attached more than onceBenjamin Tissoires
If the struct_ops is already attached, we should bail out or we will end up in various locks and pointer issues while unregistering. Link: https://patch.msgid.link/20240723-fix-6-11-bpf-v1-3-b9d770346784@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-07-22hid: bpf: add BPF_JIT dependencyArnd Bergmann
The module does not do anything when the JIT is disabled, but instead causes a warning: In file included from include/linux/bpf_verifier.h:7, from drivers/hid/bpf/hid_bpf_struct_ops.c:10: drivers/hid/bpf/hid_bpf_struct_ops.c: In function 'hid_bpf_struct_ops_init': include/linux/bpf.h:1853:50: error: statement with no effect [-Werror=unused-value] 1853 | #define register_bpf_struct_ops(st_ops, type) ({ (void *)(st_ops); 0; }) | ^~~~~~~~~~~~~~~~ drivers/hid/bpf/hid_bpf_struct_ops.c:305:16: note: in expansion of macro 'register_bpf_struct_ops' 305 | return register_bpf_struct_ops(&bpf_hid_bpf_ops, hid_bpf_ops); | ^~~~~~~~~~~~~~~~~~~~~~~ Add a Kconfig dependency to only allow building the HID-BPF support when a JIT is enabled. Fixes: ebc0d8093e8c ("HID: bpf: implement HID-BPF through bpf_struct_ops") Signed-off-by: Arnd Bergmann <arnd@arndb.de> Link: https://patch.msgid.link/96a00b6f-eb81-4c67-8c4b-6b1f3f045034@app.fastmail.com Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-07-17Merge tag 'for-linus-2024071601' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid Pull HID updates from Benjamin Tissoires: - rewrite of the HID-BPF internal implementation to use bpf struct_ops instead of a tracing endpoint (Benjamin Tissoires) - add two new HID-BPF hooks to be able to intercept userspace calls targeting a HID device and filtering them (Benjamin Tissoires) - add support for various new devices through HID-BPF filters (Benjamin Tissoires) - add support for the magic keyboard backlight (Orlando Chamberlain) - add the missing MODULE_DESCRIPTION() macros in HID drivers (Jeff Johnson) - use of kvzalloc in case memory gets too fragmented (Hailong Liu) - retrieve the device firmware node in the child HID device (Danny Kaehn) - some hid-uclogic improvements (José Expósito) - some more typos, trivial fixes, kernel doctext and unused functions cleanups * tag 'for-linus-2024071601' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (60 commits) HID: hid-steam: Fix typo in goto label HID: mcp2221: Remove unnecessary semicolon HID: Fix spelling mistakes "Kensigton" -> "Kensington" HID: add more missing MODULE_DESCRIPTION() macros HID: samples: fix the 2 struct_ops definitions HID: fix for amples in for-6.11/bpf HID: apple: Add support for magic keyboard backlight on T2 Macs HID: bpf: Thrustmaster TCA Yoke Boeing joystick fix HID: bpf: Add Huion Dial 2 bpf fixup HID: bpf: Add support for the XP-PEN Deco Mini 4 HID: bpf: move the BIT() macro to hid_bpf_helpers.h HID: bpf: add a driver for the Huion Inspiroy 2S (H641P) HID: bpf: Add a HID report composition helper macros HID: bpf: doc fixes for hid_hw_request() hooks HID: bpf: doc fixes for hid_hw_request() hooks HID: bpf: fix gcc warning and unify __u64 into u64 selftests/hid: ensure CKI can compile our new tests on old kernels selftests/hid: add an infinite loop test for hid_bpf_try_input_report selftests/hid: add another test for injecting an event from an event hook HID: bpf: allow hid_device_event hooks to inject input reports on self ...
2024-07-01HID: bpf: Thrustmaster TCA Yoke Boeing joystick fixBenjamin Tissoires
This joystick's original HID descriptor is wrong & it shows a ABS_MISC axis in Linux that doesn't exist on the hardware. Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/82 Signed-off-by: K S Iyer <kumar.s.iyer65@gmail.com> Link: https://patch.msgid.link/20240627-import-bpf-v1-6-0dbcda4a5b1f@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-07-01HID: bpf: Add Huion Dial 2 bpf fixupBenjamin Tissoires
Pretty much similar to the Inspiroy 2, but with 2 wheels and 8 buttons. This bpf also works in both normal and vendor mode. If the device is switched into vendor mode by huion-switcher, a udev property is set which is then retrieved by this bpf object. This allows to hide the now unused normal collections. Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/103 Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/104 Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/111 Link: https://patch.msgid.link/20240627-import-bpf-v1-5-0dbcda4a5b1f@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-07-01HID: bpf: Add support for the XP-PEN Deco Mini 4Benjamin Tissoires
The XP-PEN Deco Mini 4 is a UGEE device with a frame with 6 buttons. Its pen has 2 buttons and supports pressure reporting. Fix their report descriptors and transform the frame button events to support it. Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/88 Signed-off-by: José Expósito <jose.exposito89@gmail.com> Link: https://patch.msgid.link/20240627-import-bpf-v1-4-0dbcda4a5b1f@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-07-01HID: bpf: move the BIT() macro to hid_bpf_helpers.hBenjamin Tissoires
This macro can be useful in mopre than one place Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/commit/7970a9c17aa0756bad63e89fccb6ee4f2ec83ccc Signed-off-by: José Expósito <jose.exposito89@gmail.com> Link: https://patch.msgid.link/20240627-import-bpf-v1-3-0dbcda4a5b1f@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-07-01HID: bpf: add a driver for the Huion Inspiroy 2S (H641P)Benjamin Tissoires
This is a a driver for the Huion Inspiroy 2S in both modes (firmware mode and tablet mode). This device has 6 buttons and a wheel, all of which send key combinations (see the comments for the defaults). Luckily the device is quite limited in that it only supports one button down at a time, so with this BPF we can simply remap the 8 possible report IDs to our own custom-built report descriptor. If the device is in tablet mode (e.g. using huion-switcher it sends everything through the vendor report instead). This BPF program converts both, depending which devices you attach to you get both. Or if you attach to all hid devices you get a duplicate device but it'll work either way. This BPF should be mostly compatible for the M and L as well though they have more buttons so the rdescs will need some minor rework. Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/85 Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/109 Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Link: https://patch.msgid.link/20240627-import-bpf-v1-2-0dbcda4a5b1f@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-07-01HID: bpf: Add a HID report composition helper macrosBenjamin Tissoires
These macros make it slightly easier and more modular to create a HID report descriptor from scratch. Since they carry the annotation we don't need to comment it and they cannot get stale. For comparison, before we had this: 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x95, 0x04, // Report Count (4) 0x75, 0x01, // Report Size (1) Now we can write this as: LogicalRange_i8(0, 1) ReportCount(4) ReportSize(1) Because these macros are for creating new report descriptors, some bits aren't directly exposed. e.g in the example above: there is a logical range as one macro that sets both min and max. There is seldom a good use case for skipping either anyway. These macros will need to be expanded over time. For Usage Pages and Usage IDs, we use a tool to parse the HUT JSON (attached to the HUT 1.5 PDF [1]) and generate all #defines for all usage pages and usages in the form: #define UsagePage_Foo_Bar #define Usage_FB_SomeOrOther Where the FB is simply the acronym based on the capital letters in the Usage Page name or the first three letters, whichever makes slightly more sense. [1] https://usb.org/document-library/hid-usage-tables-15 Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/92 Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/96 Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Link: https://patch.msgid.link/20240627-import-bpf-v1-1-0dbcda4a5b1f@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-07-01HID: bpf: doc fixes for hid_hw_request() hooksBenjamin Tissoires
We had the following errors while doing make htmldocs: Documentation/hid/hid-bpf:185: include/linux/hid_bpf.h:167: ERROR: Unexpected indentation. Also ensure consistency with the rest of the __u64 vs u64. Reported-by: Stephen Rothwell <sfr@canb.auug.org.au> Fixes: 9286675a2aed ("HID: bpf: add HID-BPF hooks for hid_hw_output_report") Link: https://patch.msgid.link/20240701-fix-cki-v2-4-20564e2e1393@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-07-01HID: bpf: fix gcc warning and unify __u64 into u64Benjamin Tissoires
I've got multiple reports of: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]. Let's use the same trick than kernel/bpf/helpers.c to shut up that warning. Even if we were on an architecture with addresses on more than 64 bits, this isn't much of an issue as the address is not used as a pointer, but as an hash and the caller is not supposed to go back to the kernel address ever. And while we change those, make sure we use u64 instead of __u64 for consistency Reported-by: Stephen Rothwell <sfr@canb.auug.org.au> Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202406280633.OPB5uIFj-lkp@intel.com/ Closes: https://lore.kernel.org/oe-kbuild-all/202406282304.UydSVncq-lkp@intel.com/ Closes: https://lore.kernel.org/oe-kbuild-all/202406282242.Fk738zzy-lkp@intel.com/ Reported-by: Mirsad Todorovac <mtodorovac69@gmail.com> Fixes: 67eccf151d76 ("HID: add source argument to HID low level functions") Link: https://patch.msgid.link/20240701-fix-cki-v2-2-20564e2e1393@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-27HID: bpf: allow hid_device_event hooks to inject input reports on selfBenjamin Tissoires
This is the same logic than hid_hw_raw_request or hid_hw_output_report: we can allow hid_bpf_try_input_report to be called from a hook on hid_input_report if we ensure that the call can not be made twice in a row. There is one extra subtlety in which there is a lock in hid_input_report. But given that we can detect if we are already in the hook, we can notify hid_input_report to not take the lock. This is done by checking if ctx_kern data is valid or null, and if it is equal to the dedicated incoming data buffer. In order to have more control on whether the lock needs to be taken or not we introduce a new kfunc for it: hid_bpf_try_input_report() Link: https://patch.msgid.link/20240626-hid_hw_req_bpf-v2-11-cfd60fb6c79f@kernel.org Acked-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-27HID: bpf: make hid_bpf_input_report() sleep until the device is readyBenjamin Tissoires
hid_bpf_input_report() is already marked to be used in sleepable context only. So instead of hammering with timers the device to hopefully get an available slot where the device is not sending events, we can make that kfunc wait for the current event to be terminated before it goes in. This allows to work with the following pseudo code: in struct_ops/hid_device_event: - schedule a bpf_wq, which calls hid_bpf_input_report() - once this struct_ops function terminates, hid_bpf_input_report() immediately starts before the next event Link: https://patch.msgid.link/20240626-hid_hw_req_bpf-v2-9-cfd60fb6c79f@kernel.org Acked-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-27selftests/hid: add tests for hid_hw_output_report HID-BPF hooksBenjamin Tissoires
We add 3 new tests: - first, we make sure we can prevent the output_report to happen - second, we make sure that we can detect that a given hidraw client was actually doing the request, and for that client only, call ourself hid_bpf_hw_output_report(), returning a custom value - last, we ensure that we can not loop between hooks for hid_hw_output_report() and manual calls to hid_bpf_hw_output_report() from that same hook Link: https://patch.msgid.link/20240626-hid_hw_req_bpf-v2-8-cfd60fb6c79f@kernel.org Acked-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-27HID: bpf: add HID-BPF hooks for hid_hw_output_reportBenjamin Tissoires
Same story than hid_hw_raw_requests: This allows to intercept and prevent or change the behavior of hid_hw_output_report() from a bpf program. The intent is to solve a couple of use case: - firewalling a HID device: a firewall can monitor who opens the hidraw nodes and then prevent or allow access to write operations on that hidraw node. - change the behavior of a device and emulate a new HID feature request The hook is allowed to be run as sleepable so it can itself call hid_hw_output_report(), which allows to "convert" one feature request into another or even call the feature request on a different HID device on the same physical device. Link: https://patch.msgid.link/20240626-hid_hw_req_bpf-v2-7-cfd60fb6c79f@kernel.org Acked-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-27HID: bpf: prevent infinite recursions with hid_hw_raw_requests hooksBenjamin Tissoires
When we attach a sleepable hook to hid_hw_raw_requests, we can (and in many cases should) call ourself hid_bpf_raw_request(), to actually fetch data from the device itself. However, this means that we might enter an infinite loop between hid_hw_raw_requests hooks and hid_bpf_hw_request() call. To prevent that, if a hid_bpf_hw_request() call is emitted, we prevent any new call of this kfunc by storing the information in the context. This way we can always trace/monitor/filter the incoming bpf requests, while preventing those loops to happen. I don't think exposing "from_bpf" is very interesting because while writing such a bpf program, you need to match at least the report number and/or the source of the call. So a blind "if there is a hid_hw_raw_request() call, I'm emitting another one" makes no real sense. Link: https://patch.msgid.link/20240626-hid_hw_req_bpf-v2-5-cfd60fb6c79f@kernel.org Acked-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-27HID: bpf: add HID-BPF hooks for hid_hw_raw_requestsBenjamin Tissoires
This allows to intercept and prevent or change the behavior of hid_hw_raw_request() from a bpf program. The intent is to solve a couple of use case: - firewalling a HID device: a firewall can monitor who opens the hidraw nodes and then prevent or allow access to write operations on that hidraw node. - change the behavior of a device and emulate a new HID feature request The hook is allowed to be run as sleepable so it can itself call hid_bpf_hw_request(), which allows to "convert" one feature request into another or even call the feature request on a different HID device on the same physical device. Link: https://patch.msgid.link/20240626-hid_hw_req_bpf-v2-4-cfd60fb6c79f@kernel.org Acked-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-27HID: bpf: protect HID-BPF prog_list access by a SRCUBenjamin Tissoires
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. Link: https://patch.msgid.link/20240626-hid_hw_req_bpf-v2-3-cfd60fb6c79f@kernel.org Acked-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-27HID: add source argument to HID low level functionsBenjamin Tissoires
This allows to know who actually sent what when we process the request to the device. This will be useful for a BPF firewall program to allow or not requests coming from a dedicated hidraw node client. Link: https://patch.msgid.link/20240626-hid_hw_req_bpf-v2-2-cfd60fb6c79f@kernel.org Acked-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-27HID: bpf: fix dispatch_hid_bpf_device_event uninitialized ret valueBenjamin Tissoires
Looks like if a bpf program gets inserted and then removed, hdev->bpf.device_data is then allocated, but the loop iterating over the bpf program is never assigning ret. This is a problem and also revealed another bug in which only the last value of ret was checked. This effectively meant than only the last program in the chain could change the size of the incoming buffer. Reported-by: Dan Carpenter <dan.carpenter@linaro.org> Link: https://lore.kernel.org/all/00f7b624-219f-4a05-a7ad-5335f15a41c7@moroto.mountain Fixes: 4a86220e046d ("HID: bpf: remove tracing HID-BPF capability") Link: https://patch.msgid.link/20240626-hid_hw_req_bpf-v2-1-cfd60fb6c79f@kernel.org Acked-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-27hid: bpf: Fix grammarLuis Felipe Hernandez
* spelling fix: XBox -> Xbox, lowercase 'b' as per Microsoft branding * rephrase: paddle -> paddles, the controller itself has more than one paddle * rephrase: replace usage of "those" in favor of explicitly making reference to the paddles * grammatical fix: report -> reports, use present tense verb. * spelling fix: interpret * consistency: capitalize the first word in bullet points Signed-off-by: Luis Felipe Hernandez <luis.hernandez093@gmail.com> Link: https://patch.msgid.link/20240625105553.50830-1-luis.hernandez093@gmail.com [bentiss: renamed the file into Xbox, not XBox] Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-14HID: bpf: make part of struct hid_device writableBenjamin Tissoires
It is useful to change the name, the phys and/or the uniq of a struct hid_device during .rdesc_fixup(). For example, hid-uclogic.ko changes the uniq to store the firmware version to differentiate between 2 devices sharing the same PID. In the same way, changing the device name is useful when the device export 3 nodes, all with the same name. Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-16-6ac6ade58329@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-14HID: bpf: rework hid_bpf_ops_btf_struct_accessBenjamin Tissoires
The idea is to provide a list of stucts and their editable fields. Currently no functional changes are introduced here, we will add some more writeable fields in the next patch. Acked-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-15-6ac6ade58329@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-14bpf: allow bpf helpers to be used into HID-BPF struct_opsBenjamin Tissoires
Without this helpers like bpf_printk() or bpf_map_update() are not available, making anything but change of bytes impossible to do. Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-14-6ac6ade58329@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-14HID: bpf: error on warnings when compiling bpf objectsBenjamin Tissoires
There is no real reasons to paper over warnings for such small programs. Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-13-6ac6ade58329@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-14HID: bpf: Artist24: remove unused variableBenjamin Tissoires
warning: unused variable ‘tilt’ [-Wunused-variable] Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-12-6ac6ade58329@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-14HID: bpf: remove tracing HID-BPF capabilityBenjamin Tissoires
We can now rely on struct_ops as we cleared the users in-tree. Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-8-6ac6ade58329@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-14HID: bpf: convert in-tree fixes into struct_opsBenjamin Tissoires
Very mechanical: - Change HID_BPF_DEVICE_EVENT and HID_BPF_RDESC_FIXUP #defines - add a matching SEC(".struct_ops.link") - in ArtistPro16Gen2 make the 2 functions static and have a new one calling them Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-7-6ac6ade58329@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-14HID: bpf: add defines for HID-BPF SEC in in-tree bpf fixesBenjamin Tissoires
We are going to switch over struct_ops, so instead of having to manually replace all fields one by one, let's have a common place to change it. Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-6-6ac6ade58329@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-14HID: bpf: implement HID-BPF through bpf_struct_opsBenjamin Tissoires
We do this implementation in several steps to not have the CI failing: - first (this patch), we add struct_ops while keeping the existing infra available - then we change the selftests, the examples and the existing in-tree HID-BPF programs - then we remove the existing trace points making old HID-BPF obsolete There are a few advantages of struct_ops over tracing: - compatibility with sleepable programs (for hid_hw_raw_request() in a later patch) - a lot simpler in the kernel: it's a simple rcu protected list - we can add more parameters to the function called without much trouble - the "attach" is now generic through BPF-core: the caller just needs to set hid_id and flags before calling __load(). - all the BPF tough part is not handled in BPF-core through generic processing - hid_bpf_ctx is now only writable where it needs be Acked-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-3-6ac6ade58329@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-06-14HID: bpf: add hid_get/put_device() helpersBenjamin Tissoires
no code change, but this way we reduce code duplication and we can export it later. Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-2-6ac6ade58329@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>