From patchwork Tue Oct 1 14:30:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13818147 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5E3C71C6F7E; Tue, 1 Oct 2024 14:30:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727793036; cv=none; b=qwC9hfEcgrn2Tt7qtsLHy9IkjFaYvcqaH7TwrKg2J1BX/tzGyLsoWjETfRUvVND8wl6kp5rQ1B1y5KVtrJHm2dskVrqBZttHut5EADa/0VxPJqHCt1YPcXn4t10N8R1fbzEpN+MH/tehF0DbmatgHEUPHcfjnK0AD7q1Wixyyqs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727793036; c=relaxed/simple; bh=quTeQfcYupJVJt0hX7vqPPMZokG65wuGpHlzqqZgOW4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=d3IQPohPOZ5V1Ch4asngyKDfwBmS2mDgCnHNTZRrrTt7Pl+zfnSdDCYGfy5ezcqncUXwZyvonRCeUkzodtGKg4Z+Bkdb7vnhEBBkVH73N/H5xsW/g0sE7XGoCLeUqeRkBdr2CgNANfeRFVbockyw6CeQbDycN5NdZr7Xrrnj7/M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IYaYFoxF; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="IYaYFoxF" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4987DC4CED2; Tue, 1 Oct 2024 14:30:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1727793035; bh=quTeQfcYupJVJt0hX7vqPPMZokG65wuGpHlzqqZgOW4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=IYaYFoxFDT1SgtLQY1IoK0i+/wOygB+q/Zbuy92PqjRDDaDOGpf0Tg7LYV/HZZLVB C3NBOFG9obbyFDMAcri0dKMjTGtoVA+P2PFLxVQM/9MoaRN3xB6SXDEmwCGXn9k9/E Qt0CS8jqYRLO73ZVEBxG8ycKYBPdnAa2eiAkJ5A3fDng49Qieq5qbxOVsBXAaEDvnM lpUhWpSkNXIDMrOJm0oh6S2DEfWKxp0Aft7bnImCwVGqPzghggnXIU+q85KF54K70I JGlm8ar0+4iI8+Q2ujlWK+8AEN5ZOQOER/N5SiEKoWspLk4KAjS4zxDtcdFvNiuAoW JoSQdHbHd5EsQ== From: Benjamin Tissoires Date: Tue, 01 Oct 2024 16:30:05 +0200 Subject: [PATCH HID v3 1/9] HID: bpf: move HID-BPF report descriptor fixup earlier Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241001-hid-bpf-hid-generic-v3-1-2ef1019468df@kernel.org> References: <20241001-hid-bpf-hid-generic-v3-0-2ef1019468df@kernel.org> In-Reply-To: <20241001-hid-bpf-hid-generic-v3-0-2ef1019468df@kernel.org> To: Jiri Kosina , Peter Hutterer , Vicki Pfau , Shuah Khan Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1727793031; l=9574; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=quTeQfcYupJVJt0hX7vqPPMZokG65wuGpHlzqqZgOW4=; b=V1h1PsFSdpnz9PJcT3JY2c5XKoJgEi+XDDL2BCycuNNgDhf7i05pa4whMyCxBR2Rd7a64bezo uO0vQcPLUrOD0btG83padhuww+jR+4mhS7BtrM+zVbNoOapCcVS3arY X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= 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. Signed-off-by: Benjamin Tissoires --- changes in v3: - consider ->bpf_rdesc the new ->dev_rdesc to simplify the logic - add a new inline hid_free_bpf_rdesc() to ensure we don't double free ->dev_rdesc new in v2 --- drivers/hid/bpf/hid_bpf_dispatch.c | 9 ++++++--- drivers/hid/hid-core.c | 30 ++++++++++++++++++++++++++---- include/linux/hid.h | 18 ++++++++++-------- include/linux/hid_bpf.h | 11 +++-------- 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c index 8420c227e21b..961b7f35aa67 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.c +++ b/drivers/hid/bpf/hid_bpf_dispatch.c @@ -148,7 +148,7 @@ int dispatch_hid_bpf_output_report(struct hid_device *hdev, } EXPORT_SYMBOL_GPL(dispatch_hid_bpf_output_report); -u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, const u8 *rdesc, unsigned int *size) +const u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, const u8 *rdesc, unsigned int *size) { int ret; struct hid_bpf_ctx_kern ctx_kern = { @@ -183,7 +183,7 @@ u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, const u8 *rdesc, unsigned ignore_bpf: kfree(ctx_kern.data); - return kmemdup(rdesc, *size, GFP_KERNEL); + return rdesc; } EXPORT_SYMBOL_GPL(call_hid_bpf_rdesc_fixup); @@ -260,8 +260,11 @@ int hid_bpf_allocate_event_data(struct hid_device *hdev) int hid_bpf_reconnect(struct hid_device *hdev) { - if (!test_and_set_bit(ffs(HID_STAT_REPROBED), &hdev->status)) + if (!test_and_set_bit(ffs(HID_STAT_REPROBED), &hdev->status)) { + /* trigger call to call_hid_bpf_rdesc_fixup() during the next probe */ + hdev->bpf_rsize = 0; return device_reprobe(&hdev->dev); + } return 0; } diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 30de92d0bf0f..d6bf933623e8 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -698,6 +698,14 @@ static void hid_close_report(struct hid_device *device) device->status &= ~HID_STAT_PARSED; } +static inline void hid_free_bpf_rdesc(struct hid_device *hdev) +{ + /* bpf_rdesc is either equal to dev_rdesc or allocated by call_hid_bpf_rdesc_fixup() */ + if (hdev->bpf_rdesc != hdev->dev_rdesc) + kfree(hdev->bpf_rdesc); + hdev->bpf_rdesc = NULL; +} + /* * Free a device structure, all reports, and all fields. */ @@ -707,6 +715,7 @@ void hiddev_free(struct kref *ref) struct hid_device *hid = container_of(ref, struct hid_device, ref); hid_close_report(hid); + hid_free_bpf_rdesc(hid); kfree(hid->dev_rdesc); kfree(hid); } @@ -1221,13 +1230,12 @@ int hid_open_report(struct hid_device *device) if (WARN_ON(device->status & HID_STAT_PARSED)) return -EBUSY; - start = device->dev_rdesc; + start = device->bpf_rdesc; if (WARN_ON(!start)) return -ENODEV; - size = device->dev_rsize; + size = device->bpf_rsize; - /* call_hid_bpf_rdesc_fixup() ensures we work on a copy of rdesc */ - buf = call_hid_bpf_rdesc_fixup(device, start, &size); + buf = kmemdup(start, size, GFP_KERNEL); if (buf == NULL) return -ENOMEM; @@ -2684,6 +2692,18 @@ static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv) const struct hid_device_id *id; int ret; + if (!hdev->bpf_rsize) { + /* in case a bpf program gets detached, we need to free the old one */ + hid_free_bpf_rdesc(hdev); + + /* keep this around so we know we called it once */ + hdev->bpf_rsize = hdev->dev_rsize; + + /* 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 (!hid_check_device_match(hdev, hdrv, &id)) return -ENODEV; @@ -2940,9 +2960,11 @@ static void hid_remove_device(struct hid_device *hdev) hid_debug_unregister(hdev); hdev->status &= ~HID_STAT_ADDED; } + hid_free_bpf_rdesc(hdev); kfree(hdev->dev_rdesc); hdev->dev_rdesc = NULL; hdev->dev_rsize = 0; + hdev->bpf_rsize = 0; } /** diff --git a/include/linux/hid.h b/include/linux/hid.h index 121d5b8bc867..ff58b5ceb62e 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -599,15 +599,17 @@ enum hid_battery_status { struct hid_driver; struct hid_ll_driver; -struct hid_device { /* device report descriptor */ - const __u8 *dev_rdesc; - unsigned dev_rsize; - const __u8 *rdesc; - unsigned rsize; +struct hid_device { + const __u8 *dev_rdesc; /* device report descriptor */ + const __u8 *bpf_rdesc; /* bpf modified report descriptor, if any */ + const __u8 *rdesc; /* currently used report descriptor */ + unsigned int dev_rsize; + unsigned int bpf_rsize; + unsigned int rsize; + unsigned int collection_size; /* Number of allocated hid_collections */ struct hid_collection *collection; /* List of HID collections */ - unsigned collection_size; /* Number of allocated hid_collections */ - unsigned maxcollection; /* Number of parsed collections */ - unsigned maxapplication; /* Number of applications */ + unsigned int maxcollection; /* Number of parsed collections */ + unsigned int maxapplication; /* Number of applications */ __u16 bus; /* BUS ID */ __u16 group; /* Report group */ __u32 vendor; /* Vendor ID */ diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h index 6a47223e6460..a6876ab29004 100644 --- a/include/linux/hid_bpf.h +++ b/include/linux/hid_bpf.h @@ -212,7 +212,7 @@ int hid_bpf_connect_device(struct hid_device *hdev); void hid_bpf_disconnect_device(struct hid_device *hdev); void hid_bpf_destroy_device(struct hid_device *hid); int hid_bpf_device_init(struct hid_device *hid); -u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, const u8 *rdesc, unsigned int *size); +const u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, const u8 *rdesc, unsigned int *size); #else /* CONFIG_HID_BPF */ static inline u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, enum hid_report_type type, u8 *data, u32 *size, int interrupt, @@ -228,13 +228,8 @@ static inline int hid_bpf_connect_device(struct hid_device *hdev) { return 0; } static inline void hid_bpf_disconnect_device(struct hid_device *hdev) {} static inline void hid_bpf_destroy_device(struct hid_device *hid) {} static inline int hid_bpf_device_init(struct hid_device *hid) { return 0; } -/* - * This specialized allocator has to be a macro for its allocations to be - * accounted separately (to have a separate alloc_tag). The typecast is - * intentional to enforce typesafety. - */ -#define call_hid_bpf_rdesc_fixup(_hdev, _rdesc, _size) \ - ((u8 *)kmemdup(_rdesc, *(_size), GFP_KERNEL)) +static inline const u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, const u8 *rdesc, + unsigned int *size) { return rdesc; } #endif /* CONFIG_HID_BPF */ From patchwork Tue Oct 1 14:30:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13818148 X-Patchwork-Delegate: jikos@jikos.cz Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1DB351C7B8A; Tue, 1 Oct 2024 14:30:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727793038; cv=none; b=Mmol2U3sExdO3iizSZFa7e4QY11p48LiT3nHbhzogzA81mLtsEJfDoYEjbuYScPLovagLzPzgXYr1q/9NW6jPy6yUm1Bw/dnDit5xGQK8eoi//mcE7vt9TYDuPfb6nYqWMbBlGuUcYVIbD8Fqce0vVE4Zjaa2zGBbQzKW7ochl0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727793038; c=relaxed/simple; bh=BJURDqA+9kHR/SvAohPi0bq69sWfM74Vsjzf6VM/9sE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Z5hhdGijmvpVyY77RGD2vV52Q+8u8jBjYhkurZ9G088PWN3DeRvPRLj4jCdfshJ8ZCFCqEejbRJgrIE11O1hoeu1UgUUWU2NsLsSYLTKsGi07+puRqyFT9ao/RR9nhKtkgp+gKyhmbh7LylkqBk6+7HTz3ju82/2+R1+vcm1a4M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=S1MDH09W; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="S1MDH09W" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 58226C4CECD; Tue, 1 Oct 2024 14:30:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1727793038; bh=BJURDqA+9kHR/SvAohPi0bq69sWfM74Vsjzf6VM/9sE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=S1MDH09W+yroNIfEXQgVJA3ZxAFjz6D8vKLFb+4bMkZzIB4gyr8iDlSdsbqTi6cHx lCTlcuYo1kE6KsbnooUwHaByIBKBN12LqEs5Org7FAMy6B2nbixlbGQR7rctNSm17L K8jBtU0sIpUMcbH06jCaktEGpKH31OXP9noF5LPBJns95bSq6d23GebE8Y3DryPBYu jLe60UIzIojF5h/fhA54MEuzKTWWiwuFpoLqCpwvzwMO0htfAF8ldDQf4GVng9dGH3 DaifR5p/uBWIOw1qiT5YEHpg7HX7uD/gYuK4FeYbhuSX+Al/GsXDgkvnYkj3hz6oAN 7nhQNHb9lQdww== From: Benjamin Tissoires Date: Tue, 01 Oct 2024 16:30:06 +0200 Subject: [PATCH HID v3 2/9] HID: core: save one kmemdup during .probe() Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241001-hid-bpf-hid-generic-v3-2-2ef1019468df@kernel.org> References: <20241001-hid-bpf-hid-generic-v3-0-2ef1019468df@kernel.org> In-Reply-To: <20241001-hid-bpf-hid-generic-v3-0-2ef1019468df@kernel.org> To: Jiri Kosina , Peter Hutterer , Vicki Pfau , Shuah Khan Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1727793031; l=1505; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=BJURDqA+9kHR/SvAohPi0bq69sWfM74Vsjzf6VM/9sE=; b=CiFVQJkbMggNbRUHg6yY8sUusPU1QwO4QmSysy/mqGhUviqifJNXwDanOdtL1+/wMJIRBCfIu eg53Lj4ZDuIDLK+p9jkBwXN3gVDrTQanaqVq7DaaZk3zjuivbWcMicD X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Turns out the first kmemdup is only required for the .report_fixup() driver callback. There is no need to do two kmemdup() in a row in case .report_fixup() is not present. Reviewed-by: Peter Hutterer Signed-off-by: Benjamin Tissoires --- no changes in v3 new in v2 --- drivers/hid/hid-core.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index d6bf933623e8..6053e7cdc0c1 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1214,7 +1214,7 @@ int hid_open_report(struct hid_device *device) struct hid_item item; unsigned int size; const __u8 *start; - __u8 *buf; + __u8 *buf = NULL; const __u8 *end; const __u8 *next; int ret; @@ -1235,14 +1235,18 @@ int hid_open_report(struct hid_device *device) return -ENODEV; size = device->bpf_rsize; - buf = kmemdup(start, size, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; + if (device->driver->report_fixup) { + /* + * device->driver->report_fixup() needs to work + * on a copy of our report descriptor so it can + * change it. + */ + buf = kmemdup(start, size, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; - if (device->driver->report_fixup) start = device->driver->report_fixup(device, buf, &size); - else - start = buf; + } start = kmemdup(start, size, GFP_KERNEL); kfree(buf); From patchwork Tue Oct 1 14:30:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13818149 X-Patchwork-Delegate: jikos@jikos.cz Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7EBB91C9B67; Tue, 1 Oct 2024 14:30:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727793040; cv=none; b=KnzOQt1cBN82xuhNqGNMird+5wggnaoPMU5innsXAAnHM5I5Keq7OFR0NymPGsuKK0WB/bB5dIFZOVOWhtRJAXCpqA8Pdp/65C5JdySb8skaUipGnWSv46Pb9JeiYaZ1Wdud9dxxW3koySS+KixD96b6agB7imSAqXFpSC6NW7Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727793040; c=relaxed/simple; bh=BHYSNYgX8pUz6K6rRtEk1le3e4BVn69IDcbXBU2DJJY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pmUvVgXho1W2SSlxLNs41XfUiiP/qLNxJ/PWiI65tqBFrYgq7N2oQWzcwlp4ZoTh90cmHC6ZmZ2kdYM0Ao8/VCwTgtUv83lbOEg6kIDa4DS+PHZJ6dW61QrgxDvzDy/ZcCwBgaSZ4iGxs+hcJMVzBNt5huVbB3yOlLoiRqsUs3M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rD9heVYL; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rD9heVYL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 673EEC4CEC6; Tue, 1 Oct 2024 14:30:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1727793040; bh=BHYSNYgX8pUz6K6rRtEk1le3e4BVn69IDcbXBU2DJJY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=rD9heVYLaZQZy4Xq0uK86Yqz+VV103/W+Xa1Pf/9/uID9IJFIic0tuilgmwvKjhMW iS86Z91ndcBLoiGscaJdW6CU0bZbvPgAHfN4V5kvifrVedMoQOsfXSiP03qcNCio4w OkxyssvqDW9K9me9exE0lZhd0anMCf1BfBWpscAVVZiu9tnU2RGQKVey8+83+tb77u wl32pqTGEusPbUdOQaJR5wR2BZ9YrqJPJgIxWxfpyRWNwhEFUtlHPAiTgBXdYnbu9T Rk5Dp1dOgzQwQ6a+OxIXOQpiDWwmMEwJPiqv5VwJvlXAMC4+UVhWUs/yHAR+7TUyDK sQMcguAxTxJhw== From: Benjamin Tissoires Date: Tue, 01 Oct 2024 16:30:07 +0200 Subject: [PATCH HID v3 3/9] HID: core: remove one more kmemdup on .probe() Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241001-hid-bpf-hid-generic-v3-3-2ef1019468df@kernel.org> References: <20241001-hid-bpf-hid-generic-v3-0-2ef1019468df@kernel.org> In-Reply-To: <20241001-hid-bpf-hid-generic-v3-0-2ef1019468df@kernel.org> To: Jiri Kosina , Peter Hutterer , Vicki Pfau , Shuah Khan Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1727793031; l=2360; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=BHYSNYgX8pUz6K6rRtEk1le3e4BVn69IDcbXBU2DJJY=; b=QWtTy0ip2hP71iFIlzFP0MnqdWgsoM2e25eP8ptwlw17BMh9v1oszbPJEAoUfrQWcVsMQnXMQ z/HlwW1fgcGCi15vFJkJf3tv379gjDJQFslnXEKidpDxos3I7scZwv+ X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= That last kmemdup while opening the report descriptor was required to have a common kfree() on it. Move that kmemdup in the only special case it's required (if there is a .report_fixup()), and add a more elaborated check before freeing hdev->rdesc, to avoid a double free. Reviewed-by: Peter Hutterer Signed-off-by: Benjamin Tissoires --- no changes in v3 new in v2 --- drivers/hid/hid-core.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 6053e7cdc0c1..b0a22e173502 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -685,7 +685,14 @@ static void hid_close_report(struct hid_device *device) INIT_LIST_HEAD(&report_enum->report_list); } - kfree(device->rdesc); + /* + * If the HID driver had a rdesc_fixup() callback, dev->rdesc + * will be allocated by hid-core and needs to be freed. + * Otherwise, it is either equal to dev_rdesc or bpf_rdesc, in + * which cases it'll be freed later on device removal or destroy. + */ + if (device->rdesc != device->dev_rdesc && device->rdesc != device->bpf_rdesc) + kfree(device->rdesc); device->rdesc = NULL; device->rsize = 0; @@ -1214,7 +1221,6 @@ int hid_open_report(struct hid_device *device) struct hid_item item; unsigned int size; const __u8 *start; - __u8 *buf = NULL; const __u8 *end; const __u8 *next; int ret; @@ -1241,17 +1247,23 @@ int hid_open_report(struct hid_device *device) * on a copy of our report descriptor so it can * change it. */ - buf = kmemdup(start, size, GFP_KERNEL); + __u8 *buf = kmemdup(start, size, GFP_KERNEL); + if (buf == NULL) return -ENOMEM; start = device->driver->report_fixup(device, buf, &size); - } - start = kmemdup(start, size, GFP_KERNEL); - kfree(buf); - if (start == NULL) - return -ENOMEM; + /* + * The second kmemdup is required in case report_fixup() returns + * a static read-only memory, but we have no idea if that memory + * needs to be cleaned up or not at the end. + */ + start = kmemdup(start, size, GFP_KERNEL); + kfree(buf); + if (start == NULL) + return -ENOMEM; + } device->rdesc = start; device->rsize = size; From patchwork Tue Oct 1 14:30:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13818150 X-Patchwork-Delegate: jikos@jikos.cz Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 950D61C9DC1; Tue, 1 Oct 2024 14:30:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727793042; cv=none; b=jMhGzGOjONX0PU3fGSHyyXxfacDEmK+FN5XJfF9XgnwEFT6cGALeEN9U6EytNwLwdSiETiA2L29ZrqCc/I58qcEC98tUY/KrfvsdUY+Ib0gh5VZgQdrGNWKvCwMrACUFqTjhlwTxqNXHC4lrcsrNdQAF7JvQ3XScUaWsD2YWD5o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727793042; c=relaxed/simple; bh=p4g+iwuaYIPus8wrmkFnFCeAl5kqd+1zqwGl6fVXFWE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bNFUJ0K1g4TPtbBPyIuXSGlC9TEs4nU5JEsMVRVcjIEH6a4Pyt7rQlx6dqmJvDevLPjflPaC+yi11QdrL8vXCM2wuXhlaUqDGa6bqFmh0/0gLVyIidZ1T3JB9A6FJnw4orZN1uklFbsoyUIunNnvWjP+SFYovPMlUR98wSzK6ZU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ocGJRVNb; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ocGJRVNb" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 762A1C4CED2; Tue, 1 Oct 2024 14:30:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1727793042; bh=p4g+iwuaYIPus8wrmkFnFCeAl5kqd+1zqwGl6fVXFWE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ocGJRVNbFA/7E2zayrfR3BWZWLLONrKzKKdL0KHVBGcTqGOcW1JR8qvGQvdoBsNs/ B3SJQY6eDA7AIKvdFahYEHawctHYVtxfQxxBXNe77FU++LcPEqEZxj5UFHe+Zl1DmA bVH12kceqfJMDAaOTiC9oavCPvFZa1wEls5FyUOh2iqtFM+MOgP1+a/Y260mkrZd+x oHjtfUCF3c0z7JU5OWfCWA9Yu5ZYtCHlhC0zsHN3F1cdRvVE1/27PiikaGmJyI44o3 x9w7Xf+UczC7YovqooDUgm6RDSrZfih39kVt8AgqdG7SCyOtU+C+IZYi+0HxTmCjMz kyzC1XQIf9PeQ== From: Benjamin Tissoires Date: Tue, 01 Oct 2024 16:30:08 +0200 Subject: [PATCH HID v3 4/9] HID: bpf: allow write access to quirks field in struct hid_device Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241001-hid-bpf-hid-generic-v3-4-2ef1019468df@kernel.org> References: <20241001-hid-bpf-hid-generic-v3-0-2ef1019468df@kernel.org> In-Reply-To: <20241001-hid-bpf-hid-generic-v3-0-2ef1019468df@kernel.org> To: Jiri Kosina , Peter Hutterer , Vicki Pfau , Shuah Khan Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1727793031; l=2396; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=p4g+iwuaYIPus8wrmkFnFCeAl5kqd+1zqwGl6fVXFWE=; b=0kRm3zqZd8+zQST2NYsrIYpThkwG5zqfgZFhExQwrERHuSh/HaCyfCmemX11ESUk42bkYhZGz UK1NkLcQPjCDP5F6K35qIHZ1Yh0gEYTq0C7yuQxCBCXm86RNYua4PrK X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= 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 Signed-off-by: Benjamin Tissoires --- 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) { From patchwork Tue Oct 1 14:30:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13818151 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 930E61C9DF7; Tue, 1 Oct 2024 14:30:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727793044; cv=none; b=LvSxVAqdz6vDDoCsQzJDFhpoFjrtcnCFLKmhUNTt6My4pEwl0SkN5OsRGHzCY/7W+V1Yqp1r/bdqxuzWBxm8fL/KNVBaDbFP9dvgkfngeIo85LHNTlhiLpoOVMWFp60Voyb0BM6sHQCD1ptsRi2svWDF63NlG07PQZpvUze2wpg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727793044; c=relaxed/simple; bh=wppJWxa4PFXTMDnMvcUDcgs5QXEfPQihMd/UMsAYQnM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=K0vS0AlUoFz+FeNZ9dGpFq8J2RiNlI/Qb339geDvBrwZfVAmkOm3gr4qT/1PHJ+SEho8ZgvS3KvYy+dFD12GQaQwU4QKt51vATimvAqy+sxTbsUS+MI2OF+P8vWkPQNSKfS+xZtK+a3whwS0z2Qmg2HfrfRwQTCOk31P78opX8k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gEKNRWdx; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gEKNRWdx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 84FB7C4CECD; Tue, 1 Oct 2024 14:30:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1727793044; bh=wppJWxa4PFXTMDnMvcUDcgs5QXEfPQihMd/UMsAYQnM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=gEKNRWdxYzYHRy857+So3PX971QEacnV+kalQirmVQtwmB/GgEz1+jZSrfgr2Q0cc 5vw85v0n+0DBl53vv/LCubXGZknzKn/DemtEafSMngj0lXBEAuOS4iafi+35Rw/bgC NFZn1P3ITtOuiKhqr06wyJNKxzMUn7EsnEbUKdMVqhxX1EsVS9e1QHLlvNRdp+VD+L COdQgzVzQ6OvtZOdTdXuZvdRbcKnoBbvVSVUFNPIlIxCDmi0sRHmQbKuLvAfRO3bjZ N9S1EJtwHf/n/3ezySkPC+LZYh1vw3gYkJKAGnWCZlPtiZHVC1Obe7NQXhMJwbGrrR dsS+MoZBthOCw== From: Benjamin Tissoires Date: Tue, 01 Oct 2024 16:30:09 +0200 Subject: [PATCH HID v3 5/9] selftests/hid: add dependency on hid_common.h Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241001-hid-bpf-hid-generic-v3-5-2ef1019468df@kernel.org> References: <20241001-hid-bpf-hid-generic-v3-0-2ef1019468df@kernel.org> In-Reply-To: <20241001-hid-bpf-hid-generic-v3-0-2ef1019468df@kernel.org> To: Jiri Kosina , Peter Hutterer , Vicki Pfau , Shuah Khan Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1727793031; l=930; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=wppJWxa4PFXTMDnMvcUDcgs5QXEfPQihMd/UMsAYQnM=; b=rjXl7WAjtkJLDaKCTw/ol1V+kbo32YqLl98rzMd6rvDUWssLGFbCu3LUW9QPdM7HamkIJHVF8 UPp/jXMQgYwAbB4tUPZU6YjOKDz9ygARimiGvHfBbWcHRaIUAsF44fb X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Allows to recompile the C tests when that file changes Reviewed-by: Peter Hutterer Signed-off-by: Benjamin Tissoires --- no changes in v3 no changes in v2 --- tools/testing/selftests/hid/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/hid/Makefile b/tools/testing/selftests/hid/Makefile index 72be55ac4bdf..9399fa3f2f9d 100644 --- a/tools/testing/selftests/hid/Makefile +++ b/tools/testing/selftests/hid/Makefile @@ -229,7 +229,7 @@ $(BPF_SKELS): %.skel.h: %.bpf.o $(BPFTOOL) | $(OUTPUT) $(Q)$(BPFTOOL) gen object $(<:.o=.linked1.o) $< $(Q)$(BPFTOOL) gen skeleton $(<:.o=.linked1.o) name $(notdir $(<:.bpf.o=)) > $@ -$(OUTPUT)/%.o: %.c $(BPF_SKELS) +$(OUTPUT)/%.o: %.c $(BPF_SKELS) hid_common.h $(call msg,CC,,$@) $(Q)$(CC) $(CFLAGS) -c $(filter %.c,$^) $(LDLIBS) -o $@ From patchwork Tue Oct 1 14:30:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13818152 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DD0BD1C9ECF; Tue, 1 Oct 2024 14:30:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727793047; cv=none; b=lDf1/WRPnpMa7x/KvZc7TIud8tjutULUYhV3gpEndFAo+rfPAe4PyBuk2dUAnTYwioO3gOv7oN2chFi9MberjtNbqwI6VmrszoD93GYdSJ58IFd12dwbU33FFKSDwEDAtWcf7MTlwhCMw+Be7bUmoF3+ShM27ZausrWSnNeYb0A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727793047; c=relaxed/simple; bh=CH+wScTa8GUFCNj8ufwkCTAXrmWWHcXN4sx7aLuS5n4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Qna3wDS29+qioaSp3DporJxwsPXYDYBvLAbkw03+u3ZB1oULPjmVqXdCl19RL1mLhsOI3CHaDtNPbadZyiHlmrdY2qN7F6T7YtwVwOe2rilacfjgIDG8AVjMFqnvCKOBd6IuahmpFfUWG/I3o1THukdx/vZSPeseOiZb/h0qLxM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TY513gcW; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="TY513gcW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 93FEFC4CED3; Tue, 1 Oct 2024 14:30:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1727793046; bh=CH+wScTa8GUFCNj8ufwkCTAXrmWWHcXN4sx7aLuS5n4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=TY513gcWN/Fd2JcO9du7Qucy38llPv6gzjKk8xnOEVDPaBhgr9a7ojy9+BUjWefv7 X81Eoo7mxfbV2dww7vVuQZcWHHoXGWPM4iCcRVeosvWij/bGs/ug1uWQMPKMhjXBmo pEo9y03dOHgoGq/2vQ5AmsuCHUXWpL5ENworT++e9IvCBHm90IgKAOTJAtZVdsxtYx L0ohS/+EEJKmlusHGbhiWCdydSefR9goXuLtNYVDpAKKwmoSp/INljZQilEpS1WWzf L/LkbShMI0+U6tX5i5wmQw9AEr8O3lNJTLGpPbEHQWAW4+F8QGm1GwDZECS1DBcfU4 nibyGFBJKp+Kw== From: Benjamin Tissoires Date: Tue, 01 Oct 2024 16:30:10 +0200 Subject: [PATCH HID v3 6/9] selftests/hid: cleanup C tests by adding a common struct uhid_device Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241001-hid-bpf-hid-generic-v3-6-2ef1019468df@kernel.org> References: <20241001-hid-bpf-hid-generic-v3-0-2ef1019468df@kernel.org> In-Reply-To: <20241001-hid-bpf-hid-generic-v3-0-2ef1019468df@kernel.org> To: Jiri Kosina , Peter Hutterer , Vicki Pfau , Shuah Khan Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1727793031; l=15763; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=CH+wScTa8GUFCNj8ufwkCTAXrmWWHcXN4sx7aLuS5n4=; b=3OSWOpQEfHBzN6E1bn7hgzjT2ASsWY8CLWeu4Hv6Xyc7L2U/jO5exwgVBqzRAo1VoDehEWDLu h1L4CJRSyGkCg84NAPjeaKVti+1PyDAUnnJzXXbITqfrDZVeUnvpBmA X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Allows to have an abstract class uhid_device which handles all of the uhid part without having to mess up with individual fds. struct attach_prog_args is now never used in hid_bpf.c, so drop it as well Signed-off-by: Benjamin Tissoires --- no changes in v3 no changes in v2 --- tools/testing/selftests/hid/hid_bpf.c | 77 +++++++++++--------------------- tools/testing/selftests/hid/hid_common.h | 74 ++++++++++++++++++++---------- tools/testing/selftests/hid/hidraw.c | 36 +++++---------- 3 files changed, 87 insertions(+), 100 deletions(-) diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c index 86f4d66379f7..31ff92e0debd 100644 --- a/tools/testing/selftests/hid/hid_bpf.c +++ b/tools/testing/selftests/hid/hid_bpf.c @@ -4,13 +4,6 @@ #include "hid_common.h" #include -struct attach_prog_args { - int prog_fd; - unsigned int hid; - int retval; - int insert_head; -}; - struct hid_hw_request_syscall_args { __u8 data[10]; unsigned int hid; @@ -21,11 +14,8 @@ struct hid_hw_request_syscall_args { }; FIXTURE(hid_bpf) { - int dev_id; - int uhid_fd; + struct uhid_device hid; int hidraw_fd; - int hid_id; - pthread_t tid; struct hid *skel; struct bpf_link *hid_links[3]; /* max number of programs loaded in a single test */ }; @@ -54,10 +44,10 @@ static void detach_bpf(FIXTURE_DATA(hid_bpf) * self) FIXTURE_TEARDOWN(hid_bpf) { void *uhid_err; - uhid_destroy(_metadata, self->uhid_fd); + uhid_destroy(_metadata, &self->hid); detach_bpf(self); - pthread_join(self->tid, &uhid_err); + pthread_join(self->hid.tid, &uhid_err); } #define TEARDOWN_LOG(fmt, ...) do { \ TH_LOG(fmt, ##__VA_ARGS__); \ @@ -66,23 +56,10 @@ FIXTURE_TEARDOWN(hid_bpf) { FIXTURE_SETUP(hid_bpf) { - time_t t; int err; - /* initialize random number generator */ - srand((unsigned int)time(&t)); - - self->dev_id = rand() % 1024; - - self->uhid_fd = setup_uhid(_metadata, self->dev_id); - - /* locate the uev, self, variant);ent file of the created device */ - self->hid_id = get_hid_id(self->dev_id); - ASSERT_GT(self->hid_id, 0) - TEARDOWN_LOG("Could not locate uhid device id: %d", self->hid_id); - - err = uhid_start_listener(_metadata, &self->tid, self->uhid_fd); - ASSERT_EQ(0, err) TEARDOWN_LOG("could not start udev listener: %d", err); + err = setup_uhid(_metadata, &self->hid); + ASSERT_OK(err); } struct test_program { @@ -129,7 +106,7 @@ static void load_programs(const struct test_program programs[], ops_hid_id = bpf_map__initial_value(map, NULL); ASSERT_OK_PTR(ops_hid_id) TH_LOG("unable to retrieve struct_ops data"); - *ops_hid_id = self->hid_id; + *ops_hid_id = self->hid.hid_id; } /* we disable the auto-attach feature of all maps because we @@ -157,7 +134,7 @@ static void load_programs(const struct test_program programs[], hid__attach(self->skel); - self->hidraw_fd = open_hidraw(self->dev_id); + self->hidraw_fd = open_hidraw(&self->hid); ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw"); } @@ -192,7 +169,7 @@ TEST_F(hid_bpf, raw_event) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* check that hid_first_event() was executed */ ASSERT_EQ(self->skel->data->callback_check, 42) TH_LOG("callback_check1"); @@ -208,7 +185,7 @@ TEST_F(hid_bpf, raw_event) memset(buf, 0, sizeof(buf)); buf[0] = 1; buf[1] = 47; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* check that hid_first_event() was executed */ ASSERT_EQ(self->skel->data->callback_check, 47) TH_LOG("callback_check1"); @@ -239,7 +216,7 @@ TEST_F(hid_bpf, subprog_raw_event) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -252,7 +229,7 @@ TEST_F(hid_bpf, subprog_raw_event) memset(buf, 0, sizeof(buf)); buf[0] = 1; buf[1] = 47; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -303,7 +280,7 @@ TEST_F(hid_bpf, test_attach_detach) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -326,14 +303,14 @@ TEST_F(hid_bpf, test_attach_detach) /* detach the program */ detach_bpf(self); - self->hidraw_fd = open_hidraw(self->dev_id); + self->hidraw_fd = open_hidraw(&self->hid); ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw"); /* inject another event */ memset(buf, 0, sizeof(buf)); buf[0] = 1; buf[1] = 47; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -352,7 +329,7 @@ TEST_F(hid_bpf, test_attach_detach) memset(buf, 0, sizeof(buf)); buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -382,7 +359,7 @@ TEST_F(hid_bpf, test_hid_change_report) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -412,7 +389,7 @@ TEST_F(hid_bpf, test_hid_user_input_report_call) LOAD_BPF; - args.hid = self->hid_id; + args.hid = self->hid.hid_id; args.data[0] = 1; /* report ID */ args.data[1] = 2; /* report ID */ args.data[2] = 42; /* report ID */ @@ -458,7 +435,7 @@ TEST_F(hid_bpf, test_hid_user_output_report_call) LOAD_BPF; - args.hid = self->hid_id; + args.hid = self->hid.hid_id; args.data[0] = 1; /* report ID */ args.data[1] = 2; /* report ID */ args.data[2] = 42; /* report ID */ @@ -506,7 +483,7 @@ TEST_F(hid_bpf, test_hid_user_raw_request_call) LOAD_BPF; - args.hid = self->hid_id; + args.hid = self->hid.hid_id; args.data[0] = 1; /* report ID */ prog_fd = bpf_program__fd(self->skel->progs.hid_user_raw_request); @@ -539,7 +516,7 @@ TEST_F(hid_bpf, test_hid_filter_raw_request_call) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -565,7 +542,7 @@ TEST_F(hid_bpf, test_hid_filter_raw_request_call) /* detach the program */ detach_bpf(self); - self->hidraw_fd = open_hidraw(self->dev_id); + self->hidraw_fd = open_hidraw(&self->hid); ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw"); err = ioctl(self->hidraw_fd, HIDIOCGFEATURE(sizeof(buf)), buf); @@ -641,7 +618,7 @@ TEST_F(hid_bpf, test_hid_filter_output_report_call) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -667,7 +644,7 @@ TEST_F(hid_bpf, test_hid_filter_output_report_call) /* detach the program */ detach_bpf(self); - self->hidraw_fd = open_hidraw(self->dev_id); + self->hidraw_fd = open_hidraw(&self->hid); ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw"); err = write(self->hidraw_fd, buf, 3); @@ -742,7 +719,7 @@ TEST_F(hid_bpf, test_multiply_events_wq) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -780,7 +757,7 @@ TEST_F(hid_bpf, test_multiply_events) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -816,7 +793,7 @@ TEST_F(hid_bpf, test_hid_infinite_loop_input_report_call) buf[1] = 2; buf[2] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -867,7 +844,7 @@ TEST_F(hid_bpf, test_hid_attach_flags) /* inject one event */ buf[0] = 1; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); diff --git a/tools/testing/selftests/hid/hid_common.h b/tools/testing/selftests/hid/hid_common.h index f151f151a1ed..a7d836a35bb1 100644 --- a/tools/testing/selftests/hid/hid_common.h +++ b/tools/testing/selftests/hid/hid_common.h @@ -19,6 +19,13 @@ __typeof__(b) _b = (b); \ _a < _b ? _a : _b; }) +struct uhid_device { + int dev_id; /* uniq (random) number to identify the device */ + int uhid_fd; + int hid_id; /* HID device id in the system */ + pthread_t tid; /* thread for reading uhid events */ +}; + static unsigned char rdesc[] = { 0x06, 0x00, 0xff, /* Usage Page (Vendor Defined Page 1) */ 0x09, 0x21, /* Usage (Vendor Usage 0x21) */ @@ -146,14 +153,14 @@ static int uhid_create(struct __test_metadata *_metadata, int fd, int rand_nb) return uhid_write(_metadata, fd, &ev); } -static void uhid_destroy(struct __test_metadata *_metadata, int fd) +static void uhid_destroy(struct __test_metadata *_metadata, struct uhid_device *hid) { struct uhid_event ev; memset(&ev, 0, sizeof(ev)); ev.type = UHID_DESTROY; - uhid_write(_metadata, fd, &ev); + uhid_write(_metadata, hid->uhid_fd, &ev); } static int uhid_event(struct __test_metadata *_metadata, int fd) @@ -281,7 +288,8 @@ static int uhid_start_listener(struct __test_metadata *_metadata, pthread_t *tid return 0; } -static int uhid_send_event(struct __test_metadata *_metadata, int fd, __u8 *buf, size_t size) +static int uhid_send_event(struct __test_metadata *_metadata, struct uhid_device *hid, + __u8 *buf, size_t size) { struct uhid_event ev; @@ -294,25 +302,7 @@ static int uhid_send_event(struct __test_metadata *_metadata, int fd, __u8 *buf, memcpy(ev.u.input2.data, buf, size); - return uhid_write(_metadata, fd, &ev); -} - -static int setup_uhid(struct __test_metadata *_metadata, int rand_nb) -{ - int fd; - const char *path = "/dev/uhid"; - int ret; - - fd = open(path, O_RDWR | O_CLOEXEC); - ASSERT_GE(fd, 0) TH_LOG("open uhid-cdev failed; %d", fd); - - ret = uhid_create(_metadata, fd, rand_nb); - ASSERT_EQ(0, ret) { - TH_LOG("create uhid device failed: %d", ret); - close(fd); - } - - return fd; + return uhid_write(_metadata, hid->uhid_fd, &ev); } static bool match_sysfs_device(int dev_id, const char *workdir, struct dirent *dir) @@ -421,12 +411,12 @@ static int get_hidraw(int dev_id) return found; } -static int open_hidraw(int dev_id) +static int open_hidraw(struct uhid_device *hid) { int hidraw_number; char hidraw_path[64] = { 0 }; - hidraw_number = get_hidraw(dev_id); + hidraw_number = get_hidraw(hid->dev_id); if (hidraw_number < 0) return hidraw_number; @@ -434,3 +424,39 @@ static int open_hidraw(int dev_id) sprintf(hidraw_path, "/dev/hidraw%d", hidraw_number); return open(hidraw_path, O_RDWR | O_NONBLOCK); } + +static int setup_uhid(struct __test_metadata *_metadata, struct uhid_device *hid) +{ + const char *path = "/dev/uhid"; + time_t t; + int ret; + + /* initialize random number generator */ + srand((unsigned int)time(&t)); + + hid->dev_id = rand() % 1024; + + hid->uhid_fd = open(path, O_RDWR | O_CLOEXEC); + ASSERT_GE(hid->uhid_fd, 0) TH_LOG("open uhid-cdev failed; %d", hid->uhid_fd); + + ret = uhid_create(_metadata, hid->uhid_fd, hid->dev_id); + ASSERT_EQ(0, ret) { + TH_LOG("create uhid device failed: %d", ret); + close(hid->uhid_fd); + return ret; + } + + /* locate the uevent file of the created device */ + hid->hid_id = get_hid_id(hid->dev_id); + ASSERT_GT(hid->hid_id, 0) + TH_LOG("Could not locate uhid device id: %d", hid->hid_id); + + ret = uhid_start_listener(_metadata, &hid->tid, hid->uhid_fd); + ASSERT_EQ(0, ret) { + TH_LOG("could not start udev listener: %d", ret); + close(hid->uhid_fd); + return ret; + } + + return 0; +} diff --git a/tools/testing/selftests/hid/hidraw.c b/tools/testing/selftests/hid/hidraw.c index f8b4f7ff292c..5934818b2036 100644 --- a/tools/testing/selftests/hid/hidraw.c +++ b/tools/testing/selftests/hid/hidraw.c @@ -9,11 +9,8 @@ #endif /* HIDIOCREVOKE */ FIXTURE(hidraw) { - int dev_id; - int uhid_fd; + struct uhid_device hid; int hidraw_fd; - int hid_id; - pthread_t tid; }; static void close_hidraw(FIXTURE_DATA(hidraw) * self) { @@ -25,10 +22,10 @@ static void close_hidraw(FIXTURE_DATA(hidraw) * self) FIXTURE_TEARDOWN(hidraw) { void *uhid_err; - uhid_destroy(_metadata, self->uhid_fd); + uhid_destroy(_metadata, &self->hid); close_hidraw(self); - pthread_join(self->tid, &uhid_err); + pthread_join(self->hid.tid, &uhid_err); } #define TEARDOWN_LOG(fmt, ...) do { \ TH_LOG(fmt, ##__VA_ARGS__); \ @@ -37,25 +34,12 @@ FIXTURE_TEARDOWN(hidraw) { FIXTURE_SETUP(hidraw) { - time_t t; int err; - /* initialize random number generator */ - srand((unsigned int)time(&t)); + err = setup_uhid(_metadata, &self->hid); + ASSERT_OK(err); - self->dev_id = rand() % 1024; - - self->uhid_fd = setup_uhid(_metadata, self->dev_id); - - /* locate the uev, self, variant);ent file of the created device */ - self->hid_id = get_hid_id(self->dev_id); - ASSERT_GT(self->hid_id, 0) - TEARDOWN_LOG("Could not locate uhid device id: %d", self->hid_id); - - err = uhid_start_listener(_metadata, &self->tid, self->uhid_fd); - ASSERT_EQ(0, err) TEARDOWN_LOG("could not start udev listener: %d", err); - - self->hidraw_fd = open_hidraw(self->dev_id); + self->hidraw_fd = open_hidraw(&self->hid); ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw"); } @@ -79,7 +63,7 @@ TEST_F(hidraw, raw_event) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -101,7 +85,7 @@ TEST_F(hidraw, raw_event_revoked) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -117,7 +101,7 @@ TEST_F(hidraw, raw_event_revoked) /* inject one other event */ buf[0] = 1; buf[1] = 43; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -161,7 +145,7 @@ TEST_F(hidraw, poll_revoked) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); while (true) { ready = poll(pfds, 1, 5000); From patchwork Tue Oct 1 14:30:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13818153 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9DB491CB320; Tue, 1 Oct 2024 14:30:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727793048; cv=none; b=nJuNs1VZsu27Yy/pe6at5zYW6BWp/+s00ebim1h+4q1qLIAs5NwiYjVlOEUkO78ttEjNnKefwA5TdymhQIFi9gu51AfCVULE+Owmr5iouveCVMmJvC00z5wiq909sevxN48r3zj1WALdZzdzu9VwgdlCdgaNKX49rI4Z3QiCCLQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727793048; c=relaxed/simple; bh=Zq08hvXmwry7CvfCYsPH7jmFtsXQ5Ycau0/tGo4Jgfc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QhCYznG033/fAP4OlCYryzKnsDsQGNbKFDTsH9PlJd8ek/+k7mUjv3Ogh4WMIEl3ao1q8b30vT5lJvc0agYDT04PgF/hXm0fp6ntM4TBSBa4zJva2xtUIpIu4NOEFcZ1huq13jUIGvAlaJl/5zQ9zCJgDigwmy0OC/Bx+pvOES0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cbfVbkTf; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cbfVbkTf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CE286C4CEC7; Tue, 1 Oct 2024 14:30:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1727793048; bh=Zq08hvXmwry7CvfCYsPH7jmFtsXQ5Ycau0/tGo4Jgfc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=cbfVbkTfrdspMX/kgUYNr3mhsdMe7YYqzbQOYoFup3XKnCLWJ3cM3gcADwGPwnOls ysSQJVmpQqqcGSyDf3FWqvekSSicdH0zP+gAayhy1780sSx1WHFXA+KUg7G+kvK3YH 17F/sMp5hSgVdUxE/JjDYd3aWgUtVVJ7ELMiA+CEZwDFtBLTe3AS+jmm/Wyw62JuGi vg0jhNIggAyMZV0rvMbQv2ZfeTBxuiFoHl/kZclBaX7ycqtfog2Be+ZfXaX3Nn/Jx1 N1rCaZECfuhypDYFIQhK7yEAm/ZHR6fN86q4sAXHyHEdj0c1yoGqjDcJVCfVvNRnFa 3wYpDL9pKGcfQ== From: Benjamin Tissoires Date: Tue, 01 Oct 2024 16:30:11 +0200 Subject: [PATCH HID v3 7/9] selftests/hid: allow to parametrize bus/vid/pid/rdesc on the test device Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241001-hid-bpf-hid-generic-v3-7-2ef1019468df@kernel.org> References: <20241001-hid-bpf-hid-generic-v3-0-2ef1019468df@kernel.org> In-Reply-To: <20241001-hid-bpf-hid-generic-v3-0-2ef1019468df@kernel.org> To: Jiri Kosina , Peter Hutterer , Vicki Pfau , Shuah Khan Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1727793031; l=6827; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=Zq08hvXmwry7CvfCYsPH7jmFtsXQ5Ycau0/tGo4Jgfc=; b=Gvp+Grj928N8IfRraiVwY83EyIJCUiGGFqiQ7R2h5P+xtVUrxY0wrO2FHvQ/HAIYAVFfWBspU YVz0avOP8rVA6dFpTkqmEEgMWE1IZwSdgjeJfKfuIef0SSqLlc28X4+ X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= This will be useful to introduce variants in tests to test the interactions between HID-BPF and some kernel modules. Reviewed-by: Peter Hutterer Signed-off-by: Benjamin Tissoires --- no changes in v3 no changes in v2 --- tools/testing/selftests/hid/hid_bpf.c | 2 +- tools/testing/selftests/hid/hid_common.h | 46 ++++++++++++++++++++------------ tools/testing/selftests/hid/hidraw.c | 2 +- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c index 31ff92e0debd..1e979fb3542b 100644 --- a/tools/testing/selftests/hid/hid_bpf.c +++ b/tools/testing/selftests/hid/hid_bpf.c @@ -58,7 +58,7 @@ FIXTURE_SETUP(hid_bpf) { int err; - err = setup_uhid(_metadata, &self->hid); + err = setup_uhid(_metadata, &self->hid, BUS_USB, 0x0001, 0x0a36, rdesc, sizeof(rdesc)); ASSERT_OK(err); } diff --git a/tools/testing/selftests/hid/hid_common.h b/tools/testing/selftests/hid/hid_common.h index a7d836a35bb1..f77f69c6657d 100644 --- a/tools/testing/selftests/hid/hid_common.h +++ b/tools/testing/selftests/hid/hid_common.h @@ -23,6 +23,9 @@ struct uhid_device { int dev_id; /* uniq (random) number to identify the device */ int uhid_fd; int hid_id; /* HID device id in the system */ + __u16 bus; + __u32 vid; + __u32 pid; pthread_t tid; /* thread for reading uhid events */ }; @@ -129,7 +132,9 @@ static int uhid_write(struct __test_metadata *_metadata, int fd, const struct uh } } -static int uhid_create(struct __test_metadata *_metadata, int fd, int rand_nb) +static int uhid_create(struct __test_metadata *_metadata, int fd, int rand_nb, + __u16 bus, __u32 vid, __u32 pid, __u8 *rdesc, + size_t rdesc_size) { struct uhid_event ev; char buf[25]; @@ -140,10 +145,10 @@ static int uhid_create(struct __test_metadata *_metadata, int fd, int rand_nb) ev.type = UHID_CREATE; strcpy((char *)ev.u.create.name, buf); ev.u.create.rd_data = rdesc; - ev.u.create.rd_size = sizeof(rdesc); - ev.u.create.bus = BUS_USB; - ev.u.create.vendor = 0x0001; - ev.u.create.product = 0x0a37; + ev.u.create.rd_size = rdesc_size; + ev.u.create.bus = bus; + ev.u.create.vendor = vid; + ev.u.create.product = pid; ev.u.create.version = 0; ev.u.create.country = 0; @@ -305,15 +310,17 @@ static int uhid_send_event(struct __test_metadata *_metadata, struct uhid_device return uhid_write(_metadata, hid->uhid_fd, &ev); } -static bool match_sysfs_device(int dev_id, const char *workdir, struct dirent *dir) +static bool match_sysfs_device(struct uhid_device *hid, const char *workdir, struct dirent *dir) { - const char *target = "0003:0001:0A37.*"; + char target[20] = ""; char phys[512]; char uevent[1024]; char temp[512]; int fd, nread; bool found = false; + snprintf(target, sizeof(target), "%04X:%04X:%04X.*", hid->bus, hid->vid, hid->pid); + if (fnmatch(target, dir->d_name, 0)) return false; @@ -324,7 +331,7 @@ static bool match_sysfs_device(int dev_id, const char *workdir, struct dirent *d if (fd < 0) return false; - sprintf(phys, "PHYS=%d", dev_id); + sprintf(phys, "PHYS=%d", hid->dev_id); nread = read(fd, temp, ARRAY_SIZE(temp)); if (nread > 0 && (strstr(temp, phys)) != NULL) @@ -335,7 +342,7 @@ static bool match_sysfs_device(int dev_id, const char *workdir, struct dirent *d return found; } -static int get_hid_id(int dev_id) +static int get_hid_id(struct uhid_device *hid) { const char *workdir = "/sys/devices/virtual/misc/uhid"; const char *str_id; @@ -350,10 +357,10 @@ static int get_hid_id(int dev_id) d = opendir(workdir); if (d) { while ((dir = readdir(d)) != NULL) { - if (!match_sysfs_device(dev_id, workdir, dir)) + if (!match_sysfs_device(hid, workdir, dir)) continue; - str_id = dir->d_name + sizeof("0003:0001:0A37."); + str_id = dir->d_name + sizeof("0000:0000:0000."); found = (int)strtol(str_id, NULL, 16); break; @@ -367,7 +374,7 @@ static int get_hid_id(int dev_id) return found; } -static int get_hidraw(int dev_id) +static int get_hidraw(struct uhid_device *hid) { const char *workdir = "/sys/devices/virtual/misc/uhid"; char sysfs[1024]; @@ -384,7 +391,7 @@ static int get_hidraw(int dev_id) continue; while ((dir = readdir(d)) != NULL) { - if (!match_sysfs_device(dev_id, workdir, dir)) + if (!match_sysfs_device(hid, workdir, dir)) continue; sprintf(sysfs, "%s/%s/hidraw", workdir, dir->d_name); @@ -416,7 +423,7 @@ static int open_hidraw(struct uhid_device *hid) int hidraw_number; char hidraw_path[64] = { 0 }; - hidraw_number = get_hidraw(hid->dev_id); + hidraw_number = get_hidraw(hid); if (hidraw_number < 0) return hidraw_number; @@ -425,7 +432,8 @@ static int open_hidraw(struct uhid_device *hid) return open(hidraw_path, O_RDWR | O_NONBLOCK); } -static int setup_uhid(struct __test_metadata *_metadata, struct uhid_device *hid) +static int setup_uhid(struct __test_metadata *_metadata, struct uhid_device *hid, + __u16 bus, __u32 vid, __u32 pid, const __u8 *rdesc, size_t rdesc_size) { const char *path = "/dev/uhid"; time_t t; @@ -435,11 +443,15 @@ static int setup_uhid(struct __test_metadata *_metadata, struct uhid_device *hid srand((unsigned int)time(&t)); hid->dev_id = rand() % 1024; + hid->bus = bus; + hid->vid = vid; + hid->pid = pid; hid->uhid_fd = open(path, O_RDWR | O_CLOEXEC); ASSERT_GE(hid->uhid_fd, 0) TH_LOG("open uhid-cdev failed; %d", hid->uhid_fd); - ret = uhid_create(_metadata, hid->uhid_fd, hid->dev_id); + ret = uhid_create(_metadata, hid->uhid_fd, hid->dev_id, bus, vid, pid, + (__u8 *)rdesc, rdesc_size); ASSERT_EQ(0, ret) { TH_LOG("create uhid device failed: %d", ret); close(hid->uhid_fd); @@ -447,7 +459,7 @@ static int setup_uhid(struct __test_metadata *_metadata, struct uhid_device *hid } /* locate the uevent file of the created device */ - hid->hid_id = get_hid_id(hid->dev_id); + hid->hid_id = get_hid_id(hid); ASSERT_GT(hid->hid_id, 0) TH_LOG("Could not locate uhid device id: %d", hid->hid_id); diff --git a/tools/testing/selftests/hid/hidraw.c b/tools/testing/selftests/hid/hidraw.c index 5934818b2036..821db37ba4bb 100644 --- a/tools/testing/selftests/hid/hidraw.c +++ b/tools/testing/selftests/hid/hidraw.c @@ -36,7 +36,7 @@ FIXTURE_SETUP(hidraw) { int err; - err = setup_uhid(_metadata, &self->hid); + err = setup_uhid(_metadata, &self->hid, BUS_USB, 0x0001, 0x0a37, rdesc, sizeof(rdesc)); ASSERT_OK(err); self->hidraw_fd = open_hidraw(&self->hid); From patchwork Tue Oct 1 14:30:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13818154 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ED3591CB50A; Tue, 1 Oct 2024 14:30:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727793051; cv=none; b=gD9sXh8lN+05A+Oom+mXwfnsRnmmw2UpbSUEfaDK/74NOYUXFMtQvSEUEIGffw9kYgbjw10V3BQdb4CN5kmxlnvg5rMLldaF5bgaZjtttMENQEcfLHuMrUThcgN/Y3TGNYYnoaGkowtay5w7eBnjotHyEk1GbSKHWIVKIpkFOkc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727793051; c=relaxed/simple; bh=DRRfheB9mdrcUWe1w3swekqPJusrinGNe3sPZf+1eEg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eyzWPHn/v/xsGfwCcUZCxVID1TldOFWrVZLFPKgC6uCCKyBVoH8Q938Qi3QGdseYlZlSqTGKJZQQld4fXLTYCED3kc8fRV+lGgYU4ZniowtUL2lx/da6MFOT6s0GOuCzoOq0yEYv9Erv8+27J2kNzhBcM0ktBLYwZjiVIYCdsrg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YgBYwi3v; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="YgBYwi3v" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DD2DAC4CED2; Tue, 1 Oct 2024 14:30:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1727793050; bh=DRRfheB9mdrcUWe1w3swekqPJusrinGNe3sPZf+1eEg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=YgBYwi3vvdRd3vAH0VmHpG5S5b2qbg8k3rYxHhfrzabDAebeyd8Ipcapyw9eliveP 6JRHGpmt/4utyuaR/EOCr89gzgpkaxMqdpbVIuZu6aCZvuVl6I/qc6mP5THACRvgmn rAtzdF3Yca8mWA4IQ6FaPOCbBNCpJhScE8ftYf3aN2Tf3YetXeuzaQIg4HF4j+RTS4 CNzSP5bpurBPiTtRYnehtGQGGVwJnufGuiwJdGW94IyHcD7ztbz4RrCjJDrlnHGDYe hDTphp7Spjz8xa9MJv3heJyY6nkNuilra7r5IpQKlYJUn79x64Ct3ngIXfYr8uM9Bf bsEvDgUjpRrgg== From: Benjamin Tissoires Date: Tue, 01 Oct 2024 16:30:12 +0200 Subject: [PATCH HID v3 8/9] HID: add per device quirk to force bind to hid-generic Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241001-hid-bpf-hid-generic-v3-8-2ef1019468df@kernel.org> References: <20241001-hid-bpf-hid-generic-v3-0-2ef1019468df@kernel.org> In-Reply-To: <20241001-hid-bpf-hid-generic-v3-0-2ef1019468df@kernel.org> To: Jiri Kosina , Peter Hutterer , Vicki Pfau , Shuah Khan Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1727793031; l=2784; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=DRRfheB9mdrcUWe1w3swekqPJusrinGNe3sPZf+1eEg=; b=zc7qGrFJZPV8iY+dFZC1So+CsgImJ4yBf4MfFymlT1MpL4v5gVOkFM8qPlKN/2cJvfUpopmT2 uRq6gCl4j7ECbTB4TddXZ3QyhrNiGS1kGk6iQZOi/2AXnc9GaFS8Pfu X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= We already have the possibility to force not binding to hid-generic and rely on a dedicated driver, but we couldn't do the other way around. This is useful for BPF programs where we are fixing the report descriptor and the events, but want to avoid a specialized driver to come after BPF which would unwind everything that is done there. Reviewed-by: Peter Hutterer Signed-off-by: Benjamin Tissoires --- no changes in v3 changes in v2: - rely on hdev->quirks for that instead of a new struct for hid_driver --- drivers/hid/hid-core.c | 5 +++-- drivers/hid/hid-generic.c | 3 +++ include/linux/hid.h | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 8e879937e956..f1c23b21e96a 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2698,9 +2698,10 @@ static bool hid_check_device_match(struct hid_device *hdev, /* * hid-generic implements .match(), so we must be dealing with a * different HID driver here, and can simply check if - * hid_ignore_special_drivers is set or not. + * hid_ignore_special_drivers or HID_QUIRK_IGNORE_SPECIAL_DRIVER + * are set or not. */ - return !hid_ignore_special_drivers; + return !hid_ignore_special_drivers && !(hdev->quirks & HID_QUIRK_IGNORE_SPECIAL_DRIVER); } static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv) diff --git a/drivers/hid/hid-generic.c b/drivers/hid/hid-generic.c index f9db991d3c5a..88882c1bfffe 100644 --- a/drivers/hid/hid-generic.c +++ b/drivers/hid/hid-generic.c @@ -40,6 +40,9 @@ static bool hid_generic_match(struct hid_device *hdev, if (ignore_special_driver) return true; + if (hdev->quirks & HID_QUIRK_IGNORE_SPECIAL_DRIVER) + return true; + if (hdev->quirks & HID_QUIRK_HAVE_SPECIAL_DRIVER) return false; diff --git a/include/linux/hid.h b/include/linux/hid.h index ff58b5ceb62e..63330d623335 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -359,6 +359,7 @@ struct hid_item { * | @HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP: * | @HID_QUIRK_HAVE_SPECIAL_DRIVER: * | @HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE: + * | @HID_QUIRK_IGNORE_SPECIAL_DRIVER * | @HID_QUIRK_FULLSPEED_INTERVAL: * | @HID_QUIRK_NO_INIT_REPORTS: * | @HID_QUIRK_NO_IGNORE: @@ -384,6 +385,7 @@ struct hid_item { #define HID_QUIRK_HAVE_SPECIAL_DRIVER BIT(19) #define HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE BIT(20) #define HID_QUIRK_NOINVERT BIT(21) +#define HID_QUIRK_IGNORE_SPECIAL_DRIVER BIT(22) #define HID_QUIRK_FULLSPEED_INTERVAL BIT(28) #define HID_QUIRK_NO_INIT_REPORTS BIT(29) #define HID_QUIRK_NO_IGNORE BIT(30) From patchwork Tue Oct 1 14:30:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13818155 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 509701C9ECF; Tue, 1 Oct 2024 14:30:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727793053; cv=none; b=L5Op+r/gcY5Xk+RgHEN4fj+b1+ryJjzls01NF8UNQd2bBXOaw6EGA8wCKgQem5dd2mDoUO82rOHHtz7DJQjZv+GgiBZLADEl3v8YiNPrPeRvkHLxCpkV/WKLrZTj2o9CIebSVjk0S4/aAVdWwAr3p5m+TqU61fCH5T+6OvKzbr4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727793053; c=relaxed/simple; bh=bWe1uPERq9WeUEEg+CAOQs1LYJsQbjSxO2MugJ38+v8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NtGezRSW1JXVk/vixP9ogHpydh7siBjp3tU/SZGtYOdefN71Rq+PWXnLvvszLH9YnaRLT1GisTDg9gr3541Y0kKvk3p7Rq31x/gyaPMpmW+gEbSCPESdt6BU4fPQRoCi/XmeL9EQwIqt3D5P1nOvO2PE0qRTcaLDI5+7P+uKQVE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=N+rTPkqT; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="N+rTPkqT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EE077C4CECF; Tue, 1 Oct 2024 14:30:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1727793052; bh=bWe1uPERq9WeUEEg+CAOQs1LYJsQbjSxO2MugJ38+v8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=N+rTPkqTwL7sFIq8nT2kIfiJQRiFY9Ihw5Q1+2pybATIwVDXHYtgKkr97DNk5tBtX LxQ0UdjAp5uQ9G7ru7Mt7OP6kX30YoSxv6z/Nw7I8AMBWlpL89vHpu3dMHdo757Z2g mJeiofMePs2tycfIRgdQ9N9MNV9HGLYATH86s6/qRCgUjRko2+KtjzBZ88/bOP6j6E tDIowr0t/NQUG2FDzAM09lcrJgJ+hk0Iki1DXd3BiVfBEZDqe3UXAVcq6qtca8Ki0R RgIg6VxsXvyXytSpRVQ11yfq/EinLif3We8oNQzngtj6M+s9s/8bprUMspt4BZmihp zg4xx1UfejO0w== From: Benjamin Tissoires Date: Tue, 01 Oct 2024 16:30:13 +0200 Subject: [PATCH HID v3 9/9] selftests/hid: add test for assigning a given device to hid-generic Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241001-hid-bpf-hid-generic-v3-9-2ef1019468df@kernel.org> References: <20241001-hid-bpf-hid-generic-v3-0-2ef1019468df@kernel.org> In-Reply-To: <20241001-hid-bpf-hid-generic-v3-0-2ef1019468df@kernel.org> To: Jiri Kosina , Peter Hutterer , Vicki Pfau , Shuah Khan Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1727793031; l=4767; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=bWe1uPERq9WeUEEg+CAOQs1LYJsQbjSxO2MugJ38+v8=; b=j/Sah5VRmiobJ6YNAud72gDOqr5NPfi7DsBWrEmrKJSqswTSXUJg7EpAl6C/pF/mUwwhOy8Li KpEeV/VshWvCL0nKEsEefaZP0NbkVCO7owSybytzkZoJBeR0nKJP3H3 X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= We use a well known VID/PID on a driver that doesn't need to talk to the device, ensures we created the device against the target driver, then load our program and ensure we have unbound to this driver and use hid-generic instead. Reviewed-by: Peter Hutterer Signed-off-by: Benjamin Tissoires --- no changes in v3 changes in v2: - amended for the new API --- tools/testing/selftests/hid/hid_bpf.c | 80 +++++++++++++++++++++- tools/testing/selftests/hid/progs/hid.c | 12 ++++ .../testing/selftests/hid/progs/hid_bpf_helpers.h | 6 +- 3 files changed, 96 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c index 1e979fb3542b..ca58bfa3ca65 100644 --- a/tools/testing/selftests/hid/hid_bpf.c +++ b/tools/testing/selftests/hid/hid_bpf.c @@ -54,11 +54,41 @@ FIXTURE_TEARDOWN(hid_bpf) { hid_bpf_teardown(_metadata, self, variant); \ } while (0) +struct specific_device { + const char test_name[64]; + __u16 bus; + __u32 vid; + __u32 pid; +}; + FIXTURE_SETUP(hid_bpf) { + const struct specific_device *match = NULL; int err; - err = setup_uhid(_metadata, &self->hid, BUS_USB, 0x0001, 0x0a36, rdesc, sizeof(rdesc)); + const struct specific_device devices[] = { + { + .test_name = "test_hid_driver_probe", + .bus = BUS_BLUETOOTH, + .vid = 0x05ac, /* USB_VENDOR_ID_APPLE */ + .pid = 0x022c, /* USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI */ + }, { + .test_name = "*", + .bus = BUS_USB, + .vid = 0x0001, + .pid = 0x0a36, + }}; + + for (int i = 0; i < ARRAY_SIZE(devices); i++) { + match = &devices[i]; + if (!strncmp(_metadata->name, devices[i].test_name, sizeof(devices[i].test_name))) + break; + } + + ASSERT_OK_PTR(match); + + err = setup_uhid(_metadata, &self->hid, match->bus, match->vid, match->pid, + rdesc, sizeof(rdesc)); ASSERT_OK(err); } @@ -855,6 +885,54 @@ TEST_F(hid_bpf, test_hid_attach_flags) ASSERT_EQ(buf[3], 3); } +static bool is_using_driver(struct __test_metadata *_metadata, struct uhid_device *hid, + const char *driver) +{ + char driver_line[512]; + char uevent[1024]; + char temp[512]; + int fd, nread; + bool found = false; + + sprintf(uevent, "/sys/bus/hid/devices/%04X:%04X:%04X.%04X/uevent", + hid->bus, hid->vid, hid->pid, hid->hid_id); + + fd = open(uevent, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + TH_LOG("couldn't open '%s': %d, %d", uevent, fd, errno); + return false; + } + + sprintf(driver_line, "DRIVER=%s", driver); + + nread = read(fd, temp, ARRAY_SIZE(temp)); + if (nread > 0 && (strstr(temp, driver_line)) != NULL) + found = true; + + close(fd); + + return found; +} + +/* + * Attach hid_driver_probe to the given uhid device, + * check that the device is now using hid-generic. + */ +TEST_F(hid_bpf, test_hid_driver_probe) +{ + const struct test_program progs[] = { + { + .name = "hid_test_driver_probe", + }, + }; + + ASSERT_TRUE(is_using_driver(_metadata, &self->hid, "apple")); + + LOAD_PROGRAMS(progs); + + ASSERT_TRUE(is_using_driver(_metadata, &self->hid, "hid-generic")); +} + /* * Attach hid_rdesc_fixup to the given uhid device, * retrieve and open the matching hidraw node, diff --git a/tools/testing/selftests/hid/progs/hid.c b/tools/testing/selftests/hid/progs/hid.c index 5ecc845ef792..9b22e9a0e658 100644 --- a/tools/testing/selftests/hid/progs/hid.c +++ b/tools/testing/selftests/hid/progs/hid.c @@ -598,3 +598,15 @@ SEC(".struct_ops.link") struct hid_bpf_ops test_infinite_loop_input_report = { .hid_device_event = (void *)hid_test_infinite_loop_input_report, }; + +SEC("?struct_ops.s/hid_rdesc_fixup") +int BPF_PROG(hid_test_driver_probe, struct hid_bpf_ctx *hid_ctx) +{ + hid_ctx->hid->quirks |= HID_QUIRK_IGNORE_SPECIAL_DRIVER; + return 0; +} + +SEC(".struct_ops.link") +struct hid_bpf_ops test_driver_probe = { + .hid_rdesc_fixup = (void *)hid_test_driver_probe, +}; diff --git a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h index e5db897586bb..1a645684a117 100644 --- a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h +++ b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h @@ -84,10 +84,14 @@ struct hid_bpf_ops { struct hid_device *hdev; }; +#define BIT(n) (1U << n) + #ifndef BPF_F_BEFORE -#define BPF_F_BEFORE (1U << 3) +#define BPF_F_BEFORE BIT(3) #endif +#define HID_QUIRK_IGNORE_SPECIAL_DRIVER BIT(22) + /* following are kfuncs exported by HID for HID-BPF */ extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset,