Linux Input/HID development
 help / color / mirror / Atom feed
* Re: [PATCH v2 02/12] HID: hexLIN: Add support for USB LIN bus adapter
From: Christoph Fritz @ 2024-05-08  8:37 UTC (permalink / raw)
  To: Simon Horman
  Cc: Oliver Hartkopp, Marc Kleine-Budde, Vincent Mailhol,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jiri Kosina,
	Benjamin Tissoires, Greg Kroah-Hartman, Jiri Slaby,
	Sebastian Reichel, Linus Walleij, Andreas Lauser, Jonathan Corbet,
	Pavel Pisa, linux-can, netdev, devicetree, linux-input,
	linux-serial
In-Reply-To: <20240504125828.GK3167983@kernel.org>

On Sat, 2024-05-04 at 13:58 +0100, Simon Horman wrote:
> On Thu, May 02, 2024 at 09:55:24AM +0200, Christoph Fritz wrote:
> > This patch introduces driver support for the hexLIN USB LIN bus adapter,
> > enabling LIN communication over USB for both controller and responder
> > modes. The driver interfaces with the CAN_LIN framework for userland
> > connectivity.
> > 
> > For more details on the adapter, visit: https://hexdev.de/hexlin/
> > 
> > Tested-by: Andreas Lauser <andreas.lauser@mercedes-benz.com>
> > Signed-off-by: Christoph Fritz <christoph.fritz@hexdev.de>
> 
> Hi Christoph,
> 
> Some minor feedback from my side.
> 
> ...
> 
> > diff --git a/drivers/hid/hid-hexdev-hexlin.c b/drivers/hid/hid-hexdev-hexlin.c
> 
> ...
> 
> > +static int hexlin_queue_frames_insert(struct hexlin_priv_data *priv,
> > +				      const u8 *raw_data, int sz)
> > +{
> > +	struct hid_device *hdev = priv->hid_dev;
> > +	struct hexlin_frame hxf;
> > +	struct lin_frame lf;
> > +
> > +	if (sz != sizeof(struct hexlin_frame))
> > +		return -EREMOTEIO;
> > +
> > +	memcpy(&hxf, raw_data, sz);
> > +	le32_to_cpus(hxf.flags);
> > +
> > +	lf.len = hxf.len;
> > +	lf.lin_id = hxf.lin_id;
> > +	memcpy(lf.data, hxf.data, LIN_MAX_DLEN);
> > +	lf.checksum = hxf.checksum;
> > +	lf.checksum_mode = hxf.checksum_mode;
> > +
> > +	hid_dbg(hdev, "id:%02x, len:%u, data:%*ph, checksum:%02x (%s)\n",
> > +		   lf.lin_id, lf.len, lf.len, lf.data, lf.checksum,
> > +		   lf.checksum_mode ? "enhanced" : "classic");
> 
> nit: The indentation above is not quite right.
>      It should align to inside the opening '(' like this.
> 
> 	hid_dbg(hdev, "id:%02x, len:%u, data:%*ph, checksum:%02x (%s)\n",
> 		lf.lin_id, lf.len, lf.len, lf.data, lf.checksum,
> 		lf.checksum_mode ? "enhanced" : "classic");
> 
> Flagged by checkpatch.

OK

> 
> ...
> 
> > +static int hexlin_set_baudrate(struct hexlin_priv_data *priv, u16 baudrate)
> > +{
> > +	struct hexlin_baudrate_req req;
> > +	int ret;
> > +
> > +	if (baudrate < LIN_MIN_BAUDRATE || baudrate > LIN_MAX_BAUDRATE)
> > +		return -EINVAL;
> > +
> > +	req.cmd = HEXLIN_SET_BAUDRATE;
> > +	req.baudrate = cpu_to_le16(baudrate);
> 
> The type of req.baudrate is u16, a host byte-order type.
> But it is being assigned a little endian value.
> This does not seem right.
> 
> Flagged by Smatch.

In upcoming v4 I'll use __le16

> 
> > +
> > +	ret = hexlin_tx_req_status(priv, &req,
> > +				   sizeof(struct hexlin_baudrate_req));
> > +	if (ret)
> > +		hid_err(priv->hid_dev, "%s failed with %d\n", __func__, ret);
> > +
> > +	return ret;
> > +}
> 
> ...
> 
> > +static int hexlin_probe(struct hid_device *hdev,
> > +			const struct hid_device_id *id)
> > +{
> > +	struct hexlin_priv_data *priv;
> > +	int ret;
> > +
> > +	priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL);
> > +	if (!priv)
> > +		return -ENOMEM;
> > +
> > +	priv->hid_dev = hdev;
> > +	hid_set_drvdata(hdev, priv);
> > +
> > +	mutex_init(&priv->tx_lock);
> > +
> > +	ret = hid_parse(hdev);
> > +	if (ret) {
> > +		hid_err(hdev, "hid parse failed with %d\n", ret);
> > +		goto fail_and_free;
> > +	}
> > +
> > +	ret = hid_hw_start(hdev, HID_CONNECT_DRIVER);
> > +	if (ret) {
> > +		hid_err(hdev, "hid hw start failed with %d\n", ret);
> > +		goto fail_and_stop;
> > +	}
> > +
> > +	ret = hid_hw_open(hdev);
> > +	if (ret) {
> > +		hid_err(hdev, "hid hw open failed with %d\n", ret);
> > +		goto fail_and_close;
> > +	}
> > +
> > +	init_completion(&priv->wait_in_report);
> > +
> > +	hid_device_io_start(hdev);
> > +
> > +	ret = init_hw(priv);
> > +	if (ret)
> > +		goto fail_and_close;
> > +
> > +	priv->ldev = register_lin(&hdev->dev, &hexlin_ldo);
> > +	if (IS_ERR_OR_NULL(priv->ldev)) {
> > +		ret = PTR_ERR(priv->ldev);
> > +		goto fail_and_close;
> 
> Is it intentional that when priv->ldev is NULL here,
> the function will return 0?
> 
> Flagged by Smatch.

IS_ERR_OR_NULL() gets IS_ERR() in upcoming v4

> 
> > +	}
> > +
> > +	hid_hw_close(hdev);
> > +
> > +	hid_info(hdev, "hexLIN (fw-version: %u) probed\n", priv->fw_version);
> > +
> > +	return 0;
> > +
> > +fail_and_close:
> > +	hid_hw_close(hdev);
> > +fail_and_stop:
> > +	hid_hw_stop(hdev);
> > +fail_and_free:
> > +	mutex_destroy(&priv->tx_lock);
> > +	return ret;
> > +}
> 
> ...

Thanks
  -- Christoph

^ permalink raw reply

* Re: [PATCH v2 01/12] can: Add LIN bus as CAN abstraction
From: Christoph Fritz @ 2024-05-08  8:37 UTC (permalink / raw)
  To: Simon Horman
  Cc: Oliver Hartkopp, Marc Kleine-Budde, Vincent Mailhol,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jiri Kosina,
	Benjamin Tissoires, Greg Kroah-Hartman, Jiri Slaby,
	Sebastian Reichel, Linus Walleij, Andreas Lauser, Jonathan Corbet,
	Pavel Pisa, linux-can, netdev, devicetree, linux-input,
	linux-serial
In-Reply-To: <20240504124904.GJ3167983@kernel.org>

On Sat, 2024-05-04 at 13:49 +0100, Simon Horman wrote:
> On Thu, May 02, 2024 at 09:55:23AM +0200, Christoph Fritz wrote:
> > This patch adds a LIN (local interconnect network) bus abstraction on
> > top of CAN.  It is a glue driver adapting CAN on one side while offering
> > LIN abstraction on the other side. So that upcoming LIN device drivers
> > can make use of it.
> > 
> > Tested-by: Andreas Lauser <andreas.lauser@mercedes-benz.com>
> > Signed-off-by: Christoph Fritz <christoph.fritz@hexdev.de>
> 
> ...
> 
> > diff --git a/drivers/net/can/lin.c b/drivers/net/can/lin.c
> 
> ...
> 
> > +struct lin_device *register_lin(struct device *dev,
> > +				const struct lin_device_ops *ldops)
> > +{
> > +	struct net_device *ndev;
> > +	struct lin_device *ldev;
> > +	int ret;
> > +
> > +	if (!ldops || !ldops->ldo_tx || !ldops->update_bitrate  ||
> > +	    !ldops->ldo_open || !ldops->ldo_stop) {
> > +		netdev_err(ndev, "missing mandatory lin_device_ops\n");
> 
> Hi Christoph,

Hi Simon

> The line above uses ndev, but ndev is not initialised
> until a few lines further down.
> 
> Flagged by Smatch.

Despite netdev_err() checks validity of ndev, I agree with Smatch: In
upcoming v4 I'll use dev_err() here instead.

> > +		return ERR_PTR(-EINVAL);
> > +	}
> > +
> > +	ndev = alloc_candev(sizeof(struct lin_device), 1);
> > +	if (!ndev)
> > +		return ERR_PTR(-ENOMEM);
> > +
> > +	ldev = netdev_priv(ndev);
> > +
> > +	ldev->ldev_ops = ldops;
> > +	ndev->netdev_ops = &lin_netdev_ops;
> > +	ndev->flags |= IFF_ECHO;
> > +	ndev->mtu = CANFD_MTU;
> > +	ldev->can.bittiming.bitrate = LIN_DEFAULT_BAUDRATE;
> > +	ldev->can.ctrlmode = CAN_CTRLMODE_LIN;
> > +	ldev->can.ctrlmode_supported = 0;
> > +	ldev->can.bitrate_const = lin_bitrate;
> > +	ldev->can.bitrate_const_cnt = ARRAY_SIZE(lin_bitrate);
> > +	ldev->can.do_set_bittiming = lin_set_bittiming;
> > +	ldev->ndev = ndev;
> > +	ldev->dev = dev;
> > +
> > +	SET_NETDEV_DEV(ndev, dev);
> > +
> > +	ret = lin_set_bittiming(ndev);
> > +	if (ret) {
> > +		netdev_err(ndev, "set bittiming failed\n");
> > +		goto exit_candev;
> > +	}
> > +
> > +	ret = register_candev(ndev);
> > +	if (ret)
> > +		goto exit_candev;
> > +
> > +	ldev->lin_ids_kobj = kobject_create_and_add("lin_ids", &ndev->dev.kobj);
> > +	if (!ldev->lin_ids_kobj) {
> > +		netdev_err(ndev, "Failed to create sysfs directory\n");
> > +		ret = -ENOMEM;
> > +		goto exit_unreg;
> > +	}
> > +
> > +	ret = lin_create_sysfs_id_files(ndev);
> > +	if (ret) {
> > +		netdev_err(ndev, "Failed to create sysfs entry: %d\n", ret);
> > +		goto exit_kobj_put;
> > +	}
> > +
> > +	/* Using workqueue as tx over USB/SPI/... may sleep */
> > +	ldev->wq = alloc_workqueue(dev_name(dev), WQ_FREEZABLE | WQ_MEM_RECLAIM,
> > +				   0);
> > +	if (!ldev->wq)
> > +		goto exit_rm_files;
> 
> The goto above will result in: return ERR_PTR(ret)
> But ret is 0 here. Should it be set to a negative error value?
> 
> Also flagged by Smatch.

OK, will get an

ret = -ENOMEM;

> 
> > +
> > +	INIT_WORK(&ldev->tx_work, lin_tx_work_handler);
> > +
> > +	netdev_info(ndev, "LIN initialized.\n");
> > +
> > +	return ldev;
> > +
> > +exit_rm_files:
> > +	lin_remove_sysfs_id_files(ndev);
> > +exit_kobj_put:
> > +	kobject_put(ldev->lin_ids_kobj);
> > +exit_unreg:
> > +	unregister_candev(ndev);
> > +exit_candev:
> > +	free_candev(ndev);
> > +	return ERR_PTR(ret);
> > +}
> > +EXPORT_SYMBOL_GPL(register_lin);
> 
> ...

Thanks
  -- Christoph

^ permalink raw reply

* Re: [PATCH v2 07/12] can: Add support for serdev LIN adapters
From: Christoph Fritz @ 2024-05-08  8:37 UTC (permalink / raw)
  To: Simon Horman
  Cc: Oliver Hartkopp, Marc Kleine-Budde, Vincent Mailhol,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jiri Kosina,
	Benjamin Tissoires, Greg Kroah-Hartman, Jiri Slaby,
	Sebastian Reichel, Linus Walleij, Andreas Lauser, Jonathan Corbet,
	Pavel Pisa, linux-can, netdev, devicetree, linux-input,
	linux-serial
In-Reply-To: <20240504131331.GL3167983@kernel.org>

On Sat, 2024-05-04 at 14:13 +0100, Simon Horman wrote:
> On Thu, May 02, 2024 at 09:55:29AM +0200, Christoph Fritz wrote:
> > This commit introduces LIN-Bus support for UART devices equipped with
> > LIN transceivers, utilizing the Serial Device Bus (serdev) interface.
> > 
> > For more details on an adapter, visit: https://hexdev.de/hexlin#tty
> > 
> > Signed-off-by: Christoph Fritz <christoph.fritz@hexdev.de>
> 
> ...
> 
> > diff --git a/drivers/net/can/lin-serdev.c b/drivers/net/can/lin-serdev.c
> 
> ...
> 
> > +static int linser_probe(struct serdev_device *serdev)
> > +{
> > +	struct linser_priv *priv;
> > +	int ret;
> > +
> > +	priv = devm_kzalloc(&serdev->dev, sizeof(*priv), GFP_KERNEL);
> > +	if (!priv)
> > +		return -ENOMEM;
> > +
> > +	ret = kfifo_alloc(&priv->rx_fifo, LINSER_RX_FIFO_SIZE, GFP_KERNEL);
> > +	if (ret)
> > +		return ret;
> > +
> > +	INIT_DELAYED_WORK(&priv->rx_work, linser_process_delayed);
> > +
> > +	priv->serdev = serdev;
> > +	serdev_device_set_drvdata(serdev, priv);
> > +	serdev_device_set_client_ops(serdev, &linser_ops);
> > +
> > +	ret = serdev_device_open(serdev);
> > +	if (ret) {
> > +		dev_err(&serdev->dev, "Unable to open device\n");
> > +		goto err_open;
> > +	}
> > +
> > +	serdev_device_set_flow_control(serdev, false);
> > +	serdev_device_set_break_detection(serdev, true);
> > +	linser_derive_timings(priv, LIN_DEFAULT_BAUDRATE);
> > +
> > +	mutex_init(&priv->resp_lock);
> > +
> > +	priv->lin_dev = register_lin(&serdev->dev, &linser_lindev_ops);
> > +	if (IS_ERR_OR_NULL(priv->lin_dev)) {
> > +		ret = PTR_ERR(priv->lin_dev);
> 
> As per my feedback on an earlier patch in the series,
> in the case where priv->lin_dev is NULL,
> this will result in the function returning 0.
> Is that ok?
> 
> Flagged by Smatch

IS_ERR_OR_NULL() gets IS_ERR() in upcoming v4

Thanks
  -- Christoph

> 
> > +		goto err_register_lin;
> > +	}
> > +
> > +	serdev_device_close(serdev);
> > +	priv->is_stopped = true;
> > +
> > +	return 0;
> > +
> > +err_register_lin:
> > +	serdev_device_close(serdev);
> > +err_open:
> > +	kfifo_free(&priv->rx_fifo);
> > +	return ret;
> > +}
> 
> ...


^ permalink raw reply

* Re: [PATCH] Input: goodix-berlin - Add sysfs interface for reading and writing touch IC registers
From: Richard Hughes @ 2024-05-08  8:39 UTC (permalink / raw)
  To: Mark Brown
  Cc: Dmitry Torokhov, Jeff LaBundy, Hans de Goede, Charles Wang,
	hadess, linux-input, linux-kernel, neil.armstrong
In-Reply-To: <ZjrledLjn8RsGiwC@finisterre.sirena.org.uk>

On Wed, 8 May 2024 at 03:37, Mark Brown <broonie@kernel.org> wrote:
> The other model I've seen used BTW is to expose a MTD device, if the
> device actually looks like a MTD device (perhaps even is just a flash
> that's fairly directly exposed) that minimises the kernel code quite
> well.

If it helps, fwupd already uses mtd for other devices too, although at
the moment we're using it only for system firmware -- e.g. intel-spi
style. The MTD subsystem doesn't give fwupd much info about the
{removable} device itself, and that can pose a problem unless you
start using heuristics about the parent device to match firmware to
the mtd device.

Richard.

^ permalink raw reply

* Re: [PATCH v3 03/11] tty: serdev: Add flag buffer aware receive_buf_fp()
From: Christoph Fritz @ 2024-05-08  8:48 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Jiri Slaby, Oliver Hartkopp, Marc Kleine-Budde, Vincent Mailhol,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jiri Kosina,
	Benjamin Tissoires, Sebastian Reichel, Linus Walleij,
	Andreas Lauser, Jonathan Corbet, Pavel Pisa, linux-can, netdev,
	devicetree, linux-input, linux-serial
In-Reply-To: <2024050410-gigolo-giddily-97b6@gregkh>

On Sat, 2024-05-04 at 18:00 +0200, Greg Kroah-Hartman wrote:
> On Thu, May 02, 2024 at 08:27:56PM +0200, Christoph Fritz wrote:
> > This patch introduces an additional receive buffer callback variation
> > besides the already existing receive_buf(). This new callback function
> > also passes the flag buffer (TTY_NORMAL, TTY_BREAK, and friends).
> > 
> > If defined, this function gets prioritized and called instead of the
> > standard receive_buf().
> > 
> > An alternative approach could have been to enhance the receive_buf()
> > function and update all drivers that use it.
> 
> Please, let's do that instead of adding random letters at the end of a
> function pointer :)

:) sure

