Re: [RFC PATCH v1 0/4] Add BPF decoders to ir-keytable

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Sean,

On Sat, Jun 02, 2018 at 01:37:54PM +0100, Sean Young wrote:
> This is not ready for merging yet, however while I finish this work I would
> like some feedback and ideas.
> 
> The idea is that IR decoders can be written in C, compiled to BPF relocatable
> object file. Any global variables can overriden, so we can supports lots
> of variants of similiar protocols (just like in the lircd.conf file).
> 
> The existing rc_keymap file format can't be used for variables, so I've
> converted the format to toml. An alternative would be to use the existing
> lircd.conf file format, but it's a very awkward file to parse in C and it
> contains many features which are irrelevant to us.
> 
> We use libelf to load the bpf relocatable object file.
> 
> After loading our example grundig keymap with bpf decoder, the output of
> ir-keytable is:
> 
> Found /sys/class/rc/rc0/ (/dev/input/event8) with:
> 	Name: Winbond CIR
> 	Driver: winbond-cir, table: rc-rc6-mce
> 	lirc device: /dev/lirc0
> 	Attached bpf protocols: grundig
> 	Supported protocols: lirc rc-5 rc-5-sz jvc sony nec sanyo mce_kbd rc-6 sharp xmp imon 
> 	Enabled protocols: lirc
> 	bus: 25, vendor/product: 10ad:00f1, version: 0x0004
> 	Repeat delay = 500 ms, repeat period = 125 ms

I did a few tests with this patch and noticed some issues:

clang didn't find asm/types.h, I'm running Debian Stretch here
and asm isn't in /usr/include but in /usr/include/HOST-TRIPLET
which gcc uses by default, but clang doesn't seem to know about.

With a quick workaround (adding /usr/include/x86_64-linux-gnu/
on x86_64 and /usr/include/aarch64-linux-gnu/) the grundig decoder
built fine both on x86_64 and aarch64 and grundig.o files were
identical. I noticed some pointer arithmetic warnings though:

hias@lepotato:~/install/v4l-utils/git/utils/keytable$ make
Making all in bpf_protocols
make[1]: Entering directory '/home/hias/install/v4l-utils/git/utils/keytable/bpf_protocols'
clang -I../../../include -nostdinc -isystem /usr/lib/llvm-3.8/bin/../lib/clang/3.8.1/include -I/usr/include -I/usr/include/aarch64-linux-gnu -target bpf -O2 -emit-llvm -c grundig.c -o - | llc -march=bpf -filetype=obj -o grundig.o
make[1]: Leaving directory '/home/hias/install/v4l-utils/git/utils/keytable/bpf_protocols'
make[1]: Entering directory '/home/hias/install/v4l-utils/git/utils/keytable'
  CC       keytable.o
  CC       ir-encode.o
  CC       toml.o
  CC       bpf.o
  CC       bpf_load.o
bpf_load.c: In function ‘parse_relo_and_apply’:
bpf_load.c:192:41: warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
     int32_t *p = (bpf_file->data->d_buf + sym.st_value);
                                         ^
bpf_load.c: In function ‘load_elf_maps_section’:
bpf_load.c:308:54: warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
   def = (struct bpf_load_map_def *)(data_maps->d_buf + offset);
                                                      ^
  CCLD     ir-keytable
make[1]: Leaving directory '/home/hias/install/v4l-utils/git/utils/keytable'

When trying to load the grundig decoder (tested on aarch64 with
a kernel compiled from yesterday's head of bpf-next, commit
bd3a08aaa9a3) I get an "invalid mem access 'map_value_or_null'"
error:

hias@lepotato:~/install/v4l-utils/git/utils/keytable$ sudo ./ir-keytable -c -w rc_keymaps_bpf/RP75_LCD.toml
bpf protocols removed
Old keytable cleared
Wrote 40 keycode(s) to driver
header_space (null)
header_pulse 1244
leader_pulse (null)
bpf_load_program() err=13
0: (bf) r6 = r1
1: (b7) r8 = 0
2: (63) *(u32 *)(r10 -4) = r8
3: (bf) r2 = r10
4: (07) r2 += -4
5: (18) r1 = 0xffff80006960fa00
7: (85) call bpf_map_lookup_elem#1
8: (bf) r7 = r10
9: (07) r7 += -24
10: (1d) if r0 == r8 goto pc+1
 R0=map_value_or_null(id=1,off=0,ks=4,vs=16,imm=0) R6=ctx(id=0,off=0,imm=0) R7=fp-24,call_-1 R8=inv0 R10=fp0,call_-1
11: (bf) r7 = r0
12: (7b) *(u64 *)(r10 -16) = r8
13: (7b) *(u64 *)(r10 -24) = r8
14: (61) r1 = *(u32 *)(r6 +0)
15: (18) r3 = 0xff000000
17: (bf) r2 = r1
18: (5f) r2 &= r3
19: (15) if r2 == 0x2000000 goto pc+131
 R0=map_value_or_null(id=1,off=0,ks=4,vs=16,imm=0) R1=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R2=inv(id=0,umax_value=4278190080,var_off=(0x0; 0xff000000)) R3=inv4278190080 R6=ctx(id=0,off=0,imm=0) R7=map_value_or_null(id=1,off=0,ks=4,vs=16,imm=0) R8=inv0 R10=fp0,call_-1 fp-16=0 fp-24=0
20: (57) r1 &= 16777215
21: (61) r3 = *(u32 *)(r7 +4)
R7 invalid mem access 'map_value_or_null'

Not quite sure who's to blame here, clang/llvm, the grundig code or
the loader. Do you have any ideas or hints?

so long,

Hias



[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux