All of lore.kernel.org
 help / color / mirror / Atom feed
From: Benjamin Tissoires <benjamin.tissoires@redhat.com>
To: Greg KH <gregkh@linuxfoundation.org>,
	Jiri Kosina <jikos@kernel.org>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Andrii Nakryiko <andrii@kernel.org>,
	Martin KaFai Lau <kafai@fb.com>, Song Liu <songliubraving@fb.com>,
	Yonghong Song <yhs@fb.com>,
	John Fastabend <john.fastabend@gmail.com>,
	KP Singh <kpsingh@kernel.org>
Cc: Tero Kristo <tero.kristo@linux.intel.com>,
	linux-kernel@vger.kernel.org, linux-input@vger.kernel.org,
	bpf@vger.kernel.org,
	Benjamin Tissoires <benjamin.tissoires@redhat.com>
Subject: [RFC bpf-next v4 6/7] samples/bpf: add new hid_mouse example
Date: Thu, 21 Apr 2022 16:07:39 +0200	[thread overview]
Message-ID: <20220421140740.459558-7-benjamin.tissoires@redhat.com> (raw)
In-Reply-To: <20220421140740.459558-1-benjamin.tissoires@redhat.com>

Everything should be available in the selftest part of the tree, but
providing an example without uhid and hidraw will be more easy to
follow for users.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>

---

changes in v4:
- dropped the not-yet-implemented rdesc_fixup
- use the new API

changes in v3:
- use the new hid_get_data API
- add a comment for the report descriptor fixup to explain what is done

changes in v2:
- split the series by bpf/libbpf/hid/selftests and samples
---
 samples/bpf/.gitignore      |   1 +
 samples/bpf/Makefile        |  23 +++++++
 samples/bpf/hid_mouse.bpf.c |  59 ++++++++++++++++
 samples/bpf/hid_mouse.c     | 131 ++++++++++++++++++++++++++++++++++++
 4 files changed, 214 insertions(+)
 create mode 100644 samples/bpf/hid_mouse.bpf.c
 create mode 100644 samples/bpf/hid_mouse.c

diff --git a/samples/bpf/.gitignore b/samples/bpf/.gitignore
index 0e7bfdbff80a..65440bd618b2 100644
--- a/samples/bpf/.gitignore
+++ b/samples/bpf/.gitignore
@@ -2,6 +2,7 @@
 cpustat
 fds_example
 hbm
+hid_mouse
 ibumad
 lathist
 lwt_len_hist
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 8fff5ad3444b..dffca4b04a94 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -60,6 +60,8 @@ tprogs-y += xdp_redirect_map
 tprogs-y += xdp_redirect
 tprogs-y += xdp_monitor
 
+tprogs-y += hid_mouse
+
 # Libbpf dependencies
 LIBBPF_SRC = $(TOOLS_PATH)/lib/bpf
 LIBBPF_OUTPUT = $(abspath $(BPF_SAMPLES_PATH))/libbpf
@@ -125,6 +127,8 @@ xdp_redirect-objs := xdp_redirect_user.o $(XDP_SAMPLE)
 xdp_monitor-objs := xdp_monitor_user.o $(XDP_SAMPLE)
 xdp_router_ipv4-objs := xdp_router_ipv4_user.o $(XDP_SAMPLE)
 
+hid_mouse-objs := hid_mouse.o
+
 # Tell kbuild to always build the programs
 always-y := $(tprogs-y)
 always-y += sockex1_kern.o
@@ -349,6 +353,8 @@ $(obj)/hbm_out_kern.o: $(src)/hbm.h $(src)/hbm_kern.h
 $(obj)/hbm.o: $(src)/hbm.h
 $(obj)/hbm_edt_kern.o: $(src)/hbm.h $(src)/hbm_kern.h
 
+$(obj)/hid_mouse.o: $(obj)/hid_mouse.skel.h
+
 # Override includes for xdp_sample_user.o because $(srctree)/usr/include in
 # TPROGS_CFLAGS causes conflicts
 XDP_SAMPLE_CFLAGS += -Wall -O2 \
@@ -434,6 +440,23 @@ $(BPF_SKELS_LINKED): $(BPF_OBJS_LINKED) $(BPFTOOL)
 	@echo "  BPF GEN-SKEL" $(@:.skel.h=)
 	$(Q)$(BPFTOOL) gen skeleton $(@:.skel.h=.lbpf.o) name $(notdir $(@:.skel.h=)) > $@
 