> 
> > Signed-off-by: Christoph Fritz <christoph.fritz@hexdev.de>
> > ---
> >  drivers/tty/serdev/serdev-ttyport.c |  2 +-
> >  include/linux/serdev.h              | 17 ++++++++++++++---
> >  2 files changed, 15 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c
> > index 3d7ae7fa50186..bb47691afdb21 100644
> > --- a/drivers/tty/serdev/serdev-ttyport.c
> > +++ b/drivers/tty/serdev/serdev-ttyport.c
> > @@ -32,7 +32,7 @@ static size_t ttyport_receive_buf(struct tty_port *port, const u8 *cp,
> >  	if (!test_bit(SERPORT_ACTIVE, &serport->flags))
> >  		return 0;
> >  
> > -	ret = serdev_controller_receive_buf(ctrl, cp, count);
> > +	ret = serdev_controller_receive_buf(ctrl, cp, fp, count);
> >  
> >  	dev_WARN_ONCE(&ctrl->dev, ret > count,
> >  				"receive_buf returns %zu (count = %zu)\n",
> > diff --git a/include/linux/serdev.h b/include/linux/serdev.h
> > index ff78efc1f60df..c6ef5a8988e07 100644
> > --- a/include/linux/serdev.h
> > +++ b/include/linux/serdev.h
> > @@ -23,11 +23,17 @@ struct serdev_device;
> >   * struct serdev_device_ops - Callback operations for a serdev device
> >   * @receive_buf:	Function called with data received from device;
> >   *			returns number of bytes accepted; may sleep.
> > + * @receive_buf_fp:	Function called with data and flag buffer received
> > + *			from device; If defined, this function gets called
> > + *			instead of @receive_buf;
> > + *			returns number of bytes accepted; may sleep.
> 
> I don't remember waht "fp" means here, and you don't document it, so
> let's just have one recieve_buf() callback please.

OK, that is a great opportunity for me to use Coccinelle. In the
upcoming revision v4 I'll add the "flag buffer pointer" treewide, then
named "flags".

thanks
  -- Christoph

^ permalink raw reply

* [PATCH RFC HID 0/7] Use the new __s_async for HID-BPF
From: Benjamin Tissoires @ 2024-05-08 10:26 UTC (permalink / raw)
  To: Benjamin Tissoires; +Cc: linux-kernel, linux-input, bpf, Benjamin Tissoires

This is not meant to be applied as of now.

This is just to show what I meant for [0].

And of course, this doesn't even compile because you need [0] to be
applied and the branch for-6.10/hid-bpf on the hid tree.

The purpose is to remove the bpf_tail_call from the preloaded bpf at
boot time.

Cheers,
Benjamin

[0] https://lore.kernel.org/bpf/20240507-bpf_async-v1-0-b4df966096d8@kernel.org/v

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
Benjamin Tissoires (7):
      HID: bpf: change the prog run logic
      selftests/hid: fix bpf programs for the new attachment logic
      HID: bpf: allow for sleepable bpf hooks
      HID: add source argument to HID low level functions
      WIP: add HID-BPF hooks for hid_hw_raw_requests
      WIP: selftests/hid: add tests for hid_hw_raw_request HID-BPF hooks
      HID: bpf: prevent infinite recursions with hid_hw_raw_requests hooks

 drivers/hid/bpf/entrypoints/Makefile               |  93 --------
 drivers/hid/bpf/entrypoints/README                 |   4 -
 drivers/hid/bpf/entrypoints/entrypoints.bpf.c      |  25 --
 drivers/hid/bpf/entrypoints/entrypoints.lskel.h    | 248 --------------------
 drivers/hid/bpf/hid_bpf_dispatch.c                 | 252 +++++++++++----------
 drivers/hid/bpf/hid_bpf_dispatch.h                 |  12 +-
 drivers/hid/bpf/hid_bpf_jmp_table.c                | 199 ++++------------
 drivers/hid/hid-core.c                             |  91 +++++---
 drivers/hid/hidraw.c                               |  10 +-
 include/linux/hid.h                                |   6 +
 include/linux/hid_bpf.h                            |  33 ++-
 tools/testing/selftests/hid/hid_bpf.c              |  61 ++++-
 tools/testing/selftests/hid/progs/hid.c            |  91 +++++---
 .../testing/selftests/hid/progs/hid_bpf_helpers.h  |  60 ++++-
 14 files changed, 449 insertions(+), 736 deletions(-)
---
base-commit: 89ea968a9d759f71ac7b8d50949a8e5e5bcb1111
change-id: 20240508-hid_bpf_async_fun-25a8b97b5352

Best regards,
-- 
Benjamin Tissoires <bentiss@kernel.org>


^ permalink raw reply

* [PATCH RFC HID 1/7] HID: bpf: change the prog run logic
From: Benjamin Tissoires @ 2024-05-08 10:26 UTC (permalink / raw)
  To: Benjamin Tissoires; +Cc: linux-kernel, linux-input, bpf, Benjamin Tissoires
In-Reply-To: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org>

We were previously relying on a pre-loaded tracing bpf program which runs
bpf_tail_call(). However we can simplify this by a lot by relying on
the new __async suffix which gives us basically a function pointer to
the bpf program itself. This way, we rely on a much simpler process,
ditching entirely the prog fd array and that tracing bpf program.

Note the selftests will break and are handled in the later patch.

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 drivers/hid/bpf/entrypoints/Makefile            |  93 ---------
 drivers/hid/bpf/entrypoints/README              |   4 -
 drivers/hid/bpf/entrypoints/entrypoints.bpf.c   |  25 ---
 drivers/hid/bpf/entrypoints/entrypoints.lskel.h | 248 ------------------------
 drivers/hid/bpf/hid_bpf_dispatch.c              |  94 ++-------
 drivers/hid/bpf/hid_bpf_dispatch.h              |   8 +-
 drivers/hid/bpf/hid_bpf_jmp_table.c             | 174 +++--------------
 include/linux/hid_bpf.h                         |   3 -
 8 files changed, 51 insertions(+), 598 deletions(-)

diff --git a/drivers/hid/bpf/entrypoints/Makefile b/drivers/hid/bpf/entrypoints/Makefile
deleted file mode 100644
index 43b99b5575cf..000000000000
--- a/drivers/hid/bpf/entrypoints/Makefile
+++ /dev/null
@@ -1,93 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-OUTPUT := .output
-abs_out := $(abspath $(OUTPUT))
-
-CLANG ?= clang
-LLC ?= llc
-LLVM_STRIP ?= llvm-strip
-
-TOOLS_PATH := $(abspath ../../../../tools)
-BPFTOOL_SRC := $(TOOLS_PATH)/bpf/bpftool
-BPFTOOL_OUTPUT := $(abs_out)/bpftool
-DEFAULT_BPFTOOL := $(BPFTOOL_OUTPUT)/bootstrap/bpftool
-BPFTOOL ?= $(DEFAULT_BPFTOOL)
-
-LIBBPF_SRC := $(TOOLS_PATH)/lib/bpf
-LIBBPF_OUTPUT := $(abs_out)/libbpf
-LIBBPF_DESTDIR := $(LIBBPF_OUTPUT)
-LIBBPF_INCLUDE := $(LIBBPF_DESTDIR)/include
-BPFOBJ := $(LIBBPF_OUTPUT)/libbpf.a
-
-INCLUDES := -I$(OUTPUT) -I$(LIBBPF_INCLUDE) -I$(TOOLS_PATH)/include/uapi
-CFLAGS := -g -Wall
-
-VMLINUX_BTF_PATHS ?= $(if $(O),$(O)/vmlinux)				\
-		     $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux)	\
-		     ../../../../vmlinux				\
-		     /sys/kernel/btf/vmlinux				\
-		     /boot/vmlinux-$(shell uname -r)
-VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS))))
-ifeq ($(VMLINUX_BTF),)
-$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)")
-endif
-
-ifeq ($(V),1)
-Q =
-msg =
-else
-Q = @
-msg = @printf '  %-8s %s%s\n' "$(1)" "$(notdir $(2))" "$(if $(3), $(3))";
-MAKEFLAGS += --no-print-directory
-submake_extras := feature_display=0
-endif
-
-.DELETE_ON_ERROR:
-
-.PHONY: all clean
-
-all: entrypoints.lskel.h
-
-clean:
-	$(call msg,CLEAN)
-	$(Q)rm -rf $(OUTPUT) entrypoints
-
-entrypoints.lskel.h: $(OUTPUT)/entrypoints.bpf.o | $(BPFTOOL)
-	$(call msg,GEN-SKEL,$@)
-	$(Q)$(BPFTOOL) gen skeleton -L $< > $@
-
-
-$(OUTPUT)/entrypoints.bpf.o: entrypoints.bpf.c $(OUTPUT)/vmlinux.h $(BPFOBJ) | $(OUTPUT)
-	$(call msg,BPF,$@)
-	$(Q)$(CLANG) -g -O2 --target=bpf $(INCLUDES)			      \
-		 -c $(filter %.c,$^) -o $@ &&				      \
-	$(LLVM_STRIP) -g $@
-
-$(OUTPUT)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL) | $(INCLUDE_DIR)
-ifeq ($(VMLINUX_H),)
-	$(call msg,GEN,,$@)
-	$(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@
-else
-	$(call msg,CP,,$@)
-	$(Q)cp "$(VMLINUX_H)" $@
-endif
-
-$(OUTPUT) $(LIBBPF_OUTPUT) $(BPFTOOL_OUTPUT):
-	$(call msg,MKDIR,$@)
-	$(Q)mkdir -p $@
-
-$(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(LIBBPF_OUTPUT)
-	$(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC)			       \
-		    OUTPUT=$(abspath $(dir $@))/ prefix=		       \
-		    DESTDIR=$(LIBBPF_DESTDIR) $(abspath $@) install_headers
-
-ifeq ($(CROSS_COMPILE),)
-$(DEFAULT_BPFTOOL): $(BPFOBJ) | $(BPFTOOL_OUTPUT)
-	$(Q)$(MAKE) $(submake_extras) -C $(BPFTOOL_SRC)			       \
-		    OUTPUT=$(BPFTOOL_OUTPUT)/				       \
-		    LIBBPF_BOOTSTRAP_OUTPUT=$(LIBBPF_OUTPUT)/		       \
-		    LIBBPF_BOOTSTRAP_DESTDIR=$(LIBBPF_DESTDIR)/ bootstrap
-else
-$(DEFAULT_BPFTOOL): | $(BPFTOOL_OUTPUT)
-	$(Q)$(MAKE) $(submake_extras) -C $(BPFTOOL_SRC)			       \
-		    OUTPUT=$(BPFTOOL_OUTPUT)/ bootstrap
-endif
diff --git a/drivers/hid/bpf/entrypoints/README b/drivers/hid/bpf/entrypoints/README
deleted file mode 100644
index 147e0d41509f..000000000000
--- a/drivers/hid/bpf/entrypoints/README
+++ /dev/null
@@ -1,4 +0,0 @@
-WARNING:
-If you change "entrypoints.bpf.c" do "make -j" in this directory to rebuild "entrypoints.skel.h".
-Make sure to have clang 10 installed.
-See Documentation/bpf/bpf_devel_QA.rst
diff --git a/drivers/hid/bpf/entrypoints/entrypoints.bpf.c b/drivers/hid/bpf/entrypoints/entrypoints.bpf.c
deleted file mode 100644
index c22921125a1a..000000000000
--- a/drivers/hid/bpf/entrypoints/entrypoints.bpf.c
+++ /dev/null
@@ -1,25 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright (c) 2022 Benjamin Tissoires */
-
-#include ".output/vmlinux.h"
-#include <bpf/bpf_helpers.h>
-#include <bpf/bpf_tracing.h>
-
-#define HID_BPF_MAX_PROGS 1024
-
-struct {
-	__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
-	__uint(max_entries, HID_BPF_MAX_PROGS);
-	__uint(key_size, sizeof(__u32));
-	__uint(value_size, sizeof(__u32));
-} hid_jmp_table SEC(".maps");
-
-SEC("fmod_ret/__hid_bpf_tail_call")
-int BPF_PROG(hid_tail_call, struct hid_bpf_ctx *hctx)
-{
-	bpf_tail_call(ctx, &hid_jmp_table, hctx->index);
-
-	return 0;
-}
-
-char LICENSE[] SEC("license") = "GPL";
diff --git a/drivers/hid/bpf/entrypoints/entrypoints.lskel.h b/drivers/hid/bpf/entrypoints/entrypoints.lskel.h
deleted file mode 100644
index 35618051598c..000000000000
--- a/drivers/hid/bpf/entrypoints/entrypoints.lskel.h
+++ /dev/null
@@ -1,248 +0,0 @@
-/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
-/* THIS FILE IS AUTOGENERATED BY BPFTOOL! */
-#ifndef __ENTRYPOINTS_BPF_SKEL_H__
-#define __ENTRYPOINTS_BPF_SKEL_H__
-
-#include <bpf/skel_internal.h>
-
-struct entrypoints_bpf {
-	struct bpf_loader_ctx ctx;
-	struct {
-		struct bpf_map_desc hid_jmp_table;
-	} maps;
-	struct {
-		struct bpf_prog_desc hid_tail_call;
-	} progs;
-	struct {
-		int hid_tail_call_fd;
-	} links;
-};
-
-static inline int
-entrypoints_bpf__hid_tail_call__attach(struct entrypoints_bpf *skel)
-{
-	int prog_fd = skel->progs.hid_tail_call.prog_fd;
-	int fd = skel_raw_tracepoint_open(NULL, prog_fd);
-
-	if (fd > 0)
-		skel->links.hid_tail_call_fd = fd;
-	return fd;
-}
-
-static inline int
-entrypoints_bpf__attach(struct entrypoints_bpf *skel)
-{
-	int ret = 0;
-
-	ret = ret < 0 ? ret : entrypoints_bpf__hid_tail_call__attach(skel);
-	return ret < 0 ? ret : 0;
-}
-
-static inline void
-entrypoints_bpf__detach(struct entrypoints_bpf *skel)
-{
-	skel_closenz(skel->links.hid_tail_call_fd);
-}
-static void
-entrypoints_bpf__destroy(struct entrypoints_bpf *skel)
-{
-	if (!skel)
-		return;
-	entrypoints_bpf__detach(skel);
-	skel_closenz(skel->progs.hid_tail_call.prog_fd);
-	skel_closenz(skel->maps.hid_jmp_table.map_fd);
-	skel_free(skel);
-}
-static inline struct entrypoints_bpf *
-entrypoints_bpf__open(void)
-{
-	struct entrypoints_bpf *skel;
-
-	skel = skel_alloc(sizeof(*skel));
-	if (!skel)
-		goto cleanup;
-	skel->ctx.sz = (void *)&skel->links - (void *)skel;
-	return skel;
-cleanup:
-	entrypoints_bpf__destroy(skel);
-	return NULL;
-}
-
-static inline int
-entrypoints_bpf__load(struct entrypoints_bpf *skel)
-{
-	struct bpf_load_and_run_opts opts = {};
-	int err;
-
-	opts.ctx = (struct bpf_loader_ctx *)skel;
-	opts.data_sz = 2856;
-	opts.data = (void *)"\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x9f\xeb\x01\0\
-\x18\0\0\0\0\0\0\0\x60\x02\0\0\x60\x02\0\0\x12\x02\0\0\0\0\0\0\0\0\0\x02\x03\0\
-\0\0\x01\0\0\0\0\0\0\x01\x04\0\0\0\x20\0\0\x01\0\0\0\0\0\0\0\x03\0\0\0\0\x02\0\
-\0\0\x04\0\0\0\x03\0\0\0\x05\0\0\0\0\0\0\x01\x04\0\0\0\x20\0\0\0\0\0\0\0\0\0\0\
-\x02\x06\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\0\x04\0\0\0\0\0\0\
-\0\0\0\x02\x08\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\x04\0\0\0\0\
-\0\0\0\x04\0\0\x04\x20\0\0\0\x19\0\0\0\x01\0\0\0\0\0\0\0\x1e\0\0\0\x05\0\0\0\
-\x40\0\0\0\x2a\0\0\0\x07\0\0\0\x80\0\0\0\x33\0\0\0\x07\0\0\0\xc0\0\0\0\x3e\0\0\
-\0\0\0\0\x0e\x09\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\x02\x0c\0\0\0\x4c\0\0\0\0\0\0\
-\x01\x08\0\0\0\x40\0\0\0\0\0\0\0\x01\0\0\x0d\x02\0\0\0\x5f\0\0\0\x0b\0\0\0\x63\
-\0\0\0\x01\0\0\x0c\x0d\0\0\0\x09\x01\0\0\x05\0\0\x04\x20\0\0\0\x15\x01\0\0\x10\
-\0\0\0\0\0\0\0\x1b\x01\0\0\x12\0\0\0\x40\0\0\0\x1f\x01\0\0\x10\0\0\0\x80\0\0\0\
-\x2e\x01\0\0\x14\0\0\0\xa0\0\0\0\0\0\0\0\x15\0\0\0\xc0\0\0\0\x3a\x01\0\0\0\0\0\
-\x08\x11\0\0\0\x40\x01\0\0\0\0\0\x01\x04\0\0\0\x20\0\0\0\0\0\0\0\0\0\0\x02\x13\
-\0\0\0\0\0\0\0\0\0\0\x0a\x1c\0\0\0\x4d\x01\0\0\x04\0\0\x06\x04\0\0\0\x5d\x01\0\
-\0\0\0\0\0\x6e\x01\0\0\x01\0\0\0\x80\x01\0\0\x02\0\0\0\x93\x01\0\0\x03\0\0\0\0\
-\0\0\0\x02\0\0\x05\x04\0\0\0\xa4\x01\0\0\x16\0\0\0\0\0\0\0\xab\x01\0\0\x16\0\0\
-\0\0\0\0\0\xb0\x01\0\0\0\0\0\x08\x02\0\0\0\xec\x01\0\0\0\0\0\x01\x01\0\0\0\x08\
-\0\0\x01\0\0\0\0\0\0\0\x03\0\0\0\0\x17\0\0\0\x04\0\0\0\x04\0\0\0\xf1\x01\0\0\0\
-\0\0\x0e\x18\0\0\0\x01\0\0\0\xf9\x01\0\0\x01\0\0\x0f\x20\0\0\0\x0a\0\0\0\0\0\0\
-\0\x20\0\0\0\xff\x01\0\0\x01\0\0\x0f\x04\0\0\0\x19\0\0\0\0\0\0\0\x04\0\0\0\x07\
-\x02\0\0\0\0\0\x07\0\0\0\0\0\x69\x6e\x74\0\x5f\x5f\x41\x52\x52\x41\x59\x5f\x53\
-\x49\x5a\x45\x5f\x54\x59\x50\x45\x5f\x5f\0\x74\x79\x70\x65\0\x6d\x61\x78\x5f\
-\x65\x6e\x74\x72\x69\x65\x73\0\x6b\x65\x79\x5f\x73\x69\x7a\x65\0\x76\x61\x6c\
-\x75\x65\x5f\x73\x69\x7a\x65\0\x68\x69\x64\x5f\x6a\x6d\x70\x5f\x74\x61\x62\x6c\
-\x65\0\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x6c\x6f\x6e\x67\x20\x6c\x6f\x6e\x67\
-\0\x63\x74\x78\0\x68\x69\x64\x5f\x74\x61\x69\x6c\x5f\x63\x61\x6c\x6c\0\x66\x6d\
-\x6f\x64\x5f\x72\x65\x74\x2f\x5f\x5f\x68\x69\x64\x5f\x62\x70\x66\x5f\x74\x61\
-\x69\x6c\x5f\x63\x61\x6c\x6c\0\x2f\x68\x6f\x6d\x65\x2f\x62\x74\x69\x73\x73\x6f\
-\x69\x72\x2f\x53\x72\x63\x2f\x68\x69\x64\x2f\x64\x72\x69\x76\x65\x72\x73\x2f\
-\x68\x69\x64\x2f\x62\x70\x66\x2f\x65\x6e\x74\x72\x79\x70\x6f\x69\x6e\x74\x73\
-\x2f\x65\x6e\x74\x72\x79\x70\x6f\x69\x6e\x74\x73\x2e\x62\x70\x66\x2e\x63\0\x69\
-\x6e\x74\x20\x42\x50\x46\x5f\x50\x52\x4f\x47\x28\x68\x69\x64\x5f\x74\x61\x69\
-\x6c\x5f\x63\x61\x6c\x6c\x2c\x20\x73\x74\x72\x75\x63\x74\x20\x68\x69\x64\x5f\
-\x62\x70\x66\x5f\x63\x74\x78\x20\x2a\x68\x63\x74\x78\x29\0\x68\x69\x64\x5f\x62\
-\x70\x66\x5f\x63\x74\x78\0\x69\x6e\x64\x65\x78\0\x68\x69\x64\0\x61\x6c\x6c\x6f\
-\x63\x61\x74\x65\x64\x5f\x73\x69\x7a\x65\0\x72\x65\x70\x6f\x72\x74\x5f\x74\x79\
-\x70\x65\0\x5f\x5f\x75\x33\x32\0\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x69\x6e\
-\x74\0\x68\x69\x64\x5f\x72\x65\x70\x6f\x72\x74\x5f\x74\x79\x70\x65\0\x48\x49\
-\x44\x5f\x49\x4e\x50\x55\x54\x5f\x52\x45\x50\x4f\x52\x54\0\x48\x49\x44\x5f\x4f\
-\x55\x54\x50\x55\x54\x5f\x52\x45\x50\x4f\x52\x54\0\x48\x49\x44\x5f\x46\x45\x41\
-\x54\x55\x52\x45\x5f\x52\x45\x50\x4f\x52\x54\0\x48\x49\x44\x5f\x52\x45\x50\x4f\
-\x52\x54\x5f\x54\x59\x50\x45\x53\0\x72\x65\x74\x76\x61\x6c\0\x73\x69\x7a\x65\0\
-\x5f\x5f\x73\x33\x32\0\x30\x3a\x30\0\x09\x62\x70\x66\x5f\x74\x61\x69\x6c\x5f\
-\x63\x61\x6c\x6c\x28\x63\x74\x78\x2c\x20\x26\x68\x69\x64\x5f\x6a\x6d\x70\x5f\
-\x74\x61\x62\x6c\x65\x2c\x20\x68\x63\x74\x78\x2d\x3e\x69\x6e\x64\x65\x78\x29\
-\x3b\0\x63\x68\x61\x72\0\x4c\x49\x43\x45\x4e\x53\x45\0\x2e\x6d\x61\x70\x73\0\
-\x6c\x69\x63\x65\x6e\x73\x65\0\x68\x69\x64\x5f\x64\x65\x76\x69\x63\x65\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x8a\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\
-\0\0\0\x04\0\0\0\x04\0\0\0\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x68\x69\x64\x5f\
-\x6a\x6d\x70\x5f\x74\x61\x62\x6c\x65\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\x47\x50\x4c\0\0\0\0\0\x79\x12\0\0\0\0\0\0\x61\x23\0\0\0\0\
-\0\0\x18\x52\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x85\0\0\0\x0c\0\0\0\xb7\0\0\0\0\0\0\0\
-\x95\0\0\0\0\0\0\0\0\0\0\0\x0e\0\0\0\0\0\0\0\x8e\0\0\0\xd3\0\0\0\x05\x48\0\0\
-\x01\0\0\0\x8e\0\0\0\xba\x01\0\0\x02\x50\0\0\x05\0\0\0\x8e\0\0\0\xd3\0\0\0\x05\
-\x48\0\0\x08\0\0\0\x0f\0\0\0\xb6\x01\0\0\0\0\0\0\x1a\0\0\0\x07\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x68\x69\
-\x64\x5f\x74\x61\x69\x6c\x5f\x63\x61\x6c\x6c\0\0\0\0\0\0\0\x1a\0\0\0\0\0\0\0\
-\x08\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\x10\0\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\x01\0\
-\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\x5f\
-\x5f\x68\x69\x64\x5f\x62\x70\x66\x5f\x74\x61\x69\x6c\x5f\x63\x61\x6c\x6c\0\0\0\
-\0\0";
-	opts.insns_sz = 1192;
-	opts.insns = (void *)"\
-\xbf\x16\0\0\0\0\0\0\xbf\xa1\0\0\0\0\0\0\x07\x01\0\0\x78\xff\xff\xff\xb7\x02\0\
-\0\x88\0\0\0\xb7\x03\0\0\0\0\0\0\x85\0\0\0\x71\0\0\0\x05\0\x11\0\0\0\0\0\x61\
-\xa1\x78\xff\0\0\0\0\xd5\x01\x01\0\0\0\0\0\x85\0\0\0\xa8\0\0\0\x61\xa1\x7c\xff\
-\0\0\0\0\xd5\x01\x01\0\0\0\0\0\x85\0\0\0\xa8\0\0\0\x61\xa1\x80\xff\0\0\0\0\xd5\
-\x01\x01\0\0\0\0\0\x85\0\0\0\xa8\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x61\
-\x01\0\0\0\0\0\0\xd5\x01\x02\0\0\0\0\0\xbf\x19\0\0\0\0\0\0\x85\0\0\0\xa8\0\0\0\
-\xbf\x70\0\0\0\0\0\0\x95\0\0\0\0\0\0\0\x61\x60\x08\0\0\0\0\0\x18\x61\0\0\0\0\0\
-\0\0\0\0\0\xa8\x09\0\0\x63\x01\0\0\0\0\0\0\x61\x60\x0c\0\0\0\0\0\x18\x61\0\0\0\
-\0\0\0\0\0\0\0\xa4\x09\0\0\x63\x01\0\0\0\0\0\0\x79\x60\x10\0\0\0\0\0\x18\x61\0\
-\0\0\0\0\0\0\0\0\0\x98\x09\0\0\x7b\x01\0\0\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\
-\0\x05\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\x90\x09\0\0\x7b\x01\0\0\0\0\0\0\xb7\x01\
-\0\0\x12\0\0\0\x18\x62\0\0\0\0\0\0\0\0\0\0\x90\x09\0\0\xb7\x03\0\0\x1c\0\0\0\
-\x85\0\0\0\xa6\0\0\0\xbf\x07\0\0\0\0\0\0\xc5\x07\xd7\xff\0\0\0\0\x63\x7a\x78\
-\xff\0\0\0\0\x61\x60\x1c\0\0\0\0\0\x15\0\x03\0\0\0\0\0\x18\x61\0\0\0\0\0\0\0\0\
-\0\0\xbc\x09\0\0\x63\x01\0\0\0\0\0\0\xb7\x01\0\0\0\0\0\0\x18\x62\0\0\0\0\0\0\0\
-\0\0\0\xb0\x09\0\0\xb7\x03\0\0\x48\0\0\0\x85\0\0\0\xa6\0\0\0\xbf\x07\0\0\0\0\0\
-\0\xc5\x07\xca\xff\0\0\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x63\x71\0\0\0\0\
-\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\xf8\x09\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\x90\
-\x0a\0\0\x7b\x01\0\0\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\0\x0a\0\0\x18\x61\0\0\
-\0\0\0\0\0\0\0\0\x88\x0a\0\0\x7b\x01\0\0\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\
-\x38\x0a\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\xd0\x0a\0\0\x7b\x01\0\0\0\0\0\0\x18\
-\x60\0\0\0\0\0\0\0\0\0\0\x40\x0a\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\xe0\x0a\0\0\
-\x7b\x01\0\0\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\x70\x0a\0\0\x18\x61\0\0\0\0\0\
-\0\0\0\0\0\0\x0b\0\0\x7b\x01\0\0\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\x18\x61\0\0\0\0\0\0\0\0\0\0\xf8\x0a\0\0\x7b\x01\0\0\0\0\0\0\x61\x60\x08\0\0\0\
-\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\x98\x0a\0\0\x63\x01\0\0\0\0\0\0\x61\x60\x0c\0\
-\0\0\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\x9c\x0a\0\0\x63\x01\0\0\0\0\0\0\x79\x60\
-\x10\0\0\0\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\xa0\x0a\0\0\x7b\x01\0\0\0\0\0\0\x61\
-\xa0\x78\xff\0\0\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\xc8\x0a\0\0\x63\x01\0\0\0\0\0\
-\0\x18\x61\0\0\0\0\0\0\0\0\0\0\x10\x0b\0\0\xb7\x02\0\0\x14\0\0\0\xb7\x03\0\0\
-\x0c\0\0\0\xb7\x04\0\0\0\0\0\0\x85\0\0\0\xa7\0\0\0\xbf\x07\0\0\0\0\0\0\xc5\x07\
-\x91\xff\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\x80\x0a\0\0\x63\x70\x6c\0\0\0\0\0\
-\x77\x07\0\0\x20\0\0\0\x63\x70\x70\0\0\0\0\0\xb7\x01\0\0\x05\0\0\0\x18\x62\0\0\
-\0\0\0\0\0\0\0\0\x80\x0a\0\0\xb7\x03\0\0\x8c\0\0\0\x85\0\0\0\xa6\0\0\0\xbf\x07\
-\0\0\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\xf0\x0a\0\0\x61\x01\0\0\0\0\0\0\xd5\
-\x01\x02\0\0\0\0\0\xbf\x19\0\0\0\0\0\0\x85\0\0\0\xa8\0\0\0\xc5\x07\x7f\xff\0\0\
-\0\0\x63\x7a\x80\xff\0\0\0\0\x61\xa1\x78\xff\0\0\0\0\xd5\x01\x02\0\0\0\0\0\xbf\
-\x19\0\0\0\0\0\0\x85\0\0\0\xa8\0\0\0\x61\xa0\x80\xff\0\0\0\0\x63\x06\x28\0\0\0\
-\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x61\x10\0\0\0\0\0\0\x63\x06\x18\0\0\0\
-\0\0\xb7\0\0\0\0\0\0\0\x95\0\0\0\0\0\0\0";
-	err = bpf_load_and_run(&opts);
-	if (err < 0)
-		return err;
-	return 0;
-}
-
-static inline struct entrypoints_bpf *
-entrypoints_bpf__open_and_load(void)
-{
-	struct entrypoints_bpf *skel;
-
-	skel = entrypoints_bpf__open();
-	if (!skel)
-		return NULL;
-	if (entrypoints_bpf__load(skel)) {
-		entrypoints_bpf__destroy(skel);
-		return NULL;
-	}
-	return skel;
-}
-
-__attribute__((unused)) static void
-entrypoints_bpf__assert(struct entrypoints_bpf *s __attribute__((unused)))
-{
-#ifdef __cplusplus
-#define _Static_assert static_assert
-#endif
-#ifdef __cplusplus
-#undef _Static_assert
-#endif
-}
-
-#endif /* __ENTRYPOINTS_BPF_SKEL_H__ */
diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
index 10289f44d0cc..81073db6c617 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.c
+++ b/drivers/hid/bpf/hid_bpf_dispatch.c
@@ -10,6 +10,7 @@
 #include <linux/bitops.h>
 #include <linux/btf.h>
 #include <linux/btf_ids.h>
+#include <linux/fdtable.h>
 #include <linux/filter.h>
 #include <linux/hid.h>
 #include <linux/hid_bpf.h>
@@ -19,7 +20,6 @@
 #include <linux/module.h>
 #include <linux/workqueue.h>
 #include "hid_bpf_dispatch.h"
-#include "entrypoints/entrypoints.lskel.h"
 
 struct hid_bpf_ops *hid_bpf_ops;
 EXPORT_SYMBOL(hid_bpf_ops);
@@ -203,25 +203,17 @@ int hid_bpf_reconnect(struct hid_device *hdev)
 	return 0;
 }
 
-static int do_hid_bpf_attach_prog(struct hid_device *hdev, int prog_fd, struct bpf_prog *prog,
+static int do_hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type,
+				  hid_bpf_cb_t prog_fn, struct bpf_prog *prog,
 				  __u32 flags)
 {
-	int fd, err, prog_type;
+	int fd, err;
 
-	prog_type = hid_bpf_get_prog_attach_type(prog);
-	if (prog_type < 0)
-		return prog_type;
+	err = hid_bpf_allocate_event_data(hdev);
+	if (err)
+		return err;
 
-	if (prog_type >= HID_BPF_PROG_TYPE_MAX)
-		return -EINVAL;
-
-	if (prog_type == HID_BPF_PROG_TYPE_DEVICE_EVENT) {
-		err = hid_bpf_allocate_event_data(hdev);
-		if (err)
-			return err;
-	}
-
-	fd = __hid_bpf_attach_prog(hdev, prog_type, prog_fd, prog, flags);
+	fd = __hid_bpf_attach_prog(hdev, prog_type, prog_fn, prog, flags);
 	if (fd < 0)
 		return fd;
 
@@ -277,10 +269,12 @@ hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr
  */
 /* called from syscall */
 __bpf_kfunc int
-hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags)
+hid_bpf_attach_prog_impl(unsigned int hid_id, enum hid_bpf_prog_type prog_type,
+			 hid_bpf_cb_t prog_fn__async, __u32 flags, void *prog__aux)
 {
+	struct bpf_prog_aux *aux = (struct bpf_prog_aux *)prog__aux;
+	struct bpf_prog *prog = aux->prog;
 	struct hid_device *hdev;
-	struct bpf_prog *prog;
 	struct device *dev;
 	int err, fd;
 
@@ -290,6 +284,9 @@ hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags)
 	if ((flags & ~HID_BPF_FLAG_MASK))
 		return -EINVAL;
 
+	if (prog_type < 0 || prog_type >= HID_BPF_PROG_TYPE_MAX)
+		return -EINVAL;
+
 	dev = bus_find_device(hid_bpf_ops->bus_type, NULL, &hid_id, device_match_id);
 	if (!dev)
 		return -EINVAL;
@@ -300,13 +297,13 @@ hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags)
 	 * take a ref on the prog itself, it will be released
 	 * on errors or when it'll be detached
 	 */
-	prog = bpf_prog_get(prog_fd);
+	prog = bpf_prog_inc_not_zero(prog);
 	if (IS_ERR(prog)) {
 		err = PTR_ERR(prog);
 		goto out_dev_put;
 	}
 
-	fd = do_hid_bpf_attach_prog(hdev, prog_fd, prog, flags);
+	fd = do_hid_bpf_attach_prog(hdev, prog_type, prog_fn__async, prog, flags);
 	if (fd < 0) {
 		err = fd;
 		goto out_prog_put;
@@ -538,12 +535,9 @@ hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *buf
 }
 __bpf_kfunc_end_defs();
 
-/*
- * The following set contains all functions we agree BPF programs
- * can use.
- */
 BTF_KFUNCS_START(hid_bpf_kfunc_ids)
 BTF_ID_FLAGS(func, hid_bpf_get_data, KF_RET_NULL)
+BTF_ID_FLAGS(func, hid_bpf_attach_prog_impl, KF_SLEEPABLE)
 BTF_ID_FLAGS(func, hid_bpf_allocate_context, KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE)
 BTF_ID_FLAGS(func, hid_bpf_release_context, KF_RELEASE | KF_SLEEPABLE)
 BTF_ID_FLAGS(func, hid_bpf_hw_request, KF_SLEEPABLE)
@@ -556,33 +550,6 @@ static const struct btf_kfunc_id_set hid_bpf_kfunc_set = {
 	.set   = &hid_bpf_kfunc_ids,
 };
 
-/* our HID-BPF entrypoints */
-BTF_SET8_START(hid_bpf_fmodret_ids)
-BTF_ID_FLAGS(func, hid_bpf_device_event)
-BTF_ID_FLAGS(func, hid_bpf_rdesc_fixup)
-BTF_ID_FLAGS(func, __hid_bpf_tail_call)
-BTF_SET8_END(hid_bpf_fmodret_ids)
-
-static const struct btf_kfunc_id_set hid_bpf_fmodret_set = {
-	.owner = THIS_MODULE,
-	.set   = &hid_bpf_fmodret_ids,
-};
-
-/* for syscall HID-BPF */
-BTF_KFUNCS_START(hid_bpf_syscall_kfunc_ids)
-BTF_ID_FLAGS(func, hid_bpf_attach_prog)
-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 = {
-	.owner = THIS_MODULE,
-	.set   = &hid_bpf_syscall_kfunc_ids,
-};
-
 int hid_bpf_connect_device(struct hid_device *hdev)
 {
 	struct hid_bpf_prog_list *prog_list;
@@ -636,29 +603,9 @@ static int __init hid_bpf_init(void)
 	 * will not be available, so nobody will be able to use the functionality.
 	 */
 
-	err = register_btf_fmodret_id_set(&hid_bpf_fmodret_set);
-	if (err) {
-		pr_warn("error while registering fmodret entrypoints: %d", err);
-		return 0;
-	}
-
-	err = hid_bpf_preload_skel();
-	if (err) {
-		pr_warn("error while preloading HID BPF dispatcher: %d", err);
-		return 0;
-	}
-
-	/* register tracing kfuncs after we are sure we can load our preloaded bpf program */
-	err = register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &hid_bpf_kfunc_set);
-	if (err) {
-		pr_warn("error while setting HID BPF tracing kfuncs: %d", err);
-		return 0;
-	}
-
-	/* register syscalls after we are sure we can load our preloaded bpf program */
-	err = register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &hid_bpf_syscall_kfunc_set);
+	err = register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &hid_bpf_kfunc_set);
 	if (err) {
-		pr_warn("error while setting HID BPF syscall kfuncs: %d", err);
+		pr_warn("error while setting HID BPF kfuncs: %d", err);
 		return 0;
 	}
 
@@ -670,7 +617,6 @@ static void __exit hid_bpf_exit(void)
 	/* HID depends on us, so if we hit that code, we are guaranteed that hid
 	 * has been removed and thus we do not need to clear the HID devices
 	 */
-	hid_bpf_free_links_and_skel();
 }
 
 late_initcall(hid_bpf_init);
diff --git a/drivers/hid/bpf/hid_bpf_dispatch.h b/drivers/hid/bpf/hid_bpf_dispatch.h
index fbe0639d09f2..60455a2af216 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.h
+++ b/drivers/hid/bpf/hid_bpf_dispatch.h
@@ -10,10 +10,10 @@ struct hid_bpf_ctx_kern {
 	u8 *data;
 };
 
