summaryrefslogtreecommitdiff
path: root/drivers/hid/hid-core.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-02-22 11:24:42 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2023-02-22 11:24:42 -0800
commit6c71297eaf713ece684a367ce9aff06069d715b9 (patch)
treeda6f4768868ec6c9ba90a89c88fc78560577348f /drivers/hid/hid-core.c
parentd5176cdbf64ce7d4eebf339205f17c23118e9f72 (diff)
parent904e28c6de083fa4834cdbd0026470ddc30676fc (diff)
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 ...
Diffstat (limited to 'drivers/hid/hid-core.c')
-rw-r--r--drivers/hid/hid-core.c46
1 files changed, 35 insertions, 11 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 5c72aef3d3dd..1ee623c26c49 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -41,11 +41,6 @@
#define DRIVER_DESC "HID core driver"
-int hid_debug = 0;
-module_param_named(debug, hid_debug, int, 0600);
-MODULE_PARM_DESC(debug, "toggle HID debugging messages");
-EXPORT_SYMBOL_GPL(hid_debug);
-
static int hid_ignore_special_drivers = 0;
module_param_named(ignore_special_drivers, hid_ignore_special_drivers, int, 0600);
MODULE_PARM_DESC(ignore_special_drivers, "Ignore any special drivers and handle all devices by generic driver");
@@ -804,7 +799,8 @@ static void hid_scan_collection(struct hid_parser *parser, unsigned type)
int i;
if (((parser->global.usage_page << 16) == HID_UP_SENSOR) &&
- type == HID_COLLECTION_PHYSICAL)
+ (type == HID_COLLECTION_PHYSICAL ||
+ type == HID_COLLECTION_APPLICATION))
hid->group = HID_GROUP_SENSOR_HUB;
if (hid->vendor == USB_VENDOR_ID_MICROSOFT &&
@@ -1219,7 +1215,8 @@ int hid_open_report(struct hid_device *device)
return -ENODEV;
size = device->dev_rsize;
- buf = kmemdup(start, size, GFP_KERNEL);
+ /* call_hid_bpf_rdesc_fixup() ensures we work on a copy of rdesc */
+ buf = call_hid_bpf_rdesc_fixup(device, start, &size);
if (buf == NULL)
return -ENOMEM;
@@ -2046,6 +2043,12 @@ int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data
report_enum = hid->report_enum + type;
hdrv = hid->driver;
+ data = dispatch_hid_bpf_device_event(hid, type, data, &size, interrupt);
+ if (IS_ERR(data)) {
+ ret = PTR_ERR(data);
+ goto unlock;
+ }
+
if (!size) {
dbg_hid("empty report\n");
ret = -1;
@@ -2160,6 +2163,10 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
int len;
int ret;
+ ret = hid_bpf_connect_device(hdev);
+ if (ret)
+ return ret;
+
if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE)
connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV);
if (hdev->quirks & HID_QUIRK_HIDINPUT_FORCE)
@@ -2261,6 +2268,8 @@ void hid_disconnect(struct hid_device *hdev)
if (hdev->claimed & HID_CLAIMED_HIDRAW)
hidraw_disconnect(hdev);
hdev->claimed = 0;
+
+ hid_bpf_disconnect_device(hdev);
}
EXPORT_SYMBOL_GPL(hid_disconnect);
@@ -2796,6 +2805,8 @@ struct hid_device *hid_allocate_device(void)
sema_init(&hdev->driver_input_lock, 1);
mutex_init(&hdev->ll_open_lock);
+ hid_bpf_device_init(hdev);
+
return hdev;
}
EXPORT_SYMBOL_GPL(hid_allocate_device);
@@ -2822,6 +2833,7 @@ static void hid_remove_device(struct hid_device *hdev)
*/
void hid_destroy_device(struct hid_device *hdev)
{
+ hid_bpf_destroy_device(hdev);
hid_remove_device(hdev);
put_device(&hdev->dev);
}
@@ -2908,20 +2920,29 @@ int hid_check_keys_pressed(struct hid_device *hid)
}
EXPORT_SYMBOL_GPL(hid_check_keys_pressed);
+#ifdef CONFIG_HID_BPF
+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,
+};
+#endif
+
static int __init hid_init(void)
{
int ret;
- if (hid_debug)
- pr_warn("hid_debug is now used solely for parser and driver debugging.\n"
- "debugfs is now used for inspecting the device (report descriptor, reports)\n");
-
ret = bus_register(&hid_bus_type);
if (ret) {
pr_err("can't register hid bus\n");
goto err;
}
+#ifdef CONFIG_HID_BPF
+ hid_bpf_ops = &hid_ops;
+#endif
+
ret = hidraw_init();
if (ret)
goto err_bus;
@@ -2937,6 +2958,9 @@ err:
static void __exit hid_exit(void)
{
+#ifdef CONFIG_HID_BPF
+ hid_bpf_ops = NULL;
+#endif
hid_debug_exit();
hidraw_exit();
bus_unregister(&hid_bus_type);