Insert 3 programs to check that we are doing the correct thing: '2', '1', '3' are inserted, but '1' is supposed to be executed first. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@xxxxxxxxxx> --- changes in v11: - use the new facility from selftests/hid no changes in v10 no changes in v9 no changes in v8 no changes in v7 changes in v6: - fixed copy/paste in ASSERT_OK and test execution order changes in v5: - use the new API not in v4 changes in v3: - use the new hid_get_data API new in v2 --- tools/testing/selftests/hid/hid_bpf.c | 43 ++++++++++++++++++++ tools/testing/selftests/hid/progs/hid.c | 54 ++++++++++++++++++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c index fc2ad0443803..14548a558d9e 100644 --- a/tools/testing/selftests/hid/hid_bpf.c +++ b/tools/testing/selftests/hid/hid_bpf.c @@ -88,6 +88,7 @@ static u8 feature_data[] = { 1, 2 }; struct attach_prog_args { int prog_fd; unsigned int hid; + unsigned int flags; int retval; }; @@ -491,6 +492,7 @@ FIXTURE_SETUP(hid_bpf) struct test_program { const char *name; + unsigned int flags; }; #define LOAD_PROGRAMS(progs) \ load_programs(progs, ARRAY_SIZE(progs), _metadata, self, variant) @@ -540,6 +542,7 @@ static void load_programs(const struct test_program programs[], args.prog_fd = bpf_program__fd(prog); args.hid = self->hid_id; + args.flags = programs[i].flags; err = bpf_prog_test_run_opts(attach_fd, &tattr); ASSERT_OK(args.retval) TH_LOG("attach_hid(%s): %d", programs[i].name, args.retval); } @@ -741,6 +744,46 @@ TEST_F(hid_bpf, test_hid_user_raw_request_call) ASSERT_EQ(args.data[1], 2); } +/* + * Attach hid_insert{0,1,2} to the given uhid device, + * retrieve and open the matching hidraw node, + * inject one event in the uhid device, + * check that the programs have been inserted in the correct order. + */ +TEST_F(hid_bpf, test_hid_attach_flags) +{ + const struct test_program progs[] = { + { + .name = "hid_test_insert2", + .flags = HID_BPF_FLAG_NONE, + }, + { + .name = "hid_test_insert1", + .flags = HID_BPF_FLAG_INSERT_HEAD, + }, + { + .name = "hid_test_insert3", + .flags = HID_BPF_FLAG_NONE, + }, + }; + u8 buf[10] = {0}; + int err; + + LOAD_PROGRAMS(progs); + + /* inject one event */ + buf[0] = 1; + uhid_send_event(_metadata, self->uhid_fd, buf, 6); + + /* read the data from hidraw */ + memset(buf, 0, sizeof(buf)); + err = read(self->hidraw_fd, buf, sizeof(buf)); + ASSERT_EQ(err, 6) TH_LOG("read_hidraw"); + ASSERT_EQ(buf[1], 1); + ASSERT_EQ(buf[2], 2); + ASSERT_EQ(buf[3], 3); +} + /* * 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 815ff94321c9..eb869a80c254 100644 --- a/tools/testing/selftests/hid/progs/hid.c +++ b/tools/testing/selftests/hid/progs/hid.c @@ -21,6 +21,7 @@ extern int hid_bpf_hw_request(struct hid_bpf_ctx *ctx, struct attach_prog_args { int prog_fd; unsigned int hid; + unsigned int flags; int retval; }; @@ -60,7 +61,7 @@ int attach_prog(struct attach_prog_args *ctx) { ctx->retval = hid_bpf_attach_prog(ctx->hid, ctx->prog_fd, - 0); + ctx->flags); return 0; } @@ -152,3 +153,54 @@ int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hid_ctx) return sizeof(rdesc) + 73; } + +SEC("?fmod_ret/hid_bpf_device_event") +int BPF_PROG(hid_test_insert1, struct hid_bpf_ctx *hid_ctx) +{ + __u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */); + + if (!data) + return 0; /* EPERM check */ + + /* we need to be run first */ + if (data[2] || data[3]) + return -1; + + data[1] = 1; + + return 0; +} + +SEC("?fmod_ret/hid_bpf_device_event") +int BPF_PROG(hid_test_insert2, struct hid_bpf_ctx *hid_ctx) +{ + __u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */); + + if (!data) + return 0; /* EPERM check */ + + /* after insert0 and before insert2 */ + if (!data[1] || data[3]) + return -1; + + data[2] = 2; + + return 0; +} + +SEC("?fmod_ret/hid_bpf_device_event") +int BPF_PROG(hid_test_insert3, struct hid_bpf_ctx *hid_ctx) +{ + __u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */); + + if (!data) + return 0; /* EPERM check */ + + /* at the end */ + if (!data[1] || !data[2]) + return -1; + + data[3] = 3; + + return 0; +} -- 2.36.1