mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
HID: bpf: allow to inject HID event from BPF
It can be interesting to inject events from BPF as if the event were to come from the device. For example, some multitouch devices do not all the time send a proximity out event, and we might want to send it for the physical device. Compared to uhid, we can now inject events on any physical device, not just uhid virtual ones. Link: https://lore.kernel.org/r/20240315-b4-hid-bpf-new-funcs-v4-5-079c282469d3@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
This commit is contained in:
parent
db624e82c5
commit
9be50ac30a
@ -179,7 +179,7 @@ Available API that can be used in syscall HID-BPF programs:
|
||||
-----------------------------------------------------------
|
||||
|
||||
.. kernel-doc:: drivers/hid/bpf/hid_bpf_dispatch.c
|
||||
:functions: hid_bpf_attach_prog hid_bpf_hw_request hid_bpf_hw_output_report hid_bpf_allocate_context hid_bpf_release_context
|
||||
:functions: hid_bpf_attach_prog hid_bpf_hw_request hid_bpf_hw_output_report hid_bpf_input_report hid_bpf_allocate_context hid_bpf_release_context
|
||||
|
||||
General overview of a HID-BPF program
|
||||
=====================================
|
||||
|
@ -508,6 +508,34 @@ hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz)
|
||||
kfree(dma_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* hid_bpf_input_report - Inject a HID report in the kernel from a HID device
|
||||
*
|
||||
* @ctx: the HID-BPF context previously allocated in hid_bpf_allocate_context()
|
||||
* @type: the type of the report (%HID_INPUT_REPORT, %HID_FEATURE_REPORT, %HID_OUTPUT_REPORT)
|
||||
* @buf: a %PTR_TO_MEM buffer
|
||||
* @buf__sz: the size of the data to transfer
|
||||
*
|
||||
* Returns %0 on success, a negative error code otherwise.
|
||||
*/
|
||||
__bpf_kfunc int
|
||||
hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *buf,
|
||||
const size_t buf__sz)
|
||||
{
|
||||
struct hid_device *hdev;
|
||||
size_t size = buf__sz;
|
||||
int ret;
|
||||
|
||||
/* check arguments */
|
||||
ret = __hid_bpf_hw_check_params(ctx, buf, &size, type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
hdev = (struct hid_device *)ctx->hid; /* discard const */
|
||||
|
||||
return hid_input_report(hdev, type, buf, size, 0);
|
||||
}
|
||||
__bpf_kfunc_end_defs();
|
||||
|
||||
/*
|
||||
@ -542,6 +570,7 @@ BTF_ID_FLAGS(func, hid_bpf_allocate_context, KF_ACQUIRE | KF_RET_NULL)
|
||||
BTF_ID_FLAGS(func, hid_bpf_release_context, KF_RELEASE)
|
||||
BTF_ID_FLAGS(func, hid_bpf_hw_request)
|
||||
BTF_ID_FLAGS(func, hid_bpf_hw_output_report)
|
||||
BTF_ID_FLAGS(func, hid_bpf_input_report)
|
||||
BTF_KFUNCS_END(hid_bpf_syscall_kfunc_ids)
|
||||
|
||||
static const struct btf_kfunc_id_set hid_bpf_syscall_kfunc_set = {
|
||||
|
@ -2975,6 +2975,7 @@ static struct hid_bpf_ops hid_ops = {
|
||||
.hid_get_report = hid_get_report,
|
||||
.hid_hw_raw_request = hid_hw_raw_request,
|
||||
.hid_hw_output_report = hid_hw_output_report,
|
||||
.hid_input_report = hid_input_report,
|
||||
.owner = THIS_MODULE,
|
||||
.bus_type = &hid_bus_type,
|
||||
};
|
||||
|
@ -104,6 +104,8 @@ struct hid_bpf_ops {
|
||||
size_t len, enum hid_report_type rtype,
|
||||
enum hid_class_request reqtype);
|
||||
int (*hid_hw_output_report)(struct hid_device *hdev, __u8 *buf, size_t len);
|
||||
int (*hid_input_report)(struct hid_device *hid, enum hid_report_type type,
|
||||
u8 *data, u32 size, int interrupt);
|
||||
struct module *owner;
|
||||
const struct bus_type *bus_type;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user