Skip to content

Commit 919464d

Browse files
committed
Revert "HID: bpf: allow write access to quirks field in struct hid_device"
This reverts commit 6fd47ef, and the related self-test update commit e14e0ea ("selftests/hid: add test for assigning a given device to hid-generic"). It results in things like the scroll wheel on Logitech mice not working after a reboot due to the kernel being confused about the state of the high-resolution mode. Quoting Benjamin Tissoires: "The idea of 6fd47ef was to be able to call hid_bpf_rdesc_fixup() once per reprobe of the device. However, because the bpf filter can now change the quirk value, the call had to be moved before the driver gets bound (which was previously ensuring the unicity of the call). The net effect is that now, in the case hid-generic gets loaded first and then the specific driver gets loaded once the disk is available, the value of ->quirks is not reset, but kept to the value that was set by hid-generic (HID_QUIRK_INPUT_PER_APP). Once hid-logitech-hidpp kicks in, that quirk is now set, which creates two inputs for the single mouse: one keyboard for fancy shortcuts, and one mouse node. However, hid-logitech-hidpp expects only one input node to be attached (it stores it into hidpp->input), and when a wheel event is received, because there is some processing with high-resolution wheel events, the wheel event is injected into hidpp->input. And of course, when HID_QUIRK_INPUT_PER_APP is set, hidpp->input gets the keyboard node, which doesn't have wheel event type, and the events are ignored" Reported-and-bisected-by: Mike Galbraith <[email protected]> Link: https://lore.kernel.org/all/CAHk-=wiUkQM3uheit2cNM0Y0OOY5qqspJgC8LkmOkJ2p2LDxcw@mail.gmail.com/ Acked-by: Benjamin Tissoires <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 9f16d5e commit 919464d

File tree

5 files changed

+4
-106
lines changed

5 files changed

+4
-106
lines changed

drivers/hid/bpf/hid_bpf_struct_ops.c

-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ static int hid_bpf_ops_btf_struct_access(struct bpf_verifier_log *log,
7979
WRITE_RANGE(hid_device, name, true),
8080
WRITE_RANGE(hid_device, uniq, true),
8181
WRITE_RANGE(hid_device, phys, true),
82-
WRITE_RANGE(hid_device, quirks, false),
8382
};
8483
#undef WRITE_RANGE
8584
const struct btf_type *state = NULL;

drivers/hid/hid-core.c

+2-9
Original file line numberDiff line numberDiff line change
@@ -2692,12 +2692,6 @@ static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv)
26922692
int ret;
26932693

26942694
if (!hdev->bpf_rsize) {
2695-
unsigned int quirks;
2696-
2697-
/* reset the quirks that has been previously set */
2698-
quirks = hid_lookup_quirk(hdev);
2699-
hdev->quirks = quirks;
2700-
27012695
/* in case a bpf program gets detached, we need to free the old one */
27022696
hid_free_bpf_rdesc(hdev);
27032697

@@ -2707,9 +2701,6 @@ static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv)
27072701
/* call_hid_bpf_rdesc_fixup will always return a valid pointer */
27082702
hdev->bpf_rdesc = call_hid_bpf_rdesc_fixup(hdev, hdev->dev_rdesc,
27092703
&hdev->bpf_rsize);
2710-
if (quirks ^ hdev->quirks)
2711-
hid_info(hdev, "HID-BPF toggled quirks on the device: %04x",
2712-
quirks ^ hdev->quirks);
27132704
}
27142705

27152706
if (!hid_check_device_match(hdev, hdrv, &id))
@@ -2719,6 +2710,8 @@ static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv)
27192710
if (!hdev->devres_group_id)
27202711
return -ENOMEM;
27212712

2713+
/* reset the quirks that has been previously set */
2714+
hdev->quirks = hid_lookup_quirk(hdev);
27222715
hdev->driver = hdrv;
27232716

