xref: /linux/samples/hid/hid_mouse.bpf.c (revision d6fd48ef)
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";
113