archive mirror
 help / color / mirror / Atom feed
From: Benjamin Tissoires <>
To: Jiri Kosina <>,
	Alexei Starovoitov <>,
	Daniel Borkmann <>,
	Andrii Nakryiko <>,
	Martin KaFai Lau <>, Song Liu <>,
	Yonghong Song <>,
	John Fastabend <>,
	KP Singh <>, Shuah Khan <>,
	Dave Marchevsky <>,
	Joe Stringer <>
Cc: Tero Kristo <>,,,,,,
	Benjamin Tissoires <>
Subject: [PATCH bpf-next v1 0/6] Introduce eBPF support for HID devices
Date: Thu, 24 Feb 2022 12:08:22 +0100	[thread overview]
Message-ID: <> (raw)

Hi there,

This series introduces support of eBPF for HID devices.

I have several use cases where eBPF could be interesting for those
input devices:

- simple fixup of report descriptor:

In the HID tree, we have half of the drivers that are "simple" and
that just fix one key or one byte in the report descriptor.
Currently, for users of such devices, the process of fixing them
is long and painful.
With eBPF, we could externalize those fixups in one external repo,
ship various CoRe bpf programs and have those programs loaded at boot
time without having to install a new kernel (and wait 6 months for the
fix to land in the distro kernel)

- Universal Stylus Interface (or any other new fancy feature that
  requires a new kernel API)

See [0].
Basically, USI pens are requiring a new kernel API because there are
some channels of communication our HID and input stack are not capable
of. Instead of using hidraw or creating new sysfs or ioctls, we can rely
on eBPF to have the kernel API controlled by the consumer and to not
impact the performances by waking up userspace every time there is an

- Surface Dial

This device is a "puck" from Microsoft, basically a rotary dial with a
push button. The kernel already exports it as such but doesn't handle
the haptic feedback we can get out of it.
Furthermore, that device is not recognized by userspace and so it's a
nice paperwight in the end.

With eBPF, we can morph that device into a mouse, and convert the dial
events into wheel events. Also, we can set/unset the haptic feedback
from userspace. The convenient part of BPF makes it that the kernel
doesn't make any choice that would need to be reverted because that
specific userspace doesn't handle it properly or because that other
one expects it to be different.

- firewall

What if we want to prevent other users to access a specific feature of a
device? (think a possibly bonker firmware update entry popint)
With eBPF, we can intercept any HID command emitted to the device and
validate it or not.
This also allows to sync the state between the userspace and the
kernel/bpf program because we can intercept any incoming command.

- tracing

The last usage I have in mind is tracing events and all the fun we can
do we BPF to summarize and analyze events.
Right now, tracing relies on hidraw. It works well except for a couple
of issues:
 1. if the driver doesn't export a hidraw node, we can't trace anything
    (eBPF will be a "god-mode" there, so it might raise some eyebrows)
 2. hidraw doesn't catch the other process requests to the device, which
    means that we have cases where we need to add printks to the kernel
    to understand what is happening.

With that long introduction, here is the v1 of the support of eBPF in

I have targeted bpf-next here because the parts that will have the most
conflicts are in bpf. There might be a trivial minor conflict in
include/linux/hid.h with an other series I have pending[1].

I am relatively new to bpf, so having some feedback would be most very

A couple of notes though:

- The series is missing a SEC("hid/driver_event") which would allow to
  intercept incoming requests to the device from anybody. I left it
  outside because it's not critical to have it from day one (we are more
  interested right now by the USI case above)

- I am still wondering how to integrate the tracing part:
  right now, if a bpf program is loaded before we start the tracer, we
  will see *modified* events in the tracer. However, it might be
  interesting to decide to see either unmodified (raw events from the
  device) or modified events.
  I think a flag might be able to solve that. The flag will control
  whether we add the new program at the beginning of the list or at the
  tail, but I am not sure if this is common practice in eBPF or if
  there is a better way.



