Merge branch 'for-6.3/hid-bpf' into for-linus
[linux-block.git] / drivers / hid / hid-core.c
index 53e4d5831caf87aa97b476d91961bbe7c7a697b2..1ee623c26c49d22c22aef92091d580137af0fc3c 100644 (file)
@@ -1215,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;
 
@@ -2042,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;
@@ -2156,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)
@@ -2257,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);
 
@@ -2792,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);
@@ -2818,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);
 }
@@ -2904,6 +2920,15 @@ 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;
@@ -2914,6 +2939,10 @@ static int __init hid_init(void)
                goto err;
        }
 
+#ifdef CONFIG_HID_BPF
+       hid_bpf_ops = &hid_ops;
+#endif
+
        ret = hidraw_init();
        if (ret)
                goto err_bus;
@@ -2929,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);