+# Generate BPF skeletons for non XDP progs
+OTHER_BPF_SKELS := hid_mouse.skel.h
+
+hid_mouse.skel.h-deps := hid_mouse.bpf.o
+
+OTHER_BPF_SRCS_LINKED := $(patsubst %.skel.h,%.bpf.c, $(OTHER_BPF_SKELS))
+OTHER_BPF_OBJS_LINKED := $(patsubst %.bpf.c,$(obj)/%.bpf.o, $(OTHER_BPF_SRCS_LINKED))
+OTHER_BPF_SKELS_LINKED := $(addprefix $(obj)/,$(OTHER_BPF_SKELS))
+
+$(OTHER_BPF_SKELS_LINKED): $(OTHER_BPF_OBJS_LINKED) $(BPFTOOL)
+	@echo "  BPF GEN-OBJ " $(@:.skel.h=)
+	$(Q)$(BPFTOOL) gen object $(@:.skel.h=.lbpf.o) $(addprefix $(obj)/,$($(@F)-deps))
+	@echo "  BPF GEN-SKEL" $(@:.skel.h=)
+	$(Q)$(BPFTOOL) gen skeleton $(@:.skel.h=.lbpf.o) name $(notdir $(@:.skel.h=_lskel)) > $@
+#	$(call msg,GEN-SKEL,$@)
+#	$(Q)$(BPFTOOL) gen skeleton $< > $@
+
 # asm/sysreg.h - inline assembly used by it is incompatible with llvm.
 # But, there is no easy way to fix it, so just exclude it since it is
 # useless for BPF samples.