-int hid_bpf_preload_skel(void);
-void hid_bpf_free_links_and_skel(void);
-int hid_bpf_get_prog_attach_type(struct bpf_prog *prog);
-int __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type, int prog_fd,
+typedef int (*hid_bpf_cb_t)(struct hid_bpf_ctx *hid_ctx);
+
+int __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type,
+			  int (prog_fn__async)(struct hid_bpf_ctx *hid_ctx),
 			  struct bpf_prog *prog, __u32 flags);
 void __hid_bpf_destroy_device(struct hid_device *hdev);
 int hid_bpf_prog_run(struct hid_device *hdev, enum hid_bpf_prog_type type,
diff --git a/drivers/hid/bpf/hid_bpf_jmp_table.c b/drivers/hid/bpf/hid_bpf_jmp_table.c
index aa8e1c79cdf5..8d53d41b599b 100644
--- a/drivers/hid/bpf/hid_bpf_jmp_table.c
+++ b/drivers/hid/bpf/hid_bpf_jmp_table.c
@@ -17,7 +17,6 @@
 #include <linux/module.h>
 #include <linux/workqueue.h>
 #include "hid_bpf_dispatch.h"
-#include "entrypoints/entrypoints.lskel.h"
 
 #define HID_BPF_MAX_PROGS 1024 /* keep this in sync with preloaded bpf,
 				* needs to be a power of 2 as we use it as
@@ -37,11 +36,15 @@ struct hid_bpf_prog_entry {
 	u16 idx;
 };
 
+struct hid_bpf_prog_cb {
+	struct bpf_prog *prog;
+	void *fn;
+};
+
 struct hid_bpf_jmp_table {
-	struct bpf_map *map;
 	struct hid_bpf_prog_entry entries[HID_BPF_MAX_PROGS]; /* compacted list, circular buffer */
 	int tail, head;
-	struct bpf_prog *progs[HID_BPF_MAX_PROGS]; /* idx -> progs mapping */
+	struct hid_bpf_prog_cb prog_cbs[HID_BPF_MAX_PROGS]; /* idx -> progs mapping */
 	unsigned long enabled[BITS_TO_LONGS(HID_BPF_MAX_PROGS)];
 };
 
@@ -56,10 +59,6 @@ static void hid_bpf_release_progs(struct work_struct *work);
 
 static DECLARE_WORK(release_work, hid_bpf_release_progs);
 
-BTF_ID_LIST(hid_bpf_btf_ids)
-BTF_ID(func, hid_bpf_device_event)			/* HID_BPF_PROG_TYPE_DEVICE_EVENT */
-BTF_ID(func, hid_bpf_rdesc_fixup)			/* HID_BPF_PROG_TYPE_RDESC_FIXUP */
-
 static int hid_bpf_max_programs(enum hid_bpf_prog_type type)
 {
 	switch (type) {
@@ -99,15 +98,11 @@ static int hid_bpf_program_count(struct hid_device *hdev,
 	return n;
 }
 
-__weak noinline int __hid_bpf_tail_call(struct hid_bpf_ctx *ctx)
-{
-	return 0;
-}
-
 int hid_bpf_prog_run(struct hid_device *hdev, enum hid_bpf_prog_type type,
 		     struct hid_bpf_ctx_kern *ctx_kern)
 {
 	struct hid_bpf_prog_list *prog_list;
+	bpf_callback_t prog_fn;
 	int i, idx, err = 0;
 
 	rcu_read_lock();
@@ -123,7 +118,10 @@ int hid_bpf_prog_run(struct hid_device *hdev, enum hid_bpf_prog_type type,
 			continue;
 
 		ctx_kern->ctx.index = idx;
-		err = __hid_bpf_tail_call(&ctx_kern->ctx);
+		prog_fn = jmp_table.prog_cbs[idx].fn;
+		migrate_disable();
+		err = prog_fn((u64)(long)&ctx_kern->ctx, 0, 0, 0, 0);
+		migrate_enable();
 		if (err < 0)
 			break;
 		if (err)
@@ -187,25 +185,18 @@ static int hid_bpf_populate_hdev(struct hid_device *hdev, enum hid_bpf_prog_type
 	return 0;
 }
 
-static void __hid_bpf_do_release_prog(int map_fd, unsigned int idx)
+static void __hid_bpf_do_release_prog(unsigned int idx)
 {
-	skel_map_delete_elem(map_fd, &idx);
-	jmp_table.progs[idx] = NULL;
+	bpf_prog_put(jmp_table.prog_cbs[idx].prog);
+	jmp_table.prog_cbs[idx].prog = NULL;
+	jmp_table.prog_cbs[idx].fn = NULL;
 }
 
 static void hid_bpf_release_progs(struct work_struct *work)
 {
-	int i, j, n, map_fd = -1;
+	int i, j, n;
 	bool hdev_destroyed;
 
-	if (!jmp_table.map)
-		return;
-
-	/* retrieve a fd of our prog_array map in BPF */
-	map_fd = skel_map_get_fd_by_id(jmp_table.map->id);
-	if (map_fd < 0)
-		return;
-
 	mutex_lock(&hid_bpf_attach_lock); /* protects against attaching new programs */
 
 	/* detach unused progs from HID devices */
@@ -264,7 +255,7 @@ static void hid_bpf_release_progs(struct work_struct *work)
 			continue;
 
 		if (entry->prog)
-			__hid_bpf_do_release_prog(map_fd, entry->idx);
+			__hid_bpf_do_release_prog(entry->idx);
 	}
 
 	/* compact the entry list */
@@ -282,46 +273,22 @@ static void hid_bpf_release_progs(struct work_struct *work)
 	jmp_table.head = n;
 
 	mutex_unlock(&hid_bpf_attach_lock);
-
-	if (map_fd >= 0)
-		close_fd(map_fd);
-}
-
-static void hid_bpf_release_prog_at(int idx)
-{
-	int map_fd = -1;
-
-	/* retrieve a fd of our prog_array map in BPF */
-	map_fd = skel_map_get_fd_by_id(jmp_table.map->id);
-	if (map_fd < 0)
-		return;
-
-	__hid_bpf_do_release_prog(map_fd, idx);
-
-	close(map_fd);
 }
 
 /*
- * Insert the given BPF program represented by its fd in the jmp table.
+ * Insert the given BPF program represented by its function call in the jmp table.
  * Returns the index in the jump table or a negative error.
  */
-static int hid_bpf_insert_prog(int prog_fd, struct bpf_prog *prog)
+static int hid_bpf_insert_prog(struct bpf_prog *prog, hid_bpf_cb_t prog_fn)
 {
-	int i, index = -1, map_fd = -1, err = -EINVAL;
-
-	/* retrieve a fd of our prog_array map in BPF */
-	map_fd = skel_map_get_fd_by_id(jmp_table.map->id);
-
-	if (map_fd < 0) {
-		err = -EINVAL;
-		goto out;
-	}
+	int i, index = -1, err = -EINVAL;
 
 	/* find the first available index in the jmp_table */
 	for (i = 0; i < HID_BPF_MAX_PROGS; i++) {
-		if (!jmp_table.progs[i] && index < 0) {
+		if (!jmp_table.prog_cbs[i].prog && index < 0) {
 			/* mark the index as used */
-			jmp_table.progs[i] = prog;
+			jmp_table.prog_cbs[i].fn = prog_fn;
+			jmp_table.prog_cbs[i].prog = prog;
 			index = i;
 			__set_bit(i, jmp_table.enabled);
 		}
@@ -331,37 +298,15 @@ static int hid_bpf_insert_prog(int prog_fd, struct bpf_prog *prog)
 		goto out;
 	}
 
-	/* insert the program in the jump table */
-	err = skel_map_update_elem(map_fd, &index, &prog_fd, 0);
-	if (err)
-		goto out;
-
 	/* return the index */
 	err = index;
 
  out:
 	if (err < 0)
-		__hid_bpf_do_release_prog(map_fd, index);
-	if (map_fd >= 0)
-		close_fd(map_fd);
+		__hid_bpf_do_release_prog(index);
 	return err;
 }
 
-int hid_bpf_get_prog_attach_type(struct bpf_prog *prog)
-{
-	int prog_type = HID_BPF_PROG_TYPE_UNDEF;
-	int i;
-
-	for (i = 0; i < HID_BPF_PROG_TYPE_MAX; i++) {
-		if (hid_bpf_btf_ids[i] == prog->aux->attach_btf_id) {
-			prog_type = i;
-			break;
-		}
-	}
-
-	return prog_type;
-}
-
 static void hid_bpf_link_release(struct bpf_link *link)
 {
 	struct hid_bpf_link *hid_link =
@@ -395,7 +340,7 @@ static const struct bpf_link_ops hid_bpf_link_lops = {
 /* called from syscall */
 noinline int
 __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type,
-		      int prog_fd, struct bpf_prog *prog, __u32 flags)
+		      hid_bpf_cb_t prog_fn, struct bpf_prog *prog, __u32 flags)
 {
 	struct bpf_link_primer link_primer;
 	struct hid_bpf_link *link;
@@ -425,7 +370,7 @@ __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type,
 		goto err_unlock;
 	}
 
-	prog_table_idx = hid_bpf_insert_prog(prog_fd, prog);
+	prog_table_idx = hid_bpf_insert_prog(prog, prog_fn);
 	/* if the jmp table is full, abort */
 	if (prog_table_idx < 0) {
 		err = prog_table_idx;
@@ -451,7 +396,7 @@ __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type,
 	/* finally store the index in the device list */
 	err = hid_bpf_populate_hdev(hdev, prog_type);
 	if (err) {
-		hid_bpf_release_prog_at(prog_table_idx);
+		__hid_bpf_do_release_prog(prog_table_idx);
 		goto err_unlock;
 	}
 
@@ -498,68 +443,3 @@ void __hid_bpf_destroy_device(struct hid_device *hdev)
 	/* schedule release of all detached progs */
 	schedule_work(&release_work);
 }
-
-#define HID_BPF_PROGS_COUNT 1
-
-static struct bpf_link *links[HID_BPF_PROGS_COUNT];
-static struct entrypoints_bpf *skel;
-
-void hid_bpf_free_links_and_skel(void)
-{
-	int i;
-
-	/* the following is enough to release all programs attached to hid */
-	if (jmp_table.map)
-		bpf_map_put_with_uref(jmp_table.map);
-
-	for (i = 0; i < ARRAY_SIZE(links); i++) {
-		if (!IS_ERR_OR_NULL(links[i]))
-			bpf_link_put(links[i]);
-	}
-	entrypoints_bpf__destroy(skel);
-}
-
-#define ATTACH_AND_STORE_LINK(__name) do {					\
-	err = entrypoints_bpf__##__name##__attach(skel);			\
-	if (err)								\
-		goto out;							\
-										\
-	links[idx] = bpf_link_get_from_fd(skel->links.__name##_fd);		\
-	if (IS_ERR(links[idx])) {						\
-		err = PTR_ERR(links[idx]);					\
-		goto out;							\
-	}									\
-										\
-	/* Avoid taking over stdin/stdout/stderr of init process. Zeroing out	\
-	 * makes skel_closenz() a no-op later in iterators_bpf__destroy().	\
-	 */									\
-	close_fd(skel->links.__name##_fd);					\
-	skel->links.__name##_fd = 0;						\
-	idx++;									\
-} while (0)
-
-int hid_bpf_preload_skel(void)
-{
-	int err, idx = 0;
-
-	skel = entrypoints_bpf__open();
-	if (!skel)
-		return -ENOMEM;
-
-	err = entrypoints_bpf__load(skel);
-	if (err)
-		goto out;
-
-	jmp_table.map = bpf_map_get_with_uref(skel->maps.hid_jmp_table.map_fd);
-	if (IS_ERR(jmp_table.map)) {
-		err = PTR_ERR(jmp_table.map);
-		goto out;
-	}
-
-	ATTACH_AND_STORE_LINK(hid_tail_call);
-
-	return 0;
-out:
-	hid_bpf_free_links_and_skel();
-	return err;
-}
diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h
index 17b08f500098..99ebe7bbb02a 100644
--- a/include/linux/hid_bpf.h
+++ b/include/linux/hid_bpf.h
@@ -81,9 +81,6 @@ int hid_bpf_rdesc_fixup(struct hid_bpf_ctx *ctx);
  * Below is HID internal
  */
 
-/* internal function to call eBPF programs, not to be used by anybody */
-int __hid_bpf_tail_call(struct hid_bpf_ctx *ctx);
-
 #define HID_BPF_MAX_PROGS_PER_DEV 64
 #define HID_BPF_FLAG_MASK (((HID_BPF_FLAG_MAX - 1) << 1) - 1)
 

-- 
2.44.0


^ permalink raw reply related

* [PATCH RFC HID 2/7] selftests/hid: fix bpf programs for the new attachment logic
From: Benjamin Tissoires @ 2024-05-08 10:26 UTC (permalink / raw)
  To: Benjamin Tissoires; +Cc: linux-kernel, linux-input, bpf, Benjamin Tissoires
In-Reply-To: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org>

Now each program needs to ship its own attach prog. To make things
simpler we define __HID_BPF_PROG() and the various sub-macros per
hid-bpf type of program.

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 tools/testing/selftests/hid/hid_bpf.c              |  6 +---
 tools/testing/selftests/hid/progs/hid.c            | 40 +++++-----------------
 .../testing/selftests/hid/progs/hid_bpf_helpers.h  | 29 +++++++++++++++-
 3 files changed, 37 insertions(+), 38 deletions(-)

diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c
index f825623e3edc..7fed9f599b62 100644
--- a/tools/testing/selftests/hid/hid_bpf.c
+++ b/tools/testing/selftests/hid/hid_bpf.c
@@ -90,7 +90,6 @@ static unsigned char rdesc[] = {
 static __u8 feature_data[] = { 1, 2 };
 
 struct attach_prog_args {
-	int prog_fd;
 	unsigned int hid;
 	int retval;
 	int insert_head;
@@ -556,9 +555,6 @@ static void load_programs(const struct test_program programs[],
 	err = hid__load(self->skel);
 	ASSERT_OK(err) TH_LOG("hid_skel_load failed: %d", err);
 
-	attach_fd = bpf_program__fd(self->skel->progs.attach_prog);
-	ASSERT_GE(attach_fd, 0) TH_LOG("locate attach_prog: %d", attach_fd);
-
 	for (int i = 0; i < progs_count; i++) {
 		struct bpf_program *prog;
 
@@ -566,7 +562,7 @@ static void load_programs(const struct test_program programs[],
 							programs[i].name);
 		ASSERT_OK_PTR(prog) TH_LOG("can not find program by name '%s'", programs[i].name);
 
-		args.prog_fd = bpf_program__fd(prog);
+		attach_fd = bpf_program__fd(prog);
 		args.hid = self->hid_id;
 		args.insert_head = programs[i].insert_head;
 		err = bpf_prog_test_run_opts(attach_fd, &tattr);
diff --git a/tools/testing/selftests/hid/progs/hid.c b/tools/testing/selftests/hid/progs/hid.c
index f67d35def142..b721d1256836 100644
--- a/tools/testing/selftests/hid/progs/hid.c
+++ b/tools/testing/selftests/hid/progs/hid.c
@@ -4,18 +4,10 @@
 
 char _license[] SEC("license") = "GPL";
 
-struct attach_prog_args {
-	int prog_fd;
-	unsigned int hid;
-	int retval;
-	int insert_head;
-};
-
 __u64 callback_check = 52;
 __u64 callback2_check = 52;
 
-SEC("?fmod_ret/hid_bpf_device_event")
-int BPF_PROG(hid_first_event, struct hid_bpf_ctx *hid_ctx)
+HID_BPF_DEVICE_EVENT(hid_first_event, struct hid_bpf_ctx *hid_ctx)
 {
 	__u8 *rw_data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 3 /* size */);
 
@@ -29,8 +21,7 @@ int BPF_PROG(hid_first_event, struct hid_bpf_ctx *hid_ctx)
 	return hid_ctx->size;
 }
 
-SEC("?fmod_ret/hid_bpf_device_event")
-int BPF_PROG(hid_second_event, struct hid_bpf_ctx *hid_ctx)
+HID_BPF_DEVICE_EVENT(hid_second_event, struct hid_bpf_ctx *hid_ctx)
 {
 	__u8 *rw_data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */);
 
@@ -42,8 +33,7 @@ int BPF_PROG(hid_second_event, struct hid_bpf_ctx *hid_ctx)
 	return hid_ctx->size;
 }
 
-SEC("?fmod_ret/hid_bpf_device_event")
-int BPF_PROG(hid_change_report_id, struct hid_bpf_ctx *hid_ctx)
+HID_BPF_DEVICE_EVENT(hid_change_report_id, struct hid_bpf_ctx *hid_ctx)
 {
 	__u8 *rw_data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 3 /* size */);
 
@@ -55,16 +45,6 @@ int BPF_PROG(hid_change_report_id, struct hid_bpf_ctx *hid_ctx)
 	return 9;
 }
 
-SEC("syscall")
-int attach_prog(struct attach_prog_args *ctx)
-{
-	ctx->retval = hid_bpf_attach_prog(ctx->hid,
-					  ctx->prog_fd,
-					  ctx->insert_head ? HID_BPF_FLAG_INSERT_HEAD :
-							     HID_BPF_FLAG_NONE);
-	return 0;
-}
-
 struct hid_hw_request_syscall_args {
 	/* data needs to come at offset 0 so we can use it in calls */
 	__u8 data[10];
@@ -181,13 +161,12 @@ static const __u8 rdesc[] = {
 	0xc0,			/* END_COLLECTION */
 };
 
-SEC("?fmod_ret/hid_bpf_rdesc_fixup")
-int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hid_ctx)
+HID_BPF_RDESC_FIXUP(hid_rdesc_fixup, struct hid_bpf_ctx *hid_ctx)
 {
 	__u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 4096 /* size */);
 
 	if (!data)
-		return 0; /* EPERM check */
+		return -22; /* EPERM check */
 
 	callback2_check = data[4];
 
@@ -200,8 +179,7 @@ int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hid_ctx)
 	return sizeof(rdesc) + 73;
 }
 
-SEC("?fmod_ret/hid_bpf_device_event")
-int BPF_PROG(hid_test_insert1, struct hid_bpf_ctx *hid_ctx)
+HID_BPF_DEVICE_EVENT(hid_test_insert1, struct hid_bpf_ctx *hid_ctx)
 {
 	__u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */);
 
@@ -217,8 +195,7 @@ int BPF_PROG(hid_test_insert1, struct hid_bpf_ctx *hid_ctx)
 	return 0;
 }
 
-SEC("?fmod_ret/hid_bpf_device_event")
-int BPF_PROG(hid_test_insert2, struct hid_bpf_ctx *hid_ctx)
+HID_BPF_DEVICE_EVENT(hid_test_insert2, struct hid_bpf_ctx *hid_ctx)
 {
 	__u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */);
 
@@ -234,8 +211,7 @@ int BPF_PROG(hid_test_insert2, struct hid_bpf_ctx *hid_ctx)
 	return 0;
 }
 
-SEC("?fmod_ret/hid_bpf_device_event")
-int BPF_PROG(hid_test_insert3, struct hid_bpf_ctx *hid_ctx)
+HID_BPF_DEVICE_EVENT(hid_test_insert3, struct hid_bpf_ctx *hid_ctx)
 {
 	__u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */);
 
diff --git a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h
index 9cd56821d0f1..9826880e88d1 100644
--- a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h
+++ b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h
@@ -82,11 +82,20 @@ enum hid_bpf_attach_flags {
 	HID_BPF_FLAG_MAX,
 };
 
+struct attach_prog_args {
+	unsigned int hid;
+	int retval;
+	int insert_head;
+};
+
 /* following are kfuncs exported by HID for HID-BPF */
 extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx,
 			      unsigned int offset,
 			      const size_t __sz) __ksym;
-extern int hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, u32 flags) __ksym;
+extern int hid_bpf_attach_prog_impl(unsigned int hid_id,
+				    enum hid_bpf_prog_type type,
+				    int (prog_fn)(struct hid_bpf_ctx *hid_ctx),
+				    u32 flags, void *aux) __ksym;
 extern struct hid_bpf_ctx *hid_bpf_allocate_context(unsigned int hid_id) __ksym;
 extern void hid_bpf_release_context(struct hid_bpf_ctx *ctx) __ksym;
 extern int hid_bpf_hw_request(struct hid_bpf_ctx *ctx,
@@ -101,4 +110,22 @@ extern int hid_bpf_input_report(struct hid_bpf_ctx *ctx,
 				__u8 *data,
 				size_t buf__sz) __ksym;
 
+#define __HID_BPF_PROG(type, name, arg)                                                            \
+	static int __##name(arg);                                                                  \
+	SEC("syscall")                                                                             \
+	int name(struct attach_prog_args *ctx)                                                     \
+	{                                                                                          \
+		ctx->retval = hid_bpf_attach_prog_impl(ctx->hid,                                   \
+						  type,                                            \
+						  __##name,                                        \
+						  ctx->insert_head ? HID_BPF_FLAG_INSERT_HEAD :    \
+								     HID_BPF_FLAG_NONE,            \
+						  NULL);                                           \
+		return 0;                                                                          \
+	}                                                                                          \
+	static int __##name(arg)
+
+#define HID_BPF_DEVICE_EVENT(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_DEVICE_EVENT, name, arg)
+#define HID_BPF_RDESC_FIXUP(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_RDESC_FIXUP, name, arg)
+
 #endif /* __HID_BPF_HELPERS_H */

-- 
2.44.0


^ permalink raw reply related

* [PATCH RFC HID 3/7] HID: bpf: allow for sleepable bpf hooks
From: Benjamin Tissoires @ 2024-05-08 10:26 UTC (permalink / raw)
  To: Benjamin Tissoires; +Cc: linux-kernel, linux-input, bpf, Benjamin Tissoires
In-Reply-To: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org>

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 drivers/hid/bpf/hid_bpf_dispatch.c  | 111 ++++++++++++++++++++++--------------
 drivers/hid/bpf/hid_bpf_dispatch.h  |   4 +-
 drivers/hid/bpf/hid_bpf_jmp_table.c |  30 +++++++---
 3 files changed, 92 insertions(+), 53 deletions(-)

diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
index 81073db6c617..7ede657f459b 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.c
+++ b/drivers/hid/bpf/hid_bpf_dispatch.c
@@ -70,7 +70,7 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_type type
 	memset(ctx_kern.data, 0, hdev->bpf.allocated_data);
 	memcpy(ctx_kern.data, data, *size);
 
-	ret = hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_DEVICE_EVENT, &ctx_kern);
+	ret = hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_DEVICE_EVENT, &ctx_kern, false);
 	if (ret < 0)
 		return ERR_PTR(ret);
 
@@ -122,7 +122,7 @@ u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *s
 
 	memcpy(ctx_kern.data, rdesc, min_t(unsigned int, *size, HID_MAX_DESCRIPTOR_SIZE));
 
-	ret = hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_RDESC_FIXUP, &ctx_kern);
+	ret = hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_RDESC_FIXUP, &ctx_kern, false);
 	if (ret < 0)
 		goto ignore_bpf;
 
@@ -205,7 +205,7 @@ int hid_bpf_reconnect(struct hid_device *hdev)
 
 static int do_hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type,
 				  hid_bpf_cb_t prog_fn, struct bpf_prog *prog,
-				  __u32 flags)
+				  __u32 flags, bool sleepable)
 {
 	int fd, err;
 
@@ -213,7 +213,7 @@ static int do_hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_typ
 	if (err)
 		return err;
 
-	fd = __hid_bpf_attach_prog(hdev, prog_type, prog_fn, prog, flags);
+	fd = __hid_bpf_attach_prog(hdev, prog_type, prog_fn, prog, flags, sleepable);
 	if (fd < 0)
 		return fd;
 
@@ -228,6 +228,56 @@ static int do_hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_typ
 	return fd;
 }
 
+static int
+hid_bpf_attach_prog(unsigned int hid_id, enum hid_bpf_prog_type prog_type,
+		    hid_bpf_cb_t prog_fn, __u32 flags, void *prog__aux,
+		    bool sleepable)
+{
+	struct bpf_prog_aux *aux = (struct bpf_prog_aux *)prog__aux;
+	struct bpf_prog *prog = aux->prog;
+	struct hid_device *hdev;
+	struct device *dev;
+	int err, fd;
+
+	if (!hid_bpf_ops)
+		return -EINVAL;
+
+	if ((flags & ~HID_BPF_FLAG_MASK))
+		return -EINVAL;
+
+	if (prog_type < 0 || prog_type >= HID_BPF_PROG_TYPE_MAX)
+		return -EINVAL;
+
+	dev = bus_find_device(hid_bpf_ops->bus_type, NULL, &hid_id, device_match_id);
+	if (!dev)
+		return -EINVAL;
+
+	hdev = to_hid_device(dev);
+
+	/*
+	 * take a ref on the prog itself, it will be released
+	 * on errors or when it'll be detached
+	 */
+	prog = bpf_prog_inc_not_zero(prog);
+	if (IS_ERR(prog)) {
+		err = PTR_ERR(prog);
+		goto out_dev_put;
+	}
+
+	fd = do_hid_bpf_attach_prog(hdev, prog_type, prog_fn, prog, flags, sleepable);
+	if (fd < 0) {
+		err = fd;
+		goto out_prog_put;
+	}
+
+	return fd;
+
+ out_prog_put:
+	bpf_prog_put(prog);
+ out_dev_put:
+	put_device(dev);
+	return err;
+}
 /* Disables missing prototype warnings */
 __bpf_kfunc_start_defs();
 
@@ -272,50 +322,22 @@ __bpf_kfunc int
 hid_bpf_attach_prog_impl(unsigned int hid_id, enum hid_bpf_prog_type prog_type,
 			 hid_bpf_cb_t prog_fn__async, __u32 flags, void *prog__aux)
 {
-	struct bpf_prog_aux *aux = (struct bpf_prog_aux *)prog__aux;
-	struct bpf_prog *prog = aux->prog;
-	struct hid_device *hdev;
-	struct device *dev;
-	int err, fd;
-
-	if (!hid_bpf_ops)
-		return -EINVAL;
-
-	if ((flags & ~HID_BPF_FLAG_MASK))
-		return -EINVAL;
-
-	if (prog_type < 0 || prog_type >= HID_BPF_PROG_TYPE_MAX)
-		return -EINVAL;
+	return hid_bpf_attach_prog(hid_id, prog_type, prog_fn__async, flags, prog__aux, false);
+}
 
-	dev = bus_find_device(hid_bpf_ops->bus_type, NULL, &hid_id, device_match_id);
-	if (!dev)
+__bpf_kfunc int
+hid_bpf_attach_sleepable_prog_impl(unsigned int hid_id, enum hid_bpf_prog_type prog_type,
+				   hid_bpf_cb_t prog_fn__s_async, __u32 flags, void *prog__aux)
+{
+	switch (prog_type) {
+	case HID_BPF_PROG_TYPE_RAW_REQUEST:
+		/* OK */
+		break;
+	default:
 		return -EINVAL;
-
-	hdev = to_hid_device(dev);
-
-	/*
-	 * take a ref on the prog itself, it will be released
-	 * on errors or when it'll be detached
-	 */
-	prog = bpf_prog_inc_not_zero(prog);
-	if (IS_ERR(prog)) {
-		err = PTR_ERR(prog);
-		goto out_dev_put;
-	}
-
-	fd = do_hid_bpf_attach_prog(hdev, prog_type, prog_fn__async, prog, flags);
-	if (fd < 0) {
-		err = fd;
-		goto out_prog_put;
 	}
 
-	return fd;
-
- out_prog_put:
-	bpf_prog_put(prog);
- out_dev_put:
-	put_device(dev);
-	return err;
+	return hid_bpf_attach_prog(hid_id, prog_type, prog_fn__s_async, flags, prog__aux, true);
 }
 
 /**
@@ -538,6 +560,7 @@ __bpf_kfunc_end_defs();
 BTF_KFUNCS_START(hid_bpf_kfunc_ids)
 BTF_ID_FLAGS(func, hid_bpf_get_data, KF_RET_NULL)
 BTF_ID_FLAGS(func, hid_bpf_attach_prog_impl, KF_SLEEPABLE)
+BTF_ID_FLAGS(func, hid_bpf_attach_sleepable_prog_impl, KF_SLEEPABLE)
 BTF_ID_FLAGS(func, hid_bpf_allocate_context, KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE)
 BTF_ID_FLAGS(func, hid_bpf_release_context, KF_RELEASE | KF_SLEEPABLE)
 BTF_ID_FLAGS(func, hid_bpf_hw_request, KF_SLEEPABLE)
diff --git a/drivers/hid/bpf/hid_bpf_dispatch.h b/drivers/hid/bpf/hid_bpf_dispatch.h
index 60455a2af216..f9833603e49f 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.h
+++ b/drivers/hid/bpf/hid_bpf_dispatch.h
@@ -14,10 +14,10 @@ typedef int (*hid_bpf_cb_t)(struct hid_bpf_ctx *hid_ctx);
 
 int __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type,
 			  int (prog_fn__async)(struct hid_bpf_ctx *hid_ctx),
-			  struct bpf_prog *prog, __u32 flags);
+			  struct bpf_prog *prog, __u32 flags, bool sleepable);
 void __hid_bpf_destroy_device(struct hid_device *hdev);
 int hid_bpf_prog_run(struct hid_device *hdev, enum hid_bpf_prog_type type,
-		     struct hid_bpf_ctx_kern *ctx_kern);
+		     struct hid_bpf_ctx_kern *ctx_kern, bool is_sleepable);
 int hid_bpf_reconnect(struct hid_device *hdev);
 
 struct bpf_prog;
diff --git a/drivers/hid/bpf/hid_bpf_jmp_table.c b/drivers/hid/bpf/hid_bpf_jmp_table.c
index 8d53d41b599b..4cceff354962 100644
--- a/drivers/hid/bpf/hid_bpf_jmp_table.c
+++ b/drivers/hid/bpf/hid_bpf_jmp_table.c
@@ -39,6 +39,7 @@ struct hid_bpf_prog_entry {
 struct hid_bpf_prog_cb {
 	struct bpf_prog *prog;
 	void *fn;
+	bool sleepable;
 };
 
 struct hid_bpf_jmp_table {
@@ -99,14 +100,20 @@ static int hid_bpf_program_count(struct hid_device *hdev,
 }
 
 int hid_bpf_prog_run(struct hid_device *hdev, enum hid_bpf_prog_type type,
-		     struct hid_bpf_ctx_kern *ctx_kern)
+		     struct hid_bpf_ctx_kern *ctx_kern, bool is_sleepable)
 {
 	struct hid_bpf_prog_list *prog_list;
 	bpf_callback_t prog_fn;
 	int i, idx, err = 0;
 
-	rcu_read_lock();
-	prog_list = rcu_dereference(hdev->bpf.progs[type]);
+	if (is_sleepable) {
+		prog_list = READ_ONCE(hdev->bpf.progs[type]);
+		rcu_read_lock_trace();
+		might_fault();
+	} else {
+		rcu_read_lock();
+		prog_list = rcu_dereference(hdev->bpf.progs[type]);
+	}
 
 	if (!prog_list)
 		goto out_unlock;
@@ -117,6 +124,10 @@ int hid_bpf_prog_run(struct hid_device *hdev, enum hid_bpf_prog_type type,
 		if (!test_bit(idx, jmp_table.enabled))
 			continue;
 
+		/* prevent a sleepable program to be run in a non sleepable context */
+		if (!is_sleepable && jmp_table.prog_cbs[idx].sleepable)
+			continue;
+
 		ctx_kern->ctx.index = idx;
 		prog_fn = jmp_table.prog_cbs[idx].fn;
 		migrate_disable();
@@ -129,7 +140,10 @@ int hid_bpf_prog_run(struct hid_device *hdev, enum hid_bpf_prog_type type,
 	}
 
  out_unlock:
-	rcu_read_unlock();
+	if (is_sleepable)
+		rcu_read_unlock_trace();
+	else
+		rcu_read_unlock();
 
 	return err;
 }
@@ -279,7 +293,7 @@ static void hid_bpf_release_progs(struct work_struct *work)
  * Insert the given BPF program represented by its function call in the jmp table.
  * Returns the index in the jump table or a negative error.
  */
-static int hid_bpf_insert_prog(struct bpf_prog *prog, hid_bpf_cb_t prog_fn)
+static int hid_bpf_insert_prog(struct bpf_prog *prog, hid_bpf_cb_t prog_fn, bool sleepable)
 {
 	int i, index = -1, err = -EINVAL;
 
@@ -289,6 +303,7 @@ static int hid_bpf_insert_prog(struct bpf_prog *prog, hid_bpf_cb_t prog_fn)
 			/* mark the index as used */
 			jmp_table.prog_cbs[i].fn = prog_fn;
 			jmp_table.prog_cbs[i].prog = prog;
+			jmp_table.prog_cbs[i].sleepable = sleepable;
 			index = i;
 			__set_bit(i, jmp_table.enabled);
 		}
@@ -340,7 +355,8 @@ static const struct bpf_link_ops hid_bpf_link_lops = {
 /* called from syscall */
 noinline int
 __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type,
-		      hid_bpf_cb_t prog_fn, struct bpf_prog *prog, __u32 flags)
+		      hid_bpf_cb_t prog_fn, struct bpf_prog *prog, __u32 flags,
+		      bool sleepable)
 {
 	struct bpf_link_primer link_primer;
 	struct hid_bpf_link *link;
@@ -370,7 +386,7 @@ __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type,
 		goto err_unlock;
 	}
 
-	prog_table_idx = hid_bpf_insert_prog(prog, prog_fn);
+	prog_table_idx = hid_bpf_insert_prog(prog, prog_fn, sleepable);
 	/* if the jmp table is full, abort */
 	if (prog_table_idx < 0) {
 		err = prog_table_idx;

-- 
2.44.0


^ permalink raw reply related

* [PATCH RFC HID 4/7] HID: add source argument to HID low level functions
From: Benjamin Tissoires @ 2024-05-08 10:26 UTC (permalink / raw)
  To: Benjamin Tissoires; +Cc: linux-kernel, linux-input, bpf, Benjamin Tissoires
In-Reply-To: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org>

This allows to know who actually sent what when we process the request
to the device.
This will be useful for a BPF firewall program to allow or not requests
coming from a dedicated hidraw node client.

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 drivers/hid/bpf/hid_bpf_dispatch.c | 11 +++--
 drivers/hid/hid-core.c             | 85 ++++++++++++++++++++++++--------------
 drivers/hid/hidraw.c               | 10 ++---
 include/linux/hid.h                |  6 +++
 include/linux/hid_bpf.h            | 16 ++++---
 5 files changed, 81 insertions(+), 47 deletions(-)

diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
index 7ede657f459b..55c9e74c2465 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.c
+++ b/drivers/hid/bpf/hid_bpf_dispatch.c
@@ -47,7 +47,7 @@ __weak noinline int hid_bpf_device_event(struct hid_bpf_ctx *ctx)
 
 u8 *
 dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_type type, u8 *data,
-			      u32 *size, int interrupt)
+			      u32 *size, int interrupt, u64 source)
 {
 	struct hid_bpf_ctx_kern ctx_kern = {
 		.ctx = {
@@ -55,6 +55,7 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_type type
 			.report_type = type,
 			.allocated_size = hdev->bpf.allocated_data,
 			.size = *size,
+			.source = source,
 		},
 		.data = hdev->bpf.device_data,
 	};
@@ -483,7 +484,8 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz,
 					      dma_data,
 					      size,
 					      rtype,
-					      reqtype);
+					      reqtype,
+					      (__u64)ctx);
 
 	if (ret > 0)
 		memcpy(buf, dma_data, ret);
@@ -522,7 +524,8 @@ hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz)
 
 	ret = hid_bpf_ops->hid_hw_output_report(hdev,
 						dma_data,
-						size);
+						size,
+						(__u64)ctx);
 
 	kfree(dma_data);
 	return ret;
@@ -553,7 +556,7 @@ hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *buf
 
 	hdev = (struct hid_device *)ctx->hid; /* discard const */
 
-	return hid_bpf_ops->hid_input_report(hdev, type, buf, size, 0);
+	return hid_bpf_ops->hid_input_report(hdev, type, buf, size, 0, (__u64)ctx);
 }
 __bpf_kfunc_end_defs();
 
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index b1fa0378e8f4..b8414ce62e7b 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2026,19 +2026,9 @@ int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *
 }
 EXPORT_SYMBOL_GPL(hid_report_raw_event);
 
-/**
- * hid_input_report - report data from lower layer (usb, bt...)
- *
- * @hid: hid device
- * @type: HID report type (HID_*_REPORT)
- * @data: report contents
- * @size: size of data parameter
- * @interrupt: distinguish between interrupt and control transfers
- *
- * This is data entry for lower layers.
- */
-int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data, u32 size,
-		     int interrupt)
+
+static int __hid_input_report(struct hid_device *hid, enum hid_report_type type,
+			      u8 *data, u32 size, int interrupt, u64 source)
 {
 	struct hid_report_enum *report_enum;
 	struct hid_driver *hdrv;
@@ -2058,7 +2048,7 @@ int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data
 	report_enum = hid->report_enum + type;
 	hdrv = hid->driver;
 
-	data = dispatch_hid_bpf_device_event(hid, type, data, &size, interrupt);
+	data = dispatch_hid_bpf_device_event(hid, type, data, &size, interrupt, source);
 	if (IS_ERR(data)) {
 		ret = PTR_ERR(data);
 		goto unlock;
@@ -2093,6 +2083,23 @@ int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data
 	up(&hid->driver_input_lock);
 	return ret;
 }
+
+/**
+ * hid_input_report - report data from lower layer (usb, bt...)
+ *
+ * @hid: hid device
+ * @type: HID report type (HID_*_REPORT)
+ * @data: report contents
+ * @size: size of data parameter
+ * @interrupt: distinguish between interrupt and control transfers
+ *
+ * This is data entry for lower layers.
+ */
+int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data, u32 size,
+		     int interrupt)
+{
+	return __hid_input_report(hid, type, data, size, interrupt, 0);
+}
 EXPORT_SYMBOL_GPL(hid_input_report);
 
 bool hid_match_one_id(const struct hid_device *hdev,
@@ -2393,6 +2400,24 @@ void hid_hw_request(struct hid_device *hdev,
 }
 EXPORT_SYMBOL_GPL(hid_hw_request);
 
+int __hid_hw_raw_request(struct hid_device *hdev,
+			 unsigned char reportnum, __u8 *buf,
+			 size_t len, enum hid_report_type rtype,
+			 enum hid_class_request reqtype,
+			 __u64 source)
+{
+	unsigned int max_buffer_size = HID_MAX_BUFFER_SIZE;
+
+	if (hdev->ll_driver->max_buffer_size)
+		max_buffer_size = hdev->ll_driver->max_buffer_size;
+
+	if (len < 1 || len > max_buffer_size || !buf)
+		return -EINVAL;
+
+	return hdev->ll_driver->raw_request(hdev, reportnum, buf, len,
+					    rtype, reqtype);
+}
+
 /**
  * hid_hw_raw_request - send report request to device
  *
@@ -2410,6 +2435,12 @@ EXPORT_SYMBOL_GPL(hid_hw_request);
 int hid_hw_raw_request(struct hid_device *hdev,
 		       unsigned char reportnum, __u8 *buf,
 		       size_t len, enum hid_report_type rtype, enum hid_class_request reqtype)
+{
+	return __hid_hw_raw_request(hdev, reportnum, buf, len, rtype, reqtype, 0);
+}
+EXPORT_SYMBOL_GPL(hid_hw_raw_request);
+
+int __hid_hw_output_report(struct hid_device *hdev, __u8 *buf, size_t len, __u64 source)
 {
 	unsigned int max_buffer_size = HID_MAX_BUFFER_SIZE;
 
@@ -2419,10 +2450,11 @@ int hid_hw_raw_request(struct hid_device *hdev,
 	if (len < 1 || len > max_buffer_size || !buf)
 		return -EINVAL;
 
-	return hdev->ll_driver->raw_request(hdev, reportnum, buf, len,
-					    rtype, reqtype);
+	if (hdev->ll_driver->output_report)
+		return hdev->ll_driver->output_report(hdev, buf, len);
+
+	return -ENOSYS;
 }
-EXPORT_SYMBOL_GPL(hid_hw_raw_request);
 
 /**
  * hid_hw_output_report - send output report to device
@@ -2435,18 +2467,7 @@ EXPORT_SYMBOL_GPL(hid_hw_raw_request);
  */
 int hid_hw_output_report(struct hid_device *hdev, __u8 *buf, size_t len)
 {
-	unsigned int max_buffer_size = HID_MAX_BUFFER_SIZE;
-
-	if (hdev->ll_driver->max_buffer_size)
-		max_buffer_size = hdev->ll_driver->max_buffer_size;
-
-	if (len < 1 || len > max_buffer_size || !buf)
-		return -EINVAL;
-
-	if (hdev->ll_driver->output_report)
-		return hdev->ll_driver->output_report(hdev, buf, len);
-
-	return -ENOSYS;
+	return __hid_hw_output_report(hdev, buf, len, 0);
 }
 EXPORT_SYMBOL_GPL(hid_hw_output_report);
 
@@ -2973,9 +2994,9 @@ EXPORT_SYMBOL_GPL(hid_check_keys_pressed);
 #ifdef CONFIG_HID_BPF
 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,
+	.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,
 };
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 2bc762d31ac7..6d2a6d38e42a 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -140,7 +140,7 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer,
 
 	if ((report_type == HID_OUTPUT_REPORT) &&
 	    !(dev->quirks & HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP)) {
-		ret = hid_hw_output_report(dev, buf, count);
+		ret = __hid_hw_output_report(dev, buf, count, (__u64)file);
 		/*
 		 * compatibility with old implementation of USB-HID and I2C-HID:
 		 * if the device does not support receiving output reports,
@@ -150,8 +150,8 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer,
 			goto out_free;
 	}
 
-	ret = hid_hw_raw_request(dev, buf[0], buf, count, report_type,
-				HID_REQ_SET_REPORT);
+	ret = __hid_hw_raw_request(dev, buf[0], buf, count, report_type,
+				   HID_REQ_SET_REPORT, (__u64)file);
 
 out_free:
 	kfree(buf);
@@ -227,8 +227,8 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t
 		goto out_free;
 	}
 
-	ret = hid_hw_raw_request(dev, report_number, buf, count, report_type,
-				 HID_REQ_GET_REPORT);
+	ret = __hid_hw_raw_request(dev, report_number, buf, count, report_type,
+				   HID_REQ_GET_REPORT, (__u64)file);
 
 	if (ret < 0)
 		goto out_free;
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 8e06d89698e6..dac2804b4562 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -1125,6 +1125,12 @@ int __must_check hid_hw_open(struct hid_device *hdev);
 void hid_hw_close(struct hid_device *hdev);
 void hid_hw_request(struct hid_device *hdev,
 		    struct hid_report *report, enum hid_class_request reqtype);
+int __hid_hw_raw_request(struct hid_device *hdev,
+			 unsigned char reportnum, __u8 *buf,
+			 size_t len, enum hid_report_type rtype,
+			 enum hid_class_request reqtype,
+			 __u64 source);
+int __hid_hw_output_report(struct hid_device *hdev, __u8 *buf, size_t len, __u64 source);
 int hid_hw_raw_request(struct hid_device *hdev,
 		       unsigned char reportnum, __u8 *buf,
 		       size_t len, enum hid_report_type rtype,
diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h
index 99ebe7bbb02a..6bcaf19f1cc2 100644
--- a/include/linux/hid_bpf.h
+++ b/include/linux/hid_bpf.h
@@ -48,8 +48,9 @@ struct hid_device;
  */
 struct hid_bpf_ctx {
 	__u32 index;
-	const struct hid_device *hid;
 	__u32 allocated_size;
+	__u64 source;
+	const struct hid_device *hid;
 	enum hid_report_type report_type;
 	union {
 		__s32 retval;
@@ -99,10 +100,12 @@ struct hid_bpf_ops {
 	int (*hid_hw_raw_request)(struct hid_device *hdev,
 				  unsigned char reportnum, __u8 *buf,
 				  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);
+				  enum hid_class_request reqtype,
+				  __u64 source);
+	int (*hid_hw_output_report)(struct hid_device *hdev, __u8 *buf, size_t len,
+				    __u64 source);
 	int (*hid_input_report)(struct hid_device *hid, enum hid_report_type type,
-				u8 *data, u32 size, int interrupt);
+				u8 *data, u32 size, int interrupt, u64 source);
 	struct module *owner;
 	const struct bus_type *bus_type;
 };
@@ -136,7 +139,7 @@ struct hid_bpf_link {
 
 #ifdef CONFIG_HID_BPF
 u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, enum hid_report_type type, u8 *data,
-				  u32 *size, int interrupt);
+				  u32 *size, int interrupt, u64 source);
 int hid_bpf_connect_device(struct hid_device *hdev);
 void hid_bpf_disconnect_device(struct hid_device *hdev);
 void hid_bpf_destroy_device(struct hid_device *hid);
@@ -144,7 +147,8 @@ void hid_bpf_device_init(struct hid_device *hid);
 u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *size);
 #else /* CONFIG_HID_BPF */
 static inline u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, enum hid_report_type type,
-						u8 *data, u32 *size, int interrupt) { return data; }
+						u8 *data, u32 *size, int interrupt,
+						u64 source) { return data; }
 static inline int hid_bpf_connect_device(struct hid_device *hdev) { return 0; }
 static inline void hid_bpf_disconnect_device(struct hid_device *hdev) {}
 static inline void hid_bpf_destroy_device(struct hid_device *hid) {}

-- 
2.44.0


^ permalink raw reply related

* [PATCH RFC HID 5/7] WIP: add HID-BPF hooks for hid_hw_raw_requests
From: Benjamin Tissoires @ 2024-05-08 10:26 UTC (permalink / raw)
  To: Benjamin Tissoires; +Cc: linux-kernel, linux-input, bpf, Benjamin Tissoires
In-Reply-To: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org>

---
 drivers/hid/bpf/hid_bpf_dispatch.c  | 51 +++++++++++++++++++++++++++++++++++++
 drivers/hid/bpf/hid_bpf_jmp_table.c |  1 +
 drivers/hid/hid-core.c              |  8 +++++-
 include/linux/hid_bpf.h             | 14 ++++++++++
 4 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
index 55c9e74c2465..7aeab3f9f2c7 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.c
+++ b/drivers/hid/bpf/hid_bpf_dispatch.c
@@ -45,6 +45,11 @@ __weak noinline int hid_bpf_device_event(struct hid_bpf_ctx *ctx)
 	return 0;
 }
 
+__weak noinline int hid_bpf_raw_request(struct hid_bpf_ctx *ctx)
+{
+	return 0;
+}
+
 u8 *
 dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_type type, u8 *data,
 			      u32 *size, int interrupt, u64 source)
@@ -71,6 +76,9 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_type type
 	memset(ctx_kern.data, 0, hdev->bpf.allocated_data);
 	memcpy(ctx_kern.data, data, *size);
 
+	if (*size)
+		ctx_kern.ctx.reportnum = data[0];
+
 	ret = hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_DEVICE_EVENT, &ctx_kern, false);
 	if (ret < 0)
 		return ERR_PTR(ret);
@@ -86,6 +94,49 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_type type
 }
 EXPORT_SYMBOL_GPL(dispatch_hid_bpf_device_event);
 