Benjamin Tissoires (6):
  HID: initial BPF implementation
  HID: bpf: allow to change the report descriptor from an eBPF program
  HID: bpf: add hid_{get|set}_data helpers
  HID: bpf: add new BPF type to trigger commands from userspace
  HID: bpf: tests: rely on uhid event to know if a test device is ready
  HID: bpf: add bpf_hid_raw_request helper function

 drivers/hid/Makefile                         |   1 +
 drivers/hid/hid-bpf.c                        | 327 +++++++++
 drivers/hid/hid-core.c                       |  31 +-
 include/linux/bpf-hid.h                      |  98 +++
 include/linux/bpf_types.h                    |   4 +
 include/linux/hid.h                          |  25 +
 include/uapi/linux/bpf.h                     |  33 +
 include/uapi/linux/bpf_hid.h                 |  56 ++
 kernel/bpf/Makefile                          |   3 +
 kernel/bpf/hid.c                             | 653 ++++++++++++++++++
 kernel/bpf/syscall.c                         |  12 +
 samples/bpf/.gitignore                       |   1 +
 samples/bpf/Makefile                         |   4 +
 samples/bpf/hid_mouse_kern.c                 |  91 +++
 samples/bpf/hid_mouse_user.c                 | 129 ++++
 tools/include/uapi/linux/bpf.h               |  33 +
 tools/lib/bpf/libbpf.c                       |   9 +
 tools/lib/bpf/libbpf.h                       |   2 +
 tools/lib/bpf/                     |   1 +
 tools/testing/selftests/bpf/prog_tests/hid.c | 685 +++++++++++++++++++
 tools/testing/selftests/bpf/progs/hid.c      | 149 ++++
 21 files changed, 2339 insertions(+), 8 deletions(-)
 create mode 100644 drivers/hid/hid-bpf.c
 create mode 100644 include/linux/bpf-hid.h
 create mode 100644 include/uapi/linux/bpf_hid.h
 create mode 100644 kernel/bpf/hid.c
 create mode 100644 samples/bpf/hid_mouse_kern.c
 create mode 100644 samples/bpf/hid_mouse_user.c
 create mode 100644 tools/testing/selftests/bpf/prog_tests/hid.c
 create mode 100644 tools/testing/selftests/bpf/progs/hid.c


             reply	other threads:[~2022-02-24 11:09 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-24 11:08 Benjamin Tissoires [this message]
2022-02-24 11:08 ` [PATCH bpf-next v1 1/6] HID: initial BPF implementation Benjamin Tissoires
2022-02-24 11:34   ` Greg KH
2022-02-24 13:52     ` Benjamin Tissoires
2022-02-28 17:30     ` Benjamin Tissoires
2022-02-26  7:19   ` Song Liu
2022-02-28 17:38     ` Benjamin Tissoires
2022-02-24 11:08 ` [PATCH bpf-next v1 2/6] HID: bpf: allow to change the report descriptor from an eBPF program Benjamin Tissoires
2022-02-26  7:25   ` Song Liu
2022-02-28 17:41     ` Benjamin Tissoires
2022-02-24 11:08 ` [PATCH bpf-next v1 3/6] HID: bpf: add hid_{get|set}_data helpers Benjamin Tissoires
2022-02-24 11:08 ` [PATCH bpf-next v1 4/6] HID: bpf: add new BPF type to trigger commands from userspace Benjamin Tissoires
2022-02-24 11:08 ` [PATCH bpf-next v1 5/6] HID: bpf: tests: rely on uhid event to know if a test device is ready Benjamin Tissoires
2022-02-24 11:08 ` [PATCH bpf-next v1 6/6] HID: bpf: add bpf_hid_raw_request helper function Benjamin Tissoires
2022-02-24 11:31 ` [PATCH bpf-next v1 0/6] Introduce eBPF support for HID devices Greg KH
2022-02-24 13:49   ` Benjamin Tissoires
2022-02-24 17:20     ` Yonghong Song
2022-02-25 16:06       ` Benjamin Tissoires
2022-02-25 16:19         ` Greg KH
2022-02-25 16:30         ` Yonghong Song
2022-02-25 13:38     ` Greg KH
2022-02-25 16:00       ` Benjamin Tissoires
2022-02-25 16:23         ` Greg KH
2022-02-25 16:32         ` Greg KH
2022-02-26  7:36           ` Song Liu
2022-02-26  9:19             ` Benjamin Tissoires
2022-02-28 16:33           ` Jiri Kosina
2022-02-24 17:41   ` Bastien Nocera
2022-02-24 18:20     ` Greg KH

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:

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

  git send-email \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \

* 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).