27242717
if (hdrv->probe) {

tools/testing/selftests/hid/hid_bpf.c

+1-79
Original file line numberDiff line numberDiff line change
@@ -54,41 +54,11 @@ FIXTURE_TEARDOWN(hid_bpf) {
5454
hid_bpf_teardown(_metadata, self, variant); \
5555
} while (0)
5656

57-
struct specific_device {
58-
const char test_name[64];
59-
__u16 bus;
60-
__u32 vid;
61-
__u32 pid;
62-
};
63-
6457
FIXTURE_SETUP(hid_bpf)
6558
{
66-
const struct specific_device *match = NULL;
6759
int err;
6860

69-
const struct specific_device devices[] = {
70-
{
71-
.test_name = "test_hid_driver_probe",
72-
.bus = BUS_BLUETOOTH,
73-
.vid = 0x05ac, /* USB_VENDOR_ID_APPLE */
74-
.pid = 0x022c, /* USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI */
75-
}, {
76-
.test_name = "*",
77-
.bus = BUS_USB,
78-
.vid = 0x0001,
79-
.pid = 0x0a36,
80-
}};
81-
82-
for (int i = 0; i < ARRAY_SIZE(devices); i++) {
83-
match = &devices[i];
84-
if (!strncmp(_metadata->name, devices[i].test_name, sizeof(devices[i].test_name)))
85-
break;
86-
}
87-
88-
ASSERT_OK_PTR(match);
89-
90-
err = setup_uhid(_metadata, &self->hid, match->bus, match->vid, match->pid,
91-
rdesc, sizeof(rdesc));
61+
err = setup_uhid(_metadata, &self->hid, BUS_USB, 0x0001, 0x0a36, rdesc, sizeof(rdesc));
9262
ASSERT_OK(err);
9363
}
9464

@@ -885,54 +855,6 @@ TEST_F(hid_bpf, test_hid_attach_flags)
885855
ASSERT_EQ(buf[3], 3);
886856
}
887857

888-
static bool is_using_driver(struct __test_metadata *_metadata, struct uhid_device *hid,
889-
const char *driver)
890-
{
891-
char driver_line[512];
892-
char uevent[1024];
893-
char temp[512];
894-
int fd, nread;
895-
bool found = false;
896-
897-
sprintf(uevent, "/sys/bus/hid/devices/%04X:%04X:%04X.%04X/uevent",
898-
hid->bus, hid->vid, hid->pid, hid->hid_id);
899-
900-
fd = open(uevent, O_RDONLY | O_NONBLOCK);
901-
if (fd < 0) {
902-
TH_LOG("couldn't open '%s': %d, %d", uevent, fd, errno);
903-
return false;
904-
}
905-
906-
sprintf(driver_line, "DRIVER=%s", driver);
907-
908-
nread = read(fd, temp, ARRAY_SIZE(temp));
909-
if (nread > 0 && (strstr(temp, driver_line)) != NULL)
910-
found = true;
911-
912-
close(fd);
913-
914-
return found;
915-
}
916-
917-
/*
918-
* Attach hid_driver_probe to the given uhid device,
919-
* check that the device is now using hid-generic.
920-
*/
921-
TEST_F(hid_bpf, test_hid_driver_probe)
922-
{
923-
const struct test_program progs[] = {
924-
{
925-
.name = "hid_test_driver_probe",
926-
},
927-
};
928-
929-
ASSERT_TRUE(is_using_driver(_metadata, &self->hid, "apple"));
930-
931-
LOAD_PROGRAMS(progs);
932-
933-
ASSERT_TRUE(is_using_driver(_metadata, &self->hid, "hid-generic"));
934-
}
935-
936858
/*
937859
* Attach hid_rdesc_fixup to the given uhid device,
938860
* retrieve and open the matching hidraw node,

tools/testing/selftests/hid/progs/hid.c

-12
Original file line numberDiff line numberDiff line change
@@ -598,15 +598,3 @@ SEC(".struct_ops.link")
598598
struct hid_bpf_ops test_infinite_loop_input_report = {
599599
.hid_device_event = (void *)hid_test_infinite_loop_input_report,
600600
};
601-
602-
SEC("?struct_ops.s/hid_rdesc_fixup")
603-
int BPF_PROG(hid_test_driver_probe, struct hid_bpf_ctx *hid_ctx)
604-
{
605-
hid_ctx->hid->quirks |= HID_QUIRK_IGNORE_SPECIAL_DRIVER;
606-
return 0;
607-
}
608-
609-
SEC(".struct_ops.link")
610-
struct hid_bpf_ops test_driver_probe = {
611-
.hid_rdesc_fixup = (void *)hid_test_driver_probe,
612-
};

tools/testing/selftests/hid/progs/hid_bpf_helpers.h

+1-5
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,10 @@ struct hid_bpf_ops {
8484
struct hid_device *hdev;
8585
};
8686

87-
#define BIT(n) (1U << n)
88-
8987
#ifndef BPF_F_BEFORE
90-
#define BPF_F_BEFORE BIT(3)
88+
#define BPF_F_BEFORE (1U << 3)
9189
#endif
9290

93-
#define HID_QUIRK_IGNORE_SPECIAL_DRIVER BIT(22)
94-
9591
/* following are kfuncs exported by HID for HID-BPF */
9692
extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx,
9793
unsigned int offset,

0 commit comments

Comments
 (0)