diff --git a/samples/bpf/hid_mouse.bpf.c b/samples/bpf/hid_mouse.bpf.c
new file mode 100644
index 000000000000..45cc26b70f5f
--- /dev/null
+++ b/samples/bpf/hid_mouse.bpf.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Note: for the following code to compile, we need HID to be included
+ * in vmlinuz (CONFIG_HID=y).
+ * If HID is compiled as a separate module, we need to use the vmlinux.h
+ * which contains the various hid symbols, it can be generated through:
+ *
+ * $> ./tools/bpf/bpftool/bpftool btf dump \
+ *        file /sys/kernel/btf/hid format c > samples/bpf/vmlinux.h
+ *
+ * Once the code is compiled, the fact that HID is a separate module
+ * or not is not an issue, the same binary will run similarily.
+ */
+#include "vmlinux.h"
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+
+extern __u8 *hid_bpf_kfunc_get_data(struct hid_bpf_ctx *ctx,
+				    unsigned int offset,
+				    const size_t __sz) __ksym;
+extern void hid_bpf_kfunc_data_release(__u8 *data) __ksym;
+extern int hid_bpf_kfunc_hw_request(struct hid_bpf_ctx *ctx) __ksym;
+
+#define BUS_USB 3
+
+SEC("fentry/hid_bpf_device_event")
+int BPF_KPROBE(hid_event, struct hid_bpf_ctx *hctx, __s64 type)
+{
+	__u8 *rw_data = hid_bpf_kfunc_get_data(hctx, 0, 5);
+
+	if (!rw_data)
+		return 0;
+
+	if (hctx->bus == BUS_USB) {
+		/* note: the following call prevents the program to be loaded:
+		 * hid_bpf_device_event() is not sleepable when this function is.
+		 */
+		hid_bpf_kfunc_hw_request(hctx);
+
+		bpf_printk("data: %02x %02x %02x", rw_data[0], rw_data[1], rw_data[4]);
+	}
+
+	hid_bpf_kfunc_data_release(rw_data);
+
+	return 0;
+}
+
+SEC("fmod_ret/hid_bpf_device_event")
+int BPF_PROG(hid_mod_event, struct hid_bpf_ctx *hctx, __s64 type)
+{
+	/* prevent any USB event to go through the HID stack */
+	if (hctx->bus == BUS_USB)
+		return -1;
+
+	return 0;
+}
+
+char _license[] SEC("license") = "GPL";
diff --git a/samples/bpf/hid_mouse.c b/samples/bpf/hid_mouse.c
new file mode 100644
index 000000000000..aace0b959d3b
--- /dev/null
+++ b/samples/bpf/hid_mouse.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2022 Benjamin Tissoires
+ */
+
+/* not sure why but this doesn't get preoperly imported */
+#define __must_check
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/resource.h>
+#include <unistd.h>
+
+#include <linux/bpf.h>
+#include <linux/err.h>
+
+#include "bpf_util.h"
+#include <bpf/bpf.h>
+#include <bpf/libbpf.h>
+
+#include "hid_mouse.skel.h"
+
+static char *sysfs_path;
+static int sysfs_fd;
+static int prog_count;
+
+static bool running = true;
+
+struct prog {
+	int fd;
+	struct bpf_link *link;
+	enum bpf_attach_type type;
+};
+
+static struct prog progs[10];
+
+static void int_exit(int sig)
+{
+	running = false;
+	exit(0);
+}
+
+static void usage(const char *prog)
+{
+	fprintf(stderr,
+		"%s: %s /sys/bus/hid/devices/0BUS:0VID:0PID:00ID/uevent\n\n",
+		__func__, prog);
+}
+
+int main(int argc, char **argv)
+{
+	struct hid_mouse_lskel *skel;
+	int prog_fd, err;
+	const char *optstr = "";
+	int opt;
+	char filename[256];
+
+	LIBBPF_OPTS(bpf_test_run_opts, topts,
+		    .repeat = 1,
+	);
+
+	while ((opt = getopt(argc, argv, optstr)) != -1) {
+		switch (opt) {
+		default:
+			usage(basename(argv[0]));
+			return 1;
+		}
+	}
+
+	if (optind == argc) {
+		usage(basename(argv[0]));
+		return 1;
+	}
+
+	sysfs_path = argv[optind];
+	if (!sysfs_path) {
+		perror("sysfs");
+		return 1;
+	}
+
+	skel = hid_mouse_lskel__open_and_load();
+	if (!skel) {
+		fprintf(stderr, "%s  %s:%d", __func__, __FILE__, __LINE__);
+		return -1;
+	}
+
+	err = hid_mouse_lskel__attach(skel);
+	if (err)
+		goto cleanup;
+
+	//prog_fd = bpf_program__fd(skel->progs.hid_event);
+	//err = bpf_prog_test_run_opts(prog_fd, &topts);
+
+//	sysfs_fd = open(sysfs_path, O_RDONLY);
+//
+////	bpf_object__for_each_program(prog, obj) {
+////		progs[prog_count].fd = bpf_program__fd(prog);
+////		progs[prog_count].type = bpf_program__get_expected_attach_type(prog);
+////		progs[prog_count].link = bpf_program__attach(prog);
+////		if (libbpf_get_error(progs[prog_count].link)) {
+////			fprintf(stderr, "bpf_prog_attach: err=%m\n");
+////			progs[prog_count].fd = 0;
+////			progs[prog_count].link = NULL;
+////			goto cleanup;
+////		}
+////		prog_count++;
+////	}
+//
+	signal(SIGINT, int_exit);
+	signal(SIGTERM, int_exit);
+//
+////	err = bpf_obj_get_info_by_fd(progs[0].fd, &info, &info_len);
+////	if (err) {
+////		printf("can't get prog info - %s\n", strerror(errno));
+////		goto cleanup;
+////	}
+//
+	while (running)
+		;
+
+ cleanup:
+	hid_mouse_lskel__destroy(skel);
+
+	return err;
+}
-- 
2.35.1


  parent reply	other threads:[~2022-04-21 14:08 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-21 14:07 [RFC bpf-next v4 0/7] Introduce eBPF support for HID devices (new attempt) Benjamin Tissoires
2022-04-21 14:07 ` [RFC bpf-next v4 1/7] bpf/btf: also allow kfunc in tracing programs Benjamin Tissoires
2022-04-21 14:07 ` [RFC bpf-next v4 2/7] bpf/verifier: allow kfunc to return an allocated mem Benjamin Tissoires
2022-04-26  4:08   ` Alexei Starovoitov
2022-04-26  7:30     ` Benjamin Tissoires
2022-04-30  3:25       ` Alexei Starovoitov
2022-04-30  7:17         ` Benjamin Tissoires
2022-04-21 14:07 ` [RFC bpf-next v4 3/7] error-inject: add new type that carries if the function is non sleepable Benjamin Tissoires
2022-04-26  4:11   ` Alexei Starovoitov
2022-04-26  7:52     ` Benjamin Tissoires
2022-04-30  3:29       ` Alexei Starovoitov
2022-04-30  7:24         ` Benjamin Tissoires
2022-04-21 14:07 ` [RFC bpf-next v4 4/7] btf: Add a new kfunc set which allows to mark a function to be sleepable Benjamin Tissoires
2022-04-26  4:12   ` Alexei Starovoitov
2022-04-21 14:07 ` [RFC bpf-next v4 5/7] HID: initial BPF new way implementation Benjamin Tissoires
2022-04-26  4:19   ` Alexei Starovoitov
2022-04-21 14:07 ` Benjamin Tissoires [this message]
2022-04-21 14:07 ` [RFC bpf-next v4 7/7] selftests/bpf: add tests for the HID-bpf initial implementation Benjamin Tissoires
2022-04-26  4:03 ` [RFC bpf-next v4 0/7] Introduce eBPF support for HID devices (new attempt) Alexei Starovoitov
2022-04-26  7:20   ` Benjamin Tissoires
2022-04-30  3:00     ` Alexei Starovoitov
2022-04-30  7:12       ` Benjamin Tissoires
2022-05-02 21:43         ` Benjamin Tissoires
2022-05-12  4:16           ` Alexei Starovoitov
2022-05-13 16:59             ` Benjamin Tissoires
2022-05-12  4:23         ` Alexei Starovoitov
2022-05-13 17:02           ` Benjamin Tissoires
2022-05-13 19:42             ` Alexei Starovoitov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220421140740.459558-7-benjamin.tissoires@redhat.com \
    --to=benjamin.tissoires@redhat.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=jikos@kernel.org \
    --cc=john.fastabend@gmail.com \
    --cc=kafai@fb.com \
    --cc=kpsingh@kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=songliubraving@fb.com \
    --cc=tero.kristo@linux.intel.com \
    --cc=yhs@fb.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.