+u8 *
+dispatch_hid_bpf_raw_requests(struct hid_device *hdev,
+			      unsigned char reportnum, u8 *buf,
+			      u32 *size, enum hid_report_type rtype,
+			      enum hid_class_request reqtype,
+			      u64 source)
+{
+	struct hid_bpf_ctx_kern ctx_kern = {
+		.ctx = {
+			.hid = hdev,
+			.report_type = rtype,
+			.reqtype = reqtype,
+			.allocated_size = *size,
+			.size = *size,
+			.source = source,
+			.reportnum = reportnum,
+		},
+		.data = buf,
+	};
+	int ret;
+
+	if (rtype >= HID_REPORT_TYPES)
+		return ERR_PTR(-EINVAL);
+
+	/* no program has been attached yet */
+	// if (!hdev->bpf.device_data)
+	// 	return buf;
+
+	ret = hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_RAW_REQUEST, &ctx_kern, true);
+	if (ret < 0)
+		return ERR_PTR(ret);
+
+	if (ret) {
+		if (ret > ctx_kern.ctx.allocated_size)
+			return ERR_PTR(-EINVAL);
+
+		*size = ret;
+	}
+
+	return ctx_kern.data;
+}
+EXPORT_SYMBOL_GPL(dispatch_hid_bpf_raw_requests);
+
 /**
  * hid_bpf_rdesc_fixup - Called when the probe function parses the report
  * descriptor of the HID device
diff --git a/drivers/hid/bpf/hid_bpf_jmp_table.c b/drivers/hid/bpf/hid_bpf_jmp_table.c
index 4cceff354962..e183dc2835c7 100644
--- a/drivers/hid/bpf/hid_bpf_jmp_table.c
+++ b/drivers/hid/bpf/hid_bpf_jmp_table.c
@@ -64,6 +64,7 @@ static int hid_bpf_max_programs(enum hid_bpf_prog_type type)
 {
 	switch (type) {
 	case HID_BPF_PROG_TYPE_DEVICE_EVENT:
+	case HID_BPF_PROG_TYPE_RAW_REQUEST:
 		return HID_BPF_MAX_PROGS_PER_DEV;
 	case HID_BPF_PROG_TYPE_RDESC_FIXUP:
 		return 1;
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index b8414ce62e7b..7d468f6dbefe 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2407,6 +2407,7 @@ int __hid_hw_raw_request(struct hid_device *hdev,
 			 __u64 source)
 {
 	unsigned int max_buffer_size = HID_MAX_BUFFER_SIZE;
+	u32 size = (u32)len; /* max_buffer_size is 16 KB */
 
 	if (hdev->ll_driver->max_buffer_size)
 		max_buffer_size = hdev->ll_driver->max_buffer_size;
@@ -2414,7 +2415,12 @@ int __hid_hw_raw_request(struct hid_device *hdev,
 	if (len < 1 || len > max_buffer_size || !buf)
 		return -EINVAL;
 
-	return hdev->ll_driver->raw_request(hdev, reportnum, buf, len,
+	buf = dispatch_hid_bpf_raw_requests(hdev, reportnum, buf, &size, rtype,
+			      reqtype, source);
+	if (IS_ERR(buf))
+		return PTR_ERR(buf);
+
+	return hdev->ll_driver->raw_request(hdev, reportnum, buf, size,
 					    rtype, reqtype);
 }
 
diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h
index 6bcaf19f1cc2..1cd36bfdd608 100644
--- a/include/linux/hid_bpf.h
+++ b/include/linux/hid_bpf.h
@@ -52,10 +52,12 @@ struct hid_bpf_ctx {
 	__u64 source;
 	const struct hid_device *hid;
 	enum hid_report_type report_type;
+	enum hid_class_request reqtype; /* for HID_BPF_PROG_TYPE_RAW_REQUEST */
 	union {
 		__s32 retval;
 		__s32 size;
 	};
+	__u8 reportnum;
 };
 
 /**
@@ -77,6 +79,7 @@ enum hid_bpf_attach_flags {
 /* Following functions are tracepoints that BPF programs can attach to */
 int hid_bpf_device_event(struct hid_bpf_ctx *ctx);
 int hid_bpf_rdesc_fixup(struct hid_bpf_ctx *ctx);
+int hid_bpf_raw_request(struct hid_bpf_ctx *ctx);
 
 /*
  * Below is HID internal
@@ -90,6 +93,7 @@ enum hid_bpf_prog_type {
 	HID_BPF_PROG_TYPE_UNDEF = -1,
 	HID_BPF_PROG_TYPE_DEVICE_EVENT,			/* an event is emitted from the device */
 	HID_BPF_PROG_TYPE_RDESC_FIXUP,
+	HID_BPF_PROG_TYPE_RAW_REQUEST,
 	HID_BPF_PROG_TYPE_MAX,
 };
 
@@ -140,6 +144,11 @@ struct hid_bpf_link {
 #ifdef CONFIG_HID_BPF
 u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, enum hid_report_type type, u8 *data,
 				  u32 *size, int interrupt, u64 source);
+u8 *dispatch_hid_bpf_raw_requests(struct hid_device *hdev,
+				  unsigned char reportnum, __u8 *buf,
+				  u32 *size, enum hid_report_type rtype,
+				  enum hid_class_request reqtype,
+				  __u64 source);
 int hid_bpf_connect_device(struct hid_device *hdev);
 void hid_bpf_disconnect_device(struct hid_device *hdev);
 void hid_bpf_destroy_device(struct hid_device *hid);
@@ -149,6 +158,11 @@ u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *s
 static inline u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, enum hid_report_type type,
 						u8 *data, u32 *size, int interrupt,
 						u64 source) { return data; }
+static inline u8 *dispatch_hid_bpf_raw_requests(struct hid_device *hdev,
+						unsigned char reportnum, u8 *buf,
+						u32 *size, enum hid_report_type rtype,
+						enum hid_class_request reqtype,
+						u64 source) { return buf; }
 static inline int hid_bpf_connect_device(struct hid_device *hdev) { return 0; }
 static inline void hid_bpf_disconnect_device(struct hid_device *hdev) {}
 static inline void hid_bpf_destroy_device(struct hid_device *hid) {}

-- 
2.44.0


^ permalink raw reply related

* [PATCH RFC HID 6/7] WIP: selftests/hid: add tests for hid_hw_raw_request HID-BPF hooks
From: Benjamin Tissoires @ 2024-05-08 10:26 UTC (permalink / raw)
  To: Benjamin Tissoires; +Cc: linux-kernel, linux-input, bpf, Benjamin Tissoires
In-Reply-To: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org>

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 tools/testing/selftests/hid/hid_bpf.c              | 55 ++++++++++++++++++++++
 tools/testing/selftests/hid/progs/hid.c            | 51 ++++++++++++++++++++
 .../testing/selftests/hid/progs/hid_bpf_helpers.h  | 39 +++++++++------
 3 files changed, 130 insertions(+), 15 deletions(-)

diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c
index 7fed9f599b62..522fc32a5c38 100644
--- a/tools/testing/selftests/hid/hid_bpf.c
+++ b/tools/testing/selftests/hid/hid_bpf.c
@@ -469,6 +469,8 @@ static void detach_bpf(FIXTURE_DATA(hid_bpf) * self)
 		close(self->hidraw_fd);
 	self->hidraw_fd = 0;
 
+	// hid__detach(self->skel);
+
 	for (i = 0; i < ARRAY_SIZE(self->hid_links); i++) {
 		if (self->hid_links[i])
 			close(self->hid_links[i]);
@@ -572,6 +574,8 @@ static void load_programs(const struct test_program programs[],
 		self->hid_links[i] = args.retval;
 	}
 
+	// hid__attach(self->skel);
+
 	self->hidraw_fd = open_hidraw(self->dev_id);
 	ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw");
 }
@@ -871,6 +875,57 @@ TEST_F(hid_bpf, test_hid_user_raw_request_call)
 	ASSERT_EQ(args.data[1], 2);
 }
 
+/*
+ * Call hid_hw_raw_request against the given uhid device,
+ * check that the program is called and does the expected.
+ */
+TEST_F(hid_bpf, test_hid_filter_raw_request_call)
+{
+	const struct test_program progs[] = {
+		{ .name = "hid_test_filter_raw_request" },
+		{ .name = "hid_test_raw_request" },
+	};
+	__u8 buf[10] = {0};
+	int err;
+
+	LOAD_PROGRAMS(progs);
+
+	/* first check that we did not attach to device_event */
+
+	/* inject one event */
+	buf[0] = 1;
+	buf[1] = 42;
+	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+
+	/* read the data from hidraw */
+	memset(buf, 0, sizeof(buf));
+	err = read(self->hidraw_fd, buf, sizeof(buf));
+	ASSERT_EQ(err, 6) TH_LOG("read_hidraw");
+	ASSERT_EQ(buf[0], 1);
+	ASSERT_EQ(buf[1], 42);
+	ASSERT_EQ(buf[2], 0) TH_LOG("leftovers_from_previous_test");
+
+	/* now check that our program is preventing hid_hw_raw_request() */
+
+	/* emit hid_hw_raw_request from hidraw */
+	/* Get Feature */
+	memset(buf, 0, sizeof(buf));
+	buf[0] = 0x1; /* Report Number */
+	err = ioctl(self->hidraw_fd, HIDIOCGFEATURE(sizeof(buf)), buf);
+	ASSERT_LT(err, 0) TH_LOG("unexpected success while reading HIDIOCGFEATURE: %d", err);
+
+	/* remove our bpf program and check that we can now emit commands */
+
+	/* detach the program */
+	detach_bpf(self);
+
+	self->hidraw_fd = open_hidraw(self->dev_id);
+	ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw");
+
+	err = ioctl(self->hidraw_fd, HIDIOCGFEATURE(sizeof(buf)), buf);
+	ASSERT_GE(err, 0) TH_LOG("error while reading HIDIOCGFEATURE: %d", err);
+}
+
 /*
  * Attach hid_insert{0,1,2} to the given uhid device,
  * retrieve and open the matching hidraw node,
diff --git a/tools/testing/selftests/hid/progs/hid.c b/tools/testing/selftests/hid/progs/hid.c
index b721d1256836..64aaa279bec4 100644
--- a/tools/testing/selftests/hid/progs/hid.c
+++ b/tools/testing/selftests/hid/progs/hid.c
@@ -226,3 +226,54 @@ HID_BPF_DEVICE_EVENT(hid_test_insert3, struct hid_bpf_ctx *hid_ctx)
 
 	return 0;
 }
+
+// SEC("fentry/hidraw_open")
+// int BPF_PROG(hidraw_open, struct inode *inode, struct file *file)
+// {
+// 	bpf_printk("inode: %llx, file: %llx", (u64)inode, (u64)file);
+// 	return 0;
+// }
+
+HID_BPF_RAW_REQUEST(hid_test_filter_raw_request, struct hid_bpf_ctx *hctx)
+{
+	bpf_printk("in %s:%d", __func__, __LINE__);
+	return 0;
+}
+
+HID_BPF_SLEEPABLE_RAW_REQUEST(hid_test_raw_request, struct hid_bpf_ctx *hctx)
+{
+	struct test_report buf = {
+		.data = {2, 3, 4, 5, 6, 7},
+	};
+	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 2 /* size */);
+	int ret;
+
+	bpf_printk("in %s, hctx: %llx source: %llx", __func__, (u64)hctx, hctx->source);
+
+	if (!data)
+		return 0; /* EPERM check */
+	bpf_printk("in %s:%d", __func__, __LINE__);
+
+	if (hctx->source) {
+		hid_bpf_input_report(hctx, HID_INPUT_REPORT, buf.data, sizeof(buf.data));
+
+		/* still forward the request as-is to the device, hid-bpf will not
+		 * call us again.
+		 */
+
+		data[0] = hctx->reportnum;
+
+		ret = hid_bpf_hw_request(hctx,
+					 data,
+					 2,
+					 hctx->report_type,
+					 hctx->reqtype);
+		bpf_printk("ret: %d", ret);
+		if (ret)
+			return ret;
+		return -1;
+	}
+
+	bpf_printk("in %s:%d", __func__, __LINE__);
+	return 0;
+}
diff --git a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h
index 9826880e88d1..779ec151c717 100644
--- a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h
+++ b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h
@@ -56,17 +56,6 @@ enum hid_report_type {
 	HID_REPORT_TYPES,
 };
 
-struct hid_bpf_ctx {
-	__u32 index;
-	const struct hid_device *hid;
-	__u32 allocated_size;
-	enum hid_report_type report_type;
-	union {
-		__s32 retval;
-		__s32 size;
-	};
-} __attribute__((preserve_access_index));
-
 enum hid_class_request {
 	HID_REQ_GET_REPORT		= 0x01,
 	HID_REQ_GET_IDLE		= 0x02,
@@ -88,6 +77,20 @@ struct attach_prog_args {
 	int insert_head;
 };
 
+struct hid_bpf_ctx {
+	__u32 index;
+	__u32 allocated_size;
+	__u64 source;
+	const struct hid_device *hid;
+	enum hid_report_type report_type;
+	enum hid_class_request reqtype; /* for HID_BPF_PROG_TYPE_RAW_REQUEST */
+	union {
+		__s32 retval;
+		__s32 size;
+	};
+	__u8 reportnum;
+} __attribute__((preserve_access_index));
+
 /* following are kfuncs exported by HID for HID-BPF */
 extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx,
 			      unsigned int offset,
@@ -96,6 +99,10 @@ extern int hid_bpf_attach_prog_impl(unsigned int hid_id,
 				    enum hid_bpf_prog_type type,
 				    int (prog_fn)(struct hid_bpf_ctx *hid_ctx),
 				    u32 flags, void *aux) __ksym;
+extern int hid_bpf_attach_sleepable_prog_impl(unsigned int hid_id,
+					      enum hid_bpf_prog_type type,
+					      int (prog_fn)(struct hid_bpf_ctx *hid_ctx),
+					      u32 flags, void *aux) __ksym;
 extern struct hid_bpf_ctx *hid_bpf_allocate_context(unsigned int hid_id) __ksym;
 extern void hid_bpf_release_context(struct hid_bpf_ctx *ctx) __ksym;
 extern int hid_bpf_hw_request(struct hid_bpf_ctx *ctx,
@@ -110,12 +117,12 @@ extern int hid_bpf_input_report(struct hid_bpf_ctx *ctx,
 				__u8 *data,
 				size_t buf__sz) __ksym;
 
-#define __HID_BPF_PROG(type, name, arg)                                                            \
+#define __HID_BPF_PROG(type, name, arg, sleepable)                                                 \
 	static int __##name(arg);                                                                  \
 	SEC("syscall")                                                                             \
 	int name(struct attach_prog_args *ctx)                                                     \
 	{                                                                                          \
-		ctx->retval = hid_bpf_attach_prog_impl(ctx->hid,                                   \
+		ctx->retval = hid_bpf_attach_##sleepable##prog_impl(ctx->hid,                      \
 						  type,                                            \
 						  __##name,                                        \
 						  ctx->insert_head ? HID_BPF_FLAG_INSERT_HEAD :    \
@@ -125,7 +132,9 @@ extern int hid_bpf_input_report(struct hid_bpf_ctx *ctx,
 	}                                                                                          \
 	static int __##name(arg)
 
-#define HID_BPF_DEVICE_EVENT(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_DEVICE_EVENT, name, arg)
-#define HID_BPF_RDESC_FIXUP(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_RDESC_FIXUP, name, arg)
+#define HID_BPF_DEVICE_EVENT(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_DEVICE_EVENT, name, arg, )
+#define HID_BPF_RDESC_FIXUP(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_RDESC_FIXUP, name, arg, )
+#define HID_BPF_RAW_REQUEST(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_RAW_REQUEST, name, arg, )
+#define HID_BPF_SLEEPABLE_RAW_REQUEST(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_RAW_REQUEST, name, arg, sleepable_)
 
 #endif /* __HID_BPF_HELPERS_H */

-- 
2.44.0


^ permalink raw reply related

* [PATCH RFC HID 7/7] HID: bpf: prevent infinite recursions with hid_hw_raw_requests hooks
From: Benjamin Tissoires @ 2024-05-08 10:26 UTC (permalink / raw)
  To: Benjamin Tissoires; +Cc: linux-kernel, linux-input, bpf, Benjamin Tissoires
In-Reply-To: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org>

When we attach a sleepable hook to hid_hw_raw_requests, we can (and in
many cases should) call ourself hid_bpf_raw_request(), to actaully fetch
data from the device itself.

However, this means that we might enter an infinite loop between
hid_hw_raw_requests trace and hid_bpf_raw_request() call.

To prevent that, if a hid_bpf_raw_request() call is emitted, we prevent
any sleepable bpf trace to hid_hw_raw_requests(). This way we can always
trace/monitor/filter the incoming bpf requests, while preventing those
loops to happen.

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 drivers/hid/bpf/hid_bpf_dispatch.c | 7 ++++---
 drivers/hid/hid-core.c             | 6 +++---
 drivers/hid/hidraw.c               | 4 ++--
 include/linux/hid.h                | 2 +-
 include/linux/hid_bpf.h            | 6 +++---
 5 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
index 7aeab3f9f2c7..79cac293ba29 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.c
+++ b/drivers/hid/bpf/hid_bpf_dispatch.c
@@ -99,7 +99,7 @@ dispatch_hid_bpf_raw_requests(struct hid_device *hdev,
 			      unsigned char reportnum, u8 *buf,
 			      u32 *size, enum hid_report_type rtype,
 			      enum hid_class_request reqtype,
-			      u64 source)
+			      u64 source, bool from_bpf)
 {
 	struct hid_bpf_ctx_kern ctx_kern = {
 		.ctx = {
@@ -122,7 +122,7 @@ dispatch_hid_bpf_raw_requests(struct hid_device *hdev,
 	// if (!hdev->bpf.device_data)
 	// 	return buf;
 
-	ret = hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_RAW_REQUEST, &ctx_kern, true);
+	ret = hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_RAW_REQUEST, &ctx_kern, !from_bpf);
 	if (ret < 0)
 		return ERR_PTR(ret);
 
@@ -536,7 +536,8 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz,
 					      size,
 					      rtype,
 					      reqtype,
-					      (__u64)ctx);
+					      (__u64)ctx,
+					      true); /* prevent infinite recursions */
 
 	if (ret > 0)
 		memcpy(buf, dma_data, ret);
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 7d468f6dbefe..d53f465a4ccb 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2404,7 +2404,7 @@ int __hid_hw_raw_request(struct hid_device *hdev,
 			 unsigned char reportnum, __u8 *buf,
 			 size_t len, enum hid_report_type rtype,
 			 enum hid_class_request reqtype,
-			 __u64 source)
+			 __u64 source, bool from_bpf)
 {
 	unsigned int max_buffer_size = HID_MAX_BUFFER_SIZE;
 	u32 size = (u32)len; /* max_buffer_size is 16 KB */
@@ -2416,7 +2416,7 @@ int __hid_hw_raw_request(struct hid_device *hdev,
 		return -EINVAL;
 
 	buf = dispatch_hid_bpf_raw_requests(hdev, reportnum, buf, &size, rtype,
-			      reqtype, source);
+			      reqtype, source, from_bpf);
 	if (IS_ERR(buf))
 		return PTR_ERR(buf);
 
@@ -2442,7 +2442,7 @@ int hid_hw_raw_request(struct hid_device *hdev,
 		       unsigned char reportnum, __u8 *buf,
 		       size_t len, enum hid_report_type rtype, enum hid_class_request reqtype)
 {
-	return __hid_hw_raw_request(hdev, reportnum, buf, len, rtype, reqtype, 0);
+	return __hid_hw_raw_request(hdev, reportnum, buf, len, rtype, reqtype, 0, false);
 }
 EXPORT_SYMBOL_GPL(hid_hw_raw_request);
 
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 6d2a6d38e42a..4ba3131de614 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -151,7 +151,7 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer,
 	}
 
 	ret = __hid_hw_raw_request(dev, buf[0], buf, count, report_type,
-				   HID_REQ_SET_REPORT, (__u64)file);
+				   HID_REQ_SET_REPORT, (__u64)file, false);
 
 out_free:
 	kfree(buf);
@@ -228,7 +228,7 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t
 	}
 
 	ret = __hid_hw_raw_request(dev, report_number, buf, count, report_type,
-				   HID_REQ_GET_REPORT, (__u64)file);
+				   HID_REQ_GET_REPORT, (__u64)file, false);
 
 	if (ret < 0)
 		goto out_free;
diff --git a/include/linux/hid.h b/include/linux/hid.h
index dac2804b4562..24d0d7c0bd33 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -1129,7 +1129,7 @@ int __hid_hw_raw_request(struct hid_device *hdev,
 			 unsigned char reportnum, __u8 *buf,
 			 size_t len, enum hid_report_type rtype,
 			 enum hid_class_request reqtype,
-			 __u64 source);
+			 __u64 source, bool from_bpf);
 int __hid_hw_output_report(struct hid_device *hdev, __u8 *buf, size_t len, __u64 source);
 int hid_hw_raw_request(struct hid_device *hdev,
 		       unsigned char reportnum, __u8 *buf,
diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h
index 1cd36bfdd608..6b2ac815572c 100644
--- a/include/linux/hid_bpf.h
+++ b/include/linux/hid_bpf.h
@@ -105,7 +105,7 @@ struct hid_bpf_ops {
 				  unsigned char reportnum, __u8 *buf,
 				  size_t len, enum hid_report_type rtype,
 				  enum hid_class_request reqtype,
-				  __u64 source);
+				  __u64 source, bool from_bpf);
 	int (*hid_hw_output_report)(struct hid_device *hdev, __u8 *buf, size_t len,
 				    __u64 source);
 	int (*hid_input_report)(struct hid_device *hid, enum hid_report_type type,
@@ -148,7 +148,7 @@ u8 *dispatch_hid_bpf_raw_requests(struct hid_device *hdev,
 				  unsigned char reportnum, __u8 *buf,
 				  u32 *size, enum hid_report_type rtype,
 				  enum hid_class_request reqtype,
-				  __u64 source);
+				  __u64 source, bool from_bpf);
 int hid_bpf_connect_device(struct hid_device *hdev);
 void hid_bpf_disconnect_device(struct hid_device *hdev);
 void hid_bpf_destroy_device(struct hid_device *hid);
