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 Signed-off-by: Benjamin Tissoires bentiss@kernel.org
---
no changes in v3
new in v2 --- drivers/hid/bpf/hid_bpf_struct_ops.c | 1 + drivers/hid/hid-core.c | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/bpf/hid_bpf_struct_ops.c b/drivers/hid/bpf/hid_bpf_struct_ops.c index 702c22fae136..0e611a9d79d7 100644 --- a/drivers/hid/bpf/hid_bpf_struct_ops.c +++ b/drivers/hid/bpf/hid_bpf_struct_ops.c @@ -79,6 +79,7 @@ static int hid_bpf_ops_btf_struct_access(struct bpf_verifier_log *log, WRITE_RANGE(hid_device, name, true), WRITE_RANGE(hid_device, uniq, true), WRITE_RANGE(hid_device, phys, true), + WRITE_RANGE(hid_device, quirks, false), }; #undef WRITE_RANGE const struct btf_type *state = NULL; diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index b0a22e173502..8e879937e956 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2709,6 +2709,12 @@ static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv) int ret;
if (!hdev->bpf_rsize) { + unsigned int quirks; + + /* reset the quirks that has been previously set */ + quirks = hid_lookup_quirk(hdev); + hdev->quirks = quirks; + /* in case a bpf program gets detached, we need to free the old one */ hid_free_bpf_rdesc(hdev);
@@ -2718,6 +2724,9 @@ static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv) /* call_hid_bpf_rdesc_fixup will always return a valid pointer */ hdev->bpf_rdesc = call_hid_bpf_rdesc_fixup(hdev, hdev->dev_rdesc, &hdev->bpf_rsize); + if (quirks ^ hdev->quirks) + hid_info(hdev, "HID-BPF toggled quirks on the device: %04x", + quirks ^ hdev->quirks); }
if (!hid_check_device_match(hdev, hdrv, &id)) @@ -2727,8 +2736,6 @@ static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv) if (!hdev->devres_group_id) return -ENOMEM;
- /* reset the quirks that has been previously set */ - hdev->quirks = hid_lookup_quirk(hdev); hdev->driver = hdrv;
if (hdrv->probe) {