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: 832138 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-kselftest@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: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: 832137 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-kselftest@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: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: 832136 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-kselftest@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: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: 832135 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-kselftest@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: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: 832134 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-kselftest@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,