Merge tag 'uml-for-linus-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[platform/kernel/linux-rpi.git] / samples / hid / hid_mouse.bpf.c
1 // SPDX-License-Identifier: GPL-2.0
2
3 #include "vmlinux.h"
4 #include <bpf/bpf_helpers.h>
5 #include <bpf/bpf_tracing.h>
6 #include "hid_bpf_helpers.h"
7
8 SEC("fmod_ret/hid_bpf_device_event")
9 int BPF_PROG(hid_y_event, struct hid_bpf_ctx *hctx)
10 {
11         s16 y;
12         __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */);
13
14         if (!data)
15                 return 0; /* EPERM check */
16
17         bpf_printk("event: size: %d", hctx->size);
18         bpf_printk("incoming event: %02x %02x %02x",
19                    data[0],
20                    data[1],
21                    data[2]);
22         bpf_printk("                %02x %02x %02x",
23                    data[3],
24                    data[4],
25                    data[5]);
26         bpf_printk("                %02x %02x %02x",
27                    data[6],
28                    data[7],
29                    data[8]);
30
31         y = data[3] | (data[4] << 8);
32
33         y = -y;
34
35         data[3] = y & 0xFF;
36         data[4] = (y >> 8) & 0xFF;
37
38         bpf_printk("modified event: %02x %02x %02x",
39                    data[0],
40                    data[1],
41                    data[2]);
42         bpf_printk("                %02x %02x %02x",
43                    data[3],
44                    data[4],
45                    data[5]);
46         bpf_printk("                %02x %02x %02x",
47                    data[6],
48                    data[7],
49                    data[8]);
50
51         return 0;
52 }
53
54 SEC("fmod_ret/hid_bpf_device_event")
55 int BPF_PROG(hid_x_event, struct hid_bpf_ctx *hctx)
56 {
57         s16 x;
58         __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */);
59
60         if (!data)
61                 return 0; /* EPERM check */
62
63         x = data[1] | (data[2] << 8);
64
65         x = -x;
66
67         data[1] = x & 0xFF;
68         data[2] = (x >> 8) & 0xFF;
69         return 0;
70 }
71
72 SEC("fmod_ret/hid_bpf_rdesc_fixup")
73 int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hctx)
74 {
75         __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 4096 /* size */);
76
77         if (!data)
78                 return 0; /* EPERM check */
79
80         bpf_printk("rdesc: %02x %02x %02x",
81                    data[0],
82                    data[1],
83                    data[2]);
84         bpf_printk("       %02x %02x %02x",
85                    data[3],
86                    data[4],
87                    data[5]);
88         bpf_printk("       %02x %02x %02x ...",
89                    data[6],
90                    data[7],
91                    data[8]);
92
93         /*
94          * The original report descriptor contains:
95          *
96          * 0x05, 0x01,                    //   Usage Page (Generic Desktop)      30
97          * 0x16, 0x01, 0x80,              //   Logical Minimum (-32767)          32
98          * 0x26, 0xff, 0x7f,              //   Logical Maximum (32767)           35
99          * 0x09, 0x30,                    //   Usage (X)                         38
100          * 0x09, 0x31,                    //   Usage (Y)                         40
101          *
102          * So byte 39 contains Usage X and byte 41 Usage Y.
103          *
104          * We simply swap the axes here.
105          */
106         data[39] = 0x31;
107         data[41] = 0x30;
108
109         return 0;
110 }
111
112 char _license[] SEC("license") = "GPL";