Linux Input/HID development
 help / color / mirror / Atom feed
* [PATCH 4/4] HID: wacom: validate report length for 24HDT and 27QHDT handlers
From: Jinmo Yang @ 2026-05-17 13:52 UTC (permalink / raw)
  To: linux-input; +Cc: jikos, benjamin.tissoires, linux-kernel, stable, Jinmo Yang
In-Reply-To: <20260517135215.2220117-1-jinmo44.yang@gmail.com>

wacom_24hdt_irq() accesses data[61] for WACOM_24HDT and data[63] for
WACOM_27QHDT in the raw HID report buffer without validating the buffer
length. This sub-function is called from wacom_wac_irq() which receives
the length parameter but does not pass it to the handler.

A malicious USB device can declare a small HID report in its descriptor
and send a matching short report that passes the HID core size check
(csize >= rsize), but the driver assumes a full-size hardware report
layout, leading to slab-out-of-bounds reads.

Add minimum length checks in wacom_wac_irq() before dispatching to
wacom_24hdt_irq() for both device types.

Fixes: b1e4279e4ef5 ("Input: wacom - add touch sensor support for Cintiq 24HD touch")
Cc: stable@vger.kernel.org
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
---
 drivers/hid/wacom_wac.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 269e8318f..2fd1c4e80 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -3509,7 +3509,14 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
 		break;
 
 	case WACOM_24HDT:
+		if (len < 62)
+			return;
+		sync = wacom_24hdt_irq(wacom_wac);
+		break;
+
 	case WACOM_27QHDT:
+		if (len < 64)
+			return;
 		sync = wacom_24hdt_irq(wacom_wac);
 		break;
 
-- 
2.53.0


^ permalink raw reply related

* Re: [PATCH 1/4] HID: wacom: validate report length for PL and PTU handlers
From: sashiko-bot @ 2026-05-17 14:22 UTC (permalink / raw)
  To: Jinmo Yang; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <20260517135215.2220117-2-jinmo44.yang@gmail.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Incomplete Fix / Unhandled OOB Reads for Multiple Device Types
--

commit 4ac677c30d7590ff24c2b6674eafbe8d0fff6898
Author: Jinmo Yang <jinmo44.yang@gmail.com>

HID: wacom: validate report length for PL and PTU handlers

This commit adds minimum length checks before dispatching HID reports to
the PL and PTU handlers. This prevents slab-out-of-bounds reads when a
malicious device sends an artificially small report.

> diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
> index da1f0ea85625d..6d06842b64080 100644
> --- a/drivers/hid/wacom_wac.c
> +++ b/drivers/hid/wacom_wac.c
> @@ -3453,6 +3453,8 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
>  		break;
>  
>  	case PL:
> +		if (len < 8)
> +			return;
>  		sync = wacom_pl_irq(wacom_wac);
>  		break;
>  

[ ... ]

> @@ -3464,6 +3466,8 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
>  		break;
>  
>  	case PTU:
> +		if (len < 8)
> +			return;
>  		sync = wacom_ptu_irq(wacom_wac);
>  		break;
>  

While this successfully prevents out-of-bounds reads for PL and PTU devices,
do other handlers called from wacom_wac_irq() remain vulnerable to the same
issue?

For example, wacom_graphire_irq() unconditionally accesses data[8] for
WACOM_MO:

wacom_wac_irq()
  wacom_graphire_irq()
    case WACOM_MO:
      prox = (data[7] & 0xf8) || data[8];

Similarly, wacom_remote_irq() ignores its len argument and accesses up to
data[12], and wacom_intuos_pro2_bt_battery() can access data[284].

If a device spoofing these other types sends an undersized report, could it
bypass the checks added here and still trigger a slab-out-of-bounds read?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260517135215.2220117-1-jinmo44.yang@gmail.com?part=1

^ permalink raw reply

* Re: [PATCH 2/4] HID: wacom: validate report length for DTU handler
From: sashiko-bot @ 2026-05-17 14:47 UTC (permalink / raw)
  To: Jinmo Yang; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260517135215.2220117-3-jinmo44.yang@gmail.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Incomplete fix for slab-out-of-bounds read vulnerability. The patch correctly validates the buffer length for the DTU device handler, but leaves numerous other device handlers in the same function completely unpatched and vulnerable to the identical attack vector.
--

commit 873407ec5964c67c8e302293e3be453a56be7e51
Author: Jinmo Yang <jinmo44.yang@gmail.com>

HID: wacom: validate report length for DTU handler

wacom_dtu_irq() accesses fixed offsets up to data[7] in the raw HID
report buffer without validating the buffer length. This commit adds
a minimum length check in wacom_wac_irq() before dispatching to
wacom_dtu_irq() to prevent slab-out-of-bounds reads.

> diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
> index 6d06842b64080..873d58a6d5a3b 100644
> --- a/drivers/hid/wacom_wac.c
> +++ b/drivers/hid/wacom_wac.c
> @@ -3472,6 +3472,8 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
>  		break;
>  
>  	case DTU:
> +		if (len < 8)
> +			return;
>  		sync = wacom_dtu_irq(wacom_wac);
>  		break;

Could this same regression occur in the other device handlers called
from wacom_wac_irq()?

