Skip to content
Permalink
Browse files
HID: bpf: add bpf_hid_set_data() helper
So we can set a value of a given size (in bits) from a variable index
to the data field.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
  • Loading branch information
bentiss authored and Tero Kristo committed Dec 15, 2021
1 parent 3a1e8b0 commit 3401dc074672566b15f4f14b4fb64a8471e3b470
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 2 deletions.
@@ -303,6 +303,28 @@ static const struct bpf_func_proto bpf_hid_raw_request_proto = {
.arg5_type = ARG_ANYTHING,
};

BPF_CALL_4(bpf_hid_set_data, void*, ctx, u64, offset, u8, n, u32, data)
{
struct hid_bpf_ctx *bpf_ctx = ctx;

if (n > 32 ||
((offset + n) >> 3) >= HID_BPF_MAX_BUFFER_SIZE)
return -EINVAL;

implement(bpf_ctx->hdev, bpf_ctx->event.data, offset, n, data);
return 0;
}

static const struct bpf_func_proto bpf_hid_set_data_proto = {
.func = bpf_hid_set_data,
.gpl_only = true,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
.arg2_type = ARG_ANYTHING,
.arg3_type = ARG_ANYTHING,
.arg4_type = ARG_ANYTHING,
};

static const struct bpf_func_proto *
hid_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
@@ -313,6 +335,8 @@ hid_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
return &bpf_hid_hw_close_proto;
case BPF_FUNC_hid_raw_request:
return &bpf_hid_raw_request_proto;
case BPF_FUNC_hid_set_data:
return &bpf_hid_set_data_proto;
default:
return bpf_base_func_proto(func_id);
}
@@ -1416,8 +1416,8 @@ static void __implement(u8 *report, unsigned offset, int n, u32 value)
}
}

static void implement(const struct hid_device *hid, u8 *report,
unsigned offset, unsigned n, u32 value)
void implement(const struct hid_device *hid, u8 *report,
unsigned offset, unsigned n, u32 value)
{
if (unlikely(n > 32)) {
hid_warn(hid, "%s() called with n (%d) > 32! (%s)\n",
@@ -676,6 +676,8 @@ bool hid_compare_device_paths(struct hid_device *hdev_a,
s32 hid_snto32(__u32 value, unsigned n);
__u32 hid_field_extract(const struct hid_device *hid, __u8 *report,
unsigned offset, unsigned n);
void implement(const struct hid_device *hid, u8 *report,
unsigned offset, unsigned n, u32 value);

#ifdef CONFIG_PM
int hid_driver_suspend(struct hid_device *hdev, pm_message_t state);
@@ -4960,6 +4960,13 @@ union bpf_attr {
* signal underlaying HW to stop delivering events
* Return
* Nothing
*
* int bpf_hid_set_data(void *ctx, u64 offset, u8 n, u32 data)
* Description
* Set the data of size size at offset offset in the
* ctx->event.data field
* Return
* 0 on success, a negative error on failure.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
@@ -5145,6 +5152,7 @@ union bpf_attr {
FN(hid_raw_request), \
FN(hid_hw_open), \
FN(hid_hw_close), \
FN(hid_set_data), \
/* */

/* integer value in 'imm' field of BPF_CALL instruction selects which helper
@@ -4960,6 +4960,13 @@ union bpf_attr {
* signal underlaying HW to stop delivering events
* Return
* Nothing
*
* int bpf_hid_set_data(void *ctx, u64 offset, u8 n, u32 data)
* Description
* Set the data of size size at offset offset in the
* ctx->event.data field
* Return
* 0 on success, a negative error on failure.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
@@ -5145,6 +5152,7 @@ union bpf_attr {
FN(hid_raw_request), \
FN(hid_hw_open), \
FN(hid_hw_close), \
FN(hid_set_data), \
/* */

/* integer value in 'imm' field of BPF_CALL instruction selects which helper

0 comments on commit 3401dc0

Please sign in to comment.