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 static int hid_y_event(struct hid_bpf_ctx *hctx) 9 { 10 s16 y; 11 __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */); 12 13 if (!data) 14 return 0; /* EPERM check */ 15 16 bpf_printk("event: size: %d", hctx->size); 17 bpf_printk("incoming event: %02x %02x %02x", 18 data[0], 19 data[1], 20 data[2]); 21 bpf_printk(" %02x %02x %02x", 22 data[3], 23 data[4], 24 data[5]); 25 bpf_printk(" %02x %02x %02x", 26 data[6], 27 data[7], 28 data[8]); 29 30 y = data[3] | (data[4] << 8); 31 32 y = -y; 33 34 data[3] = y & 0xFF; 35 data[4] = (y >> 8) & 0xFF; 36 37 bpf_printk("modified event: %02x %02x %02x", 38 data[0], 39 data[1], 40 data[2]); 41 bpf_printk(" %02x %02x %02x", 42 data[3], 43 data[4], 44 data[5]); 45 bpf_printk(" %02x %02x %02x", 46 data[6], 47 data[7], 48 data[8]); 49 50 return 0; 51 } 52 53 static int hid_x_event(struct hid_bpf_ctx *hctx) 54 { 55 s16 x; 56 __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */); 57 58 if (!data) 59 return 0; /* EPERM check */ 60 61 x = data[1] | (data[2] << 8); 62 63 x = -x; 64 65 data[1] = x & 0xFF; 66 data[2] = (x >> 8) & 0xFF; 67 return 0; 68 } 69 70 SEC("struct_ops/hid_device_event") 71 int BPF_PROG(hid_event, struct hid_bpf_ctx *hctx, enum hid_report_type type) 72 { 73 int ret = hid_y_event(hctx); 74 75 if (ret) 76 return ret; 77 78 return hid_x_event(hctx); 79 } 80 81 82 SEC("struct_ops/hid_rdesc_fixup") 83 int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hctx) 84 { 85 __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 4096 /* size */); 86 87 if (!data) 88 return 0; /* EPERM check */ 89 90 bpf_printk("rdesc: %02x %02x %02x", 91 data[0], 92 data[1], 93 data[2]); 94 bpf_printk(" %02x %02x %02x", 95 data[3], 96 data[4], 97 data[5]); 98 bpf_printk(" %02x %02x %02x ...", 99 data[6], 100 data[7], 101 data[8]); 102 103 /* 104 * The original report descriptor contains: 105 * 106 * 0x05, 0x01, // Usage Page (Generic Desktop) 30 107 * 0x16, 0x01, 0x80, // Logical Minimum (-32767) 32 108 * 0x26, 0xff, 0x7f, // Logical Maximum (32767) 35 109 * 0x09, 0x30, // Usage (X) 38 110 * 0x09, 0x31, // Usage (Y) 40 111 * 112 * So byte 39 contains Usage X and byte 41 Usage Y. 113 * 114 * We simply swap the axes here. 115 */ 116 data[39] = 0x31; 117 data[41] = 0x30; 118 119 return 0; 120 } 121 122 SEC(".struct_ops.link") 123 struct hid_bpf_ops mouse_invert = { 124 .hid_rdesc_fixup = (void *)hid_rdesc_fixup, 125 .hid_device_event = (void *)hid_event, 126 }; 127 128 char _license[] SEC("license") = "GPL"; 129