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