For example, cases like PENPARTNER, GRAPHIRE, and INTUOS also dispatch
to their respective handlers without checking len:

	switch (wacom_wac->features.type) {
	case PENPARTNER:
		sync = wacom_penpartner_irq(wacom_wac);
		break;
	[ ... ]
	case GRAPHIRE:
	[ ... ]
		sync = wacom_graphire_irq(wacom_wac);
		break;
	[ ... ]
	case INTUOS:
	[ ... ]
		sync = wacom_intuos_irq(wacom_wac);
		break;

Since these sub-handlers do not receive the len parameter, an attacker
spoofing the VID/PID of a PENPARTNER or INTUOS device might be able to
send a short report and trigger a similar out-of-bounds read regression.

Should length validations be added for the remaining device types to
ensure all handlers are protected?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260517135215.2220117-1-jinmo44.yang@gmail.com?part=2

^ permalink raw reply

* Re: [PATCH] platform/x86/lenovo: Add Yoga Book 9 keyboard dock detection driver
From: Dave Carey @ 2026-05-17 15:01 UTC (permalink / raw)
  To: ilpo.jarvinen
  Cc: hdegoede, pithenrich2d, mpearson-lenovo, derekjohn.clark, W_Armin,
	platform-driver-x86, linux-input, linux-kernel, Dave Carey
In-Reply-To: <9459f535-d140-a431-3f76-a5d8623f3e2d@linux.intel.com>

On Tue, 28 Apr 2026 17:39:17 +0300, Ilpo Järvinen wrote:
> On Sat, 25 Apr 2026, Dave Carey wrote:

Thank you for the review. All points addressed in v2 below.

> Please put this in depth explanation in own paragraph.
> This seems mostly duplicate of what was said previously.
> These two can be combined with the in depth explanation paragraph.
> Please write this without bullet points.

Commit message rewritten as prose. The hardware description, WMI
mechanism, and BKBD encoding are now combined into a single explanatory
paragraph. The functional summary (what the driver does) follows in a
second paragraph without bullet points.

> I don't think the functional description on this level is warranted in
> the top comment.

Top-of-file block comment trimmed to hardware context only. The
functional description (query on probe, SW_TABLET_MODE mapping, sysfs
attribute) has been removed from there; the comment now covers only the
two WMI GUIDs and the BKBD encoding table, which are non-obvious from
the code alone.

> This interface has been deprecated.

Done. v2 uses wmidev_block_query() with two arguments, returning
union acpi_object * directly. This required registering both the event
and query GUIDs in the id_table with context pointers (enum
yb9_guid_type) so the query wdev is reachable from probe and the notify
path. The event-device probe defers with -EPROBE_DEFER until the query
device arrives.

> Please use __free() instead of duplicating kfree()s.
> When converting to __free(), don't use ... = NULL; pattern, instead place
> the variable declaration mid-function as instructed in cleanup.h.

Done. The obj declaration now uses __free(kfree) placed mid-function
after the early-exit checks, per the cleanup.h guidance. Added
linux/cleanup.h to the includes.

> Can this literal be named with a define? Should it use FIELD_GET()?
> (don't forget the header if you start to use FIELD_GET())

Done. BKBD_MASK is now GENMASK(1, 0) and both extraction sites use
FIELD_GET(BKBD_MASK, bkbd). Added linux/bitfield.h to the includes.

> Unnecessary cast. And your types are a major mess between int and
> unsigned types.

Fixed. The query function returns int throughout (0-2 on success,
-errno on error); the cast is gone. Local variables in yb9_kbdock_update
are consistently int.

> Please use reverse-xmas tree order.

Fixed in yb9_kbdock_update(): tablet_mode is now declared before bkbd.

> WARN_ON_ONCE() instead of just WARN_ON() in the sysfs show function.

Done.

> You didn't document unknown but return it (maybe it should return some
> -Exx code instead?).

The "unknown" fourth entry has been removed entirely. BKBD value 3 is
now caught in yb9_kbdock_query() and returned as -EINVAL so it never
reaches the sysfs show function or priv->bkbd. The show function uses
WARN_ON_ONCE(bkbd >= ARRAY_SIZE(names)) and returns -EINVAL as
suggested — this can only fire if there is a driver bug.

> Missing include.

Added linux/bitfield.h (FIELD_GET) and linux/cleanup.h (__free).

> Normally these [DMI table] appear towards the end of the file.

Moved to just before yb9_kbdock_probe().

> Put the last two lines to one line.

Done.

> I wonder if this is similar physically to what is being added here:
> https://lore.kernel.org/all/20260419102724.91451-1-pithenrich2d@gmail.com/
> If yes, we may have to take another look at how to create the interface
> for this.

Pit Henrich's patch targets the ThinkPad X1 Fold 16 Gen 1 — also a
Lenovo device with a magnetically-attached keyboard that docks to the
display and changes between tablet and laptop mode, so the concept is
physically similar.

However, the two drivers differ in several meaningful ways:

  * Different hardware families and kernel paths: the X1 Fold patch
    extends thinkpad_acpi using an ACPI method (\\_SB.DEVD.GDST) and
    the existing TP_HKEY_EV_TABLET_CHANGED hotkey path. The Yoga Book 9
    driver is a standalone WMI driver using two separate WMI GUIDs.

  * Different state cardinality: the X1 Fold has a binary
    keyboard_attached_on_screen attribute because the keyboard is either
    present or not. The Yoga Book 9 needs three states — detached,
    docked on the top half of the bottom screen, or docked on the bottom
    half — because the two docked positions select different screen
    layouts that userspace needs to distinguish. A binary attribute
    would lose that information.

  * SW_TABLET_MODE: both drivers emit SW_TABLET_MODE=1 when the
    keyboard is absent and SW_TABLET_MODE=0 when docked, consistent
    with existing drivers in this subsystem.

Given these differences the sysfs attribute semantics do not clash, but
if a preferred naming convention is being established for keyboard-dock
attributes across these devices I am happy to align with whatever is
decided for the X1 Fold patch.

Dave

^ permalink raw reply

* [PATCH v2] platform/x86/lenovo: add Yoga Book 9 keyboard dock driver
From: Dave Carey @ 2026-05-17 15:02 UTC (permalink / raw)
  To: ilpo.jarvinen
  Cc: hdegoede, pithenrich2d, mpearson-lenovo, derekjohn.clark, W_Armin,
	platform-driver-x86, linux-input, linux-kernel, Dave Carey
In-Reply-To: <9459f535-d140-a431-3f76-a5d8623f3e2d@linux.intel.com>

The Lenovo Yoga Book 9 14IAH10 (83KJ) ships with a detachable Bluetooth
keyboard that magnetically attaches to the bottom screen in one of two
positions.

The Embedded Controller tracks the attachment state in a 2-bit field called
BKBD (byte 0x23 of EC RAM, bits 4-5) and signals changes via EC query _QB0,
which calls Notify(WM10, 0xEB) on the WM10 ACPI WMI device (_UID "GMZN").
The WMI event GUID 806BD2A2-177B-481D-BFB5-3BA0BB4A2285 fires on every
state change.  The current state is readable at any time via WMI data block
E7F300FA-21CD-4003-ADAC-2696135982E6 (WQAF), which returns an 8-byte buffer
whose upper four bytes hold the BKBD value.  BKBD encodes the attachment
state as: 0 = keyboard detached, 1 = docked on the top half of the bottom
screen, 2 = docked on the bottom half, 3 = reserved (treated as an error by
this driver).

Add a new driver, lenovo-yb9-kbdock, that queries the BKBD state on probe
and on each WMI event notification.  Both docked positions indicate a
physical keyboard is present and report SW_TABLET_MODE=0 (laptop mode);
keyboard detached reports SW_TABLET_MODE=1 (tablet mode).  The raw BKBD
value is additionally exposed via the read-only sysfs attribute
"keyboard_position" for userspace that needs to distinguish the two docked
positions (e.g. to choose a different UI layout).

Tested on Lenovo Yoga Book 9 14IAH10 (83KJ): all three BKBD states
(detached, top-half dock, bottom-half dock) reported correctly;
SW_TABLET_MODE transitions verified with evtest.

Signed-off-by: Dave Carey <carvsdriver@gmail.com>
---
 drivers/platform/x86/lenovo/Kconfig       | 14 ++++
 drivers/platform/x86/lenovo/Makefile      |  1 +
 drivers/platform/x86/lenovo/yb9-kbdock.c | 233 +++++++++++++++++++++
 3 files changed, 248 insertions(+)
 create mode 100644 drivers/platform/x86/lenovo/yb9-kbdock.c

--- a/drivers/platform/x86/lenovo/Kconfig
+++ b/drivers/platform/x86/lenovo/Kconfig
@@ -43,6 +43,20 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called lenovo-wmi-camera.

+config LENOVO_YB9_KBDOCK
+	tristate "Lenovo Yoga Book 9 keyboard dock detection"
+	depends on ACPI_WMI
+	depends on DMI
+	depends on INPUT
+	help
+	  Say Y here to enable keyboard dock detection on the Lenovo Yoga Book 9
+	  14IAH10.  The detachable Bluetooth keyboard magnetically attaches to
+	  either screen; this driver reports SW_TABLET_MODE input events based
+	  on the attachment state and exposes the raw position in sysfs.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called lenovo-yb9-kbdock.
+
 config LENOVO_YMC
 	tristate "Lenovo Yoga Tablet Mode Control"
 	depends on ACPI_WMI
--- a/drivers/platform/x86/lenovo/Makefile
+++ b/drivers/platform/x86/lenovo/Makefile
@@ -8,6 +8,7 @@
 obj-$(CONFIG_THINKPAD_ACPI)	+= thinkpad_acpi.o

 lenovo-target-$(CONFIG_LENOVO_WMI_HOTKEY_UTILITIES)	+= wmi-hotkey-utilities.o
+lenovo-target-$(CONFIG_LENOVO_YB9_KBDOCK)	+= yb9-kbdock.o
 lenovo-target-$(CONFIG_LENOVO_YMC)	+= ymc.o
 lenovo-target-$(CONFIG_YOGABOOK)	+= yogabook.o
 lenovo-target-$(CONFIG_YT2_1380)	+= yoga-tab2-pro-1380-fastcharger.o
--- a/drivers/platform/x86/lenovo/yb9-kbdock.c
+++ b/drivers/platform/x86/lenovo/yb9-kbdock.c
@@ -0,0 +1,233 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Lenovo Yoga Book 9 keyboard-dock detection
+ *
+ * Reports SW_TABLET_MODE based on keyboard attachment state and exposes the
+ * raw dock position via sysfs.
+ *
+ * Copyright (C) 2026 Dave Carey <carvsdriver@gmail.com>
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/acpi.h>
+#include <linux/bitfield.h>
+#include <linux/cleanup.h>
+#include <linux/dmi.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/wmi.h>
+
+/*
+ * WM10 ACPI device (_UID "GMZN") exposes two relevant WMI GUIDs:
+ *   YB9_KBDOCK_EVENT_GUID — notify ID 0xEB fires on attachment state change.
+ *   YB9_KBDOCK_QUERY_GUID — object "AF" (WQAF), returns an 8-byte buffer
+ *                           whose upper four bytes hold the BKBD value.
+ *
+ * BKBD encoding:
+ *   0 (BKBD_DETACHED)    — keyboard detached       → SW_TABLET_MODE = 1
+ *   1 (BKBD_TOP_HALF)    — docked, top half        → SW_TABLET_MODE = 0
+ *   2 (BKBD_BOTTOM_HALF) — docked, bottom half     → SW_TABLET_MODE = 0
+ *   3                    — reserved; treated as an error
+ */
+#define YB9_KBDOCK_EVENT_GUID		"806BD2A2-177B-481D-BFB5-3BA0BB4A2285"
+#define YB9_KBDOCK_QUERY_GUID		"E7F300FA-21CD-4003-ADAC-2696135982E6"
+#define YB9_KBDOCK_QUERY_INSTANCE	0
+
+#define BKBD_DETACHED		0
+#define BKBD_TOP_HALF		1
+#define BKBD_BOTTOM_HALF	2
+#define BKBD_MASK		GENMASK(1, 0)
+
+/* Distinguish the two GUIDs via the id_table context field. */
+enum yb9_guid_type { YB9_GUID_EVENT, YB9_GUID_QUERY };
+
+/*
+ * Both GUIDs are children of the same ACPI device (WM10).  Store the query
+ * WMI device globally so the event-device probe and notify path can reach it
+ * via wmidev_block_query().  Protected by yb9_query_lock during probe/remove.
+ */
+static struct wmi_device *yb9_query_wdev;
+static DEFINE_MUTEX(yb9_query_lock);
+
+struct yb9_kbdock_priv {
+	struct wmi_device *query_wdev;
+	struct input_dev *input_dev;
+	unsigned int bkbd;
+};
+
+/* Returns 0–2 on success, -errno on error. */
+static int yb9_kbdock_query(struct wmi_device *event_wdev,
+			     struct wmi_device *query_wdev)
+{
+	u32 bkbd;
+
+	union acpi_object *obj __free(kfree) =
+		wmidev_block_query(query_wdev, YB9_KBDOCK_QUERY_INSTANCE);
+	if (!obj) {
+		dev_warn(&event_wdev->dev, "WQAF query returned NULL\n");
+		return -EIO;
+	}
+
+	/*
+	 * WQAF returns an 8-byte buffer: bytes [0..3] = LFID (0x00060000),
+	 * bytes [4..7] = BKBD value.  Guard against short buffers.
+	 */
+	if (obj->type == ACPI_TYPE_BUFFER && obj->buffer.length >= 8)
+		memcpy(&bkbd, obj->buffer.pointer + 4, sizeof(bkbd));
+	else if (obj->type == ACPI_TYPE_INTEGER)
+		bkbd = obj->integer.value;
+	else {
+		dev_warn(&event_wdev->dev,
+			 "WQAF: unexpected result type %d len %u\n",
+			 obj->type, obj->type == ACPI_TYPE_BUFFER ? obj->buffer.length : 0);
+		return -EIO;
+	}
+
+	bkbd = FIELD_GET(BKBD_MASK, bkbd);
+	if (bkbd == 3) {
+		dev_warn(&event_wdev->dev, "BKBD value 3 is reserved\n");
+		return -EINVAL;
+	}
+
+	return bkbd;
+}
+
+static void yb9_kbdock_update(struct wmi_device *wdev)
+{
+	struct yb9_kbdock_priv *priv = dev_get_drvdata(&wdev->dev);
+	int tablet_mode;
+	int bkbd;
+
+	bkbd = yb9_kbdock_query(wdev, priv->query_wdev);
+	if (bkbd < 0)
+		return;
+
+	priv->bkbd = bkbd;
+	tablet_mode = (bkbd == BKBD_DETACHED) ? 1 : 0;
+
+	input_report_switch(priv->input_dev, SW_TABLET_MODE, tablet_mode);
+	input_sync(priv->input_dev);
+
+	dev_dbg(&wdev->dev, "BKBD=%u tablet_mode=%d\n", bkbd, tablet_mode);
+}
+
+static void yb9_kbdock_notify(struct wmi_device *wdev, union acpi_object *data)
+{
+	yb9_kbdock_update(wdev);
+}
+
+static ssize_t keyboard_position_show(struct device *dev,
+				      struct device_attribute *attr, char *buf)
+{
+	static const char * const names[] = {
+		"detached", "top-half", "bottom-half",
+	};
+	struct yb9_kbdock_priv *priv = dev_get_drvdata(dev);
+	unsigned int bkbd = priv->bkbd;
+
+	if (WARN_ON_ONCE(bkbd >= ARRAY_SIZE(names)))
+		return -EINVAL;
+	return sysfs_emit(buf, "%u (%s)\n", bkbd, names[bkbd]);
+}
+static DEVICE_ATTR_RO(keyboard_position);
+
+static struct attribute *yb9_kbdock_attrs[] = {
+	&dev_attr_keyboard_position.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(yb9_kbdock);
+
+static const struct dmi_system_id yb9_kbdock_dmi_table[] = {
+	{
+		/* Lenovo Yoga Book 9 14IAH10 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR,   "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "83KJ"),
+		},
+	},
+	{ }
+};
+
+static int yb9_kbdock_probe(struct wmi_device *wdev, const void *ctx)
+{
+	enum yb9_guid_type type = (enum yb9_guid_type)(uintptr_t)ctx;
+	struct yb9_kbdock_priv *priv;
+	struct input_dev *input_dev;
+	struct wmi_device *qwdev;
+	int err;
+
+	if (type == YB9_GUID_QUERY) {
+		mutex_lock(&yb9_query_lock);
+		yb9_query_wdev = wdev;
+		mutex_unlock(&yb9_query_lock);
+		return 0;
+	}
+
+	if (!dmi_check_system(yb9_kbdock_dmi_table))
+		return -ENODEV;
+
+	mutex_lock(&yb9_query_lock);
+	qwdev = yb9_query_wdev;
+	mutex_unlock(&yb9_query_lock);
+	if (!qwdev)
+		return -EPROBE_DEFER;
+
+	priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	input_dev = devm_input_allocate_device(&wdev->dev);
+	if (!input_dev)
+		return -ENOMEM;
+
+	input_dev->name = "Lenovo Yoga Book 9 keyboard dock switch";
+	input_dev->phys = YB9_KBDOCK_EVENT_GUID "/input0";
+	input_dev->id.bustype = BUS_HOST;
+	input_dev->dev.parent = &wdev->dev;
+	input_set_capability(input_dev, EV_SW, SW_TABLET_MODE);
+
+	err = input_register_device(input_dev);
+	if (err) {
+		dev_err(&wdev->dev, "failed to register input device: %d\n", err);
+		return err;
+	}
+
+	priv->query_wdev = qwdev;
+	priv->input_dev = input_dev;
+	dev_set_drvdata(&wdev->dev, priv);
+
+	yb9_kbdock_update(wdev);
+	return 0;
+}
+
+static void yb9_kbdock_remove(struct wmi_device *wdev)
+{
+	mutex_lock(&yb9_query_lock);
+	if (wdev == yb9_query_wdev)
+		yb9_query_wdev = NULL;
+	mutex_unlock(&yb9_query_lock);
+}
+
+static const struct wmi_device_id yb9_kbdock_wmi_id_table[] = {
+	{ .guid_string = YB9_KBDOCK_EVENT_GUID, .context = (void *)YB9_GUID_EVENT },
+	{ .guid_string = YB9_KBDOCK_QUERY_GUID, .context = (void *)YB9_GUID_QUERY },
+	{ }
+};
+MODULE_DEVICE_TABLE(wmi, yb9_kbdock_wmi_id_table);
+
+static struct wmi_driver yb9_kbdock_driver = {
+	.driver = {
+		.name = "lenovo-yb9-kbdock",
+		.dev_groups = yb9_kbdock_groups,
+	},
+	.id_table = yb9_kbdock_wmi_id_table,
+	.probe    = yb9_kbdock_probe,
+	.remove   = yb9_kbdock_remove,
+	.notify   = yb9_kbdock_notify,
+};
+module_wmi_driver(yb9_kbdock_driver);
+
+MODULE_AUTHOR("Dave Carey <carvsdriver@gmail.com>");
+MODULE_DESCRIPTION("Lenovo Yoga Book 9 keyboard dock detection");
+MODULE_LICENSE("GPL");

2.47.0

^ permalink raw reply

* Re: [PATCH 3/4] HID: wacom: validate report length for DTUS handler
From: sashiko-bot @ 2026-05-17 15:19 UTC (permalink / raw)
  To: Jinmo Yang; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260517135215.2220117-4-jinmo44.yang@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] The global `if (len < 7)` check in `wacom_wac_irq()` for DTUS/DTUSX devices drops valid short reports, breaking the DTUSPAD (pad buttons) functionality.
- [High] Incomplete fix leaving other device types vulnerable to slab-out-of-bounds reads.
- [High] NULL pointer dereference in `wacom_dtus_irq` for DTUSX devices.
--

commit bbe438798c1e7006b14d3fc0a92585f47e3776e2
Author: Jinmo Yang <jinmo44.yang@gmail.com>

HID: wacom: validate report length for DTUS handler

This commit adds a minimum length check in wacom_wac_irq() for DTUS and DTUSX
devices before dispatching to wacom_dtus_irq() to prevent out-of-bounds reads.

> diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
> index 873d58a6d5a3b..269e8318f79af 100644
> --- a/drivers/hid/wacom_wac.c
> +++ b/drivers/hid/wacom_wac.c
> @@ -3479,6 +3479,8 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
>  
>  	case DTUS:
>  	case DTUSX:
> +		if (len < 7)
> +			return;

Does this global length check drop valid short reports for pad buttons?

Looking at wacom_dtus_irq(), it processes two different reports:
WACOM_REPORT_DTUS which accesses up to data[6], and WACOM_REPORT_DTUSPAD
which only accesses data[0] and data[1].

If the pad report is sent as a 2-byte transfer, this check will drop it before
it reaches the handler, breaking the ExpressKeys functionality.

Should the validation first check the report ID (ensuring len >= 1) and then
enforce the minimum length specific to the report type?

Also, while this patch adds a check for DTUS/DTUSX, does it leave other device
types vulnerable to similar out-of-bounds reads?

Other branches in wacom_wac_irq() such as PENPARTNER (which accesses up to
data[6]) and GRAPHIRE (which accesses up to data[7]) do not appear to have
length checks before calling their respective handlers.

Lastly, looking at wacom_dtus_irq(), it handles WACOM_REPORT_DTUSPAD by using
wacom->pad_input:

drivers/hid/wacom_wac.c:wacom_dtus_irq() {
	...
	} else if (data[0] == WACOM_REPORT_DTUSPAD) {
		input = wacom->pad_input;
		input_report_key(input, BTN_0, (data[1] & 0x01));
	...
}

Since DTUSX does not receive the WACOM_DEVICETYPE_PAD capability flag during
initialization, wacom->pad_input remains NULL.

If a spoofed DTUSX device sends a WACOM_REPORT_DTUSPAD report, does this cause
a NULL pointer dereference when calling input_report_key()?

>  		sync = wacom_dtus_irq(wacom_wac);
>  		break;
>

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260517135215.2220117-1-jinmo44.yang@gmail.com?part=3

^ permalink raw reply

* Re: [PATCH v2] platform/x86/lenovo: add Yoga Book 9 keyboard dock driver
From: sashiko-bot @ 2026-05-17 15:25 UTC (permalink / raw)
  To: Dave Carey; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260517150224.50191-1-carvsdriver@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Critical] NULL Pointer Dereference on sysfs read for QUERY device and DMI check bypass
- [High] Use-After-Free due to unreferenced QUERY WMI device pointer
- [Medium] Race condition exposing incorrect initial switch state to userspace
--

commit f26ec3cd843093c54646b94f3331c501f619e886
Author: Dave Carey <carvsdriver@gmail.com>

platform/x86/lenovo: add Yoga Book 9 keyboard dock driver

This commit adds a new driver, lenovo-yb9-kbdock, to support the detachable
keyboard dock on the Lenovo Yoga Book 9 14IAH10. It queries the BKBD state
via WMI to report SW_TABLET_MODE input events and exposes the raw position
to userspace via sysfs.

> diff --git a/drivers/platform/x86/lenovo/yb9-kbdock.c b/drivers/platform/x86/lenovo/yb9-kbdock.c
> new file mode 100644
> index 0000000000000..ba0579f7981a3
> --- /dev/null
> +++ b/drivers/platform/x86/lenovo/yb9-kbdock.c
[ ... ]
> +static int yb9_kbdock_probe(struct wmi_device *wdev, const void *ctx)
> +{
> +	enum yb9_guid_type type = (enum yb9_guid_type)(uintptr_t)ctx;
> +	struct yb9_kbdock_priv *priv;
> +	struct input_dev *input_dev;
> +	struct wmi_device *qwdev;
> +	int err;
> +
> +	if (type == YB9_GUID_QUERY) {
> +		mutex_lock(&yb9_query_lock);
> +		yb9_query_wdev = wdev;
> +		mutex_unlock(&yb9_query_lock);
> +		return 0;
> +	}

The wmi_driver struct sets .dev_groups to yb9_kbdock_groups, which means the
keyboard_position sysfs attribute is created for all devices binding to this
driver, including the query WMI device.

If userspace reads this sysfs attribute on the query device, won't
keyboard_position_show() receive a NULL pointer from dev_get_drvdata()
and dereference it when accessing priv->bkbd?

Also, because this returns before dmi_check_system() is called, does this
allow the driver to bind to the query GUID on unsupported hardware?

> +
> +	if (!dmi_check_system(yb9_kbdock_dmi_table))
> +		return -ENODEV;
[ ... ]
> +	input_set_capability(input_dev, EV_SW, SW_TABLET_MODE);
> +
> +	err = input_register_device(input_dev);
> +	if (err) {
> +		dev_err(&wdev->dev, "failed to register input device: %d\n", err);
> +		return err;
> +	}
> +
> +	priv->query_wdev = qwdev;

Is a device link or reference count via get_device() needed here?

If the query WMI device is unbound or its parent ACPI device is hot-removed,
could priv->query_wdev become a dangling pointer that gets used in
yb9_kbdock_notify() when a WMI event fires?

> +	priv->input_dev = input_dev;
> +	dev_set_drvdata(&wdev->dev, priv);
> +
> +	yb9_kbdock_update(wdev);

Could this expose an incorrect initial switch state to userspace?

Since input_register_device() makes the device visible before
yb9_kbdock_update() queries the hardware state, userspace might
read the default laptop mode (0) even if the keyboard is detached.

Can the initial hardware state be queried and reported before registering
the input device?

> +	return 0;
> +}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260517150224.50191-1-carvsdriver@gmail.com?part=1

^ permalink raw reply

* Re: [PATCH 4/4] HID: wacom: validate report length for 24HDT and 27QHDT handlers
From: sashiko-bot @ 2026-05-17 15:45 UTC (permalink / raw)
  To: Jinmo Yang; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <20260517135215.2220117-5-jinmo44.yang@gmail.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] The patch provides an incomplete fix for out-of-bounds reads caused by short HID reports. It adds length checks for `WACOM_24HDT` and `WACOM_27QHDT`, but misses the exact same vulnerability in numerous other device handlers called by `wacom_wac_irq()`.
--

commit 46cbf4294f0d1877c7d3c2555971c064f005babf
Author: Jinmo Yang <jinmo44.yang@gmail.com>

HID: wacom: validate report length for 24HDT and 27QHDT handlers

This commit adds length checks to wacom_wac_irq to prevent out-of-bounds
reads for WACOM_24HDT and WACOM_27QHDT devices when they receive short HID
reports.

> diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
> index 269e8318f79af..2fd1c4e80a72b 100644
> --- a/drivers/hid/wacom_wac.c
> +++ b/drivers/hid/wacom_wac.c
> @@ -3509,7 +3509,14 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
>  		break;
>  
>  	case WACOM_24HDT:
> +		if (len < 62)
> +			return;
> +		sync = wacom_24hdt_irq(wacom_wac);
> +		break;
> +
>  	case WACOM_27QHDT:
> +		if (len < 64)
> +			return;
>  		sync = wacom_24hdt_irq(wacom_wac);
>  		break;

While this prevents out-of-bounds reads for WACOM_24HDT and WACOM_27QHDT,
are there other device handlers in this switch statement that also need
report length validation?

For example, handlers like INTUOSP2_BT, REMOTE, INTUOS, and PENPARTNER
appear to process reports without validating the buffer length.

Looking at wacom_intuos_pro2_bt_irq(), it receives the length but seems to
unconditionally call wacom_intuos_pro2_bt_pen():

wacom_wac_irq() -> wacom_intuos_pro2_bt_irq() -> wacom_intuos_pro2_bt_pen()

Does this allow wacom_intuos_pro2_bt_pen() to read up to data[107] without
validating the buffer size?

Similarly, does wacom_remote_status_irq() read up to data[30] to populate
remote serial numbers without checking the length?

Could a malicious device sending short reports still trigger regressions
like slab-out-of-bounds reads or information leaks to userspace through
these other handlers?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260517135215.2220117-1-jinmo44.yang@gmail.com?part=4

^ permalink raw reply

* Re: [PATCH v3 0/9] iio: introduce devm_ API for hid sensro setup and cleanup
From: Sanjay Chitroda @ 2026-05-17 20:19 UTC (permalink / raw)
  To: Zhang, Lixu
  Cc: jikos@kernel.org, jic23@kernel.org,
	srinivas.pandruvada@linux.intel.com, Lechner, David,
	nuno.sa@analog.com, andy@kernel.org, sakari.ailus@linux.intel.com,
	linux-input@vger.kernel.org, linux-iio@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <SJ0PR11MB5613D4ECB8081985C3F2D82293072@SJ0PR11MB5613.namprd11.prod.outlook.com>

On Thu, May 14, 2026 at 02:47:52AM +0000, Zhang, Lixu wrote:
> Tested-by: Zhang Lixu <lixu.zhang@intel.com>

Hi Zhang,

Thanks for the testing and validaiton.
I hope you validated the complete series, including the unbind flow for the
drivers using devm API.

Hi Jonathan,

How should we take this series forward? should I extend the series to
cover remaining HID IIO drivers for this devm API, or this series can
applied to IIO tree first and sent followup patches on top of that?

Thanks, Sanjay

> 
> >-----Original Message-----
> >From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
> >Sent: Saturday, May 9, 2026 6:11 PM
> >To: jikos@kernel.org; jic23@kernel.org; srinivas.pandruvada@linux.intel.com
> >Cc: Lechner, David <dlechner@baylibre.com>; nuno.sa@analog.com;
> >andy@kernel.org; sanjayembeddedse@gmail.com;
> >sakari.ailus@linux.intel.com; linux-input@vger.kernel.org; linux-
> >iio@vger.kernel.org; linux-kernel@vger.kernel.org
> >Subject: [PATCH v3 0/9] iio: introduce devm_ API for hid sensro setup and
> >cleanup
> >
> >From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
> >
> >Key highlights:
> >- Prepare change as pre-requisite for devm conversion for HID IIO
> >  drivers by removing redundant argument
> >- Add devm API to setup trigger and clenaup resource using
> >  devm_add_action_or_reset()
> >- few cleanup and prepratory changes before updating driver for devm_
> >- few sample driver update using devm conversion to auto release resource
> >
> >changes in v3:
> >- Added cleanup and prepratory changes before adding devm_ API
> >  conversion based on self review: 0002, 0004, 0006, 0007 and 0008
> >- Address andy's review comment on commit message and coding style
> >- v2 series -> https://lore.kernel.org/all/20260429175918.2541914-1-
> >sanjayembedded@gmail.com/
> >changes in v2:
> >- Following input from Jonathan and Andy, squash initial patch v1
> >  series in single change as individual change should not break anything
> >- Add devm API support and two driver using the same
> >- v1 series -> https://lore.kernel.org/all/20260428071613.1134053-1-
> >sanjayembedded@gmail.com/
> >
> >Testing:
> >  - Compiled with W=1
> >  - Build-tested on QEMU x86_64
> >
> >Based on further feedback and reviews, I would extend this series to convert all
> >HID IIO driver to use devm_* API.
> >
> >Thanks,
> >Sanjay Chitroda
> >
> >
> >Sanjay Chitroda (9):
> >  iio: hid-sensors: drop redundant iio_dev argument
> >  iio: hid-sensors: cleanup codestyle warning
> >  iio: hid-sensors: introduce device managed API
> >  iio: gyro: hid-sensor-gyro-3d: cleanup codestyle warning
> >  iio: gyro: hid-sensor-gyro-3d: drop hid_sensor_remove_trigger() using
> >    devm API
> >  iio: humidity: hid-sensor-humidity: cleanup codestyle check
> >  iio: humidity: hid-sensor-humidity: use common device for devres
> >  iio: humidity: hid-sensor-humidity: use local struct device
> >  iio: humidity: hid-sensor-humidity: drop hid_sensor_remove_trigger()
> >    using devm API
> >
> > drivers/iio/accel/hid-sensor-accel-3d.c       |  4 +-
> > .../common/hid-sensors/hid-sensor-trigger.c   | 24 +++++++-
> > .../common/hid-sensors/hid-sensor-trigger.h   |  5 +-
> > drivers/iio/gyro/hid-sensor-gyro-3d.c         | 16 ++---
> > drivers/iio/humidity/hid-sensor-humidity.c    | 61 +++++++++----------
> > drivers/iio/light/hid-sensor-als.c            |  4 +-
> > drivers/iio/light/hid-sensor-prox.c           |  4 +-
> > drivers/iio/magnetometer/hid-sensor-magn-3d.c |  4 +-
> >drivers/iio/orientation/hid-sensor-incl-3d.c  |  4 +-  drivers/iio/orientation/hid-
> >sensor-rotation.c |  4 +-  .../position/hid-sensor-custom-intel-hinge.c  |  4 +-
> > drivers/iio/pressure/hid-sensor-press.c       |  4 +-
> > .../iio/temperature/hid-sensor-temperature.c  |  4 +-
> > 13 files changed, 78 insertions(+), 64 deletions(-)
> >
> >
> >base-commit: 39b80c5c9830d12d2d6531059001301c4265322a
> >--
> >2.34.1
> >
> 

^ permalink raw reply

* Re:i2c_hid_acpi: ELAN2514 touchscreen causes IRQ flood on HP Omnibook X 14 (Lunar Lake)
From: Dennis Foster @ 2026-05-17 23:49 UTC (permalink / raw)
  To: linux-input; +Cc: linux-i2c, benjamintissoires, jikos
In-Reply-To: <19e3435bff9.5159b6ff3377555.4429246136901518864@dennisfoster.us>

Couple of corrections.

The machine is actually an HP OmniBook X Flip 16, not the
"Omnibook X 14" I wrote in the original - my mistake. Also bumped to
kernel 7.0.9 today; same behavior. BIOS is HP F.11
(03/04/2026), board 8DA1.

I disabled the udev workaround briefly to get an actual rate. With the
driver bound for ~40 seconds, /proc/interrupts went from 18,811 to
1,778,374 on IRQ 20, i.e. roughly 42,900/s pinned on CPU5. Kernel
never marks the line bad - no "nobody cared", no "disabling IRQ", it
just keeps fasteoi'ing.

One thing I missed in the DSDT that might be relevant: TPL1's
interrupt isn't a GpioInt() resource, it's a regular Interrupt()
template with the vector patched in at _INI:

    Name (SBFI, ResourceTemplate ()
    {
        Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, ,, _Y4F)
        { 0x00000000, }
    })

    Method (_INI, ...)
    {
        ...
        INT2 = INUM (GPLI)
        ...
    }

That's why it surfaces as IR-IO-APIC 20-fasteoi rather than something
gpiolib-backed. _CRS picks between this template and a G_IN()/GpioInt
template based on the BIOS variable TPLM, and this firmware ships
with TPLM != 0 so we end up on the APIC path. I don't see a setup
option to flip it.

Probably unrelated but in the same area of the DSDT - this prints
once at boot:

    ACPI BIOS Error (bug): Could not resolve symbol
        [\_SB.PC00.I2C5.TPL1], AE_NOT_FOUND

I2C5 has no TPL1 in this firmware (the touchscreen is on I2C4).

Happy to send the full decompiled DSDT/SSDTs, a fuller dmesg with
i2c_hid dyndbg enabled, or test patches.

--
Dennis


^ permalink raw reply

* [PATCH] Input: mtk-pmic-keys - use of_device_get_match_data()
From: Rosen Penev @ 2026-05-18  4:20 UTC (permalink / raw)
  To: linux-input
  Cc: Dmitry Torokhov, Matthias Brugger, AngeloGioacchino Del Regno,
	open list:ARM/Mediatek SoC support,
	moderated list:ARM/Mediatek SoC support,
	moderated list:ARM/Mediatek SoC support

Use of_device_get_match_data() to fetch the PMIC key register data directly instead of open-coding an of_match_device() lookup.

This also lets the driver drop the of_device.h include.

Assisted-by: Codex:GPT-5.5
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
 drivers/input/keyboard/mtk-pmic-keys.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/input/keyboard/mtk-pmic-keys.c b/drivers/input/keyboard/mtk-pmic-keys.c
index c78d9f6d97c4..fd684ac16938 100644
--- a/drivers/input/keyboard/mtk-pmic-keys.c
+++ b/drivers/input/keyboard/mtk-pmic-keys.c
@@ -16,7 +16,6 @@
 #include <linux/mfd/mt6397/core.h>
 #include <linux/mfd/mt6397/registers.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
@@ -333,8 +332,6 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
 	struct mtk_pmic_keys *keys;
 	const struct mtk_pmic_regs *mtk_pmic_regs;
 	struct input_dev *input_dev;
-	const struct of_device_id *of_id =
-		of_match_device(of_mtk_pmic_keys_match_tbl, &pdev->dev);
 
 	keys = devm_kzalloc(&pdev->dev, sizeof(*keys), GFP_KERNEL);
 	if (!keys)
@@ -342,7 +339,7 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
 
 	keys->dev = &pdev->dev;
 	keys->regmap = pmic_chip->regmap;
-	mtk_pmic_regs = of_id->data;
+	mtk_pmic_regs = of_device_get_match_data(&pdev->dev);
 
 	keys->input_dev = input_dev = devm_input_allocate_device(keys->dev);
 	if (!input_dev) {
-- 
2.54.0


^ permalink raw reply related

* Re: [PATCH] Input: mtk-pmic-keys - use of_device_get_match_data()
From: sashiko-bot @ 2026-05-18  4:34 UTC (permalink / raw)
  To: Rosen Penev; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260518042046.981861-1-rosenp@gmail.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Missing NULL check for of_device_get_match_data() result leads to NULL pointer dereference.
- [High] Mismatch between child counting and iteration logic can cause out-of-bounds array accesses.
--

commit 0ee3fee49ccf02b7e629f90533e67fc9b40d2b9e
Author: Rosen Penev <rosenp@gmail.com>

Input: mtk-pmic-keys - use of_device_get_match_data()

This commit simplifies the driver to fetch PMIC key register data directly
using of_device_get_match_data(). It also removes the unneeded of_device.h
include.

> diff --git a/drivers/input/keyboard/mtk-pmic-keys.c b/drivers/input/keyboard/mtk-pmic-keys.c
> index c78d9f6d97c4f..fd684ac169386 100644
> --- a/drivers/input/keyboard/mtk-pmic-keys.c
> +++ b/drivers/input/keyboard/mtk-pmic-keys.c
[ ... ]
> @@ -342,7 +339,7 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
>  
>  	keys->dev = &pdev->dev;
>  	keys->regmap = pmic_chip->regmap;
> -	mtk_pmic_regs = of_id->data;
> +	mtk_pmic_regs = of_device_get_match_data(&pdev->dev);

While this isn't a new issue introduced by this patch, can mtk_pmic_regs be
NULL here if the device is bound manually via sysfs without a matching
device tree node?

If mtk_pmic_regs is NULL, it appears it is unconditionally dereferenced
later when calling mtk_pmic_keys_lp_reset_setup().

Would it make sense to add a check for !mtk_pmic_regs right after fetching
the match data?


Also, while reviewing this probe function, I noticed another pre-existing
issue further down:

	keycount = of_get_available_child_count(node);
	if (keycount > MTK_PMIC_MAX_KEY_COUNT ||
	    keycount > ARRAY_SIZE(irqnames)) {
		dev_err(keys->dev, "too many keys defined (%d)\n", keycount);
		return -EINVAL;
	}

	for_each_child_of_node_scoped(node, child) {
		keys->keys[index].regs = &mtk_pmic_regs->keys_regs[index];

Is there a mismatch between the child counting and iteration logic?

The validation check uses of_get_available_child_count(), which ignores
disabled nodes. But the loop uses for_each_child_of_node_scoped(), which
iterates over all children, including disabled ones.

If a disabled child node exists in the device tree alongside available ones,
could the loop execute more times than the initial validation accounted for?
This might increment the index variable past the allocated array bounds,
leading to out-of-bounds accesses on irqnames[] and keys->keys[].

Would updating the loop to use for_each_available_child_of_node_scoped()
prevent this?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260518042046.981861-1-rosenp@gmail.com?part=1

^ permalink raw reply

* [PATCH v3] Input: elan_i2c - prevent division by zero on invalid device parameters
From: Ranjan Kumar @ 2026-05-18  6:26 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: bleung, bentiss, linux-input, linux-kernel, Ranjan Kumar
In-Reply-To: <20260515071052.7DDA0C2BCB0@smtp.kernel.org>

The Elan I2C touchpad driver queries the device for its physical
dimensions and trace counts to calculate the device resolution and width.
However, if the device firmware or device tree provides invalid zero
values for x_traces, y_traces, x_mm, or y_mm, it results in a fatal
division-by-zero exception leading to a kernel panic during device probe.

Add sanity checks to ensure these physical parameters are non-zero
before performing the division. If invalid trace values are detected,
log a warning and fall back to ETP_FWIDTH_REDUCE to prevent arithmetic
underflow during touch reporting. For invalid physical dimensions, fall
back to a safe default of 1.

This prevents the kernel panic while allowing the probe to complete
successfully. Completing the probe ensures the sysfs nodes are created,
keeping the firmware update path intact so a recovery firmware can be
flashed to the device.

Fixes: 6696777c6506 ("Input: add driver for Elan I2C/SMbus touchpad")
Fixes: e3a9a1290688 ("Input: elan_i2c - do not query the info if they are provided")
Signed-off-by: Ranjan Kumar <kumarranja@chromium.org>
---
Changes in v3:
 - Changed trace fallback values from 1 to ETP_FWIDTH_REDUCE to prevent 
   an unsigned integer underflow in elan_report_absolute(). 
 Changes in v2:
 - Changed error handling from aborting probe with -EINVAL to logging a
   warning and falling back to default values.

 drivers/input/mouse/elan_i2c_core.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
index fee1796da3d0..c64e1dd1e60b 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -425,8 +425,17 @@ static int elan_query_device_parameters(struct elan_tp_data *data)
 		if (error)
 			return error;
 	}
-	data->width_x = data->max_x / x_traces;
-	data->width_y = data->max_y / y_traces;
+
+	if (unlikely(x_traces == 0 || y_traces == 0)) {
+		dev_warn(&client->dev,
+			 "invalid trace numbers: x=%u, y=%u\n",
+			 x_traces, y_traces);
+		data->width_x = ETP_FWIDTH_REDUCE;
+		data->width_y = ETP_FWIDTH_REDUCE;
+	} else {
+		data->width_x = data->max_x / x_traces;
+		data->width_y = data->max_y / y_traces;
+	}
 
 	if (device_property_read_u32(&client->dev,
 				     "touchscreen-x-mm", &x_mm) ||
@@ -440,8 +449,16 @@ static int elan_query_device_parameters(struct elan_tp_data *data)
 		data->x_res = elan_convert_resolution(hw_x_res, data->pattern);
 		data->y_res = elan_convert_resolution(hw_y_res, data->pattern);
 	} else {
-		data->x_res = (data->max_x + 1) / x_mm;
-		data->y_res = (data->max_y + 1) / y_mm;
+		if (unlikely(x_mm == 0 || y_mm == 0)) {
+			dev_warn(&client->dev,
+				 "invalid physical dimensions: x_mm=%u, y_mm=%u\n",
+				 x_mm, y_mm);
+			data->x_res = 1;
+			data->y_res = 1;
+		} else {
+			data->x_res = (data->max_x + 1) / x_mm;
+			data->y_res = (data->max_y + 1) / y_mm;
+		}
 	}
 
 	if (device_property_read_bool(&client->dev, "elan,clickpad"))
-- 
2.54.0.563.g4f69b47b94-goog


^ permalink raw reply related

* Re: [PATCH] Input: mtk-pmic-keys - use of_device_get_match_data()
From: Rosen Penev @ 2026-05-18  6:37 UTC (permalink / raw)
  To: sashiko-reviews, Rosen Penev; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260518043409.EC97EC2BCB7@smtp.kernel.org>

On Sun May 17, 2026 at 9:34 PM PDT, sashiko-bot wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> - [High] Missing NULL check for of_device_get_match_data() result leads to NULL pointer dereference.
> - [High] Mismatch between child counting and iteration logic can cause out-of-bounds array accesses.
> --
>
> commit 0ee3fee49ccf02b7e629f90533e67fc9b40d2b9e
> Author: Rosen Penev <rosenp@gmail.com>
>
> Input: mtk-pmic-keys - use of_device_get_match_data()
>
> This commit simplifies the driver to fetch PMIC key register data directly
> using of_device_get_match_data(). It also removes the unneeded of_device.h
> include.
>
>> diff --git a/drivers/input/keyboard/mtk-pmic-keys.c b/drivers/input/keyboard/mtk-pmic-keys.c
>> index c78d9f6d97c4f..fd684ac169386 100644
>> --- a/drivers/input/keyboard/mtk-pmic-keys.c
>> +++ b/drivers/input/keyboard/mtk-pmic-keys.c
> [ ... ]
>> @@ -342,7 +339,7 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
>>
>>  	keys->dev = &pdev->dev;
>>  	keys->regmap = pmic_chip->regmap;
>> -	mtk_pmic_regs = of_id->data;
>> +	mtk_pmic_regs = of_device_get_match_data(&pdev->dev);
>
> While this isn't a new issue introduced by this patch, can mtk_pmic_regs be
> NULL here if the device is bound manually via sysfs without a matching
> device tree node?
>
> If mtk_pmic_regs is NULL, it appears it is unconditionally dereferenced
> later when calling mtk_pmic_keys_lp_reset_setup().
>
> Would it make sense to add a check for !mtk_pmic_regs right after fetching
> the match data?
No because every compatible has a non NULL data component.
>
>
> Also, while reviewing this probe function, I noticed another pre-existing
> issue further down:
>
> 	keycount = of_get_available_child_count(node);
> 	if (keycount > MTK_PMIC_MAX_KEY_COUNT ||
> 	    keycount > ARRAY_SIZE(irqnames)) {
> 		dev_err(keys->dev, "too many keys defined (%d)\n", keycount);
> 		return -EINVAL;
> 	}
>
> 	for_each_child_of_node_scoped(node, child) {
> 		keys->keys[index].regs = &mtk_pmic_regs->keys_regs[index];
>
> Is there a mismatch between the child counting and iteration logic?
>
> The validation check uses of_get_available_child_count(), which ignores
> disabled nodes. But the loop uses for_each_child_of_node_scoped(), which
> iterates over all children, including disabled ones.
>
> If a disabled child node exists in the device tree alongside available ones,
> could the loop execute more times than the initial validation accounted for?
> This might increment the index variable past the allocated array bounds,
> leading to out-of-bounds accesses on irqnames[] and keys->keys[].
>
> Would updating the loop to use for_each_available_child_of_node_scoped()
> prevent this?
Yes. Interesting that pre-existing issues are flagged...


^ permalink raw reply

* Re: [PATCH v1] Input: Use named initializers for arrays of i2c_device_data
From: Andy Shevchenko @ 2026-05-18  7:30 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Uwe Kleine-König (The Capable Hub), Dmitry Torokhov,
	Anshul Dalal, Michael Hennerich, Yassine Oudjana, Linus Walleij,
	Nicolas Ferre, Alexandre Belloni, Claudiu Beznea,
	Support Opensource, Nick Dyer, Hans de Goede, Job Noorman,
	Mika Penttilä, Maxime Coquelin, Alexandre Torgue, Kees Cook,
	bui duc phuc, Thorsten Blum, Yauhen Kharuzhy, Sakari Ailus,
	Marco Crivellari, Minseong Kim, Ingo Molnar, Thomas Gleixner,
	Oleh Kuzhylnyi, Marek Vasut, Krzysztof Kozlowski,
	Geert Uytterhoeven, Josua Mayer, Michael Tretter, Jeff LaBundy,
	Javier Carrasco, David Heidelberg, Petr Hodina, Svyatoslav Ryhel,
	Johannes Kirchmair, Xichao Zhao, linux-input, linux-kernel,
	linux-arm-kernel, platform-driver-x86, linux-stm32
In-Reply-To: <CAMuHMdWGSBbQtKaoFej1Qm-SUgDenLMDF0psD9o07wyHKu8A+w@mail.gmail.com>

On Mon, May 18, 2026 at 09:24:35AM +0200, Geert Uytterhoeven wrote:
> Hi Uwe,
> 
> On Fri, 15 May 2026 at 18:48, Uwe Kleine-König (The Capable Hub)
> <u.kleine-koenig@baylibre.com> wrote:
> > My additional motivation for this effort is CHERI[1]. This is a hardware
> 
> Nice!
> 
> > extension that uses 128 bit pointers but unsigned long is still 64 bit.
> > So with CHERI you cannot store pointers in unsigned long variables.
> 
> Good luck fixing all implicit assumptions about this in the kernel!
> Also, good luck convincing people to use uintptr_t instead ;-)
> 
> https://lore.kernel.org/all/CAHk-=wj2OHy-5e+srG1fy+ZU00TmZ1NFp6kFLbVLMXHe7A1d-g@mail.gmail.com

Yeah, I believe Linus will have a strong opinion about all this CHERI stuff :-)
But let see, it might be surprising turn around.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply

* Re: [PATCH v1] Input: Use named initializers for arrays of i2c_device_data
From: Geert Uytterhoeven @ 2026-05-18  7:24 UTC (permalink / raw)
  To: Uwe Kleine-König (The Capable Hub)
  Cc: Dmitry Torokhov, Anshul Dalal, Michael Hennerich, Yassine Oudjana,
	Linus Walleij, Nicolas Ferre, Alexandre Belloni, Claudiu Beznea,
	Support Opensource, Nick Dyer, Hans de Goede, Job Noorman,
	Mika Penttilä, Maxime Coquelin, Alexandre Torgue, Kees Cook,
	bui duc phuc, Thorsten Blum, Yauhen Kharuzhy, Sakari Ailus,
	Marco Crivellari, Minseong Kim, Ingo Molnar, Thomas Gleixner,
	Oleh Kuzhylnyi, Marek Vasut, Krzysztof Kozlowski,
	Geert Uytterhoeven, Josua Mayer, Michael Tretter, Jeff LaBundy,
	Javier Carrasco, David Heidelberg, Petr Hodina, Svyatoslav Ryhel,
	Johannes Kirchmair, Andy Shevchenko, Xichao Zhao, linux-input,
	linux-kernel, linux-arm-kernel, platform-driver-x86, linux-stm32
In-Reply-To: <20260515164848.497608-2-u.kleine-koenig@baylibre.com>

Hi Uwe,

On Fri, 15 May 2026 at 18:48, Uwe Kleine-König (The Capable Hub)
<u.kleine-koenig@baylibre.com> wrote:
> My additional motivation for this effort is CHERI[1]. This is a hardware

Nice!

> extension that uses 128 bit pointers but unsigned long is still 64 bit.
> So with CHERI you cannot store pointers in unsigned long variables.

Good luck fixing all implicit assumptions about this in the kernel!
Also, good luck convincing people to use uintptr_t instead ;-)

https://lore.kernel.org/all/CAHk-=wj2OHy-5e+srG1fy+ZU00TmZ1NFp6kFLbVLMXHe7A1d-g@mail.gmail.com

Gr{oetje,eeting}s,

                        Geert


--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH v1] Input: Use named initializers for arrays of i2c_device_data
From: Uwe Kleine-König (The Capable Hub) @ 2026-05-18  7:56 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Geert Uytterhoeven, Dmitry Torokhov, Anshul Dalal,
	Michael Hennerich, Yassine Oudjana, Linus Walleij, Nicolas Ferre,
	Alexandre Belloni, Claudiu Beznea, Support Opensource, Nick Dyer,
	Hans de Goede, Job Noorman, Mika Penttilä, Maxime Coquelin,
	Alexandre Torgue, Kees Cook, bui duc phuc, Thorsten Blum,
	Yauhen Kharuzhy, Sakari Ailus, Marco Crivellari, Minseong Kim,
	Ingo Molnar, Thomas Gleixner, Oleh Kuzhylnyi, Marek Vasut,
	Krzysztof Kozlowski, Geert Uytterhoeven, Josua Mayer,
	Michael Tretter, Jeff LaBundy, Javier Carrasco, David Heidelberg,
	Petr Hodina, Svyatoslav Ryhel, Johannes Kirchmair, Xichao Zhao,
	linux-input, linux-kernel, linux-arm-kernel, platform-driver-x86,
	linux-stm32
In-Reply-To: <agrAG3cLjEAPV90B@ashevche-desk.local>

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

On Mon, May 18, 2026 at 10:30:35AM +0300, Andy Shevchenko wrote:
> On Mon, May 18, 2026 at 09:24:35AM +0200, Geert Uytterhoeven wrote:
> > Hi Uwe,
> > 
> > On Fri, 15 May 2026 at 18:48, Uwe Kleine-König (The Capable Hub)
> > <u.kleine-koenig@baylibre.com> wrote:
> > > My additional motivation for this effort is CHERI[1]. This is a hardware
> > 
> > Nice!
> > 
> > > extension that uses 128 bit pointers but unsigned long is still 64 bit.
> > > So with CHERI you cannot store pointers in unsigned long variables.
> > 
> > Good luck fixing all implicit assumptions about this in the kernel!
> > Also, good luck convincing people to use uintptr_t instead ;-)
> > 
> > https://lore.kernel.org/all/CAHk-=wj2OHy-5e+srG1fy+ZU00TmZ1NFp6kFLbVLMXHe7A1d-g@mail.gmail.com
> 
> Yeah, I believe Linus will have a strong opinion about all this CHERI stuff :-)
> But let see, it might be surprising turn around.

Yeah, it's not yet the time to start that discussion, I want to have the
patch stack in a better state before that.

I think the strongest argument will be that

	"unsigned long" [...] is an integer type large enough to hold a
	pointer.

just isn't true for CHERI.

Best regards
Uwe

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

^ permalink raw reply

* [PATCH v2 0/6] tools/build: Allow versioning of all LLVM tools
From: James Clark @ 2026-05-18  9:03 UTC (permalink / raw)
  To: Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	Jiri Kosina, Benjamin Tissoires, Shuah Khan, Peter Zijlstra,
	Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	Andrii Nakryiko, Eduard Zingerman, Alexei Starovoitov,
	Daniel Borkmann, Martin KaFai Lau, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, ihor.solodrai
  Cc: linux-kernel, llvm, linux-input, linux-kselftest, bpf,
	linux-perf-users, James Clark

I ran into the build issue mentioned in the first commit, because using
an option like LLVM=-15 is a documented way to build [1], but only
some of the LLVM tools defined in tools/ support this.

After fixing that, a lot of other tidyups fell out. I didn't go too far,
for example some selftests include tools/testing/selftests/lib.mk which
reimplements some of the LLVM_SUFFIX stuff, but other selftests include
tools/scripts/Makefile.include and I stopped before touching the former.
Some other non build scripts hard code toolchains and I didn't touch
those either, this change is only focused on things that already
include Makefile.include.

[1]: Documentation/kbuild/llvm.rst

Signed-off-by: James Clark <james.clark@linaro.org>
---
Changes in v2:
- Fix selftests/bpf build. LLD needs to take the full path to be used
  with -fuse-ld=
- Link to v1: https://lore.kernel.org/r/20260514-james-perf-llvm-version-v1-0-6cac1a9a4c8d@linaro.org

---
James Clark (6):
      tools/build: Allow versioning of all LLVM tools defined in Makefile.include
      tools/build: Indent if else blocks
      selftests: Remove unused LLD variable
      tools/build: Allow versioning LLVM readelf
      tools/build: selftests: Allow versioning LLVM lld
      tools/build: selftests: Remove some duplicate toolchain definitions

 tools/bpf/resolve_btfids/Makefile    |  3 --
 tools/lib/api/Makefile               |  4 --
 tools/lib/bpf/Makefile               |  8 ++--
 tools/lib/subcmd/Makefile            |  4 --
 tools/lib/symbol/Makefile            |  4 --
 tools/perf/Makefile.perf             |  7 ----
 tools/scripts/Makefile.include       | 77 ++++++++++++++++++++----------------
 tools/testing/selftests/bpf/Makefile |  9 ++---
 tools/testing/selftests/hid/Makefile |  7 ----
 9 files changed, 50 insertions(+), 73 deletions(-)
---
base-commit: 09d355618f7ccc27ffc7fc668b2e232872962079
change-id: 20260511-james-perf-llvm-version-43ab1cb5bc7d

Best regards,
-- 
James Clark <james.clark@linaro.org>


^ permalink raw reply

* [PATCH v2 1/6] tools/build: Allow versioning of all LLVM tools defined in Makefile.include
From: James Clark @ 2026-05-18  9:03 UTC (permalink / raw)
  To: Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	Jiri Kosina, Benjamin Tissoires, Shuah Khan, Peter Zijlstra,
	Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	Andrii Nakryiko, Eduard Zingerman, Alexei Starovoitov,
	Daniel Borkmann, Martin KaFai Lau, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, ihor.solodrai
  Cc: linux-kernel, llvm, linux-input, linux-kselftest, bpf,
	linux-perf-users, James Clark
In-Reply-To: <20260518-james-perf-llvm-version-v2-0-f12cc4f031d8@linaro.org>

The version of LLVM tools can be given on the build command with
LLVM=-15, but this isn't applied to all tools. For example $(CC) gets
versioned, but $(CLANG) doesn't. This causes a Perf build with LTO=1 to
fail with an error about mixed clang versions:

 ld.lld: error: libperf/core.o: Unknown attribute kind (86)
   (Producer: 'LLVM18.1.8' Reader: 'LLVM 15.0.7')

This file has two "ifneq ($(LLVM),)" blocks adjacent to each other, so
merge these blocks making it obvious that all tools should be versioned
consistently and there is nothing special about each block.

This also reveals that ?= and "allow-override" are used inconsistently
between the blocks. "allow-override" is technically only required for
builtin variables, but isn't only used on them, and doesn't do any harm
if used on a non-builtin. Make them all "allow-override" for
consistency. The only functional difference this will cause is if there
is a file level definition of one of the variables followed by an
"#include of Makefile.include" which will now overwrite. But this isn't
done and in a later commit some of the duplicate definitions will be
removed for good measure.

There are also some other LLVM tools that are not defined here and will
be moved in a later commit.

Signed-off-by: James Clark <james.clark@linaro.org>
---
 tools/scripts/Makefile.include | 37 ++++++++++++++++++++-----------------
 1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include
index 41971a68972d..7022e78208a2 100644
--- a/tools/scripts/Makefile.include
+++ b/tools/scripts/Makefile.include
@@ -61,10 +61,18 @@ $(error Invalid value for LLVM, see Documentation/kbuild/llvm.rst)
 endif
 
 $(call allow-override,CC,$(LLVM_PREFIX)clang$(LLVM_SUFFIX))
+$(call allow-override,CLANG,$(LLVM_PREFIX)clang$(LLVM_SUFFIX))
+$(call allow-override,HOSTCC,$(LLVM_PREFIX)clang$(LLVM_SUFFIX))
 $(call allow-override,AR,$(LLVM_PREFIX)llvm-ar$(LLVM_SUFFIX))
+$(call allow-override,HOSTAR,$(LLVM_PREFIX)llvm-ar$(LLVM_SUFFIX))
 $(call allow-override,LD,$(LLVM_PREFIX)ld.lld$(LLVM_SUFFIX))
+$(call allow-override,HOSTLD,$(LLVM_PREFIX)ld.lld$(LLVM_SUFFIX))
 $(call allow-override,CXX,$(LLVM_PREFIX)clang++$(LLVM_SUFFIX))
 $(call allow-override,STRIP,$(LLVM_PREFIX)llvm-strip$(LLVM_SUFFIX))
+$(call allow-override,LLVM_STRIP,$(LLVM_PREFIX)llvm-strip$(LLVM_SUFFIX))
+$(call allow-override,LLC,$(LLVM_PREFIX)llc$(LLVM_SUFFIX))
+$(call allow-override,LLVM_CONFIG,$(LLVM_PREFIX)llvm-config$(LLVM_SUFFIX))
+$(call allow-override,LLVM_OBJCOPY,$(LLVM_PREFIX)llvm-objcopy$(LLVM_SUFFIX))
 else
 # Allow setting various cross-compile vars or setting CROSS_COMPILE as a prefix.
 $(call allow-override,CC,$(CROSS_COMPILE)gcc)
@@ -72,26 +80,21 @@ $(call allow-override,AR,$(CROSS_COMPILE)ar)
 $(call allow-override,LD,$(CROSS_COMPILE)ld)
 $(call allow-override,CXX,$(CROSS_COMPILE)g++)
 $(call allow-override,STRIP,$(CROSS_COMPILE)strip)
-endif
-
-CC_NO_CLANG := $(shell $(CC) -dM -E -x c /dev/null | grep -Fq "__clang__"; echo $$?)
 
-ifneq ($(LLVM),)
-HOSTAR  ?= $(LLVM_PREFIX)llvm-ar$(LLVM_SUFFIX)
-HOSTCC  ?= $(LLVM_PREFIX)clang$(LLVM_SUFFIX)
-HOSTLD  ?= $(LLVM_PREFIX)ld.lld$(LLVM_SUFFIX)
-else
-HOSTAR  ?= ar
-HOSTCC  ?= gcc
-HOSTLD  ?= ld
+# Host versions aren't prefixed
+$(call allow-override,HOSTAR,ar)
+$(call allow-override,HOSTCC,gcc)
+$(call allow-override,HOSTLD,ld)
+
+# Some tools still require Clang, LLC and/or LLVM utils
+$(call allow-override,CLANG,clang)
+$(call allow-override,LLC,llc)
+$(call allow-override,LLVM_CONFIG,llvm-config)
+$(call allow-override,LLVM_OBJCOPY,llvm-objcopy)
+$(call allow-override,LLVM_STRIP,llvm-strip)
 endif
 
-# Some tools require Clang, LLC and/or LLVM utils
-CLANG		?= clang
-LLC		?= llc
-LLVM_CONFIG	?= llvm-config
-LLVM_OBJCOPY	?= llvm-objcopy
-LLVM_STRIP	?= llvm-strip
+CC_NO_CLANG := $(shell $(CC) -dM -E -x c /dev/null | grep -Fq "__clang__"; echo $$?)
 
 # Some tools require bpftool
 SYSTEM_BPFTOOL	?= bpftool

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 2/6] tools/build: Indent if else blocks
From: James Clark @ 2026-05-18  9:03 UTC (permalink / raw)
  To: Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	Jiri Kosina, Benjamin Tissoires, Shuah Khan, Peter Zijlstra,
	Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	Andrii Nakryiko, Eduard Zingerman, Alexei Starovoitov,
	Daniel Borkmann, Martin KaFai Lau, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, ihor.solodrai
  Cc: linux-kernel, llvm, linux-input, linux-kselftest, bpf,
	linux-perf-users, James Clark
In-Reply-To: <20260518-james-perf-llvm-version-v2-0-f12cc4f031d8@linaro.org>

These blocks are quite big and unreadable without indentation. Indent
them.

No functional changes intended.

Signed-off-by: James Clark <james.clark@linaro.org>
---
 tools/scripts/Makefile.include | 76 +++++++++++++++++++++---------------------
 1 file changed, 38 insertions(+), 38 deletions(-)

diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include
index 7022e78208a2..e81e5b479c56 100644
--- a/tools/scripts/Makefile.include
+++ b/tools/scripts/Makefile.include
@@ -52,46 +52,46 @@ define allow-override
 endef
 
 ifneq ($(LLVM),)
-ifneq ($(filter %/,$(LLVM)),)
-LLVM_PREFIX := $(LLVM)
-else ifneq ($(filter -%,$(LLVM)),)
-LLVM_SUFFIX := $(LLVM)
-else ifneq ($(LLVM),1)
-$(error Invalid value for LLVM, see Documentation/kbuild/llvm.rst)
-endif
+  ifneq ($(filter %/,$(LLVM)),)
+    LLVM_PREFIX := $(LLVM)
+  else ifneq ($(filter -%,$(LLVM)),)
+    LLVM_SUFFIX := $(LLVM)
+  else ifneq ($(LLVM),1)
+    $(error Invalid value for LLVM, see Documentation/kbuild/llvm.rst)
+  endif
 
-$(call allow-override,CC,$(LLVM_PREFIX)clang$(LLVM_SUFFIX))
-$(call allow-override,CLANG,$(LLVM_PREFIX)clang$(LLVM_SUFFIX))
-$(call allow-override,HOSTCC,$(LLVM_PREFIX)clang$(LLVM_SUFFIX))
-$(call allow-override,AR,$(LLVM_PREFIX)llvm-ar$(LLVM_SUFFIX))
-$(call allow-override,HOSTAR,$(LLVM_PREFIX)llvm-ar$(LLVM_SUFFIX))
-$(call allow-override,LD,$(LLVM_PREFIX)ld.lld$(LLVM_SUFFIX))
-$(call allow-override,HOSTLD,$(LLVM_PREFIX)ld.lld$(LLVM_SUFFIX))
-$(call allow-override,CXX,$(LLVM_PREFIX)clang++$(LLVM_SUFFIX))
-$(call allow-override,STRIP,$(LLVM_PREFIX)llvm-strip$(LLVM_SUFFIX))
-$(call allow-override,LLVM_STRIP,$(LLVM_PREFIX)llvm-strip$(LLVM_SUFFIX))
-$(call allow-override,LLC,$(LLVM_PREFIX)llc$(LLVM_SUFFIX))
-$(call allow-override,LLVM_CONFIG,$(LLVM_PREFIX)llvm-config$(LLVM_SUFFIX))
-$(call allow-override,LLVM_OBJCOPY,$(LLVM_PREFIX)llvm-objcopy$(LLVM_SUFFIX))
+  $(call allow-override,CC,$(LLVM_PREFIX)clang$(LLVM_SUFFIX))
+  $(call allow-override,CLANG,$(LLVM_PREFIX)clang$(LLVM_SUFFIX))
+  $(call allow-override,HOSTCC,$(LLVM_PREFIX)clang$(LLVM_SUFFIX))
+  $(call allow-override,AR,$(LLVM_PREFIX)llvm-ar$(LLVM_SUFFIX))
+  $(call allow-override,HOSTAR,$(LLVM_PREFIX)llvm-ar$(LLVM_SUFFIX))
+  $(call allow-override,LD,$(LLVM_PREFIX)ld.lld$(LLVM_SUFFIX))
+  $(call allow-override,HOSTLD,$(LLVM_PREFIX)ld.lld$(LLVM_SUFFIX))
+  $(call allow-override,CXX,$(LLVM_PREFIX)clang++$(LLVM_SUFFIX))
+  $(call allow-override,STRIP,$(LLVM_PREFIX)llvm-strip$(LLVM_SUFFIX))
+  $(call allow-override,LLVM_STRIP,$(LLVM_PREFIX)llvm-strip$(LLVM_SUFFIX))
+  $(call allow-override,LLC,$(LLVM_PREFIX)llc$(LLVM_SUFFIX))
+  $(call allow-override,LLVM_CONFIG,$(LLVM_PREFIX)llvm-config$(LLVM_SUFFIX))
+  $(call allow-override,LLVM_OBJCOPY,$(LLVM_PREFIX)llvm-objcopy$(LLVM_SUFFIX))
 else
-# Allow setting various cross-compile vars or setting CROSS_COMPILE as a prefix.
-$(call allow-override,CC,$(CROSS_COMPILE)gcc)
-$(call allow-override,AR,$(CROSS_COMPILE)ar)
-$(call allow-override,LD,$(CROSS_COMPILE)ld)
-$(call allow-override,CXX,$(CROSS_COMPILE)g++)
-$(call allow-override,STRIP,$(CROSS_COMPILE)strip)
-
-# Host versions aren't prefixed
-$(call allow-override,HOSTAR,ar)
-$(call allow-override,HOSTCC,gcc)
-$(call allow-override,HOSTLD,ld)
-
-# Some tools still require Clang, LLC and/or LLVM utils
-$(call allow-override,CLANG,clang)
-$(call allow-override,LLC,llc)
-$(call allow-override,LLVM_CONFIG,llvm-config)
-$(call allow-override,LLVM_OBJCOPY,llvm-objcopy)
-$(call allow-override,LLVM_STRIP,llvm-strip)
+  # Allow setting various cross-compile vars or setting CROSS_COMPILE as a prefix.
+  $(call allow-override,CC,$(CROSS_COMPILE)gcc)
+  $(call allow-override,AR,$(CROSS_COMPILE)ar)
+  $(call allow-override,LD,$(CROSS_COMPILE)ld)
+  $(call allow-override,CXX,$(CROSS_COMPILE)g++)
+  $(call allow-override,STRIP,$(CROSS_COMPILE)strip)
+
+  # Host versions aren't prefixed
+  $(call allow-override,HOSTAR,ar)
+  $(call allow-override,HOSTCC,gcc)
+  $(call allow-override,HOSTLD,ld)
+
+  # Some tools still require Clang, LLC and/or LLVM utils
+  $(call allow-override,CLANG,clang)
+  $(call allow-override,LLC,llc)
+  $(call allow-override,LLVM_CONFIG,llvm-config)
+  $(call allow-override,LLVM_OBJCOPY,llvm-objcopy)
+  $(call allow-override,LLVM_STRIP,llvm-strip)
 endif
 
 CC_NO_CLANG := $(shell $(CC) -dM -E -x c /dev/null | grep -Fq "__clang__"; echo $$?)

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 3/6] selftests: Remove unused LLD variable
From: James Clark @ 2026-05-18  9:03 UTC (permalink / raw)
  To: Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	Jiri Kosina, Benjamin Tissoires, Shuah Khan, Peter Zijlstra,
	Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	Andrii Nakryiko, Eduard Zingerman, Alexei Starovoitov,
	Daniel Borkmann, Martin KaFai Lau, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, ihor.solodrai
  Cc: linux-kernel, llvm, linux-input, linux-kselftest, bpf,
	linux-perf-users, James Clark
In-Reply-To: <20260518-james-perf-llvm-version-v2-0-f12cc4f031d8@linaro.org>

This file was mostly copied from selftests/bpf/Makefile, but the LLD
variable is not used here. Also, this copied block didn't get the same
fixes as the original one did later.

Remove it to avoid confusion and so future fixes don't have to be in two
places.

Signed-off-by: James Clark <james.clark@linaro.org>
---
 tools/testing/selftests/hid/Makefile | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/tools/testing/selftests/hid/Makefile b/tools/testing/selftests/hid/Makefile
index 50ec9e0406ab..96071b4800e8 100644
--- a/tools/testing/selftests/hid/Makefile
+++ b/tools/testing/selftests/hid/Makefile
@@ -105,13 +105,6 @@ $(MAKE_DIRS):
 	$(call msg,MKDIR,,$@)
 	$(Q)mkdir -p $@
 
-# LLVM's ld.lld doesn't support all the architectures, so use it only on x86
-ifeq ($(SRCARCH),x86)
-LLD := lld
-else
-LLD := ld
-endif
-
 DEFAULT_BPFTOOL := $(HOST_SCRATCH_DIR)/sbin/bpftool
 
 TEST_GEN_PROGS_EXTENDED += $(DEFAULT_BPFTOOL)

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 4/6] tools/build: Allow versioning LLVM readelf
From: James Clark @ 2026-05-18  9:03 UTC (permalink / raw)
  To: Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	Jiri Kosina, Benjamin Tissoires, Shuah Khan, Peter Zijlstra,
	Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	Andrii Nakryiko, Eduard Zingerman, Alexei Starovoitov,
	Daniel Borkmann, Martin KaFai Lau, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, ihor.solodrai
  Cc: linux-kernel, llvm, linux-input, linux-kselftest, bpf,
	linux-perf-users, James Clark
In-Reply-To: <20260518-james-perf-llvm-version-v2-0-f12cc4f031d8@linaro.org>

Documentation/kbuild/llvm.rst mentions that readelf is included in the
LLVM toolchain, but it's not currently included in this block.

Add it so that LLVM=... options also apply to readelf. Users in tools/
were Perf which was hardcoding it, and another was the BPF makefile.
Both already include Makefile.include so convert them to use the new
variable.

It also didn't have the cross compile prefix, so either readelf didn't
mind opening cross binaries, or it wasn't working for cross builds.

Signed-off-by: James Clark <james.clark@linaro.org>
---
 tools/lib/bpf/Makefile         | 8 ++++----
 tools/perf/Makefile.perf       | 1 -
 tools/scripts/Makefile.include | 2 ++
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile
index 168140f8e646..180dca9c57c8 100644
--- a/tools/lib/bpf/Makefile
+++ b/tools/lib/bpf/Makefile
@@ -114,12 +114,12 @@ PC_FILE		:= $(addprefix $(OUTPUT),$(PC_FILE))
 
 TAGS_PROG := $(if $(shell which etags 2>/dev/null),etags,ctags)
 
-GLOBAL_SYM_COUNT = $(shell readelf -s --wide $(BPF_IN_SHARED) | \
+GLOBAL_SYM_COUNT = $(shell $(READELF) -s --wide $(BPF_IN_SHARED) | \
 			   cut -d "@" -f1 | sed 's/_v[0-9]_[0-9]_[0-9].*//' | \
 			   sed 's/\[.*\]//' | \
 			   awk '/GLOBAL/ && /DEFAULT/ && !/UND|ABS/ {print $$NF}' | \
 			   sort -u | wc -l)
-VERSIONED_SYM_COUNT = $(shell readelf --dyn-syms --wide $(OUTPUT)libbpf.so | \
+VERSIONED_SYM_COUNT = $(shell $(READELF) --dyn-syms --wide $(OUTPUT)libbpf.so | \
 			      sed 's/\[.*\]//' | \
 			      awk '/GLOBAL/ && /DEFAULT/ && !/UND|ABS/ {print $$NF}' | \
 			      grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 | sort -u | wc -l)
@@ -182,12 +182,12 @@ check_abi: $(OUTPUT)libbpf.so $(VERSION_SCRIPT)
 		     "versioned symbols in $^ ($(VERSIONED_SYM_COUNT))." \
 		     "Please make sure all LIBBPF_API symbols are"	 \
 		     "versioned in $(VERSION_SCRIPT)." >&2;		 \
-		readelf -s --wide $(BPF_IN_SHARED) |			 \
+		$(READELF) -s --wide $(BPF_IN_SHARED) |			 \
 		    cut -d "@" -f1 | sed 's/_v[0-9]_[0-9]_[0-9].*//' |	 \
 		    sed 's/\[.*\]//' |					 \
 		    awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$NF}'|  \
 		    sort -u > $(OUTPUT)libbpf_global_syms.tmp;		 \
-		readelf --dyn-syms --wide $(OUTPUT)libbpf.so |		 \
+		$(READELF) --dyn-syms --wide $(OUTPUT)libbpf.so |		 \
 		    sed 's/\[.*\]//' |					 \
 		    awk '/GLOBAL/ && /DEFAULT/ && !/UND|ABS/ {print $$NF}'|  \
 		    grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 |		 \
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 0aba14f22a06..63276bf55856 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -215,7 +215,6 @@ FLEX    ?= flex
 BISON   ?= bison
 STRIP   = strip
 AWK     = awk
-READELF ?= readelf
 
 # include Makefile.config by default and rule out
 # non-config cases
diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include
index e81e5b479c56..380ad84ac51e 100644
--- a/tools/scripts/Makefile.include
+++ b/tools/scripts/Makefile.include
@@ -73,6 +73,7 @@ ifneq ($(LLVM),)
   $(call allow-override,LLC,$(LLVM_PREFIX)llc$(LLVM_SUFFIX))
   $(call allow-override,LLVM_CONFIG,$(LLVM_PREFIX)llvm-config$(LLVM_SUFFIX))
   $(call allow-override,LLVM_OBJCOPY,$(LLVM_PREFIX)llvm-objcopy$(LLVM_SUFFIX))
+  $(call allow-override,READELF,$(LLVM_PREFIX)llvm-readelf$(LLVM_SUFFIX))
 else
   # Allow setting various cross-compile vars or setting CROSS_COMPILE as a prefix.
   $(call allow-override,CC,$(CROSS_COMPILE)gcc)
@@ -80,6 +81,7 @@ else
   $(call allow-override,LD,$(CROSS_COMPILE)ld)
   $(call allow-override,CXX,$(CROSS_COMPILE)g++)
   $(call allow-override,STRIP,$(CROSS_COMPILE)strip)
+  $(call allow-override,READELF,$(CROSS_COMPILE)readelf)
 
   # Host versions aren't prefixed
   $(call allow-override,HOSTAR,ar)

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 5/6] tools/build: selftests: Allow versioning LLVM lld
From: James Clark @ 2026-05-18  9:03 UTC (permalink / raw)
  To: Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	Jiri Kosina, Benjamin Tissoires, Shuah Khan, Peter Zijlstra,
	Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	Andrii Nakryiko, Eduard Zingerman, Alexei Starovoitov,
	Daniel Borkmann, Martin KaFai Lau, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, ihor.solodrai
  Cc: linux-kernel, llvm, linux-input, linux-kselftest, bpf,
	linux-perf-users, James Clark
In-Reply-To: <20260518-james-perf-llvm-version-v2-0-f12cc4f031d8@linaro.org>

Building with LLVM=... could result in a different version of lld being
used than the main toolchain for liburandom_read.so because it's
hardcoded to "lld" in this makefile.

Make it consistent with the rest of the LLVM toolchain by adding an LLD
variable to Makefile.include. Keep the fallback for other architectures
in tools/testing/selftests/bpf/Makefile as it seems like it's something
specific to this make rule and shouldn't be global.

Clang only accepts either a full path to "/x/x/ld.lld" or "lld-15" style
inputs to "-fuse-ld=", so the only way to make it work with both
prefixed and postfixed paths is to always take the full path. Also I
don't think the original use of "lld" over "ld.lld" was significant as
this is always a linux build, so that can be changed to make it work in
both cases.

Signed-off-by: James Clark <james.clark@linaro.org>
---
 tools/scripts/Makefile.include       | 2 ++
 tools/testing/selftests/bpf/Makefile | 8 ++++----
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include
index 380ad84ac51e..5c2d505cba62 100644
--- a/tools/scripts/Makefile.include
+++ b/tools/scripts/Makefile.include
@@ -67,6 +67,7 @@ ifneq ($(LLVM),)
   $(call allow-override,HOSTAR,$(LLVM_PREFIX)llvm-ar$(LLVM_SUFFIX))
   $(call allow-override,LD,$(LLVM_PREFIX)ld.lld$(LLVM_SUFFIX))
   $(call allow-override,HOSTLD,$(LLVM_PREFIX)ld.lld$(LLVM_SUFFIX))
+  $(call allow-override,LLD,$(LLVM_PREFIX)ld.lld$(LLVM_SUFFIX))
   $(call allow-override,CXX,$(LLVM_PREFIX)clang++$(LLVM_SUFFIX))
   $(call allow-override,STRIP,$(LLVM_PREFIX)llvm-strip$(LLVM_SUFFIX))
   $(call allow-override,LLVM_STRIP,$(LLVM_PREFIX)llvm-strip$(LLVM_SUFFIX))
@@ -91,6 +92,7 @@ else
   # Some tools still require Clang, LLC and/or LLVM utils
   $(call allow-override,CLANG,clang)
   $(call allow-override,LLC,llc)
+  $(call allow-override,LLD,ld.lld)
   $(call allow-override,LLVM_CONFIG,llvm-config)
   $(call allow-override,LLVM_OBJCOPY,llvm-objcopy)
   $(call allow-override,LLVM_STRIP,llvm-strip)
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 6ef6872adbc3..836e783f0170 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -245,9 +245,9 @@ $(OUTPUT)/%:%.c
 
 # LLVM's ld.lld doesn't support all the architectures, so use it only on x86
 ifeq ($(SRCARCH),$(filter $(SRCARCH),x86 riscv))
-LLD := lld
+USE_LD := $(shell command -v $(LLD))
 else
-LLD := $(shell command -v $(LD))
+USE_LD := $(shell command -v $(LD))
 endif
 
 # Filter out -static for liburandom_read.so and its dependent targets so that static builds
@@ -258,7 +258,7 @@ $(OUTPUT)/liburandom_read.so: urandom_read_lib1.c urandom_read_lib2.c liburandom
 		     $(filter-out -static,$(CFLAGS) $(LDFLAGS)) \
 		     $(filter %.c,$^) $(filter-out -static,$(LDLIBS)) \
 		     -Wno-unused-command-line-argument \
-		     -fuse-ld=$(LLD) -Wl,-znoseparate-code -Wl,--build-id=sha1 \
+		     -fuse-ld=$(USE_LD) -Wl,-znoseparate-code -Wl,--build-id=sha1 \
 		     -Wl,--version-script=liburandom_read.map \
 		     -fPIC -shared -o $@
 
@@ -268,7 +268,7 @@ $(OUTPUT)/urandom_read: urandom_read.c urandom_read_aux.c $(OUTPUT)/liburandom_r
 		     $(filter-out -static,$(CFLAGS) $(LDFLAGS)) $(filter %.c,$^) \
 		     -Wno-unused-command-line-argument \
 		     -lurandom_read $(filter-out -static,$(LDLIBS)) -L$(OUTPUT) \
-		     -fuse-ld=$(LLD) -Wl,-znoseparate-code -Wl,--build-id=sha1 \
+		     -fuse-ld=$(USE_LD) -Wl,-znoseparate-code -Wl,--build-id=sha1 \
 		     -Wl,-rpath=. -o $@
 
 $(OUTPUT)/sign-file: ../../../../scripts/sign-file.c

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 6/6] tools/build: selftests: Remove some duplicate toolchain definitions
From: James Clark @ 2026-05-18  9:03 UTC (permalink / raw)
  To: Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	Jiri Kosina, Benjamin Tissoires, Shuah Khan, Peter Zijlstra,
	Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	Andrii Nakryiko, Eduard Zingerman, Alexei Starovoitov,
	Daniel Borkmann, Martin KaFai Lau, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, ihor.solodrai
  Cc: linux-kernel, llvm, linux-input, linux-kselftest, bpf,
	linux-perf-users, James Clark
In-Reply-To: <20260518-james-perf-llvm-version-v2-0-f12cc4f031d8@linaro.org>

Try to remove some, but not all duplicate toolchain definitions. In
these instances, their makefiles already include
tools/scripts/Makefile.include which defines these in a consistent way.

STRIP is the only one that was set with an '=', but I don't think it
was significant so that difference can be dropped.

Signed-off-by: James Clark <james.clark@linaro.org>
---
 tools/bpf/resolve_btfids/Makefile    | 3 ---
 tools/lib/api/Makefile               | 4 ----
 tools/lib/subcmd/Makefile            | 4 ----
 tools/lib/symbol/Makefile            | 4 ----
 tools/perf/Makefile.perf             | 6 ------
 tools/testing/selftests/bpf/Makefile | 1 -
 6 files changed, 22 deletions(-)

diff --git a/tools/bpf/resolve_btfids/Makefile b/tools/bpf/resolve_btfids/Makefile
index 7672208f65e4..6fdb6302e0a2 100644
--- a/tools/bpf/resolve_btfids/Makefile
+++ b/tools/bpf/resolve_btfids/Makefile
@@ -20,9 +20,6 @@ HOST_OVERRIDES := AR="$(HOSTAR)" CC="$(HOSTCC)" LD="$(HOSTLD)" ARCH="$(HOSTARCH)
 		  CROSS_COMPILE="" CLANG_CROSS_FLAGS="" EXTRA_CFLAGS="$(HOSTCFLAGS)"
 
 RM      ?= rm
-HOSTCC  ?= gcc
-HOSTLD  ?= ld
-HOSTAR  ?= ar
 HOSTPKG_CONFIG ?= pkg-config
 CROSS_COMPILE =
 
diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile
index 8665c799e0fa..a228fdb5adba 100644
--- a/tools/lib/api/Makefile
+++ b/tools/lib/api/Makefile
@@ -9,10 +9,6 @@ srctree := $(patsubst %/,%,$(dir $(srctree)))
 #$(info Determined 'srctree' to be $(srctree))
 endif
 
-CC ?= $(CROSS_COMPILE)gcc
-AR ?= $(CROSS_COMPILE)ar
-LD ?= $(CROSS_COMPILE)ld
-
 MAKEFLAGS += --no-print-directory
 
 INSTALL = install
diff --git a/tools/lib/subcmd/Makefile b/tools/lib/subcmd/Makefile
index 8703ab487b68..9f1ddcf0504d 100644
--- a/tools/lib/subcmd/Makefile
+++ b/tools/lib/subcmd/Makefile
@@ -9,10 +9,6 @@ srctree := $(patsubst %/,%,$(dir $(srctree)))
 #$(info Determined 'srctree' to be $(srctree))
 endif
 
-CC ?= $(CROSS_COMPILE)gcc
-LD ?= $(CROSS_COMPILE)ld
-AR ?= $(CROSS_COMPILE)ar
-
 RM = rm -f
 
 MAKEFLAGS += --no-print-directory
diff --git a/tools/lib/symbol/Makefile b/tools/lib/symbol/Makefile
index 426b845edfac..d692abe8add6 100644
--- a/tools/lib/symbol/Makefile
+++ b/tools/lib/symbol/Makefile
@@ -9,10 +9,6 @@ srctree := $(patsubst %/,%,$(dir $(srctree)))
 #$(info Determined 'srctree' to be $(srctree))
 endif
 
-CC ?= $(CROSS_COMPILE)gcc
-AR ?= $(CROSS_COMPILE)ar
-LD ?= $(CROSS_COMPILE)ld
-
 MAKEFLAGS += --no-print-directory
 
 INSTALL = install
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 63276bf55856..948abfd2ee8d 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -174,11 +174,6 @@ endef
 
 LD += $(EXTRA_LDFLAGS)
 
-HOSTCC  ?= gcc
-HOSTLD  ?= ld
-HOSTAR  ?= ar
-CLANG   ?= clang
-
 # Some distros provide the command $(CROSS_COMPILE)pkg-config for
 # searching packges installed with Multiarch. Use it for cross
 # compilation if it is existed.
@@ -213,7 +208,6 @@ FIND    = find
 INSTALL = install
 FLEX    ?= flex
 BISON   ?= bison
-STRIP   = strip
 AWK     = awk
 
 # include Makefile.config by default and rule out
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 836e783f0170..f038642b283f 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -3,7 +3,6 @@ include ../../../build/Build.include
 include ../../../scripts/Makefile.arch
 include ../../../scripts/Makefile.include
 
-CXX ?= $(CROSS_COMPILE)g++
 OBJCOPY ?= $(CROSS_COMPILE)objcopy
 
 CURDIR := $(abspath .)

-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH 5/6] tools/build: selftests: Allow versioning LLVM lld
From: James Clark @ 2026-05-18  9:05 UTC (permalink / raw)
  To: Ihor Solodrai
  Cc: linux-kernel, llvm, linux-input, linux-kselftest, bpf,
	linux-perf-users, leo.yan, Nathan Chancellor, Nick Desaulniers,
	Bill Wendling, Justin Stitt, Jiri Kosina, Benjamin Tissoires,
	Shuah Khan, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Ian Rogers, Adrian Hunter, Andrii Nakryiko, Eduard Zingerman,
	Alexei Starovoitov, Daniel Borkmann, Martin KaFai Lau,
	Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song
In-Reply-To: <bda702a1-18f5-47ed-8a4e-a01b94829e07@linux.dev>



On 15/05/2026 11:58 pm, Ihor Solodrai wrote:
> On 5/14/26 2:32 AM, James Clark wrote:
>> Building with LLVM=... could result in a different version of lld being
>> used than the main toolchain for liburandom_read.so because it's
>> hardcoded to "lld" in this makefile.
>>
>> Make it consistent with the rest of the LLVM toolchain by adding an LLD
>> variable to Makefile.include. Keep the fallback for other architectures
>> in tools/testing/selftests/bpf/Makefile as it seems like it's something
>> specific to this make rule and shouldn't be global.
>>
>> Clang accepts either a full path or "ld.lld-15" style inputs to
>> -fuse-ld= so this will work with LLD defined the same way as the other
>> LLVM tools. However, for full paths, we need to use ".../ld.lld" instead
>> of the generic driver "lld", but I don't think the original use of "lld"
>> was significant as this is always a linux build.
>>
>> Signed-off-by: James Clark <james.clark@linaro.org>
>> ---
>>   tools/scripts/Makefile.include       | 2 ++
>>   tools/testing/selftests/bpf/Makefile | 8 ++++----
>>   2 files changed, 6 insertions(+), 4 deletions(-)
>>
>> diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include
>> index 380ad84ac51e..5c2d505cba62 100644
>> --- a/tools/scripts/Makefile.include
>> +++ b/tools/scripts/Makefile.include
>> @@ -67,6 +67,7 @@ ifneq ($(LLVM),)
>>     $(call allow-override,HOSTAR,$(LLVM_PREFIX)llvm-ar$(LLVM_SUFFIX))
>>     $(call allow-override,LD,$(LLVM_PREFIX)ld.lld$(LLVM_SUFFIX))
>>     $(call allow-override,HOSTLD,$(LLVM_PREFIX)ld.lld$(LLVM_SUFFIX))
>> +  $(call allow-override,LLD,$(LLVM_PREFIX)ld.lld$(LLVM_SUFFIX))
>>     $(call allow-override,CXX,$(LLVM_PREFIX)clang++$(LLVM_SUFFIX))
>>     $(call allow-override,STRIP,$(LLVM_PREFIX)llvm-strip$(LLVM_SUFFIX))
>>     $(call allow-override,LLVM_STRIP,$(LLVM_PREFIX)llvm-strip$(LLVM_SUFFIX))
>> @@ -91,6 +92,7 @@ else
>>     # Some tools still require Clang, LLC and/or LLVM utils
>>     $(call allow-override,CLANG,clang)
>>     $(call allow-override,LLC,llc)
>> +  $(call allow-override,LLD,ld.lld)
>>     $(call allow-override,LLVM_CONFIG,llvm-config)
>>     $(call allow-override,LLVM_OBJCOPY,llvm-objcopy)
>>     $(call allow-override,LLVM_STRIP,llvm-strip)
>> diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
>> index 6ef6872adbc3..44ba829e5d4d 100644
>> --- a/tools/testing/selftests/bpf/Makefile
>> +++ b/tools/testing/selftests/bpf/Makefile
>> @@ -245,9 +245,9 @@ $(OUTPUT)/%:%.c
>>   
>>   # LLVM's ld.lld doesn't support all the architectures, so use it only on x86
>>   ifeq ($(SRCARCH),$(filter $(SRCARCH),x86 riscv))
>> -LLD := lld
>> +USE_LD := $(LLD)
>>   else
>> -LLD := $(shell command -v $(LD))
>> +USE_LD := $(shell command -v $(LD))
>>   endif
>>   
>>   # Filter out -static for liburandom_read.so and its dependent targets so that static builds
>> @@ -258,7 +258,7 @@ $(OUTPUT)/liburandom_read.so: urandom_read_lib1.c urandom_read_lib2.c liburandom
>>   		     $(filter-out -static,$(CFLAGS) $(LDFLAGS)) \
>>   		     $(filter %.c,$^) $(filter-out -static,$(LDLIBS)) \
>>   		     -Wno-unused-command-line-argument \
>> -		     -fuse-ld=$(LLD) -Wl,-znoseparate-code -Wl,--build-id=sha1 \
>> +		     -fuse-ld=$(USE_LD) -Wl,-znoseparate-code -Wl,--build-id=sha1 \
> 
> Hi James,
> 
> This patch breaks the selftests/bpf build:
> 
> $ clang --version
> clang version 22.1.3 (CentOS 22.1.3-1.el9)
> Target: x86_64-redhat-linux-gnu
> Thread model: posix
> InstalledDir: /usr/bin
> Configuration file: /etc/clang/x86_64-redhat-linux-gnu-clang.cfg
> 
> $ make LLVM=1 -j$(nproc)
>    [...] # ok
> 
> $ make LLVM=1 -C tools/testing/selftests/bpf -j$(nproc)
> 
> [...] # somewhere in the middle
> 
>    LIB      liburandom_read.so
> clang: error: invalid linker name in argument '-fuse-ld=ld.lld'
> make: *** [Makefile:256: /home/isolodrai/workspace/review/linux/tools/testing/selftests/bpf/liburandom_read.so] Error 1
> make: Leaving directory '/home/isolodrai/workspace/review/linux/tools/testing/selftests/bpf'
> 
> [...]
> 
> Or a simpler reproducer:
> 
> $ make LLVM=1 OUTPUT=/tmp/out /tmp/out/liburandom_read.so
>    LIB      liburandom_read.so
> clang: error: invalid linker name in argument '-fuse-ld=ld.lld'
> make: *** [Makefile:256: /tmp/out/liburandom_read.so] Error 1
> 
> $ make LLVM=-22 OUTPUT=/tmp/out /tmp/out/liburandom_read.so
>    LIB      liburandom_read.so
> clang-22: error: invalid linker name in argument '-fuse-ld=ld.lld-22'
> make: *** [Makefile:256: /tmp/out/liburandom_read.so] Error 1
> 
> I tried your patches, and only then noticed BPF CI caught this too:
> https://github.com/kernel-patches/bpf/actions/runs/25943477658/job/76267174885?pr=12082
> 

Thanks for testing. Yeah looks like I made a mistake here testing the 
various different formats of LLD. Converting it to a full path works 
with both prefixed and postfixed versions, and that's what's already 
done for non x86/riscv so I'll do that.

>>   		     -Wl,--version-script=liburandom_read.map \
>>   		     -fPIC -shared -o $@
>>   
>> @@ -268,7 +268,7 @@ $(OUTPUT)/urandom_read: urandom_read.c urandom_read_aux.c $(OUTPUT)/liburandom_r
>>   		     $(filter-out -static,$(CFLAGS) $(LDFLAGS)) $(filter %.c,$^) \
>>   		     -Wno-unused-command-line-argument \
>>   		     -lurandom_read $(filter-out -static,$(LDLIBS)) -L$(OUTPUT) \
>> -		     -fuse-ld=$(LLD) -Wl,-znoseparate-code -Wl,--build-id=sha1 \
>> +		     -fuse-ld=$(USE_LD) -Wl,-znoseparate-code -Wl,--build-id=sha1 \
>>   		     -Wl,-rpath=. -o $@
>>   
>>   $(OUTPUT)/sign-file: ../../../../scripts/sign-file.c
>>
> 


^ 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