On Thu, May 19, 2022 at 4:56 AM Benjamin Tissoires <benjamin.tissoires@xxxxxxxxxx> wrote: > > As Greg mentioned in his reply, report descriptors fixups don't do > much besides changing a memory buffer at probe time. So we can either > have udev load the program, pin it and forget about it, or we can also > have the kernel do that for us. > > So I envision the distribution to be hybrid: > - for plain fixups where no userspace is required, we should > distribute those programs in the kernel itself, in-tree. > This series already implements pre-loading of BPF programs for the > core part of HID-BPF, but I plan on working on some automation of > pre-loading of these programs from the kernel itself when we need to > do so. > > Ideally, the process would be: > * user reports a bug > * developer produces an eBPF program (and maybe compile it if the user > doesn't have LLVM) > * user tests/validates the fix without having to recompile anything > * developer drops the program in-tree > * some automated magic happens (still unclear exactly how to define > which HID device needs which eBPF program ATM) > * when the kernel sees this exact same device (BUS/VID/PID/INTERFACE) > it loads the fixup > > - the other part of the hybrid solution is for when userspace is > heavily involved (because it exports a new dbus interface for that > particular feature on this device). We can not really automatically > preload the BPF program because we might not have the user in front of > it. > So in that case, the program would be hosted alongside the > application, out-of-the-tree, but given that to be able to call kernel > functions you need to be GPL, some public distribution of the sources > is required. Agree with everything you've said earlier. Just one additional comment: By default the source code is embedded in bpf objects. Here is an example. $ bpftool prog dump jited id 3927008|head -50 void cwnd_event(long long unsigned int * ctx): bpf_prog_9b9adc0a36a25303_cwnd_event: ; void BPF_STRUCT_OPS(cwnd_event, struct sock* sk, enum tcp_ca_event ev) { 0: nopl 0x0(%rax,%rax,1) 5: xchg %ax,%ax ... ; switch (ev) { 25: mov %r14d,%edi 28: add $0xfffffffc,%edi ... ; ca->loss_cwnd = tp->snd_cwnd; 4a: mov %edi,0x18(%r13) 4e: mov $0x2,%edi ; tp->snd_ssthresh = max(tp->snd_cwnd >> 1U, 2U); 53: test %rbx,%rbx 56: jne 0x000000000000005c It's not the full source, of course, but good enough in practice for a person to figure out what program is doing.