@@ -162,7 +162,7 @@ static inline u8 *dispatch_hid_bpf_raw_requests(struct hid_device *hdev,
 						unsigned char reportnum, u8 *buf,
 						u32 *size, enum hid_report_type rtype,
 						enum hid_class_request reqtype,
-						u64 source) { return buf; }
+						u64 source, bool from_bpf) { return buf; }
 static inline int hid_bpf_connect_device(struct hid_device *hdev) { return 0; }
 static inline void hid_bpf_disconnect_device(struct hid_device *hdev) {}
 static inline void hid_bpf_destroy_device(struct hid_device *hid) {}

-- 
2.44.0


^ permalink raw reply related

* Re: [PATCH v3 06/11] dt-bindings: net/can: Add serial (serdev) LIN adapter
From: Christoph Fritz @ 2024-05-08 11:34 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Conor Dooley
  Cc: Jiri Slaby, Oliver Hartkopp, Marc Kleine-Budde, Vincent Mailhol,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jiri Kosina,
	Benjamin Tissoires, Greg Kroah-Hartman, Sebastian Reichel,
	Linus Walleij, Andreas Lauser, Jonathan Corbet, Pavel Pisa,
	linux-can, netdev, devicetree, linux-input, linux-serial
In-Reply-To: <f1173a7c-f18b-47cc-8873-30347489d1be@kernel.org>

On Mon, 2024-05-06 at 20:50 +0200, Krzysztof Kozlowski wrote:
> On 06/05/2024 18:16, Conor Dooley wrote:
> > > > > +maintainers:
> > > > > +  - Christoph Fritz <christoph.fritz@hexdev.de>
> > > > > +
> > > > > +properties:
> > > > > +  compatible:
> > > > > +    const: hexdev,lin-serdev
> > > > 
> > > > Maybe I've just missed something on earlier versions that I didn't
> > > > read, but the name of the device on the website you link is "hexLIN",
> > > > so why is "lin-serdev" used here instead?
> > > 
> > > The USB one is called hexLIN and has it's own HID driver.
> > > 
> > > This serial LIN adapter doesn't really have a product name. Currently
> > > on our website it's generically called 'UART LIN Adapter'.
> > > 
> > > This LIN adapter is basically just a LIN transceiver and very generic,
> > > so that one could solder it to any single-board computer with an uart.
> > > 
> > > I think 'lin-serdev' for LIN and serial device fits great, also serdev
> > > is the name of the used kernel infrastructure (besides the LIN glue
> > > driver).
> > > 
> > > If you still don't like it, I'm open to other names. What about
> > > "hexlin-uart" or "linser"?
> >
> > I dunno, I don't really care about it being called "hexlin,lin-serdev",
> > all that much, I just found it confusing that the link in the description
> > sent me to the ""Hello World" in LIN" section of your site. If it had
> > dropped me off at the "UART LIN adapter" section things woud've been less
> > confusing.

Hi Conor and Krzysztof,

I guess this is a chromium oddity, because browsing to

 https://hexdev.de/hexlin#hexLINSER

brings the user to another headline ("hexLIN" not "hexLINSER") as long
as headline "hexLINSER" can be also displayed.

When using firefox, the top headline is hexLINSER as expected (at least
I do).

> > 
> > That said, calling the compatible after a linux-ism is a bit odd to me
> > when the device seems to be called a "UART LIN adapter" on the page, not
> > a "serdev".
> > 
> 
> If there is no real, fixed model name, I would also propose to use
> whatever is on the website currently and avoid Linuxism.

OK, I changed it to hexLINSER on the website and in the upcoming v4
revision of this patchset. LINSER for LIN and serial, or like in
"Linsen & Spätzle" :)

Thanks
  -- Christoph 


^ permalink raw reply

* Re: [PATCH] Input: goodix-berlin - Add sysfs interface for reading and writing touch IC registers
From: Mark Brown @ 2024-05-08 11:47 UTC (permalink / raw)
  To: Richard Hughes
  Cc: Dmitry Torokhov, Jeff LaBundy, Hans de Goede, Charles Wang,
	hadess, linux-input, linux-kernel, neil.armstrong
In-Reply-To: <CAD2FfiE+VFa+7sHQg=LGkBy556msNyyFUhmWW_cAfZd0V4DPYQ@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 535 bytes --]

On Wed, May 08, 2024 at 09:39:41AM +0100, Richard Hughes wrote:

> If it helps, fwupd already uses mtd for other devices too, although at
> the moment we're using it only for system firmware -- e.g. intel-spi
> style. The MTD subsystem doesn't give fwupd much info about the
> {removable} device itself, and that can pose a problem unless you
> start using heuristics about the parent device to match firmware to
> the mtd device.

FWIW I know SolareFlare network cards used to do this too, though I
don't know about current products.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH v2 1/5] selftests: Compile kselftest headers with -D_GNU_SOURCE
From: Mark Brown @ 2024-05-08 12:05 UTC (permalink / raw)
  To: Edward Liaw
  Cc: shuah, Jaroslav Kysela, Takashi Iwai, Catalin Marinas,
	Will Deacon, Nhat Pham, Johannes Weiner, Christian Brauner,
	Eric Biederman, Kees Cook, OGAWA Hirofumi, Thomas Gleixner,
	Ingo Molnar, Peter Zijlstra, Darren Hart, Davidlohr Bueso,
	André Almeida, Jiri Kosina, Benjamin Tissoires,
	Jason Gunthorpe, Kevin Tian, Andy Lutomirski, Will Drewry,
	Marc Zyngier, Oliver Upton, James Morse, Suzuki K Poulose,
	Zenghui Yu, Paolo Bonzini, Sean Christopherson, Anup Patel,
	Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Christian Borntraeger, Janosch Frank, Claudio Imbrenda,
	David Hildenbrand, Mickaël Salaün, Paul Moore,
	James Morris, Serge E. Hallyn, Andrew Morton, Seth Forshee,
	Bongsu Jeon, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Steffen Klassert, Herbert Xu, Andreas Färber,
	Manivannan Sadhasivam, Matthieu Baerts, Mat Martineau,
	Geliang Tang, Willem de Bruijn, Fenghua Yu, Reinette Chatre,
	Mathieu Desnoyers, Paul E. McKenney, Boqun Feng,
	Alexandre Belloni, Jarkko Sakkinen, Dave Hansen,
	Muhammad Usama Anjum, linux-kernel, linux-kselftest, kernel-team,
	linux-sound, linux-arm-kernel, linux-mm, linux-input, iommu,
	kvmarm, kvm, kvm-riscv, linux-riscv, linux-security-module,
	linux-fsdevel, netdev, linux-actions, mptcp, linux-rtc, linux-sgx,
	bpf, kernel test robot
In-Reply-To: <20240507214254.2787305-2-edliaw@google.com>

[-- Attachment #1: Type: text/plain, Size: 670 bytes --]

On Tue, May 07, 2024 at 09:38:26PM +0000, Edward Liaw wrote:
> Add the -D_GNU_SOURCE flag to KHDR_INCLUDES so that it is defined in a
> central location.
> 
> 809216233555 ("selftests/harness: remove use of LINE_MAX") introduced
> asprintf into kselftest_harness.h, which is a GNU extension and needs
> _GNU_SOURCE to either be defined prior to including headers or with the
> -D_GNU_SOURCE flag passed to the compiler.

Reviewed-by: Mark Brown <broonie@kernel.org>

This does mean we define _GNU_SOURCE for nolibc (and I guess any other
libc people use like bionic) but hopefully nobody's using the same
define with a different meaning so should be fine.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH v3 01/11] can: Add LIN bus as CAN abstraction
From: Christoph Fritz @ 2024-05-08 12:47 UTC (permalink / raw)
  To: Ilpo Järvinen, Oliver Hartkopp, Marc Kleine-Budde
  Cc: Jiri Slaby, Vincent Mailhol, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Jiri Kosina, Benjamin Tissoires, Greg Kroah-Hartman,
	Sebastian Reichel, Linus Walleij, Andreas Lauser, Jonathan Corbet,
	Pavel Pisa, linux-can, netdev, devicetree, linux-input,
	linux-serial
In-Reply-To: <61adf428-2205-1563-d0b6-fa843e08559d@linux.intel.com>

On Mon, 2024-05-06 at 19:24 +0300, Ilpo Järvinen wrote:
> On Thu, 2 May 2024, Christoph Fritz wrote:
> 
> > This patch adds a LIN (local interconnect network) bus abstraction on
> > top of CAN.  It is a glue driver adapting CAN on one side while offering
> > LIN abstraction on the other side. So that upcoming LIN device drivers
> > can make use of it.
...
> > +static ssize_t lin_identifier_show(struct kobject *kobj,
> > +				   struct kobj_attribute *attr, char *buf)
> > +{
> > +	struct lin_attr *lin_attr = container_of(attr, struct lin_attr, attr);
> > +	struct lin_device *ldev = lin_attr->ldev;
> > +	ssize_t count = 0;
> > +	struct lin_responder_answer answ;
> > +	int k, ret;
> > +	long id;
> > +
> > +	if (!ldev->ldev_ops->get_responder_answer)
> > +		return -EOPNOTSUPP;
> > +
> > +	ret = kstrtol(attr->attr.name, 16, &id);
> > +	if (ret)
> > +		return ret;
> > +	if (id < 0 || id >= LIN_NUM_IDS)
> > +		return -EINVAL;
> > +
> > +	count += scnprintf(buf + count, PAGE_SIZE - count,
> > +			   "%-6s %-11s %-9s %-9s %-2s %-24s %-6s\n",
> > +			   "state", "cksum-mode", "is_event", "event_id",
> > +			   "n", "data", "cksum");
> 
> Onl use sysfs_emit() and sysfs_emit_at() in *_show functions.

OK

> > +
> > +	ret = ldev->ldev_ops->get_responder_answer(ldev, id, &answ);
> > +	if (ret)
> > +		return ret;
> > +
> > +	count += scnprintf(buf + count, PAGE_SIZE - count,
> > +			   "%-6s %-11s %-9s %-9u %-2u ",
> > +			   answ.is_active ? "active" : "off",
> > +			   answ.lf.checksum_mode ? "enhanced" : "classic",
> > +			   answ.is_event_frame ? "yes" : "no",
> > +			   answ.event_associated_id,
> > +			   answ.lf.len);
> > +
> > +	for (k = 0; k < answ.lf.len; k++)
> > +		count += scnprintf(buf + count, PAGE_SIZE - count,
> > +				   "%02x ", answ.lf.data[k]);
> > +	for (; k < 8; k++)
> > +		count += scnprintf(buf + count, PAGE_SIZE - count,
> > +				   "   ");
> > +	if (answ.lf.len)
> > +		count += scnprintf(buf + count, PAGE_SIZE - count,
> > +				   " %02x", answ.lf.checksum);
> > +
> > +	count += scnprintf(buf + count, PAGE_SIZE - count, "\n");
> > +
> > +	return count;
> > +}
...
> > +
> > +static int lin_create_sysfs_id_files(struct net_device *ndev)
> > +{
> > +	struct lin_device *ldev = netdev_priv(ndev);
> > +	struct kobj_attribute *attr;
> > +	int ret;
> > +
> > +	for (int id = 0; id < LIN_NUM_IDS; id++) {
> > +		ldev->sysfs_entries[id].ldev = ldev;
> > +		attr = &ldev->sysfs_entries[id].attr;
> > +		attr->attr.name = kasprintf(GFP_KERNEL, "%02x", id);
> > +		if (!attr->attr.name)
> > +			return -ENOMEM;
> > +		attr->attr.mode = 0644;
> > +		attr->show = lin_identifier_show;
> > +		attr->store = lin_identifier_store;
> > +
> > +		sysfs_attr_init(&attr->attr);
> > +		ret = sysfs_create_file(ldev->lin_ids_kobj, &attr->attr);
> > +		if (ret) {
> > +			kfree(attr->attr.name);
> > +			return -ENOMEM;
> > +		}
> > +	}
> > +
> > +	return 0;
> > +}
> 
> Can you use .dev_groups instead ?

I'm not sure where to attach this in this glue code here. Should I do a
class_register() and add the .dev_groups there?

> FWIW, this function doesn't do rollback when error occurs.

OK, this issue can be fixed in revision v4.

...
> > diff --git a/include/net/lin.h b/include/net/lin.h
> > new file mode 100644
> > index 0000000000000..e7c7c820a6e18
> > --- /dev/null
> > +++ b/include/net/lin.h
> > @@ -0,0 +1,92 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +/* Copyright (C) 2024 hexDEV GmbH - https://hexdev.de */
> > +
> > +#ifndef _NET_LIN_H_
> > +#define _NET_LIN_H_
> > +
> > +#include <linux/bitfield.h>
> > +#include <linux/can/dev.h>
> > +#include <linux/device.h>
> > +
> > +#define LIN_NUM_IDS		64
> > +#define LIN_HEADER_SIZE		3
> > +#define LIN_MAX_DLEN		8
> > +
> > +#define LIN_MAX_BAUDRATE	20000
> > +#define LIN_MIN_BAUDRATE	1000
> > +#define LIN_DEFAULT_BAUDRATE	9600
> > +#define LIN_SYNC_BYTE		0x55
> > +
> > +#define LIN_ID_MASK		GENMASK(5, 0)
> > +/* special ID descriptions for LIN */
> > +#define LIN_RXOFFLOAD_DATA_FLAG	0x00000200U
> > +#define LIN_ENHANCED_CKSUM_FLAG	0x00000100U
> 
> BIT(x) x 2

OK

