diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-02-22 11:24:42 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-02-22 11:24:42 -0800 |
| commit | 6c71297eaf713ece684a367ce9aff06069d715b9 (patch) | |
| tree | da6f4768868ec6c9ba90a89c88fc78560577348f | |
| parent | d5176cdbf64ce7d4eebf339205f17c23118e9f72 (diff) | |
| parent | 904e28c6de083fa4834cdbd0026470ddc30676fc (diff) | |
| download | linux-6c71297eaf713ece684a367ce9aff06069d715b9.tar.gz linux-6c71297eaf713ece684a367ce9aff06069d715b9.tar.bz2 linux-6c71297eaf713ece684a367ce9aff06069d715b9.zip | |
Merge tag 'for-linus-2023022201' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
Pull HID updates from Benjamin Tissoires:
- HID-BPF infrastructure: this allows to start using HID-BPF. Note that
the mechanism to ship HID-BPF program through the kernel tree is
still not implemented yet (but is planned).
This should be a no-op for 99% of users. Also we are gaining
kselftests for the HID tree (Benjamin Tissoires)
- Some UAF fixes in workers when using uhid (Pietro Borrello & Benjamin
Tissoires)
- Constify hid_ll_driver (Thomas Weißschuh)
- Allow more custom IIO sensors through HID (Philipp Jungkamp)
- Logitech HID++ fixes for scroll wheel, protocol and debug (Bastien
Nocera)
- Some new device support: Steam Deck (Vicki Pfau), UClogic (José
Expósito), Logitech G923 Xbox Edition steering wheel (Walt Holman),
EVision keyboards (Philippe Valembois)
- other assorted code cleanups and fixes
* tag 'for-linus-2023022201' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (99 commits)
HID: mcp-2221: prevent UAF in delayed work
hid: bigben_probe(): validate report count
HID: asus: use spinlock to safely schedule workers
HID: asus: use spinlock to protect concurrent accesses
HID: bigben: use spinlock to safely schedule workers
HID: bigben_worker() remove unneeded check on report_field
HID: bigben: use spinlock to protect concurrent accesses
HID: logitech-hidpp: Add myself to authors
HID: logitech-hidpp: Retry commands when device is busy
HID: logitech-hidpp: Add more debug statements
HID: Add support for Logitech G923 Xbox Edition steering wheel
HID: logitech-hidpp: Add Signature M650
HID: logitech-hidpp: Remove HIDPP_QUIRK_NO_HIDINPUT quirk
HID: logitech-hidpp: Don't restart communication if not necessary
HID: logitech-hidpp: Add constants for HID++ 2.0 error codes
Revert "HID: logitech-hidpp: add a module parameter to keep firmware gestures"
HID: logitech-hidpp: Hard-code HID++ 1.0 fast scroll support
HID: i2c-hid: goodix: Add mainboard-vddio-supply
dt-bindings: HID: i2c-hid: goodix: Add mainboard-vddio-supply
HID: i2c-hid: goodix: Stop tying the reset line to the regulator
...
91 files changed, 6734 insertions, 1428 deletions
diff --git a/Documentation/devicetree/bindings/input/goodix,gt7375p.yaml b/Documentation/devicetree/bindings/input/goodix,gt7375p.yaml index 1c191bc5a178..ce18d7dadae2 100644 --- a/Documentation/devicetree/bindings/input/goodix,gt7375p.yaml +++ b/Documentation/devicetree/bindings/input/goodix,gt7375p.yaml @@ -36,6 +36,13 @@ properties: vdd-supply: description: The 3.3V supply to the touchscreen. + mainboard-vddio-supply: + description: + The supply on the main board needed to power up IO signals going + to the touchscreen. This supply need not go to the touchscreen + itself as long as it allows the main board to make signals compatible + with what the touchscreen is expecting for its IO rails. + required: - compatible - reg diff --git a/Documentation/hid/hid-alps.rst b/Documentation/hid/hid-alps.rst index 767c96bcbb7c..94382bb0ada4 100644 --- a/Documentation/hid/hid-alps.rst +++ b/Documentation/hid/hid-alps.rst @@ -9,7 +9,7 @@ Currently ALPS HID driver supports U1 Touchpad device. U1 device basic information. ========== ====== -Vender ID 0x044E +Vendor ID 0x044E Product ID 0x120B Version ID 0x0121 ========== ====== diff --git a/Documentation/hid/hid-bpf.rst b/Documentation/hid/hid-bpf.rst new file mode 100644 index 000000000000..4fad83a6ebc3 --- /dev/null +++ b/Documentation/hid/hid-bpf.rst @@ -0,0 +1,522 @@ +.. SPDX-License-Identifier: GPL-2.0 + +======= +HID-BPF +======= + +HID is a standard protocol for input devices but some devices may require +custom tweaks, traditionally done with a kernel driver fix. Using the eBPF +capabilities instead speeds up development and adds new capabilities to the +existing HID interfaces. + +.. contents:: + :local: + :depth: 2 + + +When (and why) to use HID-BPF +============================= + +There are several use cases when using HID-BPF is better +than standard kernel driver fix: + +Dead zone of a joystick +----------------------- + +Assuming you have a joystick that is getting older, it is common to see it +wobbling around its neutral point. This is usually filtered at the application +level by adding a *dead zone* for this specific axis. + +With HID-BPF, we can apply this filtering in the kernel directly so userspace +does not get woken up when nothing else is happening on the input controller. + +Of course, given that this dead zone is specific to an individual device, we +can not create a generic fix for all of the same joysticks. Adding a custom +kernel API for this (e.g. by adding a sysfs entry) does not guarantee this new +kernel API will be broadly adopted and maintained. + +HID-BPF allows the userspace program to load the program itself, ensuring we +only load the custom API when we have a user. + +Simple fixup of report descriptor +--------------------------------- + +In the HID tree, half of the drivers only fix one key or one byte +in the report descriptor. These fixes all require a kernel patch and the +subsequent shepherding into a release, a long and painful process for users. + +We can reduce this burden by providing an eBPF program instead. Once such a +program has been verified by the user, we can embed the source code into the +kernel tree and ship the eBPF program and load it directly instead of loading +a specific kernel module for it. + +Note: distribution of eBPF programs and their inclusion in the kernel is not +yet fully implemented + +Add a new feature that requires a new kernel API +------------------------------------------------ + +An example for such a feature are the Universal Stylus Interface (USI) pens. +Basically, USI pens require a new kernel API because there are new +channels of communication that our HID and input stack do not support. +Instead of using hidraw or creating new sysfs entries or ioctls, we can rely +on eBPF to have the kernel API controlled by the consumer and to not +impact the performances by waking up userspace every time there is an +event. + +Morph a device into something else and control that from userspace +------------------------------------------------------------------ + +The kernel has a relatively static mapping of HID items to evdev bits. +It cannot decide to dynamically transform a given device into something else +as it does not have the required context and any such transformation cannot be +undone (or even discovered) by userspace. + +However, some devices are useless with that static way of defining devices. For +example, the Microsoft Surface Dial is a pushbutton with haptic feedback that +is barely usable as of today. + +With eBPF, userspace can morph that device into a mouse, and convert the dial +events into wheel events. Also, the userspace program can set/unset the haptic +feedback depending on the context. For example, if a menu is visible on the +screen we likely need to have a haptic click every 15 degrees. But when +scrolling in a web page the user experience is better when the device emits +events at the highest resolution. + +Firewall +-------- + +What if we want to prevent other users to access a specific feature of a +device? (think a possibly broken firmware update entry point) + +With eBPF, we can intercept any HID command emitted to the device and +validate it or not. + +This also allows to sync the state between the userspace and the +kernel/bpf program because we can intercept any incoming command. + +Tracing +------- + +The last usage is tracing events and all the fun we can do we BPF to summarize +and analyze events. + +Right now, tracing relies on hidraw. It works well except for a couple +of issues: + +1. if the driver doesn't export a hidraw node, we can't trace anything + (eBPF will be a "god-mode" there, so this may raise some eyebrows) +2. hidraw doesn't catch other processes' requests to the device, which + means that we have cases where we need to add printks to the kernel + to understand what is happening. + +High-level view of HID-BPF +========================== + +The main idea behind HID-BPF is that it works at an array of bytes level. +Thus, all of the parsing of the HID report and the HID report descriptor +must be implemented in the userspace component that loads the eBPF +program. + +For example, in the dead zone joystick from above, knowing which fields +in the data stream needs to be set to ``0`` needs to be computed by userspace. + +A corollary of this is that HID-BPF doesn't know about the other subsystems +available in the kernel. *You can not directly emit input event through the +input API from eBPF*. + +When a BPF program needs to emit input events, it needs to talk with the HID +protocol, and rely on the HID kernel processing to translate the HID data into +input events. + +Available types of programs +=========================== + +HID-BPF is built "on top" of BPF, meaning that we use tracing method to +declare our programs. + +HID-BPF has the following attachment types available: + +1. event processing/filtering with ``SEC("fmod_ret/hid_bpf_device_event")`` in libbpf +2. actions coming from userspace with ``SEC("syscall")`` in libbpf +3. change of the report descriptor with ``SEC("fmod_ret/hid_bpf_rdesc_fixup")`` in libbpf + +A ``hid_bpf_device_event`` is calling a BPF program when an event is received from +the device. Thus we are in IRQ context and can act on the data or notify userspace. +And given that we are in IRQ context, we can not talk back to the device. + +A ``syscall`` means that userspace called the syscall ``BPF_PROG_RUN`` facility. +This time, we can do any operations allowed by HID-BPF, and talking to the device is +allowed. + +Last, ``hid_bpf_rdesc_fixup`` is different from the others as there can be only one +BPF program of this type. This is called on ``probe`` from the driver and allows to +change the report descriptor from the BPF program. Once a ``hid_bpf_rdesc_fixup`` +program has been loaded, it is not possible to overwrite it unless the program which +inserted it allows us by pinning the program and closing all of its fds pointing to it. + +Developer API: +============== + +User API data structures available in programs: +----------------------------------------------- + +.. kernel-doc:: include/linux/hid_bpf.h + +Available tracing functions to attach a HID-BPF program: +-------------------------------------------------------- + +.. kernel-doc:: drivers/hid/bpf/hid_bpf_dispatch.c + :functions: hid_bpf_device_event hid_bpf_rdesc_fixup + +Available API that can be used in all HID-BPF programs: +------------------------------------------------------- + +.. kernel-doc:: drivers/hid/bpf/hid_bpf_dispatch.c + :functions: hid_bpf_get_data + +Available API that can be used in syscall HID-BPF programs: +----------------------------------------------------------- + +.. kernel-doc:: drivers/hid/bpf/hid_bpf_dispatch.c + :functions: hid_bpf_attach_prog hid_bpf_hw_request hid_bpf_allocate_context hid_bpf_release_context + +General overview of a HID-BPF program +===================================== + +Accessing the data attached to the context +------------------------------------------ + +The ``struct hid_bpf_ctx`` doesn't export the ``data`` fields directly and to access +it, a bpf program needs to first call :c:func:`hid_bpf_get_data`. + +``offset`` can be any integer, but ``size`` needs to be constant, known at compile +time. + +This allows the following: + +1. for a given device, if we know that the report length will always be of a certain value, + we can request the ``data`` pointer to point at the full report length. + + The kernel will ensure we are using a correct size and offset and eBPF will ensure + the code will not attempt to read or write outside of the boundaries:: + + __u8 *data = hid_bpf_get_data(ctx, 0 /* offset */, 256 /* size */); + + if (!data) + return 0; /* ensure data is correct, now the verifier knows we + * have 256 bytes available */ + + bpf_printk("hello world: %02x %02x %02x", data[0], data[128], data[255]); + +2. if the report length is variable, but we know the value of ``X`` is always a 16-bit + integer, we can then have a pointer to that value only:: + + __u16 *x = hid_bpf_get_data(ctx, offset, sizeof(*x)); + + if (!x) + return 0; /* something went wrong */ + + *x += 1; /* increment X by one */ + +Effect of a HID-BPF program +--------------------------- + +For all HID-BPF attachment types except for :c:func:`hid_bpf_rdesc_fixup`, several eBPF +programs can be attached to the same device. + +Unless ``HID_BPF_FLAG_INSERT_HEAD`` is added to the flags while attaching the +program, the new program is appended at the end of the list. +``HID_BPF_FLAG_INSERT_HEAD`` will insert the new program at the beginning of the +list which is useful for e.g. tracing where we need to get the unprocessed events +from the device. + +Note that if there are multiple programs using the ``HID_BPF_FLAG_INSERT_HEAD`` flag, +only the most recently loaded one is actually the first in the list. + |
