lkml.org 
[lkml]   [2022]   [Mar]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH bpf-next v2 07/28] bpf/hid: add a new attach type to change the report descriptor
    Date
    The report descriptor is the dictionary of the HID protocol specific
    to the given device.
    Changing it is a common habit in the HID world, and making that feature
    accessible from eBPF allows to fix devices without having to install a
    new kernel.

    However, the report descriptor is supposed to be static on a device.
    To be able to change it, we need to reconnect the device at the HID
    level.
    So whenever the report descriptor program type is attached or detached,
    we call on a hook on HID to notify it that there is something to be
    done.

    Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>

    ---

    changes in v2:
    - split the series by bpf/libbpf/hid/selftests and samples
    - unsigned long -> __u16 in uapi/linux/bpf_hid.h
    ---
    include/linux/bpf-hid.h | 4 ++++
    include/uapi/linux/bpf.h | 1 +
    include/uapi/linux/bpf_hid.h | 1 +
    kernel/bpf/hid.c | 5 +++++
    kernel/bpf/syscall.c | 2 ++
    tools/include/uapi/linux/bpf.h | 1 +
    6 files changed, 14 insertions(+)

    diff --git a/include/linux/bpf-hid.h b/include/linux/bpf-hid.h
    index 3cda78051b5f..0c5000b28b20 100644
    --- a/include/linux/bpf-hid.h
    +++ b/include/linux/bpf-hid.h
    @@ -15,6 +15,7 @@ struct hid_device;
    enum bpf_hid_attach_type {
    BPF_HID_ATTACH_INVALID = -1,
    BPF_HID_ATTACH_DEVICE_EVENT = 0,
    + BPF_HID_ATTACH_RDESC_FIXUP,
    MAX_BPF_HID_ATTACH_TYPE
    };

    @@ -32,6 +33,8 @@ to_bpf_hid_attach_type(enum bpf_attach_type attach_type)
    switch (attach_type) {
    case BPF_HID_DEVICE_EVENT:
    return BPF_HID_ATTACH_DEVICE_EVENT;
    + case BPF_HID_RDESC_FIXUP:
    + return BPF_HID_ATTACH_RDESC_FIXUP;
    default:
    return BPF_HID_ATTACH_INVALID;
    }
    @@ -88,6 +91,7 @@ static inline bool bpf_hid_link_empty(struct bpf_hid *bpf,
    struct bpf_hid_hooks {
    struct hid_device *(*hdev_from_fd)(int fd);
    int (*link_attach)(struct hid_device *hdev, enum bpf_hid_attach_type type);
    + void (*link_attached)(struct hid_device *hdev, enum bpf_hid_attach_type type);
    void (*array_detached)(struct hid_device *hdev, enum bpf_hid_attach_type type);
    };

    diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
    index 5978b92cacd3..a7a8d9cfcf24 100644
    --- a/include/uapi/linux/bpf.h
    +++ b/include/uapi/linux/bpf.h
    @@ -999,6 +999,7 @@ enum bpf_attach_type {
    BPF_SK_REUSEPORT_SELECT_OR_MIGRATE,
    BPF_PERF_EVENT,
    BPF_HID_DEVICE_EVENT,
    + BPF_HID_RDESC_FIXUP,
    __MAX_BPF_ATTACH_TYPE
    };

    diff --git a/include/uapi/linux/bpf_hid.h b/include/uapi/linux/bpf_hid.h
    index 975ca5bd526f..634f17c0b1cb 100644
    --- a/include/uapi/linux/bpf_hid.h
    +++ b/include/uapi/linux/bpf_hid.h
    @@ -24,6 +24,7 @@ struct hid_device;
    enum hid_bpf_event {
    HID_BPF_UNDEF = 0,
    HID_BPF_DEVICE_EVENT, /* when attach type is BPF_HID_DEVICE_EVENT */
    + HID_BPF_RDESC_FIXUP, /* ................... BPF_HID_RDESC_FIXUP */
    };

    struct hid_bpf_ctx {
    diff --git a/kernel/bpf/hid.c b/kernel/bpf/hid.c
    index db7f75a0a812..37500313e270 100644
    --- a/kernel/bpf/hid.c
    +++ b/kernel/bpf/hid.c
    @@ -315,6 +315,8 @@ static int bpf_hid_max_progs(enum bpf_hid_attach_type type)
    switch (type) {
    case BPF_HID_ATTACH_DEVICE_EVENT:
    return 64;
    + case BPF_HID_ATTACH_RDESC_FIXUP:
    + return 1;
    default:
    return 0;
    }
    @@ -355,6 +357,9 @@ static int bpf_hid_link_attach(struct hid_device *hdev, struct bpf_link *link,
    lockdep_is_held(&bpf_hid_mutex));
    bpf_prog_array_free(run_array);

    + if (hid_hooks.link_attached)
    + hid_hooks.link_attached(hdev, type);
    +
    out_unlock:
    mutex_unlock(&bpf_hid_mutex);
    return err;
    diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
    index a94e78ec3211..7428a1a512c6 100644
    --- a/kernel/bpf/syscall.c
    +++ b/kernel/bpf/syscall.c
    @@ -3203,6 +3203,7 @@ attach_type_to_prog_type(enum bpf_attach_type attach_type)
    case BPF_XDP:
    return BPF_PROG_TYPE_XDP;
    case BPF_HID_DEVICE_EVENT:
    + case BPF_HID_RDESC_FIXUP:
    return BPF_PROG_TYPE_HID;
    default:
    return BPF_PROG_TYPE_UNSPEC;
    @@ -3348,6 +3349,7 @@ static int bpf_prog_query(const union bpf_attr *attr,
    case BPF_SK_SKB_VERDICT:
    return sock_map_bpf_prog_query(attr, uattr);
    case BPF_HID_DEVICE_EVENT:
    + case BPF_HID_RDESC_FIXUP:
    return bpf_hid_prog_query(attr, uattr);
    default:
    return -EINVAL;
    diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
    index 5978b92cacd3..a7a8d9cfcf24 100644
    --- a/tools/include/uapi/linux/bpf.h
    +++ b/tools/include/uapi/linux/bpf.h
    @@ -999,6 +999,7 @@ enum bpf_attach_type {
    BPF_SK_REUSEPORT_SELECT_OR_MIGRATE,
    BPF_PERF_EVENT,
    BPF_HID_DEVICE_EVENT,
    + BPF_HID_RDESC_FIXUP,
    __MAX_BPF_ATTACH_TYPE
    };

    --
    2.35.1
    \
     
     \ /
      Last update: 2022-03-04 18:32    [W:4.201 / U:0.156 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site