> 
> > +
> > +extern u8 lin_get_id_parity(u8 id);
> > +
> > +#define LIN_GET_ID(PID)		FIELD_GET(LIN_ID_MASK, PID)
> > +#define LIN_FORM_PID(ID)	(LIN_GET_ID(ID) | \
> > +					lin_get_id_parity(LIN_GET_ID(ID)))
> > +#define LIN_GET_PARITY(PID)	((PID) & ~LIN_ID_MASK)
> > +#define LIN_CHECK_PID(PID)	(LIN_GET_PARITY(PID) == \
> > +					LIN_GET_PARITY(LIN_FORM_PID(PID)))
> > +
> > +struct lin_attr {
> > +	struct kobj_attribute attr;
> > +	struct lin_device *ldev;
> > +};
> > +
> > +struct lin_device {
> > +	struct can_priv can;  /* must be the first member */
> > +	struct net_device *ndev;
> > +	struct device *dev;
> > +	const struct lin_device_ops *ldev_ops;
> > +	struct workqueue_struct *wq;
> > +	struct work_struct tx_work;
> > +	bool tx_busy;
> > +	struct sk_buff *tx_skb;
> > +	struct kobject *lin_ids_kobj;
> > +	struct lin_attr sysfs_entries[LIN_NUM_IDS];
> > +};
> > +
> > +enum lin_checksum_mode {
> > +	LINBUS_CLASSIC = 0,
> > +	LINBUS_ENHANCED,
> > +};
> > +
> > +struct lin_frame {
> > +	u8 lin_id;
> > +	u8 len;
> > +	u8 data[LIN_MAX_DLEN];
> > +	u8 checksum;
> > +	enum lin_checksum_mode checksum_mode;
> > +};
> > +
> > +struct lin_responder_answer {
> > +	bool is_active;
> > +	bool is_event_frame;
> > +	u8 event_associated_id;
> > +	struct lin_frame lf;
> > +};
> > +
> > +struct lin_device_ops {
> > +	int (*ldo_open)(struct lin_device *ldev);
> > +	int (*ldo_stop)(struct lin_device *ldev);
> > +	int (*ldo_tx)(struct lin_device *ldev, const struct lin_frame *frame);
> > +	int (*update_bitrate)(struct lin_device *ldev, u16 bitrate);
> > +	int (*update_responder_answer)(struct lin_device *ldev,
> > +				       const struct lin_responder_answer *answ);
> > +	int (*get_responder_answer)(struct lin_device *ldev, u8 id,
> > +				    struct lin_responder_answer *answ);
> > +};
> > +
> > +int lin_rx(struct lin_device *ldev, const struct lin_frame *lf);
> > +
> > +u8 lin_get_checksum(u8 pid, u8 n_of_bytes, const u8 *bytes,
> > +		    enum lin_checksum_mode cm);
> > +
> > +struct lin_device *register_lin(struct device *dev,
> > +				const struct lin_device_ops *ldops);
> > +void unregister_lin(struct lin_device *ldev);
> > +
> > +#endif /* _NET_LIN_H_ */
> > diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h
> > index 02ec32d694742..51b0e2a7624e4 100644
> > --- a/include/uapi/linux/can/netlink.h
> > +++ b/include/uapi/linux/can/netlink.h
> > @@ -103,6 +103,7 @@ struct can_ctrlmode {
> >  #define CAN_CTRLMODE_CC_LEN8_DLC	0x100	/* Classic CAN DLC option */
> >  #define CAN_CTRLMODE_TDC_AUTO		0x200	/* CAN transiver automatically calculates TDCV */
> >  #define CAN_CTRLMODE_TDC_MANUAL		0x400	/* TDCV is manually set up by user */
> 
> BIT(x) is these days available also for uapi I think.
> 
> > +#define CAN_CTRLMODE_LIN		0x800	/* LIN bus mode */

So, should I use just BIT(11) for the new define, or should I also
refactor the whole list while at it?

Thanks
  -- Christoph

^ permalink raw reply

* Re: [PATCH v3 01/11] can: Add LIN bus as CAN abstraction
From: Ilpo Järvinen @ 2024-05-08 13:08 UTC (permalink / raw)
  To: Christoph Fritz
  Cc: Oliver Hartkopp, Marc Kleine-Budde, Jiri Slaby, Vincent Mailhol,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jiri Kosina,
	Benjamin Tissoires, Greg Kroah-Hartman, Sebastian Reichel,
	Linus Walleij, Andreas Lauser, Jonathan Corbet, Pavel Pisa,
	linux-can, Netdev, devicetree, linux-input, linux-serial
In-Reply-To: <e0f3d0716ed2f4281561f08bbcd3050dddcf1831.camel@hexdev.de>

[-- Attachment #1: Type: text/plain, Size: 2565 bytes --]

On Wed, 8 May 2024, Christoph Fritz wrote:

> On Mon, 2024-05-06 at 19:24 +0300, Ilpo Järvinen wrote:
> > On Thu, 2 May 2024, Christoph Fritz wrote:
> > 
> > > This patch adds a LIN (local interconnect network) bus abstraction on
> > > top of CAN.  It is a glue driver adapting CAN on one side while offering
> > > LIN abstraction on the other side. So that upcoming LIN device drivers
> > > can make use of it.

> > > +static int lin_create_sysfs_id_files(struct net_device *ndev)
> > > +{
> > > +	struct lin_device *ldev = netdev_priv(ndev);
> > > +	struct kobj_attribute *attr;
> > > +	int ret;
> > > +
> > > +	for (int id = 0; id < LIN_NUM_IDS; id++) {
> > > +		ldev->sysfs_entries[id].ldev = ldev;
> > > +		attr = &ldev->sysfs_entries[id].attr;
> > > +		attr->attr.name = kasprintf(GFP_KERNEL, "%02x", id);
> > > +		if (!attr->attr.name)
> > > +			return -ENOMEM;
> > > +		attr->attr.mode = 0644;
> > > +		attr->show = lin_identifier_show;
> > > +		attr->store = lin_identifier_store;
> > > +
> > > +		sysfs_attr_init(&attr->attr);
> > > +		ret = sysfs_create_file(ldev->lin_ids_kobj, &attr->attr);
> > > +		if (ret) {
> > > +			kfree(attr->attr.name);
> > > +			return -ENOMEM;
> > > +		}
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > 
> > Can you use .dev_groups instead ?
> 
> I'm not sure where to attach this in this glue code here. Should I do a
> class_register() and add the .dev_groups there?

I guess struct class would be correct direction but I'm not sure if it's 
viable in this case. It would avoid the need for custom sysfs setup code
if it's workable.

> > FWIW, this function doesn't do rollback when error occurs.
> 
> OK, this issue can be fixed in revision v4.
> 
> ...

> > > diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h
> > > index 02ec32d694742..51b0e2a7624e4 100644
> > > --- a/include/uapi/linux/can/netlink.h
> > > +++ b/include/uapi/linux/can/netlink.h
> > > @@ -103,6 +103,7 @@ struct can_ctrlmode {
> > >  #define CAN_CTRLMODE_CC_LEN8_DLC	0x100	/* Classic CAN DLC option */
> > >  #define CAN_CTRLMODE_TDC_AUTO		0x200	/* CAN transiver automatically calculates TDCV */
> > >  #define CAN_CTRLMODE_TDC_MANUAL		0x400	/* TDCV is manually set up by user */
> > 
> > BIT(x) is these days available also for uapi I think.
> > 
> > > +#define CAN_CTRLMODE_LIN		0x800	/* LIN bus mode */
> 
> So, should I use just BIT(11) for the new define, or should I also
> refactor the whole list while at it?

Either is fine for me.

-- 
 i.

^ permalink raw reply

* Re: [PATCH v2 0/5] Define _GNU_SOURCE for sources using
From: Sean Christopherson @ 2024-05-08 13:47 UTC (permalink / raw)
  To: Edward Liaw
  Cc: shuah, Mark Brown, Jaroslav Kysela, Takashi Iwai, Catalin Marinas,
	Will Deacon, Nhat Pham, Johannes Weiner, Christian Brauner,
	Eric Biederman, Kees Cook, OGAWA Hirofumi, Thomas Gleixner,
	Ingo Molnar, Peter Zijlstra, Darren Hart, Davidlohr Bueso,
	André Almeida, Jiri Kosina, Benjamin Tissoires,
	Jason Gunthorpe, Kevin Tian, Andy Lutomirski, Will Drewry,
	Marc Zyngier, Oliver Upton, James Morse, Suzuki K Poulose,
	Zenghui Yu, Paolo Bonzini, Anup Patel, Atish Patra, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
	Claudio Imbrenda, David Hildenbrand, Mickaël Salaün,
	Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton,
	Seth Forshee, Bongsu Jeon, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Steffen Klassert, Herbert Xu,
	Andreas Färber, Manivannan Sadhasivam, Matthieu Baerts,
	Mat Martineau, Geliang Tang, Willem de Bruijn, Fenghua Yu,
	Reinette Chatre, Mathieu Desnoyers, Paul E. McKenney, Boqun Feng,
	Alexandre Belloni, Jarkko Sakkinen, Dave Hansen,
	Muhammad Usama Anjum, linux-kernel, linux-kselftest, kernel-team,
	linux-sound, linux-arm-kernel, linux-mm, linux-input, iommu,
	kvmarm, kvm, kvm-riscv, linux-riscv, linux-security-module,
	linux-fsdevel, netdev, linux-actions, mptcp, linux-rtc, linux-sgx,
	bpf
In-Reply-To: <20240507214254.2787305-1-edliaw@google.com>

On Tue, May 07, 2024, Edward Liaw wrote:
> 809216233555 ("selftests/harness: remove use of LINE_MAX") introduced
> asprintf into kselftest_harness.h, which is a GNU extension and needs
> _GNU_SOURCE to either be defined prior to including headers or with the
> -D_GNU_SOURCE flag passed to the compiler.
> 
> v1: https://lore.kernel.org/linux-kselftest/20240430235057.1351993-1-edliaw@google.com/
> v2: add -D_GNU_SOURCE to KHDR_INCLUDES so that it is in a single
> location.  Remove #define _GNU_SOURCE from source code to resolve
> redefinition warnings.
> 
> Edward Liaw (5):
>   selftests: Compile kselftest headers with -D_GNU_SOURCE
>   selftests/sgx: Include KHDR_INCLUDES in Makefile
>   selftests: Include KHDR_INCLUDES in Makefile
>   selftests: Drop define _GNU_SOURCE
>   selftests: Drop duplicate -D_GNU_SOURCE

Can you rebase this on top of linux-next?  I have a conflicting fix[*] for the
KVM selftests queued for 6.10, and I would prefer not to drop that commit at
this stage as it would require a rebase of a pile of other commits.

And I doubt KVM is the only subsystem that has a targeted fix for the _GNU_SOURCE
mess.

If we want/need to get a fix into 6.9, then IMO we should just revert 809216233555
("selftests/harness: remove use of LINE_MAX"), as that came in quite late in the
6.9 cycle, and I don't think it's feasible to be 100% confident that globally
defining _GNU_SOURCE works for all selftests, i.e. we really should have a full
cycle for folks to test.

[*] https://github.com/kvm-x86/linux/commit/730cfa45b5f4

^ permalink raw reply

* Re: [PATCH v2 4/5] selftests: Drop define _GNU_SOURCE
From: Sean Christopherson @ 2024-05-08 13:54 UTC (permalink / raw)
  To: Edward Liaw
  Cc: shuah, Mark Brown, Jaroslav Kysela, Takashi Iwai, Catalin Marinas,
	Will Deacon, Nhat Pham, Johannes Weiner, Christian Brauner,
	Eric Biederman, Kees Cook, OGAWA Hirofumi, Thomas Gleixner,
	Ingo Molnar, Peter Zijlstra, Darren Hart, Davidlohr Bueso,
	André Almeida, Jiri Kosina, Benjamin Tissoires,
	Jason Gunthorpe, Kevin Tian, Andy Lutomirski, Will Drewry,
	Marc Zyngier, Oliver Upton, James Morse, Suzuki K Poulose,
	Zenghui Yu, Paolo Bonzini, Anup Patel, Atish Patra, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
	Claudio Imbrenda, David Hildenbrand, Mickaël Salaün,
	Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton,
	Seth Forshee, Bongsu Jeon, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Steffen Klassert, Herbert Xu,
	Andreas Färber, Manivannan Sadhasivam, Matthieu Baerts,
	Mat Martineau, Geliang Tang, Willem de Bruijn, Fenghua Yu,
	Reinette Chatre, Mathieu Desnoyers, Paul E. McKenney, Boqun Feng,
	Alexandre Belloni, Jarkko Sakkinen, Dave Hansen,
	Muhammad Usama Anjum, linux-kernel, linux-kselftest, kernel-team,
	linux-sound, linux-arm-kernel, linux-mm, linux-input, iommu,
	kvmarm, kvm, kvm-riscv, linux-riscv, linux-security-module,
	linux-fsdevel, netdev, linux-actions, mptcp, linux-rtc, linux-sgx,
	bpf
In-Reply-To: <20240507214254.2787305-5-edliaw@google.com>

On Tue, May 07, 2024, Edward Liaw wrote:
> _GNU_SOURCE is provided by KHDR_INCLUDES, so it should be dropped to
> prevent _GNU_SOURCE redefined warnings.

...

> diff --git a/tools/testing/selftests/x86/test_syscall_vdso.c b/tools/testing/selftests/x86/test_syscall_vdso.c
> index 8965c311bd65..5cd13279bba5 100644
> --- a/tools/testing/selftests/x86/test_syscall_vdso.c
> +++ b/tools/testing/selftests/x86/test_syscall_vdso.c
> @@ -8,10 +8,6 @@
>   * Can be built statically:
>   * gcc -Os -Wall -static -m32 test_syscall_vdso.c thunks_32.S
>   */
> -#undef _GNU_SOURCE
> -#define _GNU_SOURCE 1
> -#undef __USE_GNU
> -#define __USE_GNU 1

AFAICT, manually defining __USE_GNU is frowned upon, so I'm guessing the __USE_GNU
stuff is just the result of misguided copy+paste.  But it would be nice to get
confirmation that this test isn't doing something clever.  Or at the very least,
explain the removal of __USE_GNU in the changelog.

>  #include <unistd.h>
>  #include <stdlib.h>
>  #include <string.h>

^ permalink raw reply

* Re: [PATCH v2 2/5] selftests/sgx: Include KHDR_INCLUDES in Makefile
From: Dave Hansen @ 2024-05-08 15:33 UTC (permalink / raw)
  To: Edward Liaw, shuah, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Catalin Marinas, Will Deacon, Nhat Pham, Johannes Weiner,
	Christian Brauner, Eric Biederman, Kees Cook, OGAWA Hirofumi,
	Thomas Gleixner, Ingo Molnar, Peter Zijlstra, Darren Hart,
	Davidlohr Bueso, André Almeida, Jiri Kosina,
	Benjamin Tissoires, Jason Gunthorpe, Kevin Tian, Andy Lutomirski,
	Will Drewry, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Paolo Bonzini, Sean Christopherson,
	Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Christian Borntraeger, Janosch Frank, Claudio Imbrenda,
	David Hildenbrand, Mickaël Salaün, Paul Moore,
	James Morris, Serge E. Hallyn, Andrew Morton, Seth Forshee,
	Bongsu Jeon, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Steffen Klassert, Herbert Xu, Andreas Färber,
	Manivannan Sadhasivam, Matthieu Baerts, Mat Martineau,
	Geliang Tang, Willem de Bruijn, Fenghua Yu, Reinette Chatre,
	Mathieu Desnoyers, Paul E. McKenney, Boqun Feng,
	Alexandre Belloni, Jarkko Sakkinen, Muhammad Usama Anjum
  Cc: linux-kernel, linux-kselftest, kernel-team, linux-sound,
	linux-arm-kernel, linux-mm, linux-input, iommu, kvmarm, kvm,
	kvm-riscv, linux-riscv, linux-security-module, linux-fsdevel,
	netdev, linux-actions, mptcp, linux-rtc, linux-sgx, bpf,
	kernel test robot
In-Reply-To: <20240507214254.2787305-3-edliaw@google.com>

On 5/7/24 14:38, Edward Liaw wrote:
> Add KHDR_INCLUDES to the CFLAGS to pull in the kselftest harness
> dependencies (-D_GNU_SOURCE).
> 
> Also, remove redefinitions of _GNU_SOURCE in the source code.

From an x86 and SGX perspective, looks fine.  I assume Shuah is planning
on taking this pile.

Acked-by: Dave Hansen <dave.hansen@linux.intel.com>

^ permalink raw reply

* Re: [PATCH v3 06/11] dt-bindings: net/can: Add serial (serdev) LIN adapter
From: Conor Dooley @ 2024-05-08 16:16 UTC (permalink / raw)
  To: Christoph Fritz
  Cc: Krzysztof Kozlowski, Jiri Slaby, Oliver Hartkopp,
	Marc Kleine-Budde, Vincent Mailhol, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jiri Kosina,
	Benjamin Tissoires, Greg Kroah-Hartman, Sebastian Reichel,
	Linus Walleij, Andreas Lauser, Jonathan Corbet, Pavel Pisa,
	linux-can, netdev, devicetree, linux-input, linux-serial
In-Reply-To: <b716f34ce54dfed2595690d37c121d242a18ff64.camel@hexdev.de>

[-- Attachment #1: Type: text/plain, Size: 2315 bytes --]

On Wed, May 08, 2024 at 01:34:34PM +0200, Christoph Fritz wrote:
> On Mon, 2024-05-06 at 20:50 +0200, Krzysztof Kozlowski wrote:
> > On 06/05/2024 18:16, Conor Dooley wrote:
> > > > > > +maintainers:
> > > > > > +  - Christoph Fritz <christoph.fritz@hexdev.de>
> > > > > > +
> > > > > > +properties:
> > > > > > +  compatible:
> > > > > > +    const: hexdev,lin-serdev
> > > > > 
> > > > > Maybe I've just missed something on earlier versions that I didn't
> > > > > read, but the name of the device on the website you link is "hexLIN",
> > > > > so why is "lin-serdev" used here instead?
> > > > 
> > > > The USB one is called hexLIN and has it's own HID driver.
> > > > 
> > > > This serial LIN adapter doesn't really have a product name. Currently
> > > > on our website it's generically called 'UART LIN Adapter'.
> > > > 
> > > > This LIN adapter is basically just a LIN transceiver and very generic,
> > > > so that one could solder it to any single-board computer with an uart.
> > > > 
> > > > I think 'lin-serdev' for LIN and serial device fits great, also serdev
> > > > is the name of the used kernel infrastructure (besides the LIN glue
> > > > driver).
> > > > 
> > > > If you still don't like it, I'm open to other names. What about
> > > > "hexlin-uart" or "linser"?
> > >
> > > I dunno, I don't really care about it being called "hexlin,lin-serdev",
> > > all that much, I just found it confusing that the link in the description
> > > sent me to the ""Hello World" in LIN" section of your site. If it had
> > > dropped me off at the "UART LIN adapter" section things woud've been less
> > > confusing.
> 
> Hi Conor and Krzysztof,
> 
> I guess this is a chromium oddity, because browsing to
> 
>  https://hexdev.de/hexlin#hexLINSER
> 
> brings the user to another headline ("hexLIN" not "hexLINSER") as long
> as headline "hexLINSER" can be also displayed.
> 
> When using firefox, the top headline is hexLINSER as expected (at least
> I do).


Yeah, I think its actually chrome that I saw it originally, but that's
probably irrelevant. After your re-org, in Chrome, if the window is small
enough, I still only see the "3 Open Source Tool: hexLIN" stuff, but
that's not an issue with the binding itself, so I won't hold things up
on that basis.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH v2 2/5] selftests/sgx: Include KHDR_INCLUDES in Makefile
From: Jarkko Sakkinen @ 2024-05-08 16:44 UTC (permalink / raw)
  To: Dave Hansen, Edward Liaw, shuah, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Catalin Marinas, Will Deacon, Nhat Pham,
	Johannes Weiner, Christian Brauner, Eric Biederman, Kees Cook,
	OGAWA Hirofumi, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
	Darren Hart, Davidlohr Bueso, André Almeida, Jiri Kosina,
	Benjamin Tissoires, Jason Gunthorpe, Kevin Tian, Andy Lutomirski,
	Will Drewry, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Paolo Bonzini, Sean Christopherson,
	Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Christian Borntraeger, Janosch Frank, Claudio Imbrenda,
	David Hildenbrand, Mickaël Salaün, Paul Moore,
	James Morris, Serge E. Hallyn, Andrew Morton, Seth Forshee,
	Bongsu Jeon, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Steffen Klassert, Herbert Xu, Andreas Färber,
	Manivannan Sadhasivam, Matthieu Baerts, Mat Martineau,
	Geliang Tang, Willem de Bruijn, Fenghua Yu, Reinette Chatre,
	Mathieu Desnoyers, Paul E. McKenney, Boqun Feng,
	Alexandre Belloni, Muhammad Usama Anjum
  Cc: linux-kernel, linux-kselftest, kernel-team, linux-sound,
	linux-arm-kernel, linux-mm, linux-input, iommu, kvmarm, kvm,
	kvm-riscv, linux-riscv, linux-security-module, linux-fsdevel,
	netdev, linux-actions, mptcp, linux-rtc, linux-sgx, bpf,
	kernel test robot
In-Reply-To: <c3fc5396-bc71-4dee-a3e0-d59dbbc6eda1@intel.com>

On Wed May 8, 2024 at 6:33 PM EEST, Dave Hansen wrote:
> On 5/7/24 14:38, Edward Liaw wrote:
> > Add KHDR_INCLUDES to the CFLAGS to pull in the kselftest harness
> > dependencies (-D_GNU_SOURCE).
> > 
> > Also, remove redefinitions of _GNU_SOURCE in the source code.
>
> From an x86 and SGX perspective, looks fine.  I assume Shuah is planning
> on taking this pile.
>
> Acked-by: Dave Hansen <dave.hansen@linux.intel.com>

Yep,

Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>

I also quickly tested with NUC7 for what it is worth:

Tested-by: Jarkko Sakkinen <jarkko@kernel.org>

BR, Jarkko

^ permalink raw reply

* Re: [PATCH v2 0/5] Define _GNU_SOURCE for sources using
From: Edward Liaw @ 2024-05-08 18:03 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: shuah, Mark Brown, Jaroslav Kysela, Takashi Iwai, Catalin Marinas,
	Will Deacon, Nhat Pham, Johannes Weiner, Christian Brauner,
	Eric Biederman, Kees Cook, OGAWA Hirofumi, Thomas Gleixner,
	Ingo Molnar, Peter Zijlstra, Darren Hart, Davidlohr Bueso,
	André Almeida, Jiri Kosina, Benjamin Tissoires,
	Jason Gunthorpe, Kevin Tian, Andy Lutomirski, Will Drewry,
	Marc Zyngier, Oliver Upton, James Morse, Suzuki K Poulose,
	Zenghui Yu, Paolo Bonzini, Anup Patel, Atish Patra, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
	Claudio Imbrenda, David Hildenbrand, Mickaël Salaün,
	Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton,
	Seth Forshee, Bongsu Jeon, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Steffen Klassert, Herbert Xu,
	Andreas Färber, Manivannan Sadhasivam, Matthieu Baerts,
	Mat Martineau, Geliang Tang, Willem de Bruijn, Fenghua Yu,
	Reinette Chatre, Mathieu Desnoyers, Paul E. McKenney, Boqun Feng,
	Alexandre Belloni, Jarkko Sakkinen, Dave Hansen,
	Muhammad Usama Anjum, linux-kernel, linux-kselftest, kernel-team,
	linux-sound, linux-arm-kernel, linux-mm, linux-input, iommu,
	kvmarm, kvm, kvm-riscv, linux-riscv, linux-security-module,
	linux-fsdevel, netdev, linux-actions, mptcp, linux-rtc, linux-sgx,
	bpf
In-Reply-To: <ZjuA3aY_iHkjP7bQ@google.com>

On Wed, May 8, 2024 at 6:47 AM Sean Christopherson <seanjc@google.com> wrote:
>
> On Tue, May 07, 2024, Edward Liaw wrote:
> > 809216233555 ("selftests/harness: remove use of LINE_MAX") introduced
> > asprintf into kselftest_harness.h, which is a GNU extension and needs
> > _GNU_SOURCE to either be defined prior to including headers or with the
> > -D_GNU_SOURCE flag passed to the compiler.
> >
> > v1: https://lore.kernel.org/linux-kselftest/20240430235057.1351993-1-edliaw@google.com/
> > v2: add -D_GNU_SOURCE to KHDR_INCLUDES so that it is in a single
> > location.  Remove #define _GNU_SOURCE from source code to resolve
> > redefinition warnings.
> >
> > Edward Liaw (5):
> >   selftests: Compile kselftest headers with -D_GNU_SOURCE
> >   selftests/sgx: Include KHDR_INCLUDES in Makefile
> >   selftests: Include KHDR_INCLUDES in Makefile
> >   selftests: Drop define _GNU_SOURCE
> >   selftests: Drop duplicate -D_GNU_SOURCE
>
> Can you rebase this on top of linux-next?  I have a conflicting fix[*] for the
> KVM selftests queued for 6.10, and I would prefer not to drop that commit at
> this stage as it would require a rebase of a pile of other commits.

Ok, I'll do that.

>
> And I doubt KVM is the only subsystem that has a targeted fix for the _GNU_SOURCE
> mess.
>
> If we want/need to get a fix into 6.9, then IMO we should just revert 809216233555
> ("selftests/harness: remove use of LINE_MAX"), as that came in quite late in the
> 6.9 cycle, and I don't think it's feasible to be 100% confident that globally
> defining _GNU_SOURCE works for all selftests, i.e. we really should have a full
> cycle for folks to test.

That sounds reasonable to me.  In this thread Tao suggested reverting
back to 809216233555 and using a fixed value in place of LINE_MAX to
fix 38c957f07038
https://lore.kernel.org/linux-kselftest/20240508070003.2acdf9b4@kernel.org/

>
> [*] https://github.com/kvm-x86/linux/commit/730cfa45b5f4

^ permalink raw reply

* Re: [PATCH v3 01/11] can: Add LIN bus as CAN abstraction
From: Christoph Fritz @ 2024-05-08 18:20 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Oliver Hartkopp, Marc Kleine-Budde, Jiri Slaby, Vincent Mailhol,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jiri Kosina,
	Benjamin Tissoires, Greg Kroah-Hartman, Sebastian Reichel,
	Linus Walleij, Andreas Lauser, Jonathan Corbet, Pavel Pisa,
	linux-can, Netdev, devicetree, linux-input, linux-serial
In-Reply-To: <4e8a50a0-f938-8aaf-fe4b-d18765407d4d@linux.intel.com>

...
> ...
> > > > +static int lin_create_sysfs_id_files(struct net_device *ndev)
> > > > +{
> > > > +	struct lin_device *ldev = netdev_priv(ndev);
> > > > +	struct kobj_attribute *attr;
> > > > +	int ret;
> > > > +
> > > > +	for (int id = 0; id < LIN_NUM_IDS; id++) {
> > > > +		ldev->sysfs_entries[id].ldev = ldev;
> > > > +		attr = &ldev->sysfs_entries[id].attr;
> > > > +		attr->attr.name = kasprintf(GFP_KERNEL, "%02x", id);
> > > > +		if (!attr->attr.name)
> > > > +			return -ENOMEM;
> > > > +		attr->attr.mode = 0644;
> > > > +		attr->show = lin_identifier_show;
> > > > +		attr->store = lin_identifier_store;
> > > > +
> > > > +		sysfs_attr_init(&attr->attr);
> > > > +		ret = sysfs_create_file(ldev->lin_ids_kobj, &attr->attr);
> > > > +		if (ret) {
> > > > +			kfree(attr->attr.name);
> > > > +			return -ENOMEM;
> > > > +		}
> > > > +	}
> > > > +
> > > > +	return 0;
> > > > +}
> > > 
> > > Can you use .dev_groups instead ?
> > 
> > I'm not sure where to attach this in this glue code here. Should I do a
> > class_register() and add the .dev_groups there?
> 
> I guess struct class would be correct direction but I'm not sure if it's 
> viable in this case. It would avoid the need for custom sysfs setup code
> if it's workable.

I just tried to find a way, but these are 64 sysfs files and declaring
them all static looks a bit odd to me. I might be missing something
here.

For v4 I would stick to the dynamic setup and fix the rollback.

Any objections?


Thanks
  -- Christoph


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox