From: Sasha Levin Date: Thu, 26 Mar 2026 11:17:43 +0000 (-0400) Subject: Fixes for all trees X-Git-Tag: v6.12.79~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8241c89893807b5a8f8bdcfbb41b2adfc56b6471;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for all trees Signed-off-by: Sasha Levin --- diff --git a/queue-5.10/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch b/queue-5.10/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch new file mode 100644 index 0000000000..e23a455287 --- /dev/null +++ b/queue-5.10/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch @@ -0,0 +1,43 @@ +From 7691f67a6a17324d07cf2e3654e969b61606515e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Mar 2026 06:29:06 +0500 +Subject: ALSA: hda/realtek: Add headset jack quirk for Thinkpad X390 + +From: Uzair Mughal + +[ Upstream commit 542127f6528ca7cc3cf61e1651d6ccb58495f953 ] + +The Lenovo ThinkPad X390 (ALC257 codec, subsystem ID 0x17aa2288) +does not report headset button press events. Headphone insertion is +detected (SW_HEADPHONE_INSERT), but pressing the inline microphone +button on a headset produces no input events. + +Add a SND_PCI_QUIRK entry that maps this subsystem ID to +ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, which enables +headset jack button detection through alc_fixup_headset_jack() +and ThinkPad ACPI integration. This is the same fixup used by +similar ThinkPad models (P1 Gen 3, X1 Extreme Gen 3). + +Signed-off-by: Uzair Mughal +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20260307012906.20093-1-contact@uzair.is-a.dev +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index b8c7f4c8593ba..7ea036f820f54 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9527,6 +9527,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), + SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), + SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), ++ SND_PCI_QUIRK(0x17aa, 0x2288, "Thinkpad X390", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x22c1, "Thinkpad P1 Gen 3", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), +-- +2.51.0 + diff --git a/queue-5.10/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch b/queue-5.10/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch new file mode 100644 index 0000000000..98a6c249df --- /dev/null +++ b/queue-5.10/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch @@ -0,0 +1,52 @@ +From fb5d92a8c1fc6ee9882515b3bff4440ff9be9652 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 00:25:38 +0000 +Subject: ASoC: fsl_easrc: Fix event generation in fsl_easrc_iec958_set_reg() + +From: Mark Brown + +[ Upstream commit 31ddc62c1cd92e51b9db61d7954b85ae2ec224da ] + +ALSA controls should return 1 if the value in the control changed but the +control put operation fsl_easrc_set_reg() only returns 0 or a negative +error code, causing ALSA to not generate any change events. Add a suitable +check by using regmap_update_bits_check() with the underlying regmap, this +is more clearly and simply correct than trying to verify that one of the +generic ops is exactly equivalent to this one. + +Signed-off-by: Mark Brown +Link: https://patch.msgid.link/20260205-asoc-fsl-easrc-fix-events-v1-2-39d4c766918b@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_easrc.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c +index acd500c3b9d04..52b3f2d44f681 100644 +--- a/sound/soc/fsl/fsl_easrc.c ++++ b/sound/soc/fsl/fsl_easrc.c +@@ -93,14 +93,17 @@ static int fsl_easrc_set_reg(struct snd_kcontrol *kcontrol, + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_value; ++ struct fsl_asrc *easrc = snd_soc_component_get_drvdata(component); + unsigned int regval = ucontrol->value.integer.value[0]; ++ bool changed; + int ret; + +- ret = snd_soc_component_write(component, mc->regbase, regval); +- if (ret < 0) ++ ret = regmap_update_bits_check(easrc->regmap, mc->regbase, ++ GENMASK(31, 0), regval, &changed); ++ if (ret != 0) + return ret; + +- return 0; ++ return changed; + } + + #define SOC_SINGLE_REG_RW(xname, xreg) \ +-- +2.51.0 + diff --git a/queue-5.10/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-25677 b/queue-5.10/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-25677 new file mode 100644 index 0000000000..0077747ce9 --- /dev/null +++ b/queue-5.10/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-25677 @@ -0,0 +1,49 @@ +From 19f8498c231a99f3d675e487024cc25d36757313 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 00:25:37 +0000 +Subject: ASoC: fsl_easrc: Fix event generation in fsl_easrc_iec958_put_bits() + +From: Mark Brown + +[ Upstream commit 54a86cf48eaa6d1ab5130d756b718775e81e1748 ] + +ALSA controls should return 1 if the value in the control changed but the +control put operation fsl_easrc_iec958_put_bits() unconditionally returns +0, causing ALSA to not generate any change events. This is detected by +mixer-test with large numbers of messages in the form: + + No event generated for Context 3 IEC958 CS5 + Context 3 IEC958 CS5.0 orig 5224 read 5225, is_volatile 0 + +Add a suitable check. + +Signed-off-by: Mark Brown +Link: https://patch.msgid.link/20260205-asoc-fsl-easrc-fix-events-v1-1-39d4c766918b@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_easrc.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c +index 52b3f2d44f681..6af5c1735e2ed 100644 +--- a/sound/soc/fsl/fsl_easrc.c ++++ b/sound/soc/fsl/fsl_easrc.c +@@ -52,10 +52,13 @@ static int fsl_easrc_iec958_put_bits(struct snd_kcontrol *kcontrol, + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_value; + unsigned int regval = ucontrol->value.integer.value[0]; ++ int ret; ++ ++ ret = (easrc_priv->bps_iec958[mc->regbase] != regval); + + easrc_priv->bps_iec958[mc->regbase] = regval; + +- return 0; ++ return ret; + } + + static int fsl_easrc_iec958_get_bits(struct snd_kcontrol *kcontrol, +-- +2.51.0 + diff --git a/queue-5.10/dma-buf-include-ioctl.h-in-uapi-header.patch b/queue-5.10/dma-buf-include-ioctl.h-in-uapi-header.patch new file mode 100644 index 0000000000..2393cf9432 --- /dev/null +++ b/queue-5.10/dma-buf-include-ioctl.h-in-uapi-header.patch @@ -0,0 +1,44 @@ +From 8029e7b771b420a132fb69034b1375d5ee0d1abf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Mar 2026 16:23:09 -0800 +Subject: dma-buf: Include ioctl.h in UAPI header +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Isaac J. Manjarres + +[ Upstream commit a116bac87118903925108e57781bbfc7a7eea27b ] + +include/uapi/linux/dma-buf.h uses several macros from ioctl.h to define +its ioctl commands. However, it does not include ioctl.h itself. So, +if userspace source code tries to include the dma-buf.h file without +including ioctl.h, it can result in build failures. + +Therefore, include ioctl.h in the dma-buf UAPI header. + +Signed-off-by: Isaac J. Manjarres +Reviewed-by: T.J. Mercier +Reviewed-by: Christian König +Signed-off-by: Christian König +Link: https://lore.kernel.org/r/20260303002309.1401849-1-isaacmanjarres@google.com +Signed-off-by: Sasha Levin +--- + include/uapi/linux/dma-buf.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h +index f76d11725c6c6..dd9fa80184f3e 100644 +--- a/include/uapi/linux/dma-buf.h ++++ b/include/uapi/linux/dma-buf.h +@@ -20,6 +20,7 @@ + #ifndef _DMA_BUF_UAPI_H_ + #define _DMA_BUF_UAPI_H_ + ++#include + #include + + /* begin/end dma-buf functions used for userspace mmap. */ +-- +2.51.0 + diff --git a/queue-5.10/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch b/queue-5.10/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch new file mode 100644 index 0000000000..e27617899f --- /dev/null +++ b/queue-5.10/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch @@ -0,0 +1,65 @@ +From a04c3699783fd4f7b027471bf81cd1f4bd4bb811 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Feb 2026 16:43:38 +0100 +Subject: HID: asus: avoid memory leak in asus_report_fixup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Günther Noack + +[ Upstream commit 2bad24c17742fc88973d6aea526ce1353f5334a3 ] + +The asus_report_fixup() function was returning a newly allocated +kmemdup()-allocated buffer, but never freeing it. Switch to +devm_kzalloc() to ensure the memory is managed and freed automatically +when the device is removed. + +The caller of report_fixup() does not take ownership of the returned +pointer, but it is permitted to return a pointer whose lifetime is at +least that of the input buffer. + +Also fix a harmless out-of-bounds read by copying only the original +descriptor size. + +Assisted-by: Gemini-CLI:Google Gemini 3 +Signed-off-by: Günther Noack +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-asus.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index 2f82946fb36a2..9d425f81d6224 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -1116,14 +1116,21 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, + */ + if (*rsize == rsize_orig && + rdesc[offs] == 0x09 && rdesc[offs + 1] == 0x76) { +- *rsize = rsize_orig + 1; +- rdesc = kmemdup(rdesc, *rsize, GFP_KERNEL); +- if (!rdesc) +- return NULL; ++ __u8 *new_rdesc; ++ ++ new_rdesc = devm_kzalloc(&hdev->dev, rsize_orig + 1, ++ GFP_KERNEL); ++ if (!new_rdesc) ++ return rdesc; + + hid_info(hdev, "Fixing up %s keyb report descriptor\n", + drvdata->quirks & QUIRK_T100CHI ? + "T100CHI" : "T90CHI"); ++ ++ memcpy(new_rdesc, rdesc, rsize_orig); ++ *rsize = rsize_orig + 1; ++ rdesc = new_rdesc; ++ + memmove(rdesc + offs + 4, rdesc + offs + 2, 12); + rdesc[offs] = 0x19; + rdesc[offs + 1] = 0x00; +-- +2.51.0 + diff --git a/queue-5.10/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch b/queue-5.10/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch new file mode 100644 index 0000000000..c79d9cd195 --- /dev/null +++ b/queue-5.10/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch @@ -0,0 +1,41 @@ +From 7b0024ea69e91bfbe2f12d409be1412b008e7667 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 17:32:58 +0100 +Subject: HID: mcp2221: cancel last I2C command on read error + +From: Romain Sioen + +[ Upstream commit e31b556c0ba21f20c298aa61181b96541140b7b9 ] + +When an I2C SMBus read operation fails, the MCP2221 internal state machine +may not reset correctly, causing subsequent transactions to fail. + +By adding a short delay and explicitly cancelling the last command, +we ensure the device is ready for the next operation. + +Fix an issue where i2cdetect was not able to detect all devices correctly +on the bus. + +Signed-off-by: Romain Sioen +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-mcp2221.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c +index 589f13ff0b606..9fb98c8e1ffb7 100644 +--- a/drivers/hid/hid-mcp2221.c ++++ b/drivers/hid/hid-mcp2221.c +@@ -319,6 +319,8 @@ static int mcp_i2c_smbus_read(struct mcp2221 *mcp, + usleep_range(90, 100); + retries++; + } else { ++ usleep_range(980, 1000); ++ mcp_cancel_last_cmd(mcp); + return ret; + } + } else { +-- +2.51.0 + diff --git a/queue-5.10/hwmon-axi-fan-control-make-use-of-dev_err_probe.patch b/queue-5.10/hwmon-axi-fan-control-make-use-of-dev_err_probe.patch new file mode 100644 index 0000000000..7fddb91ce8 --- /dev/null +++ b/queue-5.10/hwmon-axi-fan-control-make-use-of-dev_err_probe.patch @@ -0,0 +1,91 @@ +From 8342080b3f972f0d33b4bc7086ccd19be1715f4a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Feb 2024 15:36:45 +0100 +Subject: hwmon: (axi-fan-control) Make use of dev_err_probe() + +From: Nuno Sa + +[ Upstream commit ec823656c1e0e5f49e92ed86cee9fb26585da18e ] + +Use dev_err_probe() to slightly simplify printing errors during probe. +No functional changes intended. + +Signed-off-by: Nuno Sa +Link: https://lore.kernel.org/r/20240214-axi-fan-control-no-of-v1-3-43ca656fe2e3@analog.com +Signed-off-by: Guenter Roeck +Stable-dep-of: 813bbc4d33d2 ("hwmon: axi-fan: don't use driver_override as IRQ name") +Signed-off-by: Sasha Levin +--- + drivers/hwmon/axi-fan-control.c | 40 +++++++++++++++------------------ + 1 file changed, 18 insertions(+), 22 deletions(-) + +diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c +index cb46615555720..4ea86778d49da 100644 +--- a/drivers/hwmon/axi-fan-control.c ++++ b/drivers/hwmon/axi-fan-control.c +@@ -465,10 +465,9 @@ static int axi_fan_control_probe(struct platform_device *pdev) + return PTR_ERR(ctl->base); + + clk = devm_clk_get_enabled(&pdev->dev, NULL); +- if (IS_ERR(clk)) { +- dev_err(&pdev->dev, "clk_get failed with %ld\n", PTR_ERR(clk)); +- return PTR_ERR(clk); +- } ++ if (IS_ERR(clk)) ++ return dev_err_probe(&pdev->dev, PTR_ERR(clk), ++ "clk_get failed\n"); + + ctl->clk_rate = clk_get_rate(clk); + if (!ctl->clk_rate) +@@ -476,22 +475,20 @@ static int axi_fan_control_probe(struct platform_device *pdev) + + version = axi_ioread(ADI_AXI_REG_VERSION, ctl); + if (ADI_AXI_PCORE_VER_MAJOR(version) != +- ADI_AXI_PCORE_VER_MAJOR((*id))) { +- dev_err(&pdev->dev, "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", +- ADI_AXI_PCORE_VER_MAJOR(*id), +- ADI_AXI_PCORE_VER_MINOR(*id), +- ADI_AXI_PCORE_VER_PATCH(*id), +- ADI_AXI_PCORE_VER_MAJOR(version), +- ADI_AXI_PCORE_VER_MINOR(version), +- ADI_AXI_PCORE_VER_PATCH(version)); +- return -ENODEV; +- } ++ ADI_AXI_PCORE_VER_MAJOR((*id))) ++ return dev_err_probe(&pdev->dev, -ENODEV, ++ "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", ++ ADI_AXI_PCORE_VER_MAJOR(*id), ++ ADI_AXI_PCORE_VER_MINOR(*id), ++ ADI_AXI_PCORE_VER_PATCH(*id), ++ ADI_AXI_PCORE_VER_MAJOR(version), ++ ADI_AXI_PCORE_VER_MINOR(version), ++ ADI_AXI_PCORE_VER_PATCH(version)); + + ret = axi_fan_control_init(ctl, &pdev->dev); +- if (ret) { +- dev_err(&pdev->dev, "Failed to initialize device\n"); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(&pdev->dev, ret, ++ "Failed to initialize device\n"); + + ctl->hdev = devm_hwmon_device_register_with_info(&pdev->dev, + name, +@@ -510,10 +507,9 @@ static int axi_fan_control_probe(struct platform_device *pdev) + axi_fan_control_irq_handler, + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, + pdev->driver_override, ctl); +- if (ret) { +- dev_err(&pdev->dev, "failed to request an irq, %d", ret); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(&pdev->dev, ret, ++ "failed to request an irq\n"); + + return 0; + } +-- +2.51.0 + diff --git a/queue-5.10/hwmon-axi-fan-control-use-device-firmware-agnostic-a.patch b/queue-5.10/hwmon-axi-fan-control-use-device-firmware-agnostic-a.patch new file mode 100644 index 0000000000..7a205900fd --- /dev/null +++ b/queue-5.10/hwmon-axi-fan-control-use-device-firmware-agnostic-a.patch @@ -0,0 +1,126 @@ +From 10fe75f492d9515aedfcf9d4186d824e77530114 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Feb 2024 15:36:43 +0100 +Subject: hwmon: (axi-fan-control) Use device firmware agnostic API + +From: Nuno Sa + +[ Upstream commit 1b5239f70fcd2d7fe86f0f5473006c2896db07a8 ] + +Don't directly use OF and use device property APIs. In addition, this +makes the probe() code neater and also allow us to move the +of_device_id table to it's natural place. + +While at it, make sure to explicitly include mod_devicetable.h for the +of_device_id table. + +Signed-off-by: Nuno Sa +Link: https://lore.kernel.org/r/20240214-axi-fan-control-no-of-v1-1-43ca656fe2e3@analog.com +Signed-off-by: Guenter Roeck +Stable-dep-of: 813bbc4d33d2 ("hwmon: axi-fan: don't use driver_override as IRQ name") +Signed-off-by: Sasha Levin +--- + drivers/hwmon/axi-fan-control.c | 39 +++++++++++++++++---------------- + 1 file changed, 20 insertions(+), 19 deletions(-) + +diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c +index 6cfc063c133f4..cb46615555720 100644 +--- a/drivers/hwmon/axi-fan-control.c ++++ b/drivers/hwmon/axi-fan-control.c +@@ -13,8 +13,9 @@ + #include + #include + #include +-#include ++#include + #include ++#include + + /* register map */ + #define ADI_REG_RSTN 0x0080 +@@ -367,12 +368,12 @@ static irqreturn_t axi_fan_control_irq_handler(int irq, void *data) + } + + static int axi_fan_control_init(struct axi_fan_control_data *ctl, +- const struct device_node *np) ++ const struct device *dev) + { + int ret; + + /* get fan pulses per revolution */ +- ret = of_property_read_u32(np, "pulses-per-revolution", &ctl->ppr); ++ ret = device_property_read_u32(dev, "pulses-per-revolution", &ctl->ppr); + if (ret) + return ret; + +@@ -442,25 +443,16 @@ static struct attribute *axi_fan_control_attrs[] = { + }; + ATTRIBUTE_GROUPS(axi_fan_control); + +-static const u32 version_1_0_0 = ADI_AXI_PCORE_VER(1, 0, 'a'); +- +-static const struct of_device_id axi_fan_control_of_match[] = { +- { .compatible = "adi,axi-fan-control-1.00.a", +- .data = (void *)&version_1_0_0}, +- {}, +-}; +-MODULE_DEVICE_TABLE(of, axi_fan_control_of_match); +- + static int axi_fan_control_probe(struct platform_device *pdev) + { + struct axi_fan_control_data *ctl; + struct clk *clk; +- const struct of_device_id *id; ++ const unsigned int *id; + const char *name = "axi_fan_control"; + u32 version; + int ret; + +- id = of_match_node(axi_fan_control_of_match, pdev->dev.of_node); ++ id = device_get_match_data(&pdev->dev); + if (!id) + return -EINVAL; + +@@ -484,18 +476,18 @@ static int axi_fan_control_probe(struct platform_device *pdev) + + version = axi_ioread(ADI_AXI_REG_VERSION, ctl); + if (ADI_AXI_PCORE_VER_MAJOR(version) != +- ADI_AXI_PCORE_VER_MAJOR((*(u32 *)id->data))) { ++ ADI_AXI_PCORE_VER_MAJOR((*id))) { + dev_err(&pdev->dev, "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", +- ADI_AXI_PCORE_VER_MAJOR((*(u32 *)id->data)), +- ADI_AXI_PCORE_VER_MINOR((*(u32 *)id->data)), +- ADI_AXI_PCORE_VER_PATCH((*(u32 *)id->data)), ++ ADI_AXI_PCORE_VER_MAJOR(*id), ++ ADI_AXI_PCORE_VER_MINOR(*id), ++ ADI_AXI_PCORE_VER_PATCH(*id), + ADI_AXI_PCORE_VER_MAJOR(version), + ADI_AXI_PCORE_VER_MINOR(version), + ADI_AXI_PCORE_VER_PATCH(version)); + return -ENODEV; + } + +- ret = axi_fan_control_init(ctl, pdev->dev.of_node); ++ ret = axi_fan_control_init(ctl, &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "Failed to initialize device\n"); + return ret; +@@ -526,6 +518,15 @@ static int axi_fan_control_probe(struct platform_device *pdev) + return 0; + } + ++static const u32 version_1_0_0 = ADI_AXI_PCORE_VER(1, 0, 'a'); ++ ++static const struct of_device_id axi_fan_control_of_match[] = { ++ { .compatible = "adi,axi-fan-control-1.00.a", ++ .data = (void *)&version_1_0_0}, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, axi_fan_control_of_match); ++ + static struct platform_driver axi_fan_control_driver = { + .driver = { + .name = "axi_fan_control_driver", +-- +2.51.0 + diff --git a/queue-5.10/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch b/queue-5.10/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch new file mode 100644 index 0000000000..d17dc78e6d --- /dev/null +++ b/queue-5.10/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch @@ -0,0 +1,43 @@ +From 2e1878ac518d58b2384a3ee12efbf2f8548cd7b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Mar 2026 12:53:20 +0100 +Subject: hwmon: axi-fan: don't use driver_override as IRQ name +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Danilo Krummrich + +[ Upstream commit 813bbc4d33d2ca5b0da63e70ae13b60874f20d37 ] + +Do not use driver_override as IRQ name, as it is not guaranteed to point +to a valid string; use NULL instead (which makes the devm IRQ helpers +use dev_name()). + +Fixes: 8412b410fa5e ("hwmon: Support ADI Fan Control IP") +Reviewed-by: Nuno Sá +Acked-by: Guenter Roeck +Reviewed-by: Greg Kroah-Hartman +Link: https://patch.msgid.link/20260303115720.48783-4-dakr@kernel.org +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + drivers/hwmon/axi-fan-control.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c +index 4ea86778d49da..5593be1664be7 100644 +--- a/drivers/hwmon/axi-fan-control.c ++++ b/drivers/hwmon/axi-fan-control.c +@@ -506,7 +506,7 @@ static int axi_fan_control_probe(struct platform_device *pdev) + ret = devm_request_threaded_irq(&pdev->dev, ctl->irq, NULL, + axi_fan_control_irq_handler, + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, +- pdev->driver_override, ctl); ++ NULL, ctl); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "failed to request an irq\n"); +-- +2.51.0 + diff --git a/queue-5.10/hwmon-make-use-of-devm_clk_get_enabled.patch b/queue-5.10/hwmon-make-use-of-devm_clk_get_enabled.patch new file mode 100644 index 0000000000..7ae9240a6c --- /dev/null +++ b/queue-5.10/hwmon-make-use-of-devm_clk_get_enabled.patch @@ -0,0 +1,133 @@ +From 2729af35760cfd5f38d89ee802a333a7b1560fbd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 Aug 2022 08:06:40 +0200 +Subject: hwmon: Make use of devm_clk_get_enabled() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit 0dee25ebc7d315d9ee785ea5f457ae980979ea89 ] + +Several drivers manually register a devm handler to disable their clk. +Convert them to devm_clk_get_enabled(). + +Acked-by: Guenter Roeck +Reviewed-by: Nuno Sá +Acked-by: Jonathan Cameron +Signed-off-by: Uwe Kleine-König +Signed-off-by: Guenter Roeck +Stable-dep-of: 813bbc4d33d2 ("hwmon: axi-fan: don't use driver_override as IRQ name") +Signed-off-by: Sasha Levin +--- + drivers/hwmon/axi-fan-control.c | 2 +- + drivers/hwmon/ltc2947-core.c | 17 +---------------- + drivers/hwmon/mr75203.c | 26 +------------------------- + 3 files changed, 3 insertions(+), 42 deletions(-) + +diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c +index 4b8250f2bb421..6cfc063c133f4 100644 +--- a/drivers/hwmon/axi-fan-control.c ++++ b/drivers/hwmon/axi-fan-control.c +@@ -472,7 +472,7 @@ static int axi_fan_control_probe(struct platform_device *pdev) + if (IS_ERR(ctl->base)) + return PTR_ERR(ctl->base); + +- clk = devm_clk_get(&pdev->dev, NULL); ++ clk = devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "clk_get failed with %ld\n", PTR_ERR(clk)); + return PTR_ERR(clk); +diff --git a/drivers/hwmon/ltc2947-core.c b/drivers/hwmon/ltc2947-core.c +index e918490f3ff75..f752701818192 100644 +--- a/drivers/hwmon/ltc2947-core.c ++++ b/drivers/hwmon/ltc2947-core.c +@@ -956,13 +956,6 @@ static struct attribute *ltc2947_attrs[] = { + }; + ATTRIBUTE_GROUPS(ltc2947); + +-static void ltc2947_clk_disable(void *data) +-{ +- struct clk *extclk = data; +- +- clk_disable_unprepare(extclk); +-} +- + static int ltc2947_setup(struct ltc2947_data *st) + { + int ret; +@@ -989,7 +982,7 @@ static int ltc2947_setup(struct ltc2947_data *st) + return ret; + + /* check external clock presence */ +- extclk = devm_clk_get_optional(st->dev, NULL); ++ extclk = devm_clk_get_optional_enabled(st->dev, NULL); + if (IS_ERR(extclk)) + return dev_err_probe(st->dev, PTR_ERR(extclk), + "Failed to get external clock\n"); +@@ -1007,14 +1000,6 @@ static int ltc2947_setup(struct ltc2947_data *st) + return -EINVAL; + } + +- ret = clk_prepare_enable(extclk); +- if (ret) +- return ret; +- +- ret = devm_add_action_or_reset(st->dev, ltc2947_clk_disable, +- extclk); +- if (ret) +- return ret; + /* as in table 1 of the datasheet */ + if (rate_hz >= LTC2947_CLK_MIN && rate_hz <= 1000000) + pre = 0; +diff --git a/drivers/hwmon/mr75203.c b/drivers/hwmon/mr75203.c +index 19ec9fb912020..cb4cdb26385bc 100644 +--- a/drivers/hwmon/mr75203.c ++++ b/drivers/hwmon/mr75203.c +@@ -487,24 +487,6 @@ static int pvt_get_regmap(struct platform_device *pdev, char *reg_name, + return 0; + } + +-static void pvt_clk_disable(void *data) +-{ +- struct pvt_device *pvt = data; +- +- clk_disable_unprepare(pvt->clk); +-} +- +-static int pvt_clk_enable(struct device *dev, struct pvt_device *pvt) +-{ +- int ret; +- +- ret = clk_prepare_enable(pvt->clk); +- if (ret) +- return ret; +- +- return devm_add_action_or_reset(dev, pvt_clk_disable, pvt); +-} +- + static void pvt_reset_control_assert(void *data) + { + struct pvt_device *pvt = data; +@@ -541,16 +523,10 @@ static int mr75203_probe(struct platform_device *pdev) + if (ret) + return ret; + +- pvt->clk = devm_clk_get(dev, NULL); ++ pvt->clk = devm_clk_get_enabled(dev, NULL); + if (IS_ERR(pvt->clk)) + return dev_err_probe(dev, PTR_ERR(pvt->clk), "failed to get clock\n"); + +- ret = pvt_clk_enable(dev, pvt); +- if (ret) { +- dev_err(dev, "failed to enable clock\n"); +- return ret; +- } +- + pvt->rst = devm_reset_control_get_optional_exclusive(dev, NULL); + if (IS_ERR(pvt->rst)) + return dev_err_probe(dev, PTR_ERR(pvt->rst), +-- +2.51.0 + diff --git a/queue-5.10/hwmon-mr75203-skip-reset-control-deassert-for-socs-t.patch b/queue-5.10/hwmon-mr75203-skip-reset-control-deassert-for-socs-t.patch new file mode 100644 index 0000000000..85050973c6 --- /dev/null +++ b/queue-5.10/hwmon-mr75203-skip-reset-control-deassert-for-socs-t.patch @@ -0,0 +1,54 @@ +From c6c2193ad57da00489f65f0109027deda72f4ba4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Sep 2022 15:24:37 +0000 +Subject: hwmon: (mr75203) skip reset-control deassert for SOCs that don't + support it + +From: Eliav Farber + +[ Upstream commit 493372f5d3df9905087a2ce9f8b5a2dca5af889f ] + +Don't fail the probe function and don't deassert the reset controller if +a "reset" property doesn't exist in the device tree. + +Change is done for SOCs that don't support a reset controller. + +Signed-off-by: Eliav Farber +Reviewed-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220908152449.35457-10-farbere@amazon.com +Signed-off-by: Guenter Roeck +Stable-dep-of: 813bbc4d33d2 ("hwmon: axi-fan: don't use driver_override as IRQ name") +Signed-off-by: Sasha Levin +--- + drivers/hwmon/mr75203.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/drivers/hwmon/mr75203.c b/drivers/hwmon/mr75203.c +index 41e3d3b54baff..19ec9fb912020 100644 +--- a/drivers/hwmon/mr75203.c ++++ b/drivers/hwmon/mr75203.c +@@ -551,14 +551,17 @@ static int mr75203_probe(struct platform_device *pdev) + return ret; + } + +- pvt->rst = devm_reset_control_get_exclusive(dev, NULL); ++ pvt->rst = devm_reset_control_get_optional_exclusive(dev, NULL); + if (IS_ERR(pvt->rst)) + return dev_err_probe(dev, PTR_ERR(pvt->rst), + "failed to get reset control\n"); + +- ret = pvt_reset_control_deassert(dev, pvt); +- if (ret) +- return dev_err_probe(dev, ret, "cannot deassert reset control\n"); ++ if (pvt->rst) { ++ ret = pvt_reset_control_deassert(dev, pvt); ++ if (ret) ++ return dev_err_probe(dev, ret, ++ "cannot deassert reset control\n"); ++ } + + ret = regmap_read(pvt->c_map, PVT_IP_CONFIG, &val); + if(ret < 0) +-- +2.51.0 + diff --git a/queue-5.10/nvme-pci-ensure-we-re-polling-a-polled-queue.patch b/queue-5.10/nvme-pci-ensure-we-re-polling-a-polled-queue.patch new file mode 100644 index 0000000000..d7803e461a --- /dev/null +++ b/queue-5.10/nvme-pci-ensure-we-re-polling-a-polled-queue.patch @@ -0,0 +1,39 @@ +From a19a55fb6d82ce55b3261400ff3727d4e281258b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 09:26:54 -0800 +Subject: nvme-pci: ensure we're polling a polled queue + +From: Keith Busch + +[ Upstream commit 166e31d7dbf6aa44829b98aa446bda5c9580f12a ] + +A user can change the polled queue count at run time. There's a brief +window during a reset where a hipri task may try to poll that queue +before the block layer has updated the queue maps, which would race with +the now interrupt driven queue and may cause double completions. + +Reviewed-by: Christoph Hellwig +Reviewed-by: Kanchan Joshi +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index fbf8961f69efa..03df42e613f0f 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1097,7 +1097,8 @@ static int nvme_poll(struct blk_mq_hw_ctx *hctx) + struct nvme_queue *nvmeq = hctx->driver_data; + bool found; + +- if (!nvme_cqe_pending(nvmeq)) ++ if (!test_bit(NVMEQ_POLLED, &nvmeq->flags) || ++ !nvme_cqe_pending(nvmeq)) + return 0; + + spin_lock(&nvmeq->cq_poll_lock); +-- +2.51.0 + diff --git a/queue-5.10/platform-x86-intel-hid-enable-5-button-array-on-thin.patch b/queue-5.10/platform-x86-intel-hid-enable-5-button-array-on-thin.patch new file mode 100644 index 0000000000..9e7b4eb999 --- /dev/null +++ b/queue-5.10/platform-x86-intel-hid-enable-5-button-array-on-thin.patch @@ -0,0 +1,52 @@ +From d56ca3b4d9b0ce8bce34d2a875c302319c865607 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 09:56:25 +0100 +Subject: platform/x86: intel-hid: Enable 5-button array on ThinkPad X1 Fold 16 + Gen 1 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Leif Skunberg + +[ Upstream commit b38d478dad79e61e8a65931021bdfd7a71741212 ] + +The Lenovo ThinkPad X1 Fold 16 Gen 1 has physical volume up/down +buttons that are handled through the intel-hid 5-button array +interface. The firmware does not advertise 5-button array support via +HEBC, so the driver relies on a DMI allowlist to enable it. + +Add the ThinkPad X1 Fold 16 Gen 1 to the button_array_table so the +volume buttons work out of the box. + +Signed-off-by: Leif Skunberg +Reviewed-by: Hans de Goede +Link: https://patch.msgid.link/20260210085625.34380-1-diamondback@cohunt.app +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/intel-hid.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/platform/x86/intel-hid.c b/drivers/platform/x86/intel-hid.c +index 9bc2652b15e71..12d695adf3f74 100644 +--- a/drivers/platform/x86/intel-hid.c ++++ b/drivers/platform/x86/intel-hid.c +@@ -93,6 +93,13 @@ static const struct dmi_system_id button_array_table[] = { + DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Tablet Gen 2"), + }, + }, ++ { ++ .ident = "Lenovo ThinkPad X1 Fold 16 Gen 1", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Fold 16 Gen 1"), ++ }, ++ }, + { + .ident = "Microsoft Surface Go 3", + .matches = { +-- +2.51.0 + diff --git a/queue-5.10/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch b/queue-5.10/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch new file mode 100644 index 0000000000..42ef4c83f0 --- /dev/null +++ b/queue-5.10/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch @@ -0,0 +1,71 @@ +From 2e1921ea62bc0644f2590f5a39f18ef91a7c148f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 14:23:46 +0100 +Subject: platform/x86: touchscreen_dmi: Add quirk for y-inverted Goodix + touchscreen on SUPI S10 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Hans de Goede + +[ Upstream commit 7d87ed70fc95482c12edf9493c249b6413be485e ] + +The touchscreen on the SUPI S10 tablet reports inverted Y coordinates, +causing touch input to be mirrored vertically relative to the display. + +Add a quirk to set the "touchscreen-inverted-y" boolean device-property +on the touchscreen device, so that the goodix_ts driver will fixup +the coordinates. + +Reported-by: Yajat Kumar +Closes: https://lore.kernel.org/linux-input/20251230221639.582406-1-yajatapps3@gmail.com/ +Tested-by: Yajat Kumar +Signed-off-by: Hans de Goede +Link: https://patch.msgid.link/20260217132346.34535-1-johannes.goede@oss.qualcomm.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/touchscreen_dmi.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c +index eff29dc7e2c6c..13ba93e7ed8f0 100644 +--- a/drivers/platform/x86/touchscreen_dmi.c ++++ b/drivers/platform/x86/touchscreen_dmi.c +@@ -402,6 +402,16 @@ static const struct ts_dmi_data gdix1002_00_upside_down_data = { + .properties = gdix1001_upside_down_props, + }; + ++static const struct property_entry gdix1001_y_inverted_props[] = { ++ PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), ++ { } ++}; ++ ++static const struct ts_dmi_data gdix1001_y_inverted_data = { ++ .acpi_name = "GDIX1001", ++ .properties = gdix1001_y_inverted_props, ++}; ++ + static const struct property_entry gp_electronic_t701_props[] = { + PROPERTY_ENTRY_U32("touchscreen-size-x", 960), + PROPERTY_ENTRY_U32("touchscreen-size-y", 640), +@@ -1552,6 +1562,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_SKU, "PN20170413488"), + }, + }, ++ { ++ /* SUPI S10 */ ++ .driver_data = (void *)&gdix1001_y_inverted_data, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "SUPI"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "S10"), ++ }, ++ }, + { + /* Techbite Arc 11.6 */ + .driver_data = (void *)&techbite_arc_11_6_data, +-- +2.51.0 + diff --git a/queue-5.10/series b/queue-5.10/series index afa198c2de..7481d2871a 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -236,3 +236,18 @@ tools-bootconfig-fix-fd-leak-in-load_xbc_file-on-fst.patch netfilter-nft_set_pipapo-split-gc-into-unlink-and-reclaim-phase.patch xen-privcmd-restrict-usage-in-unprivileged-domu.patch xen-privcmd-add-boot-control-for-restricted-usage-in-domu.patch +hwmon-mr75203-skip-reset-control-deassert-for-socs-t.patch +hwmon-make-use-of-devm_clk_get_enabled.patch +hwmon-axi-fan-control-use-device-firmware-agnostic-a.patch +hwmon-axi-fan-control-make-use-of-dev_err_probe.patch +hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch +sh-platform_early-remove-pdev-driver_override-check.patch +hid-asus-avoid-memory-leak-in-asus_report_fixup.patch +platform-x86-intel-hid-enable-5-button-array-on-thin.patch +platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch +nvme-pci-ensure-we-re-polling-a-polled-queue.patch +hid-mcp2221-cancel-last-i2c-command-on-read-error.patch +asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch +asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-25677 +dma-buf-include-ioctl.h-in-uapi-header.patch +alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch diff --git a/queue-5.10/sh-platform_early-remove-pdev-driver_override-check.patch b/queue-5.10/sh-platform_early-remove-pdev-driver_override-check.patch new file mode 100644 index 0000000000..1be6afc501 --- /dev/null +++ b/queue-5.10/sh-platform_early-remove-pdev-driver_override-check.patch @@ -0,0 +1,45 @@ +From e72635783783feef63e0f6d0da52f51de5460e12 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Mar 2026 00:37:15 +0100 +Subject: sh: platform_early: remove pdev->driver_override check + +From: Danilo Krummrich + +[ Upstream commit c5f60e3f07b6609562d21efda878e83ce8860728 ] + +In commit 507fd01d5333 ("drivers: move the early platform device support to +arch/sh") platform_match() was copied over to the sh platform_early +code, accidentally including the driver_override check. + +This check does not make sense for platform_early, as sysfs is not even +available in first place at this point in the boot process, hence remove +the check. + +Reviewed-by: Greg Kroah-Hartman +Reviewed-by: Geert Uytterhoeven +Fixes: 507fd01d5333 ("drivers: move the early platform device support to arch/sh") +Link: https://lore.kernel.org/all/DH4M3DJ4P58T.1BGVAVXN71Z09@kernel.org/ +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + arch/sh/drivers/platform_early.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c +index 143747c45206f..48ddbc547bd9a 100644 +--- a/arch/sh/drivers/platform_early.c ++++ b/arch/sh/drivers/platform_early.c +@@ -26,10 +26,6 @@ static int platform_match(struct device *dev, struct device_driver *drv) + struct platform_device *pdev = to_platform_device(dev); + struct platform_driver *pdrv = to_platform_driver(drv); + +- /* When driver_override is set, only bind to the matching driver */ +- if (pdev->driver_override) +- return !strcmp(pdev->driver_override, drv->name); +- + /* Then try to match against the id table */ + if (pdrv->id_table) + return platform_match_id(pdrv->id_table, pdev) != NULL; +-- +2.51.0 + diff --git a/queue-5.15/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch b/queue-5.15/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch new file mode 100644 index 0000000000..9f37e22c10 --- /dev/null +++ b/queue-5.15/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch @@ -0,0 +1,43 @@ +From 77bc236c072609d26e69c4a7d92577faa40465c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Mar 2026 06:29:06 +0500 +Subject: ALSA: hda/realtek: Add headset jack quirk for Thinkpad X390 + +From: Uzair Mughal + +[ Upstream commit 542127f6528ca7cc3cf61e1651d6ccb58495f953 ] + +The Lenovo ThinkPad X390 (ALC257 codec, subsystem ID 0x17aa2288) +does not report headset button press events. Headphone insertion is +detected (SW_HEADPHONE_INSERT), but pressing the inline microphone +button on a headset produces no input events. + +Add a SND_PCI_QUIRK entry that maps this subsystem ID to +ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, which enables +headset jack button detection through alc_fixup_headset_jack() +and ThinkPad ACPI integration. This is the same fixup used by +similar ThinkPad models (P1 Gen 3, X1 Extreme Gen 3). + +Signed-off-by: Uzair Mughal +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20260307012906.20093-1-contact@uzair.is-a.dev +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 72d9ea5171bbd..38fda5dbd75ba 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9608,6 +9608,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), + SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), + SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), ++ SND_PCI_QUIRK(0x17aa, 0x2288, "Thinkpad X390", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x22c1, "Thinkpad P1 Gen 3", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), +-- +2.51.0 + diff --git a/queue-5.15/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch b/queue-5.15/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch new file mode 100644 index 0000000000..ceef12e8b2 --- /dev/null +++ b/queue-5.15/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch @@ -0,0 +1,52 @@ +From c28a89ff830bf4a8a1045f0acac8b36807675585 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 00:25:38 +0000 +Subject: ASoC: fsl_easrc: Fix event generation in fsl_easrc_iec958_set_reg() + +From: Mark Brown + +[ Upstream commit 31ddc62c1cd92e51b9db61d7954b85ae2ec224da ] + +ALSA controls should return 1 if the value in the control changed but the +control put operation fsl_easrc_set_reg() only returns 0 or a negative +error code, causing ALSA to not generate any change events. Add a suitable +check by using regmap_update_bits_check() with the underlying regmap, this +is more clearly and simply correct than trying to verify that one of the +generic ops is exactly equivalent to this one. + +Signed-off-by: Mark Brown +Link: https://patch.msgid.link/20260205-asoc-fsl-easrc-fix-events-v1-2-39d4c766918b@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_easrc.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c +index c7ff48208d005..95ad4eeec4863 100644 +--- a/sound/soc/fsl/fsl_easrc.c ++++ b/sound/soc/fsl/fsl_easrc.c +@@ -93,14 +93,17 @@ static int fsl_easrc_set_reg(struct snd_kcontrol *kcontrol, + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_value; ++ struct fsl_asrc *easrc = snd_soc_component_get_drvdata(component); + unsigned int regval = ucontrol->value.integer.value[0]; ++ bool changed; + int ret; + +- ret = snd_soc_component_write(component, mc->regbase, regval); +- if (ret < 0) ++ ret = regmap_update_bits_check(easrc->regmap, mc->regbase, ++ GENMASK(31, 0), regval, &changed); ++ if (ret != 0) + return ret; + +- return 0; ++ return changed; + } + + #define SOC_SINGLE_REG_RW(xname, xreg) \ +-- +2.51.0 + diff --git a/queue-5.15/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-32526 b/queue-5.15/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-32526 new file mode 100644 index 0000000000..4cdd9055e8 --- /dev/null +++ b/queue-5.15/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-32526 @@ -0,0 +1,49 @@ +From 3c27e94c4100cee87f52f9a7ea0907976872df46 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 00:25:37 +0000 +Subject: ASoC: fsl_easrc: Fix event generation in fsl_easrc_iec958_put_bits() + +From: Mark Brown + +[ Upstream commit 54a86cf48eaa6d1ab5130d756b718775e81e1748 ] + +ALSA controls should return 1 if the value in the control changed but the +control put operation fsl_easrc_iec958_put_bits() unconditionally returns +0, causing ALSA to not generate any change events. This is detected by +mixer-test with large numbers of messages in the form: + + No event generated for Context 3 IEC958 CS5 + Context 3 IEC958 CS5.0 orig 5224 read 5225, is_volatile 0 + +Add a suitable check. + +Signed-off-by: Mark Brown +Link: https://patch.msgid.link/20260205-asoc-fsl-easrc-fix-events-v1-1-39d4c766918b@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_easrc.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c +index 95ad4eeec4863..84ef6758cc003 100644 +--- a/sound/soc/fsl/fsl_easrc.c ++++ b/sound/soc/fsl/fsl_easrc.c +@@ -52,10 +52,13 @@ static int fsl_easrc_iec958_put_bits(struct snd_kcontrol *kcontrol, + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_value; + unsigned int regval = ucontrol->value.integer.value[0]; ++ int ret; ++ ++ ret = (easrc_priv->bps_iec958[mc->regbase] != regval); + + easrc_priv->bps_iec958[mc->regbase] = regval; + +- return 0; ++ return ret; + } + + static int fsl_easrc_iec958_get_bits(struct snd_kcontrol *kcontrol, +-- +2.51.0 + diff --git a/queue-5.15/bpf-release-module-btf-idr-before-module-unload.patch b/queue-5.15/bpf-release-module-btf-idr-before-module-unload.patch new file mode 100644 index 0000000000..e7700c5adf --- /dev/null +++ b/queue-5.15/bpf-release-module-btf-idr-before-module-unload.patch @@ -0,0 +1,128 @@ +From 78d47abf3ec9484fc5b23c96073b5dd7fd757600 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Mar 2026 13:53:07 -0700 +Subject: bpf: Release module BTF IDR before module unload + +From: Kumar Kartikeya Dwivedi + +[ Upstream commit 146bd2a87a65aa407bb17fac70d8d583d19aba06 ] + +Gregory reported in [0] that the global_map_resize test when run in +repeatedly ends up failing during program load. This stems from the fact +that BTF reference has not dropped to zero after the previous run's +module is unloaded, and the older module's BTF is still discoverable and +visible. Later, in libbpf, load_module_btfs() will find the ID for this +stale BTF, open its fd, and then it will be used during program load +where later steps taking module reference using btf_try_get_module() +fail since the underlying module for the BTF is gone. + +Logically, once a module is unloaded, it's associated BTF artifacts +should become hidden. The BTF object inside the kernel may still remain +alive as long its reference counts are alive, but it should no longer be +discoverable. + +To fix this, let us call btf_free_id() from the MODULE_STATE_GOING case +for the module unload to free the BTF associated IDR entry, and disable +its discovery once module unload returns to user space. If a race +happens during unload, the outcome is non-deterministic anyway. However, +user space should be able to rely on the guarantee that once it has +synchronously established a successful module unload, no more stale +artifacts associated with this module can be obtained subsequently. + +Note that we must be careful to not invoke btf_free_id() in btf_put() +when btf_is_module() is true now. There could be a window where the +module unload drops a non-terminal reference, frees the IDR, but the +same ID gets reused and the second unconditional btf_free_id() ends up +releasing an unrelated entry. + +To avoid a special case for btf_is_module() case, set btf->id to zero to +make btf_free_id() idempotent, such that we can unconditionally invoke it +from btf_put(), and also from the MODULE_STATE_GOING case. Since zero is +an invalid IDR, the idr_remove() should be a noop. + +Note that we can be sure that by the time we reach final btf_put() for +btf_is_module() case, the btf_free_id() is already done, since the +module itself holds the BTF reference, and it will call this function +for the BTF before dropping its own reference. + + [0]: https://lore.kernel.org/bpf/cover.1773170190.git.grbell@redhat.com + +Fixes: 36e68442d1af ("bpf: Load and verify kernel module BTFs") +Acked-by: Martin KaFai Lau +Suggested-by: Martin KaFai Lau +Reported-by: Gregory Bell +Reviewed-by: Emil Tsalapatis +Signed-off-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20260312205307.1346991-1-memxor@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/btf.c | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c +index d3eb75bfd9718..5d87df80c4bd7 100644 +--- a/kernel/bpf/btf.c ++++ b/kernel/bpf/btf.c +@@ -1501,7 +1501,16 @@ static void btf_free_id(struct btf *btf) + * of the _bh() version. + */ + spin_lock_irqsave(&btf_idr_lock, flags); +- idr_remove(&btf_idr, btf->id); ++ if (btf->id) { ++ idr_remove(&btf_idr, btf->id); ++ /* ++ * Clear the id here to make this function idempotent, since it will get ++ * called a couple of times for module BTFs: on module unload, and then ++ * the final btf_put(). btf_alloc_id() starts IDs with 1, so we can use ++ * 0 as sentinel value. ++ */ ++ WRITE_ONCE(btf->id, 0); ++ } + spin_unlock_irqrestore(&btf_idr_lock, flags); + } + +@@ -5890,7 +5899,7 @@ static void bpf_btf_show_fdinfo(struct seq_file *m, struct file *filp) + { + const struct btf *btf = filp->private_data; + +- seq_printf(m, "btf_id:\t%u\n", btf->id); ++ seq_printf(m, "btf_id:\t%u\n", READ_ONCE(btf->id)); + } + #endif + +@@ -5985,7 +5994,7 @@ int btf_get_info_by_fd(const struct btf *btf, + if (copy_from_user(&info, uinfo, info_copy)) + return -EFAULT; + +- info.id = btf->id; ++ info.id = READ_ONCE(btf->id); + ubtf = u64_to_user_ptr(info.btf); + btf_copy = min_t(u32, btf->data_size, info.btf_size); + if (copy_to_user(ubtf, btf->data, btf_copy)) +@@ -6048,7 +6057,7 @@ int btf_get_fd_by_id(u32 id) + + u32 btf_obj_id(const struct btf *btf) + { +- return btf->id; ++ return READ_ONCE(btf->id); + } + + bool btf_is_kernel(const struct btf *btf) +@@ -6185,6 +6194,13 @@ static int btf_module_notify(struct notifier_block *nb, unsigned long op, + if (btf_mod->module != module) + continue; + ++ /* ++ * For modules, we do the freeing of BTF IDR as soon as ++ * module goes away to disable BTF discovery, since the ++ * btf_try_get_module() on such BTFs will fail. This may ++ * be called again on btf_put(), but it's ok to do so. ++ */ ++ btf_free_id(btf_mod->btf); + list_del(&btf_mod->list); + if (btf_mod->sysfs_attr) + sysfs_remove_bin_file(btf_kobj, btf_mod->sysfs_attr); +-- +2.51.0 + diff --git a/queue-5.15/dma-buf-include-ioctl.h-in-uapi-header.patch b/queue-5.15/dma-buf-include-ioctl.h-in-uapi-header.patch new file mode 100644 index 0000000000..4c889474de --- /dev/null +++ b/queue-5.15/dma-buf-include-ioctl.h-in-uapi-header.patch @@ -0,0 +1,44 @@ +From 328b7b6abc5ae9dba4016f349065055e21af0912 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Mar 2026 16:23:09 -0800 +Subject: dma-buf: Include ioctl.h in UAPI header +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Isaac J. Manjarres + +[ Upstream commit a116bac87118903925108e57781bbfc7a7eea27b ] + +include/uapi/linux/dma-buf.h uses several macros from ioctl.h to define +its ioctl commands. However, it does not include ioctl.h itself. So, +if userspace source code tries to include the dma-buf.h file without +including ioctl.h, it can result in build failures. + +Therefore, include ioctl.h in the dma-buf UAPI header. + +Signed-off-by: Isaac J. Manjarres +Reviewed-by: T.J. Mercier +Reviewed-by: Christian König +Signed-off-by: Christian König +Link: https://lore.kernel.org/r/20260303002309.1401849-1-isaacmanjarres@google.com +Signed-off-by: Sasha Levin +--- + include/uapi/linux/dma-buf.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h +index b1523cb8ab307..5e2b1949ffd49 100644 +--- a/include/uapi/linux/dma-buf.h ++++ b/include/uapi/linux/dma-buf.h +@@ -20,6 +20,7 @@ + #ifndef _DMA_BUF_UAPI_H_ + #define _DMA_BUF_UAPI_H_ + ++#include + #include + + /** +-- +2.51.0 + diff --git a/queue-5.15/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch b/queue-5.15/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch new file mode 100644 index 0000000000..3739ef5ec6 --- /dev/null +++ b/queue-5.15/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch @@ -0,0 +1,65 @@ +From c188aeb03972c5bc69bbd5972e8de15174fb9ff4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Feb 2026 16:43:38 +0100 +Subject: HID: asus: avoid memory leak in asus_report_fixup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Günther Noack + +[ Upstream commit 2bad24c17742fc88973d6aea526ce1353f5334a3 ] + +The asus_report_fixup() function was returning a newly allocated +kmemdup()-allocated buffer, but never freeing it. Switch to +devm_kzalloc() to ensure the memory is managed and freed automatically +when the device is removed. + +The caller of report_fixup() does not take ownership of the returned +pointer, but it is permitted to return a pointer whose lifetime is at +least that of the input buffer. + +Also fix a harmless out-of-bounds read by copying only the original +descriptor size. + +Assisted-by: Gemini-CLI:Google Gemini 3 +Signed-off-by: Günther Noack +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-asus.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index feec0724328ff..3be17a8b7a293 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -1224,14 +1224,21 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, + */ + if (*rsize == rsize_orig && + rdesc[offs] == 0x09 && rdesc[offs + 1] == 0x76) { +- *rsize = rsize_orig + 1; +- rdesc = kmemdup(rdesc, *rsize, GFP_KERNEL); +- if (!rdesc) +- return NULL; ++ __u8 *new_rdesc; ++ ++ new_rdesc = devm_kzalloc(&hdev->dev, rsize_orig + 1, ++ GFP_KERNEL); ++ if (!new_rdesc) ++ return rdesc; + + hid_info(hdev, "Fixing up %s keyb report descriptor\n", + drvdata->quirks & QUIRK_T100CHI ? + "T100CHI" : "T90CHI"); ++ ++ memcpy(new_rdesc, rdesc, rsize_orig); ++ *rsize = rsize_orig + 1; ++ rdesc = new_rdesc; ++ + memmove(rdesc + offs + 4, rdesc + offs + 2, 12); + rdesc[offs] = 0x19; + rdesc[offs + 1] = 0x00; +-- +2.51.0 + diff --git a/queue-5.15/hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch b/queue-5.15/hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch new file mode 100644 index 0000000000..822c510146 --- /dev/null +++ b/queue-5.15/hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch @@ -0,0 +1,45 @@ +From 31536b04f3fd930b801f9139e50e610000202f99 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Feb 2026 16:43:37 +0100 +Subject: HID: magicmouse: avoid memory leak in magicmouse_report_fixup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Günther Noack + +[ Upstream commit 91e8c6e601bdc1ccdf886479b6513c01c7e51c2c ] + +The magicmouse_report_fixup() function was returning a +newly kmemdup()-allocated buffer, but never freeing it. + +The caller of report_fixup() does not take ownership of the returned +pointer, but it *is* permitted to return a sub-portion of the input +rdesc, whose lifetime is managed by the caller. + +Assisted-by: Gemini-CLI:Google Gemini 3 +Signed-off-by: Günther Noack +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-magicmouse.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index df5809cd4b637..2eda56779b4c4 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -934,9 +934,7 @@ static __u8 *magicmouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, + hid_info(hdev, + "fixing up magicmouse battery report descriptor\n"); + *rsize = *rsize - 1; +- rdesc = kmemdup(rdesc + 1, *rsize, GFP_KERNEL); +- if (!rdesc) +- return NULL; ++ rdesc = rdesc + 1; + + rdesc[0] = 0x05; + rdesc[1] = 0x01; +-- +2.51.0 + diff --git a/queue-5.15/hid-magicmouse-fix-battery-reporting-for-apple-magic.patch b/queue-5.15/hid-magicmouse-fix-battery-reporting-for-apple-magic.patch new file mode 100644 index 0000000000..9de3d75ffa --- /dev/null +++ b/queue-5.15/hid-magicmouse-fix-battery-reporting-for-apple-magic.patch @@ -0,0 +1,41 @@ +From 4684f4d002ce9c97a90f30e04a3c2298d3736cf5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Feb 2026 20:34:21 +0100 +Subject: HID: magicmouse: fix battery reporting for Apple Magic Trackpad 2 + +From: Julius Lehmann + +[ Upstream commit 5f3518d77419255f8b12bb23c8ec22acbeb6bc5b ] + +Battery reporting does not work for the Apple Magic Trackpad 2 if it is +connected via USB. The current hid descriptor fixup code checks for a +hid descriptor length of exactly 83 bytes. If the hid descriptor is +larger, which is the case for newer apple mice, the fixup is not +applied. + +This fix checks for hid descriptor sizes greater/equal 83 bytes which +applies the fixup for newer devices as well. + +Signed-off-by: Julius Lehmann +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-magicmouse.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index ec7b4f7b3d8c9..df5809cd4b637 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -930,7 +930,7 @@ static __u8 *magicmouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, + */ + if ((is_usb_magicmouse2(hdev->vendor, hdev->product) || + is_usb_magictrackpad2(hdev->vendor, hdev->product)) && +- *rsize == 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) { ++ *rsize >= 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) { + hid_info(hdev, + "fixing up magicmouse battery report descriptor\n"); + *rsize = *rsize - 1; +-- +2.51.0 + diff --git a/queue-5.15/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch b/queue-5.15/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch new file mode 100644 index 0000000000..48537fb8d0 --- /dev/null +++ b/queue-5.15/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch @@ -0,0 +1,41 @@ +From 9c9747f67a6ad86ecf23484a2d0cf92dd86d6f38 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 17:32:58 +0100 +Subject: HID: mcp2221: cancel last I2C command on read error + +From: Romain Sioen + +[ Upstream commit e31b556c0ba21f20c298aa61181b96541140b7b9 ] + +When an I2C SMBus read operation fails, the MCP2221 internal state machine +may not reset correctly, causing subsequent transactions to fail. + +By adding a short delay and explicitly cancelling the last command, +we ensure the device is ready for the next operation. + +Fix an issue where i2cdetect was not able to detect all devices correctly +on the bus. + +Signed-off-by: Romain Sioen +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-mcp2221.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c +index 589f13ff0b606..9fb98c8e1ffb7 100644 +--- a/drivers/hid/hid-mcp2221.c ++++ b/drivers/hid/hid-mcp2221.c +@@ -319,6 +319,8 @@ static int mcp_i2c_smbus_read(struct mcp2221 *mcp, + usleep_range(90, 100); + retries++; + } else { ++ usleep_range(980, 1000); ++ mcp_cancel_last_cmd(mcp); + return ret; + } + } else { +-- +2.51.0 + diff --git a/queue-5.15/hwmon-axi-fan-control-make-use-of-dev_err_probe.patch b/queue-5.15/hwmon-axi-fan-control-make-use-of-dev_err_probe.patch new file mode 100644 index 0000000000..2f9d03ba21 --- /dev/null +++ b/queue-5.15/hwmon-axi-fan-control-make-use-of-dev_err_probe.patch @@ -0,0 +1,91 @@ +From f699df3cc124ad390c4c8cb4b08ad7314c9806b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Feb 2024 15:36:45 +0100 +Subject: hwmon: (axi-fan-control) Make use of dev_err_probe() + +From: Nuno Sa + +[ Upstream commit ec823656c1e0e5f49e92ed86cee9fb26585da18e ] + +Use dev_err_probe() to slightly simplify printing errors during probe. +No functional changes intended. + +Signed-off-by: Nuno Sa +Link: https://lore.kernel.org/r/20240214-axi-fan-control-no-of-v1-3-43ca656fe2e3@analog.com +Signed-off-by: Guenter Roeck +Stable-dep-of: 813bbc4d33d2 ("hwmon: axi-fan: don't use driver_override as IRQ name") +Signed-off-by: Sasha Levin +--- + drivers/hwmon/axi-fan-control.c | 40 +++++++++++++++------------------ + 1 file changed, 18 insertions(+), 22 deletions(-) + +diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c +index 49ef395eab7ad..61f24ef470728 100644 +--- a/drivers/hwmon/axi-fan-control.c ++++ b/drivers/hwmon/axi-fan-control.c +@@ -465,10 +465,9 @@ static int axi_fan_control_probe(struct platform_device *pdev) + return PTR_ERR(ctl->base); + + clk = devm_clk_get_enabled(&pdev->dev, NULL); +- if (IS_ERR(clk)) { +- dev_err(&pdev->dev, "clk_get failed with %ld\n", PTR_ERR(clk)); +- return PTR_ERR(clk); +- } ++ if (IS_ERR(clk)) ++ return dev_err_probe(&pdev->dev, PTR_ERR(clk), ++ "clk_get failed\n"); + + ctl->clk_rate = clk_get_rate(clk); + if (!ctl->clk_rate) +@@ -476,22 +475,20 @@ static int axi_fan_control_probe(struct platform_device *pdev) + + version = axi_ioread(ADI_AXI_REG_VERSION, ctl); + if (ADI_AXI_PCORE_VER_MAJOR(version) != +- ADI_AXI_PCORE_VER_MAJOR((*id))) { +- dev_err(&pdev->dev, "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", +- ADI_AXI_PCORE_VER_MAJOR(*id), +- ADI_AXI_PCORE_VER_MINOR(*id), +- ADI_AXI_PCORE_VER_PATCH(*id), +- ADI_AXI_PCORE_VER_MAJOR(version), +- ADI_AXI_PCORE_VER_MINOR(version), +- ADI_AXI_PCORE_VER_PATCH(version)); +- return -ENODEV; +- } ++ ADI_AXI_PCORE_VER_MAJOR((*id))) ++ return dev_err_probe(&pdev->dev, -ENODEV, ++ "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", ++ ADI_AXI_PCORE_VER_MAJOR(*id), ++ ADI_AXI_PCORE_VER_MINOR(*id), ++ ADI_AXI_PCORE_VER_PATCH(*id), ++ ADI_AXI_PCORE_VER_MAJOR(version), ++ ADI_AXI_PCORE_VER_MINOR(version), ++ ADI_AXI_PCORE_VER_PATCH(version)); + + ret = axi_fan_control_init(ctl, &pdev->dev); +- if (ret) { +- dev_err(&pdev->dev, "Failed to initialize device\n"); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(&pdev->dev, ret, ++ "Failed to initialize device\n"); + + ctl->hdev = devm_hwmon_device_register_with_info(&pdev->dev, + name, +@@ -510,10 +507,9 @@ static int axi_fan_control_probe(struct platform_device *pdev) + axi_fan_control_irq_handler, + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, + pdev->driver_override, ctl); +- if (ret) { +- dev_err(&pdev->dev, "failed to request an irq, %d", ret); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(&pdev->dev, ret, ++ "failed to request an irq\n"); + + return 0; + } +-- +2.51.0 + diff --git a/queue-5.15/hwmon-axi-fan-control-use-device-firmware-agnostic-a.patch b/queue-5.15/hwmon-axi-fan-control-use-device-firmware-agnostic-a.patch new file mode 100644 index 0000000000..c045a97cdd --- /dev/null +++ b/queue-5.15/hwmon-axi-fan-control-use-device-firmware-agnostic-a.patch @@ -0,0 +1,126 @@ +From 50f8eeb34216ce58cbbe31107f9b73fed952609d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Feb 2024 15:36:43 +0100 +Subject: hwmon: (axi-fan-control) Use device firmware agnostic API + +From: Nuno Sa + +[ Upstream commit 1b5239f70fcd2d7fe86f0f5473006c2896db07a8 ] + +Don't directly use OF and use device property APIs. In addition, this +makes the probe() code neater and also allow us to move the +of_device_id table to it's natural place. + +While at it, make sure to explicitly include mod_devicetable.h for the +of_device_id table. + +Signed-off-by: Nuno Sa +Link: https://lore.kernel.org/r/20240214-axi-fan-control-no-of-v1-1-43ca656fe2e3@analog.com +Signed-off-by: Guenter Roeck +Stable-dep-of: 813bbc4d33d2 ("hwmon: axi-fan: don't use driver_override as IRQ name") +Signed-off-by: Sasha Levin +--- + drivers/hwmon/axi-fan-control.c | 39 +++++++++++++++++---------------- + 1 file changed, 20 insertions(+), 19 deletions(-) + +diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c +index 8ed141f0d4a6b..49ef395eab7ad 100644 +--- a/drivers/hwmon/axi-fan-control.c ++++ b/drivers/hwmon/axi-fan-control.c +@@ -13,8 +13,9 @@ + #include + #include + #include +-#include ++#include + #include ++#include + + /* register map */ + #define ADI_REG_RSTN 0x0080 +@@ -367,12 +368,12 @@ static irqreturn_t axi_fan_control_irq_handler(int irq, void *data) + } + + static int axi_fan_control_init(struct axi_fan_control_data *ctl, +- const struct device_node *np) ++ const struct device *dev) + { + int ret; + + /* get fan pulses per revolution */ +- ret = of_property_read_u32(np, "pulses-per-revolution", &ctl->ppr); ++ ret = device_property_read_u32(dev, "pulses-per-revolution", &ctl->ppr); + if (ret) + return ret; + +@@ -442,25 +443,16 @@ static struct attribute *axi_fan_control_attrs[] = { + }; + ATTRIBUTE_GROUPS(axi_fan_control); + +-static const u32 version_1_0_0 = ADI_AXI_PCORE_VER(1, 0, 'a'); +- +-static const struct of_device_id axi_fan_control_of_match[] = { +- { .compatible = "adi,axi-fan-control-1.00.a", +- .data = (void *)&version_1_0_0}, +- {}, +-}; +-MODULE_DEVICE_TABLE(of, axi_fan_control_of_match); +- + static int axi_fan_control_probe(struct platform_device *pdev) + { + struct axi_fan_control_data *ctl; + struct clk *clk; +- const struct of_device_id *id; ++ const unsigned int *id; + const char *name = "axi_fan_control"; + u32 version; + int ret; + +- id = of_match_node(axi_fan_control_of_match, pdev->dev.of_node); ++ id = device_get_match_data(&pdev->dev); + if (!id) + return -EINVAL; + +@@ -484,18 +476,18 @@ static int axi_fan_control_probe(struct platform_device *pdev) + + version = axi_ioread(ADI_AXI_REG_VERSION, ctl); + if (ADI_AXI_PCORE_VER_MAJOR(version) != +- ADI_AXI_PCORE_VER_MAJOR((*(u32 *)id->data))) { ++ ADI_AXI_PCORE_VER_MAJOR((*id))) { + dev_err(&pdev->dev, "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", +- ADI_AXI_PCORE_VER_MAJOR((*(u32 *)id->data)), +- ADI_AXI_PCORE_VER_MINOR((*(u32 *)id->data)), +- ADI_AXI_PCORE_VER_PATCH((*(u32 *)id->data)), ++ ADI_AXI_PCORE_VER_MAJOR(*id), ++ ADI_AXI_PCORE_VER_MINOR(*id), ++ ADI_AXI_PCORE_VER_PATCH(*id), + ADI_AXI_PCORE_VER_MAJOR(version), + ADI_AXI_PCORE_VER_MINOR(version), + ADI_AXI_PCORE_VER_PATCH(version)); + return -ENODEV; + } + +- ret = axi_fan_control_init(ctl, pdev->dev.of_node); ++ ret = axi_fan_control_init(ctl, &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "Failed to initialize device\n"); + return ret; +@@ -526,6 +518,15 @@ static int axi_fan_control_probe(struct platform_device *pdev) + return 0; + } + ++static const u32 version_1_0_0 = ADI_AXI_PCORE_VER(1, 0, 'a'); ++ ++static const struct of_device_id axi_fan_control_of_match[] = { ++ { .compatible = "adi,axi-fan-control-1.00.a", ++ .data = (void *)&version_1_0_0}, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, axi_fan_control_of_match); ++ + static struct platform_driver axi_fan_control_driver = { + .driver = { + .name = "axi_fan_control_driver", +-- +2.51.0 + diff --git a/queue-5.15/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch b/queue-5.15/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch new file mode 100644 index 0000000000..ec793cb1c3 --- /dev/null +++ b/queue-5.15/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch @@ -0,0 +1,43 @@ +From 10da045f0b20ab7427f4bcee70ba7648196feb22 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Mar 2026 12:53:20 +0100 +Subject: hwmon: axi-fan: don't use driver_override as IRQ name +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Danilo Krummrich + +[ Upstream commit 813bbc4d33d2ca5b0da63e70ae13b60874f20d37 ] + +Do not use driver_override as IRQ name, as it is not guaranteed to point +to a valid string; use NULL instead (which makes the devm IRQ helpers +use dev_name()). + +Fixes: 8412b410fa5e ("hwmon: Support ADI Fan Control IP") +Reviewed-by: Nuno Sá +Acked-by: Guenter Roeck +Reviewed-by: Greg Kroah-Hartman +Link: https://patch.msgid.link/20260303115720.48783-4-dakr@kernel.org +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + drivers/hwmon/axi-fan-control.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c +index 61f24ef470728..ef51d05b4eb61 100644 +--- a/drivers/hwmon/axi-fan-control.c ++++ b/drivers/hwmon/axi-fan-control.c +@@ -506,7 +506,7 @@ static int axi_fan_control_probe(struct platform_device *pdev) + ret = devm_request_threaded_irq(&pdev->dev, ctl->irq, NULL, + axi_fan_control_irq_handler, + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, +- pdev->driver_override, ctl); ++ NULL, ctl); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "failed to request an irq\n"); +-- +2.51.0 + diff --git a/queue-5.15/hwmon-make-use-of-devm_clk_get_enabled.patch b/queue-5.15/hwmon-make-use-of-devm_clk_get_enabled.patch new file mode 100644 index 0000000000..b6e362c56e --- /dev/null +++ b/queue-5.15/hwmon-make-use-of-devm_clk_get_enabled.patch @@ -0,0 +1,158 @@ +From 705f03a3e0f866fd4fe28453e8b0386389331f9f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 Aug 2022 08:06:40 +0200 +Subject: hwmon: Make use of devm_clk_get_enabled() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit 0dee25ebc7d315d9ee785ea5f457ae980979ea89 ] + +Several drivers manually register a devm handler to disable their clk. +Convert them to devm_clk_get_enabled(). + +Acked-by: Guenter Roeck +Reviewed-by: Nuno Sá +Acked-by: Jonathan Cameron +Signed-off-by: Uwe Kleine-König +Signed-off-by: Guenter Roeck +Stable-dep-of: 813bbc4d33d2 ("hwmon: axi-fan: don't use driver_override as IRQ name") +Signed-off-by: Sasha Levin +--- + drivers/hwmon/axi-fan-control.c | 15 +-------------- + drivers/hwmon/ltc2947-core.c | 17 +---------------- + drivers/hwmon/mr75203.c | 26 +------------------------- + 3 files changed, 3 insertions(+), 55 deletions(-) + +diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c +index 7af18018a32ff..8ed141f0d4a6b 100644 +--- a/drivers/hwmon/axi-fan-control.c ++++ b/drivers/hwmon/axi-fan-control.c +@@ -393,11 +393,6 @@ static int axi_fan_control_init(struct axi_fan_control_data *ctl, + return ret; + } + +-static void axi_fan_control_clk_disable(void *clk) +-{ +- clk_disable_unprepare(clk); +-} +- + static const struct hwmon_channel_info *axi_fan_control_info[] = { + HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT), + HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT | HWMON_F_FAULT | HWMON_F_LABEL), +@@ -477,20 +472,12 @@ static int axi_fan_control_probe(struct platform_device *pdev) + if (IS_ERR(ctl->base)) + return PTR_ERR(ctl->base); + +- clk = devm_clk_get(&pdev->dev, NULL); ++ clk = devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "clk_get failed with %ld\n", PTR_ERR(clk)); + return PTR_ERR(clk); + } + +- ret = clk_prepare_enable(clk); +- if (ret) +- return ret; +- +- ret = devm_add_action_or_reset(&pdev->dev, axi_fan_control_clk_disable, clk); +- if (ret) +- return ret; +- + ctl->clk_rate = clk_get_rate(clk); + if (!ctl->clk_rate) + return -EINVAL; +diff --git a/drivers/hwmon/ltc2947-core.c b/drivers/hwmon/ltc2947-core.c +index e918490f3ff75..f752701818192 100644 +--- a/drivers/hwmon/ltc2947-core.c ++++ b/drivers/hwmon/ltc2947-core.c +@@ -956,13 +956,6 @@ static struct attribute *ltc2947_attrs[] = { + }; + ATTRIBUTE_GROUPS(ltc2947); + +-static void ltc2947_clk_disable(void *data) +-{ +- struct clk *extclk = data; +- +- clk_disable_unprepare(extclk); +-} +- + static int ltc2947_setup(struct ltc2947_data *st) + { + int ret; +@@ -989,7 +982,7 @@ static int ltc2947_setup(struct ltc2947_data *st) + return ret; + + /* check external clock presence */ +- extclk = devm_clk_get_optional(st->dev, NULL); ++ extclk = devm_clk_get_optional_enabled(st->dev, NULL); + if (IS_ERR(extclk)) + return dev_err_probe(st->dev, PTR_ERR(extclk), + "Failed to get external clock\n"); +@@ -1007,14 +1000,6 @@ static int ltc2947_setup(struct ltc2947_data *st) + return -EINVAL; + } + +- ret = clk_prepare_enable(extclk); +- if (ret) +- return ret; +- +- ret = devm_add_action_or_reset(st->dev, ltc2947_clk_disable, +- extclk); +- if (ret) +- return ret; + /* as in table 1 of the datasheet */ + if (rate_hz >= LTC2947_CLK_MIN && rate_hz <= 1000000) + pre = 0; +diff --git a/drivers/hwmon/mr75203.c b/drivers/hwmon/mr75203.c +index 15ae3f4336340..71087741e27e2 100644 +--- a/drivers/hwmon/mr75203.c ++++ b/drivers/hwmon/mr75203.c +@@ -487,24 +487,6 @@ static int pvt_get_regmap(struct platform_device *pdev, char *reg_name, + return 0; + } + +-static void pvt_clk_disable(void *data) +-{ +- struct pvt_device *pvt = data; +- +- clk_disable_unprepare(pvt->clk); +-} +- +-static int pvt_clk_enable(struct device *dev, struct pvt_device *pvt) +-{ +- int ret; +- +- ret = clk_prepare_enable(pvt->clk); +- if (ret) +- return ret; +- +- return devm_add_action_or_reset(dev, pvt_clk_disable, pvt); +-} +- + static void pvt_reset_control_assert(void *data) + { + struct pvt_device *pvt = data; +@@ -541,16 +523,10 @@ static int mr75203_probe(struct platform_device *pdev) + if (ret) + return ret; + +- pvt->clk = devm_clk_get(dev, NULL); ++ pvt->clk = devm_clk_get_enabled(dev, NULL); + if (IS_ERR(pvt->clk)) + return dev_err_probe(dev, PTR_ERR(pvt->clk), "failed to get clock\n"); + +- ret = pvt_clk_enable(dev, pvt); +- if (ret) { +- dev_err(dev, "failed to enable clock\n"); +- return ret; +- } +- + pvt->rst = devm_reset_control_get_optional_exclusive(dev, NULL); + if (IS_ERR(pvt->rst)) + return dev_err_probe(dev, PTR_ERR(pvt->rst), +-- +2.51.0 + diff --git a/queue-5.15/hwmon-mr75203-skip-reset-control-deassert-for-socs-t.patch b/queue-5.15/hwmon-mr75203-skip-reset-control-deassert-for-socs-t.patch new file mode 100644 index 0000000000..68e6d716b6 --- /dev/null +++ b/queue-5.15/hwmon-mr75203-skip-reset-control-deassert-for-socs-t.patch @@ -0,0 +1,54 @@ +From 228b6e37686c3fa3421136d4a7b3f5b237885501 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Sep 2022 15:24:37 +0000 +Subject: hwmon: (mr75203) skip reset-control deassert for SOCs that don't + support it + +From: Eliav Farber + +[ Upstream commit 493372f5d3df9905087a2ce9f8b5a2dca5af889f ] + +Don't fail the probe function and don't deassert the reset controller if +a "reset" property doesn't exist in the device tree. + +Change is done for SOCs that don't support a reset controller. + +Signed-off-by: Eliav Farber +Reviewed-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220908152449.35457-10-farbere@amazon.com +Signed-off-by: Guenter Roeck +Stable-dep-of: 813bbc4d33d2 ("hwmon: axi-fan: don't use driver_override as IRQ name") +Signed-off-by: Sasha Levin +--- + drivers/hwmon/mr75203.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/drivers/hwmon/mr75203.c b/drivers/hwmon/mr75203.c +index 05da83841536f..15ae3f4336340 100644 +--- a/drivers/hwmon/mr75203.c ++++ b/drivers/hwmon/mr75203.c +@@ -551,14 +551,17 @@ static int mr75203_probe(struct platform_device *pdev) + return ret; + } + +- pvt->rst = devm_reset_control_get_exclusive(dev, NULL); ++ pvt->rst = devm_reset_control_get_optional_exclusive(dev, NULL); + if (IS_ERR(pvt->rst)) + return dev_err_probe(dev, PTR_ERR(pvt->rst), + "failed to get reset control\n"); + +- ret = pvt_reset_control_deassert(dev, pvt); +- if (ret) +- return dev_err_probe(dev, ret, "cannot deassert reset control\n"); ++ if (pvt->rst) { ++ ret = pvt_reset_control_deassert(dev, pvt); ++ if (ret) ++ return dev_err_probe(dev, ret, ++ "cannot deassert reset control\n"); ++ } + + ret = regmap_read(pvt->c_map, PVT_IP_CONFIG, &val); + if(ret < 0) +-- +2.51.0 + diff --git a/queue-5.15/module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch b/queue-5.15/module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch new file mode 100644 index 0000000000..56ddda911d --- /dev/null +++ b/queue-5.15/module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch @@ -0,0 +1,80 @@ +From 70e0ea37f42fbd2dbf4ec7d9b5dc710afc1573a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Dec 2025 10:32:08 -0800 +Subject: module: Fix kernel panic when a symbol st_shndx is out of bounds + +From: Ihor Solodrai + +[ Upstream commit f9d69d5e7bde2295eb7488a56f094ac8f5383b92 ] + +The module loader doesn't check for bounds of the ELF section index in +simplify_symbols(): + + for (i = 1; i < symsec->sh_size / sizeof(Elf_Sym); i++) { + const char *name = info->strtab + sym[i].st_name; + + switch (sym[i].st_shndx) { + case SHN_COMMON: + + [...] + + default: + /* Divert to percpu allocation if a percpu var. */ + if (sym[i].st_shndx == info->index.pcpu) + secbase = (unsigned long)mod_percpu(mod); + else + /** HERE --> **/ secbase = info->sechdrs[sym[i].st_shndx].sh_addr; + sym[i].st_value += secbase; + break; + } + } + +A symbol with an out-of-bounds st_shndx value, for example 0xffff +(known as SHN_XINDEX or SHN_HIRESERVE), may cause a kernel panic: + + BUG: unable to handle page fault for address: ... + RIP: 0010:simplify_symbols+0x2b2/0x480 + ... + Kernel panic - not syncing: Fatal exception + +This can happen when module ELF is legitimately using SHN_XINDEX or +when it is corrupted. + +Add a bounds check in simplify_symbols() to validate that st_shndx is +within the valid range before using it. + +This issue was discovered due to a bug in llvm-objcopy, see relevant +discussion for details [1]. + +[1] https://lore.kernel.org/linux-modules/20251224005752.201911-1-ihor.solodrai@linux.dev/ + +Signed-off-by: Ihor Solodrai +Reviewed-by: Daniel Gomez +Reviewed-by: Petr Pavlu +Signed-off-by: Sami Tolvanen +Signed-off-by: Sasha Levin +--- + kernel/module.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/kernel/module.c b/kernel/module.c +index 2226b591b52e0..07fa34461fa2f 100644 +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -2347,6 +2347,13 @@ static int simplify_symbols(struct module *mod, const struct load_info *info) + break; + + default: ++ if (sym[i].st_shndx >= info->hdr->e_shnum) { ++ pr_err("%s: Symbol %s has an invalid section index %u (max %u)\n", ++ mod->name, name, sym[i].st_shndx, info->hdr->e_shnum - 1); ++ ret = -ENOEXEC; ++ break; ++ } ++ + /* Divert to percpu allocation if a percpu var. */ + if (sym[i].st_shndx == info->index.pcpu) + secbase = (unsigned long)mod_percpu(mod); +-- +2.51.0 + diff --git a/queue-5.15/net-usb-r8152-add-trendnet-tuc-et2g.patch b/queue-5.15/net-usb-r8152-add-trendnet-tuc-et2g.patch new file mode 100644 index 0000000000..3038bf8642 --- /dev/null +++ b/queue-5.15/net-usb-r8152-add-trendnet-tuc-et2g.patch @@ -0,0 +1,48 @@ +From cedb858b7cb1b9e178e1e5037ce62b9c1f3daa56 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Feb 2026 20:54:09 +0100 +Subject: net: usb: r8152: add TRENDnet TUC-ET2G + +From: Valentin Spreckels + +[ Upstream commit 15fba71533bcdfaa8eeba69a5a5a2927afdf664a ] + +The TRENDnet TUC-ET2G is a RTL8156 based usb ethernet adapter. Add its +vendor and product IDs. + +Signed-off-by: Valentin Spreckels +Link: https://patch.msgid.link/20260226195409.7891-2-valentin@spreckels.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/usb/r8152.c | 1 + + include/linux/usb/r8152.h | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c +index e70f3cb8bad94..59baa673738b6 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -9857,6 +9857,7 @@ static const struct usb_device_id rtl8152_table[] = { + { USB_DEVICE(VENDOR_ID_DLINK, 0xb301) }, + { USB_DEVICE(VENDOR_ID_DELL, 0xb097) }, + { USB_DEVICE(VENDOR_ID_ASUS, 0x1976) }, ++ { USB_DEVICE(VENDOR_ID_TRENDNET, 0xe02b) }, + {} + }; + +diff --git a/include/linux/usb/r8152.h b/include/linux/usb/r8152.h +index 2ca60828f28bb..1502b2a355f98 100644 +--- a/include/linux/usb/r8152.h ++++ b/include/linux/usb/r8152.h +@@ -32,6 +32,7 @@ + #define VENDOR_ID_DLINK 0x2001 + #define VENDOR_ID_DELL 0x413c + #define VENDOR_ID_ASUS 0x0b05 ++#define VENDOR_ID_TRENDNET 0x20f4 + + #if IS_REACHABLE(CONFIG_USB_RTL8152) + extern u8 rtl8152_get_version(struct usb_interface *intf); +-- +2.51.0 + diff --git a/queue-5.15/nvme-pci-cap-queue-creation-to-used-queues.patch b/queue-5.15/nvme-pci-cap-queue-creation-to-used-queues.patch new file mode 100644 index 0000000000..1b097e3579 --- /dev/null +++ b/queue-5.15/nvme-pci-cap-queue-creation-to-used-queues.patch @@ -0,0 +1,45 @@ +From 796e6aed83a5b18df5e53dc8b7bc6db5870260f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 11:00:12 -0800 +Subject: nvme-pci: cap queue creation to used queues + +From: Keith Busch + +[ Upstream commit 4735b510a00fb2d4ac9e8d21a8c9552cb281f585 ] + +If the user reduces the special queue count at runtime and resets the +controller, we need to reduce the number of queues and interrupts +requested accordingly rather than start with the pre-allocated queue +count. + +Tested-by: Kanchan Joshi +Reviewed-by: Kanchan Joshi +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 04cccbb05372a..c4a33e9d2c717 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2306,7 +2306,13 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) + dev->nr_write_queues = write_queues; + dev->nr_poll_queues = poll_queues; + +- nr_io_queues = dev->nr_allocated_queues - 1; ++ /* ++ * The initial number of allocated queue slots may be too large if the ++ * user reduced the special queue parameters. Cap the value to the ++ * number we need for this round. ++ */ ++ nr_io_queues = min(nvme_max_io_queues(dev), ++ dev->nr_allocated_queues - 1); + result = nvme_set_queue_count(&dev->ctrl, &nr_io_queues); + if (result < 0) + return result; +-- +2.51.0 + diff --git a/queue-5.15/nvme-pci-ensure-we-re-polling-a-polled-queue.patch b/queue-5.15/nvme-pci-ensure-we-re-polling-a-polled-queue.patch new file mode 100644 index 0000000000..375b0c7a50 --- /dev/null +++ b/queue-5.15/nvme-pci-ensure-we-re-polling-a-polled-queue.patch @@ -0,0 +1,39 @@ +From 7cbd7d76b9b2575ec1927f7807ecd32886e5a3cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 09:26:54 -0800 +Subject: nvme-pci: ensure we're polling a polled queue + +From: Keith Busch + +[ Upstream commit 166e31d7dbf6aa44829b98aa446bda5c9580f12a ] + +A user can change the polled queue count at run time. There's a brief +window during a reset where a hipri task may try to poll that queue +before the block layer has updated the queue maps, which would race with +the now interrupt driven queue and may cause double completions. + +Reviewed-by: Christoph Hellwig +Reviewed-by: Kanchan Joshi +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index c4a33e9d2c717..432c21d3a9c4a 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1096,7 +1096,8 @@ static int nvme_poll(struct blk_mq_hw_ctx *hctx) + struct nvme_queue *nvmeq = hctx->driver_data; + bool found; + +- if (!nvme_cqe_pending(nvmeq)) ++ if (!test_bit(NVMEQ_POLLED, &nvmeq->flags) || ++ !nvme_cqe_pending(nvmeq)) + return 0; + + spin_lock(&nvmeq->cq_poll_lock); +-- +2.51.0 + diff --git a/queue-5.15/platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch b/queue-5.15/platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch new file mode 100644 index 0000000000..1e0ec9c94d --- /dev/null +++ b/queue-5.15/platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch @@ -0,0 +1,51 @@ +From f6fddb8b92aac4a371d71004c5352d110b9c1e55 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 23:46:27 -0500 +Subject: platform/x86: intel-hid: Add Dell 14 Plus 2-in-1 to + dmi_vgbs_allow_list +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Peter Metz + +[ Upstream commit 6b3fa0615cd8432148581de62a52f83847af3d70 ] + +The Dell 14 Plus 2-in-1 (model DB04250) requires the VGBS allow list +entry to correctly enable the tablet mode switch. Without this, the +chassis state is not reported, and the hinge rotation only emits +unknown scancodes. + +Verified on Dell 14 Plus 2-in-1 DB04250. + +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221090 +Signed-off-by: Peter Metz +Reviewed-by: Hans de Goede +Link: https://patch.msgid.link/20260213044627.203638-1-peter.metz@unarin.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/intel/hid.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c +index 4d488e985dc55..6331469ee6585 100644 +--- a/drivers/platform/x86/intel/hid.c ++++ b/drivers/platform/x86/intel/hid.c +@@ -156,6 +156,12 @@ static const struct dmi_system_id dmi_vgbs_allow_list[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Dell Pro Rugged 12 Tablet RA02260"), + }, + }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Dell 14 Plus 2-in-1 DB04250"), ++ }, ++ }, + { } + }; + +-- +2.51.0 + diff --git a/queue-5.15/platform-x86-intel-hid-enable-5-button-array-on-thin.patch b/queue-5.15/platform-x86-intel-hid-enable-5-button-array-on-thin.patch new file mode 100644 index 0000000000..857b15be32 --- /dev/null +++ b/queue-5.15/platform-x86-intel-hid-enable-5-button-array-on-thin.patch @@ -0,0 +1,52 @@ +From dfa5fadbcfcbaf4dbd42269067d91bed6c8ea294 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 09:56:25 +0100 +Subject: platform/x86: intel-hid: Enable 5-button array on ThinkPad X1 Fold 16 + Gen 1 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Leif Skunberg + +[ Upstream commit b38d478dad79e61e8a65931021bdfd7a71741212 ] + +The Lenovo ThinkPad X1 Fold 16 Gen 1 has physical volume up/down +buttons that are handled through the intel-hid 5-button array +interface. The firmware does not advertise 5-button array support via +HEBC, so the driver relies on a DMI allowlist to enable it. + +Add the ThinkPad X1 Fold 16 Gen 1 to the button_array_table so the +volume buttons work out of the box. + +Signed-off-by: Leif Skunberg +Reviewed-by: Hans de Goede +Link: https://patch.msgid.link/20260210085625.34380-1-diamondback@cohunt.app +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/intel/hid.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c +index 6331469ee6585..cbc4ec2f8479b 100644 +--- a/drivers/platform/x86/intel/hid.c ++++ b/drivers/platform/x86/intel/hid.c +@@ -102,6 +102,13 @@ static const struct dmi_system_id button_array_table[] = { + DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Tablet Gen 2"), + }, + }, ++ { ++ .ident = "Lenovo ThinkPad X1 Fold 16 Gen 1", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Fold 16 Gen 1"), ++ }, ++ }, + { + .ident = "Microsoft Surface Go 3", + .matches = { +-- +2.51.0 + diff --git a/queue-5.15/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch b/queue-5.15/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch new file mode 100644 index 0000000000..79ff0fd305 --- /dev/null +++ b/queue-5.15/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch @@ -0,0 +1,71 @@ +From 99c87f3baadbf92580b86bedb5aaa77655158a96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 14:23:46 +0100 +Subject: platform/x86: touchscreen_dmi: Add quirk for y-inverted Goodix + touchscreen on SUPI S10 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Hans de Goede + +[ Upstream commit 7d87ed70fc95482c12edf9493c249b6413be485e ] + +The touchscreen on the SUPI S10 tablet reports inverted Y coordinates, +causing touch input to be mirrored vertically relative to the display. + +Add a quirk to set the "touchscreen-inverted-y" boolean device-property +on the touchscreen device, so that the goodix_ts driver will fixup +the coordinates. + +Reported-by: Yajat Kumar +Closes: https://lore.kernel.org/linux-input/20251230221639.582406-1-yajatapps3@gmail.com/ +Tested-by: Yajat Kumar +Signed-off-by: Hans de Goede +Link: https://patch.msgid.link/20260217132346.34535-1-johannes.goede@oss.qualcomm.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/touchscreen_dmi.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c +index b0b1f1b201682..50b1ce7f450eb 100644 +--- a/drivers/platform/x86/touchscreen_dmi.c ++++ b/drivers/platform/x86/touchscreen_dmi.c +@@ -402,6 +402,16 @@ static const struct ts_dmi_data gdix1002_00_upside_down_data = { + .properties = gdix1001_upside_down_props, + }; + ++static const struct property_entry gdix1001_y_inverted_props[] = { ++ PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), ++ { } ++}; ++ ++static const struct ts_dmi_data gdix1001_y_inverted_data = { ++ .acpi_name = "GDIX1001", ++ .properties = gdix1001_y_inverted_props, ++}; ++ + static const struct property_entry gp_electronic_t701_props[] = { + PROPERTY_ENTRY_U32("touchscreen-size-x", 960), + PROPERTY_ENTRY_U32("touchscreen-size-y", 640), +@@ -1631,6 +1641,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_SKU, "PN20170413488"), + }, + }, ++ { ++ /* SUPI S10 */ ++ .driver_data = (void *)&gdix1001_y_inverted_data, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "SUPI"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "S10"), ++ }, ++ }, + { + /* Techbite Arc 11.6 */ + .driver_data = (void *)&techbite_arc_11_6_data, +-- +2.51.0 + diff --git a/queue-5.15/series b/queue-5.15/series index 83bffd4d5b..96d95df3f6 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -292,3 +292,25 @@ netfilter-nf_tables-de-constify-set-commit-ops-function-argument.patch netfilter-nft_set_pipapo-split-gc-into-unlink-and-reclaim-phase.patch xen-privcmd-restrict-usage-in-unprivileged-domu.patch xen-privcmd-add-boot-control-for-restricted-usage-in-domu.patch +hwmon-mr75203-skip-reset-control-deassert-for-socs-t.patch +hwmon-make-use-of-devm_clk_get_enabled.patch +hwmon-axi-fan-control-use-device-firmware-agnostic-a.patch +hwmon-axi-fan-control-make-use-of-dev_err_probe.patch +hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch +sh-platform_early-remove-pdev-driver_override-check.patch +bpf-release-module-btf-idr-before-module-unload.patch +hid-asus-avoid-memory-leak-in-asus_report_fixup.patch +platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch +nvme-pci-cap-queue-creation-to-used-queues.patch +platform-x86-intel-hid-enable-5-button-array-on-thin.patch +platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch +nvme-pci-ensure-we-re-polling-a-polled-queue.patch +hid-magicmouse-fix-battery-reporting-for-apple-magic.patch +hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch +net-usb-r8152-add-trendnet-tuc-et2g.patch +hid-mcp2221-cancel-last-i2c-command-on-read-error.patch +module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch +asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch +asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-32526 +dma-buf-include-ioctl.h-in-uapi-header.patch +alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch diff --git a/queue-5.15/sh-platform_early-remove-pdev-driver_override-check.patch b/queue-5.15/sh-platform_early-remove-pdev-driver_override-check.patch new file mode 100644 index 0000000000..039b146613 --- /dev/null +++ b/queue-5.15/sh-platform_early-remove-pdev-driver_override-check.patch @@ -0,0 +1,45 @@ +From 8291b722776866cc7ab22d7bd31fec720f606c5a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Mar 2026 00:37:15 +0100 +Subject: sh: platform_early: remove pdev->driver_override check + +From: Danilo Krummrich + +[ Upstream commit c5f60e3f07b6609562d21efda878e83ce8860728 ] + +In commit 507fd01d5333 ("drivers: move the early platform device support to +arch/sh") platform_match() was copied over to the sh platform_early +code, accidentally including the driver_override check. + +This check does not make sense for platform_early, as sysfs is not even +available in first place at this point in the boot process, hence remove +the check. + +Reviewed-by: Greg Kroah-Hartman +Reviewed-by: Geert Uytterhoeven +Fixes: 507fd01d5333 ("drivers: move the early platform device support to arch/sh") +Link: https://lore.kernel.org/all/DH4M3DJ4P58T.1BGVAVXN71Z09@kernel.org/ +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + arch/sh/drivers/platform_early.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c +index 143747c45206f..48ddbc547bd9a 100644 +--- a/arch/sh/drivers/platform_early.c ++++ b/arch/sh/drivers/platform_early.c +@@ -26,10 +26,6 @@ static int platform_match(struct device *dev, struct device_driver *drv) + struct platform_device *pdev = to_platform_device(dev); + struct platform_driver *pdrv = to_platform_driver(drv); + +- /* When driver_override is set, only bind to the matching driver */ +- if (pdev->driver_override) +- return !strcmp(pdev->driver_override, drv->name); +- + /* Then try to match against the id table */ + if (pdrv->id_table) + return platform_match_id(pdrv->id_table, pdev) != NULL; +-- +2.51.0 + diff --git a/queue-6.1/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch b/queue-6.1/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch new file mode 100644 index 0000000000..8fac8a1de9 --- /dev/null +++ b/queue-6.1/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch @@ -0,0 +1,43 @@ +From 93556b7b248100938fb7f3c700ace166d3059d07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Mar 2026 06:29:06 +0500 +Subject: ALSA: hda/realtek: Add headset jack quirk for Thinkpad X390 + +From: Uzair Mughal + +[ Upstream commit 542127f6528ca7cc3cf61e1651d6ccb58495f953 ] + +The Lenovo ThinkPad X390 (ALC257 codec, subsystem ID 0x17aa2288) +does not report headset button press events. Headphone insertion is +detected (SW_HEADPHONE_INSERT), but pressing the inline microphone +button on a headset produces no input events. + +Add a SND_PCI_QUIRK entry that maps this subsystem ID to +ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, which enables +headset jack button detection through alc_fixup_headset_jack() +and ThinkPad ACPI integration. This is the same fixup used by +similar ThinkPad models (P1 Gen 3, X1 Extreme Gen 3). + +Signed-off-by: Uzair Mughal +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20260307012906.20093-1-contact@uzair.is-a.dev +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 1f069d7c3829f..9d6b3a6b8ed26 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10345,6 +10345,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), + SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), + SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), ++ SND_PCI_QUIRK(0x17aa, 0x2288, "Thinkpad X390", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x22c1, "Thinkpad P1 Gen 3", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), +-- +2.51.0 + diff --git a/queue-6.1/alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch b/queue-6.1/alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch new file mode 100644 index 0000000000..424936b5cb --- /dev/null +++ b/queue-6.1/alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch @@ -0,0 +1,38 @@ +From 31b40d6df3a3b9b04041a24b76462d07e81d2272 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Mar 2026 11:27:27 +0800 +Subject: ALSA: hda/realtek: add HP Laptop 14s-dr5xxx mute LED quirk + +From: Liucheng Lu + +[ Upstream commit 178dd118c0f07fd63a9ed74cfbd8c31ae50e33af ] + +HP Laptop 14s-dr5xxx with ALC236 codec does not handle the toggling of +the mute LED. +This patch adds a quirk entry for subsystem ID 0x8a1f using +ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 fixup, enabling correct mute LED +behavior. + +Signed-off-by: Liucheng Lu +Link: https://patch.msgid.link/PAVPR03MB9774F3FCE9CCD181C585281AE37BA@PAVPR03MB9774.eurprd03.prod.outlook.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 89410d40561d7..1f069d7c3829f 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10019,6 +10019,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x89d3, "HP EliteBook 645 G9 (MB 89D2)", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x8a0f, "HP Pavilion 14-ec1xxx", ALC287_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8a1f, "HP Laptop 14s-dr5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), + SND_PCI_QUIRK(0x103c, 0x8a78, "HP Dev One", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), +-- +2.51.0 + diff --git a/queue-6.1/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch b/queue-6.1/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch new file mode 100644 index 0000000000..da640a2777 --- /dev/null +++ b/queue-6.1/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch @@ -0,0 +1,52 @@ +From 5d5776bfc1847dfd96591120e4661bfd09f64ffb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 00:25:38 +0000 +Subject: ASoC: fsl_easrc: Fix event generation in fsl_easrc_iec958_set_reg() + +From: Mark Brown + +[ Upstream commit 31ddc62c1cd92e51b9db61d7954b85ae2ec224da ] + +ALSA controls should return 1 if the value in the control changed but the +control put operation fsl_easrc_set_reg() only returns 0 or a negative +error code, causing ALSA to not generate any change events. Add a suitable +check by using regmap_update_bits_check() with the underlying regmap, this +is more clearly and simply correct than trying to verify that one of the +generic ops is exactly equivalent to this one. + +Signed-off-by: Mark Brown +Link: https://patch.msgid.link/20260205-asoc-fsl-easrc-fix-events-v1-2-39d4c766918b@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_easrc.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c +index 210ca7199adab..8cf414ab1295b 100644 +--- a/sound/soc/fsl/fsl_easrc.c ++++ b/sound/soc/fsl/fsl_easrc.c +@@ -93,14 +93,17 @@ static int fsl_easrc_set_reg(struct snd_kcontrol *kcontrol, + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_value; ++ struct fsl_asrc *easrc = snd_soc_component_get_drvdata(component); + unsigned int regval = ucontrol->value.integer.value[0]; ++ bool changed; + int ret; + +- ret = snd_soc_component_write(component, mc->regbase, regval); +- if (ret < 0) ++ ret = regmap_update_bits_check(easrc->regmap, mc->regbase, ++ GENMASK(31, 0), regval, &changed); ++ if (ret != 0) + return ret; + +- return 0; ++ return changed; + } + + #define SOC_SINGLE_REG_RW(xname, xreg) \ +-- +2.51.0 + diff --git a/queue-6.1/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-8112 b/queue-6.1/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-8112 new file mode 100644 index 0000000000..d0bec468c8 --- /dev/null +++ b/queue-6.1/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-8112 @@ -0,0 +1,49 @@ +From f13423f4c725f7d0546f502694370867ef1bf8b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 00:25:37 +0000 +Subject: ASoC: fsl_easrc: Fix event generation in fsl_easrc_iec958_put_bits() + +From: Mark Brown + +[ Upstream commit 54a86cf48eaa6d1ab5130d756b718775e81e1748 ] + +ALSA controls should return 1 if the value in the control changed but the +control put operation fsl_easrc_iec958_put_bits() unconditionally returns +0, causing ALSA to not generate any change events. This is detected by +mixer-test with large numbers of messages in the form: + + No event generated for Context 3 IEC958 CS5 + Context 3 IEC958 CS5.0 orig 5224 read 5225, is_volatile 0 + +Add a suitable check. + +Signed-off-by: Mark Brown +Link: https://patch.msgid.link/20260205-asoc-fsl-easrc-fix-events-v1-1-39d4c766918b@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_easrc.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c +index 8cf414ab1295b..cbe1f48a58d23 100644 +--- a/sound/soc/fsl/fsl_easrc.c ++++ b/sound/soc/fsl/fsl_easrc.c +@@ -52,10 +52,13 @@ static int fsl_easrc_iec958_put_bits(struct snd_kcontrol *kcontrol, + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_value; + unsigned int regval = ucontrol->value.integer.value[0]; ++ int ret; ++ ++ ret = (easrc_priv->bps_iec958[mc->regbase] != regval); + + easrc_priv->bps_iec958[mc->regbase] = regval; + +- return 0; ++ return ret; + } + + static int fsl_easrc_iec958_get_bits(struct snd_kcontrol *kcontrol, +-- +2.51.0 + diff --git a/queue-6.1/bpf-release-module-btf-idr-before-module-unload.patch b/queue-6.1/bpf-release-module-btf-idr-before-module-unload.patch new file mode 100644 index 0000000000..239733539b --- /dev/null +++ b/queue-6.1/bpf-release-module-btf-idr-before-module-unload.patch @@ -0,0 +1,128 @@ +From 769441a4e165e664abb9a5b4dbdf42521edf117f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Mar 2026 13:53:07 -0700 +Subject: bpf: Release module BTF IDR before module unload + +From: Kumar Kartikeya Dwivedi + +[ Upstream commit 146bd2a87a65aa407bb17fac70d8d583d19aba06 ] + +Gregory reported in [0] that the global_map_resize test when run in +repeatedly ends up failing during program load. This stems from the fact +that BTF reference has not dropped to zero after the previous run's +module is unloaded, and the older module's BTF is still discoverable and +visible. Later, in libbpf, load_module_btfs() will find the ID for this +stale BTF, open its fd, and then it will be used during program load +where later steps taking module reference using btf_try_get_module() +fail since the underlying module for the BTF is gone. + +Logically, once a module is unloaded, it's associated BTF artifacts +should become hidden. The BTF object inside the kernel may still remain +alive as long its reference counts are alive, but it should no longer be +discoverable. + +To fix this, let us call btf_free_id() from the MODULE_STATE_GOING case +for the module unload to free the BTF associated IDR entry, and disable +its discovery once module unload returns to user space. If a race +happens during unload, the outcome is non-deterministic anyway. However, +user space should be able to rely on the guarantee that once it has +synchronously established a successful module unload, no more stale +artifacts associated with this module can be obtained subsequently. + +Note that we must be careful to not invoke btf_free_id() in btf_put() +when btf_is_module() is true now. There could be a window where the +module unload drops a non-terminal reference, frees the IDR, but the +same ID gets reused and the second unconditional btf_free_id() ends up +releasing an unrelated entry. + +To avoid a special case for btf_is_module() case, set btf->id to zero to +make btf_free_id() idempotent, such that we can unconditionally invoke it +from btf_put(), and also from the MODULE_STATE_GOING case. Since zero is +an invalid IDR, the idr_remove() should be a noop. + +Note that we can be sure that by the time we reach final btf_put() for +btf_is_module() case, the btf_free_id() is already done, since the +module itself holds the BTF reference, and it will call this function +for the BTF before dropping its own reference. + + [0]: https://lore.kernel.org/bpf/cover.1773170190.git.grbell@redhat.com + +Fixes: 36e68442d1af ("bpf: Load and verify kernel module BTFs") +Acked-by: Martin KaFai Lau +Suggested-by: Martin KaFai Lau +Reported-by: Gregory Bell +Reviewed-by: Emil Tsalapatis +Signed-off-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20260312205307.1346991-1-memxor@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/btf.c | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c +index 9f9996cdb6e2f..d9f6ad515d890 100644 +--- a/kernel/bpf/btf.c ++++ b/kernel/bpf/btf.c +@@ -1606,7 +1606,16 @@ static void btf_free_id(struct btf *btf) + * of the _bh() version. + */ + spin_lock_irqsave(&btf_idr_lock, flags); +- idr_remove(&btf_idr, btf->id); ++ if (btf->id) { ++ idr_remove(&btf_idr, btf->id); ++ /* ++ * Clear the id here to make this function idempotent, since it will get ++ * called a couple of times for module BTFs: on module unload, and then ++ * the final btf_put(). btf_alloc_id() starts IDs with 1, so we can use ++ * 0 as sentinel value. ++ */ ++ WRITE_ONCE(btf->id, 0); ++ } + spin_unlock_irqrestore(&btf_idr_lock, flags); + } + +@@ -6875,7 +6884,7 @@ static void bpf_btf_show_fdinfo(struct seq_file *m, struct file *filp) + { + const struct btf *btf = filp->private_data; + +- seq_printf(m, "btf_id:\t%u\n", btf->id); ++ seq_printf(m, "btf_id:\t%u\n", READ_ONCE(btf->id)); + } + #endif + +@@ -6970,7 +6979,7 @@ int btf_get_info_by_fd(const struct btf *btf, + if (copy_from_user(&info, uinfo, info_copy)) + return -EFAULT; + +- info.id = btf->id; ++ info.id = READ_ONCE(btf->id); + ubtf = u64_to_user_ptr(info.btf); + btf_copy = min_t(u32, btf->data_size, info.btf_size); + if (copy_to_user(ubtf, btf->data, btf_copy)) +@@ -7033,7 +7042,7 @@ int btf_get_fd_by_id(u32 id) + + u32 btf_obj_id(const struct btf *btf) + { +- return btf->id; ++ return READ_ONCE(btf->id); + } + + bool btf_is_kernel(const struct btf *btf) +@@ -7179,6 +7188,13 @@ static int btf_module_notify(struct notifier_block *nb, unsigned long op, + if (btf_mod->module != module) + continue; + ++ /* ++ * For modules, we do the freeing of BTF IDR as soon as ++ * module goes away to disable BTF discovery, since the ++ * btf_try_get_module() on such BTFs will fail. This may ++ * be called again on btf_put(), but it's ok to do so. ++ */ ++ btf_free_id(btf_mod->btf); + list_del(&btf_mod->list); + if (btf_mod->sysfs_attr) + sysfs_remove_bin_file(btf_kobj, btf_mod->sysfs_attr); +-- +2.51.0 + diff --git a/queue-6.1/btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch b/queue-6.1/btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch new file mode 100644 index 0000000000..d52e5e1959 --- /dev/null +++ b/queue-6.1/btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch @@ -0,0 +1,196 @@ +From adccdec3d1952b2d2f996c0514092dc4bf24c572 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Feb 2026 14:25:35 -0800 +Subject: btrfs: set BTRFS_ROOT_ORPHAN_CLEANUP during subvol create + +From: Boris Burkov + +[ Upstream commit 5131fa077f9bb386a1b901bf5b247041f0ec8f80 ] + +We have recently observed a number of subvolumes with broken dentries. +ls-ing the parent dir looks like: + +drwxrwxrwt 1 root root 16 Jan 23 16:49 . +drwxr-xr-x 1 root root 24 Jan 23 16:48 .. +d????????? ? ? ? ? ? broken_subvol + +and similarly stat-ing the file fails. + +In this state, deleting the subvol fails with ENOENT, but attempting to +create a new file or subvol over it errors out with EEXIST and even +aborts the fs. Which leaves us a bit stuck. + +dmesg contains a single notable error message reading: +"could not do orphan cleanup -2" + +2 is ENOENT and the error comes from the failure handling path of +btrfs_orphan_cleanup(), with the stack leading back up to +btrfs_lookup(). + +btrfs_lookup +btrfs_lookup_dentry +btrfs_orphan_cleanup // prints that message and returns -ENOENT + +After some detailed inspection of the internal state, it became clear +that: +- there are no orphan items for the subvol +- the subvol is otherwise healthy looking, it is not half-deleted or + anything, there is no drop progress, etc. +- the subvol was created a while ago and does the meaningful first + btrfs_orphan_cleanup() call that sets BTRFS_ROOT_ORPHAN_CLEANUP much + later. +- after btrfs_orphan_cleanup() fails, btrfs_lookup_dentry() returns -ENOENT, + which results in a negative dentry for the subvolume via + d_splice_alias(NULL, dentry), leading to the observed behavior. The + bug can be mitigated by dropping the dentry cache, at which point we + can successfully delete the subvolume if we want. + +i.e., +btrfs_lookup() + btrfs_lookup_dentry() + if (!sb_rdonly(inode->vfs_inode)->vfs_inode) + btrfs_orphan_cleanup(sub_root) + test_and_set_bit(BTRFS_ROOT_ORPHAN_CLEANUP) + btrfs_search_slot() // finds orphan item for inode N + ... + prints "could not do orphan cleanup -2" + if (inode == ERR_PTR(-ENOENT)) + inode = NULL; + return d_splice_alias(NULL, dentry) // NEGATIVE DENTRY for valid subvolume + +btrfs_orphan_cleanup() does test_and_set_bit(BTRFS_ROOT_ORPHAN_CLEANUP) +on the root when it runs, so it cannot run more than once on a given +root, so something else must run concurrently. However, the obvious +routes to deleting an orphan when nlinks goes to 0 should not be able to +run without first doing a lookup into the subvolume, which should run +btrfs_orphan_cleanup() and set the bit. + +The final important observation is that create_subvol() calls +d_instantiate_new() but does not set BTRFS_ROOT_ORPHAN_CLEANUP, so if +the dentry cache gets dropped, the next lookup into the subvolume will +make a real call into btrfs_orphan_cleanup() for the first time. This +opens up the possibility of concurrently deleting the inode/orphan items +but most typical evict() paths will be holding a reference on the parent +dentry (child dentry holds parent->d_lockref.count via dget in +d_alloc(), released in __dentry_kill()) and prevent the parent from +being removed from the dentry cache. + +The one exception is delayed iputs. Ordered extent creation calls +igrab() on the inode. If the file is unlinked and closed while those +refs are held, iput() in __dentry_kill() decrements i_count but does +not trigger eviction (i_count > 0). The child dentry is freed and the +subvol dentry's d_lockref.count drops to 0, making it evictable while +the inode is still alive. + +Since there are two races (the race between writeback and unlink and +the race between lookup and delayed iputs), and there are too many moving +parts, the following three diagrams show the complete picture. +(Only the second and third are races) + +Phase 1: +Create Subvol in dentry cache without BTRFS_ROOT_ORPHAN_CLEANUP set + +btrfs_mksubvol() + lookup_one_len() + __lookup_slow() + d_alloc_parallel() + __d_alloc() // d_lockref.count = 1 + create_subvol(dentry) + // doesn't touch the bit.. + d_instantiate_new(dentry, inode) // dentry in cache with d_lockref.count == 1 + +Phase 2: +Create a delayed iput for a file in the subvol but leave the subvol in +state where its dentry can be evicted (d_lockref.count == 0) + +T1 (task) T2 (writeback) T3 (OE workqueue) + +write() // dirty pages + btrfs_writepages() + btrfs_run_delalloc_range() + cow_file_range() + btrfs_alloc_ordered_extent() + igrab() // i_count: 1 -> 2 +btrfs_unlink_inode() + btrfs_orphan_add() +close() + __fput() + dput() + finish_dput() + __dentry_kill() + dentry_unlink_inode() + iput() // 2 -> 1 + --parent->d_lockref.count // 1 -> 0; evictable + finish_ordered_fn() + btrfs_finish_ordered_io() + btrfs_put_ordered_extent() + btrfs_add_delayed_iput() + +Phase 3: +Once the delayed iput is pending and the subvol dentry is evictable, +the shrinker can free it, causing the next lookup to go through +btrfs_lookup() and call btrfs_orphan_cleanup() for the first time. +If the cleaner kthread processes the delayed iput concurrently, the +two race: + + T1 (shrinker) T2 (cleaner kthread) T3 (lookup) + + super_cache_scan() + prune_dcache_sb() + __dentry_kill() + // subvol dentry freed + btrfs_run_delayed_iputs() + iput() // i_count -> 0 + evict() // sets I_FREEING + btrfs_evict_inode() + // truncation loop + btrfs_lookup() + btrfs_lookup_dentry() + btrfs_orphan_cleanup() + // first call (bit never set) + btrfs_iget() + // blocks on I_FREEING + + btrfs_orphan_del() + // inode freed + // returns -ENOENT + btrfs_del_orphan_item() + // -ENOENT + // "could not do orphan cleanup -2" + d_splice_alias(NULL, dentry) + // negative dentry for valid subvol + +The most straightforward fix is to ensure the invariant that a dentry +for a subvolume can exist if and only if that subvolume has +BTRFS_ROOT_ORPHAN_CLEANUP set on its root (and is known to have no +orphans or ran btrfs_orphan_cleanup()). + +Reviewed-by: Filipe Manana +Signed-off-by: Boris Burkov +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/ioctl.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index e491c7f3ec350..835ce20304104 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -744,6 +744,13 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, + goto out; + } + ++ /* ++ * Subvolumes have orphans cleaned on first dentry lookup. A new ++ * subvolume cannot have any orphans, so we should set the bit before we ++ * add the subvolume dentry to the dentry cache, so that it is in the ++ * same state as a subvolume after first lookup. ++ */ ++ set_bit(BTRFS_ROOT_ORPHAN_CLEANUP, &new_root->state); + d_instantiate_new(dentry, new_inode_args.inode); + new_inode_args.inode = NULL; + +-- +2.51.0 + diff --git a/queue-6.1/dma-buf-include-ioctl.h-in-uapi-header.patch b/queue-6.1/dma-buf-include-ioctl.h-in-uapi-header.patch new file mode 100644 index 0000000000..136708344a --- /dev/null +++ b/queue-6.1/dma-buf-include-ioctl.h-in-uapi-header.patch @@ -0,0 +1,44 @@ +From fdf1b9dd9fb476fc5bed2ecac3e5faa0b8755759 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Mar 2026 16:23:09 -0800 +Subject: dma-buf: Include ioctl.h in UAPI header +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Isaac J. Manjarres + +[ Upstream commit a116bac87118903925108e57781bbfc7a7eea27b ] + +include/uapi/linux/dma-buf.h uses several macros from ioctl.h to define +its ioctl commands. However, it does not include ioctl.h itself. So, +if userspace source code tries to include the dma-buf.h file without +including ioctl.h, it can result in build failures. + +Therefore, include ioctl.h in the dma-buf UAPI header. + +Signed-off-by: Isaac J. Manjarres +Reviewed-by: T.J. Mercier +Reviewed-by: Christian König +Signed-off-by: Christian König +Link: https://lore.kernel.org/r/20260303002309.1401849-1-isaacmanjarres@google.com +Signed-off-by: Sasha Levin +--- + include/uapi/linux/dma-buf.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h +index 5a6fda66d9adf..e827c9d20c5d3 100644 +--- a/include/uapi/linux/dma-buf.h ++++ b/include/uapi/linux/dma-buf.h +@@ -20,6 +20,7 @@ + #ifndef _DMA_BUF_UAPI_H_ + #define _DMA_BUF_UAPI_H_ + ++#include + #include + + /** +-- +2.51.0 + diff --git a/queue-6.1/hid-apple-avoid-memory-leak-in-apple_report_fixup.patch b/queue-6.1/hid-apple-avoid-memory-leak-in-apple_report_fixup.patch new file mode 100644 index 0000000000..4d0dd41418 --- /dev/null +++ b/queue-6.1/hid-apple-avoid-memory-leak-in-apple_report_fixup.patch @@ -0,0 +1,45 @@ +From 67c15d5e475c831c07bea499c6531e0b59ba4d9d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Feb 2026 16:43:36 +0100 +Subject: HID: apple: avoid memory leak in apple_report_fixup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Günther Noack + +[ Upstream commit 239c15116d80f67d32f00acc34575f1a6b699613 ] + +The apple_report_fixup() function was returning a +newly kmemdup()-allocated buffer, but never freeing it. + +The caller of report_fixup() does not take ownership of the returned +pointer, but it *is* permitted to return a sub-portion of the input +rdesc, whose lifetime is managed by the caller. + +Assisted-by: Gemini-CLI:Google Gemini 3 +Signed-off-by: Günther Noack +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-apple.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 0dff3f557e632..742ff0c86e0f9 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -611,9 +611,7 @@ static __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc, + hid_info(hdev, + "fixing up Magic Keyboard battery report descriptor\n"); + *rsize = *rsize - 1; +- rdesc = kmemdup(rdesc + 1, *rsize, GFP_KERNEL); +- if (!rdesc) +- return NULL; ++ rdesc = rdesc + 1; + + rdesc[0] = 0x05; + rdesc[1] = 0x01; +-- +2.51.0 + diff --git a/queue-6.1/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch b/queue-6.1/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch new file mode 100644 index 0000000000..1c02ac8cc7 --- /dev/null +++ b/queue-6.1/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch @@ -0,0 +1,65 @@ +From 1c114ad8166af961a873f2965a653cdcfbef61fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Feb 2026 16:43:38 +0100 +Subject: HID: asus: avoid memory leak in asus_report_fixup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Günther Noack + +[ Upstream commit 2bad24c17742fc88973d6aea526ce1353f5334a3 ] + +The asus_report_fixup() function was returning a newly allocated +kmemdup()-allocated buffer, but never freeing it. Switch to +devm_kzalloc() to ensure the memory is managed and freed automatically +when the device is removed. + +The caller of report_fixup() does not take ownership of the returned +pointer, but it is permitted to return a pointer whose lifetime is at +least that of the input buffer. + +Also fix a harmless out-of-bounds read by copying only the original +descriptor size. + +Assisted-by: Gemini-CLI:Google Gemini 3 +Signed-off-by: Günther Noack +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-asus.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index ff301fd25725a..a95e47ce6d1e5 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -1206,14 +1206,21 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, + */ + if (*rsize == rsize_orig && + rdesc[offs] == 0x09 && rdesc[offs + 1] == 0x76) { +- *rsize = rsize_orig + 1; +- rdesc = kmemdup(rdesc, *rsize, GFP_KERNEL); +- if (!rdesc) +- return NULL; ++ __u8 *new_rdesc; ++ ++ new_rdesc = devm_kzalloc(&hdev->dev, rsize_orig + 1, ++ GFP_KERNEL); ++ if (!new_rdesc) ++ return rdesc; + + hid_info(hdev, "Fixing up %s keyb report descriptor\n", + drvdata->quirks & QUIRK_T100CHI ? + "T100CHI" : "T90CHI"); ++ ++ memcpy(new_rdesc, rdesc, rsize_orig); ++ *rsize = rsize_orig + 1; ++ rdesc = new_rdesc; ++ + memmove(rdesc + offs + 4, rdesc + offs + 2, 12); + rdesc[offs] = 0x19; + rdesc[offs + 1] = 0x00; +-- +2.51.0 + diff --git a/queue-6.1/hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch b/queue-6.1/hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch new file mode 100644 index 0000000000..3daf63deeb --- /dev/null +++ b/queue-6.1/hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch @@ -0,0 +1,45 @@ +From e0f452ede590e0e014d8c717f60becc8edf95d97 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Feb 2026 16:43:37 +0100 +Subject: HID: magicmouse: avoid memory leak in magicmouse_report_fixup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Günther Noack + +[ Upstream commit 91e8c6e601bdc1ccdf886479b6513c01c7e51c2c ] + +The magicmouse_report_fixup() function was returning a +newly kmemdup()-allocated buffer, but never freeing it. + +The caller of report_fixup() does not take ownership of the returned +pointer, but it *is* permitted to return a sub-portion of the input +rdesc, whose lifetime is managed by the caller. + +Assisted-by: Gemini-CLI:Google Gemini 3 +Signed-off-by: Günther Noack +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-magicmouse.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index bb725dfcef196..d5df2745f3da4 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -967,9 +967,7 @@ static __u8 *magicmouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, + hid_info(hdev, + "fixing up magicmouse battery report descriptor\n"); + *rsize = *rsize - 1; +- rdesc = kmemdup(rdesc + 1, *rsize, GFP_KERNEL); +- if (!rdesc) +- return NULL; ++ rdesc = rdesc + 1; + + rdesc[0] = 0x05; + rdesc[1] = 0x01; +-- +2.51.0 + diff --git a/queue-6.1/hid-magicmouse-fix-battery-reporting-for-apple-magic.patch b/queue-6.1/hid-magicmouse-fix-battery-reporting-for-apple-magic.patch new file mode 100644 index 0000000000..e3424d5469 --- /dev/null +++ b/queue-6.1/hid-magicmouse-fix-battery-reporting-for-apple-magic.patch @@ -0,0 +1,41 @@ +From c969fb74c4ea636e3c3d47c868eb99084d7fd095 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Feb 2026 20:34:21 +0100 +Subject: HID: magicmouse: fix battery reporting for Apple Magic Trackpad 2 + +From: Julius Lehmann + +[ Upstream commit 5f3518d77419255f8b12bb23c8ec22acbeb6bc5b ] + +Battery reporting does not work for the Apple Magic Trackpad 2 if it is +connected via USB. The current hid descriptor fixup code checks for a +hid descriptor length of exactly 83 bytes. If the hid descriptor is +larger, which is the case for newer apple mice, the fixup is not +applied. + +This fix checks for hid descriptor sizes greater/equal 83 bytes which +applies the fixup for newer devices as well. + +Signed-off-by: Julius Lehmann +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-magicmouse.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 99d0dbf62af37..bb725dfcef196 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -963,7 +963,7 @@ static __u8 *magicmouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, + */ + if ((is_usb_magicmouse2(hdev->vendor, hdev->product) || + is_usb_magictrackpad2(hdev->vendor, hdev->product)) && +- *rsize == 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) { ++ *rsize >= 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) { + hid_info(hdev, + "fixing up magicmouse battery report descriptor\n"); + *rsize = *rsize - 1; +-- +2.51.0 + diff --git a/queue-6.1/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch b/queue-6.1/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch new file mode 100644 index 0000000000..0955da016f --- /dev/null +++ b/queue-6.1/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch @@ -0,0 +1,41 @@ +From 1bba72db3b594a3f15e468f665745d95011ca03c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 17:32:58 +0100 +Subject: HID: mcp2221: cancel last I2C command on read error + +From: Romain Sioen + +[ Upstream commit e31b556c0ba21f20c298aa61181b96541140b7b9 ] + +When an I2C SMBus read operation fails, the MCP2221 internal state machine +may not reset correctly, causing subsequent transactions to fail. + +By adding a short delay and explicitly cancelling the last command, +we ensure the device is ready for the next operation. + +Fix an issue where i2cdetect was not able to detect all devices correctly +on the bus. + +Signed-off-by: Romain Sioen +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-mcp2221.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c +index 474f563c23a43..e1bd1744bf307 100644 +--- a/drivers/hid/hid-mcp2221.c ++++ b/drivers/hid/hid-mcp2221.c +@@ -319,6 +319,8 @@ static int mcp_i2c_smbus_read(struct mcp2221 *mcp, + usleep_range(90, 100); + retries++; + } else { ++ usleep_range(980, 1000); ++ mcp_cancel_last_cmd(mcp); + return ret; + } + } else { +-- +2.51.0 + diff --git a/queue-6.1/hwmon-axi-fan-control-make-use-of-dev_err_probe.patch b/queue-6.1/hwmon-axi-fan-control-make-use-of-dev_err_probe.patch new file mode 100644 index 0000000000..b7e0b77c2e --- /dev/null +++ b/queue-6.1/hwmon-axi-fan-control-make-use-of-dev_err_probe.patch @@ -0,0 +1,91 @@ +From 06e89dd919312e41b7a842d3b66eb7bb3cc67d8f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Feb 2024 15:36:45 +0100 +Subject: hwmon: (axi-fan-control) Make use of dev_err_probe() + +From: Nuno Sa + +[ Upstream commit ec823656c1e0e5f49e92ed86cee9fb26585da18e ] + +Use dev_err_probe() to slightly simplify printing errors during probe. +No functional changes intended. + +Signed-off-by: Nuno Sa +Link: https://lore.kernel.org/r/20240214-axi-fan-control-no-of-v1-3-43ca656fe2e3@analog.com +Signed-off-by: Guenter Roeck +Stable-dep-of: 813bbc4d33d2 ("hwmon: axi-fan: don't use driver_override as IRQ name") +Signed-off-by: Sasha Levin +--- + drivers/hwmon/axi-fan-control.c | 40 +++++++++++++++------------------ + 1 file changed, 18 insertions(+), 22 deletions(-) + +diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c +index b847d91dd5bab..15a3455577dd7 100644 +--- a/drivers/hwmon/axi-fan-control.c ++++ b/drivers/hwmon/axi-fan-control.c +@@ -466,10 +466,9 @@ static int axi_fan_control_probe(struct platform_device *pdev) + return PTR_ERR(ctl->base); + + clk = devm_clk_get_enabled(&pdev->dev, NULL); +- if (IS_ERR(clk)) { +- dev_err(&pdev->dev, "clk_get failed with %ld\n", PTR_ERR(clk)); +- return PTR_ERR(clk); +- } ++ if (IS_ERR(clk)) ++ return dev_err_probe(&pdev->dev, PTR_ERR(clk), ++ "clk_get failed\n"); + + ctl->clk_rate = clk_get_rate(clk); + if (!ctl->clk_rate) +@@ -477,22 +476,20 @@ static int axi_fan_control_probe(struct platform_device *pdev) + + version = axi_ioread(ADI_AXI_REG_VERSION, ctl); + if (ADI_AXI_PCORE_VER_MAJOR(version) != +- ADI_AXI_PCORE_VER_MAJOR((*id))) { +- dev_err(&pdev->dev, "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", +- ADI_AXI_PCORE_VER_MAJOR(*id), +- ADI_AXI_PCORE_VER_MINOR(*id), +- ADI_AXI_PCORE_VER_PATCH(*id), +- ADI_AXI_PCORE_VER_MAJOR(version), +- ADI_AXI_PCORE_VER_MINOR(version), +- ADI_AXI_PCORE_VER_PATCH(version)); +- return -ENODEV; +- } ++ ADI_AXI_PCORE_VER_MAJOR((*id))) ++ return dev_err_probe(&pdev->dev, -ENODEV, ++ "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", ++ ADI_AXI_PCORE_VER_MAJOR(*id), ++ ADI_AXI_PCORE_VER_MINOR(*id), ++ ADI_AXI_PCORE_VER_PATCH(*id), ++ ADI_AXI_PCORE_VER_MAJOR(version), ++ ADI_AXI_PCORE_VER_MINOR(version), ++ ADI_AXI_PCORE_VER_PATCH(version)); + + ret = axi_fan_control_init(ctl, &pdev->dev); +- if (ret) { +- dev_err(&pdev->dev, "Failed to initialize device\n"); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(&pdev->dev, ret, ++ "Failed to initialize device\n"); + + ctl->hdev = devm_hwmon_device_register_with_info(&pdev->dev, + name, +@@ -511,10 +508,9 @@ static int axi_fan_control_probe(struct platform_device *pdev) + axi_fan_control_irq_handler, + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, + pdev->driver_override, ctl); +- if (ret) { +- dev_err(&pdev->dev, "failed to request an irq, %d", ret); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(&pdev->dev, ret, ++ "failed to request an irq\n"); + + return 0; + } +-- +2.51.0 + diff --git a/queue-6.1/hwmon-axi-fan-control-use-device-firmware-agnostic-a.patch b/queue-6.1/hwmon-axi-fan-control-use-device-firmware-agnostic-a.patch new file mode 100644 index 0000000000..2c3dcd42c9 --- /dev/null +++ b/queue-6.1/hwmon-axi-fan-control-use-device-firmware-agnostic-a.patch @@ -0,0 +1,126 @@ +From 5f193643c6b952c12096ca8987b45975cc392adb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Feb 2024 15:36:43 +0100 +Subject: hwmon: (axi-fan-control) Use device firmware agnostic API + +From: Nuno Sa + +[ Upstream commit 1b5239f70fcd2d7fe86f0f5473006c2896db07a8 ] + +Don't directly use OF and use device property APIs. In addition, this +makes the probe() code neater and also allow us to move the +of_device_id table to it's natural place. + +While at it, make sure to explicitly include mod_devicetable.h for the +of_device_id table. + +Signed-off-by: Nuno Sa +Link: https://lore.kernel.org/r/20240214-axi-fan-control-no-of-v1-1-43ca656fe2e3@analog.com +Signed-off-by: Guenter Roeck +Stable-dep-of: 813bbc4d33d2 ("hwmon: axi-fan: don't use driver_override as IRQ name") +Signed-off-by: Sasha Levin +--- + drivers/hwmon/axi-fan-control.c | 39 +++++++++++++++++---------------- + 1 file changed, 20 insertions(+), 19 deletions(-) + +diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c +index 25abf28084c96..b847d91dd5bab 100644 +--- a/drivers/hwmon/axi-fan-control.c ++++ b/drivers/hwmon/axi-fan-control.c +@@ -13,8 +13,9 @@ + #include + #include + #include +-#include ++#include + #include ++#include + + /* register map */ + #define ADI_REG_RSTN 0x0080 +@@ -368,12 +369,12 @@ static irqreturn_t axi_fan_control_irq_handler(int irq, void *data) + } + + static int axi_fan_control_init(struct axi_fan_control_data *ctl, +- const struct device_node *np) ++ const struct device *dev) + { + int ret; + + /* get fan pulses per revolution */ +- ret = of_property_read_u32(np, "pulses-per-revolution", &ctl->ppr); ++ ret = device_property_read_u32(dev, "pulses-per-revolution", &ctl->ppr); + if (ret) + return ret; + +@@ -443,25 +444,16 @@ static struct attribute *axi_fan_control_attrs[] = { + }; + ATTRIBUTE_GROUPS(axi_fan_control); + +-static const u32 version_1_0_0 = ADI_AXI_PCORE_VER(1, 0, 'a'); +- +-static const struct of_device_id axi_fan_control_of_match[] = { +- { .compatible = "adi,axi-fan-control-1.00.a", +- .data = (void *)&version_1_0_0}, +- {}, +-}; +-MODULE_DEVICE_TABLE(of, axi_fan_control_of_match); +- + static int axi_fan_control_probe(struct platform_device *pdev) + { + struct axi_fan_control_data *ctl; + struct clk *clk; +- const struct of_device_id *id; ++ const unsigned int *id; + const char *name = "axi_fan_control"; + u32 version; + int ret; + +- id = of_match_node(axi_fan_control_of_match, pdev->dev.of_node); ++ id = device_get_match_data(&pdev->dev); + if (!id) + return -EINVAL; + +@@ -485,18 +477,18 @@ static int axi_fan_control_probe(struct platform_device *pdev) + + version = axi_ioread(ADI_AXI_REG_VERSION, ctl); + if (ADI_AXI_PCORE_VER_MAJOR(version) != +- ADI_AXI_PCORE_VER_MAJOR((*(u32 *)id->data))) { ++ ADI_AXI_PCORE_VER_MAJOR((*id))) { + dev_err(&pdev->dev, "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", +- ADI_AXI_PCORE_VER_MAJOR((*(u32 *)id->data)), +- ADI_AXI_PCORE_VER_MINOR((*(u32 *)id->data)), +- ADI_AXI_PCORE_VER_PATCH((*(u32 *)id->data)), ++ ADI_AXI_PCORE_VER_MAJOR(*id), ++ ADI_AXI_PCORE_VER_MINOR(*id), ++ ADI_AXI_PCORE_VER_PATCH(*id), + ADI_AXI_PCORE_VER_MAJOR(version), + ADI_AXI_PCORE_VER_MINOR(version), + ADI_AXI_PCORE_VER_PATCH(version)); + return -ENODEV; + } + +- ret = axi_fan_control_init(ctl, pdev->dev.of_node); ++ ret = axi_fan_control_init(ctl, &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "Failed to initialize device\n"); + return ret; +@@ -527,6 +519,15 @@ static int axi_fan_control_probe(struct platform_device *pdev) + return 0; + } + ++static const u32 version_1_0_0 = ADI_AXI_PCORE_VER(1, 0, 'a'); ++ ++static const struct of_device_id axi_fan_control_of_match[] = { ++ { .compatible = "adi,axi-fan-control-1.00.a", ++ .data = (void *)&version_1_0_0}, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, axi_fan_control_of_match); ++ + static struct platform_driver axi_fan_control_driver = { + .driver = { + .name = "axi_fan_control_driver", +-- +2.51.0 + diff --git a/queue-6.1/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch b/queue-6.1/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch new file mode 100644 index 0000000000..b5a5bae90b --- /dev/null +++ b/queue-6.1/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch @@ -0,0 +1,43 @@ +From 2307a2ff1de9fcb8b368d53fab2a9c8a2970528b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Mar 2026 12:53:20 +0100 +Subject: hwmon: axi-fan: don't use driver_override as IRQ name +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Danilo Krummrich + +[ Upstream commit 813bbc4d33d2ca5b0da63e70ae13b60874f20d37 ] + +Do not use driver_override as IRQ name, as it is not guaranteed to point +to a valid string; use NULL instead (which makes the devm IRQ helpers +use dev_name()). + +Fixes: 8412b410fa5e ("hwmon: Support ADI Fan Control IP") +Reviewed-by: Nuno Sá +Acked-by: Guenter Roeck +Reviewed-by: Greg Kroah-Hartman +Link: https://patch.msgid.link/20260303115720.48783-4-dakr@kernel.org +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + drivers/hwmon/axi-fan-control.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c +index 15a3455577dd7..ce20f54ce2a09 100644 +--- a/drivers/hwmon/axi-fan-control.c ++++ b/drivers/hwmon/axi-fan-control.c +@@ -507,7 +507,7 @@ static int axi_fan_control_probe(struct platform_device *pdev) + ret = devm_request_threaded_irq(&pdev->dev, ctl->irq, NULL, + axi_fan_control_irq_handler, + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, +- pdev->driver_override, ctl); ++ NULL, ctl); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "failed to request an irq\n"); +-- +2.51.0 + diff --git a/queue-6.1/module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch b/queue-6.1/module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch new file mode 100644 index 0000000000..90f96d6ef6 --- /dev/null +++ b/queue-6.1/module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch @@ -0,0 +1,80 @@ +From 8b73cb2c4009504e9a07842baaef6af0baf90742 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Dec 2025 10:32:08 -0800 +Subject: module: Fix kernel panic when a symbol st_shndx is out of bounds + +From: Ihor Solodrai + +[ Upstream commit f9d69d5e7bde2295eb7488a56f094ac8f5383b92 ] + +The module loader doesn't check for bounds of the ELF section index in +simplify_symbols(): + + for (i = 1; i < symsec->sh_size / sizeof(Elf_Sym); i++) { + const char *name = info->strtab + sym[i].st_name; + + switch (sym[i].st_shndx) { + case SHN_COMMON: + + [...] + + default: + /* Divert to percpu allocation if a percpu var. */ + if (sym[i].st_shndx == info->index.pcpu) + secbase = (unsigned long)mod_percpu(mod); + else + /** HERE --> **/ secbase = info->sechdrs[sym[i].st_shndx].sh_addr; + sym[i].st_value += secbase; + break; + } + } + +A symbol with an out-of-bounds st_shndx value, for example 0xffff +(known as SHN_XINDEX or SHN_HIRESERVE), may cause a kernel panic: + + BUG: unable to handle page fault for address: ... + RIP: 0010:simplify_symbols+0x2b2/0x480 + ... + Kernel panic - not syncing: Fatal exception + +This can happen when module ELF is legitimately using SHN_XINDEX or +when it is corrupted. + +Add a bounds check in simplify_symbols() to validate that st_shndx is +within the valid range before using it. + +This issue was discovered due to a bug in llvm-objcopy, see relevant +discussion for details [1]. + +[1] https://lore.kernel.org/linux-modules/20251224005752.201911-1-ihor.solodrai@linux.dev/ + +Signed-off-by: Ihor Solodrai +Reviewed-by: Daniel Gomez +Reviewed-by: Petr Pavlu +Signed-off-by: Sami Tolvanen +Signed-off-by: Sasha Levin +--- + kernel/module/main.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/kernel/module/main.c b/kernel/module/main.c +index 3269f6c468145..6b3cffd9f8a8a 100644 +--- a/kernel/module/main.c ++++ b/kernel/module/main.c +@@ -1343,6 +1343,13 @@ static int simplify_symbols(struct module *mod, const struct load_info *info) + break; + + default: ++ if (sym[i].st_shndx >= info->hdr->e_shnum) { ++ pr_err("%s: Symbol %s has an invalid section index %u (max %u)\n", ++ mod->name, name, sym[i].st_shndx, info->hdr->e_shnum - 1); ++ ret = -ENOEXEC; ++ break; ++ } ++ + /* Divert to percpu allocation if a percpu var. */ + if (sym[i].st_shndx == info->index.pcpu) + secbase = (unsigned long)mod_percpu(mod); +-- +2.51.0 + diff --git a/queue-6.1/net-usb-r8152-add-trendnet-tuc-et2g.patch b/queue-6.1/net-usb-r8152-add-trendnet-tuc-et2g.patch new file mode 100644 index 0000000000..a32d6fb9a4 --- /dev/null +++ b/queue-6.1/net-usb-r8152-add-trendnet-tuc-et2g.patch @@ -0,0 +1,48 @@ +From 4dfe897f415e473705aa024c94e85709de2a0ea4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Feb 2026 20:54:09 +0100 +Subject: net: usb: r8152: add TRENDnet TUC-ET2G + +From: Valentin Spreckels + +[ Upstream commit 15fba71533bcdfaa8eeba69a5a5a2927afdf664a ] + +The TRENDnet TUC-ET2G is a RTL8156 based usb ethernet adapter. Add its +vendor and product IDs. + +Signed-off-by: Valentin Spreckels +Link: https://patch.msgid.link/20260226195409.7891-2-valentin@spreckels.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/usb/r8152.c | 1 + + include/linux/usb/r8152.h | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c +index fef3e3fd26e6b..15979cd7d15ae 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -9884,6 +9884,7 @@ static const struct usb_device_id rtl8152_table[] = { + { USB_DEVICE(VENDOR_ID_DLINK, 0xb301) }, + { USB_DEVICE(VENDOR_ID_DELL, 0xb097) }, + { USB_DEVICE(VENDOR_ID_ASUS, 0x1976) }, ++ { USB_DEVICE(VENDOR_ID_TRENDNET, 0xe02b) }, + {} + }; + +diff --git a/include/linux/usb/r8152.h b/include/linux/usb/r8152.h +index 2ca60828f28bb..1502b2a355f98 100644 +--- a/include/linux/usb/r8152.h ++++ b/include/linux/usb/r8152.h +@@ -32,6 +32,7 @@ + #define VENDOR_ID_DLINK 0x2001 + #define VENDOR_ID_DELL 0x413c + #define VENDOR_ID_ASUS 0x0b05 ++#define VENDOR_ID_TRENDNET 0x20f4 + + #if IS_REACHABLE(CONFIG_USB_RTL8152) + extern u8 rtl8152_get_version(struct usb_interface *intf); +-- +2.51.0 + diff --git a/queue-6.1/nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch b/queue-6.1/nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch new file mode 100644 index 0000000000..7cfdfea9ce --- /dev/null +++ b/queue-6.1/nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch @@ -0,0 +1,40 @@ +From 5f7f1a6a9bd27c5d3ea6d7ff927223181895cbbb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 31 Jan 2026 19:08:40 -0800 +Subject: nvme-fabrics: use kfree_sensitive() for DHCHAP secrets + +From: Daniel Hodges + +[ Upstream commit 0a1fc2f301529ac75aec0ce80d5ab9d9e4dc4b16 ] + +The DHCHAP secrets (dhchap_secret and dhchap_ctrl_secret) contain +authentication key material for NVMe-oF. Use kfree_sensitive() instead +of kfree() in nvmf_free_options() to ensure secrets are zeroed before +the memory is freed, preventing recovery from freed pages. + +Reviewed-by: Christoph Hellwig +Signed-off-by: Daniel Hodges +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/fabrics.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c +index fe621028a082e..24d3c6f0580a9 100644 +--- a/drivers/nvme/host/fabrics.c ++++ b/drivers/nvme/host/fabrics.c +@@ -1049,8 +1049,8 @@ void nvmf_free_options(struct nvmf_ctrl_options *opts) + kfree(opts->subsysnqn); + kfree(opts->host_traddr); + kfree(opts->host_iface); +- kfree(opts->dhchap_secret); +- kfree(opts->dhchap_ctrl_secret); ++ kfree_sensitive(opts->dhchap_secret); ++ kfree_sensitive(opts->dhchap_ctrl_secret); + kfree(opts); + } + EXPORT_SYMBOL_GPL(nvmf_free_options); +-- +2.51.0 + diff --git a/queue-6.1/nvme-pci-cap-queue-creation-to-used-queues.patch b/queue-6.1/nvme-pci-cap-queue-creation-to-used-queues.patch new file mode 100644 index 0000000000..07138d5f82 --- /dev/null +++ b/queue-6.1/nvme-pci-cap-queue-creation-to-used-queues.patch @@ -0,0 +1,45 @@ +From aae99afff7edb910912940d5bca46aa185e3ac48 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 11:00:12 -0800 +Subject: nvme-pci: cap queue creation to used queues + +From: Keith Busch + +[ Upstream commit 4735b510a00fb2d4ac9e8d21a8c9552cb281f585 ] + +If the user reduces the special queue count at runtime and resets the +controller, we need to reduce the number of queues and interrupts +requested accordingly rather than start with the pre-allocated queue +count. + +Tested-by: Kanchan Joshi +Reviewed-by: Kanchan Joshi +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 518f8c5012bdf..509a788cc7350 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2402,7 +2402,13 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) + dev->nr_write_queues = write_queues; + dev->nr_poll_queues = poll_queues; + +- nr_io_queues = dev->nr_allocated_queues - 1; ++ /* ++ * The initial number of allocated queue slots may be too large if the ++ * user reduced the special queue parameters. Cap the value to the ++ * number we need for this round. ++ */ ++ nr_io_queues = min(nvme_max_io_queues(dev), ++ dev->nr_allocated_queues - 1); + result = nvme_set_queue_count(&dev->ctrl, &nr_io_queues); + if (result < 0) + return result; +-- +2.51.0 + diff --git a/queue-6.1/nvme-pci-ensure-we-re-polling-a-polled-queue.patch b/queue-6.1/nvme-pci-ensure-we-re-polling-a-polled-queue.patch new file mode 100644 index 0000000000..70653b5c3d --- /dev/null +++ b/queue-6.1/nvme-pci-ensure-we-re-polling-a-polled-queue.patch @@ -0,0 +1,39 @@ +From d69401a83c5e083941c1f02f29f8b024f287df65 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 09:26:54 -0800 +Subject: nvme-pci: ensure we're polling a polled queue + +From: Keith Busch + +[ Upstream commit 166e31d7dbf6aa44829b98aa446bda5c9580f12a ] + +A user can change the polled queue count at run time. There's a brief +window during a reset where a hipri task may try to poll that queue +before the block layer has updated the queue maps, which would race with +the now interrupt driven queue and may cause double completions. + +Reviewed-by: Christoph Hellwig +Reviewed-by: Kanchan Joshi +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 509a788cc7350..15bc7d81df4bd 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1167,7 +1167,8 @@ static int nvme_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob) + struct nvme_queue *nvmeq = hctx->driver_data; + bool found; + +- if (!nvme_cqe_pending(nvmeq)) ++ if (!test_bit(NVMEQ_POLLED, &nvmeq->flags) || ++ !nvme_cqe_pending(nvmeq)) + return 0; + + spin_lock(&nvmeq->cq_poll_lock); +-- +2.51.0 + diff --git a/queue-6.1/platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch b/queue-6.1/platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch new file mode 100644 index 0000000000..c5cf3f66db --- /dev/null +++ b/queue-6.1/platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch @@ -0,0 +1,51 @@ +From 7bc792be4b6a0d29b7615d5dddb1710486126472 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 23:46:27 -0500 +Subject: platform/x86: intel-hid: Add Dell 14 Plus 2-in-1 to + dmi_vgbs_allow_list +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Peter Metz + +[ Upstream commit 6b3fa0615cd8432148581de62a52f83847af3d70 ] + +The Dell 14 Plus 2-in-1 (model DB04250) requires the VGBS allow list +entry to correctly enable the tablet mode switch. Without this, the +chassis state is not reported, and the hinge rotation only emits +unknown scancodes. + +Verified on Dell 14 Plus 2-in-1 DB04250. + +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221090 +Signed-off-by: Peter Metz +Reviewed-by: Hans de Goede +Link: https://patch.msgid.link/20260213044627.203638-1-peter.metz@unarin.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/intel/hid.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c +index 051f2bb786e90..6e991cfa90c15 100644 +--- a/drivers/platform/x86/intel/hid.c ++++ b/drivers/platform/x86/intel/hid.c +@@ -156,6 +156,12 @@ static const struct dmi_system_id dmi_vgbs_allow_list[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Dell Pro Rugged 12 Tablet RA02260"), + }, + }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Dell 14 Plus 2-in-1 DB04250"), ++ }, ++ }, + { } + }; + +-- +2.51.0 + diff --git a/queue-6.1/platform-x86-intel-hid-enable-5-button-array-on-thin.patch b/queue-6.1/platform-x86-intel-hid-enable-5-button-array-on-thin.patch new file mode 100644 index 0000000000..fba6e9657f --- /dev/null +++ b/queue-6.1/platform-x86-intel-hid-enable-5-button-array-on-thin.patch @@ -0,0 +1,52 @@ +From bd3c2f2de35d32410e3c99cb7a3363b2a466a414 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 09:56:25 +0100 +Subject: platform/x86: intel-hid: Enable 5-button array on ThinkPad X1 Fold 16 + Gen 1 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Leif Skunberg + +[ Upstream commit b38d478dad79e61e8a65931021bdfd7a71741212 ] + +The Lenovo ThinkPad X1 Fold 16 Gen 1 has physical volume up/down +buttons that are handled through the intel-hid 5-button array +interface. The firmware does not advertise 5-button array support via +HEBC, so the driver relies on a DMI allowlist to enable it. + +Add the ThinkPad X1 Fold 16 Gen 1 to the button_array_table so the +volume buttons work out of the box. + +Signed-off-by: Leif Skunberg +Reviewed-by: Hans de Goede +Link: https://patch.msgid.link/20260210085625.34380-1-diamondback@cohunt.app +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/intel/hid.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c +index 6e991cfa90c15..761d88929ef97 100644 +--- a/drivers/platform/x86/intel/hid.c ++++ b/drivers/platform/x86/intel/hid.c +@@ -102,6 +102,13 @@ static const struct dmi_system_id button_array_table[] = { + DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Tablet Gen 2"), + }, + }, ++ { ++ .ident = "Lenovo ThinkPad X1 Fold 16 Gen 1", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Fold 16 Gen 1"), ++ }, ++ }, + { + .ident = "Microsoft Surface Go 3", + .matches = { +-- +2.51.0 + diff --git a/queue-6.1/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch b/queue-6.1/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch new file mode 100644 index 0000000000..7b8745695c --- /dev/null +++ b/queue-6.1/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch @@ -0,0 +1,71 @@ +From b382fabaf952ec1d47fcd993e0cf799fde4aea55 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 14:23:46 +0100 +Subject: platform/x86: touchscreen_dmi: Add quirk for y-inverted Goodix + touchscreen on SUPI S10 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Hans de Goede + +[ Upstream commit 7d87ed70fc95482c12edf9493c249b6413be485e ] + +The touchscreen on the SUPI S10 tablet reports inverted Y coordinates, +causing touch input to be mirrored vertically relative to the display. + +Add a quirk to set the "touchscreen-inverted-y" boolean device-property +on the touchscreen device, so that the goodix_ts driver will fixup +the coordinates. + +Reported-by: Yajat Kumar +Closes: https://lore.kernel.org/linux-input/20251230221639.582406-1-yajatapps3@gmail.com/ +Tested-by: Yajat Kumar +Signed-off-by: Hans de Goede +Link: https://patch.msgid.link/20260217132346.34535-1-johannes.goede@oss.qualcomm.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/touchscreen_dmi.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c +index 427c590102a19..4612370b43469 100644 +--- a/drivers/platform/x86/touchscreen_dmi.c ++++ b/drivers/platform/x86/touchscreen_dmi.c +@@ -399,6 +399,16 @@ static const struct ts_dmi_data gdix1002_00_upside_down_data = { + .properties = gdix1001_upside_down_props, + }; + ++static const struct property_entry gdix1001_y_inverted_props[] = { ++ PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), ++ { } ++}; ++ ++static const struct ts_dmi_data gdix1001_y_inverted_data = { ++ .acpi_name = "GDIX1001", ++ .properties = gdix1001_y_inverted_props, ++}; ++ + static const struct property_entry gp_electronic_t701_props[] = { + PROPERTY_ENTRY_U32("touchscreen-size-x", 960), + PROPERTY_ENTRY_U32("touchscreen-size-y", 640), +@@ -1646,6 +1656,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_SKU, "PN20170413488"), + }, + }, ++ { ++ /* SUPI S10 */ ++ .driver_data = (void *)&gdix1001_y_inverted_data, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "SUPI"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "S10"), ++ }, ++ }, + { + /* Techbite Arc 11.6 */ + .driver_data = (void *)&techbite_arc_11_6_data, +-- +2.51.0 + diff --git a/queue-6.1/series b/queue-6.1/series new file mode 100644 index 0000000000..dd48da9c07 --- /dev/null +++ b/queue-6.1/series @@ -0,0 +1,25 @@ +hwmon-axi-fan-control-use-device-firmware-agnostic-a.patch +hwmon-axi-fan-control-make-use-of-dev_err_probe.patch +hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch +sh-platform_early-remove-pdev-driver_override-check.patch +bpf-release-module-btf-idr-before-module-unload.patch +hid-asus-avoid-memory-leak-in-asus_report_fixup.patch +platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch +nvme-pci-cap-queue-creation-to-used-queues.patch +nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch +platform-x86-intel-hid-enable-5-button-array-on-thin.patch +platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch +nvme-pci-ensure-we-re-polling-a-polled-queue.patch +hid-magicmouse-fix-battery-reporting-for-apple-magic.patch +hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch +net-usb-r8152-add-trendnet-tuc-et2g.patch +hid-mcp2221-cancel-last-i2c-command-on-read-error.patch +module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch +asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch +asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-8112 +dma-buf-include-ioctl.h-in-uapi-header.patch +hid-apple-avoid-memory-leak-in-apple_report_fixup.patch +btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch +alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch +alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch +usb-core-new-quirk-to-handle-devices-with-zero-confi.patch diff --git a/queue-6.1/sh-platform_early-remove-pdev-driver_override-check.patch b/queue-6.1/sh-platform_early-remove-pdev-driver_override-check.patch new file mode 100644 index 0000000000..0f4c4e9bc6 --- /dev/null +++ b/queue-6.1/sh-platform_early-remove-pdev-driver_override-check.patch @@ -0,0 +1,45 @@ +From 081e34e891a3b379feb0ebf1ae798298d555acfb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Mar 2026 00:37:15 +0100 +Subject: sh: platform_early: remove pdev->driver_override check + +From: Danilo Krummrich + +[ Upstream commit c5f60e3f07b6609562d21efda878e83ce8860728 ] + +In commit 507fd01d5333 ("drivers: move the early platform device support to +arch/sh") platform_match() was copied over to the sh platform_early +code, accidentally including the driver_override check. + +This check does not make sense for platform_early, as sysfs is not even +available in first place at this point in the boot process, hence remove +the check. + +Reviewed-by: Greg Kroah-Hartman +Reviewed-by: Geert Uytterhoeven +Fixes: 507fd01d5333 ("drivers: move the early platform device support to arch/sh") +Link: https://lore.kernel.org/all/DH4M3DJ4P58T.1BGVAVXN71Z09@kernel.org/ +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + arch/sh/drivers/platform_early.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c +index 143747c45206f..48ddbc547bd9a 100644 +--- a/arch/sh/drivers/platform_early.c ++++ b/arch/sh/drivers/platform_early.c +@@ -26,10 +26,6 @@ static int platform_match(struct device *dev, struct device_driver *drv) + struct platform_device *pdev = to_platform_device(dev); + struct platform_driver *pdrv = to_platform_driver(drv); + +- /* When driver_override is set, only bind to the matching driver */ +- if (pdev->driver_override) +- return !strcmp(pdev->driver_override, drv->name); +- + /* Then try to match against the id table */ + if (pdrv->id_table) + return platform_match_id(pdrv->id_table, pdev) != NULL; +-- +2.51.0 + diff --git a/queue-6.1/usb-core-new-quirk-to-handle-devices-with-zero-confi.patch b/queue-6.1/usb-core-new-quirk-to-handle-devices-with-zero-confi.patch new file mode 100644 index 0000000000..838fc314ee --- /dev/null +++ b/queue-6.1/usb-core-new-quirk-to-handle-devices-with-zero-confi.patch @@ -0,0 +1,107 @@ +From f9be5e17aa927cf8bed0a0f3748a67987d613402 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Feb 2026 16:49:31 +0800 +Subject: usb: core: new quirk to handle devices with zero configurations + +From: Jie Deng + +[ Upstream commit 9f6a983cfa22ac662c86e60816d3a357d4b551e9 ] + +Some USB devices incorrectly report bNumConfigurations as 0 in their +device descriptor, which causes the USB core to reject them during +enumeration. +logs: +usb 1-2: device descriptor read/64, error -71 +usb 1-2: no configurations +usb 1-2: can't read configurations, error -22 + +However, these devices actually work correctly when +treated as having a single configuration. + +Add a new quirk USB_QUIRK_FORCE_ONE_CONFIG to handle such devices. +When this quirk is set, assume the device has 1 configuration instead +of failing with -EINVAL. + +This quirk is applied to the device with VID:PID 5131:2007 which +exhibits this behavior. + +Signed-off-by: Jie Deng +Link: https://patch.msgid.link/20260227084931.1527461-1-dengjie03@kylinos.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + Documentation/admin-guide/kernel-parameters.txt | 3 +++ + drivers/usb/core/config.c | 6 +++++- + drivers/usb/core/quirks.c | 5 +++++ + include/linux/usb/quirks.h | 3 +++ + 4 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index b026eb1c4c7db..33744e931489a 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -6643,6 +6643,9 @@ + p = USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT + (Reduce timeout of the SET_ADDRESS + request from 5000 ms to 500 ms); ++ q = USB_QUIRK_FORCE_ONE_CONFIG (Device ++ claims zero configurations, ++ forcing to 1); + Example: quirks=0781:5580:bk,0a5c:5834:gij + + usbhid.mousepoll= +diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c +index 4ca54506a1ac0..de9e885563985 100644 +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -891,7 +891,11 @@ int usb_get_configuration(struct usb_device *dev) + dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG; + } + +- if (ncfg < 1) { ++ if (ncfg < 1 && dev->quirks & USB_QUIRK_FORCE_ONE_CONFIG) { ++ dev_info(ddev, "Device claims zero configurations, forcing to 1\n"); ++ dev->descriptor.bNumConfigurations = 1; ++ ncfg = 1; ++ } else if (ncfg < 1) { + dev_err(ddev, "no configurations\n"); + return -EINVAL; + } +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index c12942a533ce2..53b08d6cf7824 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -141,6 +141,8 @@ static int quirks_param_set(const char *value, const struct kernel_param *kp) + case 'p': + flags |= USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT; + break; ++ case 'q': ++ flags |= USB_QUIRK_FORCE_ONE_CONFIG; + /* Ignore unrecognized flag characters */ + } + } +@@ -594,6 +596,9 @@ static const struct usb_device_id usb_quirk_list[] = { + /* VCOM device */ + { USB_DEVICE(0x4296, 0x7570), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS }, + ++ /* Noji-MCS SmartCard Reader */ ++ { USB_DEVICE(0x5131, 0x2007), .driver_info = USB_QUIRK_FORCE_ONE_CONFIG }, ++ + /* INTEL VALUE SSD */ + { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, + +diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h +index 2f7bd2fdc6164..b3cc7beab4a3c 100644 +--- a/include/linux/usb/quirks.h ++++ b/include/linux/usb/quirks.h +@@ -78,4 +78,7 @@ + /* skip BOS descriptor request */ + #define USB_QUIRK_NO_BOS BIT(17) + ++/* Device claims zero configurations, forcing to 1 */ ++#define USB_QUIRK_FORCE_ONE_CONFIG BIT(18) ++ + #endif /* __LINUX_USB_QUIRKS_H */ +-- +2.51.0 + diff --git a/queue-6.12/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch b/queue-6.12/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch new file mode 100644 index 0000000000..0566c77fba --- /dev/null +++ b/queue-6.12/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch @@ -0,0 +1,43 @@ +From cbbaa08d5d0a8b98abe56c23e92f47d90f1f23ff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Mar 2026 06:29:06 +0500 +Subject: ALSA: hda/realtek: Add headset jack quirk for Thinkpad X390 + +From: Uzair Mughal + +[ Upstream commit 542127f6528ca7cc3cf61e1651d6ccb58495f953 ] + +The Lenovo ThinkPad X390 (ALC257 codec, subsystem ID 0x17aa2288) +does not report headset button press events. Headphone insertion is +detected (SW_HEADPHONE_INSERT), but pressing the inline microphone +button on a headset produces no input events. + +Add a SND_PCI_QUIRK entry that maps this subsystem ID to +ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, which enables +headset jack button detection through alc_fixup_headset_jack() +and ThinkPad ACPI integration. This is the same fixup used by +similar ThinkPad models (P1 Gen 3, X1 Extreme Gen 3). + +Signed-off-by: Uzair Mughal +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20260307012906.20093-1-contact@uzair.is-a.dev +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 77623373fad3d..79bbe9894c35f 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -11449,6 +11449,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), + SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), + SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), ++ SND_PCI_QUIRK(0x17aa, 0x2288, "Thinkpad X390", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x22c1, "Thinkpad P1 Gen 3", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), +-- +2.51.0 + diff --git a/queue-6.12/alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch b/queue-6.12/alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch new file mode 100644 index 0000000000..0623961421 --- /dev/null +++ b/queue-6.12/alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch @@ -0,0 +1,38 @@ +From 2e51e6b9b505288ddacf27ed107ca112d28dc021 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Mar 2026 11:27:27 +0800 +Subject: ALSA: hda/realtek: add HP Laptop 14s-dr5xxx mute LED quirk + +From: Liucheng Lu + +[ Upstream commit 178dd118c0f07fd63a9ed74cfbd8c31ae50e33af ] + +HP Laptop 14s-dr5xxx with ALC236 codec does not handle the toggling of +the mute LED. +This patch adds a quirk entry for subsystem ID 0x8a1f using +ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 fixup, enabling correct mute LED +behavior. + +Signed-off-by: Liucheng Lu +Link: https://patch.msgid.link/PAVPR03MB9774F3FCE9CCD181C585281AE37BA@PAVPR03MB9774.eurprd03.prod.outlook.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index cb6ff3c36c5f0..77623373fad3d 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10953,6 +10953,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x89d3, "HP EliteBook 645 G9 (MB 89D2)", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x89e7, "HP Elite x2 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8a0f, "HP Pavilion 14-ec1xxx", ALC287_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8a1f, "HP Laptop 14s-dr5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), + SND_PCI_QUIRK(0x103c, 0x8a26, "HP Victus 16-d1xxx (MB 8A26)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), +-- +2.51.0 + diff --git a/queue-6.12/alsa-hda-realtek-add-quirk-for-asus-um6702rc.patch b/queue-6.12/alsa-hda-realtek-add-quirk-for-asus-um6702rc.patch new file mode 100644 index 0000000000..cea5f39400 --- /dev/null +++ b/queue-6.12/alsa-hda-realtek-add-quirk-for-asus-um6702rc.patch @@ -0,0 +1,37 @@ +From 55a88e763d5c1c02dafb68b75095f63451ed01d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 20:33:17 +0800 +Subject: ALSA: hda/realtek: add quirk for ASUS UM6702RC + +From: Zhang Heng + +[ Upstream commit 0d3429f12133c2ca47aa82ddab2342bc360c47d3 ] + +The sound card of this machine cannot adjust the volume, it can only +be 0 or 100%. The reason is that the DAC with pin 0x17 is connected +to 0x06. Testing found that connecting 0x02 can fix this problem. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=220356 +Signed-off-by: Zhang Heng +Link: https://patch.msgid.link/20260306123317.575346-1-zhangheng@kylinos.cn +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 79bbe9894c35f..689b5510a95e8 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -11234,6 +11234,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x1eb3, "ASUS Ally RCLA72", ALC287_FIXUP_TAS2781_I2C), + SND_PCI_QUIRK(0x1043, 0x1ed3, "ASUS HN7306W", ALC287_FIXUP_CS35L41_I2C_2), ++ HDA_CODEC_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC285_FIXUP_ASUS_I2C_SPEAKER2_TO_DAC1), + SND_PCI_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), +-- +2.51.0 + diff --git a/queue-6.12/alsa-hda-senary-ensure-eapd-is-enabled-during-init.patch b/queue-6.12/alsa-hda-senary-ensure-eapd-is-enabled-during-init.patch new file mode 100644 index 0000000000..d2f5eac261 --- /dev/null +++ b/queue-6.12/alsa-hda-senary-ensure-eapd-is-enabled-during-init.patch @@ -0,0 +1,56 @@ +From 103128e0e0b1f1e7902d5dab0001e2e264f79522 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Mar 2026 16:15:16 +0800 +Subject: ALSA: hda/senary: Ensure EAPD is enabled during init + +From: wangdicheng + +[ Upstream commit 7ae0d8f1abbbba6f98cac735145e1206927c67d9 ] + +The driver sets spec->gen.own_eapd_ctl to take manual control of the +EAPD (External Amplifier). However, senary_init does not turn on the +EAPD, while senary_shutdown turns it off. + +Since the generic driver skips EAPD handling when own_eapd_ctl is set, +the EAPD remains off after initialization (e.g., after resume), leaving +the codec in a non-functional state. + +Explicitly call senary_auto_turn_eapd in senary_init to ensure the EAPD +is enabled and the codec is functional. + +Signed-off-by: wangdicheng +Link: https://patch.msgid.link/20260303081516.583438-1-wangdich9700@163.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_senarytech.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/sound/pci/hda/patch_senarytech.c b/sound/pci/hda/patch_senarytech.c +index 0691996fa971c..2ebc5b5a4fc36 100644 +--- a/sound/pci/hda/patch_senarytech.c ++++ b/sound/pci/hda/patch_senarytech.c +@@ -25,6 +25,7 @@ struct senary_spec { + /* extra EAPD pins */ + unsigned int num_eapds; + hda_nid_t eapds[4]; ++ bool dynamic_eapd; + hda_nid_t mute_led_eapd; + + unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */ +@@ -131,8 +132,12 @@ static void senary_init_gpio_led(struct hda_codec *codec) + + static int senary_auto_init(struct hda_codec *codec) + { ++ struct senary_spec *spec = codec->spec; ++ + snd_hda_gen_init(codec); + senary_init_gpio_led(codec); ++ if (!spec->dynamic_eapd) ++ senary_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); + + return 0; +-- +2.51.0 + diff --git a/queue-6.12/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch b/queue-6.12/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch new file mode 100644 index 0000000000..31edea34ce --- /dev/null +++ b/queue-6.12/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch @@ -0,0 +1,52 @@ +From 376b751660e521eb3e912eb247f184fbc8f3b0ab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 00:25:38 +0000 +Subject: ASoC: fsl_easrc: Fix event generation in fsl_easrc_iec958_set_reg() + +From: Mark Brown + +[ Upstream commit 31ddc62c1cd92e51b9db61d7954b85ae2ec224da ] + +ALSA controls should return 1 if the value in the control changed but the +control put operation fsl_easrc_set_reg() only returns 0 or a negative +error code, causing ALSA to not generate any change events. Add a suitable +check by using regmap_update_bits_check() with the underlying regmap, this +is more clearly and simply correct than trying to verify that one of the +generic ops is exactly equivalent to this one. + +Signed-off-by: Mark Brown +Link: https://patch.msgid.link/20260205-asoc-fsl-easrc-fix-events-v1-2-39d4c766918b@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_easrc.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c +index 82359edd6a8b4..7aaea441f7a57 100644 +--- a/sound/soc/fsl/fsl_easrc.c ++++ b/sound/soc/fsl/fsl_easrc.c +@@ -93,14 +93,17 @@ static int fsl_easrc_set_reg(struct snd_kcontrol *kcontrol, + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_value; ++ struct fsl_asrc *easrc = snd_soc_component_get_drvdata(component); + unsigned int regval = ucontrol->value.integer.value[0]; ++ bool changed; + int ret; + +- ret = snd_soc_component_write(component, mc->regbase, regval); +- if (ret < 0) ++ ret = regmap_update_bits_check(easrc->regmap, mc->regbase, ++ GENMASK(31, 0), regval, &changed); ++ if (ret != 0) + return ret; + +- return 0; ++ return changed; + } + + #define SOC_SINGLE_REG_RW(xname, xreg) \ +-- +2.51.0 + diff --git a/queue-6.12/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-13155 b/queue-6.12/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-13155 new file mode 100644 index 0000000000..e1a0642fbe --- /dev/null +++ b/queue-6.12/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-13155 @@ -0,0 +1,49 @@ +From abb4a287113848ce1ae863218435d5bbef4a5e95 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 00:25:37 +0000 +Subject: ASoC: fsl_easrc: Fix event generation in fsl_easrc_iec958_put_bits() + +From: Mark Brown + +[ Upstream commit 54a86cf48eaa6d1ab5130d756b718775e81e1748 ] + +ALSA controls should return 1 if the value in the control changed but the +control put operation fsl_easrc_iec958_put_bits() unconditionally returns +0, causing ALSA to not generate any change events. This is detected by +mixer-test with large numbers of messages in the form: + + No event generated for Context 3 IEC958 CS5 + Context 3 IEC958 CS5.0 orig 5224 read 5225, is_volatile 0 + +Add a suitable check. + +Signed-off-by: Mark Brown +Link: https://patch.msgid.link/20260205-asoc-fsl-easrc-fix-events-v1-1-39d4c766918b@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_easrc.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c +index 7aaea441f7a57..683792f29688c 100644 +--- a/sound/soc/fsl/fsl_easrc.c ++++ b/sound/soc/fsl/fsl_easrc.c +@@ -52,10 +52,13 @@ static int fsl_easrc_iec958_put_bits(struct snd_kcontrol *kcontrol, + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_value; + unsigned int regval = ucontrol->value.integer.value[0]; ++ int ret; ++ ++ ret = (easrc_priv->bps_iec958[mc->regbase] != regval); + + easrc_priv->bps_iec958[mc->regbase] = regval; + +- return 0; ++ return ret; + } + + static int fsl_easrc_iec958_get_bits(struct snd_kcontrol *kcontrol, +-- +2.51.0 + diff --git a/queue-6.12/bpf-fix-constant-blinding-for-probe_mem32-stores.patch b/queue-6.12/bpf-fix-constant-blinding-for-probe_mem32-stores.patch new file mode 100644 index 0000000000..254fa7f6be --- /dev/null +++ b/queue-6.12/bpf-fix-constant-blinding-for-probe_mem32-stores.patch @@ -0,0 +1,77 @@ +From c060c7dd4c703474824e7d6a963d06b5cd170c1a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Mar 2026 18:25:42 +0000 +Subject: bpf: Fix constant blinding for PROBE_MEM32 stores + +From: Sachin Kumar + +[ Upstream commit 2321a9596d2260310267622e0ad8fbfa6f95378f ] + +BPF_ST | BPF_PROBE_MEM32 immediate stores are not handled by +bpf_jit_blind_insn(), allowing user-controlled 32-bit immediates to +survive unblinded into JIT-compiled native code when bpf_jit_harden >= 1. + +The root cause is that convert_ctx_accesses() rewrites BPF_ST|BPF_MEM +to BPF_ST|BPF_PROBE_MEM32 for arena pointer stores during verification, +before bpf_jit_blind_constants() runs during JIT compilation. The +blinding switch only matches BPF_ST|BPF_MEM (mode 0x60), not +BPF_ST|BPF_PROBE_MEM32 (mode 0xa0). The instruction falls through +unblinded. + +Add BPF_ST|BPF_PROBE_MEM32 cases to bpf_jit_blind_insn() alongside the +existing BPF_ST|BPF_MEM cases. The blinding transformation is identical: +load the blinded immediate into BPF_REG_AX via mov+xor, then convert +the immediate store to a register store (BPF_STX). + +The rewritten STX instruction must preserve the BPF_PROBE_MEM32 mode so +the architecture JIT emits the correct arena addressing (R12-based on +x86-64). Cannot use the BPF_STX_MEM() macro here because it hardcodes +BPF_MEM mode; construct the instruction directly instead. + +Fixes: 6082b6c328b5 ("bpf: Recognize addr_space_cast instruction in the verifier.") +Reviewed-by: Puranjay Mohan +Reviewed-by: Emil Tsalapatis +Signed-off-by: Sachin Kumar +Acked-by: Daniel Borkmann +Link: https://lore.kernel.org/r/Y6IT5VvNRchPBLI5D7JZHBzZrU9rb0ycRJPJzJSXGj7kJlX8RJwZFSM2YZjcDxoQKABkxt1T8Os2gi23PYyFuQe6KkZGWVyfz8K5afdy9ak=@protonmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/core.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c +index 76dfa9ab43a5d..fbd5d292d8bf9 100644 +--- a/kernel/bpf/core.c ++++ b/kernel/bpf/core.c +@@ -1424,6 +1424,27 @@ static int bpf_jit_blind_insn(const struct bpf_insn *from, + *to++ = BPF_ALU64_IMM(BPF_XOR, BPF_REG_AX, imm_rnd); + *to++ = BPF_STX_MEM(from->code, from->dst_reg, BPF_REG_AX, from->off); + break; ++ ++ case BPF_ST | BPF_PROBE_MEM32 | BPF_DW: ++ case BPF_ST | BPF_PROBE_MEM32 | BPF_W: ++ case BPF_ST | BPF_PROBE_MEM32 | BPF_H: ++ case BPF_ST | BPF_PROBE_MEM32 | BPF_B: ++ *to++ = BPF_ALU64_IMM(BPF_MOV, BPF_REG_AX, imm_rnd ^ ++ from->imm); ++ *to++ = BPF_ALU64_IMM(BPF_XOR, BPF_REG_AX, imm_rnd); ++ /* ++ * Cannot use BPF_STX_MEM() macro here as it ++ * hardcodes BPF_MEM mode, losing PROBE_MEM32 ++ * and breaking arena addressing in the JIT. ++ */ ++ *to++ = (struct bpf_insn) { ++ .code = BPF_STX | BPF_PROBE_MEM32 | ++ BPF_SIZE(from->code), ++ .dst_reg = from->dst_reg, ++ .src_reg = BPF_REG_AX, ++ .off = from->off, ++ }; ++ break; + } + out: + return to - to_buff; +-- +2.51.0 + diff --git a/queue-6.12/bpf-fix-u32-s32-bounds-when-ranges-cross-min-max-bou.patch b/queue-6.12/bpf-fix-u32-s32-bounds-when-ranges-cross-min-max-bou.patch new file mode 100644 index 0000000000..6e287e0224 --- /dev/null +++ b/queue-6.12/bpf-fix-u32-s32-bounds-when-ranges-cross-min-max-bou.patch @@ -0,0 +1,201 @@ +From ae7a77ae8f09d9668f64617a272456b45d736631 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 16:54:24 -0800 +Subject: bpf: Fix u32/s32 bounds when ranges cross min/max boundary +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Eduard Zingerman + +[ Upstream commit fbc7aef517d8765e4c425d2792409bb9bf2e1f13 ] + +Same as in __reg64_deduce_bounds(), refine s32/u32 ranges +in __reg32_deduce_bounds() in the following situations: + +- s32 range crosses U32_MAX/0 boundary, positive part of the s32 range + overlaps with u32 range: + + 0 U32_MAX + | [xxxxxxxxxxxxxx u32 range xxxxxxxxxxxxxx] | + |----------------------------|----------------------------| + |xxxxx s32 range xxxxxxxxx] [xxxxxxx| + 0 S32_MAX S32_MIN -1 + +- s32 range crosses U32_MAX/0 boundary, negative part of the s32 range + overlaps with u32 range: + + 0 U32_MAX + | [xxxxxxxxxxxxxx u32 range xxxxxxxxxxxxxx] | + |----------------------------|----------------------------| + |xxxxxxxxx] [xxxxxxxxxxxx s32 range | + 0 S32_MAX S32_MIN -1 + +- No refinement if ranges overlap in two intervals. + +This helps for e.g. consider the following program: + + call %[bpf_get_prandom_u32]; + w0 &= 0xffffffff; + if w0 < 0x3 goto 1f; // on fall-through u32 range [3..U32_MAX] + if w0 s> 0x1 goto 1f; // on fall-through s32 range [S32_MIN..1] + if w0 s< 0x0 goto 1f; // range can be narrowed to [S32_MIN..-1] + r10 = 0; +1: ...; + +The reg_bounds.c selftest is updated to incorporate identical logic, +refinement based on non-overflowing range halves: + + ((x ∩ [0, smax]) ∩ (y ∩ [0, smax])) ∪ + ((x ∩ [smin,-1]) ∩ (y ∩ [smin,-1])) + +Reported-by: Andrea Righi +Reported-by: Emil Tsalapatis +Closes: https://lore.kernel.org/bpf/aakqucg4vcujVwif@gpd4/T/ +Reviewed-by: Emil Tsalapatis +Acked-by: Shung-Hsi Yu +Signed-off-by: Eduard Zingerman +Link: https://lore.kernel.org/r/20260306-bpf-32-bit-range-overflow-v3-1-f7f67e060a6b@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 24 +++++++ + .../selftests/bpf/prog_tests/reg_bounds.c | 62 +++++++++++++++++-- + 2 files changed, 82 insertions(+), 4 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 68fa30852051e..0195726266f4d 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -2046,6 +2046,30 @@ static void __reg32_deduce_bounds(struct bpf_reg_state *reg) + if ((u32)reg->s32_min_value <= (u32)reg->s32_max_value) { + reg->u32_min_value = max_t(u32, reg->s32_min_value, reg->u32_min_value); + reg->u32_max_value = min_t(u32, reg->s32_max_value, reg->u32_max_value); ++ } else { ++ if (reg->u32_max_value < (u32)reg->s32_min_value) { ++ /* See __reg64_deduce_bounds() for detailed explanation. ++ * Refine ranges in the following situation: ++ * ++ * 0 U32_MAX ++ * | [xxxxxxxxxxxxxx u32 range xxxxxxxxxxxxxx] | ++ * |----------------------------|----------------------------| ++ * |xxxxx s32 range xxxxxxxxx] [xxxxxxx| ++ * 0 S32_MAX S32_MIN -1 ++ */ ++ reg->s32_min_value = (s32)reg->u32_min_value; ++ reg->u32_max_value = min_t(u32, reg->u32_max_value, reg->s32_max_value); ++ } else if ((u32)reg->s32_max_value < reg->u32_min_value) { ++ /* ++ * 0 U32_MAX ++ * | [xxxxxxxxxxxxxx u32 range xxxxxxxxxxxxxx] | ++ * |----------------------------|----------------------------| ++ * |xxxxxxxxx] [xxxxxxxxxxxx s32 range | ++ * 0 S32_MAX S32_MIN -1 ++ */ ++ reg->s32_max_value = (s32)reg->u32_max_value; ++ reg->u32_min_value = max_t(u32, reg->u32_min_value, reg->s32_min_value); ++ } + } + } + +diff --git a/tools/testing/selftests/bpf/prog_tests/reg_bounds.c b/tools/testing/selftests/bpf/prog_tests/reg_bounds.c +index 39d42271cc460..ac4e2557f7391 100644 +--- a/tools/testing/selftests/bpf/prog_tests/reg_bounds.c ++++ b/tools/testing/selftests/bpf/prog_tests/reg_bounds.c +@@ -422,15 +422,69 @@ static bool is_valid_range(enum num_t t, struct range x) + } + } + +-static struct range range_improve(enum num_t t, struct range old, struct range new) ++static struct range range_intersection(enum num_t t, struct range old, struct range new) + { + return range(t, max_t(t, old.a, new.a), min_t(t, old.b, new.b)); + } + ++/* ++ * Result is precise when 'x' and 'y' overlap or form a continuous range, ++ * result is an over-approximation if 'x' and 'y' do not overlap. ++ */ ++static struct range range_union(enum num_t t, struct range x, struct range y) ++{ ++ if (!is_valid_range(t, x)) ++ return y; ++ if (!is_valid_range(t, y)) ++ return x; ++ return range(t, min_t(t, x.a, y.a), max_t(t, x.b, y.b)); ++} ++ ++/* ++ * This function attempts to improve x range intersecting it with y. ++ * range_cast(... to_t ...) looses precision for ranges that pass to_t ++ * min/max boundaries. To avoid such precision loses this function ++ * splits both x and y into halves corresponding to non-overflowing ++ * sub-ranges: [0, smin] and [smax, -1]. ++ * Final result is computed as follows: ++ * ++ * ((x ∩ [0, smax]) ∩ (y ∩ [0, smax])) ∪ ++ * ((x ∩ [smin,-1]) ∩ (y ∩ [smin,-1])) ++ * ++ * Precision might still be lost if final union is not a continuous range. ++ */ ++static struct range range_refine_in_halves(enum num_t x_t, struct range x, ++ enum num_t y_t, struct range y) ++{ ++ struct range x_pos, x_neg, y_pos, y_neg, r_pos, r_neg; ++ u64 smax, smin, neg_one; ++ ++ if (t_is_32(x_t)) { ++ smax = (u64)(u32)S32_MAX; ++ smin = (u64)(u32)S32_MIN; ++ neg_one = (u64)(u32)(s32)(-1); ++ } else { ++ smax = (u64)S64_MAX; ++ smin = (u64)S64_MIN; ++ neg_one = U64_MAX; ++ } ++ x_pos = range_intersection(x_t, x, range(x_t, 0, smax)); ++ x_neg = range_intersection(x_t, x, range(x_t, smin, neg_one)); ++ y_pos = range_intersection(y_t, y, range(x_t, 0, smax)); ++ y_neg = range_intersection(y_t, y, range(y_t, smin, neg_one)); ++ r_pos = range_intersection(x_t, x_pos, range_cast(y_t, x_t, y_pos)); ++ r_neg = range_intersection(x_t, x_neg, range_cast(y_t, x_t, y_neg)); ++ return range_union(x_t, r_pos, r_neg); ++ ++} ++ + static struct range range_refine(enum num_t x_t, struct range x, enum num_t y_t, struct range y) + { + struct range y_cast; + ++ if (t_is_32(x_t) == t_is_32(y_t)) ++ x = range_refine_in_halves(x_t, x, y_t, y); ++ + y_cast = range_cast(y_t, x_t, y); + + /* If we know that +@@ -444,7 +498,7 @@ static struct range range_refine(enum num_t x_t, struct range x, enum num_t y_t, + */ + if (x_t == S64 && y_t == S32 && y_cast.a <= S32_MAX && y_cast.b <= S32_MAX && + (s64)x.a >= S32_MIN && (s64)x.b <= S32_MAX) +- return range_improve(x_t, x, y_cast); ++ return range_intersection(x_t, x, y_cast); + + /* the case when new range knowledge, *y*, is a 32-bit subregister + * range, while previous range knowledge, *x*, is a full register +@@ -462,11 +516,11 @@ static struct range range_refine(enum num_t x_t, struct range x, enum num_t y_t, + x_swap = range(x_t, swap_low32(x.a, y_cast.a), swap_low32(x.b, y_cast.b)); + if (!is_valid_range(x_t, x_swap)) + return x; +- return range_improve(x_t, x, x_swap); ++ return range_intersection(x_t, x, x_swap); + } + + /* otherwise, plain range cast and intersection works */ +- return range_improve(x_t, x, y_cast); ++ return range_intersection(x_t, x, y_cast); + } + + /* ======================= +-- +2.51.0 + diff --git a/queue-6.12/bpf-fix-undefined-behavior-in-interpreter-sdiv-smod-.patch b/queue-6.12/bpf-fix-undefined-behavior-in-interpreter-sdiv-smod-.patch new file mode 100644 index 0000000000..7a872eba57 --- /dev/null +++ b/queue-6.12/bpf-fix-undefined-behavior-in-interpreter-sdiv-smod-.patch @@ -0,0 +1,104 @@ +From af5d25c024408dc8f3d89a95a8af78b1151a6724 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Mar 2026 01:11:15 +0000 +Subject: bpf: Fix undefined behavior in interpreter sdiv/smod for INT_MIN + +From: Jenny Guanni Qu + +[ Upstream commit c77b30bd1dcb61f66c640ff7d2757816210c7cb0 ] + +The BPF interpreter's signed 32-bit division and modulo handlers use +the kernel abs() macro on s32 operands. The abs() macro documentation +(include/linux/math.h) explicitly states the result is undefined when +the input is the type minimum. When DST contains S32_MIN (0x80000000), +abs((s32)DST) triggers undefined behavior and returns S32_MIN unchanged +on arm64/x86. This value is then sign-extended to u64 as +0xFFFFFFFF80000000, causing do_div() to compute the wrong result. + +The verifier's abstract interpretation (scalar32_min_max_sdiv) computes +the mathematically correct result for range tracking, creating a +verifier/interpreter mismatch that can be exploited for out-of-bounds +map value access. + +Introduce abs_s32() which handles S32_MIN correctly by casting to u32 +before negating, avoiding signed overflow entirely. Replace all 8 +abs((s32)...) call sites in the interpreter's sdiv32/smod32 handlers. + +s32 is the only affected case -- the s64 division/modulo handlers do +not use abs(). + +Fixes: ec0e2da95f72 ("bpf: Support new signed div/mod instructions.") +Acked-by: Yonghong Song +Acked-by: Mykyta Yatsenko +Signed-off-by: Jenny Guanni Qu +Link: https://lore.kernel.org/r/20260311011116.2108005-2-qguanni@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/core.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c +index fbd5d292d8bf9..b58833e99969a 100644 +--- a/kernel/bpf/core.c ++++ b/kernel/bpf/core.c +@@ -1735,6 +1735,12 @@ bool bpf_opcode_in_insntable(u8 code) + } + + #ifndef CONFIG_BPF_JIT_ALWAYS_ON ++/* Absolute value of s32 without undefined behavior for S32_MIN */ ++static u32 abs_s32(s32 x) ++{ ++ return x >= 0 ? (u32)x : -(u32)x; ++} ++ + /** + * ___bpf_prog_run - run eBPF program on a given context + * @regs: is the array of MAX_BPF_EXT_REG eBPF pseudo-registers +@@ -1899,8 +1905,8 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn) + DST = do_div(AX, (u32) SRC); + break; + case 1: +- AX = abs((s32)DST); +- AX = do_div(AX, abs((s32)SRC)); ++ AX = abs_s32((s32)DST); ++ AX = do_div(AX, abs_s32((s32)SRC)); + if ((s32)DST < 0) + DST = (u32)-AX; + else +@@ -1927,8 +1933,8 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn) + DST = do_div(AX, (u32) IMM); + break; + case 1: +- AX = abs((s32)DST); +- AX = do_div(AX, abs((s32)IMM)); ++ AX = abs_s32((s32)DST); ++ AX = do_div(AX, abs_s32((s32)IMM)); + if ((s32)DST < 0) + DST = (u32)-AX; + else +@@ -1954,8 +1960,8 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn) + DST = (u32) AX; + break; + case 1: +- AX = abs((s32)DST); +- do_div(AX, abs((s32)SRC)); ++ AX = abs_s32((s32)DST); ++ do_div(AX, abs_s32((s32)SRC)); + if (((s32)DST < 0) == ((s32)SRC < 0)) + DST = (u32)AX; + else +@@ -1981,8 +1987,8 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn) + DST = (u32) AX; + break; + case 1: +- AX = abs((s32)DST); +- do_div(AX, abs((s32)IMM)); ++ AX = abs_s32((s32)DST); ++ do_div(AX, abs_s32((s32)IMM)); + if (((s32)DST < 0) == ((s32)IMM < 0)) + DST = (u32)AX; + else +-- +2.51.0 + diff --git a/queue-6.12/bpf-fix-unsound-scalar-forking-in-maybe_fork_scalars.patch b/queue-6.12/bpf-fix-unsound-scalar-forking-in-maybe_fork_scalars.patch new file mode 100644 index 0000000000..daf198d6f8 --- /dev/null +++ b/queue-6.12/bpf-fix-unsound-scalar-forking-in-maybe_fork_scalars.patch @@ -0,0 +1,52 @@ +From eb03a827fa752740ce46a3127b31842a28428f0b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Mar 2026 13:15:20 +1100 +Subject: bpf: Fix unsound scalar forking in maybe_fork_scalars() for BPF_OR + +From: Daniel Wade + +[ Upstream commit c845894ebd6fb43226b3118d6b017942550910c5 ] + +maybe_fork_scalars() is called for both BPF_AND and BPF_OR when the +source operand is a constant. When dst has signed range [-1, 0], it +forks the verifier state: the pushed path gets dst = 0, the current +path gets dst = -1. + +For BPF_AND this is correct: 0 & K == 0. +For BPF_OR this is wrong: 0 | K == K, not 0. + +The pushed path therefore tracks dst as 0 when the runtime value is K, +producing an exploitable verifier/runtime divergence that allows +out-of-bounds map access. + +Fix this by passing env->insn_idx (instead of env->insn_idx + 1) to +push_stack(), so the pushed path re-executes the ALU instruction with +dst = 0 and naturally computes the correct result for any opcode. + +Fixes: bffacdb80b93 ("bpf: Recognize special arithmetic shift in the verifier") +Signed-off-by: Daniel Wade +Reviewed-by: Amery Hung +Acked-by: Eduard Zingerman +Link: https://lore.kernel.org/r/20260314021521.128361-2-danjwade95@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index a9e2380327b45..68fa30852051e 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -14206,7 +14206,7 @@ static int maybe_fork_scalars(struct bpf_verifier_env *env, struct bpf_insn *ins + else + return 0; + +- branch = push_stack(env, env->insn_idx + 1, env->insn_idx, false); ++ branch = push_stack(env, env->insn_idx, env->insn_idx, false); + if (IS_ERR(branch)) + return PTR_ERR(branch); + +-- +2.51.0 + diff --git a/queue-6.12/bpf-release-module-btf-idr-before-module-unload.patch b/queue-6.12/bpf-release-module-btf-idr-before-module-unload.patch new file mode 100644 index 0000000000..a7115b425b --- /dev/null +++ b/queue-6.12/bpf-release-module-btf-idr-before-module-unload.patch @@ -0,0 +1,128 @@ +From 7a718b2c3f6b4d0abc8ffedfac2d74d017ead0fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Mar 2026 13:53:07 -0700 +Subject: bpf: Release module BTF IDR before module unload + +From: Kumar Kartikeya Dwivedi + +[ Upstream commit 146bd2a87a65aa407bb17fac70d8d583d19aba06 ] + +Gregory reported in [0] that the global_map_resize test when run in +repeatedly ends up failing during program load. This stems from the fact +that BTF reference has not dropped to zero after the previous run's +module is unloaded, and the older module's BTF is still discoverable and +visible. Later, in libbpf, load_module_btfs() will find the ID for this +stale BTF, open its fd, and then it will be used during program load +where later steps taking module reference using btf_try_get_module() +fail since the underlying module for the BTF is gone. + +Logically, once a module is unloaded, it's associated BTF artifacts +should become hidden. The BTF object inside the kernel may still remain +alive as long its reference counts are alive, but it should no longer be +discoverable. + +To fix this, let us call btf_free_id() from the MODULE_STATE_GOING case +for the module unload to free the BTF associated IDR entry, and disable +its discovery once module unload returns to user space. If a race +happens during unload, the outcome is non-deterministic anyway. However, +user space should be able to rely on the guarantee that once it has +synchronously established a successful module unload, no more stale +artifacts associated with this module can be obtained subsequently. + +Note that we must be careful to not invoke btf_free_id() in btf_put() +when btf_is_module() is true now. There could be a window where the +module unload drops a non-terminal reference, frees the IDR, but the +same ID gets reused and the second unconditional btf_free_id() ends up +releasing an unrelated entry. + +To avoid a special case for btf_is_module() case, set btf->id to zero to +make btf_free_id() idempotent, such that we can unconditionally invoke it +from btf_put(), and also from the MODULE_STATE_GOING case. Since zero is +an invalid IDR, the idr_remove() should be a noop. + +Note that we can be sure that by the time we reach final btf_put() for +btf_is_module() case, the btf_free_id() is already done, since the +module itself holds the BTF reference, and it will call this function +for the BTF before dropping its own reference. + + [0]: https://lore.kernel.org/bpf/cover.1773170190.git.grbell@redhat.com + +Fixes: 36e68442d1af ("bpf: Load and verify kernel module BTFs") +Acked-by: Martin KaFai Lau +Suggested-by: Martin KaFai Lau +Reported-by: Gregory Bell +Reviewed-by: Emil Tsalapatis +Signed-off-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20260312205307.1346991-1-memxor@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/btf.c | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c +index f83bd019db141..cd523ad72838a 100644 +--- a/kernel/bpf/btf.c ++++ b/kernel/bpf/btf.c +@@ -1657,7 +1657,16 @@ static void btf_free_id(struct btf *btf) + * of the _bh() version. + */ + spin_lock_irqsave(&btf_idr_lock, flags); +- idr_remove(&btf_idr, btf->id); ++ if (btf->id) { ++ idr_remove(&btf_idr, btf->id); ++ /* ++ * Clear the id here to make this function idempotent, since it will get ++ * called a couple of times for module BTFs: on module unload, and then ++ * the final btf_put(). btf_alloc_id() starts IDs with 1, so we can use ++ * 0 as sentinel value. ++ */ ++ WRITE_ONCE(btf->id, 0); ++ } + spin_unlock_irqrestore(&btf_idr_lock, flags); + } + +@@ -7805,7 +7814,7 @@ static void bpf_btf_show_fdinfo(struct seq_file *m, struct file *filp) + { + const struct btf *btf = filp->private_data; + +- seq_printf(m, "btf_id:\t%u\n", btf->id); ++ seq_printf(m, "btf_id:\t%u\n", READ_ONCE(btf->id)); + } + #endif + +@@ -7892,7 +7901,7 @@ int btf_get_info_by_fd(const struct btf *btf, + if (copy_from_user(&info, uinfo, info_copy)) + return -EFAULT; + +- info.id = btf->id; ++ info.id = READ_ONCE(btf->id); + ubtf = u64_to_user_ptr(info.btf); + btf_copy = min_t(u32, btf->data_size, info.btf_size); + if (copy_to_user(ubtf, btf->data, btf_copy)) +@@ -7955,7 +7964,7 @@ int btf_get_fd_by_id(u32 id) + + u32 btf_obj_id(const struct btf *btf) + { +- return btf->id; ++ return READ_ONCE(btf->id); + } + + bool btf_is_kernel(const struct btf *btf) +@@ -8088,6 +8097,13 @@ static int btf_module_notify(struct notifier_block *nb, unsigned long op, + if (btf_mod->module != module) + continue; + ++ /* ++ * For modules, we do the freeing of BTF IDR as soon as ++ * module goes away to disable BTF discovery, since the ++ * btf_try_get_module() on such BTFs will fail. This may ++ * be called again on btf_put(), but it's ok to do so. ++ */ ++ btf_free_id(btf_mod->btf); + list_del(&btf_mod->list); + if (btf_mod->sysfs_attr) + sysfs_remove_bin_file(btf_kobj, btf_mod->sysfs_attr); +-- +2.51.0 + diff --git a/queue-6.12/btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch b/queue-6.12/btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch new file mode 100644 index 0000000000..c044bdae7b --- /dev/null +++ b/queue-6.12/btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch @@ -0,0 +1,196 @@ +From e84f35bc8e62c9fc711fcbd255a3bd59e2524e1e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Feb 2026 14:25:35 -0800 +Subject: btrfs: set BTRFS_ROOT_ORPHAN_CLEANUP during subvol create + +From: Boris Burkov + +[ Upstream commit 5131fa077f9bb386a1b901bf5b247041f0ec8f80 ] + +We have recently observed a number of subvolumes with broken dentries. +ls-ing the parent dir looks like: + +drwxrwxrwt 1 root root 16 Jan 23 16:49 . +drwxr-xr-x 1 root root 24 Jan 23 16:48 .. +d????????? ? ? ? ? ? broken_subvol + +and similarly stat-ing the file fails. + +In this state, deleting the subvol fails with ENOENT, but attempting to +create a new file or subvol over it errors out with EEXIST and even +aborts the fs. Which leaves us a bit stuck. + +dmesg contains a single notable error message reading: +"could not do orphan cleanup -2" + +2 is ENOENT and the error comes from the failure handling path of +btrfs_orphan_cleanup(), with the stack leading back up to +btrfs_lookup(). + +btrfs_lookup +btrfs_lookup_dentry +btrfs_orphan_cleanup // prints that message and returns -ENOENT + +After some detailed inspection of the internal state, it became clear +that: +- there are no orphan items for the subvol +- the subvol is otherwise healthy looking, it is not half-deleted or + anything, there is no drop progress, etc. +- the subvol was created a while ago and does the meaningful first + btrfs_orphan_cleanup() call that sets BTRFS_ROOT_ORPHAN_CLEANUP much + later. +- after btrfs_orphan_cleanup() fails, btrfs_lookup_dentry() returns -ENOENT, + which results in a negative dentry for the subvolume via + d_splice_alias(NULL, dentry), leading to the observed behavior. The + bug can be mitigated by dropping the dentry cache, at which point we + can successfully delete the subvolume if we want. + +i.e., +btrfs_lookup() + btrfs_lookup_dentry() + if (!sb_rdonly(inode->vfs_inode)->vfs_inode) + btrfs_orphan_cleanup(sub_root) + test_and_set_bit(BTRFS_ROOT_ORPHAN_CLEANUP) + btrfs_search_slot() // finds orphan item for inode N + ... + prints "could not do orphan cleanup -2" + if (inode == ERR_PTR(-ENOENT)) + inode = NULL; + return d_splice_alias(NULL, dentry) // NEGATIVE DENTRY for valid subvolume + +btrfs_orphan_cleanup() does test_and_set_bit(BTRFS_ROOT_ORPHAN_CLEANUP) +on the root when it runs, so it cannot run more than once on a given +root, so something else must run concurrently. However, the obvious +routes to deleting an orphan when nlinks goes to 0 should not be able to +run without first doing a lookup into the subvolume, which should run +btrfs_orphan_cleanup() and set the bit. + +The final important observation is that create_subvol() calls +d_instantiate_new() but does not set BTRFS_ROOT_ORPHAN_CLEANUP, so if +the dentry cache gets dropped, the next lookup into the subvolume will +make a real call into btrfs_orphan_cleanup() for the first time. This +opens up the possibility of concurrently deleting the inode/orphan items +but most typical evict() paths will be holding a reference on the parent +dentry (child dentry holds parent->d_lockref.count via dget in +d_alloc(), released in __dentry_kill()) and prevent the parent from +being removed from the dentry cache. + +The one exception is delayed iputs. Ordered extent creation calls +igrab() on the inode. If the file is unlinked and closed while those +refs are held, iput() in __dentry_kill() decrements i_count but does +not trigger eviction (i_count > 0). The child dentry is freed and the +subvol dentry's d_lockref.count drops to 0, making it evictable while +the inode is still alive. + +Since there are two races (the race between writeback and unlink and +the race between lookup and delayed iputs), and there are too many moving +parts, the following three diagrams show the complete picture. +(Only the second and third are races) + +Phase 1: +Create Subvol in dentry cache without BTRFS_ROOT_ORPHAN_CLEANUP set + +btrfs_mksubvol() + lookup_one_len() + __lookup_slow() + d_alloc_parallel() + __d_alloc() // d_lockref.count = 1 + create_subvol(dentry) + // doesn't touch the bit.. + d_instantiate_new(dentry, inode) // dentry in cache with d_lockref.count == 1 + +Phase 2: +Create a delayed iput for a file in the subvol but leave the subvol in +state where its dentry can be evicted (d_lockref.count == 0) + +T1 (task) T2 (writeback) T3 (OE workqueue) + +write() // dirty pages + btrfs_writepages() + btrfs_run_delalloc_range() + cow_file_range() + btrfs_alloc_ordered_extent() + igrab() // i_count: 1 -> 2 +btrfs_unlink_inode() + btrfs_orphan_add() +close() + __fput() + dput() + finish_dput() + __dentry_kill() + dentry_unlink_inode() + iput() // 2 -> 1 + --parent->d_lockref.count // 1 -> 0; evictable + finish_ordered_fn() + btrfs_finish_ordered_io() + btrfs_put_ordered_extent() + btrfs_add_delayed_iput() + +Phase 3: +Once the delayed iput is pending and the subvol dentry is evictable, +the shrinker can free it, causing the next lookup to go through +btrfs_lookup() and call btrfs_orphan_cleanup() for the first time. +If the cleaner kthread processes the delayed iput concurrently, the +two race: + + T1 (shrinker) T2 (cleaner kthread) T3 (lookup) + + super_cache_scan() + prune_dcache_sb() + __dentry_kill() + // subvol dentry freed + btrfs_run_delayed_iputs() + iput() // i_count -> 0 + evict() // sets I_FREEING + btrfs_evict_inode() + // truncation loop + btrfs_lookup() + btrfs_lookup_dentry() + btrfs_orphan_cleanup() + // first call (bit never set) + btrfs_iget() + // blocks on I_FREEING + + btrfs_orphan_del() + // inode freed + // returns -ENOENT + btrfs_del_orphan_item() + // -ENOENT + // "could not do orphan cleanup -2" + d_splice_alias(NULL, dentry) + // negative dentry for valid subvol + +The most straightforward fix is to ensure the invariant that a dentry +for a subvolume can exist if and only if that subvolume has +BTRFS_ROOT_ORPHAN_CLEANUP set on its root (and is known to have no +orphans or ran btrfs_orphan_cleanup()). + +Reviewed-by: Filipe Manana +Signed-off-by: Boris Burkov +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/ioctl.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index 72d73953d1b77..9a548f2eec3af 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -766,6 +766,13 @@ static noinline int create_subvol(struct mnt_idmap *idmap, + goto out; + } + ++ /* ++ * Subvolumes have orphans cleaned on first dentry lookup. A new ++ * subvolume cannot have any orphans, so we should set the bit before we ++ * add the subvolume dentry to the dentry cache, so that it is in the ++ * same state as a subvolume after first lookup. ++ */ ++ set_bit(BTRFS_ROOT_ORPHAN_CLEANUP, &new_root->state); + d_instantiate_new(dentry, new_inode_args.inode); + new_inode_args.inode = NULL; + +-- +2.51.0 + diff --git a/queue-6.12/cxl-hdm-avoid-incorrect-dvsec-fallback-when-hdm-deco.patch b/queue-6.12/cxl-hdm-avoid-incorrect-dvsec-fallback-when-hdm-deco.patch new file mode 100644 index 0000000000..2b665e486d --- /dev/null +++ b/queue-6.12/cxl-hdm-avoid-incorrect-dvsec-fallback-when-hdm-deco.patch @@ -0,0 +1,101 @@ +From 5093fffca27d991134502257f46071db82136c8c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Mar 2026 20:19:49 +0000 +Subject: cxl/hdm: Avoid incorrect DVSEC fallback when HDM decoders are enabled + +From: Smita Koralahalli + +[ Upstream commit 75cea0776de502f2a1be5ca02d37c586dc81887e ] + +Check the global CXL_HDM_DECODER_ENABLE bit instead of looping over +per-decoder COMMITTED bits to determine whether to fall back to DVSEC +range emulation. When the HDM decoder capability is globally enabled, +ignore DVSEC range registers regardless of individual decoder commit +state. + +should_emulate_decoders() currently loops over per-decoder COMMITTED +bits, which leads to an incorrect DVSEC fallback when those bits are +zero. One way to trigger this is to destroy a region and bounce the +memdev: + + cxl disable-region region0 + cxl destroy-region region0 + cxl disable-memdev mem0 + cxl enable-memdev mem0 + +Region teardown zeroes the HDM decoder registers including the committed +bits. The subsequent memdev re-probe finds uncommitted decoders and falls +back to DVSEC emulation, even though HDM remains globally enabled. + +Observed failures: + + should_emulate_decoders: cxl_port endpoint6: decoder6.0: committed: 0 base: 0x0_00000000 size: 0x0_00000000 + devm_cxl_setup_hdm: cxl_port endpoint6: Fallback map 1 range register + .. + devm_cxl_add_region: cxl_acpi ACPI0017:00: decoder0.0: created region0 + __construct_region: cxl_pci 0000:e1:00.0: mem1:decoder6.0: + __construct_region region0 res: [mem 0x850000000-0x284fffffff flags 0x200] iw: 1 ig: 4096 + cxl region0: pci0000:e0:port1 cxl_port_setup_targets expected iw: 1 ig: 4096 .. + cxl region0: pci0000:e0:port1 cxl_port_setup_targets got iw: 1 ig: 256 state: disabled .. + cxl_port endpoint6: failed to attach decoder6.0 to region0: -6 + .. + devm_cxl_add_region: cxl_acpi ACPI0017:00: decoder0.0: created region4 + alloc_hpa: cxl region4: HPA allocation error (-34) .. + +Fixes: 52cc48ad2a76 ("cxl/hdm: Limit emulation to the number of range registers") +Signed-off-by: Smita Koralahalli +Reviewed-by: Dan Williams +Link: https://patch.msgid.link/20260316201950.224567-1-Smita.KoralahalliChannabasappa@amd.com +Signed-off-by: Dave Jiang +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/hdm.c | 25 +++++++++---------------- + 1 file changed, 9 insertions(+), 16 deletions(-) + +diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c +index fde609f37e562..5b4ddc1262d7c 100644 +--- a/drivers/cxl/core/hdm.c ++++ b/drivers/cxl/core/hdm.c +@@ -99,7 +99,6 @@ static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info) + struct cxl_hdm *cxlhdm; + void __iomem *hdm; + u32 ctrl; +- int i; + + if (!info) + return false; +@@ -118,22 +117,16 @@ static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info) + return false; + + /* +- * If any decoders are committed already, there should not be any +- * emulated DVSEC decoders. ++ * If HDM decoders are globally enabled, do not fall back to DVSEC ++ * range emulation. Zeroed decoder registers after region teardown ++ * do not imply absence of HDM capability. ++ * ++ * Falling back to DVSEC here would treat the decoder as AUTO and ++ * may incorrectly latch default interleave settings. + */ +- for (i = 0; i < cxlhdm->decoder_count; i++) { +- ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(i)); +- dev_dbg(&info->port->dev, +- "decoder%d.%d: committed: %ld base: %#x_%.8x size: %#x_%.8x\n", +- info->port->id, i, +- FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl), +- readl(hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET(i)), +- readl(hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(i)), +- readl(hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET(i)), +- readl(hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(i))); +- if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl)) +- return false; +- } ++ ctrl = readl(hdm + CXL_HDM_DECODER_CTRL_OFFSET); ++ if (ctrl & CXL_HDM_DECODER_ENABLE) ++ return false; + + return true; + } +-- +2.51.0 + diff --git a/queue-6.12/cxl-port-fix-use-after-free-of-parent_port-in-cxl_de.patch b/queue-6.12/cxl-port-fix-use-after-free-of-parent_port-in-cxl_de.patch new file mode 100644 index 0000000000..9eda3db3cd --- /dev/null +++ b/queue-6.12/cxl-port-fix-use-after-free-of-parent_port-in-cxl_de.patch @@ -0,0 +1,96 @@ +From a4cde0e4ba4b163e380192f989689b4734aeb0e1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Feb 2026 10:44:36 -0800 +Subject: cxl/port: Fix use after free of parent_port in cxl_detach_ep() + +From: Alison Schofield + +[ Upstream commit 19d2f0b97a131198efc2c4ca3eb7f980bba8c2b4 ] + +cxl_detach_ep() is called during bottom-up removal when all CXL memory +devices beneath a switch port have been removed. For each port in the +hierarchy it locks both the port and its parent, removes the endpoint, +and if the port is now empty, marks it dead and unregisters the port +by calling delete_switch_port(). There are two places during this work +where the parent_port may be used after freeing: + +First, a concurrent detach may have already processed a port by the +time a second worker finds it via bus_find_device(). Without pinning +parent_port, it may already be freed when we discover port->dead and +attempt to unlock the parent_port. In a production kernel that's a +silent memory corruption, with lock debug, it looks like this: + +[]DEBUG_LOCKS_WARN_ON(__owner_task(owner) != get_current()) +[]WARNING: kernel/locking/mutex.c:949 at __mutex_unlock_slowpath+0x1ee/0x310 +[]Call Trace: +[]mutex_unlock+0xd/0x20 +[]cxl_detach_ep+0x180/0x400 [cxl_core] +[]devm_action_release+0x10/0x20 +[]devres_release_all+0xa8/0xe0 +[]device_unbind_cleanup+0xd/0xa0 +[]really_probe+0x1a6/0x3e0 + +Second, delete_switch_port() releases three devm actions registered +against parent_port. The last of those is unregister_port() and it +calls device_unregister() on the child port, which can cascade. If +parent_port is now also empty the device core may unregister and free +it too. So by the time delete_switch_port() returns, parent_port may +be free, and the subsequent device_unlock(&parent_port->dev) operates +on freed memory. The kernel log looks same as above, with a different +offset in cxl_detach_ep(). + +Both of these issues stem from the absence of a lifetime guarantee +between a child port and its parent port. + +Establish a lifetime rule for ports: child ports hold a reference to +their parent device until release. Take the reference when the port +is allocated and drop it when released. This ensures the parent is +valid for the full lifetime of the child and eliminates the use after +free window in cxl_detach_ep(). + +This is easily reproduced with a reload of cxl_acpi in QEMU with CXL +devices present. + +Fixes: 2345df54249c ("cxl/memdev: Fix endpoint port removal") +Reviewed-by: Dave Jiang +Reviewed-by: Li Ming +Signed-off-by: Alison Schofield +Reviewed-by: Jonathan Cameron +Link: https://patch.msgid.link/20260226184439.1732841-1-alison.schofield@intel.com +Signed-off-by: Dave Jiang +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/port.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c +index af92c67bc9542..6eb2e69361412 100644 +--- a/drivers/cxl/core/port.c ++++ b/drivers/cxl/core/port.c +@@ -539,10 +539,13 @@ static void cxl_port_release(struct device *dev) + xa_destroy(&port->dports); + xa_destroy(&port->regions); + ida_free(&cxl_port_ida, port->id); +- if (is_cxl_root(port)) ++ ++ if (is_cxl_root(port)) { + kfree(to_cxl_root(port)); +- else ++ } else { ++ put_device(dev->parent); + kfree(port); ++ } + } + + static ssize_t decoders_committed_show(struct device *dev, +@@ -710,6 +713,7 @@ static struct cxl_port *cxl_port_alloc(struct device *uport_dev, + struct cxl_port *iter; + + dev->parent = &parent_port->dev; ++ get_device(dev->parent); + port->depth = parent_port->depth + 1; + port->parent_dport = parent_dport; + +-- +2.51.0 + diff --git a/queue-6.12/dma-buf-include-ioctl.h-in-uapi-header.patch b/queue-6.12/dma-buf-include-ioctl.h-in-uapi-header.patch new file mode 100644 index 0000000000..2a6aef0100 --- /dev/null +++ b/queue-6.12/dma-buf-include-ioctl.h-in-uapi-header.patch @@ -0,0 +1,44 @@ +From e960fde74f8da05d3c9e1abb720cd163f9583188 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Mar 2026 16:23:09 -0800 +Subject: dma-buf: Include ioctl.h in UAPI header +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Isaac J. Manjarres + +[ Upstream commit a116bac87118903925108e57781bbfc7a7eea27b ] + +include/uapi/linux/dma-buf.h uses several macros from ioctl.h to define +its ioctl commands. However, it does not include ioctl.h itself. So, +if userspace source code tries to include the dma-buf.h file without +including ioctl.h, it can result in build failures. + +Therefore, include ioctl.h in the dma-buf UAPI header. + +Signed-off-by: Isaac J. Manjarres +Reviewed-by: T.J. Mercier +Reviewed-by: Christian König +Signed-off-by: Christian König +Link: https://lore.kernel.org/r/20260303002309.1401849-1-isaacmanjarres@google.com +Signed-off-by: Sasha Levin +--- + include/uapi/linux/dma-buf.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h +index 5a6fda66d9adf..e827c9d20c5d3 100644 +--- a/include/uapi/linux/dma-buf.h ++++ b/include/uapi/linux/dma-buf.h +@@ -20,6 +20,7 @@ + #ifndef _DMA_BUF_UAPI_H_ + #define _DMA_BUF_UAPI_H_ + ++#include + #include + + /** +-- +2.51.0 + diff --git a/queue-6.12/driver-core-generalize-driver_override-in-struct-dev.patch b/queue-6.12/driver-core-generalize-driver_override-in-struct-dev.patch new file mode 100644 index 0000000000..b3980fff0b --- /dev/null +++ b/queue-6.12/driver-core-generalize-driver_override-in-struct-dev.patch @@ -0,0 +1,322 @@ +From a793dd02296f14ca3ae8b0687bc4953e78438983 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Mar 2026 12:53:18 +0100 +Subject: driver core: generalize driver_override in struct device + +From: Danilo Krummrich + +[ Upstream commit cb3d1049f4ea77d5ad93f17d8ac1f2ed4da70501 ] + +Currently, there are 12 busses (including platform and PCI) that +duplicate the driver_override logic for their individual devices. + +All of them seem to be prone to the bug described in [1]. + +While this could be solved for every bus individually using a separate +lock, solving this in the driver-core generically results in less (and +cleaner) changes overall. + +Thus, move driver_override to struct device, provide corresponding +accessors for busses and handle locking with a separate lock internally. + +In particular, add device_set_driver_override(), +device_has_driver_override(), device_match_driver_override() and +generalize the sysfs store() and show() callbacks via a driver_override +feature flag in struct bus_type. + +Until all busses have migrated, keep driver_set_override() in place. + +Note that we can't use the device lock for the reasons described in [2]. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=220789 [1] +Link: https://lore.kernel.org/driver-core/DGRGTIRHA62X.3RY09D9SOK77P@kernel.org/ [2] +Tested-by: Gui-Dong Han +Co-developed-by: Gui-Dong Han +Signed-off-by: Gui-Dong Han +Reviewed-by: Greg Kroah-Hartman +Link: https://patch.msgid.link/20260303115720.48783-2-dakr@kernel.org +[ Use dev->bus instead of sp->bus for consistency; fix commit message to + refer to the struct bus_type's driver_override feature flag. - Danilo ] +Signed-off-by: Danilo Krummrich +Stable-dep-of: 2b38efc05bf7 ("driver core: platform: use generic driver_override infrastructure") +Signed-off-by: Sasha Levin +--- + drivers/base/bus.c | 43 ++++++++++++++++++++++++++- + drivers/base/core.c | 2 ++ + drivers/base/dd.c | 60 ++++++++++++++++++++++++++++++++++++++ + include/linux/device.h | 54 ++++++++++++++++++++++++++++++++++ + include/linux/device/bus.h | 4 +++ + 5 files changed, 162 insertions(+), 1 deletion(-) + +diff --git a/drivers/base/bus.c b/drivers/base/bus.c +index eaf38a6f6091c..4075865a3a2a8 100644 +--- a/drivers/base/bus.c ++++ b/drivers/base/bus.c +@@ -463,6 +463,36 @@ int bus_for_each_drv(const struct bus_type *bus, struct device_driver *start, + } + EXPORT_SYMBOL_GPL(bus_for_each_drv); + ++static ssize_t driver_override_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ int ret; ++ ++ ret = __device_set_driver_override(dev, buf, count); ++ if (ret) ++ return ret; ++ ++ return count; ++} ++ ++static ssize_t driver_override_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ guard(spinlock)(&dev->driver_override.lock); ++ return sysfs_emit(buf, "%s\n", dev->driver_override.name); ++} ++static DEVICE_ATTR_RW(driver_override); ++ ++static struct attribute *driver_override_dev_attrs[] = { ++ &dev_attr_driver_override.attr, ++ NULL, ++}; ++ ++static const struct attribute_group driver_override_dev_group = { ++ .attrs = driver_override_dev_attrs, ++}; ++ + /** + * bus_add_device - add device to bus + * @dev: device being added +@@ -496,9 +526,15 @@ int bus_add_device(struct device *dev) + if (error) + goto out_put; + ++ if (dev->bus->driver_override) { ++ error = device_add_group(dev, &driver_override_dev_group); ++ if (error) ++ goto out_groups; ++ } ++ + error = sysfs_create_link(&sp->devices_kset->kobj, &dev->kobj, dev_name(dev)); + if (error) +- goto out_groups; ++ goto out_override; + + error = sysfs_create_link(&dev->kobj, &sp->subsys.kobj, "subsystem"); + if (error) +@@ -509,6 +545,9 @@ int bus_add_device(struct device *dev) + + out_subsys: + sysfs_remove_link(&sp->devices_kset->kobj, dev_name(dev)); ++out_override: ++ if (dev->bus->driver_override) ++ device_remove_group(dev, &driver_override_dev_group); + out_groups: + device_remove_groups(dev, sp->bus->dev_groups); + out_put: +@@ -567,6 +606,8 @@ void bus_remove_device(struct device *dev) + + sysfs_remove_link(&dev->kobj, "subsystem"); + sysfs_remove_link(&sp->devices_kset->kobj, dev_name(dev)); ++ if (dev->bus->driver_override) ++ device_remove_group(dev, &driver_override_dev_group); + device_remove_groups(dev, dev->bus->dev_groups); + if (klist_node_attached(&dev->p->knode_bus)) + klist_del(&dev->p->knode_bus); +diff --git a/drivers/base/core.c b/drivers/base/core.c +index ba9b4cbef9e08..09139e265c9b4 100644 +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -2559,6 +2559,7 @@ static void device_release(struct kobject *kobj) + devres_release_all(dev); + + kfree(dev->dma_range_map); ++ kfree(dev->driver_override.name); + + if (dev->release) + dev->release(dev); +@@ -3162,6 +3163,7 @@ void device_initialize(struct device *dev) + kobject_init(&dev->kobj, &device_ktype); + INIT_LIST_HEAD(&dev->dma_pools); + mutex_init(&dev->mutex); ++ spin_lock_init(&dev->driver_override.lock); + lockdep_set_novalidate_class(&dev->mutex); + spin_lock_init(&dev->devres_lock); + INIT_LIST_HEAD(&dev->devres_head); +diff --git a/drivers/base/dd.c b/drivers/base/dd.c +index b526e0e0f52d7..70d6ded3dd0a7 100644 +--- a/drivers/base/dd.c ++++ b/drivers/base/dd.c +@@ -380,6 +380,66 @@ static void __exit deferred_probe_exit(void) + } + __exitcall(deferred_probe_exit); + ++int __device_set_driver_override(struct device *dev, const char *s, size_t len) ++{ ++ const char *new, *old; ++ char *cp; ++ ++ if (!s) ++ return -EINVAL; ++ ++ /* ++ * The stored value will be used in sysfs show callback (sysfs_emit()), ++ * which has a length limit of PAGE_SIZE and adds a trailing newline. ++ * Thus we can store one character less to avoid truncation during sysfs ++ * show. ++ */ ++ if (len >= (PAGE_SIZE - 1)) ++ return -EINVAL; ++ ++ /* ++ * Compute the real length of the string in case userspace sends us a ++ * bunch of \0 characters like python likes to do. ++ */ ++ len = strlen(s); ++ ++ if (!len) { ++ /* Empty string passed - clear override */ ++ spin_lock(&dev->driver_override.lock); ++ old = dev->driver_override.name; ++ dev->driver_override.name = NULL; ++ spin_unlock(&dev->driver_override.lock); ++ kfree(old); ++ ++ return 0; ++ } ++ ++ cp = strnchr(s, len, '\n'); ++ if (cp) ++ len = cp - s; ++ ++ new = kstrndup(s, len, GFP_KERNEL); ++ if (!new) ++ return -ENOMEM; ++ ++ spin_lock(&dev->driver_override.lock); ++ old = dev->driver_override.name; ++ if (cp != s) { ++ dev->driver_override.name = new; ++ spin_unlock(&dev->driver_override.lock); ++ } else { ++ /* "\n" passed - clear override */ ++ dev->driver_override.name = NULL; ++ spin_unlock(&dev->driver_override.lock); ++ ++ kfree(new); ++ } ++ kfree(old); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(__device_set_driver_override); ++ + /** + * device_is_bound() - Check if device is bound to a driver + * @dev: device to check +diff --git a/include/linux/device.h b/include/linux/device.h +index 1f6130e13620d..b678bcca224c6 100644 +--- a/include/linux/device.h ++++ b/include/linux/device.h +@@ -524,6 +524,8 @@ struct device_physical_location { + * on. This shrinks the "Board Support Packages" (BSPs) and + * minimizes board-specific #ifdefs in drivers. + * @driver_data: Private pointer for driver specific info. ++ * @driver_override: Driver name to force a match. Do not touch directly; use ++ * device_set_driver_override() instead. + * @links: Links to suppliers and consumers of this device. + * @power: For device power management. + * See Documentation/driver-api/pm/devices.rst for details. +@@ -617,6 +619,10 @@ struct device { + core doesn't touch it */ + void *driver_data; /* Driver data, set and get with + dev_set_drvdata/dev_get_drvdata */ ++ struct { ++ const char *name; ++ spinlock_t lock; ++ } driver_override; + struct mutex mutex; /* mutex to synchronize calls to + * its driver. + */ +@@ -742,6 +748,54 @@ struct device_link { + + #define kobj_to_dev(__kobj) container_of_const(__kobj, struct device, kobj) + ++int __device_set_driver_override(struct device *dev, const char *s, size_t len); ++ ++/** ++ * device_set_driver_override() - Helper to set or clear driver override. ++ * @dev: Device to change ++ * @s: NUL-terminated string, new driver name to force a match, pass empty ++ * string to clear it ("" or "\n", where the latter is only for sysfs ++ * interface). ++ * ++ * Helper to set or clear driver override of a device. ++ * ++ * Returns: 0 on success or a negative error code on failure. ++ */ ++static inline int device_set_driver_override(struct device *dev, const char *s) ++{ ++ return __device_set_driver_override(dev, s, s ? strlen(s) : 0); ++} ++ ++/** ++ * device_has_driver_override() - Check if a driver override has been set. ++ * @dev: device to check ++ * ++ * Returns true if a driver override has been set for this device. ++ */ ++static inline bool device_has_driver_override(struct device *dev) ++{ ++ guard(spinlock)(&dev->driver_override.lock); ++ return !!dev->driver_override.name; ++} ++ ++/** ++ * device_match_driver_override() - Match a driver against the device's driver_override. ++ * @dev: device to check ++ * @drv: driver to match against ++ * ++ * Returns > 0 if a driver override is set and matches the given driver, 0 if a ++ * driver override is set but does not match, or < 0 if a driver override is not ++ * set at all. ++ */ ++static inline int device_match_driver_override(struct device *dev, ++ const struct device_driver *drv) ++{ ++ guard(spinlock)(&dev->driver_override.lock); ++ if (dev->driver_override.name) ++ return !strcmp(dev->driver_override.name, drv->name); ++ return -1; ++} ++ + /** + * device_iommu_mapped - Returns true when the device DMA is translated + * by an IOMMU +diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h +index b18658bce2c38..cd9aa90ad53a9 100644 +--- a/include/linux/device/bus.h ++++ b/include/linux/device/bus.h +@@ -63,6 +63,9 @@ struct fwnode_handle; + * this bus. + * @pm: Power management operations of this bus, callback the specific + * device driver's pm-ops. ++ * @driver_override: Set to true if this bus supports the driver_override ++ * mechanism, which allows userspace to force a specific ++ * driver to bind to a device via a sysfs attribute. + * @need_parent_lock: When probing or removing a device on this bus, the + * device core should lock the device's parent. + * +@@ -104,6 +107,7 @@ struct bus_type { + + const struct dev_pm_ops *pm; + ++ bool driver_override; + bool need_parent_lock; + }; + +-- +2.51.0 + diff --git a/queue-6.12/driver-core-platform-use-generic-driver_override-inf.patch b/queue-6.12/driver-core-platform-use-generic-driver_override-inf.patch new file mode 100644 index 0000000000..6726fd2e0b --- /dev/null +++ b/queue-6.12/driver-core-platform-use-generic-driver_override-inf.patch @@ -0,0 +1,200 @@ +From 0c8fe6d359e280e1fed6810d1f6f0f80ddb8df1f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Mar 2026 12:53:21 +0100 +Subject: driver core: platform: use generic driver_override infrastructure + +From: Danilo Krummrich + +[ Upstream commit 2b38efc05bf7a8568ec74bfffea0f5cfa62bc01d ] + +When a driver is probed through __driver_attach(), the bus' match() +callback is called without the device lock held, thus accessing the +driver_override field without a lock, which can cause a UAF. + +Fix this by using the driver-core driver_override infrastructure taking +care of proper locking internally. + +Note that calling match() from __driver_attach() without the device lock +held is intentional. [1] + +Link: https://lore.kernel.org/driver-core/DGRGTIRHA62X.3RY09D9SOK77P@kernel.org/ [1] +Reported-by: Gui-Dong Han +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220789 +Fixes: 3d713e0e382e ("driver core: platform: add device binding path 'driver_override'") +Reviewed-by: Greg Kroah-Hartman +Link: https://patch.msgid.link/20260303115720.48783-5-dakr@kernel.org +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + drivers/base/platform.c | 37 +++++---------------------------- + drivers/bus/simple-pm-bus.c | 4 ++-- + drivers/clk/imx/clk-scu.c | 3 +-- + drivers/slimbus/qcom-ngd-ctrl.c | 6 ++---- + include/linux/platform_device.h | 5 ----- + sound/soc/samsung/i2s.c | 6 +++--- + 6 files changed, 13 insertions(+), 48 deletions(-) + +diff --git a/drivers/base/platform.c b/drivers/base/platform.c +index 6f2a33722c520..24440eec1d4a2 100644 +--- a/drivers/base/platform.c ++++ b/drivers/base/platform.c +@@ -562,7 +562,6 @@ static void platform_device_release(struct device *dev) + kfree(pa->pdev.dev.platform_data); + kfree(pa->pdev.mfd_cell); + kfree(pa->pdev.resource); +- kfree(pa->pdev.driver_override); + kfree(pa); + } + +@@ -1265,38 +1264,9 @@ static ssize_t numa_node_show(struct device *dev, + } + static DEVICE_ATTR_RO(numa_node); + +-static ssize_t driver_override_show(struct device *dev, +- struct device_attribute *attr, char *buf) +-{ +- struct platform_device *pdev = to_platform_device(dev); +- ssize_t len; +- +- device_lock(dev); +- len = sysfs_emit(buf, "%s\n", pdev->driver_override); +- device_unlock(dev); +- +- return len; +-} +- +-static ssize_t driver_override_store(struct device *dev, +- struct device_attribute *attr, +- const char *buf, size_t count) +-{ +- struct platform_device *pdev = to_platform_device(dev); +- int ret; +- +- ret = driver_set_override(dev, &pdev->driver_override, buf, count); +- if (ret) +- return ret; +- +- return count; +-} +-static DEVICE_ATTR_RW(driver_override); +- + static struct attribute *platform_dev_attrs[] = { + &dev_attr_modalias.attr, + &dev_attr_numa_node.attr, +- &dev_attr_driver_override.attr, + NULL, + }; + +@@ -1336,10 +1306,12 @@ static int platform_match(struct device *dev, const struct device_driver *drv) + { + struct platform_device *pdev = to_platform_device(dev); + struct platform_driver *pdrv = to_platform_driver(drv); ++ int ret; + + /* When driver_override is set, only bind to the matching driver */ +- if (pdev->driver_override) +- return !strcmp(pdev->driver_override, drv->name); ++ ret = device_match_driver_override(dev, drv); ++ if (ret >= 0) ++ return ret; + + /* Attempt an OF style match first */ + if (of_driver_match_device(dev, drv)) +@@ -1477,6 +1449,7 @@ static const struct dev_pm_ops platform_dev_pm_ops = { + const struct bus_type platform_bus_type = { + .name = "platform", + .dev_groups = platform_dev_groups, ++ .driver_override = true, + .match = platform_match, + .uevent = platform_uevent, + .probe = platform_probe, +diff --git a/drivers/bus/simple-pm-bus.c b/drivers/bus/simple-pm-bus.c +index 50870c8278899..11fb711edd999 100644 +--- a/drivers/bus/simple-pm-bus.c ++++ b/drivers/bus/simple-pm-bus.c +@@ -36,7 +36,7 @@ static int simple_pm_bus_probe(struct platform_device *pdev) + * that's not listed in simple_pm_bus_of_match. We don't want to do any + * of the simple-pm-bus tasks for these devices, so return early. + */ +- if (pdev->driver_override) ++ if (device_has_driver_override(&pdev->dev)) + return 0; + + match = of_match_device(dev->driver->of_match_table, dev); +@@ -78,7 +78,7 @@ static void simple_pm_bus_remove(struct platform_device *pdev) + { + const void *data = of_device_get_match_data(&pdev->dev); + +- if (pdev->driver_override || data) ++ if (device_has_driver_override(&pdev->dev) || data) + return; + + dev_dbg(&pdev->dev, "%s\n", __func__); +diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c +index b27186aaf2a15..75a6d91c0711c 100644 +--- a/drivers/clk/imx/clk-scu.c ++++ b/drivers/clk/imx/clk-scu.c +@@ -715,8 +715,7 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name, + if (ret) + goto put_device; + +- ret = driver_set_override(&pdev->dev, &pdev->driver_override, +- "imx-scu-clk", strlen("imx-scu-clk")); ++ ret = device_set_driver_override(&pdev->dev, "imx-scu-clk"); + if (ret) + goto put_device; + +diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c +index f8d033a289810..ecc74a8903859 100644 +--- a/drivers/slimbus/qcom-ngd-ctrl.c ++++ b/drivers/slimbus/qcom-ngd-ctrl.c +@@ -1539,10 +1539,8 @@ static int of_qcom_slim_ngd_register(struct device *parent, + ngd->id = id; + ngd->pdev->dev.parent = parent; + +- ret = driver_set_override(&ngd->pdev->dev, +- &ngd->pdev->driver_override, +- QCOM_SLIM_NGD_DRV_NAME, +- strlen(QCOM_SLIM_NGD_DRV_NAME)); ++ ret = device_set_driver_override(&ngd->pdev->dev, ++ QCOM_SLIM_NGD_DRV_NAME); + if (ret) { + platform_device_put(ngd->pdev); + kfree(ngd); +diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h +index 7132623e46585..40f9d2e725bff 100644 +--- a/include/linux/platform_device.h ++++ b/include/linux/platform_device.h +@@ -31,11 +31,6 @@ struct platform_device { + struct resource *resource; + + const struct platform_device_id *id_entry; +- /* +- * Driver name to force a match. Do not set directly, because core +- * frees it. Use driver_set_override() to set or clear it. +- */ +- const char *driver_override; + + /* MFD cell pointer */ + struct mfd_cell *mfd_cell; +diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c +index 8f6deb06e2346..8ad99f1ef6554 100644 +--- a/sound/soc/samsung/i2s.c ++++ b/sound/soc/samsung/i2s.c +@@ -1362,10 +1362,10 @@ static int i2s_create_secondary_device(struct samsung_i2s_priv *priv) + if (!pdev_sec) + return -ENOMEM; + +- pdev_sec->driver_override = kstrdup("samsung-i2s", GFP_KERNEL); +- if (!pdev_sec->driver_override) { ++ ret = device_set_driver_override(&pdev_sec->dev, "samsung-i2s"); ++ if (ret) { + platform_device_put(pdev_sec); +- return -ENOMEM; ++ return ret; + } + + ret = platform_device_add(pdev_sec); +-- +2.51.0 + diff --git a/queue-6.12/drm-amdgpu-fix-gpu-idle-power-consumption-issue-for-.patch b/queue-6.12/drm-amdgpu-fix-gpu-idle-power-consumption-issue-for-.patch new file mode 100644 index 0000000000..e635612696 --- /dev/null +++ b/queue-6.12/drm-amdgpu-fix-gpu-idle-power-consumption-issue-for-.patch @@ -0,0 +1,50 @@ +From f67cb96bc399ddabdd881cb45e467da1e16e4b86 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Mar 2026 18:45:45 -0500 +Subject: drm/amdgpu: fix gpu idle power consumption issue for gfx v12 + +From: Yang Wang + +[ Upstream commit a6571045cf06c4aa749b4801382ae96650e2f0e1 ] + +Older versions of the MES firmware may cause abnormal GPU power consumption. +When performing inference tasks on the GPU (e.g., with Ollama using ROCm), +the GPU may show abnormal power consumption in idle state and incorrect GPU load information. +This issue has been fixed in firmware version 0x8b and newer. + +Closes: https://github.com/ROCm/ROCm/issues/5706 +Signed-off-by: Yang Wang +Acked-by: Alex Deucher +Signed-off-by: Alex Deucher +(cherry picked from commit 4e22a5fe6ea6e0b057e7f246df4ac3ff8bfbc46a) +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/mes_v12_0.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c +index 333a31da85568..945016712157d 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c +@@ -567,6 +567,9 @@ static int mes_v12_0_set_hw_resources(struct amdgpu_mes *mes, int pipe) + int i; + struct amdgpu_device *adev = mes->adev; + union MESAPI_SET_HW_RESOURCES mes_set_hw_res_pkt; ++ uint32_t mes_rev = (pipe == AMDGPU_MES_SCHED_PIPE) ? ++ (mes->sched_version & AMDGPU_MES_VERSION_MASK) : ++ (mes->kiq_version & AMDGPU_MES_VERSION_MASK); + + memset(&mes_set_hw_res_pkt, 0, sizeof(mes_set_hw_res_pkt)); + +@@ -621,7 +624,7 @@ static int mes_v12_0_set_hw_resources(struct amdgpu_mes *mes, int pipe) + * handling support, other queue will not use the oversubscribe timer. + * handling mode - 0: disabled; 1: basic version; 2: basic+ version + */ +- mes_set_hw_res_pkt.oversubscription_timer = 50; ++ mes_set_hw_res_pkt.oversubscription_timer = mes_rev < 0x8b ? 0 : 50; + mes_set_hw_res_pkt.unmapped_doorbell_handling = 1; + + if (amdgpu_mes_log_enable) { +-- +2.51.0 + diff --git a/queue-6.12/drm-ttm-tests-fix-build-failure-on-preempt_rt.patch b/queue-6.12/drm-ttm-tests-fix-build-failure-on-preempt_rt.patch new file mode 100644 index 0000000000..eae66a4ed1 --- /dev/null +++ b/queue-6.12/drm-ttm-tests-fix-build-failure-on-preempt_rt.patch @@ -0,0 +1,48 @@ +From 4973399bf956b4ce7d4e533c698d43577ca6f7e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Mar 2026 09:56:16 +0100 +Subject: drm/ttm/tests: Fix build failure on PREEMPT_RT +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Maarten Lankhorst + +[ Upstream commit a58d487fb1a52579d3c37544ea371da78ed70c45 ] + +Fix a compile error in the kunit tests when CONFIG_PREEMPT_RT is +enabled, and the normal mutex is converted into a rtmutex. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202602261547.3bM6yVAS-lkp@intel.com/ +Reviewed-by: Jouni Högander +Link: https://patch.msgid.link/20260304085616.1216961-1-dev@lankhorst.se +Signed-off-by: Maarten Lankhorst +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/ttm/tests/ttm_bo_test.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/ttm/tests/ttm_bo_test.c b/drivers/gpu/drm/ttm/tests/ttm_bo_test.c +index f0a7eb62116ca..b5b385a1da481 100644 +--- a/drivers/gpu/drm/ttm/tests/ttm_bo_test.c ++++ b/drivers/gpu/drm/ttm/tests/ttm_bo_test.c +@@ -222,13 +222,13 @@ static void ttm_bo_reserve_interrupted(struct kunit *test) + KUNIT_FAIL(test, "Couldn't create ttm bo reserve task\n"); + + /* Take a lock so the threaded reserve has to wait */ +- mutex_lock(&bo->base.resv->lock.base); ++ dma_resv_lock(bo->base.resv, NULL); + + wake_up_process(task); + msleep(20); + err = kthread_stop(task); + +- mutex_unlock(&bo->base.resv->lock.base); ++ dma_resv_unlock(bo->base.resv); + + KUNIT_ASSERT_EQ(test, err, -ERESTARTSYS); + } +-- +2.51.0 + diff --git a/queue-6.12/hid-apple-add-epomaker-th87-to-the-non-apple-keyboar.patch b/queue-6.12/hid-apple-add-epomaker-th87-to-the-non-apple-keyboar.patch new file mode 100644 index 0000000000..b0a5e1ca10 --- /dev/null +++ b/queue-6.12/hid-apple-add-epomaker-th87-to-the-non-apple-keyboar.patch @@ -0,0 +1,41 @@ +From 5ac8c9c47fbeb107d25353692f440fda928334ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Feb 2026 10:00:02 +0100 +Subject: HID: apple: Add EPOMAKER TH87 to the non-apple keyboards list + +From: Takashi Iwai + +[ Upstream commit 7c698de0dc5daa1e1a5fd1f0c6aa1b6bb2f5d867 ] + +EPOMAKER TH87 has the very same ID as Apple Aluminum keyboard +(05ac:024f) although it doesn't work as expected in compatible way. + +Put three entries to the non-apple keyboards list to exclude this +device: one for BT ("TH87"), one for USB ("HFD Epomaker TH87") and one +for dongle ("2.4G Wireless Receiver"). + +Link: https://bugzilla.suse.com/show_bug.cgi?id=1258455 +Signed-off-by: Takashi Iwai +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-apple.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index b0cf13cd292bd..16540546a210c 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -364,6 +364,9 @@ static const struct apple_non_apple_keyboard non_apple_keyboards[] = { + { "A3R" }, + { "hfd.cn" }, + { "WKB603" }, ++ { "TH87" }, /* EPOMAKER TH87 BT mode */ ++ { "HFD Epomaker TH87" }, /* EPOMAKER TH87 USB mode */ ++ { "2.4G Wireless Receiver" }, /* EPOMAKER TH87 dongle */ + }; + + static bool apple_is_non_apple_keyboard(struct hid_device *hdev) +-- +2.51.0 + diff --git a/queue-6.12/hid-apple-avoid-memory-leak-in-apple_report_fixup.patch b/queue-6.12/hid-apple-avoid-memory-leak-in-apple_report_fixup.patch new file mode 100644 index 0000000000..07e1f73282 --- /dev/null +++ b/queue-6.12/hid-apple-avoid-memory-leak-in-apple_report_fixup.patch @@ -0,0 +1,45 @@ +From 4271ca6ca5b301296cb1bcd1eb64abf19303feed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Feb 2026 16:43:36 +0100 +Subject: HID: apple: avoid memory leak in apple_report_fixup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Günther Noack + +[ Upstream commit 239c15116d80f67d32f00acc34575f1a6b699613 ] + +The apple_report_fixup() function was returning a +newly kmemdup()-allocated buffer, but never freeing it. + +The caller of report_fixup() does not take ownership of the returned +pointer, but it *is* permitted to return a sub-portion of the input +rdesc, whose lifetime is managed by the caller. + +Assisted-by: Gemini-CLI:Google Gemini 3 +Signed-off-by: Günther Noack +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-apple.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 16540546a210c..7e11f2932ff09 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -663,9 +663,7 @@ static const __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc, + hid_info(hdev, + "fixing up Magic Keyboard battery report descriptor\n"); + *rsize = *rsize - 1; +- rdesc = kmemdup(rdesc + 1, *rsize, GFP_KERNEL); +- if (!rdesc) +- return NULL; ++ rdesc = rdesc + 1; + + rdesc[0] = 0x05; + rdesc[1] = 0x01; +-- +2.51.0 + diff --git a/queue-6.12/hid-asus-add-xg-mobile-2023-external-hardware-suppor.patch b/queue-6.12/hid-asus-add-xg-mobile-2023-external-hardware-suppor.patch new file mode 100644 index 0000000000..e6fd268ee1 --- /dev/null +++ b/queue-6.12/hid-asus-add-xg-mobile-2023-external-hardware-suppor.patch @@ -0,0 +1,49 @@ +From 28a47b01fb9c8d4cb8a1f82d668064e42aee2e6b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 18:55:38 +0100 +Subject: HID: asus: add xg mobile 2023 external hardware support + +From: Denis Benato + +[ Upstream commit 377f8e788945d45b012ed9cfc35ca56c02e86cd8 ] + +XG mobile stations have the 0x5a endpoint and has to be initialized: +add them to hid-asus. + +Signed-off-by: Denis Benato +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-asus.c | 3 +++ + drivers/hid/hid-ids.h | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index a914b862dbfa4..b2788bb0477f0 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -1400,6 +1400,9 @@ static const struct hid_device_id asus_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, + USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X), + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_ALLY_XPAD }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, ++ USB_DEVICE_ID_ASUSTEK_XGM_2023), ++ }, + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, + USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD), + QUIRK_ROG_CLAYMORE_II_KEYBOARD }, +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 0a65490dfcb43..25eb5cc7de70e 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -225,6 +225,7 @@ + #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X 0x1b4c + #define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b + #define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869 ++#define USB_DEVICE_ID_ASUSTEK_XGM_2023 0x1a9a + + #define USB_VENDOR_ID_ATEN 0x0557 + #define USB_DEVICE_ID_ATEN_UC100KM 0x2004 +-- +2.51.0 + diff --git a/queue-6.12/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch b/queue-6.12/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch new file mode 100644 index 0000000000..5acebd6164 --- /dev/null +++ b/queue-6.12/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch @@ -0,0 +1,65 @@ +From 410c1287a76e9a50a54e10a5cc620235c48091b2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Feb 2026 16:43:38 +0100 +Subject: HID: asus: avoid memory leak in asus_report_fixup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Günther Noack + +[ Upstream commit 2bad24c17742fc88973d6aea526ce1353f5334a3 ] + +The asus_report_fixup() function was returning a newly allocated +kmemdup()-allocated buffer, but never freeing it. Switch to +devm_kzalloc() to ensure the memory is managed and freed automatically +when the device is removed. + +The caller of report_fixup() does not take ownership of the returned +pointer, but it is permitted to return a pointer whose lifetime is at +least that of the input buffer. + +Also fix a harmless out-of-bounds read by copying only the original +descriptor size. + +Assisted-by: Gemini-CLI:Google Gemini 3 +Signed-off-by: Günther Noack +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-asus.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index 6cecfdae5c8fc..a914b862dbfa4 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -1302,14 +1302,21 @@ static const __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, + */ + if (*rsize == rsize_orig && + rdesc[offs] == 0x09 && rdesc[offs + 1] == 0x76) { +- *rsize = rsize_orig + 1; +- rdesc = kmemdup(rdesc, *rsize, GFP_KERNEL); +- if (!rdesc) +- return NULL; ++ __u8 *new_rdesc; ++ ++ new_rdesc = devm_kzalloc(&hdev->dev, rsize_orig + 1, ++ GFP_KERNEL); ++ if (!new_rdesc) ++ return rdesc; + + hid_info(hdev, "Fixing up %s keyb report descriptor\n", + drvdata->quirks & QUIRK_T100CHI ? + "T100CHI" : "T90CHI"); ++ ++ memcpy(new_rdesc, rdesc, rsize_orig); ++ *rsize = rsize_orig + 1; ++ rdesc = new_rdesc; ++ + memmove(rdesc + offs + 4, rdesc + offs + 2, 12); + rdesc[offs] = 0x19; + rdesc[offs + 1] = 0x00; +-- +2.51.0 + diff --git a/queue-6.12/hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch b/queue-6.12/hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch new file mode 100644 index 0000000000..a4ad48051a --- /dev/null +++ b/queue-6.12/hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch @@ -0,0 +1,45 @@ +From 3be7fa7f518eddc0893b4f56f64493bcb35239dd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Feb 2026 16:43:37 +0100 +Subject: HID: magicmouse: avoid memory leak in magicmouse_report_fixup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Günther Noack + +[ Upstream commit 91e8c6e601bdc1ccdf886479b6513c01c7e51c2c ] + +The magicmouse_report_fixup() function was returning a +newly kmemdup()-allocated buffer, but never freeing it. + +The caller of report_fixup() does not take ownership of the returned +pointer, but it *is* permitted to return a sub-portion of the input +rdesc, whose lifetime is managed by the caller. + +Assisted-by: Gemini-CLI:Google Gemini 3 +Signed-off-by: Günther Noack +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-magicmouse.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 69ea1de96bbab..c59cfab104928 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -970,9 +970,7 @@ static const __u8 *magicmouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, + hid_info(hdev, + "fixing up magicmouse battery report descriptor\n"); + *rsize = *rsize - 1; +- rdesc = kmemdup(rdesc + 1, *rsize, GFP_KERNEL); +- if (!rdesc) +- return NULL; ++ rdesc = rdesc + 1; + + rdesc[0] = 0x05; + rdesc[1] = 0x01; +-- +2.51.0 + diff --git a/queue-6.12/hid-magicmouse-fix-battery-reporting-for-apple-magic.patch b/queue-6.12/hid-magicmouse-fix-battery-reporting-for-apple-magic.patch new file mode 100644 index 0000000000..87580d7624 --- /dev/null +++ b/queue-6.12/hid-magicmouse-fix-battery-reporting-for-apple-magic.patch @@ -0,0 +1,41 @@ +From 400b3c929b92156171c182d163d6628509db4473 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Feb 2026 20:34:21 +0100 +Subject: HID: magicmouse: fix battery reporting for Apple Magic Trackpad 2 + +From: Julius Lehmann + +[ Upstream commit 5f3518d77419255f8b12bb23c8ec22acbeb6bc5b ] + +Battery reporting does not work for the Apple Magic Trackpad 2 if it is +connected via USB. The current hid descriptor fixup code checks for a +hid descriptor length of exactly 83 bytes. If the hid descriptor is +larger, which is the case for newer apple mice, the fixup is not +applied. + +This fix checks for hid descriptor sizes greater/equal 83 bytes which +applies the fixup for newer devices as well. + +Signed-off-by: Julius Lehmann +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-magicmouse.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 19c811f9ae074..69ea1de96bbab 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -966,7 +966,7 @@ static const __u8 *magicmouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, + */ + if ((is_usb_magicmouse2(hdev->vendor, hdev->product) || + is_usb_magictrackpad2(hdev->vendor, hdev->product)) && +- *rsize == 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) { ++ *rsize >= 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) { + hid_info(hdev, + "fixing up magicmouse battery report descriptor\n"); + *rsize = *rsize - 1; +-- +2.51.0 + diff --git a/queue-6.12/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch b/queue-6.12/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch new file mode 100644 index 0000000000..dfa607226a --- /dev/null +++ b/queue-6.12/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch @@ -0,0 +1,41 @@ +From 133a2679d87e9d3b830126f7d8573985be604b8f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 17:32:58 +0100 +Subject: HID: mcp2221: cancel last I2C command on read error + +From: Romain Sioen + +[ Upstream commit e31b556c0ba21f20c298aa61181b96541140b7b9 ] + +When an I2C SMBus read operation fails, the MCP2221 internal state machine +may not reset correctly, causing subsequent transactions to fail. + +By adding a short delay and explicitly cancelling the last command, +we ensure the device is ready for the next operation. + +Fix an issue where i2cdetect was not able to detect all devices correctly +on the bus. + +Signed-off-by: Romain Sioen +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-mcp2221.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c +index 83941b916cd6b..f7b12d4cd2160 100644 +--- a/drivers/hid/hid-mcp2221.c ++++ b/drivers/hid/hid-mcp2221.c +@@ -337,6 +337,8 @@ static int mcp_i2c_smbus_read(struct mcp2221 *mcp, + usleep_range(90, 100); + retries++; + } else { ++ usleep_range(980, 1000); ++ mcp_cancel_last_cmd(mcp); + return ret; + } + } else { +-- +2.51.0 + diff --git a/queue-6.12/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch b/queue-6.12/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch new file mode 100644 index 0000000000..6884c202a0 --- /dev/null +++ b/queue-6.12/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch @@ -0,0 +1,43 @@ +From 579f4ad3622c19bbb7e30ce74ba7a354a0b6e8d7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Mar 2026 12:53:20 +0100 +Subject: hwmon: axi-fan: don't use driver_override as IRQ name +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Danilo Krummrich + +[ Upstream commit 813bbc4d33d2ca5b0da63e70ae13b60874f20d37 ] + +Do not use driver_override as IRQ name, as it is not guaranteed to point +to a valid string; use NULL instead (which makes the devm IRQ helpers +use dev_name()). + +Fixes: 8412b410fa5e ("hwmon: Support ADI Fan Control IP") +Reviewed-by: Nuno Sá +Acked-by: Guenter Roeck +Reviewed-by: Greg Kroah-Hartman +Link: https://patch.msgid.link/20260303115720.48783-4-dakr@kernel.org +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + drivers/hwmon/axi-fan-control.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c +index 35c862eb158b0..7beefbd7469f8 100644 +--- a/drivers/hwmon/axi-fan-control.c ++++ b/drivers/hwmon/axi-fan-control.c +@@ -507,7 +507,7 @@ static int axi_fan_control_probe(struct platform_device *pdev) + ret = devm_request_threaded_irq(&pdev->dev, ctl->irq, NULL, + axi_fan_control_irq_handler, + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, +- pdev->driver_override, ctl); ++ NULL, ctl); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "failed to request an irq\n"); +-- +2.51.0 + diff --git a/queue-6.12/i3c-master-dw-i3c-fix-missing-of_node-for-virtual-i2.patch b/queue-6.12/i3c-master-dw-i3c-fix-missing-of_node-for-virtual-i2.patch new file mode 100644 index 0000000000..62b9e88e8a --- /dev/null +++ b/queue-6.12/i3c-master-dw-i3c-fix-missing-of_node-for-virtual-i2.patch @@ -0,0 +1,43 @@ +From b79c1e899617eab6744250022797728eec2abec8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Mar 2026 15:56:42 +0800 +Subject: i3c: master: dw-i3c: Fix missing of_node for virtual I2C adapter + +From: Peter Yin + +[ Upstream commit f26ecaa0f0abfe5db173416214098a00d3b7db79 ] + +The DesignWare I3C master driver creates a virtual I2C adapter to +provide backward compatibility with I2C devices. However, the current +implementation does not associate this virtual adapter with any +Device Tree node. + +Propagate the of_node from the I3C master platform device to the +virtual I2C adapter's device structure. This ensures that standard +I2C aliases are correctly resolved and bus numbering remains consistent. + +Signed-off-by: Peter Yin +Reviewed-by: Frank Li +Link: https://patch.msgid.link/20260302075645.1492766-1-peteryin.openbmc@gmail.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/dw-i3c-master.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c +index e0853a6bde0a4..3453431e49a24 100644 +--- a/drivers/i3c/master/dw-i3c-master.c ++++ b/drivers/i3c/master/dw-i3c-master.c +@@ -1606,6 +1606,8 @@ int dw_i3c_common_probe(struct dw_i3c_master *master, + master->free_pos = GENMASK(master->maxdevs - 1, 0); + + INIT_WORK(&master->hj_work, dw_i3c_hj_work); ++ ++ device_set_of_node_from_dev(&master->base.i2c.dev, &pdev->dev); + ret = i3c_master_register(&master->base, &pdev->dev, + &dw_mipi_i3c_ops, false); + if (ret) +-- +2.51.0 + diff --git a/queue-6.12/kbuild-install-extmod-build-package-resolve_btfids-i.patch b/queue-6.12/kbuild-install-extmod-build-package-resolve_btfids-i.patch new file mode 100644 index 0000000000..a64a752110 --- /dev/null +++ b/queue-6.12/kbuild-install-extmod-build-package-resolve_btfids-i.patch @@ -0,0 +1,47 @@ +From f6a44da21fbacad494acd46278559dc08ee8938d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Feb 2026 08:41:48 +0100 +Subject: kbuild: install-extmod-build: Package resolve_btfids if necessary +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weißschuh + +[ Upstream commit 459cb3c054c2352bb321648744b620259a716b60 ] + +When CONFIG_DEBUG_INFO_BTF_MODULES is enabled and vmlinux is available, +Makefile.modfinal and gen-btf.sh will try to use resolve_btfids on the +module .ko. install-extmod-build currently does not package +resolve_btfids, so that step fails. + +Package resolve_btfids if it may be used. + +Signed-off-by: Thomas Weißschuh +Reviewed-by: Nicolas Schier +Link: https://patch.msgid.link/20260226-kbuild-resolve_btfids-v1-1-2bf38b93dfe7@linutronix.de +[nathan: Small commit message tweaks] +Signed-off-by: Nathan Chancellor +Signed-off-by: Sasha Levin +--- + scripts/package/install-extmod-build | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/scripts/package/install-extmod-build b/scripts/package/install-extmod-build +index 7ec1f061a519c..3edca72599812 100755 +--- a/scripts/package/install-extmod-build ++++ b/scripts/package/install-extmod-build +@@ -32,6 +32,10 @@ mkdir -p "${destdir}" + echo tools/objtool/objtool + fi + ++ if is_enabled CONFIG_DEBUG_INFO_BTF_MODULES; then ++ echo tools/bpf/resolve_btfids/resolve_btfids ++ fi ++ + echo Module.symvers + echo "arch/${SRCARCH}/include/generated" + echo include/config/auto.conf +-- +2.51.0 + diff --git a/queue-6.12/module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch b/queue-6.12/module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch new file mode 100644 index 0000000000..27a28dc68e --- /dev/null +++ b/queue-6.12/module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch @@ -0,0 +1,80 @@ +From 3f9e5ea0c9f82a6d14cc662d13d7534fdff00613 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Dec 2025 10:32:08 -0800 +Subject: module: Fix kernel panic when a symbol st_shndx is out of bounds + +From: Ihor Solodrai + +[ Upstream commit f9d69d5e7bde2295eb7488a56f094ac8f5383b92 ] + +The module loader doesn't check for bounds of the ELF section index in +simplify_symbols(): + + for (i = 1; i < symsec->sh_size / sizeof(Elf_Sym); i++) { + const char *name = info->strtab + sym[i].st_name; + + switch (sym[i].st_shndx) { + case SHN_COMMON: + + [...] + + default: + /* Divert to percpu allocation if a percpu var. */ + if (sym[i].st_shndx == info->index.pcpu) + secbase = (unsigned long)mod_percpu(mod); + else + /** HERE --> **/ secbase = info->sechdrs[sym[i].st_shndx].sh_addr; + sym[i].st_value += secbase; + break; + } + } + +A symbol with an out-of-bounds st_shndx value, for example 0xffff +(known as SHN_XINDEX or SHN_HIRESERVE), may cause a kernel panic: + + BUG: unable to handle page fault for address: ... + RIP: 0010:simplify_symbols+0x2b2/0x480 + ... + Kernel panic - not syncing: Fatal exception + +This can happen when module ELF is legitimately using SHN_XINDEX or +when it is corrupted. + +Add a bounds check in simplify_symbols() to validate that st_shndx is +within the valid range before using it. + +This issue was discovered due to a bug in llvm-objcopy, see relevant +discussion for details [1]. + +[1] https://lore.kernel.org/linux-modules/20251224005752.201911-1-ihor.solodrai@linux.dev/ + +Signed-off-by: Ihor Solodrai +Reviewed-by: Daniel Gomez +Reviewed-by: Petr Pavlu +Signed-off-by: Sami Tolvanen +Signed-off-by: Sasha Levin +--- + kernel/module/main.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/kernel/module/main.c b/kernel/module/main.c +index 4511d0a4762a2..915a9cf33dd0d 100644 +--- a/kernel/module/main.c ++++ b/kernel/module/main.c +@@ -1449,6 +1449,13 @@ static int simplify_symbols(struct module *mod, const struct load_info *info) + break; + + default: ++ if (sym[i].st_shndx >= info->hdr->e_shnum) { ++ pr_err("%s: Symbol %s has an invalid section index %u (max %u)\n", ++ mod->name, name, sym[i].st_shndx, info->hdr->e_shnum - 1); ++ ret = -ENOEXEC; ++ break; ++ } ++ + /* Divert to percpu allocation if a percpu var. */ + if (sym[i].st_shndx == info->index.pcpu) + secbase = (unsigned long)mod_percpu(mod); +-- +2.51.0 + diff --git a/queue-6.12/net-usb-r8152-add-trendnet-tuc-et2g.patch b/queue-6.12/net-usb-r8152-add-trendnet-tuc-et2g.patch new file mode 100644 index 0000000000..5555dba188 --- /dev/null +++ b/queue-6.12/net-usb-r8152-add-trendnet-tuc-et2g.patch @@ -0,0 +1,48 @@ +From 6e48ea26488b1811becd3062e7477e926e1e2218 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Feb 2026 20:54:09 +0100 +Subject: net: usb: r8152: add TRENDnet TUC-ET2G + +From: Valentin Spreckels + +[ Upstream commit 15fba71533bcdfaa8eeba69a5a5a2927afdf664a ] + +The TRENDnet TUC-ET2G is a RTL8156 based usb ethernet adapter. Add its +vendor and product IDs. + +Signed-off-by: Valentin Spreckels +Link: https://patch.msgid.link/20260226195409.7891-2-valentin@spreckels.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/usb/r8152.c | 1 + + include/linux/usb/r8152.h | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c +index e4eb4e5425364..6ce25673e4cc8 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -10090,6 +10090,7 @@ static const struct usb_device_id rtl8152_table[] = { + { USB_DEVICE(VENDOR_ID_DLINK, 0xb301) }, + { USB_DEVICE(VENDOR_ID_DELL, 0xb097) }, + { USB_DEVICE(VENDOR_ID_ASUS, 0x1976) }, ++ { USB_DEVICE(VENDOR_ID_TRENDNET, 0xe02b) }, + {} + }; + +diff --git a/include/linux/usb/r8152.h b/include/linux/usb/r8152.h +index 2ca60828f28bb..1502b2a355f98 100644 +--- a/include/linux/usb/r8152.h ++++ b/include/linux/usb/r8152.h +@@ -32,6 +32,7 @@ + #define VENDOR_ID_DLINK 0x2001 + #define VENDOR_ID_DELL 0x413c + #define VENDOR_ID_ASUS 0x0b05 ++#define VENDOR_ID_TRENDNET 0x20f4 + + #if IS_REACHABLE(CONFIG_USB_RTL8152) + extern u8 rtl8152_get_version(struct usb_interface *intf); +-- +2.51.0 + diff --git a/queue-6.12/nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch b/queue-6.12/nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch new file mode 100644 index 0000000000..bff555cbd1 --- /dev/null +++ b/queue-6.12/nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch @@ -0,0 +1,40 @@ +From 84ae143bcb762c685860c36d1f5ecc9a9560061e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 31 Jan 2026 19:08:40 -0800 +Subject: nvme-fabrics: use kfree_sensitive() for DHCHAP secrets + +From: Daniel Hodges + +[ Upstream commit 0a1fc2f301529ac75aec0ce80d5ab9d9e4dc4b16 ] + +The DHCHAP secrets (dhchap_secret and dhchap_ctrl_secret) contain +authentication key material for NVMe-oF. Use kfree_sensitive() instead +of kfree() in nvmf_free_options() to ensure secrets are zeroed before +the memory is freed, preventing recovery from freed pages. + +Reviewed-by: Christoph Hellwig +Signed-off-by: Daniel Hodges +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/fabrics.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c +index 2e47c56b2d4b2..fdcd655ee7434 100644 +--- a/drivers/nvme/host/fabrics.c ++++ b/drivers/nvme/host/fabrics.c +@@ -1262,8 +1262,8 @@ void nvmf_free_options(struct nvmf_ctrl_options *opts) + kfree(opts->subsysnqn); + kfree(opts->host_traddr); + kfree(opts->host_iface); +- kfree(opts->dhchap_secret); +- kfree(opts->dhchap_ctrl_secret); ++ kfree_sensitive(opts->dhchap_secret); ++ kfree_sensitive(opts->dhchap_ctrl_secret); + kfree(opts); + } + EXPORT_SYMBOL_GPL(nvmf_free_options); +-- +2.51.0 + diff --git a/queue-6.12/nvme-pci-cap-queue-creation-to-used-queues.patch b/queue-6.12/nvme-pci-cap-queue-creation-to-used-queues.patch new file mode 100644 index 0000000000..ffd2440efc --- /dev/null +++ b/queue-6.12/nvme-pci-cap-queue-creation-to-used-queues.patch @@ -0,0 +1,45 @@ +From 3bb202dd07ac63dfc2745e04fd0ebec140b8ce7f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 11:00:12 -0800 +Subject: nvme-pci: cap queue creation to used queues + +From: Keith Busch + +[ Upstream commit 4735b510a00fb2d4ac9e8d21a8c9552cb281f585 ] + +If the user reduces the special queue count at runtime and resets the +controller, we need to reduce the number of queues and interrupts +requested accordingly rather than start with the pre-allocated queue +count. + +Tested-by: Kanchan Joshi +Reviewed-by: Kanchan Joshi +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 6bd02c9116501..7a58ba05484bf 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2456,7 +2456,13 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) + dev->nr_write_queues = write_queues; + dev->nr_poll_queues = poll_queues; + +- nr_io_queues = dev->nr_allocated_queues - 1; ++ /* ++ * The initial number of allocated queue slots may be too large if the ++ * user reduced the special queue parameters. Cap the value to the ++ * number we need for this round. ++ */ ++ nr_io_queues = min(nvme_max_io_queues(dev), ++ dev->nr_allocated_queues - 1); + result = nvme_set_queue_count(&dev->ctrl, &nr_io_queues); + if (result < 0) + return result; +-- +2.51.0 + diff --git a/queue-6.12/nvme-pci-ensure-we-re-polling-a-polled-queue.patch b/queue-6.12/nvme-pci-ensure-we-re-polling-a-polled-queue.patch new file mode 100644 index 0000000000..9c4d1825e6 --- /dev/null +++ b/queue-6.12/nvme-pci-ensure-we-re-polling-a-polled-queue.patch @@ -0,0 +1,39 @@ +From 1b6607c76064ba0833e4391784574a360e222bb2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 09:26:54 -0800 +Subject: nvme-pci: ensure we're polling a polled queue + +From: Keith Busch + +[ Upstream commit 166e31d7dbf6aa44829b98aa446bda5c9580f12a ] + +A user can change the polled queue count at run time. There's a brief +window during a reset where a hipri task may try to poll that queue +before the block layer has updated the queue maps, which would race with +the now interrupt driven queue and may cause double completions. + +Reviewed-by: Christoph Hellwig +Reviewed-by: Kanchan Joshi +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 7a58ba05484bf..c04858da28eae 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1218,7 +1218,8 @@ static int nvme_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob) + struct nvme_queue *nvmeq = hctx->driver_data; + bool found; + +- if (!nvme_cqe_pending(nvmeq)) ++ if (!test_bit(NVMEQ_POLLED, &nvmeq->flags) || ++ !nvme_cqe_pending(nvmeq)) + return 0; + + spin_lock(&nvmeq->cq_poll_lock); +-- +2.51.0 + diff --git a/queue-6.12/nvmet-move-async-event-work-off-nvmet-wq.patch b/queue-6.12/nvmet-move-async-event-work-off-nvmet-wq.patch new file mode 100644 index 0000000000..f3e532dc51 --- /dev/null +++ b/queue-6.12/nvmet-move-async-event-work-off-nvmet-wq.patch @@ -0,0 +1,178 @@ +From d95a3b802795eeb1c53e87249e1811d08ff9cb67 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Feb 2026 20:30:03 -0800 +Subject: nvmet: move async event work off nvmet-wq + +From: Chaitanya Kulkarni + +[ Upstream commit 2922e3507f6d5caa7f1d07f145e186fc6f317a4e ] + +For target nvmet_ctrl_free() flushes ctrl->async_event_work. +If nvmet_ctrl_free() runs on nvmet-wq, the flush re-enters workqueue +completion for the same worker:- + +A. Async event work queued on nvmet-wq (prior to disconnect): + nvmet_execute_async_event() + queue_work(nvmet_wq, &ctrl->async_event_work) + + nvmet_add_async_event() + queue_work(nvmet_wq, &ctrl->async_event_work) + +B. Full pre-work chain (RDMA CM path): + nvmet_rdma_cm_handler() + nvmet_rdma_queue_disconnect() + __nvmet_rdma_queue_disconnect() + queue_work(nvmet_wq, &queue->release_work) + process_one_work() + lock((wq_completion)nvmet-wq) <--------- 1st + nvmet_rdma_release_queue_work() + +C. Recursive path (same worker): + nvmet_rdma_release_queue_work() + nvmet_rdma_free_queue() + nvmet_sq_destroy() + nvmet_ctrl_put() + nvmet_ctrl_free() + flush_work(&ctrl->async_event_work) + __flush_work() + touch_wq_lockdep_map() + lock((wq_completion)nvmet-wq) <--------- 2nd + +Lockdep splat: + + ============================================ + WARNING: possible recursive locking detected + 6.19.0-rc3nvme+ #14 Tainted: G N + -------------------------------------------- + kworker/u192:42/44933 is trying to acquire lock: + ffff888118a00948 ((wq_completion)nvmet-wq){+.+.}-{0:0}, at: touch_wq_lockdep_map+0x26/0x90 + + but task is already holding lock: + ffff888118a00948 ((wq_completion)nvmet-wq){+.+.}-{0:0}, at: process_one_work+0x53e/0x660 + + 3 locks held by kworker/u192:42/44933: + #0: ffff888118a00948 ((wq_completion)nvmet-wq){+.+.}-{0:0}, at: process_one_work+0x53e/0x660 + #1: ffffc9000e6cbe28 ((work_completion)(&queue->release_work)){+.+.}-{0:0}, at: process_one_work+0x1c5/0x660 + #2: ffffffff82d4db60 (rcu_read_lock){....}-{1:3}, at: __flush_work+0x62/0x530 + + Workqueue: nvmet-wq nvmet_rdma_release_queue_work [nvmet_rdma] + Call Trace: + __flush_work+0x268/0x530 + nvmet_ctrl_free+0x140/0x310 [nvmet] + nvmet_cq_put+0x74/0x90 [nvmet] + nvmet_rdma_free_queue+0x23/0xe0 [nvmet_rdma] + nvmet_rdma_release_queue_work+0x19/0x50 [nvmet_rdma] + process_one_work+0x206/0x660 + worker_thread+0x184/0x320 + kthread+0x10c/0x240 + ret_from_fork+0x319/0x390 + +Move async event work to a dedicated nvmet-aen-wq to avoid reentrant +flush on nvmet-wq. + +Reviewed-by: Christoph Hellwig +Signed-off-by: Chaitanya Kulkarni +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/admin-cmd.c | 2 +- + drivers/nvme/target/core.c | 14 ++++++++++++-- + drivers/nvme/target/nvmet.h | 1 + + drivers/nvme/target/rdma.c | 1 + + 4 files changed, 15 insertions(+), 3 deletions(-) + +diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c +index 081f0473cd9ea..72e31ef1f2f06 100644 +--- a/drivers/nvme/target/admin-cmd.c ++++ b/drivers/nvme/target/admin-cmd.c +@@ -985,7 +985,7 @@ void nvmet_execute_async_event(struct nvmet_req *req) + ctrl->async_event_cmds[ctrl->nr_async_event_cmds++] = req; + mutex_unlock(&ctrl->lock); + +- queue_work(nvmet_wq, &ctrl->async_event_work); ++ queue_work(nvmet_aen_wq, &ctrl->async_event_work); + } + + void nvmet_execute_keep_alive(struct nvmet_req *req) +diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c +index 710e74d3ec3e9..be9a7e8b547ac 100644 +--- a/drivers/nvme/target/core.c ++++ b/drivers/nvme/target/core.c +@@ -26,6 +26,8 @@ static DEFINE_IDA(cntlid_ida); + + struct workqueue_struct *nvmet_wq; + EXPORT_SYMBOL_GPL(nvmet_wq); ++struct workqueue_struct *nvmet_aen_wq; ++EXPORT_SYMBOL_GPL(nvmet_aen_wq); + + /* + * This read/write semaphore is used to synchronize access to configuration +@@ -205,7 +207,7 @@ void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type, + list_add_tail(&aen->entry, &ctrl->async_events); + mutex_unlock(&ctrl->lock); + +- queue_work(nvmet_wq, &ctrl->async_event_work); ++ queue_work(nvmet_aen_wq, &ctrl->async_event_work); + } + + static void nvmet_add_to_changed_ns_log(struct nvmet_ctrl *ctrl, __le32 nsid) +@@ -1714,9 +1716,14 @@ static int __init nvmet_init(void) + if (!nvmet_wq) + goto out_free_buffered_work_queue; + ++ nvmet_aen_wq = alloc_workqueue("nvmet-aen-wq", ++ WQ_MEM_RECLAIM | WQ_UNBOUND, 0); ++ if (!nvmet_aen_wq) ++ goto out_free_nvmet_work_queue; ++ + error = nvmet_init_debugfs(); + if (error) +- goto out_free_nvmet_work_queue; ++ goto out_free_nvmet_aen_work_queue; + + error = nvmet_init_discovery(); + if (error) +@@ -1732,6 +1739,8 @@ static int __init nvmet_init(void) + nvmet_exit_discovery(); + out_exit_debugfs: + nvmet_exit_debugfs(); ++out_free_nvmet_aen_work_queue: ++ destroy_workqueue(nvmet_aen_wq); + out_free_nvmet_work_queue: + destroy_workqueue(nvmet_wq); + out_free_buffered_work_queue: +@@ -1749,6 +1758,7 @@ static void __exit nvmet_exit(void) + nvmet_exit_discovery(); + nvmet_exit_debugfs(); + ida_destroy(&cntlid_ida); ++ destroy_workqueue(nvmet_aen_wq); + destroy_workqueue(nvmet_wq); + destroy_workqueue(buffered_io_wq); + destroy_workqueue(zbd_wq); +diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h +index 3062562c096a1..31a422a3f85b8 100644 +--- a/drivers/nvme/target/nvmet.h ++++ b/drivers/nvme/target/nvmet.h +@@ -419,6 +419,7 @@ extern struct kmem_cache *nvmet_bvec_cache; + extern struct workqueue_struct *buffered_io_wq; + extern struct workqueue_struct *zbd_wq; + extern struct workqueue_struct *nvmet_wq; ++extern struct workqueue_struct *nvmet_aen_wq; + + static inline void nvmet_set_result(struct nvmet_req *req, u32 result) + { +diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c +index 2a4536ef61848..ef55a63848b4c 100644 +--- a/drivers/nvme/target/rdma.c ++++ b/drivers/nvme/target/rdma.c +@@ -2086,6 +2086,7 @@ static void nvmet_rdma_remove_one(struct ib_device *ib_device, void *client_data + mutex_unlock(&nvmet_rdma_queue_mutex); + + flush_workqueue(nvmet_wq); ++ flush_workqueue(nvmet_aen_wq); + } + + static struct ib_client nvmet_rdma_ib_client = { +-- +2.51.0 + diff --git a/queue-6.12/objtool-handle-clang-rsp-musical-chairs.patch b/queue-6.12/objtool-handle-clang-rsp-musical-chairs.patch new file mode 100644 index 0000000000..21214aa05b --- /dev/null +++ b/queue-6.12/objtool-handle-clang-rsp-musical-chairs.patch @@ -0,0 +1,136 @@ +From 99bb4220d94f4f9a83b7891053d7f917e0ae367d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 09:35:06 -0800 +Subject: objtool: Handle Clang RSP musical chairs + +From: Josh Poimboeuf + +[ Upstream commit 7fdaa640c810cb42090a182c33f905bcc47a616a ] + +For no apparent reason (possibly related to CONFIG_KMSAN), Clang can +randomly pass the value of RSP to other registers and then back again to +RSP. Handle that accordingly. + +Fixes the following warnings: + + drivers/input/misc/uinput.o: warning: objtool: uinput_str_to_user+0x165: undefined stack state + drivers/input/misc/uinput.o: warning: objtool: uinput_str_to_user+0x165: unknown CFA base reg -1 + +Reported-by: Arnd Bergmann +Closes: https://lore.kernel.org/90956545-2066-46e3-b547-10c884582eb0@app.fastmail.com +Link: https://patch.msgid.link/240e6a172cc73292499334a3724d02ccb3247fc7.1772818491.git.jpoimboe@kernel.org +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/arch/x86/decode.c | 62 ++++++++++++--------------------- + tools/objtool/check.c | 14 ++++++++ + 2 files changed, 37 insertions(+), 39 deletions(-) + +diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c +index ed6bff0e01dcd..f96b7b47babd5 100644 +--- a/tools/objtool/arch/x86/decode.c ++++ b/tools/objtool/arch/x86/decode.c +@@ -331,52 +331,36 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec + if (!rex_w) + break; + +- if (modrm_reg == CFI_SP) { +- +- if (mod_is_reg()) { +- /* mov %rsp, reg */ +- ADD_OP(op) { +- op->src.type = OP_SRC_REG; +- op->src.reg = CFI_SP; +- op->dest.type = OP_DEST_REG; +- op->dest.reg = modrm_rm; +- } +- break; +- +- } else { +- /* skip RIP relative displacement */ +- if (is_RIP()) +- break; +- +- /* skip nontrivial SIB */ +- if (have_SIB()) { +- modrm_rm = sib_base; +- if (sib_index != CFI_SP) +- break; +- } +- +- /* mov %rsp, disp(%reg) */ +- ADD_OP(op) { +- op->src.type = OP_SRC_REG; +- op->src.reg = CFI_SP; +- op->dest.type = OP_DEST_REG_INDIRECT; +- op->dest.reg = modrm_rm; +- op->dest.offset = ins.displacement.value; +- } +- break; ++ if (mod_is_reg()) { ++ /* mov reg, reg */ ++ ADD_OP(op) { ++ op->src.type = OP_SRC_REG; ++ op->src.reg = modrm_reg; ++ op->dest.type = OP_DEST_REG; ++ op->dest.reg = modrm_rm; + } +- + break; + } + +- if (rm_is_reg(CFI_SP)) { ++ /* skip RIP relative displacement */ ++ if (is_RIP()) ++ break; + +- /* mov reg, %rsp */ ++ /* skip nontrivial SIB */ ++ if (have_SIB()) { ++ modrm_rm = sib_base; ++ if (sib_index != CFI_SP) ++ break; ++ } ++ ++ /* mov %rsp, disp(%reg) */ ++ if (modrm_reg == CFI_SP) { + ADD_OP(op) { + op->src.type = OP_SRC_REG; +- op->src.reg = modrm_reg; +- op->dest.type = OP_DEST_REG; +- op->dest.reg = CFI_SP; ++ op->src.reg = CFI_SP; ++ op->dest.type = OP_DEST_REG_INDIRECT; ++ op->dest.reg = modrm_rm; ++ op->dest.offset = ins.displacement.value; + } + break; + } +diff --git a/tools/objtool/check.c b/tools/objtool/check.c +index 4adb3f3d9aed8..ad83bb3197225 100644 +--- a/tools/objtool/check.c ++++ b/tools/objtool/check.c +@@ -3021,6 +3021,20 @@ static int update_cfi_state(struct instruction *insn, + cfi->stack_size += 8; + } + ++ else if (cfi->vals[op->src.reg].base == CFI_CFA) { ++ /* ++ * Clang RSP musical chairs: ++ * ++ * mov %rsp, %rdx [handled above] ++ * ... ++ * mov %rdx, %rbx [handled here] ++ * ... ++ * mov %rbx, %rsp [handled above] ++ */ ++ cfi->vals[op->dest.reg].base = CFI_CFA; ++ cfi->vals[op->dest.reg].offset = cfi->vals[op->src.reg].offset; ++ } ++ + + break; + +-- +2.51.0 + diff --git a/queue-6.12/perf-make-sure-to-use-pmu_ctx-pmu-for-groups.patch b/queue-6.12/perf-make-sure-to-use-pmu_ctx-pmu-for-groups.patch new file mode 100644 index 0000000000..8a3fbe96cb --- /dev/null +++ b/queue-6.12/perf-make-sure-to-use-pmu_ctx-pmu-for-groups.patch @@ -0,0 +1,99 @@ +From f2ae4c9d4f7b8168f1d480851aa9a61e6f565177 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Mar 2026 13:55:46 +0100 +Subject: perf: Make sure to use pmu_ctx->pmu for groups + +From: Peter Zijlstra + +[ Upstream commit 4b9ce671960627b2505b3f64742544ae9801df97 ] + +Oliver reported that x86_pmu_del() ended up doing an out-of-bound memory access +when group_sched_in() fails and needs to roll back. + +This *should* be handled by the transaction callbacks, but he found that when +the group leader is a software event, the transaction handlers of the wrong PMU +are used. Despite the move_group case in perf_event_open() and group_sched_in() +using pmu_ctx->pmu. + +Turns out, inherit uses event->pmu to clone the events, effectively undoing the +move_group case for all inherited contexts. Fix this by also making inherit use +pmu_ctx->pmu, ensuring all inherited counters end up in the same pmu context. + +Similarly, __perf_event_read() should use equally use pmu_ctx->pmu for the +group case. + +Fixes: bd2756811766 ("perf: Rewrite core context handling") +Reported-by: Oliver Rosenberg +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Ian Rogers +Link: https://patch.msgid.link/20260309133713.GB606826@noisy.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + kernel/events/core.c | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 814b6536b09d4..bcedf9611cf4f 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -4634,7 +4634,7 @@ static void __perf_event_read(void *info) + struct perf_event *sub, *event = data->event; + struct perf_event_context *ctx = event->ctx; + struct perf_cpu_context *cpuctx = this_cpu_ptr(&perf_cpu_context); +- struct pmu *pmu = event->pmu; ++ struct pmu *pmu; + + /* + * If this is a task context, we need to check whether it is +@@ -4646,7 +4646,7 @@ static void __perf_event_read(void *info) + if (ctx->task && cpuctx->task_ctx != ctx) + return; + +- raw_spin_lock(&ctx->lock); ++ guard(raw_spinlock)(&ctx->lock); + ctx_time_update_event(ctx, event); + + perf_event_update_time(event); +@@ -4654,25 +4654,22 @@ static void __perf_event_read(void *info) + perf_event_update_sibling_time(event); + + if (event->state != PERF_EVENT_STATE_ACTIVE) +- goto unlock; ++ return; + + if (!data->group) { +- pmu->read(event); ++ perf_pmu_read(event); + data->ret = 0; +- goto unlock; ++ return; + } + ++ pmu = event->pmu_ctx->pmu; + pmu->start_txn(pmu, PERF_PMU_TXN_READ); + +- pmu->read(event); +- ++ perf_pmu_read(event); + for_each_sibling_event(sub, event) + perf_pmu_read(sub); + + data->ret = pmu->commit_txn(pmu); +- +-unlock: +- raw_spin_unlock(&ctx->lock); + } + + static inline u64 perf_event_count(struct perf_event *event, bool self) +@@ -13789,7 +13786,7 @@ inherit_event(struct perf_event *parent_event, + get_ctx(child_ctx); + child_event->ctx = child_ctx; + +- pmu_ctx = find_get_pmu_context(child_event->pmu, child_ctx, child_event); ++ pmu_ctx = find_get_pmu_context(parent_event->pmu_ctx->pmu, child_ctx, child_event); + if (IS_ERR(pmu_ctx)) { + free_event(child_event); + return ERR_CAST(pmu_ctx); +-- +2.51.0 + diff --git a/queue-6.12/platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch b/queue-6.12/platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch new file mode 100644 index 0000000000..a4bf3dfaa2 --- /dev/null +++ b/queue-6.12/platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch @@ -0,0 +1,51 @@ +From cb93c801d35070ff2bab42462be9cb7d496fce17 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 23:46:27 -0500 +Subject: platform/x86: intel-hid: Add Dell 14 Plus 2-in-1 to + dmi_vgbs_allow_list +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Peter Metz + +[ Upstream commit 6b3fa0615cd8432148581de62a52f83847af3d70 ] + +The Dell 14 Plus 2-in-1 (model DB04250) requires the VGBS allow list +entry to correctly enable the tablet mode switch. Without this, the +chassis state is not reported, and the hinge rotation only emits +unknown scancodes. + +Verified on Dell 14 Plus 2-in-1 DB04250. + +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221090 +Signed-off-by: Peter Metz +Reviewed-by: Hans de Goede +Link: https://patch.msgid.link/20260213044627.203638-1-peter.metz@unarin.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/intel/hid.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c +index 04056fbd92196..0b21d8317db30 100644 +--- a/drivers/platform/x86/intel/hid.c ++++ b/drivers/platform/x86/intel/hid.c +@@ -180,6 +180,12 @@ static const struct dmi_system_id dmi_vgbs_allow_list[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Dell Pro Rugged 12 Tablet RA02260"), + }, + }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Dell 14 Plus 2-in-1 DB04250"), ++ }, ++ }, + { } + }; + +-- +2.51.0 + diff --git a/queue-6.12/platform-x86-intel-hid-enable-5-button-array-on-thin.patch b/queue-6.12/platform-x86-intel-hid-enable-5-button-array-on-thin.patch new file mode 100644 index 0000000000..d91d4f8f5c --- /dev/null +++ b/queue-6.12/platform-x86-intel-hid-enable-5-button-array-on-thin.patch @@ -0,0 +1,52 @@ +From 8229a1c1747c32478ab9f1f3a4bbdd832fe8844b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 09:56:25 +0100 +Subject: platform/x86: intel-hid: Enable 5-button array on ThinkPad X1 Fold 16 + Gen 1 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Leif Skunberg + +[ Upstream commit b38d478dad79e61e8a65931021bdfd7a71741212 ] + +The Lenovo ThinkPad X1 Fold 16 Gen 1 has physical volume up/down +buttons that are handled through the intel-hid 5-button array +interface. The firmware does not advertise 5-button array support via +HEBC, so the driver relies on a DMI allowlist to enable it. + +Add the ThinkPad X1 Fold 16 Gen 1 to the button_array_table so the +volume buttons work out of the box. + +Signed-off-by: Leif Skunberg +Reviewed-by: Hans de Goede +Link: https://patch.msgid.link/20260210085625.34380-1-diamondback@cohunt.app +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/intel/hid.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c +index 0b21d8317db30..a51b65280bc40 100644 +--- a/drivers/platform/x86/intel/hid.c ++++ b/drivers/platform/x86/intel/hid.c +@@ -126,6 +126,13 @@ static const struct dmi_system_id button_array_table[] = { + DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Tablet Gen 2"), + }, + }, ++ { ++ .ident = "Lenovo ThinkPad X1 Fold 16 Gen 1", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Fold 16 Gen 1"), ++ }, ++ }, + { + .ident = "Microsoft Surface Go 3", + .matches = { +-- +2.51.0 + diff --git a/queue-6.12/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch b/queue-6.12/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch new file mode 100644 index 0000000000..76868f757d --- /dev/null +++ b/queue-6.12/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch @@ -0,0 +1,71 @@ +From ef22c30cd50641a252dea403ad5b0bfd9cdb1f49 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 14:23:46 +0100 +Subject: platform/x86: touchscreen_dmi: Add quirk for y-inverted Goodix + touchscreen on SUPI S10 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Hans de Goede + +[ Upstream commit 7d87ed70fc95482c12edf9493c249b6413be485e ] + +The touchscreen on the SUPI S10 tablet reports inverted Y coordinates, +causing touch input to be mirrored vertically relative to the display. + +Add a quirk to set the "touchscreen-inverted-y" boolean device-property +on the touchscreen device, so that the goodix_ts driver will fixup +the coordinates. + +Reported-by: Yajat Kumar +Closes: https://lore.kernel.org/linux-input/20251230221639.582406-1-yajatapps3@gmail.com/ +Tested-by: Yajat Kumar +Signed-off-by: Hans de Goede +Link: https://patch.msgid.link/20260217132346.34535-1-johannes.goede@oss.qualcomm.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/touchscreen_dmi.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c +index 0a39f68c641d1..02b0bb8af80a9 100644 +--- a/drivers/platform/x86/touchscreen_dmi.c ++++ b/drivers/platform/x86/touchscreen_dmi.c +@@ -410,6 +410,16 @@ static const struct ts_dmi_data gdix1002_upside_down_data = { + .properties = gdix1001_upside_down_props, + }; + ++static const struct property_entry gdix1001_y_inverted_props[] = { ++ PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), ++ { } ++}; ++ ++static const struct ts_dmi_data gdix1001_y_inverted_data = { ++ .acpi_name = "GDIX1001", ++ .properties = gdix1001_y_inverted_props, ++}; ++ + static const struct property_entry gp_electronic_t701_props[] = { + PROPERTY_ENTRY_U32("touchscreen-size-x", 960), + PROPERTY_ENTRY_U32("touchscreen-size-y", 640), +@@ -1632,6 +1642,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_SKU, "PN20170413488"), + }, + }, ++ { ++ /* SUPI S10 */ ++ .driver_data = (void *)&gdix1001_y_inverted_data, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "SUPI"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "S10"), ++ }, ++ }, + { + /* Techbite Arc 11.6 */ + .driver_data = (void *)&techbite_arc_11_6_data, +-- +2.51.0 + diff --git a/queue-6.12/sched_ext-use-write_once-for-the-write-side-of-dsq-s.patch b/queue-6.12/sched_ext-use-write_once-for-the-write-side-of-dsq-s.patch new file mode 100644 index 0000000000..c59682bc5f --- /dev/null +++ b/queue-6.12/sched_ext-use-write_once-for-the-write-side-of-dsq-s.patch @@ -0,0 +1,53 @@ +From 300b6518547ee1930db6545b74a7dbdfa22b1459 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Mar 2026 13:37:30 +0800 +Subject: sched_ext: Use WRITE_ONCE() for the write side of dsq->seq update + +From: zhidao su + +[ Upstream commit 7a8464555d2e5f038758bb19e72ab4710b79e9cd ] + +bpf_iter_scx_dsq_new() reads dsq->seq via READ_ONCE() without holding +any lock, making dsq->seq a lock-free concurrently accessed variable. +However, dispatch_enqueue(), the sole writer of dsq->seq, uses a plain +increment without the matching WRITE_ONCE() on the write side: + + dsq->seq++; + ^^^^^^^^^^^ + plain write -- KCSAN data race + +The KCSAN documentation requires that if one accessor uses READ_ONCE() +or WRITE_ONCE() on a variable to annotate lock-free access, all other +accesses must also use the appropriate accessor. A plain write leaves +the pair incomplete and will trigger KCSAN warnings. + +Fix by using WRITE_ONCE() for the write side of the update: + + WRITE_ONCE(dsq->seq, dsq->seq + 1); + +This is consistent with bpf_iter_scx_dsq_new() and makes the +concurrent access annotation complete and KCSAN-clean. + +Signed-off-by: zhidao su +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/sched/ext.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c +index 545f197d330c1..86ef9c8f45dae 100644 +--- a/kernel/sched/ext.c ++++ b/kernel/sched/ext.c +@@ -1775,7 +1775,7 @@ static void dispatch_enqueue(struct scx_dispatch_q *dsq, struct task_struct *p, + } + + /* seq records the order tasks are queued, used by BPF DSQ iterator */ +- dsq->seq++; ++ WRITE_ONCE(dsq->seq, dsq->seq + 1); + p->scx.dsq_seq = dsq->seq; + + dsq_mod_nr(dsq, 1); +-- +2.51.0 + diff --git a/queue-6.12/scsi-devinfo-add-blist_skip_io_hints-for-iomega-zip.patch b/queue-6.12/scsi-devinfo-add-blist_skip_io_hints-for-iomega-zip.patch new file mode 100644 index 0000000000..5dd1ada66c --- /dev/null +++ b/queue-6.12/scsi-devinfo-add-blist_skip_io_hints-for-iomega-zip.patch @@ -0,0 +1,44 @@ +From 30f720a6ad510d3d148259c53eeab796381a8fa6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Feb 2026 19:18:23 +0100 +Subject: scsi: devinfo: Add BLIST_SKIP_IO_HINTS for Iomega ZIP + +From: Florian Fuchs + +[ Upstream commit 80bf3b28d32b431f84f244a8469488eb6d96afbb ] + +The Iomega ZIP 100 (Z100P2) can't process IO Advice Hints Grouping mode +page query. It immediately switches to the status phase 0xb8 after +receiving the subpage code 0x05 of MODE_SENSE_10 command, which fails +imm_out() and turns into DID_ERROR of this command, which leads to unusable +device. This was tested with an Iomega ZIP 100 (Z100P2) connected with a +StarTech PEX1P2 AX99100 PCIe parallel port card. + +Prior to this fix, Test Unit Ready fails and the drive can't be used: + IMM: returned SCSI status b8 + sd 7:0:6:0: [sdh] Test Unit Ready failed: Result: hostbyte=0x01 driverbyte=DRIVER_OK + +Signed-off-by: Florian Fuchs +Link: https://patch.msgid.link/20260227181823.892932-1-fuchsfl@gmail.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/scsi_devinfo.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c +index 90f1393a23f87..3cdc4cd4b1639 100644 +--- a/drivers/scsi/scsi_devinfo.c ++++ b/drivers/scsi/scsi_devinfo.c +@@ -190,7 +190,7 @@ static struct { + {"IBM", "2076", NULL, BLIST_NO_VPD_SIZE}, + {"IBM", "2105", NULL, BLIST_RETRY_HWERROR}, + {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN}, +- {"IOMEGA", "ZIP", NULL, BLIST_NOTQ | BLIST_NOLUN}, ++ {"IOMEGA", "ZIP", NULL, BLIST_NOTQ | BLIST_NOLUN | BLIST_SKIP_IO_HINTS}, + {"IOMEGA", "Io20S *F", NULL, BLIST_KEY}, + {"INSITE", "Floptical F*8I", NULL, BLIST_KEY}, + {"INSITE", "I325VM", NULL, BLIST_KEY}, +-- +2.51.0 + diff --git a/queue-6.12/scsi-mpi3mr-clear-reset-history-on-ready-and-recheck.patch b/queue-6.12/scsi-mpi3mr-clear-reset-history-on-ready-and-recheck.patch new file mode 100644 index 0000000000..3e12a90e3d --- /dev/null +++ b/queue-6.12/scsi-mpi3mr-clear-reset-history-on-ready-and-recheck.patch @@ -0,0 +1,59 @@ +From 264ee5c1bf3c8078a614f68f886c20071114cef0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Feb 2026 13:56:22 +0530 +Subject: scsi: mpi3mr: Clear reset history on ready and recheck state after + timeout + +From: Ranjan Kumar + +[ Upstream commit dbd53975ed4132d161b6a97ebe785a262380182d ] + +The driver retains reset history even after the IOC has successfully +reached the READY state. That leaves stale reset information active during +normal operation and can mislead recovery and diagnostics. In addition, if +the IOC becomes READY just as the ready timeout loop exits, the driver +still follows the failure path and may retry or report failure incorrectly. + +Clear reset history once READY is confirmed so driver state matches actual +IOC status. After the timeout loop, recheck the IOC state and treat READY +as success instead of failing. + +Signed-off-by: Ranjan Kumar +Link: https://patch.msgid.link/20260225082622.82588-1-ranjan.kumar@broadcom.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/mpi3mr/mpi3mr_fw.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c +index 3a057a0f0d809..25e8186f5df49 100644 +--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c ++++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c +@@ -1514,6 +1514,7 @@ static int mpi3mr_bring_ioc_ready(struct mpi3mr_ioc *mrioc) + ioc_info(mrioc, + "successfully transitioned to %s state\n", + mpi3mr_iocstate_name(ioc_state)); ++ mpi3mr_clear_reset_history(mrioc); + return 0; + } + ioc_status = readl(&mrioc->sysif_regs->ioc_status); +@@ -1533,6 +1534,15 @@ static int mpi3mr_bring_ioc_ready(struct mpi3mr_ioc *mrioc) + elapsed_time_sec = jiffies_to_msecs(jiffies - start_time)/1000; + } while (elapsed_time_sec < mrioc->ready_timeout); + ++ ioc_state = mpi3mr_get_iocstate(mrioc); ++ if (ioc_state == MRIOC_STATE_READY) { ++ ioc_info(mrioc, ++ "successfully transitioned to %s state after %llu seconds\n", ++ mpi3mr_iocstate_name(ioc_state), elapsed_time_sec); ++ mpi3mr_clear_reset_history(mrioc); ++ return 0; ++ } ++ + out_failed: + elapsed_time_sec = jiffies_to_msecs(jiffies - start_time)/1000; + if ((retry < 2) && (elapsed_time_sec < (mrioc->ready_timeout - 60))) { +-- +2.51.0 + diff --git a/queue-6.12/series b/queue-6.12/series new file mode 100644 index 0000000000..252f801e62 --- /dev/null +++ b/queue-6.12/series @@ -0,0 +1,46 @@ +cxl-port-fix-use-after-free-of-parent_port-in-cxl_de.patch +bpf-fix-constant-blinding-for-probe_mem32-stores.patch +perf-make-sure-to-use-pmu_ctx-pmu-for-groups.patch +cxl-hdm-avoid-incorrect-dvsec-fallback-when-hdm-deco.patch +hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch +sh-platform_early-remove-pdev-driver_override-check.patch +driver-core-generalize-driver_override-in-struct-dev.patch +driver-core-platform-use-generic-driver_override-inf.patch +bpf-release-module-btf-idr-before-module-unload.patch +bpf-fix-undefined-behavior-in-interpreter-sdiv-smod-.patch +bpf-fix-unsound-scalar-forking-in-maybe_fork_scalars.patch +hid-asus-avoid-memory-leak-in-asus_report_fixup.patch +platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch +nvme-pci-cap-queue-creation-to-used-queues.patch +nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch +platform-x86-intel-hid-enable-5-button-array-on-thin.patch +platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch +nvme-pci-ensure-we-re-polling-a-polled-queue.patch +hid-magicmouse-fix-battery-reporting-for-apple-magic.patch +hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch +hid-apple-add-epomaker-th87-to-the-non-apple-keyboar.patch +net-usb-r8152-add-trendnet-tuc-et2g.patch +kbuild-install-extmod-build-package-resolve_btfids-i.patch +hid-mcp2221-cancel-last-i2c-command-on-read-error.patch +hid-asus-add-xg-mobile-2023-external-hardware-suppor.patch +module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch +asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch +scsi-mpi3mr-clear-reset-history-on-ready-and-recheck.patch +scsi-devinfo-add-blist_skip_io_hints-for-iomega-zip.patch +asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-13155 +dma-buf-include-ioctl.h-in-uapi-header.patch +alsa-hda-senary-ensure-eapd-is-enabled-during-init.patch +drm-ttm-tests-fix-build-failure-on-preempt_rt.patch +bpf-fix-u32-s32-bounds-when-ranges-cross-min-max-bou.patch +hid-apple-avoid-memory-leak-in-apple_report_fixup.patch +sched_ext-use-write_once-for-the-write-side-of-dsq-s.patch +btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch +alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch +alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch +objtool-handle-clang-rsp-musical-chairs.patch +nvmet-move-async-event-work-off-nvmet-wq.patch +drm-amdgpu-fix-gpu-idle-power-consumption-issue-for-.patch +usb-core-new-quirk-to-handle-devices-with-zero-confi.patch +spi-intel-pci-add-support-for-nova-lake-mobile-spi-f.patch +alsa-hda-realtek-add-quirk-for-asus-um6702rc.patch +i3c-master-dw-i3c-fix-missing-of_node-for-virtual-i2.patch diff --git a/queue-6.12/sh-platform_early-remove-pdev-driver_override-check.patch b/queue-6.12/sh-platform_early-remove-pdev-driver_override-check.patch new file mode 100644 index 0000000000..2ba4fcaa8d --- /dev/null +++ b/queue-6.12/sh-platform_early-remove-pdev-driver_override-check.patch @@ -0,0 +1,45 @@ +From d8f6a3af02504b9d97f700590d08b56d6e11182a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Mar 2026 00:37:15 +0100 +Subject: sh: platform_early: remove pdev->driver_override check + +From: Danilo Krummrich + +[ Upstream commit c5f60e3f07b6609562d21efda878e83ce8860728 ] + +In commit 507fd01d5333 ("drivers: move the early platform device support to +arch/sh") platform_match() was copied over to the sh platform_early +code, accidentally including the driver_override check. + +This check does not make sense for platform_early, as sysfs is not even +available in first place at this point in the boot process, hence remove +the check. + +Reviewed-by: Greg Kroah-Hartman +Reviewed-by: Geert Uytterhoeven +Fixes: 507fd01d5333 ("drivers: move the early platform device support to arch/sh") +Link: https://lore.kernel.org/all/DH4M3DJ4P58T.1BGVAVXN71Z09@kernel.org/ +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + arch/sh/drivers/platform_early.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c +index 143747c45206f..48ddbc547bd9a 100644 +--- a/arch/sh/drivers/platform_early.c ++++ b/arch/sh/drivers/platform_early.c +@@ -26,10 +26,6 @@ static int platform_match(struct device *dev, struct device_driver *drv) + struct platform_device *pdev = to_platform_device(dev); + struct platform_driver *pdrv = to_platform_driver(drv); + +- /* When driver_override is set, only bind to the matching driver */ +- if (pdev->driver_override) +- return !strcmp(pdev->driver_override, drv->name); +- + /* Then try to match against the id table */ + if (pdrv->id_table) + return platform_match_id(pdrv->id_table, pdev) != NULL; +-- +2.51.0 + diff --git a/queue-6.12/spi-intel-pci-add-support-for-nova-lake-mobile-spi-f.patch b/queue-6.12/spi-intel-pci-add-support-for-nova-lake-mobile-spi-f.patch new file mode 100644 index 0000000000..a6246d7236 --- /dev/null +++ b/queue-6.12/spi-intel-pci-add-support-for-nova-lake-mobile-spi-f.patch @@ -0,0 +1,36 @@ +From cfd275472bca4dbdf69481c49f01933abffdc673 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Mar 2026 16:37:03 +0100 +Subject: spi: intel-pci: Add support for Nova Lake mobile SPI flash + +From: Alan Borzeszkowski + +[ Upstream commit 85b731ad4bbf6eb3fedf267ab00be3596f148432 ] + +Add Intel Nova Lake PCD-H SPI serial flash PCI ID to the list of +supported devices. + +Signed-off-by: Alan Borzeszkowski +Acked-by: Mika Westerberg +Link: https://patch.msgid.link/20260309153703.74282-1-alan.borzeszkowski@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-intel-pci.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/spi/spi-intel-pci.c b/drivers/spi/spi-intel-pci.c +index 5c0dec90eec1d..43692315ea305 100644 +--- a/drivers/spi/spi-intel-pci.c ++++ b/drivers/spi/spi-intel-pci.c +@@ -86,6 +86,7 @@ static const struct pci_device_id intel_spi_pci_ids[] = { + { PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xa823), (unsigned long)&cnl_info }, ++ { PCI_VDEVICE(INTEL, 0xd323), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xe323), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xe423), (unsigned long)&cnl_info }, + { }, +-- +2.51.0 + diff --git a/queue-6.12/usb-core-new-quirk-to-handle-devices-with-zero-confi.patch b/queue-6.12/usb-core-new-quirk-to-handle-devices-with-zero-confi.patch new file mode 100644 index 0000000000..f96b1c7156 --- /dev/null +++ b/queue-6.12/usb-core-new-quirk-to-handle-devices-with-zero-confi.patch @@ -0,0 +1,107 @@ +From d0cd41b6500a886b1d372569292a1957dc2d8789 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Feb 2026 16:49:31 +0800 +Subject: usb: core: new quirk to handle devices with zero configurations + +From: Jie Deng + +[ Upstream commit 9f6a983cfa22ac662c86e60816d3a357d4b551e9 ] + +Some USB devices incorrectly report bNumConfigurations as 0 in their +device descriptor, which causes the USB core to reject them during +enumeration. +logs: +usb 1-2: device descriptor read/64, error -71 +usb 1-2: no configurations +usb 1-2: can't read configurations, error -22 + +However, these devices actually work correctly when +treated as having a single configuration. + +Add a new quirk USB_QUIRK_FORCE_ONE_CONFIG to handle such devices. +When this quirk is set, assume the device has 1 configuration instead +of failing with -EINVAL. + +This quirk is applied to the device with VID:PID 5131:2007 which +exhibits this behavior. + +Signed-off-by: Jie Deng +Link: https://patch.msgid.link/20260227084931.1527461-1-dengjie03@kylinos.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + Documentation/admin-guide/kernel-parameters.txt | 3 +++ + drivers/usb/core/config.c | 6 +++++- + drivers/usb/core/quirks.c | 5 +++++ + include/linux/usb/quirks.h | 3 +++ + 4 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index e88505e945d52..811345669be4e 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -7249,6 +7249,9 @@ + p = USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT + (Reduce timeout of the SET_ADDRESS + request from 5000 ms to 500 ms); ++ q = USB_QUIRK_FORCE_ONE_CONFIG (Device ++ claims zero configurations, ++ forcing to 1); + Example: quirks=0781:5580:bk,0a5c:5834:gij + + usbhid.mousepoll= +diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c +index bbc3cb1ba7b5c..0baecdd342c7a 100644 +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -891,7 +891,11 @@ int usb_get_configuration(struct usb_device *dev) + dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG; + } + +- if (ncfg < 1) { ++ if (ncfg < 1 && dev->quirks & USB_QUIRK_FORCE_ONE_CONFIG) { ++ dev_info(ddev, "Device claims zero configurations, forcing to 1\n"); ++ dev->descriptor.bNumConfigurations = 1; ++ ncfg = 1; ++ } else if (ncfg < 1) { + dev_err(ddev, "no configurations\n"); + return -EINVAL; + } +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index c12942a533ce2..53b08d6cf7824 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -141,6 +141,8 @@ static int quirks_param_set(const char *value, const struct kernel_param *kp) + case 'p': + flags |= USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT; + break; ++ case 'q': ++ flags |= USB_QUIRK_FORCE_ONE_CONFIG; + /* Ignore unrecognized flag characters */ + } + } +@@ -594,6 +596,9 @@ static const struct usb_device_id usb_quirk_list[] = { + /* VCOM device */ + { USB_DEVICE(0x4296, 0x7570), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS }, + ++ /* Noji-MCS SmartCard Reader */ ++ { USB_DEVICE(0x5131, 0x2007), .driver_info = USB_QUIRK_FORCE_ONE_CONFIG }, ++ + /* INTEL VALUE SSD */ + { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, + +diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h +index 2f7bd2fdc6164..b3cc7beab4a3c 100644 +--- a/include/linux/usb/quirks.h ++++ b/include/linux/usb/quirks.h +@@ -78,4 +78,7 @@ + /* skip BOS descriptor request */ + #define USB_QUIRK_NO_BOS BIT(17) + ++/* Device claims zero configurations, forcing to 1 */ ++#define USB_QUIRK_FORCE_ONE_CONFIG BIT(18) ++ + #endif /* __LINUX_USB_QUIRKS_H */ +-- +2.51.0 + diff --git a/queue-6.18/alsa-hda-hdmi-add-tegra238-hda-codec-device-id.patch b/queue-6.18/alsa-hda-hdmi-add-tegra238-hda-codec-device-id.patch new file mode 100644 index 0000000000..6373b4235f --- /dev/null +++ b/queue-6.18/alsa-hda-hdmi-add-tegra238-hda-codec-device-id.patch @@ -0,0 +1,34 @@ +From c92bcbc4d3a049fc7b1a9761d7024b5112a50b44 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Mar 2026 14:12:17 +0530 +Subject: ALSA: hda/hdmi: Add Tegra238 HDA codec device ID + +From: Sheetal + +[ Upstream commit 5f4338e5633dc034a81000b2516a78cfb51c601d ] + +Add Tegra238 HDA codec device in hda_device_id list. + +Signed-off-by: Sheetal +Link: https://patch.msgid.link/20260302084217.3135982-1-sheetal@nvidia.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/hda/codecs/hdmi/tegrahdmi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/hda/codecs/hdmi/tegrahdmi.c b/sound/hda/codecs/hdmi/tegrahdmi.c +index 5f6fe31aa2028..ebb6410a48313 100644 +--- a/sound/hda/codecs/hdmi/tegrahdmi.c ++++ b/sound/hda/codecs/hdmi/tegrahdmi.c +@@ -299,6 +299,7 @@ static const struct hda_device_id snd_hda_id_tegrahdmi[] = { + HDA_CODEC_ID_MODEL(0x10de002f, "Tegra194 HDMI/DP2", MODEL_TEGRA), + HDA_CODEC_ID_MODEL(0x10de0030, "Tegra194 HDMI/DP3", MODEL_TEGRA), + HDA_CODEC_ID_MODEL(0x10de0031, "Tegra234 HDMI/DP", MODEL_TEGRA234), ++ HDA_CODEC_ID_MODEL(0x10de0032, "Tegra238 HDMI/DP", MODEL_TEGRA234), + HDA_CODEC_ID_MODEL(0x10de0033, "SoC 33 HDMI/DP", MODEL_TEGRA234), + HDA_CODEC_ID_MODEL(0x10de0034, "Tegra264 HDMI/DP", MODEL_TEGRA234), + HDA_CODEC_ID_MODEL(0x10de0035, "SoC 35 HDMI/DP", MODEL_TEGRA234), +-- +2.51.0 + diff --git a/queue-6.18/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch b/queue-6.18/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch new file mode 100644 index 0000000000..9f4965a218 --- /dev/null +++ b/queue-6.18/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch @@ -0,0 +1,43 @@ +From 6427512d07661b2cb197957be6d272a394c82df0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Mar 2026 06:29:06 +0500 +Subject: ALSA: hda/realtek: Add headset jack quirk for Thinkpad X390 + +From: Uzair Mughal + +[ Upstream commit 542127f6528ca7cc3cf61e1651d6ccb58495f953 ] + +The Lenovo ThinkPad X390 (ALC257 codec, subsystem ID 0x17aa2288) +does not report headset button press events. Headphone insertion is +detected (SW_HEADPHONE_INSERT), but pressing the inline microphone +button on a headset produces no input events. + +Add a SND_PCI_QUIRK entry that maps this subsystem ID to +ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, which enables +headset jack button detection through alc_fixup_headset_jack() +and ThinkPad ACPI integration. This is the same fixup used by +similar ThinkPad models (P1 Gen 3, X1 Extreme Gen 3). + +Signed-off-by: Uzair Mughal +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20260307012906.20093-1-contact@uzair.is-a.dev +Signed-off-by: Sasha Levin +--- + sound/hda/codecs/realtek/alc269.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c +index 437a7a2070e58..a42c3d43f5d93 100644 +--- a/sound/hda/codecs/realtek/alc269.c ++++ b/sound/hda/codecs/realtek/alc269.c +@@ -7323,6 +7323,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), + SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), + SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), ++ SND_PCI_QUIRK(0x17aa, 0x2288, "Thinkpad X390", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x22c1, "Thinkpad P1 Gen 3", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), +-- +2.51.0 + diff --git a/queue-6.18/alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch b/queue-6.18/alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch new file mode 100644 index 0000000000..3223396edd --- /dev/null +++ b/queue-6.18/alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch @@ -0,0 +1,38 @@ +From a736ca404f8286d134912bbdd599a9051b622d6a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Mar 2026 11:27:27 +0800 +Subject: ALSA: hda/realtek: add HP Laptop 14s-dr5xxx mute LED quirk + +From: Liucheng Lu + +[ Upstream commit 178dd118c0f07fd63a9ed74cfbd8c31ae50e33af ] + +HP Laptop 14s-dr5xxx with ALC236 codec does not handle the toggling of +the mute LED. +This patch adds a quirk entry for subsystem ID 0x8a1f using +ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 fixup, enabling correct mute LED +behavior. + +Signed-off-by: Liucheng Lu +Link: https://patch.msgid.link/PAVPR03MB9774F3FCE9CCD181C585281AE37BA@PAVPR03MB9774.eurprd03.prod.outlook.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/hda/codecs/realtek/alc269.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c +index a32a966be8ba1..437a7a2070e58 100644 +--- a/sound/hda/codecs/realtek/alc269.c ++++ b/sound/hda/codecs/realtek/alc269.c +@@ -6792,6 +6792,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x89da, "HP Spectre x360 14t-ea100", ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX), + SND_PCI_QUIRK(0x103c, 0x89e7, "HP Elite x2 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8a0f, "HP Pavilion 14-ec1xxx", ALC287_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8a1f, "HP Laptop 14s-dr5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), + SND_PCI_QUIRK(0x103c, 0x8a26, "HP Victus 16-d1xxx (MB 8A26)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), +-- +2.51.0 + diff --git a/queue-6.18/alsa-hda-realtek-add-quirk-for-asus-um6702rc.patch b/queue-6.18/alsa-hda-realtek-add-quirk-for-asus-um6702rc.patch new file mode 100644 index 0000000000..0d847b8b29 --- /dev/null +++ b/queue-6.18/alsa-hda-realtek-add-quirk-for-asus-um6702rc.patch @@ -0,0 +1,37 @@ +From 50fc35614b129fae1479d92432db3d02577cefe5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 20:33:17 +0800 +Subject: ALSA: hda/realtek: add quirk for ASUS UM6702RC + +From: Zhang Heng + +[ Upstream commit 0d3429f12133c2ca47aa82ddab2342bc360c47d3 ] + +The sound card of this machine cannot adjust the volume, it can only +be 0 or 100%. The reason is that the DAC with pin 0x17 is connected +to 0x06. Testing found that connecting 0x02 can fix this problem. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=220356 +Signed-off-by: Zhang Heng +Link: https://patch.msgid.link/20260306123317.575346-1-zhangheng@kylinos.cn +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/hda/codecs/realtek/alc269.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c +index a42c3d43f5d93..38fe144e6238a 100644 +--- a/sound/hda/codecs/realtek/alc269.c ++++ b/sound/hda/codecs/realtek/alc269.c +@@ -7104,6 +7104,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x1e93, "ASUS ExpertBook B9403CVAR", ALC294_FIXUP_ASUS_HPE), + SND_PCI_QUIRK(0x1043, 0x1eb3, "ASUS Ally RCLA72", ALC287_FIXUP_TAS2781_I2C), + SND_PCI_QUIRK(0x1043, 0x1ed3, "ASUS HN7306W", ALC287_FIXUP_CS35L41_I2C_2), ++ HDA_CODEC_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC285_FIXUP_ASUS_I2C_SPEAKER2_TO_DAC1), + SND_PCI_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), +-- +2.51.0 + diff --git a/queue-6.18/alsa-hda-realtek-add-quirk-for-gigabyte-technology-t.patch b/queue-6.18/alsa-hda-realtek-add-quirk-for-gigabyte-technology-t.patch new file mode 100644 index 0000000000..833b481ced --- /dev/null +++ b/queue-6.18/alsa-hda-realtek-add-quirk-for-gigabyte-technology-t.patch @@ -0,0 +1,58 @@ +From f23c3c42e371894da6e1b62ed357bb9516107dc0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Mar 2026 10:35:59 +0800 +Subject: ALSA: hda/realtek: Add quirk for Gigabyte Technology to fix headphone + +From: Zhang Heng + +[ Upstream commit 56fbbe096a89ff4b52af78a21a4afd9d94bdcc80 ] + +The BIOS of this machine has set 0x19 to mic, which needs to be set +to headphone pin in order to work properly. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=220814 +Signed-off-by: Zhang Heng +Link: https://patch.msgid.link/b55f6ebe-7449-49f7-ae85-00d2ba1e7af0@kylinos.cn +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/hda/codecs/realtek/alc662.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/sound/hda/codecs/realtek/alc662.c b/sound/hda/codecs/realtek/alc662.c +index 5073165d1f3cf..3a943adf90876 100644 +--- a/sound/hda/codecs/realtek/alc662.c ++++ b/sound/hda/codecs/realtek/alc662.c +@@ -313,6 +313,7 @@ enum { + ALC897_FIXUP_HEADSET_MIC_PIN2, + ALC897_FIXUP_UNIS_H3C_X500S, + ALC897_FIXUP_HEADSET_MIC_PIN3, ++ ALC897_FIXUP_H610M_HP_PIN, + }; + + static const struct hda_fixup alc662_fixups[] = { +@@ -766,6 +767,13 @@ static const struct hda_fixup alc662_fixups[] = { + { } + }, + }, ++ [ALC897_FIXUP_H610M_HP_PIN] = { ++ .type = HDA_FIXUP_PINS, ++ .v.pins = (const struct hda_pintbl[]) { ++ { 0x19, 0x0321403f }, /* HP out */ ++ { } ++ }, ++ }, + }; + + static const struct hda_quirk alc662_fixup_tbl[] = { +@@ -815,6 +823,7 @@ static const struct hda_quirk alc662_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), + SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), + SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), ++ SND_PCI_QUIRK(0x1458, 0xa194, "H610M H V2 DDR4", ALC897_FIXUP_H610M_HP_PIN), + SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE), + SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS), + SND_PCI_QUIRK(0x17aa, 0x1057, "Lenovo P360", ALC897_FIXUP_HEADSET_MIC_PIN), +-- +2.51.0 + diff --git a/queue-6.18/alsa-hda-senary-ensure-eapd-is-enabled-during-init.patch b/queue-6.18/alsa-hda-senary-ensure-eapd-is-enabled-during-init.patch new file mode 100644 index 0000000000..48cfb2973a --- /dev/null +++ b/queue-6.18/alsa-hda-senary-ensure-eapd-is-enabled-during-init.patch @@ -0,0 +1,56 @@ +From 1f9fb329db976789b81ef38f30fd338b8e1ff16d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Mar 2026 16:15:16 +0800 +Subject: ALSA: hda/senary: Ensure EAPD is enabled during init + +From: wangdicheng + +[ Upstream commit 7ae0d8f1abbbba6f98cac735145e1206927c67d9 ] + +The driver sets spec->gen.own_eapd_ctl to take manual control of the +EAPD (External Amplifier). However, senary_init does not turn on the +EAPD, while senary_shutdown turns it off. + +Since the generic driver skips EAPD handling when own_eapd_ctl is set, +the EAPD remains off after initialization (e.g., after resume), leaving +the codec in a non-functional state. + +Explicitly call senary_auto_turn_eapd in senary_init to ensure the EAPD +is enabled and the codec is functional. + +Signed-off-by: wangdicheng +Link: https://patch.msgid.link/20260303081516.583438-1-wangdich9700@163.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/hda/codecs/senarytech.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/sound/hda/codecs/senarytech.c b/sound/hda/codecs/senarytech.c +index 9aa1e9bcd9ec0..601b7eb38eb13 100644 +--- a/sound/hda/codecs/senarytech.c ++++ b/sound/hda/codecs/senarytech.c +@@ -25,6 +25,7 @@ struct senary_spec { + /* extra EAPD pins */ + unsigned int num_eapds; + hda_nid_t eapds[4]; ++ bool dynamic_eapd; + hda_nid_t mute_led_eapd; + + unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */ +@@ -131,8 +132,12 @@ static void senary_init_gpio_led(struct hda_codec *codec) + + static int senary_init(struct hda_codec *codec) + { ++ struct senary_spec *spec = codec->spec; ++ + snd_hda_gen_init(codec); + senary_init_gpio_led(codec); ++ if (!spec->dynamic_eapd) ++ senary_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); + + return 0; +-- +2.51.0 + diff --git a/queue-6.18/asoc-amd-acp-add-acp6.3-match-entries-for-cirrus-log.patch b/queue-6.18/asoc-amd-acp-add-acp6.3-match-entries-for-cirrus-log.patch new file mode 100644 index 0000000000..03cec68fb2 --- /dev/null +++ b/queue-6.18/asoc-amd-acp-add-acp6.3-match-entries-for-cirrus-log.patch @@ -0,0 +1,508 @@ +From 33b12ec1d385f42ab8911a3aef6451af5eb79e4e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Feb 2026 13:03:07 +0000 +Subject: ASoC: amd: acp: Add ACP6.3 match entries for Cirrus Logic parts + +From: Simon Trimmer + +[ Upstream commit fd13fc700e3e239826a46448bf7f01847dd26f5a ] + +This adds some match entries for a few system configurations: + +cs42l43 link 0 UID 0 +cs35l56 link 1 UID 0 +cs35l56 link 1 UID 1 +cs35l56 link 1 UID 2 +cs35l56 link 1 UID 3 + +cs42l45 link 1 UID 0 +cs35l63 link 0 UID 0 +cs35l63 link 0 UID 2 +cs35l63 link 0 UID 4 +cs35l63 link 0 UID 6 + +cs42l45 link 0 UID 0 +cs35l63 link 1 UID 0 +cs35l63 link 1 UID 1 + +cs42l45 link 0 UID 0 +cs35l63 link 1 UID 1 +cs35l63 link 1 UID 3 + +cs42l45 link 1 UID 0 +cs35l63 link 0 UID 0 +cs35l63 link 0 UID 1 + +cs42l43 link 1 UID 0 +cs35l56 link 1 UID 0 +cs35l56 link 1 UID 1 +cs35l56 link 1 UID 2 +cs35l56 link 1 UID 3 + +cs35l56 link 1 UID 0 +cs35l56 link 1 UID 1 +cs35l56 link 1 UID 2 +cs35l56 link 1 UID 3 + +cs35l63 link 0 UID 0 +cs35l63 link 0 UID 2 +cs35l63 link 0 UID 4 +cs35l63 link 0 UID 6 + +cs42l43 link 0 UID 1 + +cs42l43b link 0 UID 1 + +cs42l45 link 0 UID 0 + +cs42l45 link 1 UID 0 + +Signed-off-by: Simon Trimmer +Link: https://patch.msgid.link/20260224130307.526626-1-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/amd/acp/amd-acp63-acpi-match.c | 413 +++++++++++++++++++++++ + 1 file changed, 413 insertions(+) + +diff --git a/sound/soc/amd/acp/amd-acp63-acpi-match.c b/sound/soc/amd/acp/amd-acp63-acpi-match.c +index 9b6a49c051cda..1dbbaba3c75b3 100644 +--- a/sound/soc/amd/acp/amd-acp63-acpi-match.c ++++ b/sound/soc/amd/acp/amd-acp63-acpi-match.c +@@ -30,6 +30,20 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = { + .group_id = 1 + }; + ++static const struct snd_soc_acpi_endpoint spk_2_endpoint = { ++ .num = 0, ++ .aggregated = 1, ++ .group_position = 2, ++ .group_id = 1 ++}; ++ ++static const struct snd_soc_acpi_endpoint spk_3_endpoint = { ++ .num = 0, ++ .aggregated = 1, ++ .group_position = 3, ++ .group_id = 1 ++}; ++ + static const struct snd_soc_acpi_adr_device rt711_rt1316_group_adr[] = { + { + .adr = 0x000030025D071101ull, +@@ -103,6 +117,345 @@ static const struct snd_soc_acpi_adr_device rt722_0_single_adr[] = { + } + }; + ++static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = { ++ { /* Jack Playback Endpoint */ ++ .num = 0, ++ .aggregated = 0, ++ .group_position = 0, ++ .group_id = 0, ++ }, ++ { /* DMIC Capture Endpoint */ ++ .num = 1, ++ .aggregated = 0, ++ .group_position = 0, ++ .group_id = 0, ++ }, ++ { /* Jack Capture Endpoint */ ++ .num = 2, ++ .aggregated = 0, ++ .group_position = 0, ++ .group_id = 0, ++ }, ++ { /* Speaker Playback Endpoint */ ++ .num = 3, ++ .aggregated = 0, ++ .group_position = 0, ++ .group_id = 0, ++ }, ++}; ++ ++static const struct snd_soc_acpi_adr_device cs35l56x4_l1u3210_adr[] = { ++ { ++ .adr = 0x00013301FA355601ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_l_endpoint, ++ .name_prefix = "AMP1" ++ }, ++ { ++ .adr = 0x00013201FA355601ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_r_endpoint, ++ .name_prefix = "AMP2" ++ }, ++ { ++ .adr = 0x00013101FA355601ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_2_endpoint, ++ .name_prefix = "AMP3" ++ }, ++ { ++ .adr = 0x00013001FA355601ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_3_endpoint, ++ .name_prefix = "AMP4" ++ }, ++}; ++ ++static const struct snd_soc_acpi_adr_device cs35l63x2_l0u01_adr[] = { ++ { ++ .adr = 0x00003001FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_l_endpoint, ++ .name_prefix = "AMP1" ++ }, ++ { ++ .adr = 0x00003101FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_r_endpoint, ++ .name_prefix = "AMP2" ++ }, ++}; ++ ++static const struct snd_soc_acpi_adr_device cs35l63x2_l1u01_adr[] = { ++ { ++ .adr = 0x00013001FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_l_endpoint, ++ .name_prefix = "AMP1" ++ }, ++ { ++ .adr = 0x00013101FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_r_endpoint, ++ .name_prefix = "AMP2" ++ }, ++}; ++ ++static const struct snd_soc_acpi_adr_device cs35l63x2_l1u13_adr[] = { ++ { ++ .adr = 0x00013101FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_l_endpoint, ++ .name_prefix = "AMP1" ++ }, ++ { ++ .adr = 0x00013301FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_r_endpoint, ++ .name_prefix = "AMP2" ++ }, ++}; ++ ++static const struct snd_soc_acpi_adr_device cs35l63x4_l0u0246_adr[] = { ++ { ++ .adr = 0x00003001FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_l_endpoint, ++ .name_prefix = "AMP1" ++ }, ++ { ++ .adr = 0x00003201FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_r_endpoint, ++ .name_prefix = "AMP2" ++ }, ++ { ++ .adr = 0x00003401FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_2_endpoint, ++ .name_prefix = "AMP3" ++ }, ++ { ++ .adr = 0x00003601FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_3_endpoint, ++ .name_prefix = "AMP4" ++ }, ++}; ++ ++static const struct snd_soc_acpi_adr_device cs42l43_l0u0_adr[] = { ++ { ++ .adr = 0x00003001FA424301ull, ++ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), ++ .endpoints = cs42l43_endpoints, ++ .name_prefix = "cs42l43" ++ } ++}; ++ ++static const struct snd_soc_acpi_adr_device cs42l43_l0u1_adr[] = { ++ { ++ .adr = 0x00003101FA424301ull, ++ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), ++ .endpoints = cs42l43_endpoints, ++ .name_prefix = "cs42l43" ++ } ++}; ++ ++static const struct snd_soc_acpi_adr_device cs42l43b_l0u1_adr[] = { ++ { ++ .adr = 0x00003101FA2A3B01ull, ++ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), ++ .endpoints = cs42l43_endpoints, ++ .name_prefix = "cs42l43" ++ } ++}; ++ ++static const struct snd_soc_acpi_adr_device cs42l43_l1u0_cs35l56x4_l1u0123_adr[] = { ++ { ++ .adr = 0x00013001FA424301ull, ++ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), ++ .endpoints = cs42l43_endpoints, ++ .name_prefix = "cs42l43" ++ }, ++ { ++ .adr = 0x00013001FA355601ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_l_endpoint, ++ .name_prefix = "AMP1" ++ }, ++ { ++ .adr = 0x00013101FA355601ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_r_endpoint, ++ .name_prefix = "AMP2" ++ }, ++ { ++ .adr = 0x00013201FA355601ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_2_endpoint, ++ .name_prefix = "AMP3" ++ }, ++ { ++ .adr = 0x00013301FA355601ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_3_endpoint, ++ .name_prefix = "AMP4" ++ }, ++}; ++ ++static const struct snd_soc_acpi_adr_device cs42l45_l0u0_adr[] = { ++ { ++ .adr = 0x00003001FA424501ull, ++ /* Re-use endpoints, but cs42l45 has no speaker */ ++ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints) - 1, ++ .endpoints = cs42l43_endpoints, ++ .name_prefix = "cs42l45" ++ } ++}; ++ ++static const struct snd_soc_acpi_adr_device cs42l45_l1u0_adr[] = { ++ { ++ .adr = 0x00013001FA424501ull, ++ /* Re-use endpoints, but cs42l45 has no speaker */ ++ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints) - 1, ++ .endpoints = cs42l43_endpoints, ++ .name_prefix = "cs42l45" ++ } ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs35l56x4_l1u3210[] = { ++ { ++ .mask = BIT(1), ++ .num_adr = ARRAY_SIZE(cs35l56x4_l1u3210_adr), ++ .adr_d = cs35l56x4_l1u3210_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs35l63x4_l0u0246[] = { ++ { ++ .mask = BIT(0), ++ .num_adr = ARRAY_SIZE(cs35l63x4_l0u0246_adr), ++ .adr_d = cs35l63x4_l0u0246_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l43_l0u1[] = { ++ { ++ .mask = BIT(0), ++ .num_adr = ARRAY_SIZE(cs42l43_l0u1_adr), ++ .adr_d = cs42l43_l0u1_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l43b_l0u1[] = { ++ { ++ .mask = BIT(0), ++ .num_adr = ARRAY_SIZE(cs42l43b_l0u1_adr), ++ .adr_d = cs42l43b_l0u1_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l43_l0u0_cs35l56x4_l1u3210[] = { ++ { ++ .mask = BIT(0), ++ .num_adr = ARRAY_SIZE(cs42l43_l0u0_adr), ++ .adr_d = cs42l43_l0u0_adr, ++ }, ++ { ++ .mask = BIT(1), ++ .num_adr = ARRAY_SIZE(cs35l56x4_l1u3210_adr), ++ .adr_d = cs35l56x4_l1u3210_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l43_l1u0_cs35l56x4_l1u0123[] = { ++ { ++ .mask = BIT(1), ++ .num_adr = ARRAY_SIZE(cs42l43_l1u0_cs35l56x4_l1u0123_adr), ++ .adr_d = cs42l43_l1u0_cs35l56x4_l1u0123_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l45_l0u0[] = { ++ { ++ .mask = BIT(0), ++ .num_adr = ARRAY_SIZE(cs42l45_l0u0_adr), ++ .adr_d = cs42l45_l0u0_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l45_l0u0_cs35l63x2_l1u01[] = { ++ { ++ .mask = BIT(0), ++ .num_adr = ARRAY_SIZE(cs42l45_l0u0_adr), ++ .adr_d = cs42l45_l0u0_adr, ++ }, ++ { ++ .mask = BIT(1), ++ .num_adr = ARRAY_SIZE(cs35l63x2_l1u01_adr), ++ .adr_d = cs35l63x2_l1u01_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l45_l0u0_cs35l63x2_l1u13[] = { ++ { ++ .mask = BIT(0), ++ .num_adr = ARRAY_SIZE(cs42l45_l0u0_adr), ++ .adr_d = cs42l45_l0u0_adr, ++ }, ++ { ++ .mask = BIT(1), ++ .num_adr = ARRAY_SIZE(cs35l63x2_l1u13_adr), ++ .adr_d = cs35l63x2_l1u13_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l45_l1u0[] = { ++ { ++ .mask = BIT(1), ++ .num_adr = ARRAY_SIZE(cs42l45_l1u0_adr), ++ .adr_d = cs42l45_l1u0_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l45_l1u0_cs35l63x2_l0u01[] = { ++ { ++ .mask = BIT(1), ++ .num_adr = ARRAY_SIZE(cs42l45_l1u0_adr), ++ .adr_d = cs42l45_l1u0_adr, ++ }, ++ { ++ .mask = BIT(0), ++ .num_adr = ARRAY_SIZE(cs35l63x2_l0u01_adr), ++ .adr_d = cs35l63x2_l0u01_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l45_l1u0_cs35l63x4_l0u0246[] = { ++ { ++ .mask = BIT(1), ++ .num_adr = ARRAY_SIZE(cs42l45_l1u0_adr), ++ .adr_d = cs42l45_l1u0_adr, ++ }, ++ { ++ .mask = BIT(0), ++ .num_adr = ARRAY_SIZE(cs35l63x4_l0u0246_adr), ++ .adr_d = cs35l63x4_l0u0246_adr, ++ }, ++ {} ++}; ++ + static const struct snd_soc_acpi_link_adr acp63_rt722_only[] = { + { + .mask = BIT(0), +@@ -135,6 +488,66 @@ struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sdw_machines[] = { + .links = acp63_4_in_1_sdca, + .drv_name = "amd_sdw", + }, ++ { ++ .link_mask = BIT(0) | BIT(1), ++ .links = acp63_cs42l43_l0u0_cs35l56x4_l1u3210, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(0) | BIT(1), ++ .links = acp63_cs42l45_l1u0_cs35l63x4_l0u0246, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(0) | BIT(1), ++ .links = acp63_cs42l45_l0u0_cs35l63x2_l1u01, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(0) | BIT(1), ++ .links = acp63_cs42l45_l0u0_cs35l63x2_l1u13, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(0) | BIT(1), ++ .links = acp63_cs42l45_l1u0_cs35l63x2_l0u01, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(1), ++ .links = acp63_cs42l43_l1u0_cs35l56x4_l1u0123, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(1), ++ .links = acp63_cs35l56x4_l1u3210, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(0), ++ .links = acp63_cs35l63x4_l0u0246, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(0), ++ .links = acp63_cs42l43_l0u1, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(0), ++ .links = acp63_cs42l43b_l0u1, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(0), ++ .links = acp63_cs42l45_l0u0, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(1), ++ .links = acp63_cs42l45_l1u0, ++ .drv_name = "amd_sdw", ++ }, + {}, + }; + EXPORT_SYMBOL(snd_soc_acpi_amd_acp63_sdw_machines); +-- +2.51.0 + diff --git a/queue-6.18/asoc-cs35l56-only-patch-asp-registers-if-the-dai-is-.patch b/queue-6.18/asoc-cs35l56-only-patch-asp-registers-if-the-dai-is-.patch new file mode 100644 index 0000000000..0009e48ad2 --- /dev/null +++ b/queue-6.18/asoc-cs35l56-only-patch-asp-registers-if-the-dai-is-.patch @@ -0,0 +1,113 @@ +From a7029b551d29f1ea96a64101245ac0dbba1d1e57 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Feb 2026 11:01:37 +0000 +Subject: ASoC: cs35l56: Only patch ASP registers if the DAI is part of a + DAIlink + +From: Richard Fitzgerald + +[ Upstream commit 9351cf3fd92dc1349bb75f2f7f7324607dcf596f ] + +Move the ASP register patches to a separate struct and apply this from the +ASP DAI probe() function so that the registers are only patched if the DAI +is part of a DAI link. + +Some systems use the ASP as a special-purpose interconnect and on these +systems the ASP registers are configured by a third party (the firmware, +the BIOS, or another device using the amp's secondary host control +interface). + +If the machine driver does not hook up the ASP DAI then the ASP registers +must be omitted from the patch to prevent overwriting the third party +configuration. + +If the machine driver includes the ASP DAI in a DAI link, this implies that +the machine driver and higher components (such as alsa-ucm) are taking +ownership of the ASP. In this case the ASP registers are patched to known +defaults and the machine driver should configure the ASP. + +Signed-off-by: Richard Fitzgerald +Link: https://patch.msgid.link/20260226110137.1664562-1-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + include/sound/cs35l56.h | 1 + + sound/soc/codecs/cs35l56-shared.c | 16 +++++++++++++++- + sound/soc/codecs/cs35l56.c | 8 ++++++++ + 3 files changed, 24 insertions(+), 1 deletion(-) + +diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h +index ab044ce2aa8b3..0374c251901f5 100644 +--- a/include/sound/cs35l56.h ++++ b/include/sound/cs35l56.h +@@ -344,6 +344,7 @@ extern const struct cirrus_amp_cal_controls cs35l56_calibration_controls; + extern const char * const cs35l56_tx_input_texts[CS35L56_NUM_INPUT_SRC]; + extern const unsigned int cs35l56_tx_input_values[CS35L56_NUM_INPUT_SRC]; + ++int cs35l56_set_asp_patch(struct cs35l56_base *cs35l56_base); + int cs35l56_set_patch(struct cs35l56_base *cs35l56_base); + int cs35l56_mbox_send(struct cs35l56_base *cs35l56_base, unsigned int command); + int cs35l56_firmware_shutdown(struct cs35l56_base *cs35l56_base); +diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-shared.c +index 9e6b9ca2f3547..a13e8eaf277d4 100644 +--- a/sound/soc/codecs/cs35l56-shared.c ++++ b/sound/soc/codecs/cs35l56-shared.c +@@ -16,7 +16,7 @@ + + #include "cs35l56.h" + +-static const struct reg_sequence cs35l56_patch[] = { ++static const struct reg_sequence cs35l56_asp_patch[] = { + /* + * Firmware can change these to non-defaults to satisfy SDCA. + * Ensure that they are at known defaults. +@@ -33,6 +33,20 @@ static const struct reg_sequence cs35l56_patch[] = { + { CS35L56_ASP1TX2_INPUT, 0x00000000 }, + { CS35L56_ASP1TX3_INPUT, 0x00000000 }, + { CS35L56_ASP1TX4_INPUT, 0x00000000 }, ++}; ++ ++int cs35l56_set_asp_patch(struct cs35l56_base *cs35l56_base) ++{ ++ return regmap_register_patch(cs35l56_base->regmap, cs35l56_asp_patch, ++ ARRAY_SIZE(cs35l56_asp_patch)); ++} ++EXPORT_SYMBOL_NS_GPL(cs35l56_set_asp_patch, "SND_SOC_CS35L56_SHARED"); ++ ++static const struct reg_sequence cs35l56_patch[] = { ++ /* ++ * Firmware can change these to non-defaults to satisfy SDCA. ++ * Ensure that they are at known defaults. ++ */ + { CS35L56_SWIRE_DP3_CH1_INPUT, 0x00000018 }, + { CS35L56_SWIRE_DP3_CH2_INPUT, 0x00000019 }, + { CS35L56_SWIRE_DP3_CH3_INPUT, 0x00000029 }, +diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c +index 2c1edbd636efc..193adba0cd1a4 100644 +--- a/sound/soc/codecs/cs35l56.c ++++ b/sound/soc/codecs/cs35l56.c +@@ -324,6 +324,13 @@ static int cs35l56_dsp_event(struct snd_soc_dapm_widget *w, + return wm_adsp_event(w, kcontrol, event); + } + ++static int cs35l56_asp_dai_probe(struct snd_soc_dai *codec_dai) ++{ ++ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(codec_dai->component); ++ ++ return cs35l56_set_asp_patch(&cs35l56->base); ++} ++ + static int cs35l56_asp_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) + { + struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(codec_dai->component); +@@ -528,6 +535,7 @@ static int cs35l56_asp_dai_set_sysclk(struct snd_soc_dai *dai, + } + + static const struct snd_soc_dai_ops cs35l56_ops = { ++ .probe = cs35l56_asp_dai_probe, + .set_fmt = cs35l56_asp_dai_set_fmt, + .set_tdm_slot = cs35l56_asp_dai_set_tdm_slot, + .hw_params = cs35l56_asp_dai_hw_params, +-- +2.51.0 + diff --git a/queue-6.18/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch b/queue-6.18/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch new file mode 100644 index 0000000000..6d4fa475bb --- /dev/null +++ b/queue-6.18/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch @@ -0,0 +1,52 @@ +From 1a4c07042bac9459e0e5853a6adcbbe512ed2429 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 00:25:38 +0000 +Subject: ASoC: fsl_easrc: Fix event generation in fsl_easrc_iec958_set_reg() + +From: Mark Brown + +[ Upstream commit 31ddc62c1cd92e51b9db61d7954b85ae2ec224da ] + +ALSA controls should return 1 if the value in the control changed but the +control put operation fsl_easrc_set_reg() only returns 0 or a negative +error code, causing ALSA to not generate any change events. Add a suitable +check by using regmap_update_bits_check() with the underlying regmap, this +is more clearly and simply correct than trying to verify that one of the +generic ops is exactly equivalent to this one. + +Signed-off-by: Mark Brown +Link: https://patch.msgid.link/20260205-asoc-fsl-easrc-fix-events-v1-2-39d4c766918b@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_easrc.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c +index f404a39009e1a..ec49da2d1ebb2 100644 +--- a/sound/soc/fsl/fsl_easrc.c ++++ b/sound/soc/fsl/fsl_easrc.c +@@ -93,14 +93,17 @@ static int fsl_easrc_set_reg(struct snd_kcontrol *kcontrol, + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_value; ++ struct fsl_asrc *easrc = snd_soc_component_get_drvdata(component); + unsigned int regval = ucontrol->value.integer.value[0]; ++ bool changed; + int ret; + +- ret = snd_soc_component_write(component, mc->regbase, regval); +- if (ret < 0) ++ ret = regmap_update_bits_check(easrc->regmap, mc->regbase, ++ GENMASK(31, 0), regval, &changed); ++ if (ret != 0) + return ret; + +- return 0; ++ return changed; + } + + #define SOC_SINGLE_REG_RW(xname, xreg) \ +-- +2.51.0 + diff --git a/queue-6.18/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-30095 b/queue-6.18/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-30095 new file mode 100644 index 0000000000..57d6e8fa2c --- /dev/null +++ b/queue-6.18/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-30095 @@ -0,0 +1,49 @@ +From 70e3603c36cbbf440c8d8bae647dfb71bd2899f7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 00:25:37 +0000 +Subject: ASoC: fsl_easrc: Fix event generation in fsl_easrc_iec958_put_bits() + +From: Mark Brown + +[ Upstream commit 54a86cf48eaa6d1ab5130d756b718775e81e1748 ] + +ALSA controls should return 1 if the value in the control changed but the +control put operation fsl_easrc_iec958_put_bits() unconditionally returns +0, causing ALSA to not generate any change events. This is detected by +mixer-test with large numbers of messages in the form: + + No event generated for Context 3 IEC958 CS5 + Context 3 IEC958 CS5.0 orig 5224 read 5225, is_volatile 0 + +Add a suitable check. + +Signed-off-by: Mark Brown +Link: https://patch.msgid.link/20260205-asoc-fsl-easrc-fix-events-v1-1-39d4c766918b@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_easrc.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c +index ec49da2d1ebb2..d86f01fbecd4a 100644 +--- a/sound/soc/fsl/fsl_easrc.c ++++ b/sound/soc/fsl/fsl_easrc.c +@@ -52,10 +52,13 @@ static int fsl_easrc_iec958_put_bits(struct snd_kcontrol *kcontrol, + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_value; + unsigned int regval = ucontrol->value.integer.value[0]; ++ int ret; ++ ++ ret = (easrc_priv->bps_iec958[mc->regbase] != regval); + + easrc_priv->bps_iec958[mc->regbase] = regval; + +- return 0; ++ return ret; + } + + static int fsl_easrc_iec958_get_bits(struct snd_kcontrol *kcontrol, +-- +2.51.0 + diff --git a/queue-6.18/asoc-intel-sof_sdw-add-quirk-for-alienware-area-51-2.patch b/queue-6.18/asoc-intel-sof_sdw-add-quirk-for-alienware-area-51-2.patch new file mode 100644 index 0000000000..e698bd5eee --- /dev/null +++ b/queue-6.18/asoc-intel-sof_sdw-add-quirk-for-alienware-area-51-2.patch @@ -0,0 +1,44 @@ +From 7a4cd213298ad0d3230c0435acfbf71b578bc5c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Feb 2026 20:02:24 +0100 +Subject: ASoC: Intel: sof_sdw: Add quirk for Alienware Area 51 (2025) 0CCD SKU + +From: Oliver Freyermuth + +[ Upstream commit 70eddf6a0a3fc6d3ab6f77251676da97cc7f12ae ] + +This adds the necessary quirk for the Alienware 18 Area 51 (2025). +Complements commit 1b03391d073d ("ASoC: Intel: sof_sdw: Add quirk +for Alienware Area 51 (2025) 0CCC SKU"). + +Signed-off-by: Oliver Freyermuth +Tested-by: Oliver Freyermuth +Link: https://patch.msgid.link/20260224190224.30630-1-o.freyermuth@googlemail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/boards/sof_sdw.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c +index 6c95b1f8fc1a5..465bf5fafecf7 100644 +--- a/sound/soc/intel/boards/sof_sdw.c ++++ b/sound/soc/intel/boards/sof_sdw.c +@@ -749,6 +749,14 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { + }, + .driver_data = (void *)(SOC_SDW_CODEC_SPKR), + }, ++ { ++ .callback = sof_sdw_quirk_cb, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CCD") ++ }, ++ .driver_data = (void *)(SOC_SDW_CODEC_SPKR), ++ }, + /* Pantherlake devices*/ + { + .callback = sof_sdw_quirk_cb, +-- +2.51.0 + diff --git a/queue-6.18/asoc-rt1321-fix-dmic-ch2-3-mask-issue.patch b/queue-6.18/asoc-rt1321-fix-dmic-ch2-3-mask-issue.patch new file mode 100644 index 0000000000..f70549366c --- /dev/null +++ b/queue-6.18/asoc-rt1321-fix-dmic-ch2-3-mask-issue.patch @@ -0,0 +1,45 @@ +From 1c70b2d8c5d697a739794b5829027d64f2b967a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Feb 2026 17:12:10 +0800 +Subject: ASoC: rt1321: fix DMIC ch2/3 mask issue + +From: Shuming Fan + +[ Upstream commit 986841dcad257615a6e3f89231bb38e1f3506b77 ] + +This patch fixed the DMIC ch2/3 mask missing problem. + +Signed-off-by: Shuming Fan +Link: https://patch.msgid.link/20260225091210.3648905-1-shumingf@realtek.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/rt1320-sdw.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/rt1320-sdw.c b/sound/soc/codecs/rt1320-sdw.c +index e3f9b03df3aae..e1bd991a823a4 100644 +--- a/sound/soc/codecs/rt1320-sdw.c ++++ b/sound/soc/codecs/rt1320-sdw.c +@@ -1455,7 +1455,7 @@ static int rt1320_sdw_hw_params(struct snd_pcm_substream *substream, + struct sdw_port_config port_config; + struct sdw_port_config dmic_port_config[2]; + struct sdw_stream_runtime *sdw_stream; +- int retval; ++ int retval, num_channels; + unsigned int sampling_rate; + + dev_dbg(dai->dev, "%s %s", __func__, dai->name); +@@ -1487,7 +1487,8 @@ static int rt1320_sdw_hw_params(struct snd_pcm_substream *substream, + dmic_port_config[1].num = 10; + break; + case RT1321_DEV_ID: +- dmic_port_config[0].ch_mask = BIT(0) | BIT(1); ++ num_channels = params_channels(params); ++ dmic_port_config[0].ch_mask = GENMASK(num_channels - 1, 0); + dmic_port_config[0].num = 8; + break; + default: +-- +2.51.0 + diff --git a/queue-6.18/block-break-pcpu_alloc_mutex-dependency-on-freeze_lo.patch b/queue-6.18/block-break-pcpu_alloc_mutex-dependency-on-freeze_lo.patch new file mode 100644 index 0000000000..9c70454586 --- /dev/null +++ b/queue-6.18/block-break-pcpu_alloc_mutex-dependency-on-freeze_lo.patch @@ -0,0 +1,129 @@ +From 4c1b537d6ab690f403300b758b0405736bdac5fb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 1 Mar 2026 18:29:43 +0530 +Subject: block: break pcpu_alloc_mutex dependency on freeze_lock + +From: Nilay Shroff + +[ Upstream commit 539d1b47e935e8384977dd7e5cec370c08b7a644 ] + +While nr_hw_update allocates tagset tags it acquires ->pcpu_alloc_mutex +after ->freeze_lock is acquired or queue is frozen. This potentially +creates a circular dependency involving ->fs_reclaim if reclaim is +triggered simultaneously in a code path which first acquires ->pcpu_ +alloc_mutex. As the queue is already frozen while nr_hw_queue update +allocates tagsets, the reclaim can't forward progress and thus it could +cause a potential deadlock as reported in lockdep splat[1]. + +Fix this by pre-allocating tagset tags before we freeze queue during +nr_hw_queue update. Later the allocated tagset tags could be safely +installed and used after queue is frozen. + +Reported-by: Yi Zhang +Closes: https://lore.kernel.org/all/CAHj4cs8F=OV9s3La2kEQ34YndgfZP-B5PHS4Z8_b9euKG6J4mw@mail.gmail.com/ [1] +Signed-off-by: Nilay Shroff +Reviewed-by: Ming Lei +Tested-by: Yi Zhang +Reviewed-by: Yu Kuai +[axboe: fix brace style issue] +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/blk-mq.c | 45 ++++++++++++++++++++++++++++++--------------- + 1 file changed, 30 insertions(+), 15 deletions(-) + +diff --git a/block/blk-mq.c b/block/blk-mq.c +index a03f52ab87d64..4ebb92014eae1 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -4747,38 +4747,45 @@ static void blk_mq_update_queue_map(struct blk_mq_tag_set *set) + } + } + +-static int blk_mq_realloc_tag_set_tags(struct blk_mq_tag_set *set, +- int new_nr_hw_queues) ++static struct blk_mq_tags **blk_mq_prealloc_tag_set_tags( ++ struct blk_mq_tag_set *set, ++ int new_nr_hw_queues) + { + struct blk_mq_tags **new_tags; + int i; + + if (set->nr_hw_queues >= new_nr_hw_queues) +- goto done; ++ return NULL; + + new_tags = kcalloc_node(new_nr_hw_queues, sizeof(struct blk_mq_tags *), + GFP_KERNEL, set->numa_node); + if (!new_tags) +- return -ENOMEM; ++ return ERR_PTR(-ENOMEM); + + if (set->tags) + memcpy(new_tags, set->tags, set->nr_hw_queues * + sizeof(*set->tags)); +- kfree(set->tags); +- set->tags = new_tags; + + for (i = set->nr_hw_queues; i < new_nr_hw_queues; i++) { +- if (!__blk_mq_alloc_map_and_rqs(set, i)) { +- while (--i >= set->nr_hw_queues) +- __blk_mq_free_map_and_rqs(set, i); +- return -ENOMEM; ++ if (blk_mq_is_shared_tags(set->flags)) { ++ new_tags[i] = set->shared_tags; ++ } else { ++ new_tags[i] = blk_mq_alloc_map_and_rqs(set, i, ++ set->queue_depth); ++ if (!new_tags[i]) ++ goto out_unwind; + } + cond_resched(); + } + +-done: +- set->nr_hw_queues = new_nr_hw_queues; +- return 0; ++ return new_tags; ++out_unwind: ++ while (--i >= set->nr_hw_queues) { ++ if (!blk_mq_is_shared_tags(set->flags)) ++ blk_mq_free_map_and_rqs(set, new_tags[i], i); ++ } ++ kfree(new_tags); ++ return ERR_PTR(-ENOMEM); + } + + /* +@@ -5062,6 +5069,7 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, + unsigned int memflags; + int i; + struct xarray elv_tbl; ++ struct blk_mq_tags **new_tags; + bool queues_frozen = false; + + lockdep_assert_held(&set->tag_list_lock); +@@ -5096,11 +5104,18 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, + if (blk_mq_elv_switch_none(q, &elv_tbl)) + goto switch_back; + ++ new_tags = blk_mq_prealloc_tag_set_tags(set, nr_hw_queues); ++ if (IS_ERR(new_tags)) ++ goto switch_back; ++ + list_for_each_entry(q, &set->tag_list, tag_set_list) + blk_mq_freeze_queue_nomemsave(q); + queues_frozen = true; +- if (blk_mq_realloc_tag_set_tags(set, nr_hw_queues) < 0) +- goto switch_back; ++ if (new_tags) { ++ kfree(set->tags); ++ set->tags = new_tags; ++ } ++ set->nr_hw_queues = nr_hw_queues; + + fallback: + blk_mq_update_queue_map(set); +-- +2.51.0 + diff --git a/queue-6.18/bpf-fix-constant-blinding-for-probe_mem32-stores.patch b/queue-6.18/bpf-fix-constant-blinding-for-probe_mem32-stores.patch new file mode 100644 index 0000000000..4aba39d922 --- /dev/null +++ b/queue-6.18/bpf-fix-constant-blinding-for-probe_mem32-stores.patch @@ -0,0 +1,77 @@ +From 8f6d39d1d8939b4661a506d3f02401b4d518314f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Mar 2026 18:25:42 +0000 +Subject: bpf: Fix constant blinding for PROBE_MEM32 stores + +From: Sachin Kumar + +[ Upstream commit 2321a9596d2260310267622e0ad8fbfa6f95378f ] + +BPF_ST | BPF_PROBE_MEM32 immediate stores are not handled by +bpf_jit_blind_insn(), allowing user-controlled 32-bit immediates to +survive unblinded into JIT-compiled native code when bpf_jit_harden >= 1. + +The root cause is that convert_ctx_accesses() rewrites BPF_ST|BPF_MEM +to BPF_ST|BPF_PROBE_MEM32 for arena pointer stores during verification, +before bpf_jit_blind_constants() runs during JIT compilation. The +blinding switch only matches BPF_ST|BPF_MEM (mode 0x60), not +BPF_ST|BPF_PROBE_MEM32 (mode 0xa0). The instruction falls through +unblinded. + +Add BPF_ST|BPF_PROBE_MEM32 cases to bpf_jit_blind_insn() alongside the +existing BPF_ST|BPF_MEM cases. The blinding transformation is identical: +load the blinded immediate into BPF_REG_AX via mov+xor, then convert +the immediate store to a register store (BPF_STX). + +The rewritten STX instruction must preserve the BPF_PROBE_MEM32 mode so +the architecture JIT emits the correct arena addressing (R12-based on +x86-64). Cannot use the BPF_STX_MEM() macro here because it hardcodes +BPF_MEM mode; construct the instruction directly instead. + +Fixes: 6082b6c328b5 ("bpf: Recognize addr_space_cast instruction in the verifier.") +Reviewed-by: Puranjay Mohan +Reviewed-by: Emil Tsalapatis +Signed-off-by: Sachin Kumar +Acked-by: Daniel Borkmann +Link: https://lore.kernel.org/r/Y6IT5VvNRchPBLI5D7JZHBzZrU9rb0ycRJPJzJSXGj7kJlX8RJwZFSM2YZjcDxoQKABkxt1T8Os2gi23PYyFuQe6KkZGWVyfz8K5afdy9ak=@protonmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/core.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c +index c2278f392e932..a17e42ff89853 100644 +--- a/kernel/bpf/core.c ++++ b/kernel/bpf/core.c +@@ -1403,6 +1403,27 @@ static int bpf_jit_blind_insn(const struct bpf_insn *from, + *to++ = BPF_ALU64_IMM(BPF_XOR, BPF_REG_AX, imm_rnd); + *to++ = BPF_STX_MEM(from->code, from->dst_reg, BPF_REG_AX, from->off); + break; ++ ++ case BPF_ST | BPF_PROBE_MEM32 | BPF_DW: ++ case BPF_ST | BPF_PROBE_MEM32 | BPF_W: ++ case BPF_ST | BPF_PROBE_MEM32 | BPF_H: ++ case BPF_ST | BPF_PROBE_MEM32 | BPF_B: ++ *to++ = BPF_ALU64_IMM(BPF_MOV, BPF_REG_AX, imm_rnd ^ ++ from->imm); ++ *to++ = BPF_ALU64_IMM(BPF_XOR, BPF_REG_AX, imm_rnd); ++ /* ++ * Cannot use BPF_STX_MEM() macro here as it ++ * hardcodes BPF_MEM mode, losing PROBE_MEM32 ++ * and breaking arena addressing in the JIT. ++ */ ++ *to++ = (struct bpf_insn) { ++ .code = BPF_STX | BPF_PROBE_MEM32 | ++ BPF_SIZE(from->code), ++ .dst_reg = from->dst_reg, ++ .src_reg = BPF_REG_AX, ++ .off = from->off, ++ }; ++ break; + } + out: + return to - to_buff; +-- +2.51.0 + diff --git a/queue-6.18/bpf-fix-exception-exit-lock-checking-for-subprogs.patch b/queue-6.18/bpf-fix-exception-exit-lock-checking-for-subprogs.patch new file mode 100644 index 0000000000..b419d9b87a --- /dev/null +++ b/queue-6.18/bpf-fix-exception-exit-lock-checking-for-subprogs.patch @@ -0,0 +1,102 @@ +From 7f2e7178bfbca91247a1de4e152c12ecf5dca891 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Mar 2026 17:08:08 -0700 +Subject: bpf: Fix exception exit lock checking for subprogs + +From: Ihor Solodrai + +[ Upstream commit 6c2128505f61b504c79a20b89596feba61388112 ] + +process_bpf_exit_full() passes check_lock = !curframe to +check_resource_leak(), which is false in cases when bpf_throw() is +called from a static subprog. This makes check_resource_leak() to skip +validation of active_rcu_locks, active_preempt_locks, and +active_irq_id on exception exits from subprogs. + +At runtime bpf_throw() unwinds the stack via ORC without releasing any +user-acquired locks, which may cause various issues as the result. + +Fix by setting check_lock = true for exception exits regardless of +curframe, since exceptions bypass all intermediate frame +cleanup. Update the error message prefix to "bpf_throw" for exception +exits to distinguish them from normal BPF_EXIT. + +Fix reject_subprog_with_rcu_read_lock test which was previously +passing for the wrong reason. Test program returned directly from the +subprog call without closing the RCU section, so the error was +triggered by the unclosed RCU lock on normal exit, not by +bpf_throw. Update __msg annotations for affected tests to match the +new "bpf_throw" error prefix. + +The spin_lock case is not affected because they are already checked [1] +at the call site in do_check_insn() before bpf_throw can run. + +[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/bpf/verifier.c?h=v7.0-rc4#n21098 + +Assisted-by: Claude:claude-opus-4-6 +Fixes: f18b03fabaa9 ("bpf: Implement BPF exceptions") +Signed-off-by: Ihor Solodrai +Acked-by: Yonghong Song +Acked-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20260320000809.643798-1-ihor.solodrai@linux.dev +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 3 ++- + tools/testing/selftests/bpf/progs/exceptions_fail.c | 9 ++++++--- + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 1280ee4c81c33..af87530450ec2 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -19955,7 +19955,8 @@ static int process_bpf_exit_full(struct bpf_verifier_env *env, + * state when it exits. + */ + int err = check_resource_leak(env, exception_exit, +- !env->cur_state->curframe, ++ exception_exit || !env->cur_state->curframe, ++ exception_exit ? "bpf_throw" : + "BPF_EXIT instruction in main prog"); + if (err) + return err; +diff --git a/tools/testing/selftests/bpf/progs/exceptions_fail.c b/tools/testing/selftests/bpf/progs/exceptions_fail.c +index 8a0fdff899271..d7f1c492e3dd3 100644 +--- a/tools/testing/selftests/bpf/progs/exceptions_fail.c ++++ b/tools/testing/selftests/bpf/progs/exceptions_fail.c +@@ -8,6 +8,7 @@ + #include "bpf_experimental.h" + + extern void bpf_rcu_read_lock(void) __ksym; ++extern void bpf_rcu_read_unlock(void) __ksym; + + #define private(name) SEC(".bss." #name) __hidden __attribute__((aligned(8))) + +@@ -131,7 +132,7 @@ int reject_subprog_with_lock(void *ctx) + } + + SEC("?tc") +-__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_rcu_read_lock-ed region") ++__failure __msg("bpf_throw cannot be used inside bpf_rcu_read_lock-ed region") + int reject_with_rcu_read_lock(void *ctx) + { + bpf_rcu_read_lock(); +@@ -147,11 +148,13 @@ __noinline static int throwing_subprog(struct __sk_buff *ctx) + } + + SEC("?tc") +-__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_rcu_read_lock-ed region") ++__failure __msg("bpf_throw cannot be used inside bpf_rcu_read_lock-ed region") + int reject_subprog_with_rcu_read_lock(void *ctx) + { + bpf_rcu_read_lock(); +- return throwing_subprog(ctx); ++ throwing_subprog(ctx); ++ bpf_rcu_read_unlock(); ++ return 0; + } + + static bool rbless(struct bpf_rb_node *n1, const struct bpf_rb_node *n2) +-- +2.51.0 + diff --git a/queue-6.18/bpf-fix-u32-s32-bounds-when-ranges-cross-min-max-bou.patch b/queue-6.18/bpf-fix-u32-s32-bounds-when-ranges-cross-min-max-bou.patch new file mode 100644 index 0000000000..ea37715ba3 --- /dev/null +++ b/queue-6.18/bpf-fix-u32-s32-bounds-when-ranges-cross-min-max-bou.patch @@ -0,0 +1,205 @@ +From 8369f27293a676d9ff4cdf0b6aefb3b84867c072 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 16:54:24 -0800 +Subject: bpf: Fix u32/s32 bounds when ranges cross min/max boundary +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Eduard Zingerman + +[ Upstream commit fbc7aef517d8765e4c425d2792409bb9bf2e1f13 ] + +Same as in __reg64_deduce_bounds(), refine s32/u32 ranges +in __reg32_deduce_bounds() in the following situations: + +- s32 range crosses U32_MAX/0 boundary, positive part of the s32 range + overlaps with u32 range: + + 0 U32_MAX + | [xxxxxxxxxxxxxx u32 range xxxxxxxxxxxxxx] | + |----------------------------|----------------------------| + |xxxxx s32 range xxxxxxxxx] [xxxxxxx| + 0 S32_MAX S32_MIN -1 + +- s32 range crosses U32_MAX/0 boundary, negative part of the s32 range + overlaps with u32 range: + + 0 U32_MAX + | [xxxxxxxxxxxxxx u32 range xxxxxxxxxxxxxx] | + |----------------------------|----------------------------| + |xxxxxxxxx] [xxxxxxxxxxxx s32 range | + 0 S32_MAX S32_MIN -1 + +- No refinement if ranges overlap in two intervals. + +This helps for e.g. consider the following program: + + call %[bpf_get_prandom_u32]; + w0 &= 0xffffffff; + if w0 < 0x3 goto 1f; // on fall-through u32 range [3..U32_MAX] + if w0 s> 0x1 goto 1f; // on fall-through s32 range [S32_MIN..1] + if w0 s< 0x0 goto 1f; // range can be narrowed to [S32_MIN..-1] + r10 = 0; +1: ...; + +The reg_bounds.c selftest is updated to incorporate identical logic, +refinement based on non-overflowing range halves: + + ((x ∩ [0, smax]) ∩ (y ∩ [0, smax])) ∪ + ((x ∩ [smin,-1]) ∩ (y ∩ [smin,-1])) + +Reported-by: Andrea Righi +Reported-by: Emil Tsalapatis +Closes: https://lore.kernel.org/bpf/aakqucg4vcujVwif@gpd4/T/ +Reviewed-by: Emil Tsalapatis +Acked-by: Shung-Hsi Yu +Signed-off-by: Eduard Zingerman +Link: https://lore.kernel.org/r/20260306-bpf-32-bit-range-overflow-v3-1-f7f67e060a6b@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 24 +++++++ + .../selftests/bpf/prog_tests/reg_bounds.c | 62 +++++++++++++++++-- + 2 files changed, 82 insertions(+), 4 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index f1264972e0245..3eaff8453e9a9 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -2479,6 +2479,30 @@ static void __reg32_deduce_bounds(struct bpf_reg_state *reg) + if ((u32)reg->s32_min_value <= (u32)reg->s32_max_value) { + reg->u32_min_value = max_t(u32, reg->s32_min_value, reg->u32_min_value); + reg->u32_max_value = min_t(u32, reg->s32_max_value, reg->u32_max_value); ++ } else { ++ if (reg->u32_max_value < (u32)reg->s32_min_value) { ++ /* See __reg64_deduce_bounds() for detailed explanation. ++ * Refine ranges in the following situation: ++ * ++ * 0 U32_MAX ++ * | [xxxxxxxxxxxxxx u32 range xxxxxxxxxxxxxx] | ++ * |----------------------------|----------------------------| ++ * |xxxxx s32 range xxxxxxxxx] [xxxxxxx| ++ * 0 S32_MAX S32_MIN -1 ++ */ ++ reg->s32_min_value = (s32)reg->u32_min_value; ++ reg->u32_max_value = min_t(u32, reg->u32_max_value, reg->s32_max_value); ++ } else if ((u32)reg->s32_max_value < reg->u32_min_value) { ++ /* ++ * 0 U32_MAX ++ * | [xxxxxxxxxxxxxx u32 range xxxxxxxxxxxxxx] | ++ * |----------------------------|----------------------------| ++ * |xxxxxxxxx] [xxxxxxxxxxxx s32 range | ++ * 0 S32_MAX S32_MIN -1 ++ */ ++ reg->s32_max_value = (s32)reg->u32_max_value; ++ reg->u32_min_value = max_t(u32, reg->u32_min_value, reg->s32_min_value); ++ } + } + } + +diff --git a/tools/testing/selftests/bpf/prog_tests/reg_bounds.c b/tools/testing/selftests/bpf/prog_tests/reg_bounds.c +index 0322f817d07be..04938d0d431b3 100644 +--- a/tools/testing/selftests/bpf/prog_tests/reg_bounds.c ++++ b/tools/testing/selftests/bpf/prog_tests/reg_bounds.c +@@ -422,15 +422,69 @@ static bool is_valid_range(enum num_t t, struct range x) + } + } + +-static struct range range_improve(enum num_t t, struct range old, struct range new) ++static struct range range_intersection(enum num_t t, struct range old, struct range new) + { + return range(t, max_t(t, old.a, new.a), min_t(t, old.b, new.b)); + } + ++/* ++ * Result is precise when 'x' and 'y' overlap or form a continuous range, ++ * result is an over-approximation if 'x' and 'y' do not overlap. ++ */ ++static struct range range_union(enum num_t t, struct range x, struct range y) ++{ ++ if (!is_valid_range(t, x)) ++ return y; ++ if (!is_valid_range(t, y)) ++ return x; ++ return range(t, min_t(t, x.a, y.a), max_t(t, x.b, y.b)); ++} ++ ++/* ++ * This function attempts to improve x range intersecting it with y. ++ * range_cast(... to_t ...) looses precision for ranges that pass to_t ++ * min/max boundaries. To avoid such precision loses this function ++ * splits both x and y into halves corresponding to non-overflowing ++ * sub-ranges: [0, smin] and [smax, -1]. ++ * Final result is computed as follows: ++ * ++ * ((x ∩ [0, smax]) ∩ (y ∩ [0, smax])) ∪ ++ * ((x ∩ [smin,-1]) ∩ (y ∩ [smin,-1])) ++ * ++ * Precision might still be lost if final union is not a continuous range. ++ */ ++static struct range range_refine_in_halves(enum num_t x_t, struct range x, ++ enum num_t y_t, struct range y) ++{ ++ struct range x_pos, x_neg, y_pos, y_neg, r_pos, r_neg; ++ u64 smax, smin, neg_one; ++ ++ if (t_is_32(x_t)) { ++ smax = (u64)(u32)S32_MAX; ++ smin = (u64)(u32)S32_MIN; ++ neg_one = (u64)(u32)(s32)(-1); ++ } else { ++ smax = (u64)S64_MAX; ++ smin = (u64)S64_MIN; ++ neg_one = U64_MAX; ++ } ++ x_pos = range_intersection(x_t, x, range(x_t, 0, smax)); ++ x_neg = range_intersection(x_t, x, range(x_t, smin, neg_one)); ++ y_pos = range_intersection(y_t, y, range(x_t, 0, smax)); ++ y_neg = range_intersection(y_t, y, range(y_t, smin, neg_one)); ++ r_pos = range_intersection(x_t, x_pos, range_cast(y_t, x_t, y_pos)); ++ r_neg = range_intersection(x_t, x_neg, range_cast(y_t, x_t, y_neg)); ++ return range_union(x_t, r_pos, r_neg); ++ ++} ++ + static struct range range_refine(enum num_t x_t, struct range x, enum num_t y_t, struct range y) + { + struct range y_cast; + ++ if (t_is_32(x_t) == t_is_32(y_t)) ++ x = range_refine_in_halves(x_t, x, y_t, y); ++ + y_cast = range_cast(y_t, x_t, y); + + /* If we know that +@@ -444,7 +498,7 @@ static struct range range_refine(enum num_t x_t, struct range x, enum num_t y_t, + */ + if (x_t == S64 && y_t == S32 && y_cast.a <= S32_MAX && y_cast.b <= S32_MAX && + (s64)x.a >= S32_MIN && (s64)x.b <= S32_MAX) +- return range_improve(x_t, x, y_cast); ++ return range_intersection(x_t, x, y_cast); + + /* the case when new range knowledge, *y*, is a 32-bit subregister + * range, while previous range knowledge, *x*, is a full register +@@ -462,7 +516,7 @@ static struct range range_refine(enum num_t x_t, struct range x, enum num_t y_t, + x_swap = range(x_t, swap_low32(x.a, y_cast.a), swap_low32(x.b, y_cast.b)); + if (!is_valid_range(x_t, x_swap)) + return x; +- return range_improve(x_t, x, x_swap); ++ return range_intersection(x_t, x, x_swap); + } + + if (!t_is_32(x_t) && !t_is_32(y_t) && x_t != y_t) { +@@ -480,7 +534,7 @@ static struct range range_refine(enum num_t x_t, struct range x, enum num_t y_t, + } + + /* otherwise, plain range cast and intersection works */ +- return range_improve(x_t, x, y_cast); ++ return range_intersection(x_t, x, y_cast); + } + + /* ======================= +-- +2.51.0 + diff --git a/queue-6.18/bpf-fix-undefined-behavior-in-interpreter-sdiv-smod-.patch b/queue-6.18/bpf-fix-undefined-behavior-in-interpreter-sdiv-smod-.patch new file mode 100644 index 0000000000..e64898bb7e --- /dev/null +++ b/queue-6.18/bpf-fix-undefined-behavior-in-interpreter-sdiv-smod-.patch @@ -0,0 +1,104 @@ +From 7b13d47c74ee9b582c6dfa795313f281dba53064 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Mar 2026 01:11:15 +0000 +Subject: bpf: Fix undefined behavior in interpreter sdiv/smod for INT_MIN + +From: Jenny Guanni Qu + +[ Upstream commit c77b30bd1dcb61f66c640ff7d2757816210c7cb0 ] + +The BPF interpreter's signed 32-bit division and modulo handlers use +the kernel abs() macro on s32 operands. The abs() macro documentation +(include/linux/math.h) explicitly states the result is undefined when +the input is the type minimum. When DST contains S32_MIN (0x80000000), +abs((s32)DST) triggers undefined behavior and returns S32_MIN unchanged +on arm64/x86. This value is then sign-extended to u64 as +0xFFFFFFFF80000000, causing do_div() to compute the wrong result. + +The verifier's abstract interpretation (scalar32_min_max_sdiv) computes +the mathematically correct result for range tracking, creating a +verifier/interpreter mismatch that can be exploited for out-of-bounds +map value access. + +Introduce abs_s32() which handles S32_MIN correctly by casting to u32 +before negating, avoiding signed overflow entirely. Replace all 8 +abs((s32)...) call sites in the interpreter's sdiv32/smod32 handlers. + +s32 is the only affected case -- the s64 division/modulo handlers do +not use abs(). + +Fixes: ec0e2da95f72 ("bpf: Support new signed div/mod instructions.") +Acked-by: Yonghong Song +Acked-by: Mykyta Yatsenko +Signed-off-by: Jenny Guanni Qu +Link: https://lore.kernel.org/r/20260311011116.2108005-2-qguanni@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/core.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c +index a17e42ff89853..8de006d388f67 100644 +--- a/kernel/bpf/core.c ++++ b/kernel/bpf/core.c +@@ -1717,6 +1717,12 @@ bool bpf_opcode_in_insntable(u8 code) + } + + #ifndef CONFIG_BPF_JIT_ALWAYS_ON ++/* Absolute value of s32 without undefined behavior for S32_MIN */ ++static u32 abs_s32(s32 x) ++{ ++ return x >= 0 ? (u32)x : -(u32)x; ++} ++ + /** + * ___bpf_prog_run - run eBPF program on a given context + * @regs: is the array of MAX_BPF_EXT_REG eBPF pseudo-registers +@@ -1881,8 +1887,8 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn) + DST = do_div(AX, (u32) SRC); + break; + case 1: +- AX = abs((s32)DST); +- AX = do_div(AX, abs((s32)SRC)); ++ AX = abs_s32((s32)DST); ++ AX = do_div(AX, abs_s32((s32)SRC)); + if ((s32)DST < 0) + DST = (u32)-AX; + else +@@ -1909,8 +1915,8 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn) + DST = do_div(AX, (u32) IMM); + break; + case 1: +- AX = abs((s32)DST); +- AX = do_div(AX, abs((s32)IMM)); ++ AX = abs_s32((s32)DST); ++ AX = do_div(AX, abs_s32((s32)IMM)); + if ((s32)DST < 0) + DST = (u32)-AX; + else +@@ -1936,8 +1942,8 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn) + DST = (u32) AX; + break; + case 1: +- AX = abs((s32)DST); +- do_div(AX, abs((s32)SRC)); ++ AX = abs_s32((s32)DST); ++ do_div(AX, abs_s32((s32)SRC)); + if (((s32)DST < 0) == ((s32)SRC < 0)) + DST = (u32)AX; + else +@@ -1963,8 +1969,8 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn) + DST = (u32) AX; + break; + case 1: +- AX = abs((s32)DST); +- do_div(AX, abs((s32)IMM)); ++ AX = abs_s32((s32)DST); ++ do_div(AX, abs_s32((s32)IMM)); + if (((s32)DST < 0) == ((s32)IMM < 0)) + DST = (u32)AX; + else +-- +2.51.0 + diff --git a/queue-6.18/bpf-fix-unsound-scalar-forking-in-maybe_fork_scalars.patch b/queue-6.18/bpf-fix-unsound-scalar-forking-in-maybe_fork_scalars.patch new file mode 100644 index 0000000000..b82084f851 --- /dev/null +++ b/queue-6.18/bpf-fix-unsound-scalar-forking-in-maybe_fork_scalars.patch @@ -0,0 +1,52 @@ +From db860740984717cf5c052c9d21eb7d55b0bf31c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Mar 2026 13:15:20 +1100 +Subject: bpf: Fix unsound scalar forking in maybe_fork_scalars() for BPF_OR + +From: Daniel Wade + +[ Upstream commit c845894ebd6fb43226b3118d6b017942550910c5 ] + +maybe_fork_scalars() is called for both BPF_AND and BPF_OR when the +source operand is a constant. When dst has signed range [-1, 0], it +forks the verifier state: the pushed path gets dst = 0, the current +path gets dst = -1. + +For BPF_AND this is correct: 0 & K == 0. +For BPF_OR this is wrong: 0 | K == K, not 0. + +The pushed path therefore tracks dst as 0 when the runtime value is K, +producing an exploitable verifier/runtime divergence that allows +out-of-bounds map access. + +Fix this by passing env->insn_idx (instead of env->insn_idx + 1) to +push_stack(), so the pushed path re-executes the ALU instruction with +dst = 0 and naturally computes the correct result for any opcode. + +Fixes: bffacdb80b93 ("bpf: Recognize special arithmetic shift in the verifier") +Signed-off-by: Daniel Wade +Reviewed-by: Amery Hung +Acked-by: Eduard Zingerman +Link: https://lore.kernel.org/r/20260314021521.128361-2-danjwade95@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index af87530450ec2..f1264972e0245 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -15512,7 +15512,7 @@ static int maybe_fork_scalars(struct bpf_verifier_env *env, struct bpf_insn *ins + else + return 0; + +- branch = push_stack(env, env->insn_idx + 1, env->insn_idx, false); ++ branch = push_stack(env, env->insn_idx, env->insn_idx, false); + if (IS_ERR(branch)) + return PTR_ERR(branch); + +-- +2.51.0 + diff --git a/queue-6.18/bpf-release-module-btf-idr-before-module-unload.patch b/queue-6.18/bpf-release-module-btf-idr-before-module-unload.patch new file mode 100644 index 0000000000..bac692a28b --- /dev/null +++ b/queue-6.18/bpf-release-module-btf-idr-before-module-unload.patch @@ -0,0 +1,128 @@ +From 3c5107ed78daafa872c2493f2d2850dbbc146651 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Mar 2026 13:53:07 -0700 +Subject: bpf: Release module BTF IDR before module unload + +From: Kumar Kartikeya Dwivedi + +[ Upstream commit 146bd2a87a65aa407bb17fac70d8d583d19aba06 ] + +Gregory reported in [0] that the global_map_resize test when run in +repeatedly ends up failing during program load. This stems from the fact +that BTF reference has not dropped to zero after the previous run's +module is unloaded, and the older module's BTF is still discoverable and +visible. Later, in libbpf, load_module_btfs() will find the ID for this +stale BTF, open its fd, and then it will be used during program load +where later steps taking module reference using btf_try_get_module() +fail since the underlying module for the BTF is gone. + +Logically, once a module is unloaded, it's associated BTF artifacts +should become hidden. The BTF object inside the kernel may still remain +alive as long its reference counts are alive, but it should no longer be +discoverable. + +To fix this, let us call btf_free_id() from the MODULE_STATE_GOING case +for the module unload to free the BTF associated IDR entry, and disable +its discovery once module unload returns to user space. If a race +happens during unload, the outcome is non-deterministic anyway. However, +user space should be able to rely on the guarantee that once it has +synchronously established a successful module unload, no more stale +artifacts associated with this module can be obtained subsequently. + +Note that we must be careful to not invoke btf_free_id() in btf_put() +when btf_is_module() is true now. There could be a window where the +module unload drops a non-terminal reference, frees the IDR, but the +same ID gets reused and the second unconditional btf_free_id() ends up +releasing an unrelated entry. + +To avoid a special case for btf_is_module() case, set btf->id to zero to +make btf_free_id() idempotent, such that we can unconditionally invoke it +from btf_put(), and also from the MODULE_STATE_GOING case. Since zero is +an invalid IDR, the idr_remove() should be a noop. + +Note that we can be sure that by the time we reach final btf_put() for +btf_is_module() case, the btf_free_id() is already done, since the +module itself holds the BTF reference, and it will call this function +for the BTF before dropping its own reference. + + [0]: https://lore.kernel.org/bpf/cover.1773170190.git.grbell@redhat.com + +Fixes: 36e68442d1af ("bpf: Load and verify kernel module BTFs") +Acked-by: Martin KaFai Lau +Suggested-by: Martin KaFai Lau +Reported-by: Gregory Bell +Reviewed-by: Emil Tsalapatis +Signed-off-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20260312205307.1346991-1-memxor@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/btf.c | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c +index 0de8fc8a0e0b3..75a5df36f9170 100644 +--- a/kernel/bpf/btf.c ++++ b/kernel/bpf/btf.c +@@ -1676,7 +1676,16 @@ static void btf_free_id(struct btf *btf) + * of the _bh() version. + */ + spin_lock_irqsave(&btf_idr_lock, flags); +- idr_remove(&btf_idr, btf->id); ++ if (btf->id) { ++ idr_remove(&btf_idr, btf->id); ++ /* ++ * Clear the id here to make this function idempotent, since it will get ++ * called a couple of times for module BTFs: on module unload, and then ++ * the final btf_put(). btf_alloc_id() starts IDs with 1, so we can use ++ * 0 as sentinel value. ++ */ ++ WRITE_ONCE(btf->id, 0); ++ } + spin_unlock_irqrestore(&btf_idr_lock, flags); + } + +@@ -7995,7 +8004,7 @@ static void bpf_btf_show_fdinfo(struct seq_file *m, struct file *filp) + { + const struct btf *btf = filp->private_data; + +- seq_printf(m, "btf_id:\t%u\n", btf->id); ++ seq_printf(m, "btf_id:\t%u\n", READ_ONCE(btf->id)); + } + #endif + +@@ -8077,7 +8086,7 @@ int btf_get_info_by_fd(const struct btf *btf, + if (copy_from_user(&info, uinfo, info_copy)) + return -EFAULT; + +- info.id = btf->id; ++ info.id = READ_ONCE(btf->id); + ubtf = u64_to_user_ptr(info.btf); + btf_copy = min_t(u32, btf->data_size, info.btf_size); + if (copy_to_user(ubtf, btf->data, btf_copy)) +@@ -8140,7 +8149,7 @@ int btf_get_fd_by_id(u32 id) + + u32 btf_obj_id(const struct btf *btf) + { +- return btf->id; ++ return READ_ONCE(btf->id); + } + + bool btf_is_kernel(const struct btf *btf) +@@ -8262,6 +8271,13 @@ static int btf_module_notify(struct notifier_block *nb, unsigned long op, + if (btf_mod->module != module) + continue; + ++ /* ++ * For modules, we do the freeing of BTF IDR as soon as ++ * module goes away to disable BTF discovery, since the ++ * btf_try_get_module() on such BTFs will fail. This may ++ * be called again on btf_put(), but it's ok to do so. ++ */ ++ btf_free_id(btf_mod->btf); + list_del(&btf_mod->list); + if (btf_mod->sysfs_attr) + sysfs_remove_bin_file(btf_kobj, btf_mod->sysfs_attr); +-- +2.51.0 + diff --git a/queue-6.18/bpf-reset-register-id-for-bpf_end-value-tracking.patch b/queue-6.18/bpf-reset-register-id-for-bpf_end-value-tracking.patch new file mode 100644 index 0000000000..4fed2b49d9 --- /dev/null +++ b/queue-6.18/bpf-reset-register-id-for-bpf_end-value-tracking.patch @@ -0,0 +1,62 @@ +From ee808e5bcbbc72039b79a5b9bd3dd5acf05231b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Mar 2026 16:32:27 +0800 +Subject: bpf: Reset register ID for BPF_END value tracking + +From: Yazhou Tang + +[ Upstream commit a3125bc01884431d30d731461634c8295b6f0529 ] + +When a register undergoes a BPF_END (byte swap) operation, its scalar +value is mutated in-place. If this register previously shared a scalar ID +with another register (e.g., after an `r1 = r0` assignment), this tie must +be broken. + +Currently, the verifier misses resetting `dst_reg->id` to 0 for BPF_END. +Consequently, if a conditional jump checks the swapped register, the +verifier incorrectly propagates the learned bounds to the linked register, +leading to false confidence in the linked register's value and potentially +allowing out-of-bounds memory accesses. + +Fix this by explicitly resetting `dst_reg->id` to 0 in the BPF_END case +to break the scalar tie, similar to how BPF_NEG handles it via +`__mark_reg_known`. + +Fixes: 9d2119984224 ("bpf: Add bitwise tracking for BPF_END") +Closes: https://lore.kernel.org/bpf/AMBPR06MB108683CFEB1CB8D9E02FC95ECF17EA@AMBPR06MB10868.eurprd06.prod.outlook.com/ +Link: https://lore.kernel.org/bpf/4be25f7442a52244d0dd1abb47bc6750e57984c9.camel@gmail.com/ +Reported-by: Guillaume Laporte +Co-developed-by: Tianci Cao +Signed-off-by: Tianci Cao +Co-developed-by: Shenghao Yuan +Signed-off-by: Shenghao Yuan +Signed-off-by: Yazhou Tang +Acked-by: Eduard Zingerman +Link: https://lore.kernel.org/r/20260304083228.142016-2-tangyazhou@zju.edu.cn +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 648c4bd3e5a92..1280ee4c81c33 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -15431,6 +15431,13 @@ static void scalar_byte_swap(struct bpf_reg_state *dst_reg, struct bpf_insn *ins + /* Apply bswap if alu64 or switch between big-endian and little-endian machines */ + bool need_bswap = alu64 || (to_le == is_big_endian); + ++ /* ++ * If the register is mutated, manually reset its scalar ID to break ++ * any existing ties and avoid incorrect bounds propagation. ++ */ ++ if (need_bswap || insn->imm == 16 || insn->imm == 32) ++ dst_reg->id = 0; ++ + if (need_bswap) { + if (insn->imm == 16) + dst_reg->var_off = tnum_bswap16(dst_reg->var_off); +-- +2.51.0 + diff --git a/queue-6.18/btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch b/queue-6.18/btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch new file mode 100644 index 0000000000..ceb3da8f12 --- /dev/null +++ b/queue-6.18/btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch @@ -0,0 +1,196 @@ +From 0278fbaa5256830e6b7e4f8ad15e08d45e70da73 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Feb 2026 14:25:35 -0800 +Subject: btrfs: set BTRFS_ROOT_ORPHAN_CLEANUP during subvol create + +From: Boris Burkov + +[ Upstream commit 5131fa077f9bb386a1b901bf5b247041f0ec8f80 ] + +We have recently observed a number of subvolumes with broken dentries. +ls-ing the parent dir looks like: + +drwxrwxrwt 1 root root 16 Jan 23 16:49 . +drwxr-xr-x 1 root root 24 Jan 23 16:48 .. +d????????? ? ? ? ? ? broken_subvol + +and similarly stat-ing the file fails. + +In this state, deleting the subvol fails with ENOENT, but attempting to +create a new file or subvol over it errors out with EEXIST and even +aborts the fs. Which leaves us a bit stuck. + +dmesg contains a single notable error message reading: +"could not do orphan cleanup -2" + +2 is ENOENT and the error comes from the failure handling path of +btrfs_orphan_cleanup(), with the stack leading back up to +btrfs_lookup(). + +btrfs_lookup +btrfs_lookup_dentry +btrfs_orphan_cleanup // prints that message and returns -ENOENT + +After some detailed inspection of the internal state, it became clear +that: +- there are no orphan items for the subvol +- the subvol is otherwise healthy looking, it is not half-deleted or + anything, there is no drop progress, etc. +- the subvol was created a while ago and does the meaningful first + btrfs_orphan_cleanup() call that sets BTRFS_ROOT_ORPHAN_CLEANUP much + later. +- after btrfs_orphan_cleanup() fails, btrfs_lookup_dentry() returns -ENOENT, + which results in a negative dentry for the subvolume via + d_splice_alias(NULL, dentry), leading to the observed behavior. The + bug can be mitigated by dropping the dentry cache, at which point we + can successfully delete the subvolume if we want. + +i.e., +btrfs_lookup() + btrfs_lookup_dentry() + if (!sb_rdonly(inode->vfs_inode)->vfs_inode) + btrfs_orphan_cleanup(sub_root) + test_and_set_bit(BTRFS_ROOT_ORPHAN_CLEANUP) + btrfs_search_slot() // finds orphan item for inode N + ... + prints "could not do orphan cleanup -2" + if (inode == ERR_PTR(-ENOENT)) + inode = NULL; + return d_splice_alias(NULL, dentry) // NEGATIVE DENTRY for valid subvolume + +btrfs_orphan_cleanup() does test_and_set_bit(BTRFS_ROOT_ORPHAN_CLEANUP) +on the root when it runs, so it cannot run more than once on a given +root, so something else must run concurrently. However, the obvious +routes to deleting an orphan when nlinks goes to 0 should not be able to +run without first doing a lookup into the subvolume, which should run +btrfs_orphan_cleanup() and set the bit. + +The final important observation is that create_subvol() calls +d_instantiate_new() but does not set BTRFS_ROOT_ORPHAN_CLEANUP, so if +the dentry cache gets dropped, the next lookup into the subvolume will +make a real call into btrfs_orphan_cleanup() for the first time. This +opens up the possibility of concurrently deleting the inode/orphan items +but most typical evict() paths will be holding a reference on the parent +dentry (child dentry holds parent->d_lockref.count via dget in +d_alloc(), released in __dentry_kill()) and prevent the parent from +being removed from the dentry cache. + +The one exception is delayed iputs. Ordered extent creation calls +igrab() on the inode. If the file is unlinked and closed while those +refs are held, iput() in __dentry_kill() decrements i_count but does +not trigger eviction (i_count > 0). The child dentry is freed and the +subvol dentry's d_lockref.count drops to 0, making it evictable while +the inode is still alive. + +Since there are two races (the race between writeback and unlink and +the race between lookup and delayed iputs), and there are too many moving +parts, the following three diagrams show the complete picture. +(Only the second and third are races) + +Phase 1: +Create Subvol in dentry cache without BTRFS_ROOT_ORPHAN_CLEANUP set + +btrfs_mksubvol() + lookup_one_len() + __lookup_slow() + d_alloc_parallel() + __d_alloc() // d_lockref.count = 1 + create_subvol(dentry) + // doesn't touch the bit.. + d_instantiate_new(dentry, inode) // dentry in cache with d_lockref.count == 1 + +Phase 2: +Create a delayed iput for a file in the subvol but leave the subvol in +state where its dentry can be evicted (d_lockref.count == 0) + +T1 (task) T2 (writeback) T3 (OE workqueue) + +write() // dirty pages + btrfs_writepages() + btrfs_run_delalloc_range() + cow_file_range() + btrfs_alloc_ordered_extent() + igrab() // i_count: 1 -> 2 +btrfs_unlink_inode() + btrfs_orphan_add() +close() + __fput() + dput() + finish_dput() + __dentry_kill() + dentry_unlink_inode() + iput() // 2 -> 1 + --parent->d_lockref.count // 1 -> 0; evictable + finish_ordered_fn() + btrfs_finish_ordered_io() + btrfs_put_ordered_extent() + btrfs_add_delayed_iput() + +Phase 3: +Once the delayed iput is pending and the subvol dentry is evictable, +the shrinker can free it, causing the next lookup to go through +btrfs_lookup() and call btrfs_orphan_cleanup() for the first time. +If the cleaner kthread processes the delayed iput concurrently, the +two race: + + T1 (shrinker) T2 (cleaner kthread) T3 (lookup) + + super_cache_scan() + prune_dcache_sb() + __dentry_kill() + // subvol dentry freed + btrfs_run_delayed_iputs() + iput() // i_count -> 0 + evict() // sets I_FREEING + btrfs_evict_inode() + // truncation loop + btrfs_lookup() + btrfs_lookup_dentry() + btrfs_orphan_cleanup() + // first call (bit never set) + btrfs_iget() + // blocks on I_FREEING + + btrfs_orphan_del() + // inode freed + // returns -ENOENT + btrfs_del_orphan_item() + // -ENOENT + // "could not do orphan cleanup -2" + d_splice_alias(NULL, dentry) + // negative dentry for valid subvol + +The most straightforward fix is to ensure the invariant that a dentry +for a subvolume can exist if and only if that subvolume has +BTRFS_ROOT_ORPHAN_CLEANUP set on its root (and is known to have no +orphans or ran btrfs_orphan_cleanup()). + +Reviewed-by: Filipe Manana +Signed-off-by: Boris Burkov +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/ioctl.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index 5f0bac5cea7e4..c7977bd5442b3 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -674,6 +674,13 @@ static noinline int create_subvol(struct mnt_idmap *idmap, + goto out; + } + ++ /* ++ * Subvolumes have orphans cleaned on first dentry lookup. A new ++ * subvolume cannot have any orphans, so we should set the bit before we ++ * add the subvolume dentry to the dentry cache, so that it is in the ++ * same state as a subvolume after first lookup. ++ */ ++ set_bit(BTRFS_ROOT_ORPHAN_CLEANUP, &new_root->state); + d_instantiate_new(dentry, new_inode_args.inode); + new_inode_args.inode = NULL; + +-- +2.51.0 + diff --git a/queue-6.18/cxl-adjust-the-startup-priority-of-cxl_pmem-to-be-hi.patch b/queue-6.18/cxl-adjust-the-startup-priority-of-cxl_pmem-to-be-hi.patch new file mode 100644 index 0000000000..0b5ae7c257 --- /dev/null +++ b/queue-6.18/cxl-adjust-the-startup-priority-of-cxl_pmem-to-be-hi.patch @@ -0,0 +1,52 @@ +From 54ef833ab596e53f7f259f103804f0a597205584 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Mar 2026 15:45:35 +0800 +Subject: cxl: Adjust the startup priority of cxl_pmem to be higher than that + of cxl_acpi + +From: Cui Chao + +[ Upstream commit be5c5280cf2b20e363dc8e2a424dd200a29b1c77 ] + +During the cxl_acpi probe process, it checks whether the cxl_nvb device +and driver have been attached. Currently, the startup priority of the +cxl_pmem driver is lower than that of the cxl_acpi driver. At this point, +the cxl_nvb driver has not yet been registered on the cxl_bus, causing +the attachment check to fail. This results in a failure to add the root +nvdimm bridge, leading to a cxl_acpi probe failure and ultimately +affecting the subsequent loading of cxl drivers. As a consequence, only +one mem device object exists on the cxl_bus, while the cxl_port device +objects and decoder device objects are missing. + +The solution is to raise the startup priority of cxl_pmem to be higher +than that of cxl_acpi, ensuring that the cxl_pmem driver is registered +before the aforementioned attachment check occurs. + +Co-developed-by: Wang Yinfeng +Signed-off-by: Wang Yinfeng +Signed-off-by: Cui Chao +Fixes: e7e222ad73d9 ("cxl: Move devm_cxl_add_nvdimm_bridge() to cxl_pmem.ko") +Reviewed-by: Dan Williams +Link: https://patch.msgid.link/20260319074535.1709250-1-cuichao1753@phytium.com.cn +Signed-off-by: Dave Jiang +Signed-off-by: Sasha Levin +--- + drivers/cxl/pmem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c +index c00b84b960761..3432fd83b1e2a 100644 +--- a/drivers/cxl/pmem.c ++++ b/drivers/cxl/pmem.c +@@ -554,7 +554,7 @@ static __exit void cxl_pmem_exit(void) + + MODULE_DESCRIPTION("CXL PMEM: Persistent Memory Support"); + MODULE_LICENSE("GPL v2"); +-module_init(cxl_pmem_init); ++subsys_initcall(cxl_pmem_init); + module_exit(cxl_pmem_exit); + MODULE_IMPORT_NS("CXL"); + MODULE_ALIAS_CXL(CXL_DEVICE_NVDIMM_BRIDGE); +-- +2.51.0 + diff --git a/queue-6.18/cxl-hdm-avoid-incorrect-dvsec-fallback-when-hdm-deco.patch b/queue-6.18/cxl-hdm-avoid-incorrect-dvsec-fallback-when-hdm-deco.patch new file mode 100644 index 0000000000..6d7c747c39 --- /dev/null +++ b/queue-6.18/cxl-hdm-avoid-incorrect-dvsec-fallback-when-hdm-deco.patch @@ -0,0 +1,101 @@ +From 80ccd02290622365a9678a10b288684fcf1f6a88 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Mar 2026 20:19:49 +0000 +Subject: cxl/hdm: Avoid incorrect DVSEC fallback when HDM decoders are enabled + +From: Smita Koralahalli + +[ Upstream commit 75cea0776de502f2a1be5ca02d37c586dc81887e ] + +Check the global CXL_HDM_DECODER_ENABLE bit instead of looping over +per-decoder COMMITTED bits to determine whether to fall back to DVSEC +range emulation. When the HDM decoder capability is globally enabled, +ignore DVSEC range registers regardless of individual decoder commit +state. + +should_emulate_decoders() currently loops over per-decoder COMMITTED +bits, which leads to an incorrect DVSEC fallback when those bits are +zero. One way to trigger this is to destroy a region and bounce the +memdev: + + cxl disable-region region0 + cxl destroy-region region0 + cxl disable-memdev mem0 + cxl enable-memdev mem0 + +Region teardown zeroes the HDM decoder registers including the committed +bits. The subsequent memdev re-probe finds uncommitted decoders and falls +back to DVSEC emulation, even though HDM remains globally enabled. + +Observed failures: + + should_emulate_decoders: cxl_port endpoint6: decoder6.0: committed: 0 base: 0x0_00000000 size: 0x0_00000000 + devm_cxl_setup_hdm: cxl_port endpoint6: Fallback map 1 range register + .. + devm_cxl_add_region: cxl_acpi ACPI0017:00: decoder0.0: created region0 + __construct_region: cxl_pci 0000:e1:00.0: mem1:decoder6.0: + __construct_region region0 res: [mem 0x850000000-0x284fffffff flags 0x200] iw: 1 ig: 4096 + cxl region0: pci0000:e0:port1 cxl_port_setup_targets expected iw: 1 ig: 4096 .. + cxl region0: pci0000:e0:port1 cxl_port_setup_targets got iw: 1 ig: 256 state: disabled .. + cxl_port endpoint6: failed to attach decoder6.0 to region0: -6 + .. + devm_cxl_add_region: cxl_acpi ACPI0017:00: decoder0.0: created region4 + alloc_hpa: cxl region4: HPA allocation error (-34) .. + +Fixes: 52cc48ad2a76 ("cxl/hdm: Limit emulation to the number of range registers") +Signed-off-by: Smita Koralahalli +Reviewed-by: Dan Williams +Link: https://patch.msgid.link/20260316201950.224567-1-Smita.KoralahalliChannabasappa@amd.com +Signed-off-by: Dave Jiang +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/hdm.c | 25 +++++++++---------------- + 1 file changed, 9 insertions(+), 16 deletions(-) + +diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c +index 13dafac7c6d56..4d5113b5e6316 100644 +--- a/drivers/cxl/core/hdm.c ++++ b/drivers/cxl/core/hdm.c +@@ -94,7 +94,6 @@ static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info) + struct cxl_hdm *cxlhdm; + void __iomem *hdm; + u32 ctrl; +- int i; + + if (!info) + return false; +@@ -113,22 +112,16 @@ static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info) + return false; + + /* +- * If any decoders are committed already, there should not be any +- * emulated DVSEC decoders. ++ * If HDM decoders are globally enabled, do not fall back to DVSEC ++ * range emulation. Zeroed decoder registers after region teardown ++ * do not imply absence of HDM capability. ++ * ++ * Falling back to DVSEC here would treat the decoder as AUTO and ++ * may incorrectly latch default interleave settings. + */ +- for (i = 0; i < cxlhdm->decoder_count; i++) { +- ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(i)); +- dev_dbg(&info->port->dev, +- "decoder%d.%d: committed: %ld base: %#x_%.8x size: %#x_%.8x\n", +- info->port->id, i, +- FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl), +- readl(hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET(i)), +- readl(hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(i)), +- readl(hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET(i)), +- readl(hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(i))); +- if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl)) +- return false; +- } ++ ctrl = readl(hdm + CXL_HDM_DECODER_CTRL_OFFSET); ++ if (ctrl & CXL_HDM_DECODER_ENABLE) ++ return false; + + return true; + } +-- +2.51.0 + diff --git a/queue-6.18/cxl-port-fix-use-after-free-of-parent_port-in-cxl_de.patch b/queue-6.18/cxl-port-fix-use-after-free-of-parent_port-in-cxl_de.patch new file mode 100644 index 0000000000..e005a41160 --- /dev/null +++ b/queue-6.18/cxl-port-fix-use-after-free-of-parent_port-in-cxl_de.patch @@ -0,0 +1,96 @@ +From b6f151cb1753c826a56f6187c36871dcc79442dc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Feb 2026 10:44:36 -0800 +Subject: cxl/port: Fix use after free of parent_port in cxl_detach_ep() + +From: Alison Schofield + +[ Upstream commit 19d2f0b97a131198efc2c4ca3eb7f980bba8c2b4 ] + +cxl_detach_ep() is called during bottom-up removal when all CXL memory +devices beneath a switch port have been removed. For each port in the +hierarchy it locks both the port and its parent, removes the endpoint, +and if the port is now empty, marks it dead and unregisters the port +by calling delete_switch_port(). There are two places during this work +where the parent_port may be used after freeing: + +First, a concurrent detach may have already processed a port by the +time a second worker finds it via bus_find_device(). Without pinning +parent_port, it may already be freed when we discover port->dead and +attempt to unlock the parent_port. In a production kernel that's a +silent memory corruption, with lock debug, it looks like this: + +[]DEBUG_LOCKS_WARN_ON(__owner_task(owner) != get_current()) +[]WARNING: kernel/locking/mutex.c:949 at __mutex_unlock_slowpath+0x1ee/0x310 +[]Call Trace: +[]mutex_unlock+0xd/0x20 +[]cxl_detach_ep+0x180/0x400 [cxl_core] +[]devm_action_release+0x10/0x20 +[]devres_release_all+0xa8/0xe0 +[]device_unbind_cleanup+0xd/0xa0 +[]really_probe+0x1a6/0x3e0 + +Second, delete_switch_port() releases three devm actions registered +against parent_port. The last of those is unregister_port() and it +calls device_unregister() on the child port, which can cascade. If +parent_port is now also empty the device core may unregister and free +it too. So by the time delete_switch_port() returns, parent_port may +be free, and the subsequent device_unlock(&parent_port->dev) operates +on freed memory. The kernel log looks same as above, with a different +offset in cxl_detach_ep(). + +Both of these issues stem from the absence of a lifetime guarantee +between a child port and its parent port. + +Establish a lifetime rule for ports: child ports hold a reference to +their parent device until release. Take the reference when the port +is allocated and drop it when released. This ensures the parent is +valid for the full lifetime of the child and eliminates the use after +free window in cxl_detach_ep(). + +This is easily reproduced with a reload of cxl_acpi in QEMU with CXL +devices present. + +Fixes: 2345df54249c ("cxl/memdev: Fix endpoint port removal") +Reviewed-by: Dave Jiang +Reviewed-by: Li Ming +Signed-off-by: Alison Schofield +Reviewed-by: Jonathan Cameron +Link: https://patch.msgid.link/20260226184439.1732841-1-alison.schofield@intel.com +Signed-off-by: Dave Jiang +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/port.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c +index 85131872d7f6e..c53a13d4f1662 100644 +--- a/drivers/cxl/core/port.c ++++ b/drivers/cxl/core/port.c +@@ -553,10 +553,13 @@ static void cxl_port_release(struct device *dev) + xa_destroy(&port->dports); + xa_destroy(&port->regions); + ida_free(&cxl_port_ida, port->id); +- if (is_cxl_root(port)) ++ ++ if (is_cxl_root(port)) { + kfree(to_cxl_root(port)); +- else ++ } else { ++ put_device(dev->parent); + kfree(port); ++ } + } + + static ssize_t decoders_committed_show(struct device *dev, +@@ -722,6 +725,7 @@ static struct cxl_port *cxl_port_alloc(struct device *uport_dev, + struct cxl_port *iter; + + dev->parent = &parent_port->dev; ++ get_device(dev->parent); + port->depth = parent_port->depth + 1; + port->parent_dport = parent_dport; + +-- +2.51.0 + diff --git a/queue-6.18/dma-buf-include-ioctl.h-in-uapi-header.patch b/queue-6.18/dma-buf-include-ioctl.h-in-uapi-header.patch new file mode 100644 index 0000000000..e3721aedbd --- /dev/null +++ b/queue-6.18/dma-buf-include-ioctl.h-in-uapi-header.patch @@ -0,0 +1,44 @@ +From 0c6bbf18819ab89973e9ca718d003788c5414027 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Mar 2026 16:23:09 -0800 +Subject: dma-buf: Include ioctl.h in UAPI header +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Isaac J. Manjarres + +[ Upstream commit a116bac87118903925108e57781bbfc7a7eea27b ] + +include/uapi/linux/dma-buf.h uses several macros from ioctl.h to define +its ioctl commands. However, it does not include ioctl.h itself. So, +if userspace source code tries to include the dma-buf.h file without +including ioctl.h, it can result in build failures. + +Therefore, include ioctl.h in the dma-buf UAPI header. + +Signed-off-by: Isaac J. Manjarres +Reviewed-by: T.J. Mercier +Reviewed-by: Christian König +Signed-off-by: Christian König +Link: https://lore.kernel.org/r/20260303002309.1401849-1-isaacmanjarres@google.com +Signed-off-by: Sasha Levin +--- + include/uapi/linux/dma-buf.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h +index 5a6fda66d9adf..e827c9d20c5d3 100644 +--- a/include/uapi/linux/dma-buf.h ++++ b/include/uapi/linux/dma-buf.h +@@ -20,6 +20,7 @@ + #ifndef _DMA_BUF_UAPI_H_ + #define _DMA_BUF_UAPI_H_ + ++#include + #include + + /** +-- +2.51.0 + diff --git a/queue-6.18/driver-core-generalize-driver_override-in-struct-dev.patch b/queue-6.18/driver-core-generalize-driver_override-in-struct-dev.patch new file mode 100644 index 0000000000..0af5224f57 --- /dev/null +++ b/queue-6.18/driver-core-generalize-driver_override-in-struct-dev.patch @@ -0,0 +1,322 @@ +From 73127aba8a931da77e65934e31a8647c5a029f69 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Mar 2026 12:53:18 +0100 +Subject: driver core: generalize driver_override in struct device + +From: Danilo Krummrich + +[ Upstream commit cb3d1049f4ea77d5ad93f17d8ac1f2ed4da70501 ] + +Currently, there are 12 busses (including platform and PCI) that +duplicate the driver_override logic for their individual devices. + +All of them seem to be prone to the bug described in [1]. + +While this could be solved for every bus individually using a separate +lock, solving this in the driver-core generically results in less (and +cleaner) changes overall. + +Thus, move driver_override to struct device, provide corresponding +accessors for busses and handle locking with a separate lock internally. + +In particular, add device_set_driver_override(), +device_has_driver_override(), device_match_driver_override() and +generalize the sysfs store() and show() callbacks via a driver_override +feature flag in struct bus_type. + +Until all busses have migrated, keep driver_set_override() in place. + +Note that we can't use the device lock for the reasons described in [2]. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=220789 [1] +Link: https://lore.kernel.org/driver-core/DGRGTIRHA62X.3RY09D9SOK77P@kernel.org/ [2] +Tested-by: Gui-Dong Han +Co-developed-by: Gui-Dong Han +Signed-off-by: Gui-Dong Han +Reviewed-by: Greg Kroah-Hartman +Link: https://patch.msgid.link/20260303115720.48783-2-dakr@kernel.org +[ Use dev->bus instead of sp->bus for consistency; fix commit message to + refer to the struct bus_type's driver_override feature flag. - Danilo ] +Signed-off-by: Danilo Krummrich +Stable-dep-of: 2b38efc05bf7 ("driver core: platform: use generic driver_override infrastructure") +Signed-off-by: Sasha Levin +--- + drivers/base/bus.c | 43 ++++++++++++++++++++++++++- + drivers/base/core.c | 2 ++ + drivers/base/dd.c | 60 ++++++++++++++++++++++++++++++++++++++ + include/linux/device.h | 54 ++++++++++++++++++++++++++++++++++ + include/linux/device/bus.h | 4 +++ + 5 files changed, 162 insertions(+), 1 deletion(-) + +diff --git a/drivers/base/bus.c b/drivers/base/bus.c +index 5e75e1bce5516..2653670f962f4 100644 +--- a/drivers/base/bus.c ++++ b/drivers/base/bus.c +@@ -466,6 +466,36 @@ int bus_for_each_drv(const struct bus_type *bus, struct device_driver *start, + } + EXPORT_SYMBOL_GPL(bus_for_each_drv); + ++static ssize_t driver_override_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ int ret; ++ ++ ret = __device_set_driver_override(dev, buf, count); ++ if (ret) ++ return ret; ++ ++ return count; ++} ++ ++static ssize_t driver_override_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ guard(spinlock)(&dev->driver_override.lock); ++ return sysfs_emit(buf, "%s\n", dev->driver_override.name); ++} ++static DEVICE_ATTR_RW(driver_override); ++ ++static struct attribute *driver_override_dev_attrs[] = { ++ &dev_attr_driver_override.attr, ++ NULL, ++}; ++ ++static const struct attribute_group driver_override_dev_group = { ++ .attrs = driver_override_dev_attrs, ++}; ++ + /** + * bus_add_device - add device to bus + * @dev: device being added +@@ -499,9 +529,15 @@ int bus_add_device(struct device *dev) + if (error) + goto out_put; + ++ if (dev->bus->driver_override) { ++ error = device_add_group(dev, &driver_override_dev_group); ++ if (error) ++ goto out_groups; ++ } ++ + error = sysfs_create_link(&sp->devices_kset->kobj, &dev->kobj, dev_name(dev)); + if (error) +- goto out_groups; ++ goto out_override; + + error = sysfs_create_link(&dev->kobj, &sp->subsys.kobj, "subsystem"); + if (error) +@@ -512,6 +548,9 @@ int bus_add_device(struct device *dev) + + out_subsys: + sysfs_remove_link(&sp->devices_kset->kobj, dev_name(dev)); ++out_override: ++ if (dev->bus->driver_override) ++ device_remove_group(dev, &driver_override_dev_group); + out_groups: + device_remove_groups(dev, sp->bus->dev_groups); + out_put: +@@ -570,6 +609,8 @@ void bus_remove_device(struct device *dev) + + sysfs_remove_link(&dev->kobj, "subsystem"); + sysfs_remove_link(&sp->devices_kset->kobj, dev_name(dev)); ++ if (dev->bus->driver_override) ++ device_remove_group(dev, &driver_override_dev_group); + device_remove_groups(dev, dev->bus->dev_groups); + if (klist_node_attached(&dev->p->knode_bus)) + klist_del(&dev->p->knode_bus); +diff --git a/drivers/base/core.c b/drivers/base/core.c +index f69dc9c859545..3099dbca234ab 100644 +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -2556,6 +2556,7 @@ static void device_release(struct kobject *kobj) + devres_release_all(dev); + + kfree(dev->dma_range_map); ++ kfree(dev->driver_override.name); + + if (dev->release) + dev->release(dev); +@@ -3159,6 +3160,7 @@ void device_initialize(struct device *dev) + kobject_init(&dev->kobj, &device_ktype); + INIT_LIST_HEAD(&dev->dma_pools); + mutex_init(&dev->mutex); ++ spin_lock_init(&dev->driver_override.lock); + lockdep_set_novalidate_class(&dev->mutex); + spin_lock_init(&dev->devres_lock); + INIT_LIST_HEAD(&dev->devres_head); +diff --git a/drivers/base/dd.c b/drivers/base/dd.c +index 13ab98e033eaa..2996f4c667c42 100644 +--- a/drivers/base/dd.c ++++ b/drivers/base/dd.c +@@ -381,6 +381,66 @@ static void __exit deferred_probe_exit(void) + } + __exitcall(deferred_probe_exit); + ++int __device_set_driver_override(struct device *dev, const char *s, size_t len) ++{ ++ const char *new, *old; ++ char *cp; ++ ++ if (!s) ++ return -EINVAL; ++ ++ /* ++ * The stored value will be used in sysfs show callback (sysfs_emit()), ++ * which has a length limit of PAGE_SIZE and adds a trailing newline. ++ * Thus we can store one character less to avoid truncation during sysfs ++ * show. ++ */ ++ if (len >= (PAGE_SIZE - 1)) ++ return -EINVAL; ++ ++ /* ++ * Compute the real length of the string in case userspace sends us a ++ * bunch of \0 characters like python likes to do. ++ */ ++ len = strlen(s); ++ ++ if (!len) { ++ /* Empty string passed - clear override */ ++ spin_lock(&dev->driver_override.lock); ++ old = dev->driver_override.name; ++ dev->driver_override.name = NULL; ++ spin_unlock(&dev->driver_override.lock); ++ kfree(old); ++ ++ return 0; ++ } ++ ++ cp = strnchr(s, len, '\n'); ++ if (cp) ++ len = cp - s; ++ ++ new = kstrndup(s, len, GFP_KERNEL); ++ if (!new) ++ return -ENOMEM; ++ ++ spin_lock(&dev->driver_override.lock); ++ old = dev->driver_override.name; ++ if (cp != s) { ++ dev->driver_override.name = new; ++ spin_unlock(&dev->driver_override.lock); ++ } else { ++ /* "\n" passed - clear override */ ++ dev->driver_override.name = NULL; ++ spin_unlock(&dev->driver_override.lock); ++ ++ kfree(new); ++ } ++ kfree(old); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(__device_set_driver_override); ++ + /** + * device_is_bound() - Check if device is bound to a driver + * @dev: device to check +diff --git a/include/linux/device.h b/include/linux/device.h +index b031ff71a5bdf..8733a4edf3ccd 100644 +--- a/include/linux/device.h ++++ b/include/linux/device.h +@@ -502,6 +502,8 @@ struct device_physical_location { + * on. This shrinks the "Board Support Packages" (BSPs) and + * minimizes board-specific #ifdefs in drivers. + * @driver_data: Private pointer for driver specific info. ++ * @driver_override: Driver name to force a match. Do not touch directly; use ++ * device_set_driver_override() instead. + * @links: Links to suppliers and consumers of this device. + * @power: For device power management. + * See Documentation/driver-api/pm/devices.rst for details. +@@ -595,6 +597,10 @@ struct device { + core doesn't touch it */ + void *driver_data; /* Driver data, set and get with + dev_set_drvdata/dev_get_drvdata */ ++ struct { ++ const char *name; ++ spinlock_t lock; ++ } driver_override; + struct mutex mutex; /* mutex to synchronize calls to + * its driver. + */ +@@ -720,6 +726,54 @@ struct device_link { + + #define kobj_to_dev(__kobj) container_of_const(__kobj, struct device, kobj) + ++int __device_set_driver_override(struct device *dev, const char *s, size_t len); ++ ++/** ++ * device_set_driver_override() - Helper to set or clear driver override. ++ * @dev: Device to change ++ * @s: NUL-terminated string, new driver name to force a match, pass empty ++ * string to clear it ("" or "\n", where the latter is only for sysfs ++ * interface). ++ * ++ * Helper to set or clear driver override of a device. ++ * ++ * Returns: 0 on success or a negative error code on failure. ++ */ ++static inline int device_set_driver_override(struct device *dev, const char *s) ++{ ++ return __device_set_driver_override(dev, s, s ? strlen(s) : 0); ++} ++ ++/** ++ * device_has_driver_override() - Check if a driver override has been set. ++ * @dev: device to check ++ * ++ * Returns true if a driver override has been set for this device. ++ */ ++static inline bool device_has_driver_override(struct device *dev) ++{ ++ guard(spinlock)(&dev->driver_override.lock); ++ return !!dev->driver_override.name; ++} ++ ++/** ++ * device_match_driver_override() - Match a driver against the device's driver_override. ++ * @dev: device to check ++ * @drv: driver to match against ++ * ++ * Returns > 0 if a driver override is set and matches the given driver, 0 if a ++ * driver override is set but does not match, or < 0 if a driver override is not ++ * set at all. ++ */ ++static inline int device_match_driver_override(struct device *dev, ++ const struct device_driver *drv) ++{ ++ guard(spinlock)(&dev->driver_override.lock); ++ if (dev->driver_override.name) ++ return !strcmp(dev->driver_override.name, drv->name); ++ return -1; ++} ++ + /** + * device_iommu_mapped - Returns true when the device DMA is translated + * by an IOMMU +diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h +index f5a56efd2bd6a..15de0d7881f9e 100644 +--- a/include/linux/device/bus.h ++++ b/include/linux/device/bus.h +@@ -63,6 +63,9 @@ struct fwnode_handle; + * this bus. + * @pm: Power management operations of this bus, callback the specific + * device driver's pm-ops. ++ * @driver_override: Set to true if this bus supports the driver_override ++ * mechanism, which allows userspace to force a specific ++ * driver to bind to a device via a sysfs attribute. + * @need_parent_lock: When probing or removing a device on this bus, the + * device core should lock the device's parent. + * +@@ -104,6 +107,7 @@ struct bus_type { + + const struct dev_pm_ops *pm; + ++ bool driver_override; + bool need_parent_lock; + }; + +-- +2.51.0 + diff --git a/queue-6.18/driver-core-platform-use-generic-driver_override-inf.patch b/queue-6.18/driver-core-platform-use-generic-driver_override-inf.patch new file mode 100644 index 0000000000..cc8925d131 --- /dev/null +++ b/queue-6.18/driver-core-platform-use-generic-driver_override-inf.patch @@ -0,0 +1,200 @@ +From f229ba464e97f100dedab5381b72c5eb3f3f7f20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Mar 2026 12:53:21 +0100 +Subject: driver core: platform: use generic driver_override infrastructure + +From: Danilo Krummrich + +[ Upstream commit 2b38efc05bf7a8568ec74bfffea0f5cfa62bc01d ] + +When a driver is probed through __driver_attach(), the bus' match() +callback is called without the device lock held, thus accessing the +driver_override field without a lock, which can cause a UAF. + +Fix this by using the driver-core driver_override infrastructure taking +care of proper locking internally. + +Note that calling match() from __driver_attach() without the device lock +held is intentional. [1] + +Link: https://lore.kernel.org/driver-core/DGRGTIRHA62X.3RY09D9SOK77P@kernel.org/ [1] +Reported-by: Gui-Dong Han +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220789 +Fixes: 3d713e0e382e ("driver core: platform: add device binding path 'driver_override'") +Reviewed-by: Greg Kroah-Hartman +Link: https://patch.msgid.link/20260303115720.48783-5-dakr@kernel.org +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + drivers/base/platform.c | 37 +++++---------------------------- + drivers/bus/simple-pm-bus.c | 4 ++-- + drivers/clk/imx/clk-scu.c | 3 +-- + drivers/slimbus/qcom-ngd-ctrl.c | 6 ++---- + include/linux/platform_device.h | 5 ----- + sound/soc/samsung/i2s.c | 6 +++--- + 6 files changed, 13 insertions(+), 48 deletions(-) + +diff --git a/drivers/base/platform.c b/drivers/base/platform.c +index 09450349cf323..019d3f26807d9 100644 +--- a/drivers/base/platform.c ++++ b/drivers/base/platform.c +@@ -562,7 +562,6 @@ static void platform_device_release(struct device *dev) + kfree(pa->pdev.dev.platform_data); + kfree(pa->pdev.mfd_cell); + kfree(pa->pdev.resource); +- kfree(pa->pdev.driver_override); + kfree(pa); + } + +@@ -1265,38 +1264,9 @@ static ssize_t numa_node_show(struct device *dev, + } + static DEVICE_ATTR_RO(numa_node); + +-static ssize_t driver_override_show(struct device *dev, +- struct device_attribute *attr, char *buf) +-{ +- struct platform_device *pdev = to_platform_device(dev); +- ssize_t len; +- +- device_lock(dev); +- len = sysfs_emit(buf, "%s\n", pdev->driver_override); +- device_unlock(dev); +- +- return len; +-} +- +-static ssize_t driver_override_store(struct device *dev, +- struct device_attribute *attr, +- const char *buf, size_t count) +-{ +- struct platform_device *pdev = to_platform_device(dev); +- int ret; +- +- ret = driver_set_override(dev, &pdev->driver_override, buf, count); +- if (ret) +- return ret; +- +- return count; +-} +-static DEVICE_ATTR_RW(driver_override); +- + static struct attribute *platform_dev_attrs[] = { + &dev_attr_modalias.attr, + &dev_attr_numa_node.attr, +- &dev_attr_driver_override.attr, + NULL, + }; + +@@ -1336,10 +1306,12 @@ static int platform_match(struct device *dev, const struct device_driver *drv) + { + struct platform_device *pdev = to_platform_device(dev); + struct platform_driver *pdrv = to_platform_driver(drv); ++ int ret; + + /* When driver_override is set, only bind to the matching driver */ +- if (pdev->driver_override) +- return !strcmp(pdev->driver_override, drv->name); ++ ret = device_match_driver_override(dev, drv); ++ if (ret >= 0) ++ return ret; + + /* Attempt an OF style match first */ + if (of_driver_match_device(dev, drv)) +@@ -1475,6 +1447,7 @@ static const struct dev_pm_ops platform_dev_pm_ops = { + const struct bus_type platform_bus_type = { + .name = "platform", + .dev_groups = platform_dev_groups, ++ .driver_override = true, + .match = platform_match, + .uevent = platform_uevent, + .probe = platform_probe, +diff --git a/drivers/bus/simple-pm-bus.c b/drivers/bus/simple-pm-bus.c +index d8e029e7e53f7..50f8b4e2ba5bc 100644 +--- a/drivers/bus/simple-pm-bus.c ++++ b/drivers/bus/simple-pm-bus.c +@@ -36,7 +36,7 @@ static int simple_pm_bus_probe(struct platform_device *pdev) + * that's not listed in simple_pm_bus_of_match. We don't want to do any + * of the simple-pm-bus tasks for these devices, so return early. + */ +- if (pdev->driver_override) ++ if (device_has_driver_override(&pdev->dev)) + return 0; + + match = of_match_device(dev->driver->of_match_table, dev); +@@ -78,7 +78,7 @@ static void simple_pm_bus_remove(struct platform_device *pdev) + { + const void *data = of_device_get_match_data(&pdev->dev); + +- if (pdev->driver_override || data) ++ if (device_has_driver_override(&pdev->dev) || data) + return; + + dev_dbg(&pdev->dev, "%s\n", __func__); +diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c +index 34c9dc1fb20e5..c03f7821824d1 100644 +--- a/drivers/clk/imx/clk-scu.c ++++ b/drivers/clk/imx/clk-scu.c +@@ -696,8 +696,7 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name, + if (ret) + goto put_device; + +- ret = driver_set_override(&pdev->dev, &pdev->driver_override, +- "imx-scu-clk", strlen("imx-scu-clk")); ++ ret = device_set_driver_override(&pdev->dev, "imx-scu-clk"); + if (ret) + goto put_device; + +diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c +index cd40ab839c541..db45654f16955 100644 +--- a/drivers/slimbus/qcom-ngd-ctrl.c ++++ b/drivers/slimbus/qcom-ngd-ctrl.c +@@ -1539,10 +1539,8 @@ static int of_qcom_slim_ngd_register(struct device *parent, + ngd->id = id; + ngd->pdev->dev.parent = parent; + +- ret = driver_set_override(&ngd->pdev->dev, +- &ngd->pdev->driver_override, +- QCOM_SLIM_NGD_DRV_NAME, +- strlen(QCOM_SLIM_NGD_DRV_NAME)); ++ ret = device_set_driver_override(&ngd->pdev->dev, ++ QCOM_SLIM_NGD_DRV_NAME); + if (ret) { + platform_device_put(ngd->pdev); + kfree(ngd); +diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h +index 074754c23d330..bc843d76066a5 100644 +--- a/include/linux/platform_device.h ++++ b/include/linux/platform_device.h +@@ -31,11 +31,6 @@ struct platform_device { + struct resource *resource; + + const struct platform_device_id *id_entry; +- /* +- * Driver name to force a match. Do not set directly, because core +- * frees it. Use driver_set_override() to set or clear it. +- */ +- const char *driver_override; + + /* MFD cell pointer */ + struct mfd_cell *mfd_cell; +diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c +index e9964f0e010ae..140907a41a70d 100644 +--- a/sound/soc/samsung/i2s.c ++++ b/sound/soc/samsung/i2s.c +@@ -1360,10 +1360,10 @@ static int i2s_create_secondary_device(struct samsung_i2s_priv *priv) + if (!pdev_sec) + return -ENOMEM; + +- pdev_sec->driver_override = kstrdup("samsung-i2s", GFP_KERNEL); +- if (!pdev_sec->driver_override) { ++ ret = device_set_driver_override(&pdev_sec->dev, "samsung-i2s"); ++ if (ret) { + platform_device_put(pdev_sec); +- return -ENOMEM; ++ return ret; + } + + ret = platform_device_add(pdev_sec); +-- +2.51.0 + diff --git a/queue-6.18/drm-amdgpu-fix-gpu-idle-power-consumption-issue-for-.patch b/queue-6.18/drm-amdgpu-fix-gpu-idle-power-consumption-issue-for-.patch new file mode 100644 index 0000000000..b35e75f8d3 --- /dev/null +++ b/queue-6.18/drm-amdgpu-fix-gpu-idle-power-consumption-issue-for-.patch @@ -0,0 +1,50 @@ +From c33e57af9f6326aad82b09dd40efa6bd0a8b948f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Mar 2026 18:45:45 -0500 +Subject: drm/amdgpu: fix gpu idle power consumption issue for gfx v12 + +From: Yang Wang + +[ Upstream commit a6571045cf06c4aa749b4801382ae96650e2f0e1 ] + +Older versions of the MES firmware may cause abnormal GPU power consumption. +When performing inference tasks on the GPU (e.g., with Ollama using ROCm), +the GPU may show abnormal power consumption in idle state and incorrect GPU load information. +This issue has been fixed in firmware version 0x8b and newer. + +Closes: https://github.com/ROCm/ROCm/issues/5706 +Signed-off-by: Yang Wang +Acked-by: Alex Deucher +Signed-off-by: Alex Deucher +(cherry picked from commit 4e22a5fe6ea6e0b057e7f246df4ac3ff8bfbc46a) +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/mes_v12_0.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c +index 4a424c1f9d55c..c40aed5a8fc21 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c +@@ -727,6 +727,9 @@ static int mes_v12_0_set_hw_resources(struct amdgpu_mes *mes, int pipe) + int i; + struct amdgpu_device *adev = mes->adev; + union MESAPI_SET_HW_RESOURCES mes_set_hw_res_pkt; ++ uint32_t mes_rev = (pipe == AMDGPU_MES_SCHED_PIPE) ? ++ (mes->sched_version & AMDGPU_MES_VERSION_MASK) : ++ (mes->kiq_version & AMDGPU_MES_VERSION_MASK); + + memset(&mes_set_hw_res_pkt, 0, sizeof(mes_set_hw_res_pkt)); + +@@ -781,7 +784,7 @@ static int mes_v12_0_set_hw_resources(struct amdgpu_mes *mes, int pipe) + * handling support, other queue will not use the oversubscribe timer. + * handling mode - 0: disabled; 1: basic version; 2: basic+ version + */ +- mes_set_hw_res_pkt.oversubscription_timer = 50; ++ mes_set_hw_res_pkt.oversubscription_timer = mes_rev < 0x8b ? 0 : 50; + mes_set_hw_res_pkt.unmapped_doorbell_handling = 1; + + if (amdgpu_mes_log_enable) { +-- +2.51.0 + diff --git a/queue-6.18/drm-ttm-tests-fix-build-failure-on-preempt_rt.patch b/queue-6.18/drm-ttm-tests-fix-build-failure-on-preempt_rt.patch new file mode 100644 index 0000000000..8b14578329 --- /dev/null +++ b/queue-6.18/drm-ttm-tests-fix-build-failure-on-preempt_rt.patch @@ -0,0 +1,48 @@ +From d4384d6a9d04e116793c71a5b813031acf5dbe52 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Mar 2026 09:56:16 +0100 +Subject: drm/ttm/tests: Fix build failure on PREEMPT_RT +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Maarten Lankhorst + +[ Upstream commit a58d487fb1a52579d3c37544ea371da78ed70c45 ] + +Fix a compile error in the kunit tests when CONFIG_PREEMPT_RT is +enabled, and the normal mutex is converted into a rtmutex. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202602261547.3bM6yVAS-lkp@intel.com/ +Reviewed-by: Jouni Högander +Link: https://patch.msgid.link/20260304085616.1216961-1-dev@lankhorst.se +Signed-off-by: Maarten Lankhorst +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/ttm/tests/ttm_bo_test.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/ttm/tests/ttm_bo_test.c b/drivers/gpu/drm/ttm/tests/ttm_bo_test.c +index 6c77550c51af1..40a55f81bf47d 100644 +--- a/drivers/gpu/drm/ttm/tests/ttm_bo_test.c ++++ b/drivers/gpu/drm/ttm/tests/ttm_bo_test.c +@@ -222,13 +222,13 @@ static void ttm_bo_reserve_interrupted(struct kunit *test) + KUNIT_FAIL(test, "Couldn't create ttm bo reserve task\n"); + + /* Take a lock so the threaded reserve has to wait */ +- mutex_lock(&bo->base.resv->lock.base); ++ dma_resv_lock(bo->base.resv, NULL); + + wake_up_process(task); + msleep(20); + err = kthread_stop(task); + +- mutex_unlock(&bo->base.resv->lock.base); ++ dma_resv_unlock(bo->base.resv); + + KUNIT_ASSERT_EQ(test, err, -ERESTARTSYS); + } +-- +2.51.0 + diff --git a/queue-6.18/hid-apple-add-epomaker-th87-to-the-non-apple-keyboar.patch b/queue-6.18/hid-apple-add-epomaker-th87-to-the-non-apple-keyboar.patch new file mode 100644 index 0000000000..c3b83682dd --- /dev/null +++ b/queue-6.18/hid-apple-add-epomaker-th87-to-the-non-apple-keyboar.patch @@ -0,0 +1,41 @@ +From 84413851e1bc0d6fd4112acc533929779b5163d7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Feb 2026 10:00:02 +0100 +Subject: HID: apple: Add EPOMAKER TH87 to the non-apple keyboards list + +From: Takashi Iwai + +[ Upstream commit 7c698de0dc5daa1e1a5fd1f0c6aa1b6bb2f5d867 ] + +EPOMAKER TH87 has the very same ID as Apple Aluminum keyboard +(05ac:024f) although it doesn't work as expected in compatible way. + +Put three entries to the non-apple keyboards list to exclude this +device: one for BT ("TH87"), one for USB ("HFD Epomaker TH87") and one +for dongle ("2.4G Wireless Receiver"). + +Link: https://bugzilla.suse.com/show_bug.cgi?id=1258455 +Signed-off-by: Takashi Iwai +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-apple.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 233e367cce1d1..2f9a2e07c4263 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -365,6 +365,9 @@ static const struct apple_non_apple_keyboard non_apple_keyboards[] = { + { "A3R" }, + { "hfd.cn" }, + { "WKB603" }, ++ { "TH87" }, /* EPOMAKER TH87 BT mode */ ++ { "HFD Epomaker TH87" }, /* EPOMAKER TH87 USB mode */ ++ { "2.4G Wireless Receiver" }, /* EPOMAKER TH87 dongle */ + }; + + static bool apple_is_non_apple_keyboard(struct hid_device *hdev) +-- +2.51.0 + diff --git a/queue-6.18/hid-apple-avoid-memory-leak-in-apple_report_fixup.patch b/queue-6.18/hid-apple-avoid-memory-leak-in-apple_report_fixup.patch new file mode 100644 index 0000000000..5ec3fc69a5 --- /dev/null +++ b/queue-6.18/hid-apple-avoid-memory-leak-in-apple_report_fixup.patch @@ -0,0 +1,45 @@ +From aad99870aa199e17d1c39a5e006be33af8b3c953 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Feb 2026 16:43:36 +0100 +Subject: HID: apple: avoid memory leak in apple_report_fixup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Günther Noack + +[ Upstream commit 239c15116d80f67d32f00acc34575f1a6b699613 ] + +The apple_report_fixup() function was returning a +newly kmemdup()-allocated buffer, but never freeing it. + +The caller of report_fixup() does not take ownership of the returned +pointer, but it *is* permitted to return a sub-portion of the input +rdesc, whose lifetime is managed by the caller. + +Assisted-by: Gemini-CLI:Google Gemini 3 +Signed-off-by: Günther Noack +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-apple.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 2f9a2e07c4263..9dcb252c5d6c7 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -689,9 +689,7 @@ static const __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc, + hid_info(hdev, + "fixing up Magic Keyboard battery report descriptor\n"); + *rsize = *rsize - 1; +- rdesc = kmemdup(rdesc + 1, *rsize, GFP_KERNEL); +- if (!rdesc) +- return NULL; ++ rdesc = rdesc + 1; + + rdesc[0] = 0x05; + rdesc[1] = 0x01; +-- +2.51.0 + diff --git a/queue-6.18/hid-asus-add-xg-mobile-2023-external-hardware-suppor.patch b/queue-6.18/hid-asus-add-xg-mobile-2023-external-hardware-suppor.patch new file mode 100644 index 0000000000..835ca56e7e --- /dev/null +++ b/queue-6.18/hid-asus-add-xg-mobile-2023-external-hardware-suppor.patch @@ -0,0 +1,49 @@ +From df19a5b00eb582fbf1509bc60752892cdd578fb6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 18:55:38 +0100 +Subject: HID: asus: add xg mobile 2023 external hardware support + +From: Denis Benato + +[ Upstream commit 377f8e788945d45b012ed9cfc35ca56c02e86cd8 ] + +XG mobile stations have the 0x5a endpoint and has to be initialized: +add them to hid-asus. + +Signed-off-by: Denis Benato +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-asus.c | 3 +++ + drivers/hid/hid-ids.h | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index 7904b3b7ea63c..5a068f6fd2ce5 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -1403,6 +1403,9 @@ static const struct hid_device_id asus_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, + USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X), + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_ALLY_XPAD }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, ++ USB_DEVICE_ID_ASUSTEK_XGM_2023), ++ }, + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, + USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD), + QUIRK_ROG_CLAYMORE_II_KEYBOARD }, +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index f5715cf9468fc..d9d354f1b8847 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -229,6 +229,7 @@ + #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X 0x1b4c + #define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b + #define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869 ++#define USB_DEVICE_ID_ASUSTEK_XGM_2023 0x1a9a + + #define USB_VENDOR_ID_ATEN 0x0557 + #define USB_DEVICE_ID_ATEN_UC100KM 0x2004 +-- +2.51.0 + diff --git a/queue-6.18/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch b/queue-6.18/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch new file mode 100644 index 0000000000..6aa0eaf6f4 --- /dev/null +++ b/queue-6.18/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch @@ -0,0 +1,65 @@ +From c99f8567c134ef26f92a73adf843bc0ff0a18df8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Feb 2026 16:43:38 +0100 +Subject: HID: asus: avoid memory leak in asus_report_fixup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Günther Noack + +[ Upstream commit 2bad24c17742fc88973d6aea526ce1353f5334a3 ] + +The asus_report_fixup() function was returning a newly allocated +kmemdup()-allocated buffer, but never freeing it. Switch to +devm_kzalloc() to ensure the memory is managed and freed automatically +when the device is removed. + +The caller of report_fixup() does not take ownership of the returned +pointer, but it is permitted to return a pointer whose lifetime is at +least that of the input buffer. + +Also fix a harmless out-of-bounds read by copying only the original +descriptor size. + +Assisted-by: Gemini-CLI:Google Gemini 3 +Signed-off-by: Günther Noack +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-asus.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index a444d41e53b6c..7904b3b7ea63c 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -1305,14 +1305,21 @@ static const __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, + */ + if (*rsize == rsize_orig && + rdesc[offs] == 0x09 && rdesc[offs + 1] == 0x76) { +- *rsize = rsize_orig + 1; +- rdesc = kmemdup(rdesc, *rsize, GFP_KERNEL); +- if (!rdesc) +- return NULL; ++ __u8 *new_rdesc; ++ ++ new_rdesc = devm_kzalloc(&hdev->dev, rsize_orig + 1, ++ GFP_KERNEL); ++ if (!new_rdesc) ++ return rdesc; + + hid_info(hdev, "Fixing up %s keyb report descriptor\n", + drvdata->quirks & QUIRK_T100CHI ? + "T100CHI" : "T90CHI"); ++ ++ memcpy(new_rdesc, rdesc, rsize_orig); ++ *rsize = rsize_orig + 1; ++ rdesc = new_rdesc; ++ + memmove(rdesc + offs + 4, rdesc + offs + 2, 12); + rdesc[offs] = 0x19; + rdesc[offs + 1] = 0x00; +-- +2.51.0 + diff --git a/queue-6.18/hid-intel-ish-hid-ipc-add-nova-lake-h-s-pci-device-i.patch b/queue-6.18/hid-intel-ish-hid-ipc-add-nova-lake-h-s-pci-device-i.patch new file mode 100644 index 0000000000..716bc5d496 --- /dev/null +++ b/queue-6.18/hid-intel-ish-hid-ipc-add-nova-lake-h-s-pci-device-i.patch @@ -0,0 +1,79 @@ +From 7c9eb8f5d4dddb7199f3978e90c4223e1e1cf73b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Feb 2026 08:55:07 +0800 +Subject: HID: intel-ish-hid: ipc: Add Nova Lake-H/S PCI device IDs + +From: Zhang Lixu + +[ Upstream commit 22f8bcec5aeb05104b3eaa950cb5a345e95f0aa8 ] + +Add device IDs of Nova Lake-H and Nova Lake-S into ishtp support list. + +Signed-off-by: Zhang Lixu +Reviewed-by: Andy Shevchenko +Acked-by: Srinivas Pandruvada +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/intel-ish-hid/ipc/hw-ish.h | 2 ++ + drivers/hid/intel-ish-hid/ipc/pci-ish.c | 12 ++++++++++++ + 2 files changed, 14 insertions(+) + +diff --git a/drivers/hid/intel-ish-hid/ipc/hw-ish.h b/drivers/hid/intel-ish-hid/ipc/hw-ish.h +index fa5d68c363134..27389971b96cc 100644 +--- a/drivers/hid/intel-ish-hid/ipc/hw-ish.h ++++ b/drivers/hid/intel-ish-hid/ipc/hw-ish.h +@@ -39,6 +39,8 @@ + #define PCI_DEVICE_ID_INTEL_ISH_PTL_H 0xE345 + #define PCI_DEVICE_ID_INTEL_ISH_PTL_P 0xE445 + #define PCI_DEVICE_ID_INTEL_ISH_WCL 0x4D45 ++#define PCI_DEVICE_ID_INTEL_ISH_NVL_H 0xD354 ++#define PCI_DEVICE_ID_INTEL_ISH_NVL_S 0x6E78 + + #define REVISION_ID_CHT_A0 0x6 + #define REVISION_ID_CHT_Ax_SI 0x0 +diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c +index b748ac6fbfdc7..51a41a28541c5 100644 +--- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c ++++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c +@@ -28,11 +28,15 @@ enum ishtp_driver_data_index { + ISHTP_DRIVER_DATA_LNL_M, + ISHTP_DRIVER_DATA_PTL, + ISHTP_DRIVER_DATA_WCL, ++ ISHTP_DRIVER_DATA_NVL_H, ++ ISHTP_DRIVER_DATA_NVL_S, + }; + + #define ISH_FW_GEN_LNL_M "lnlm" + #define ISH_FW_GEN_PTL "ptl" + #define ISH_FW_GEN_WCL "wcl" ++#define ISH_FW_GEN_NVL_H "nvlh" ++#define ISH_FW_GEN_NVL_S "nvls" + + #define ISH_FIRMWARE_PATH(gen) "intel/ish/ish_" gen ".bin" + #define ISH_FIRMWARE_PATH_ALL "intel/ish/ish_*.bin" +@@ -47,6 +51,12 @@ static struct ishtp_driver_data ishtp_driver_data[] = { + [ISHTP_DRIVER_DATA_WCL] = { + .fw_generation = ISH_FW_GEN_WCL, + }, ++ [ISHTP_DRIVER_DATA_NVL_H] = { ++ .fw_generation = ISH_FW_GEN_NVL_H, ++ }, ++ [ISHTP_DRIVER_DATA_NVL_S] = { ++ .fw_generation = ISH_FW_GEN_NVL_S, ++ }, + }; + + static const struct pci_device_id ish_pci_tbl[] = { +@@ -76,6 +86,8 @@ static const struct pci_device_id ish_pci_tbl[] = { + {PCI_DEVICE_DATA(INTEL, ISH_PTL_H, ISHTP_DRIVER_DATA_PTL)}, + {PCI_DEVICE_DATA(INTEL, ISH_PTL_P, ISHTP_DRIVER_DATA_PTL)}, + {PCI_DEVICE_DATA(INTEL, ISH_WCL, ISHTP_DRIVER_DATA_WCL)}, ++ {PCI_DEVICE_DATA(INTEL, ISH_NVL_H, ISHTP_DRIVER_DATA_NVL_H)}, ++ {PCI_DEVICE_DATA(INTEL, ISH_NVL_S, ISHTP_DRIVER_DATA_NVL_S)}, + {} + }; + MODULE_DEVICE_TABLE(pci, ish_pci_tbl); +-- +2.51.0 + diff --git a/queue-6.18/hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch b/queue-6.18/hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch new file mode 100644 index 0000000000..4cec24851a --- /dev/null +++ b/queue-6.18/hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch @@ -0,0 +1,45 @@ +From 7f955fe1b05419abdb499c65111b98a2ffd7b8ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Feb 2026 16:43:37 +0100 +Subject: HID: magicmouse: avoid memory leak in magicmouse_report_fixup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Günther Noack + +[ Upstream commit 91e8c6e601bdc1ccdf886479b6513c01c7e51c2c ] + +The magicmouse_report_fixup() function was returning a +newly kmemdup()-allocated buffer, but never freeing it. + +The caller of report_fixup() does not take ownership of the returned +pointer, but it *is* permitted to return a sub-portion of the input +rdesc, whose lifetime is managed by the caller. + +Assisted-by: Gemini-CLI:Google Gemini 3 +Signed-off-by: Günther Noack +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-magicmouse.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index f4cf29c2e8330..9eadf3252d0dc 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -994,9 +994,7 @@ static const __u8 *magicmouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, + hid_info(hdev, + "fixing up magicmouse battery report descriptor\n"); + *rsize = *rsize - 1; +- rdesc = kmemdup(rdesc + 1, *rsize, GFP_KERNEL); +- if (!rdesc) +- return NULL; ++ rdesc = rdesc + 1; + + rdesc[0] = 0x05; + rdesc[1] = 0x01; +-- +2.51.0 + diff --git a/queue-6.18/hid-magicmouse-fix-battery-reporting-for-apple-magic.patch b/queue-6.18/hid-magicmouse-fix-battery-reporting-for-apple-magic.patch new file mode 100644 index 0000000000..4c82f02f4c --- /dev/null +++ b/queue-6.18/hid-magicmouse-fix-battery-reporting-for-apple-magic.patch @@ -0,0 +1,41 @@ +From 3944e3a87dc14f8543770d5da0e4298e11a766ee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Feb 2026 20:34:21 +0100 +Subject: HID: magicmouse: fix battery reporting for Apple Magic Trackpad 2 + +From: Julius Lehmann + +[ Upstream commit 5f3518d77419255f8b12bb23c8ec22acbeb6bc5b ] + +Battery reporting does not work for the Apple Magic Trackpad 2 if it is +connected via USB. The current hid descriptor fixup code checks for a +hid descriptor length of exactly 83 bytes. If the hid descriptor is +larger, which is the case for newer apple mice, the fixup is not +applied. + +This fix checks for hid descriptor sizes greater/equal 83 bytes which +applies the fixup for newer devices as well. + +Signed-off-by: Julius Lehmann +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-magicmouse.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 91f621ceb924b..f4cf29c2e8330 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -990,7 +990,7 @@ static const __u8 *magicmouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, + */ + if ((is_usb_magicmouse2(hdev->vendor, hdev->product) || + is_usb_magictrackpad2(hdev->vendor, hdev->product)) && +- *rsize == 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) { ++ *rsize >= 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) { + hid_info(hdev, + "fixing up magicmouse battery report descriptor\n"); + *rsize = *rsize - 1; +-- +2.51.0 + diff --git a/queue-6.18/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch b/queue-6.18/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch new file mode 100644 index 0000000000..46a31635b9 --- /dev/null +++ b/queue-6.18/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch @@ -0,0 +1,41 @@ +From d45cd6c7d9ec6ddf14db14af34a7a773aa6424d9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 17:32:58 +0100 +Subject: HID: mcp2221: cancel last I2C command on read error + +From: Romain Sioen + +[ Upstream commit e31b556c0ba21f20c298aa61181b96541140b7b9 ] + +When an I2C SMBus read operation fails, the MCP2221 internal state machine +may not reset correctly, causing subsequent transactions to fail. + +By adding a short delay and explicitly cancelling the last command, +we ensure the device is ready for the next operation. + +Fix an issue where i2cdetect was not able to detect all devices correctly +on the bus. + +Signed-off-by: Romain Sioen +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-mcp2221.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c +index 33603b019f975..ef3b5c77c38e3 100644 +--- a/drivers/hid/hid-mcp2221.c ++++ b/drivers/hid/hid-mcp2221.c +@@ -353,6 +353,8 @@ static int mcp_i2c_smbus_read(struct mcp2221 *mcp, + usleep_range(90, 100); + retries++; + } else { ++ usleep_range(980, 1000); ++ mcp_cancel_last_cmd(mcp); + return ret; + } + } else { +-- +2.51.0 + diff --git a/queue-6.18/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch b/queue-6.18/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch new file mode 100644 index 0000000000..072a21390d --- /dev/null +++ b/queue-6.18/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch @@ -0,0 +1,43 @@ +From f97ad7cfd979bd271a26698cb708564e5fddf2f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Mar 2026 12:53:20 +0100 +Subject: hwmon: axi-fan: don't use driver_override as IRQ name +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Danilo Krummrich + +[ Upstream commit 813bbc4d33d2ca5b0da63e70ae13b60874f20d37 ] + +Do not use driver_override as IRQ name, as it is not guaranteed to point +to a valid string; use NULL instead (which makes the devm IRQ helpers +use dev_name()). + +Fixes: 8412b410fa5e ("hwmon: Support ADI Fan Control IP") +Reviewed-by: Nuno Sá +Acked-by: Guenter Roeck +Reviewed-by: Greg Kroah-Hartman +Link: https://patch.msgid.link/20260303115720.48783-4-dakr@kernel.org +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + drivers/hwmon/axi-fan-control.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c +index b7bb325c3ad96..01590dfa55e60 100644 +--- a/drivers/hwmon/axi-fan-control.c ++++ b/drivers/hwmon/axi-fan-control.c +@@ -507,7 +507,7 @@ static int axi_fan_control_probe(struct platform_device *pdev) + ret = devm_request_threaded_irq(&pdev->dev, ctl->irq, NULL, + axi_fan_control_irq_handler, + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, +- pdev->driver_override, ctl); ++ NULL, ctl); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "failed to request an irq\n"); +-- +2.51.0 + diff --git a/queue-6.18/i3c-master-dw-i3c-fix-missing-of_node-for-virtual-i2.patch b/queue-6.18/i3c-master-dw-i3c-fix-missing-of_node-for-virtual-i2.patch new file mode 100644 index 0000000000..2afaf7079c --- /dev/null +++ b/queue-6.18/i3c-master-dw-i3c-fix-missing-of_node-for-virtual-i2.patch @@ -0,0 +1,43 @@ +From 43f9db3e2b4d428208c45828bb85997d709bdfb5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Mar 2026 15:56:42 +0800 +Subject: i3c: master: dw-i3c: Fix missing of_node for virtual I2C adapter + +From: Peter Yin + +[ Upstream commit f26ecaa0f0abfe5db173416214098a00d3b7db79 ] + +The DesignWare I3C master driver creates a virtual I2C adapter to +provide backward compatibility with I2C devices. However, the current +implementation does not associate this virtual adapter with any +Device Tree node. + +Propagate the of_node from the I3C master platform device to the +virtual I2C adapter's device structure. This ensures that standard +I2C aliases are correctly resolved and bus numbering remains consistent. + +Signed-off-by: Peter Yin +Reviewed-by: Frank Li +Link: https://patch.msgid.link/20260302075645.1492766-1-peteryin.openbmc@gmail.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/dw-i3c-master.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c +index 41ddac1d49d5e..825eb2d20e9eb 100644 +--- a/drivers/i3c/master/dw-i3c-master.c ++++ b/drivers/i3c/master/dw-i3c-master.c +@@ -1596,6 +1596,8 @@ int dw_i3c_common_probe(struct dw_i3c_master *master, + master->quirks = (unsigned long)device_get_match_data(&pdev->dev); + + INIT_WORK(&master->hj_work, dw_i3c_hj_work); ++ ++ device_set_of_node_from_dev(&master->base.i2c.dev, &pdev->dev); + ret = i3c_master_register(&master->base, &pdev->dev, + &dw_mipi_i3c_ops, false); + if (ret) +-- +2.51.0 + diff --git a/queue-6.18/kbuild-install-extmod-build-package-resolve_btfids-i.patch b/queue-6.18/kbuild-install-extmod-build-package-resolve_btfids-i.patch new file mode 100644 index 0000000000..612a14473c --- /dev/null +++ b/queue-6.18/kbuild-install-extmod-build-package-resolve_btfids-i.patch @@ -0,0 +1,47 @@ +From ee2b5f7668b30b4676c423a4ddb7eb3f3a754e16 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Feb 2026 08:41:48 +0100 +Subject: kbuild: install-extmod-build: Package resolve_btfids if necessary +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weißschuh + +[ Upstream commit 459cb3c054c2352bb321648744b620259a716b60 ] + +When CONFIG_DEBUG_INFO_BTF_MODULES is enabled and vmlinux is available, +Makefile.modfinal and gen-btf.sh will try to use resolve_btfids on the +module .ko. install-extmod-build currently does not package +resolve_btfids, so that step fails. + +Package resolve_btfids if it may be used. + +Signed-off-by: Thomas Weißschuh +Reviewed-by: Nicolas Schier +Link: https://patch.msgid.link/20260226-kbuild-resolve_btfids-v1-1-2bf38b93dfe7@linutronix.de +[nathan: Small commit message tweaks] +Signed-off-by: Nathan Chancellor +Signed-off-by: Sasha Levin +--- + scripts/package/install-extmod-build | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/scripts/package/install-extmod-build b/scripts/package/install-extmod-build +index 2576cf7902dbb..f12e1ffe409eb 100755 +--- a/scripts/package/install-extmod-build ++++ b/scripts/package/install-extmod-build +@@ -32,6 +32,10 @@ mkdir -p "${destdir}" + echo tools/objtool/objtool + fi + ++ if is_enabled CONFIG_DEBUG_INFO_BTF_MODULES; then ++ echo tools/bpf/resolve_btfids/resolve_btfids ++ fi ++ + echo Module.symvers + echo "arch/${SRCARCH}/include/generated" + echo include/config/auto.conf +-- +2.51.0 + diff --git a/queue-6.18/module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch b/queue-6.18/module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch new file mode 100644 index 0000000000..a50b4a7323 --- /dev/null +++ b/queue-6.18/module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch @@ -0,0 +1,80 @@ +From 898b0e9c65410d440859f07df265d0ceca733774 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Dec 2025 10:32:08 -0800 +Subject: module: Fix kernel panic when a symbol st_shndx is out of bounds + +From: Ihor Solodrai + +[ Upstream commit f9d69d5e7bde2295eb7488a56f094ac8f5383b92 ] + +The module loader doesn't check for bounds of the ELF section index in +simplify_symbols(): + + for (i = 1; i < symsec->sh_size / sizeof(Elf_Sym); i++) { + const char *name = info->strtab + sym[i].st_name; + + switch (sym[i].st_shndx) { + case SHN_COMMON: + + [...] + + default: + /* Divert to percpu allocation if a percpu var. */ + if (sym[i].st_shndx == info->index.pcpu) + secbase = (unsigned long)mod_percpu(mod); + else + /** HERE --> **/ secbase = info->sechdrs[sym[i].st_shndx].sh_addr; + sym[i].st_value += secbase; + break; + } + } + +A symbol with an out-of-bounds st_shndx value, for example 0xffff +(known as SHN_XINDEX or SHN_HIRESERVE), may cause a kernel panic: + + BUG: unable to handle page fault for address: ... + RIP: 0010:simplify_symbols+0x2b2/0x480 + ... + Kernel panic - not syncing: Fatal exception + +This can happen when module ELF is legitimately using SHN_XINDEX or +when it is corrupted. + +Add a bounds check in simplify_symbols() to validate that st_shndx is +within the valid range before using it. + +This issue was discovered due to a bug in llvm-objcopy, see relevant +discussion for details [1]. + +[1] https://lore.kernel.org/linux-modules/20251224005752.201911-1-ihor.solodrai@linux.dev/ + +Signed-off-by: Ihor Solodrai +Reviewed-by: Daniel Gomez +Reviewed-by: Petr Pavlu +Signed-off-by: Sami Tolvanen +Signed-off-by: Sasha Levin +--- + kernel/module/main.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/kernel/module/main.c b/kernel/module/main.c +index a2c798d06e3f5..66d4efbddfffe 100644 +--- a/kernel/module/main.c ++++ b/kernel/module/main.c +@@ -1568,6 +1568,13 @@ static int simplify_symbols(struct module *mod, const struct load_info *info) + break; + + default: ++ if (sym[i].st_shndx >= info->hdr->e_shnum) { ++ pr_err("%s: Symbol %s has an invalid section index %u (max %u)\n", ++ mod->name, name, sym[i].st_shndx, info->hdr->e_shnum - 1); ++ ret = -ENOEXEC; ++ break; ++ } ++ + /* Divert to percpu allocation if a percpu var. */ + if (sym[i].st_shndx == info->index.pcpu) + secbase = (unsigned long)mod_percpu(mod); +-- +2.51.0 + diff --git a/queue-6.18/net-usb-r8152-add-trendnet-tuc-et2g.patch b/queue-6.18/net-usb-r8152-add-trendnet-tuc-et2g.patch new file mode 100644 index 0000000000..cfc60c6d4e --- /dev/null +++ b/queue-6.18/net-usb-r8152-add-trendnet-tuc-et2g.patch @@ -0,0 +1,48 @@ +From 9c1720c60c44a21e61298e163cdadd67e8baf043 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Feb 2026 20:54:09 +0100 +Subject: net: usb: r8152: add TRENDnet TUC-ET2G + +From: Valentin Spreckels + +[ Upstream commit 15fba71533bcdfaa8eeba69a5a5a2927afdf664a ] + +The TRENDnet TUC-ET2G is a RTL8156 based usb ethernet adapter. Add its +vendor and product IDs. + +Signed-off-by: Valentin Spreckels +Link: https://patch.msgid.link/20260226195409.7891-2-valentin@spreckels.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/usb/r8152.c | 1 + + include/linux/usb/r8152.h | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c +index da8de7b1a4891..357f5c733d0b5 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -10061,6 +10061,7 @@ static const struct usb_device_id rtl8152_table[] = { + { USB_DEVICE(VENDOR_ID_DLINK, 0xb301) }, + { USB_DEVICE(VENDOR_ID_DELL, 0xb097) }, + { USB_DEVICE(VENDOR_ID_ASUS, 0x1976) }, ++ { USB_DEVICE(VENDOR_ID_TRENDNET, 0xe02b) }, + {} + }; + +diff --git a/include/linux/usb/r8152.h b/include/linux/usb/r8152.h +index 2ca60828f28bb..1502b2a355f98 100644 +--- a/include/linux/usb/r8152.h ++++ b/include/linux/usb/r8152.h +@@ -32,6 +32,7 @@ + #define VENDOR_ID_DLINK 0x2001 + #define VENDOR_ID_DELL 0x413c + #define VENDOR_ID_ASUS 0x0b05 ++#define VENDOR_ID_TRENDNET 0x20f4 + + #if IS_REACHABLE(CONFIG_USB_RTL8152) + extern u8 rtl8152_get_version(struct usb_interface *intf); +-- +2.51.0 + diff --git a/queue-6.18/nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch b/queue-6.18/nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch new file mode 100644 index 0000000000..841120086a --- /dev/null +++ b/queue-6.18/nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch @@ -0,0 +1,40 @@ +From 4fd3faf675337c9614d72b09fe4d6c771b21d4b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 31 Jan 2026 19:08:40 -0800 +Subject: nvme-fabrics: use kfree_sensitive() for DHCHAP secrets + +From: Daniel Hodges + +[ Upstream commit 0a1fc2f301529ac75aec0ce80d5ab9d9e4dc4b16 ] + +The DHCHAP secrets (dhchap_secret and dhchap_ctrl_secret) contain +authentication key material for NVMe-oF. Use kfree_sensitive() instead +of kfree() in nvmf_free_options() to ensure secrets are zeroed before +the memory is freed, preventing recovery from freed pages. + +Reviewed-by: Christoph Hellwig +Signed-off-by: Daniel Hodges +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/fabrics.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c +index 55a8afd2efd50..d37cb140d8323 100644 +--- a/drivers/nvme/host/fabrics.c ++++ b/drivers/nvme/host/fabrics.c +@@ -1290,8 +1290,8 @@ void nvmf_free_options(struct nvmf_ctrl_options *opts) + kfree(opts->subsysnqn); + kfree(opts->host_traddr); + kfree(opts->host_iface); +- kfree(opts->dhchap_secret); +- kfree(opts->dhchap_ctrl_secret); ++ kfree_sensitive(opts->dhchap_secret); ++ kfree_sensitive(opts->dhchap_ctrl_secret); + kfree(opts); + } + EXPORT_SYMBOL_GPL(nvmf_free_options); +-- +2.51.0 + diff --git a/queue-6.18/nvme-pci-cap-queue-creation-to-used-queues.patch b/queue-6.18/nvme-pci-cap-queue-creation-to-used-queues.patch new file mode 100644 index 0000000000..2218b4844c --- /dev/null +++ b/queue-6.18/nvme-pci-cap-queue-creation-to-used-queues.patch @@ -0,0 +1,45 @@ +From 5640d89810d4b766609721e8230c555f7a5eb894 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 11:00:12 -0800 +Subject: nvme-pci: cap queue creation to used queues + +From: Keith Busch + +[ Upstream commit 4735b510a00fb2d4ac9e8d21a8c9552cb281f585 ] + +If the user reduces the special queue count at runtime and resets the +controller, we need to reduce the number of queues and interrupts +requested accordingly rather than start with the pre-allocated queue +count. + +Tested-by: Kanchan Joshi +Reviewed-by: Kanchan Joshi +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 9987b711091f0..4459687eb7bb6 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2707,7 +2707,13 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) + dev->nr_write_queues = write_queues; + dev->nr_poll_queues = poll_queues; + +- nr_io_queues = dev->nr_allocated_queues - 1; ++ /* ++ * The initial number of allocated queue slots may be too large if the ++ * user reduced the special queue parameters. Cap the value to the ++ * number we need for this round. ++ */ ++ nr_io_queues = min(nvme_max_io_queues(dev), ++ dev->nr_allocated_queues - 1); + result = nvme_set_queue_count(&dev->ctrl, &nr_io_queues); + if (result < 0) + return result; +-- +2.51.0 + diff --git a/queue-6.18/nvme-pci-ensure-we-re-polling-a-polled-queue.patch b/queue-6.18/nvme-pci-ensure-we-re-polling-a-polled-queue.patch new file mode 100644 index 0000000000..70fd1949f0 --- /dev/null +++ b/queue-6.18/nvme-pci-ensure-we-re-polling-a-polled-queue.patch @@ -0,0 +1,39 @@ +From 360a3e0c858d3e92b51a9d8de5fe8726e58441ee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 09:26:54 -0800 +Subject: nvme-pci: ensure we're polling a polled queue + +From: Keith Busch + +[ Upstream commit 166e31d7dbf6aa44829b98aa446bda5c9580f12a ] + +A user can change the polled queue count at run time. There's a brief +window during a reset where a hipri task may try to poll that queue +before the block layer has updated the queue maps, which would race with +the now interrupt driven queue and may cause double completions. + +Reviewed-by: Christoph Hellwig +Reviewed-by: Kanchan Joshi +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 4459687eb7bb6..a64b4b4a18a19 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1430,7 +1430,8 @@ static int nvme_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob) + struct nvme_queue *nvmeq = hctx->driver_data; + bool found; + +- if (!nvme_cqe_pending(nvmeq)) ++ if (!test_bit(NVMEQ_POLLED, &nvmeq->flags) || ++ !nvme_cqe_pending(nvmeq)) + return 0; + + spin_lock(&nvmeq->cq_poll_lock); +-- +2.51.0 + diff --git a/queue-6.18/nvmet-move-async-event-work-off-nvmet-wq.patch b/queue-6.18/nvmet-move-async-event-work-off-nvmet-wq.patch new file mode 100644 index 0000000000..fdcaad1226 --- /dev/null +++ b/queue-6.18/nvmet-move-async-event-work-off-nvmet-wq.patch @@ -0,0 +1,178 @@ +From 64fdaee2c2b35f8faeb64b0ff11642b875ff5161 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Feb 2026 20:30:03 -0800 +Subject: nvmet: move async event work off nvmet-wq + +From: Chaitanya Kulkarni + +[ Upstream commit 2922e3507f6d5caa7f1d07f145e186fc6f317a4e ] + +For target nvmet_ctrl_free() flushes ctrl->async_event_work. +If nvmet_ctrl_free() runs on nvmet-wq, the flush re-enters workqueue +completion for the same worker:- + +A. Async event work queued on nvmet-wq (prior to disconnect): + nvmet_execute_async_event() + queue_work(nvmet_wq, &ctrl->async_event_work) + + nvmet_add_async_event() + queue_work(nvmet_wq, &ctrl->async_event_work) + +B. Full pre-work chain (RDMA CM path): + nvmet_rdma_cm_handler() + nvmet_rdma_queue_disconnect() + __nvmet_rdma_queue_disconnect() + queue_work(nvmet_wq, &queue->release_work) + process_one_work() + lock((wq_completion)nvmet-wq) <--------- 1st + nvmet_rdma_release_queue_work() + +C. Recursive path (same worker): + nvmet_rdma_release_queue_work() + nvmet_rdma_free_queue() + nvmet_sq_destroy() + nvmet_ctrl_put() + nvmet_ctrl_free() + flush_work(&ctrl->async_event_work) + __flush_work() + touch_wq_lockdep_map() + lock((wq_completion)nvmet-wq) <--------- 2nd + +Lockdep splat: + + ============================================ + WARNING: possible recursive locking detected + 6.19.0-rc3nvme+ #14 Tainted: G N + -------------------------------------------- + kworker/u192:42/44933 is trying to acquire lock: + ffff888118a00948 ((wq_completion)nvmet-wq){+.+.}-{0:0}, at: touch_wq_lockdep_map+0x26/0x90 + + but task is already holding lock: + ffff888118a00948 ((wq_completion)nvmet-wq){+.+.}-{0:0}, at: process_one_work+0x53e/0x660 + + 3 locks held by kworker/u192:42/44933: + #0: ffff888118a00948 ((wq_completion)nvmet-wq){+.+.}-{0:0}, at: process_one_work+0x53e/0x660 + #1: ffffc9000e6cbe28 ((work_completion)(&queue->release_work)){+.+.}-{0:0}, at: process_one_work+0x1c5/0x660 + #2: ffffffff82d4db60 (rcu_read_lock){....}-{1:3}, at: __flush_work+0x62/0x530 + + Workqueue: nvmet-wq nvmet_rdma_release_queue_work [nvmet_rdma] + Call Trace: + __flush_work+0x268/0x530 + nvmet_ctrl_free+0x140/0x310 [nvmet] + nvmet_cq_put+0x74/0x90 [nvmet] + nvmet_rdma_free_queue+0x23/0xe0 [nvmet_rdma] + nvmet_rdma_release_queue_work+0x19/0x50 [nvmet_rdma] + process_one_work+0x206/0x660 + worker_thread+0x184/0x320 + kthread+0x10c/0x240 + ret_from_fork+0x319/0x390 + +Move async event work to a dedicated nvmet-aen-wq to avoid reentrant +flush on nvmet-wq. + +Reviewed-by: Christoph Hellwig +Signed-off-by: Chaitanya Kulkarni +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/admin-cmd.c | 2 +- + drivers/nvme/target/core.c | 14 ++++++++++++-- + drivers/nvme/target/nvmet.h | 1 + + drivers/nvme/target/rdma.c | 1 + + 4 files changed, 15 insertions(+), 3 deletions(-) + +diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c +index 3e378153a7817..950b7f8e8ad56 100644 +--- a/drivers/nvme/target/admin-cmd.c ++++ b/drivers/nvme/target/admin-cmd.c +@@ -1586,7 +1586,7 @@ void nvmet_execute_async_event(struct nvmet_req *req) + ctrl->async_event_cmds[ctrl->nr_async_event_cmds++] = req; + mutex_unlock(&ctrl->lock); + +- queue_work(nvmet_wq, &ctrl->async_event_work); ++ queue_work(nvmet_aen_wq, &ctrl->async_event_work); + } + + void nvmet_execute_keep_alive(struct nvmet_req *req) +diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c +index 5d7d483bfbe37..1c5b6bab47791 100644 +--- a/drivers/nvme/target/core.c ++++ b/drivers/nvme/target/core.c +@@ -26,6 +26,8 @@ static DEFINE_IDA(cntlid_ida); + + struct workqueue_struct *nvmet_wq; + EXPORT_SYMBOL_GPL(nvmet_wq); ++struct workqueue_struct *nvmet_aen_wq; ++EXPORT_SYMBOL_GPL(nvmet_aen_wq); + + /* + * This read/write semaphore is used to synchronize access to configuration +@@ -205,7 +207,7 @@ void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type, + list_add_tail(&aen->entry, &ctrl->async_events); + mutex_unlock(&ctrl->lock); + +- queue_work(nvmet_wq, &ctrl->async_event_work); ++ queue_work(nvmet_aen_wq, &ctrl->async_event_work); + } + + static void nvmet_add_to_changed_ns_log(struct nvmet_ctrl *ctrl, __le32 nsid) +@@ -1957,9 +1959,14 @@ static int __init nvmet_init(void) + if (!nvmet_wq) + goto out_free_buffered_work_queue; + ++ nvmet_aen_wq = alloc_workqueue("nvmet-aen-wq", ++ WQ_MEM_RECLAIM | WQ_UNBOUND, 0); ++ if (!nvmet_aen_wq) ++ goto out_free_nvmet_work_queue; ++ + error = nvmet_init_debugfs(); + if (error) +- goto out_free_nvmet_work_queue; ++ goto out_free_nvmet_aen_work_queue; + + error = nvmet_init_discovery(); + if (error) +@@ -1975,6 +1982,8 @@ static int __init nvmet_init(void) + nvmet_exit_discovery(); + out_exit_debugfs: + nvmet_exit_debugfs(); ++out_free_nvmet_aen_work_queue: ++ destroy_workqueue(nvmet_aen_wq); + out_free_nvmet_work_queue: + destroy_workqueue(nvmet_wq); + out_free_buffered_work_queue: +@@ -1992,6 +2001,7 @@ static void __exit nvmet_exit(void) + nvmet_exit_discovery(); + nvmet_exit_debugfs(); + ida_destroy(&cntlid_ida); ++ destroy_workqueue(nvmet_aen_wq); + destroy_workqueue(nvmet_wq); + destroy_workqueue(buffered_io_wq); + destroy_workqueue(zbd_wq); +diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h +index f3b09f4099f08..059fd9f356c45 100644 +--- a/drivers/nvme/target/nvmet.h ++++ b/drivers/nvme/target/nvmet.h +@@ -502,6 +502,7 @@ extern struct kmem_cache *nvmet_bvec_cache; + extern struct workqueue_struct *buffered_io_wq; + extern struct workqueue_struct *zbd_wq; + extern struct workqueue_struct *nvmet_wq; ++extern struct workqueue_struct *nvmet_aen_wq; + + static inline void nvmet_set_result(struct nvmet_req *req, u32 result) + { +diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c +index 0485e25ab797c..284ab759bbce3 100644 +--- a/drivers/nvme/target/rdma.c ++++ b/drivers/nvme/target/rdma.c +@@ -2088,6 +2088,7 @@ static void nvmet_rdma_remove_one(struct ib_device *ib_device, void *client_data + mutex_unlock(&nvmet_rdma_queue_mutex); + + flush_workqueue(nvmet_wq); ++ flush_workqueue(nvmet_aen_wq); + } + + static struct ib_client nvmet_rdma_ib_client = { +-- +2.51.0 + diff --git a/queue-6.18/objtool-handle-clang-rsp-musical-chairs.patch b/queue-6.18/objtool-handle-clang-rsp-musical-chairs.patch new file mode 100644 index 0000000000..fe58098064 --- /dev/null +++ b/queue-6.18/objtool-handle-clang-rsp-musical-chairs.patch @@ -0,0 +1,136 @@ +From 31d6312baaf6fbd6b9ce7fe47194027ca0447c14 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 09:35:06 -0800 +Subject: objtool: Handle Clang RSP musical chairs + +From: Josh Poimboeuf + +[ Upstream commit 7fdaa640c810cb42090a182c33f905bcc47a616a ] + +For no apparent reason (possibly related to CONFIG_KMSAN), Clang can +randomly pass the value of RSP to other registers and then back again to +RSP. Handle that accordingly. + +Fixes the following warnings: + + drivers/input/misc/uinput.o: warning: objtool: uinput_str_to_user+0x165: undefined stack state + drivers/input/misc/uinput.o: warning: objtool: uinput_str_to_user+0x165: unknown CFA base reg -1 + +Reported-by: Arnd Bergmann +Closes: https://lore.kernel.org/90956545-2066-46e3-b547-10c884582eb0@app.fastmail.com +Link: https://patch.msgid.link/240e6a172cc73292499334a3724d02ccb3247fc7.1772818491.git.jpoimboe@kernel.org +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/arch/x86/decode.c | 62 ++++++++++++--------------------- + tools/objtool/check.c | 14 ++++++++ + 2 files changed, 37 insertions(+), 39 deletions(-) + +diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c +index 0ad5cc70ecbe7..fdaddc636e977 100644 +--- a/tools/objtool/arch/x86/decode.c ++++ b/tools/objtool/arch/x86/decode.c +@@ -340,52 +340,36 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec + if (!rex_w) + break; + +- if (modrm_reg == CFI_SP) { +- +- if (mod_is_reg()) { +- /* mov %rsp, reg */ +- ADD_OP(op) { +- op->src.type = OP_SRC_REG; +- op->src.reg = CFI_SP; +- op->dest.type = OP_DEST_REG; +- op->dest.reg = modrm_rm; +- } +- break; +- +- } else { +- /* skip RIP relative displacement */ +- if (is_RIP()) +- break; +- +- /* skip nontrivial SIB */ +- if (have_SIB()) { +- modrm_rm = sib_base; +- if (sib_index != CFI_SP) +- break; +- } +- +- /* mov %rsp, disp(%reg) */ +- ADD_OP(op) { +- op->src.type = OP_SRC_REG; +- op->src.reg = CFI_SP; +- op->dest.type = OP_DEST_REG_INDIRECT; +- op->dest.reg = modrm_rm; +- op->dest.offset = ins.displacement.value; +- } +- break; ++ if (mod_is_reg()) { ++ /* mov reg, reg */ ++ ADD_OP(op) { ++ op->src.type = OP_SRC_REG; ++ op->src.reg = modrm_reg; ++ op->dest.type = OP_DEST_REG; ++ op->dest.reg = modrm_rm; + } +- + break; + } + +- if (rm_is_reg(CFI_SP)) { ++ /* skip RIP relative displacement */ ++ if (is_RIP()) ++ break; + +- /* mov reg, %rsp */ ++ /* skip nontrivial SIB */ ++ if (have_SIB()) { ++ modrm_rm = sib_base; ++ if (sib_index != CFI_SP) ++ break; ++ } ++ ++ /* mov %rsp, disp(%reg) */ ++ if (modrm_reg == CFI_SP) { + ADD_OP(op) { + op->src.type = OP_SRC_REG; +- op->src.reg = modrm_reg; +- op->dest.type = OP_DEST_REG; +- op->dest.reg = CFI_SP; ++ op->src.reg = CFI_SP; ++ op->dest.type = OP_DEST_REG_INDIRECT; ++ op->dest.reg = modrm_rm; ++ op->dest.offset = ins.displacement.value; + } + break; + } +diff --git a/tools/objtool/check.c b/tools/objtool/check.c +index 6059a546fb759..bb34484046060 100644 +--- a/tools/objtool/check.c ++++ b/tools/objtool/check.c +@@ -2902,6 +2902,20 @@ static int update_cfi_state(struct instruction *insn, + cfi->stack_size += 8; + } + ++ else if (cfi->vals[op->src.reg].base == CFI_CFA) { ++ /* ++ * Clang RSP musical chairs: ++ * ++ * mov %rsp, %rdx [handled above] ++ * ... ++ * mov %rdx, %rbx [handled here] ++ * ... ++ * mov %rbx, %rsp [handled above] ++ */ ++ cfi->vals[op->dest.reg].base = CFI_CFA; ++ cfi->vals[op->dest.reg].offset = cfi->vals[op->src.reg].offset; ++ } ++ + + break; + +-- +2.51.0 + diff --git a/queue-6.18/perf-make-sure-to-use-pmu_ctx-pmu-for-groups.patch b/queue-6.18/perf-make-sure-to-use-pmu_ctx-pmu-for-groups.patch new file mode 100644 index 0000000000..9fd7edf54e --- /dev/null +++ b/queue-6.18/perf-make-sure-to-use-pmu_ctx-pmu-for-groups.patch @@ -0,0 +1,99 @@ +From d6001310d8b0980bbc61403b75644a8ca81ad402 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Mar 2026 13:55:46 +0100 +Subject: perf: Make sure to use pmu_ctx->pmu for groups + +From: Peter Zijlstra + +[ Upstream commit 4b9ce671960627b2505b3f64742544ae9801df97 ] + +Oliver reported that x86_pmu_del() ended up doing an out-of-bound memory access +when group_sched_in() fails and needs to roll back. + +This *should* be handled by the transaction callbacks, but he found that when +the group leader is a software event, the transaction handlers of the wrong PMU +are used. Despite the move_group case in perf_event_open() and group_sched_in() +using pmu_ctx->pmu. + +Turns out, inherit uses event->pmu to clone the events, effectively undoing the +move_group case for all inherited contexts. Fix this by also making inherit use +pmu_ctx->pmu, ensuring all inherited counters end up in the same pmu context. + +Similarly, __perf_event_read() should use equally use pmu_ctx->pmu for the +group case. + +Fixes: bd2756811766 ("perf: Rewrite core context handling") +Reported-by: Oliver Rosenberg +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Ian Rogers +Link: https://patch.msgid.link/20260309133713.GB606826@noisy.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + kernel/events/core.c | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index b7e73ac3e512f..6b6fea8d33e04 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -4671,7 +4671,7 @@ static void __perf_event_read(void *info) + struct perf_event *sub, *event = data->event; + struct perf_event_context *ctx = event->ctx; + struct perf_cpu_context *cpuctx = this_cpu_ptr(&perf_cpu_context); +- struct pmu *pmu = event->pmu; ++ struct pmu *pmu; + + /* + * If this is a task context, we need to check whether it is +@@ -4683,7 +4683,7 @@ static void __perf_event_read(void *info) + if (ctx->task && cpuctx->task_ctx != ctx) + return; + +- raw_spin_lock(&ctx->lock); ++ guard(raw_spinlock)(&ctx->lock); + ctx_time_update_event(ctx, event); + + perf_event_update_time(event); +@@ -4691,25 +4691,22 @@ static void __perf_event_read(void *info) + perf_event_update_sibling_time(event); + + if (event->state != PERF_EVENT_STATE_ACTIVE) +- goto unlock; ++ return; + + if (!data->group) { +- pmu->read(event); ++ perf_pmu_read(event); + data->ret = 0; +- goto unlock; ++ return; + } + ++ pmu = event->pmu_ctx->pmu; + pmu->start_txn(pmu, PERF_PMU_TXN_READ); + +- pmu->read(event); +- ++ perf_pmu_read(event); + for_each_sibling_event(sub, event) + perf_pmu_read(sub); + + data->ret = pmu->commit_txn(pmu); +- +-unlock: +- raw_spin_unlock(&ctx->lock); + } + + static inline u64 perf_event_count(struct perf_event *event, bool self) +@@ -14390,7 +14387,7 @@ inherit_event(struct perf_event *parent_event, + get_ctx(child_ctx); + child_event->ctx = child_ctx; + +- pmu_ctx = find_get_pmu_context(child_event->pmu, child_ctx, child_event); ++ pmu_ctx = find_get_pmu_context(parent_event->pmu_ctx->pmu, child_ctx, child_event); + if (IS_ERR(pmu_ctx)) { + free_event(child_event); + return ERR_CAST(pmu_ctx); +-- +2.51.0 + diff --git a/queue-6.18/platform-x86-hp-wmi-add-omen-16-wf0xxx-fan-and-therm.patch b/queue-6.18/platform-x86-hp-wmi-add-omen-16-wf0xxx-fan-and-therm.patch new file mode 100644 index 0000000000..d059d8f25b --- /dev/null +++ b/queue-6.18/platform-x86-hp-wmi-add-omen-16-wf0xxx-fan-and-therm.patch @@ -0,0 +1,53 @@ +From fd7bb2b12a4070d5b5d9eb2e3fa02ed2733686b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 12:50:03 +0530 +Subject: platform/x86: hp-wmi: Add Omen 16-wf0xxx fan and thermal support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Krishna Chomal + +[ Upstream commit 13fa3aaf02edaad9b41fc61d7f6326d2b6a4bf80 ] + +The HP Omen 16-wf0xxx (board ID: 8BAB) has the same WMI interface as +other Victus S boards, but requires quirks for correctly switching +thermal profile (similar to HP Omen 16-wf1xxx, board ID: 8C78). + +Add the DMI board name to victus_s_thermal_profile_boards[] table and +map it to omen_v1_thermal_params. + +Testing on HP Omen 16-wf0xxx confirmed that platform profile is +registered successfully and fan RPMs are readable and controllable. + +Suggested-by: Noah Provenzano +Tested-by: Juan Martin Morales +Reported-by: Juan Martin Morales +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220639 +Signed-off-by: Krishna Chomal +Link: https://patch.msgid.link/20260216072003.90151-1-krishna.chomal108@gmail.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/hp/hp-wmi.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c +index dfe45692c956a..244833fd785f3 100644 +--- a/drivers/platform/x86/hp/hp-wmi.c ++++ b/drivers/platform/x86/hp/hp-wmi.c +@@ -154,6 +154,10 @@ static const char * const victus_thermal_profile_boards[] = { + + /* DMI Board names of Victus 16-r and Victus 16-s laptops */ + static const struct dmi_system_id victus_s_thermal_profile_boards[] __initconst = { ++ { ++ .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BAB") }, ++ .driver_data = (void *)&omen_v1_thermal_params, ++ }, + { + .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BBE") }, + .driver_data = (void *)&victus_s_thermal_params, +-- +2.51.0 + diff --git a/queue-6.18/platform-x86-hp-wmi-add-omen-16-xd0xxx-fan-and-therm.patch b/queue-6.18/platform-x86-hp-wmi-add-omen-16-xd0xxx-fan-and-therm.patch new file mode 100644 index 0000000000..ec403a0bac --- /dev/null +++ b/queue-6.18/platform-x86-hp-wmi-add-omen-16-xd0xxx-fan-and-therm.patch @@ -0,0 +1,50 @@ +From 26848484bd325890ae2748b5312f79478df5c26b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 10:32:35 +0530 +Subject: platform/x86: hp-wmi: Add Omen 16-xd0xxx fan and thermal support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Krishna Chomal + +[ Upstream commit 3c99a545b372c77b5d39715968a141f523eccbf2 ] + +The HP Omen 16-xd0xxx (board ID: 8BCD) has the same WMI interface as +other Victus S boards, but requires quirks for correctly switching +thermal profile (similar to HP Omen 16-wf1xxx, board ID: 8C78). + +Add the DMI board name to victus_s_thermal_profile_boards[] table and +map it to omen_v1_thermal_params. + +Testing on HP Omen 16-xd0xxx confirmed that platform profile is +registered successfully and fan RPMs are readable and controllable. + +Tested-by: Varad Amol Pisale +Signed-off-by: Krishna Chomal +Link: https://patch.msgid.link/20260218050235.94687-1-krishna.chomal108@gmail.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/hp/hp-wmi.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c +index 244833fd785f3..008f3364230e2 100644 +--- a/drivers/platform/x86/hp/hp-wmi.c ++++ b/drivers/platform/x86/hp/hp-wmi.c +@@ -162,6 +162,10 @@ static const struct dmi_system_id victus_s_thermal_profile_boards[] __initconst + .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BBE") }, + .driver_data = (void *)&victus_s_thermal_params, + }, ++ { ++ .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BCD") }, ++ .driver_data = (void *)&omen_v1_thermal_params, ++ }, + { + .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BD4") }, + .driver_data = (void *)&victus_s_thermal_params, +-- +2.51.0 + diff --git a/queue-6.18/platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch b/queue-6.18/platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch new file mode 100644 index 0000000000..40e128ec85 --- /dev/null +++ b/queue-6.18/platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch @@ -0,0 +1,51 @@ +From e56f35ca07563ead06449652c74d5b26173b0d9b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 23:46:27 -0500 +Subject: platform/x86: intel-hid: Add Dell 14 Plus 2-in-1 to + dmi_vgbs_allow_list +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Peter Metz + +[ Upstream commit 6b3fa0615cd8432148581de62a52f83847af3d70 ] + +The Dell 14 Plus 2-in-1 (model DB04250) requires the VGBS allow list +entry to correctly enable the tablet mode switch. Without this, the +chassis state is not reported, and the hinge rotation only emits +unknown scancodes. + +Verified on Dell 14 Plus 2-in-1 DB04250. + +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221090 +Signed-off-by: Peter Metz +Reviewed-by: Hans de Goede +Link: https://patch.msgid.link/20260213044627.203638-1-peter.metz@unarin.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/intel/hid.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c +index 560cc063198e1..5b475a09645a3 100644 +--- a/drivers/platform/x86/intel/hid.c ++++ b/drivers/platform/x86/intel/hid.c +@@ -189,6 +189,12 @@ static const struct dmi_system_id dmi_vgbs_allow_list[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Dell Pro Rugged 12 Tablet RA02260"), + }, + }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Dell 14 Plus 2-in-1 DB04250"), ++ }, ++ }, + { } + }; + +-- +2.51.0 + diff --git a/queue-6.18/platform-x86-intel-hid-enable-5-button-array-on-thin.patch b/queue-6.18/platform-x86-intel-hid-enable-5-button-array-on-thin.patch new file mode 100644 index 0000000000..ed8f8e0f85 --- /dev/null +++ b/queue-6.18/platform-x86-intel-hid-enable-5-button-array-on-thin.patch @@ -0,0 +1,52 @@ +From ed032d4978259b20e66cb981bdd912bc378b928a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 09:56:25 +0100 +Subject: platform/x86: intel-hid: Enable 5-button array on ThinkPad X1 Fold 16 + Gen 1 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Leif Skunberg + +[ Upstream commit b38d478dad79e61e8a65931021bdfd7a71741212 ] + +The Lenovo ThinkPad X1 Fold 16 Gen 1 has physical volume up/down +buttons that are handled through the intel-hid 5-button array +interface. The firmware does not advertise 5-button array support via +HEBC, so the driver relies on a DMI allowlist to enable it. + +Add the ThinkPad X1 Fold 16 Gen 1 to the button_array_table so the +volume buttons work out of the box. + +Signed-off-by: Leif Skunberg +Reviewed-by: Hans de Goede +Link: https://patch.msgid.link/20260210085625.34380-1-diamondback@cohunt.app +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/intel/hid.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c +index 5b475a09645a3..f2b309f6e458a 100644 +--- a/drivers/platform/x86/intel/hid.c ++++ b/drivers/platform/x86/intel/hid.c +@@ -135,6 +135,13 @@ static const struct dmi_system_id button_array_table[] = { + DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Tablet Gen 2"), + }, + }, ++ { ++ .ident = "Lenovo ThinkPad X1 Fold 16 Gen 1", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Fold 16 Gen 1"), ++ }, ++ }, + { + .ident = "Microsoft Surface Go 3", + .matches = { +-- +2.51.0 + diff --git a/queue-6.18/platform-x86-oxpec-add-support-for-aokzoe-a2-pro.patch b/queue-6.18/platform-x86-oxpec-add-support-for-aokzoe-a2-pro.patch new file mode 100644 index 0000000000..a666e8f361 --- /dev/null +++ b/queue-6.18/platform-x86-oxpec-add-support-for-aokzoe-a2-pro.patch @@ -0,0 +1,46 @@ +From 41226cc37e10d05d5117bd6081d4451e79332a45 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Feb 2026 19:29:53 +0100 +Subject: platform/x86: oxpec: Add support for Aokzoe A2 Pro +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Antheas Kapenekakis + +[ Upstream commit cd0883055b04586770dab43c64159348bf480a3e ] + +Aokzoe A2 Pro is an older device that the oxpec driver is missing the +quirk for. It has the same behavior as the AOKZOE A1 devices. Add a +quirk for it to the oxpec driver. + +Signed-off-by: Antheas Kapenekakis +Link: https://patch.msgid.link/20260223183004.2696892-5-lkml@antheas.dev +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/oxpec.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c +index bf07732776ca9..d66c9c0003585 100644 +--- a/drivers/platform/x86/oxpec.c ++++ b/drivers/platform/x86/oxpec.c +@@ -124,6 +124,13 @@ static const struct dmi_system_id dmi_table[] = { + }, + .driver_data = (void *)aok_zoe_a1, + }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "AOKZOE"), ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "AOKZOE A2 Pro"), ++ }, ++ .driver_data = (void *)aok_zoe_a1, ++ }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "AOKZOE"), +-- +2.51.0 + diff --git a/queue-6.18/platform-x86-oxpec-add-support-for-onexplayer-apex.patch b/queue-6.18/platform-x86-oxpec-add-support-for-onexplayer-apex.patch new file mode 100644 index 0000000000..aae69624ad --- /dev/null +++ b/queue-6.18/platform-x86-oxpec-add-support-for-onexplayer-apex.patch @@ -0,0 +1,54 @@ +From 1fd030cca784703db7ed0f421326376d7f9f6693 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Feb 2026 19:29:50 +0100 +Subject: platform/x86: oxpec: Add support for OneXPlayer APEX +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Antheas Kapenekakis + +[ Upstream commit 3385ea97c14d271dcb0c6e6fcf16972f819eecd8 ] + +OneXPlayer Apex is a new Strix Halo handheld. It uses the same registers +as the OneXPlayer Fly devices. Add a quirk for it to the oxpec driver. + +Signed-off-by: Antheas Kapenekakis +Link: https://patch.msgid.link/20260223183004.2696892-2-lkml@antheas.dev +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/oxpec.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c +index 54377b282ff88..9511791f04d9a 100644 +--- a/drivers/platform/x86/oxpec.c ++++ b/drivers/platform/x86/oxpec.c +@@ -13,7 +13,7 @@ + * + * Copyright (C) 2022 Joaquín I. Aramendía + * Copyright (C) 2024 Derek J. Clark +- * Copyright (C) 2025 Antheas Kapenekakis ++ * Copyright (C) 2025-2026 Antheas Kapenekakis + */ + + #include +@@ -208,6 +208,13 @@ static const struct dmi_system_id dmi_table[] = { + }, + .driver_data = (void *)oxp_2, + }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER APEX"), ++ }, ++ .driver_data = (void *)oxp_fly, ++ }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), +-- +2.51.0 + diff --git a/queue-6.18/platform-x86-oxpec-add-support-for-onexplayer-x1-air.patch b/queue-6.18/platform-x86-oxpec-add-support-for-onexplayer-x1-air.patch new file mode 100644 index 0000000000..fc644cc427 --- /dev/null +++ b/queue-6.18/platform-x86-oxpec-add-support-for-onexplayer-x1-air.patch @@ -0,0 +1,45 @@ +From a6127eac563517e0d4943e9bcd05cc0f99ea59d9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Feb 2026 19:29:52 +0100 +Subject: platform/x86: oxpec: Add support for OneXPlayer X1 Air +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Antheas Kapenekakis + +[ Upstream commit 2a3b4a8c10a64a62c4243007139d253dc1324dfd ] + +X1 Air is an X1 variant with a newer Intel chipset. It uses the same +registers as the X1. Add a quirk for it to the oxpec driver. + +Signed-off-by: Antheas Kapenekakis +Link: https://patch.msgid.link/20260223183004.2696892-4-lkml@antheas.dev +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/oxpec.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c +index d66c9c0003585..a30845ba37969 100644 +--- a/drivers/platform/x86/oxpec.c ++++ b/drivers/platform/x86/oxpec.c +@@ -313,6 +313,13 @@ static const struct dmi_system_id dmi_table[] = { + }, + .driver_data = (void *)oxp_x1, + }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER X1Air"), ++ }, ++ .driver_data = (void *)oxp_x1, ++ }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), +-- +2.51.0 + diff --git a/queue-6.18/platform-x86-oxpec-add-support-for-onexplayer-x1z.patch b/queue-6.18/platform-x86-oxpec-add-support-for-onexplayer-x1z.patch new file mode 100644 index 0000000000..d60be74a02 --- /dev/null +++ b/queue-6.18/platform-x86-oxpec-add-support-for-onexplayer-x1z.patch @@ -0,0 +1,45 @@ +From 139af9202b85091b3d501b93fac542fb13d60c64 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Feb 2026 19:29:51 +0100 +Subject: platform/x86: oxpec: Add support for OneXPlayer X1z +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Antheas Kapenekakis + +[ Upstream commit 4049c46edb5d44c0de045f6f504371705dd603dd ] + +X1z is a variant of OneXPlayer X1 A with 8840U. It seems that only one +user has this one. Add a quirk for it to the oxpec driver. + +Signed-off-by: Antheas Kapenekakis +Link: https://patch.msgid.link/20260223183004.2696892-3-lkml@antheas.dev +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/oxpec.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c +index 9511791f04d9a..bf07732776ca9 100644 +--- a/drivers/platform/x86/oxpec.c ++++ b/drivers/platform/x86/oxpec.c +@@ -285,6 +285,13 @@ static const struct dmi_system_id dmi_table[] = { + }, + .driver_data = (void *)oxp_mini_amd_pro, + }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER X1z"), ++ }, ++ .driver_data = (void *)oxp_x1, ++ }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), +-- +2.51.0 + diff --git a/queue-6.18/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch b/queue-6.18/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch new file mode 100644 index 0000000000..b4afd9b596 --- /dev/null +++ b/queue-6.18/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch @@ -0,0 +1,71 @@ +From cb8512d10035a7c4c7f46b705f7f4d1973c2820f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 14:23:46 +0100 +Subject: platform/x86: touchscreen_dmi: Add quirk for y-inverted Goodix + touchscreen on SUPI S10 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Hans de Goede + +[ Upstream commit 7d87ed70fc95482c12edf9493c249b6413be485e ] + +The touchscreen on the SUPI S10 tablet reports inverted Y coordinates, +causing touch input to be mirrored vertically relative to the display. + +Add a quirk to set the "touchscreen-inverted-y" boolean device-property +on the touchscreen device, so that the goodix_ts driver will fixup +the coordinates. + +Reported-by: Yajat Kumar +Closes: https://lore.kernel.org/linux-input/20251230221639.582406-1-yajatapps3@gmail.com/ +Tested-by: Yajat Kumar +Signed-off-by: Hans de Goede +Link: https://patch.msgid.link/20260217132346.34535-1-johannes.goede@oss.qualcomm.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/touchscreen_dmi.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c +index bdc19cd8d3edf..d83c387821ea1 100644 +--- a/drivers/platform/x86/touchscreen_dmi.c ++++ b/drivers/platform/x86/touchscreen_dmi.c +@@ -410,6 +410,16 @@ static const struct ts_dmi_data gdix1002_upside_down_data = { + .properties = gdix1001_upside_down_props, + }; + ++static const struct property_entry gdix1001_y_inverted_props[] = { ++ PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), ++ { } ++}; ++ ++static const struct ts_dmi_data gdix1001_y_inverted_data = { ++ .acpi_name = "GDIX1001", ++ .properties = gdix1001_y_inverted_props, ++}; ++ + static const struct property_entry gp_electronic_t701_props[] = { + PROPERTY_ENTRY_U32("touchscreen-size-x", 960), + PROPERTY_ENTRY_U32("touchscreen-size-y", 640), +@@ -1658,6 +1668,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_SKU, "PN20170413488"), + }, + }, ++ { ++ /* SUPI S10 */ ++ .driver_data = (void *)&gdix1001_y_inverted_data, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "SUPI"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "S10"), ++ }, ++ }, + { + /* Techbite Arc 11.6 */ + .driver_data = (void *)&techbite_arc_11_6_data, +-- +2.51.0 + diff --git a/queue-6.18/powerpc64-ftrace-fix-ool-stub-count-with-clang.patch b/queue-6.18/powerpc64-ftrace-fix-ool-stub-count-with-clang.patch new file mode 100644 index 0000000000..221bddd209 --- /dev/null +++ b/queue-6.18/powerpc64-ftrace-fix-ool-stub-count-with-clang.patch @@ -0,0 +1,47 @@ +From 34bcc67731a5ab99f929146bb632701853515d15 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Jan 2026 14:19:25 +0530 +Subject: powerpc64/ftrace: fix OOL stub count with clang + +From: Hari Bathini + +[ Upstream commit 875612a7745013a43c67493cb0583ee3f7476344 ] + +The total number of out-of-line (OOL) stubs required for function +tracing is determined using the following command: + + $(OBJDUMP) -r -j __patchable_function_entries vmlinux.o + +While this works correctly with GNU objdump, llvm-objdump does not +list the expected relocation records for this section. Fix this by +using the -d option and counting R_PPC64_ADDR64 relocation entries. +This works as desired with both objdump and llvm-objdump. + +Signed-off-by: Hari Bathini +Tested-by: Venkat Rao Bagalkote +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20260127084926.34497-3-hbathini@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/tools/ftrace-gen-ool-stubs.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/powerpc/tools/ftrace-gen-ool-stubs.sh b/arch/powerpc/tools/ftrace-gen-ool-stubs.sh +index bac186bdf64a7..9218d43aeb548 100755 +--- a/arch/powerpc/tools/ftrace-gen-ool-stubs.sh ++++ b/arch/powerpc/tools/ftrace-gen-ool-stubs.sh +@@ -15,9 +15,9 @@ if [ -z "$is_64bit" ]; then + RELOCATION=R_PPC_ADDR32 + fi + +-num_ool_stubs_total=$($objdump -r -j __patchable_function_entries "$vmlinux_o" | ++num_ool_stubs_total=$($objdump -r -j __patchable_function_entries -d "$vmlinux_o" | + grep -c "$RELOCATION") +-num_ool_stubs_inittext=$($objdump -r -j __patchable_function_entries "$vmlinux_o" | ++num_ool_stubs_inittext=$($objdump -r -j __patchable_function_entries -d "$vmlinux_o" | + grep -e ".init.text" -e ".text.startup" | grep -c "$RELOCATION") + num_ool_stubs_text=$((num_ool_stubs_total - num_ool_stubs_inittext)) + +-- +2.51.0 + diff --git a/queue-6.18/s390-mm-add-missing-secure-storage-access-fixups-for.patch b/queue-6.18/s390-mm-add-missing-secure-storage-access-fixups-for.patch new file mode 100644 index 0000000000..56b2e5e3b3 --- /dev/null +++ b/queue-6.18/s390-mm-add-missing-secure-storage-access-fixups-for.patch @@ -0,0 +1,63 @@ +From 2d89dc03566b71e27784d13620e148667255bcb9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Mar 2026 10:18:37 +0000 +Subject: s390/mm: Add missing secure storage access fixups for donated memory + +From: Janosch Frank + +[ Upstream commit b00be77302d7ec4ad0367bb236494fce7172b730 ] + +There are special cases where secure storage access exceptions happen +in a kernel context for pages that don't have the PG_arch_1 bit +set. That bit is set for non-exported guest secure storage (memory) +but is absent on storage donated to the Ultravisor since the kernel +isn't allowed to export donated pages. + +Prior to this patch we would try to export the page by calling +arch_make_folio_accessible() which would instantly return since the +arch bit is absent signifying that the page was already exported and +no further action is necessary. This leads to secure storage access +exception loops which can never be resolved. + +With this patch we unconditionally try to export and if that fails we +fixup. + +Fixes: 084ea4d611a3 ("s390/mm: add (non)secure page access exceptions handlers") +Reported-by: Heiko Carstens +Suggested-by: Heiko Carstens +Reviewed-by: Claudio Imbrenda +Tested-by: Christian Borntraeger +Signed-off-by: Janosch Frank +Signed-off-by: Christian Borntraeger +Signed-off-by: Sasha Levin +--- + arch/s390/mm/fault.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c +index e1ad05bfd28ad..d1f165048055b 100644 +--- a/arch/s390/mm/fault.c ++++ b/arch/s390/mm/fault.c +@@ -436,10 +436,17 @@ void do_secure_storage_access(struct pt_regs *regs) + folio = phys_to_folio(addr); + if (unlikely(!folio_try_get(folio))) + return; +- rc = arch_make_folio_accessible(folio); ++ rc = uv_convert_from_secure(folio_to_phys(folio)); ++ if (!rc) ++ clear_bit(PG_arch_1, &folio->flags.f); + folio_put(folio); ++ /* ++ * There are some valid fixup types for kernel ++ * accesses to donated secure memory. zeropad is one ++ * of them. ++ */ + if (rc) +- BUG(); ++ return handle_fault_error_nolock(regs, 0); + } else { + if (faulthandler_disabled()) + return handle_fault_error_nolock(regs, 0); +-- +2.51.0 + diff --git a/queue-6.18/sched_ext-use-write_once-for-the-write-side-of-dsq-s.patch b/queue-6.18/sched_ext-use-write_once-for-the-write-side-of-dsq-s.patch new file mode 100644 index 0000000000..44f6e688f2 --- /dev/null +++ b/queue-6.18/sched_ext-use-write_once-for-the-write-side-of-dsq-s.patch @@ -0,0 +1,53 @@ +From 6411072bbd8b5583140313f5fec9f20916cf9cd9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Mar 2026 13:37:30 +0800 +Subject: sched_ext: Use WRITE_ONCE() for the write side of dsq->seq update + +From: zhidao su + +[ Upstream commit 7a8464555d2e5f038758bb19e72ab4710b79e9cd ] + +bpf_iter_scx_dsq_new() reads dsq->seq via READ_ONCE() without holding +any lock, making dsq->seq a lock-free concurrently accessed variable. +However, dispatch_enqueue(), the sole writer of dsq->seq, uses a plain +increment without the matching WRITE_ONCE() on the write side: + + dsq->seq++; + ^^^^^^^^^^^ + plain write -- KCSAN data race + +The KCSAN documentation requires that if one accessor uses READ_ONCE() +or WRITE_ONCE() on a variable to annotate lock-free access, all other +accesses must also use the appropriate accessor. A plain write leaves +the pair incomplete and will trigger KCSAN warnings. + +Fix by using WRITE_ONCE() for the write side of the update: + + WRITE_ONCE(dsq->seq, dsq->seq + 1); + +This is consistent with bpf_iter_scx_dsq_new() and makes the +concurrent access annotation complete and KCSAN-clean. + +Signed-off-by: zhidao su +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/sched/ext.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c +index 4e3f06c19ab46..bf4bea3595cd0 100644 +--- a/kernel/sched/ext.c ++++ b/kernel/sched/ext.c +@@ -1019,7 +1019,7 @@ static void dispatch_enqueue(struct scx_sched *sch, struct scx_dispatch_q *dsq, + } + + /* seq records the order tasks are queued, used by BPF DSQ iterator */ +- dsq->seq++; ++ WRITE_ONCE(dsq->seq, dsq->seq + 1); + p->scx.dsq_seq = dsq->seq; + + dsq_mod_nr(dsq, 1); +-- +2.51.0 + diff --git a/queue-6.18/scsi-devinfo-add-blist_skip_io_hints-for-iomega-zip.patch b/queue-6.18/scsi-devinfo-add-blist_skip_io_hints-for-iomega-zip.patch new file mode 100644 index 0000000000..cd3ce24c62 --- /dev/null +++ b/queue-6.18/scsi-devinfo-add-blist_skip_io_hints-for-iomega-zip.patch @@ -0,0 +1,44 @@ +From 4b900ec678274df63218ca00222d91e932525c04 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Feb 2026 19:18:23 +0100 +Subject: scsi: devinfo: Add BLIST_SKIP_IO_HINTS for Iomega ZIP + +From: Florian Fuchs + +[ Upstream commit 80bf3b28d32b431f84f244a8469488eb6d96afbb ] + +The Iomega ZIP 100 (Z100P2) can't process IO Advice Hints Grouping mode +page query. It immediately switches to the status phase 0xb8 after +receiving the subpage code 0x05 of MODE_SENSE_10 command, which fails +imm_out() and turns into DID_ERROR of this command, which leads to unusable +device. This was tested with an Iomega ZIP 100 (Z100P2) connected with a +StarTech PEX1P2 AX99100 PCIe parallel port card. + +Prior to this fix, Test Unit Ready fails and the drive can't be used: + IMM: returned SCSI status b8 + sd 7:0:6:0: [sdh] Test Unit Ready failed: Result: hostbyte=0x01 driverbyte=DRIVER_OK + +Signed-off-by: Florian Fuchs +Link: https://patch.msgid.link/20260227181823.892932-1-fuchsfl@gmail.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/scsi_devinfo.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c +index 78346b2b69c91..c51146882a1fa 100644 +--- a/drivers/scsi/scsi_devinfo.c ++++ b/drivers/scsi/scsi_devinfo.c +@@ -190,7 +190,7 @@ static struct { + {"IBM", "2076", NULL, BLIST_NO_VPD_SIZE}, + {"IBM", "2105", NULL, BLIST_RETRY_HWERROR}, + {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN}, +- {"IOMEGA", "ZIP", NULL, BLIST_NOTQ | BLIST_NOLUN}, ++ {"IOMEGA", "ZIP", NULL, BLIST_NOTQ | BLIST_NOLUN | BLIST_SKIP_IO_HINTS}, + {"IOMEGA", "Io20S *F", NULL, BLIST_KEY}, + {"INSITE", "Floptical F*8I", NULL, BLIST_KEY}, + {"INSITE", "I325VM", NULL, BLIST_KEY}, +-- +2.51.0 + diff --git a/queue-6.18/scsi-mpi3mr-clear-reset-history-on-ready-and-recheck.patch b/queue-6.18/scsi-mpi3mr-clear-reset-history-on-ready-and-recheck.patch new file mode 100644 index 0000000000..4fbe60dfeb --- /dev/null +++ b/queue-6.18/scsi-mpi3mr-clear-reset-history-on-ready-and-recheck.patch @@ -0,0 +1,59 @@ +From a3ec3065612033b268de2cb4ab0951994e6cea17 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Feb 2026 13:56:22 +0530 +Subject: scsi: mpi3mr: Clear reset history on ready and recheck state after + timeout + +From: Ranjan Kumar + +[ Upstream commit dbd53975ed4132d161b6a97ebe785a262380182d ] + +The driver retains reset history even after the IOC has successfully +reached the READY state. That leaves stale reset information active during +normal operation and can mislead recovery and diagnostics. In addition, if +the IOC becomes READY just as the ready timeout loop exits, the driver +still follows the failure path and may retry or report failure incorrectly. + +Clear reset history once READY is confirmed so driver state matches actual +IOC status. After the timeout loop, recheck the IOC state and treat READY +as success instead of failing. + +Signed-off-by: Ranjan Kumar +Link: https://patch.msgid.link/20260225082622.82588-1-ranjan.kumar@broadcom.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/mpi3mr/mpi3mr_fw.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c +index 8382afed12813..4c8d78b840fc9 100644 +--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c ++++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c +@@ -1530,6 +1530,7 @@ static int mpi3mr_bring_ioc_ready(struct mpi3mr_ioc *mrioc) + ioc_info(mrioc, + "successfully transitioned to %s state\n", + mpi3mr_iocstate_name(ioc_state)); ++ mpi3mr_clear_reset_history(mrioc); + return 0; + } + ioc_status = readl(&mrioc->sysif_regs->ioc_status); +@@ -1549,6 +1550,15 @@ static int mpi3mr_bring_ioc_ready(struct mpi3mr_ioc *mrioc) + elapsed_time_sec = jiffies_to_msecs(jiffies - start_time)/1000; + } while (elapsed_time_sec < mrioc->ready_timeout); + ++ ioc_state = mpi3mr_get_iocstate(mrioc); ++ if (ioc_state == MRIOC_STATE_READY) { ++ ioc_info(mrioc, ++ "successfully transitioned to %s state after %llu seconds\n", ++ mpi3mr_iocstate_name(ioc_state), elapsed_time_sec); ++ mpi3mr_clear_reset_history(mrioc); ++ return 0; ++ } ++ + out_failed: + elapsed_time_sec = jiffies_to_msecs(jiffies - start_time)/1000; + if ((retry < 2) && (elapsed_time_sec < (mrioc->ready_timeout - 60))) { +-- +2.51.0 + diff --git a/queue-6.18/series b/queue-6.18/series new file mode 100644 index 0000000000..343f9a8f1f --- /dev/null +++ b/queue-6.18/series @@ -0,0 +1,67 @@ +cxl-port-fix-use-after-free-of-parent_port-in-cxl_de.patch +bpf-reset-register-id-for-bpf_end-value-tracking.patch +bpf-fix-constant-blinding-for-probe_mem32-stores.patch +x86-perf-make-sure-to-program-the-counter-value-for-.patch +perf-make-sure-to-use-pmu_ctx-pmu-for-groups.patch +s390-mm-add-missing-secure-storage-access-fixups-for.patch +cxl-hdm-avoid-incorrect-dvsec-fallback-when-hdm-deco.patch +hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch +sh-platform_early-remove-pdev-driver_override-check.patch +driver-core-generalize-driver_override-in-struct-dev.patch +driver-core-platform-use-generic-driver_override-inf.patch +bpf-release-module-btf-idr-before-module-unload.patch +cxl-adjust-the-startup-priority-of-cxl_pmem-to-be-hi.patch +bpf-fix-exception-exit-lock-checking-for-subprogs.patch +bpf-fix-undefined-behavior-in-interpreter-sdiv-smod-.patch +bpf-fix-unsound-scalar-forking-in-maybe_fork_scalars.patch +tracing-revert-tracing-remove-pid-in-task_rename-tra.patch +platform-x86-hp-wmi-add-omen-16-wf0xxx-fan-and-therm.patch +hid-asus-avoid-memory-leak-in-asus_report_fixup.patch +platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch +nvme-pci-cap-queue-creation-to-used-queues.patch +nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch +platform-x86-hp-wmi-add-omen-16-xd0xxx-fan-and-therm.patch +platform-x86-intel-hid-enable-5-button-array-on-thin.patch +platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch +nvme-pci-ensure-we-re-polling-a-polled-queue.patch +hid-magicmouse-fix-battery-reporting-for-apple-magic.patch +hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch +hid-intel-ish-hid-ipc-add-nova-lake-h-s-pci-device-i.patch +platform-x86-oxpec-add-support-for-onexplayer-apex.patch +hid-apple-add-epomaker-th87-to-the-non-apple-keyboar.patch +platform-x86-oxpec-add-support-for-onexplayer-x1z.patch +net-usb-r8152-add-trendnet-tuc-et2g.patch +kbuild-install-extmod-build-package-resolve_btfids-i.patch +platform-x86-oxpec-add-support-for-aokzoe-a2-pro.patch +platform-x86-oxpec-add-support-for-onexplayer-x1-air.patch +hid-mcp2221-cancel-last-i2c-command-on-read-error.patch +hid-asus-add-xg-mobile-2023-external-hardware-suppor.patch +module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch +asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch +scsi-mpi3mr-clear-reset-history-on-ready-and-recheck.patch +asoc-rt1321-fix-dmic-ch2-3-mask-issue.patch +scsi-devinfo-add-blist_skip_io_hints-for-iomega-zip.patch +asoc-intel-sof_sdw-add-quirk-for-alienware-area-51-2.patch +alsa-hda-hdmi-add-tegra238-hda-codec-device-id.patch +asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-30095 +asoc-cs35l56-only-patch-asp-registers-if-the-dai-is-.patch +dma-buf-include-ioctl.h-in-uapi-header.patch +block-break-pcpu_alloc_mutex-dependency-on-freeze_lo.patch +alsa-hda-senary-ensure-eapd-is-enabled-during-init.patch +drm-ttm-tests-fix-build-failure-on-preempt_rt.patch +asoc-amd-acp-add-acp6.3-match-entries-for-cirrus-log.patch +bpf-fix-u32-s32-bounds-when-ranges-cross-min-max-bou.patch +hid-apple-avoid-memory-leak-in-apple_report_fixup.patch +sched_ext-use-write_once-for-the-write-side-of-dsq-s.patch +btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch +powerpc64-ftrace-fix-ool-stub-count-with-clang.patch +alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch +alsa-hda-realtek-add-quirk-for-gigabyte-technology-t.patch +alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch +objtool-handle-clang-rsp-musical-chairs.patch +nvmet-move-async-event-work-off-nvmet-wq.patch +drm-amdgpu-fix-gpu-idle-power-consumption-issue-for-.patch +usb-core-new-quirk-to-handle-devices-with-zero-confi.patch +spi-intel-pci-add-support-for-nova-lake-mobile-spi-f.patch +alsa-hda-realtek-add-quirk-for-asus-um6702rc.patch +i3c-master-dw-i3c-fix-missing-of_node-for-virtual-i2.patch diff --git a/queue-6.18/sh-platform_early-remove-pdev-driver_override-check.patch b/queue-6.18/sh-platform_early-remove-pdev-driver_override-check.patch new file mode 100644 index 0000000000..cacc28dc7f --- /dev/null +++ b/queue-6.18/sh-platform_early-remove-pdev-driver_override-check.patch @@ -0,0 +1,45 @@ +From e8f5d160ccdcf37ba2c0f5fdcbefd353828909b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Mar 2026 00:37:15 +0100 +Subject: sh: platform_early: remove pdev->driver_override check + +From: Danilo Krummrich + +[ Upstream commit c5f60e3f07b6609562d21efda878e83ce8860728 ] + +In commit 507fd01d5333 ("drivers: move the early platform device support to +arch/sh") platform_match() was copied over to the sh platform_early +code, accidentally including the driver_override check. + +This check does not make sense for platform_early, as sysfs is not even +available in first place at this point in the boot process, hence remove +the check. + +Reviewed-by: Greg Kroah-Hartman +Reviewed-by: Geert Uytterhoeven +Fixes: 507fd01d5333 ("drivers: move the early platform device support to arch/sh") +Link: https://lore.kernel.org/all/DH4M3DJ4P58T.1BGVAVXN71Z09@kernel.org/ +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + arch/sh/drivers/platform_early.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c +index 143747c45206f..48ddbc547bd9a 100644 +--- a/arch/sh/drivers/platform_early.c ++++ b/arch/sh/drivers/platform_early.c +@@ -26,10 +26,6 @@ static int platform_match(struct device *dev, struct device_driver *drv) + struct platform_device *pdev = to_platform_device(dev); + struct platform_driver *pdrv = to_platform_driver(drv); + +- /* When driver_override is set, only bind to the matching driver */ +- if (pdev->driver_override) +- return !strcmp(pdev->driver_override, drv->name); +- + /* Then try to match against the id table */ + if (pdrv->id_table) + return platform_match_id(pdrv->id_table, pdev) != NULL; +-- +2.51.0 + diff --git a/queue-6.18/spi-intel-pci-add-support-for-nova-lake-mobile-spi-f.patch b/queue-6.18/spi-intel-pci-add-support-for-nova-lake-mobile-spi-f.patch new file mode 100644 index 0000000000..f3d112a653 --- /dev/null +++ b/queue-6.18/spi-intel-pci-add-support-for-nova-lake-mobile-spi-f.patch @@ -0,0 +1,36 @@ +From 4d20146c38d2434b289d0a4d2c9329f8f750f85c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Mar 2026 16:37:03 +0100 +Subject: spi: intel-pci: Add support for Nova Lake mobile SPI flash + +From: Alan Borzeszkowski + +[ Upstream commit 85b731ad4bbf6eb3fedf267ab00be3596f148432 ] + +Add Intel Nova Lake PCD-H SPI serial flash PCI ID to the list of +supported devices. + +Signed-off-by: Alan Borzeszkowski +Acked-by: Mika Westerberg +Link: https://patch.msgid.link/20260309153703.74282-1-alan.borzeszkowski@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-intel-pci.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/spi/spi-intel-pci.c b/drivers/spi/spi-intel-pci.c +index bce3d149bea18..d8ef8f89330ac 100644 +--- a/drivers/spi/spi-intel-pci.c ++++ b/drivers/spi/spi-intel-pci.c +@@ -96,6 +96,7 @@ static const struct pci_device_id intel_spi_pci_ids[] = { + { PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xa823), (unsigned long)&cnl_info }, ++ { PCI_VDEVICE(INTEL, 0xd323), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xe323), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xe423), (unsigned long)&cnl_info }, + { }, +-- +2.51.0 + diff --git a/queue-6.18/tracing-revert-tracing-remove-pid-in-task_rename-tra.patch b/queue-6.18/tracing-revert-tracing-remove-pid-in-task_rename-tra.patch new file mode 100644 index 0000000000..3065c965ae --- /dev/null +++ b/queue-6.18/tracing-revert-tracing-remove-pid-in-task_rename-tra.patch @@ -0,0 +1,74 @@ +From a22022132d5ac2a1f22b6e15a6ee1560f2ef29c7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 15:59:54 +0800 +Subject: tracing: Revert "tracing: Remove pid in task_rename tracing output" + +From: Xuewen Yan + +[ Upstream commit a6f22e50c7d51aa225c392c62c33f0fae11f734d ] + +This reverts commit e3f6a42272e028c46695acc83fc7d7c42f2750ad. + +The commit says that the tracepoint only deals with the current task, +however the following case is not current task: + +comm_write() { + p = get_proc_task(inode); + if (!p) + return -ESRCH; + + if (same_thread_group(current, p)) + set_task_comm(p, buffer); +} +where set_task_comm() calls __set_task_comm() which records +the update of p and not current. + +So revert the patch to show pid. + +Cc: +Cc: +Cc: +Cc: +Link: https://patch.msgid.link/20260306075954.4533-1-xuewen.yan@unisoc.com +Fixes: e3f6a42272e0 ("tracing: Remove pid in task_rename tracing output") +Reported-by: Guohua Yan +Signed-off-by: Xuewen Yan +Reviewed-by: Steven Rostedt (Google) +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Sasha Levin +--- + include/trace/events/task.h | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/include/trace/events/task.h b/include/trace/events/task.h +index 4f0759634306c..b9a129eb54d9e 100644 +--- a/include/trace/events/task.h ++++ b/include/trace/events/task.h +@@ -38,19 +38,22 @@ TRACE_EVENT(task_rename, + TP_ARGS(task, comm), + + TP_STRUCT__entry( ++ __field( pid_t, pid) + __array( char, oldcomm, TASK_COMM_LEN) + __array( char, newcomm, TASK_COMM_LEN) + __field( short, oom_score_adj) + ), + + TP_fast_assign( ++ __entry->pid = task->pid; + memcpy(entry->oldcomm, task->comm, TASK_COMM_LEN); + strscpy(entry->newcomm, comm, TASK_COMM_LEN); + __entry->oom_score_adj = task->signal->oom_score_adj; + ), + +- TP_printk("oldcomm=%s newcomm=%s oom_score_adj=%hd", +- __entry->oldcomm, __entry->newcomm, __entry->oom_score_adj) ++ TP_printk("pid=%d oldcomm=%s newcomm=%s oom_score_adj=%hd", ++ __entry->pid, __entry->oldcomm, ++ __entry->newcomm, __entry->oom_score_adj) + ); + + /** +-- +2.51.0 + diff --git a/queue-6.18/usb-core-new-quirk-to-handle-devices-with-zero-confi.patch b/queue-6.18/usb-core-new-quirk-to-handle-devices-with-zero-confi.patch new file mode 100644 index 0000000000..ac10085e08 --- /dev/null +++ b/queue-6.18/usb-core-new-quirk-to-handle-devices-with-zero-confi.patch @@ -0,0 +1,107 @@ +From eb1baac0b91da977b3b6018139f3f63aab74a219 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Feb 2026 16:49:31 +0800 +Subject: usb: core: new quirk to handle devices with zero configurations + +From: Jie Deng + +[ Upstream commit 9f6a983cfa22ac662c86e60816d3a357d4b551e9 ] + +Some USB devices incorrectly report bNumConfigurations as 0 in their +device descriptor, which causes the USB core to reject them during +enumeration. +logs: +usb 1-2: device descriptor read/64, error -71 +usb 1-2: no configurations +usb 1-2: can't read configurations, error -22 + +However, these devices actually work correctly when +treated as having a single configuration. + +Add a new quirk USB_QUIRK_FORCE_ONE_CONFIG to handle such devices. +When this quirk is set, assume the device has 1 configuration instead +of failing with -EINVAL. + +This quirk is applied to the device with VID:PID 5131:2007 which +exhibits this behavior. + +Signed-off-by: Jie Deng +Link: https://patch.msgid.link/20260227084931.1527461-1-dengjie03@kylinos.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + Documentation/admin-guide/kernel-parameters.txt | 3 +++ + drivers/usb/core/config.c | 6 +++++- + drivers/usb/core/quirks.c | 5 +++++ + include/linux/usb/quirks.h | 3 +++ + 4 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index 6c42061ca20e5..ab4e03f91e744 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -7925,6 +7925,9 @@ + p = USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT + (Reduce timeout of the SET_ADDRESS + request from 5000 ms to 500 ms); ++ q = USB_QUIRK_FORCE_ONE_CONFIG (Device ++ claims zero configurations, ++ forcing to 1); + Example: quirks=0781:5580:bk,0a5c:5834:gij + + usbhid.mousepoll= +diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c +index 2bb1ceb9d621a..3067e18ec4d8a 100644 +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -927,7 +927,11 @@ int usb_get_configuration(struct usb_device *dev) + dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG; + } + +- if (ncfg < 1) { ++ if (ncfg < 1 && dev->quirks & USB_QUIRK_FORCE_ONE_CONFIG) { ++ dev_info(ddev, "Device claims zero configurations, forcing to 1\n"); ++ dev->descriptor.bNumConfigurations = 1; ++ ncfg = 1; ++ } else if (ncfg < 1) { + dev_err(ddev, "no configurations\n"); + return -EINVAL; + } +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 9fef2f4d604a5..65168eb89295c 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -141,6 +141,8 @@ static int quirks_param_set(const char *value, const struct kernel_param *kp) + case 'p': + flags |= USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT; + break; ++ case 'q': ++ flags |= USB_QUIRK_FORCE_ONE_CONFIG; + /* Ignore unrecognized flag characters */ + } + } +@@ -597,6 +599,9 @@ static const struct usb_device_id usb_quirk_list[] = { + /* VCOM device */ + { USB_DEVICE(0x4296, 0x7570), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS }, + ++ /* Noji-MCS SmartCard Reader */ ++ { USB_DEVICE(0x5131, 0x2007), .driver_info = USB_QUIRK_FORCE_ONE_CONFIG }, ++ + /* INTEL VALUE SSD */ + { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, + +diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h +index 2f7bd2fdc6164..b3cc7beab4a3c 100644 +--- a/include/linux/usb/quirks.h ++++ b/include/linux/usb/quirks.h +@@ -78,4 +78,7 @@ + /* skip BOS descriptor request */ + #define USB_QUIRK_NO_BOS BIT(17) + ++/* Device claims zero configurations, forcing to 1 */ ++#define USB_QUIRK_FORCE_ONE_CONFIG BIT(18) ++ + #endif /* __LINUX_USB_QUIRKS_H */ +-- +2.51.0 + diff --git a/queue-6.18/x86-perf-make-sure-to-program-the-counter-value-for-.patch b/queue-6.18/x86-perf-make-sure-to-program-the-counter-value-for-.patch new file mode 100644 index 0000000000..757bd89a8d --- /dev/null +++ b/queue-6.18/x86-perf-make-sure-to-program-the-counter-value-for-.patch @@ -0,0 +1,51 @@ +From baa59b9c638e473a06a21b7afa3f848a0acfbb88 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Mar 2026 21:29:14 +0100 +Subject: x86/perf: Make sure to program the counter value for stopped events + on migration + +From: Peter Zijlstra + +[ Upstream commit f1cac6ac62d28a9a57b17f51ac5795bf250c12d3 ] + +Both Mi Dapeng and Ian Rogers noted that not everything that sets HES_STOPPED +is required to EF_UPDATE. Specifically the 'step 1' loop of rescheduling +explicitly does EF_UPDATE to ensure the counter value is read. + +However, then 'step 2' simply leaves the new counter uninitialized when +HES_STOPPED, even though, as noted above, the thing that stopped them might not +be aware it needs to EF_RELOAD -- since it didn't EF_UPDATE on stop. + +One such location that is affected is throttling, throttle does pmu->stop(, 0); +and unthrottle does pmu->start(, 0); possibly restarting an uninitialized counter. + +Fixes: a4eaf7f14675 ("perf: Rework the PMU methods") +Reported-by: Dapeng Mi +Reported-by: Ian Rogers +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Dapeng Mi +Link: https://patch.msgid.link/20260311204035.GX606826@noisy.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + arch/x86/events/core.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c +index 6227690d19090..8a0cd2ebb60db 100644 +--- a/arch/x86/events/core.c ++++ b/arch/x86/events/core.c +@@ -1361,8 +1361,10 @@ static void x86_pmu_enable(struct pmu *pmu) + + cpuc->events[hwc->idx] = event; + +- if (hwc->state & PERF_HES_ARCH) ++ if (hwc->state & PERF_HES_ARCH) { ++ static_call(x86_pmu_set_period)(event); + continue; ++ } + + /* + * if cpuc->enabled = 0, then no wrmsr as +-- +2.51.0 + diff --git a/queue-6.19/alsa-hda-hdmi-add-tegra238-hda-codec-device-id.patch b/queue-6.19/alsa-hda-hdmi-add-tegra238-hda-codec-device-id.patch new file mode 100644 index 0000000000..c0116d7671 --- /dev/null +++ b/queue-6.19/alsa-hda-hdmi-add-tegra238-hda-codec-device-id.patch @@ -0,0 +1,34 @@ +From 284d6fa85db849fc729fc98aa93c393c63a951dc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Mar 2026 14:12:17 +0530 +Subject: ALSA: hda/hdmi: Add Tegra238 HDA codec device ID + +From: Sheetal + +[ Upstream commit 5f4338e5633dc034a81000b2516a78cfb51c601d ] + +Add Tegra238 HDA codec device in hda_device_id list. + +Signed-off-by: Sheetal +Link: https://patch.msgid.link/20260302084217.3135982-1-sheetal@nvidia.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/hda/codecs/hdmi/tegrahdmi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/hda/codecs/hdmi/tegrahdmi.c b/sound/hda/codecs/hdmi/tegrahdmi.c +index 5f6fe31aa2028..ebb6410a48313 100644 +--- a/sound/hda/codecs/hdmi/tegrahdmi.c ++++ b/sound/hda/codecs/hdmi/tegrahdmi.c +@@ -299,6 +299,7 @@ static const struct hda_device_id snd_hda_id_tegrahdmi[] = { + HDA_CODEC_ID_MODEL(0x10de002f, "Tegra194 HDMI/DP2", MODEL_TEGRA), + HDA_CODEC_ID_MODEL(0x10de0030, "Tegra194 HDMI/DP3", MODEL_TEGRA), + HDA_CODEC_ID_MODEL(0x10de0031, "Tegra234 HDMI/DP", MODEL_TEGRA234), ++ HDA_CODEC_ID_MODEL(0x10de0032, "Tegra238 HDMI/DP", MODEL_TEGRA234), + HDA_CODEC_ID_MODEL(0x10de0033, "SoC 33 HDMI/DP", MODEL_TEGRA234), + HDA_CODEC_ID_MODEL(0x10de0034, "Tegra264 HDMI/DP", MODEL_TEGRA234), + HDA_CODEC_ID_MODEL(0x10de0035, "SoC 35 HDMI/DP", MODEL_TEGRA234), +-- +2.51.0 + diff --git a/queue-6.19/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch b/queue-6.19/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch new file mode 100644 index 0000000000..46bce31af7 --- /dev/null +++ b/queue-6.19/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch @@ -0,0 +1,43 @@ +From 5a1fca3535383ace9327840b95e3d902410278b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Mar 2026 06:29:06 +0500 +Subject: ALSA: hda/realtek: Add headset jack quirk for Thinkpad X390 + +From: Uzair Mughal + +[ Upstream commit 542127f6528ca7cc3cf61e1651d6ccb58495f953 ] + +The Lenovo ThinkPad X390 (ALC257 codec, subsystem ID 0x17aa2288) +does not report headset button press events. Headphone insertion is +detected (SW_HEADPHONE_INSERT), but pressing the inline microphone +button on a headset produces no input events. + +Add a SND_PCI_QUIRK entry that maps this subsystem ID to +ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, which enables +headset jack button detection through alc_fixup_headset_jack() +and ThinkPad ACPI integration. This is the same fixup used by +similar ThinkPad models (P1 Gen 3, X1 Extreme Gen 3). + +Signed-off-by: Uzair Mughal +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20260307012906.20093-1-contact@uzair.is-a.dev +Signed-off-by: Sasha Levin +--- + sound/hda/codecs/realtek/alc269.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c +index fcddab2cc54b3..024d0b37574db 100644 +--- a/sound/hda/codecs/realtek/alc269.c ++++ b/sound/hda/codecs/realtek/alc269.c +@@ -7494,6 +7494,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), + SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), + SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), ++ SND_PCI_QUIRK(0x17aa, 0x2288, "Thinkpad X390", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x22c1, "Thinkpad P1 Gen 3", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), +-- +2.51.0 + diff --git a/queue-6.19/alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch b/queue-6.19/alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch new file mode 100644 index 0000000000..d6f98443f4 --- /dev/null +++ b/queue-6.19/alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch @@ -0,0 +1,38 @@ +From 245865bb3ca6857ebeba6f0543eff4242705524c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Mar 2026 11:27:27 +0800 +Subject: ALSA: hda/realtek: add HP Laptop 14s-dr5xxx mute LED quirk + +From: Liucheng Lu + +[ Upstream commit 178dd118c0f07fd63a9ed74cfbd8c31ae50e33af ] + +HP Laptop 14s-dr5xxx with ALC236 codec does not handle the toggling of +the mute LED. +This patch adds a quirk entry for subsystem ID 0x8a1f using +ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 fixup, enabling correct mute LED +behavior. + +Signed-off-by: Liucheng Lu +Link: https://patch.msgid.link/PAVPR03MB9774F3FCE9CCD181C585281AE37BA@PAVPR03MB9774.eurprd03.prod.outlook.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/hda/codecs/realtek/alc269.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c +index 4c49f1195e1bc..fcddab2cc54b3 100644 +--- a/sound/hda/codecs/realtek/alc269.c ++++ b/sound/hda/codecs/realtek/alc269.c +@@ -6940,6 +6940,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x89da, "HP Spectre x360 14t-ea100", ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX), + SND_PCI_QUIRK(0x103c, 0x89e7, "HP Elite x2 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8a0f, "HP Pavilion 14-ec1xxx", ALC287_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8a1f, "HP Laptop 14s-dr5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), + SND_PCI_QUIRK(0x103c, 0x8a26, "HP Victus 16-d1xxx (MB 8A26)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), +-- +2.51.0 + diff --git a/queue-6.19/alsa-hda-realtek-add-quirk-for-asus-um6702rc.patch b/queue-6.19/alsa-hda-realtek-add-quirk-for-asus-um6702rc.patch new file mode 100644 index 0000000000..ef3656703a --- /dev/null +++ b/queue-6.19/alsa-hda-realtek-add-quirk-for-asus-um6702rc.patch @@ -0,0 +1,37 @@ +From 7c4f637c3547d2829369138213a0a70c0a25e850 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 20:33:17 +0800 +Subject: ALSA: hda/realtek: add quirk for ASUS UM6702RC + +From: Zhang Heng + +[ Upstream commit 0d3429f12133c2ca47aa82ddab2342bc360c47d3 ] + +The sound card of this machine cannot adjust the volume, it can only +be 0 or 100%. The reason is that the DAC with pin 0x17 is connected +to 0x06. Testing found that connecting 0x02 can fix this problem. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=220356 +Signed-off-by: Zhang Heng +Link: https://patch.msgid.link/20260306123317.575346-1-zhangheng@kylinos.cn +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/hda/codecs/realtek/alc269.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c +index 024d0b37574db..ab4b22fcb72ed 100644 +--- a/sound/hda/codecs/realtek/alc269.c ++++ b/sound/hda/codecs/realtek/alc269.c +@@ -7274,6 +7274,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x1e93, "ASUS ExpertBook B9403CVAR", ALC294_FIXUP_ASUS_HPE), + SND_PCI_QUIRK(0x1043, 0x1eb3, "ASUS Ally RCLA72", ALC287_FIXUP_TAS2781_I2C), + SND_PCI_QUIRK(0x1043, 0x1ed3, "ASUS HN7306W", ALC287_FIXUP_CS35L41_I2C_2), ++ HDA_CODEC_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC285_FIXUP_ASUS_I2C_SPEAKER2_TO_DAC1), + SND_PCI_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), +-- +2.51.0 + diff --git a/queue-6.19/alsa-hda-realtek-add-quirk-for-gigabyte-technology-t.patch b/queue-6.19/alsa-hda-realtek-add-quirk-for-gigabyte-technology-t.patch new file mode 100644 index 0000000000..5ca808a8ec --- /dev/null +++ b/queue-6.19/alsa-hda-realtek-add-quirk-for-gigabyte-technology-t.patch @@ -0,0 +1,58 @@ +From 8cf9e151a7b8647ba0fd011b0622af111a013dca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Mar 2026 10:35:59 +0800 +Subject: ALSA: hda/realtek: Add quirk for Gigabyte Technology to fix headphone + +From: Zhang Heng + +[ Upstream commit 56fbbe096a89ff4b52af78a21a4afd9d94bdcc80 ] + +The BIOS of this machine has set 0x19 to mic, which needs to be set +to headphone pin in order to work properly. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=220814 +Signed-off-by: Zhang Heng +Link: https://patch.msgid.link/b55f6ebe-7449-49f7-ae85-00d2ba1e7af0@kylinos.cn +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/hda/codecs/realtek/alc662.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/sound/hda/codecs/realtek/alc662.c b/sound/hda/codecs/realtek/alc662.c +index 5073165d1f3cf..3a943adf90876 100644 +--- a/sound/hda/codecs/realtek/alc662.c ++++ b/sound/hda/codecs/realtek/alc662.c +@@ -313,6 +313,7 @@ enum { + ALC897_FIXUP_HEADSET_MIC_PIN2, + ALC897_FIXUP_UNIS_H3C_X500S, + ALC897_FIXUP_HEADSET_MIC_PIN3, ++ ALC897_FIXUP_H610M_HP_PIN, + }; + + static const struct hda_fixup alc662_fixups[] = { +@@ -766,6 +767,13 @@ static const struct hda_fixup alc662_fixups[] = { + { } + }, + }, ++ [ALC897_FIXUP_H610M_HP_PIN] = { ++ .type = HDA_FIXUP_PINS, ++ .v.pins = (const struct hda_pintbl[]) { ++ { 0x19, 0x0321403f }, /* HP out */ ++ { } ++ }, ++ }, + }; + + static const struct hda_quirk alc662_fixup_tbl[] = { +@@ -815,6 +823,7 @@ static const struct hda_quirk alc662_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), + SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), + SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), ++ SND_PCI_QUIRK(0x1458, 0xa194, "H610M H V2 DDR4", ALC897_FIXUP_H610M_HP_PIN), + SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE), + SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS), + SND_PCI_QUIRK(0x17aa, 0x1057, "Lenovo P360", ALC897_FIXUP_HEADSET_MIC_PIN), +-- +2.51.0 + diff --git a/queue-6.19/alsa-hda-senary-ensure-eapd-is-enabled-during-init.patch b/queue-6.19/alsa-hda-senary-ensure-eapd-is-enabled-during-init.patch new file mode 100644 index 0000000000..eefc6751f0 --- /dev/null +++ b/queue-6.19/alsa-hda-senary-ensure-eapd-is-enabled-during-init.patch @@ -0,0 +1,56 @@ +From 6eefac1f26263bf895c20a9bae83231038c1f549 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Mar 2026 16:15:16 +0800 +Subject: ALSA: hda/senary: Ensure EAPD is enabled during init + +From: wangdicheng + +[ Upstream commit 7ae0d8f1abbbba6f98cac735145e1206927c67d9 ] + +The driver sets spec->gen.own_eapd_ctl to take manual control of the +EAPD (External Amplifier). However, senary_init does not turn on the +EAPD, while senary_shutdown turns it off. + +Since the generic driver skips EAPD handling when own_eapd_ctl is set, +the EAPD remains off after initialization (e.g., after resume), leaving +the codec in a non-functional state. + +Explicitly call senary_auto_turn_eapd in senary_init to ensure the EAPD +is enabled and the codec is functional. + +Signed-off-by: wangdicheng +Link: https://patch.msgid.link/20260303081516.583438-1-wangdich9700@163.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/hda/codecs/senarytech.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/sound/hda/codecs/senarytech.c b/sound/hda/codecs/senarytech.c +index 63cda57cf7868..f4732a8d7955d 100644 +--- a/sound/hda/codecs/senarytech.c ++++ b/sound/hda/codecs/senarytech.c +@@ -28,6 +28,7 @@ struct senary_spec { + /* extra EAPD pins */ + unsigned int num_eapds; + hda_nid_t eapds[4]; ++ bool dynamic_eapd; + hda_nid_t mute_led_eapd; + + unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */ +@@ -134,8 +135,12 @@ static void senary_init_gpio_led(struct hda_codec *codec) + + static int senary_init(struct hda_codec *codec) + { ++ struct senary_spec *spec = codec->spec; ++ + snd_hda_gen_init(codec); + senary_init_gpio_led(codec); ++ if (!spec->dynamic_eapd) ++ senary_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); + + return 0; +-- +2.51.0 + diff --git a/queue-6.19/alsa-usb-audio-add-iface-reset-and-delay-quirk-for-s.patch b/queue-6.19/alsa-usb-audio-add-iface-reset-and-delay-quirk-for-s.patch new file mode 100644 index 0000000000..caa4379561 --- /dev/null +++ b/queue-6.19/alsa-usb-audio-add-iface-reset-and-delay-quirk-for-s.patch @@ -0,0 +1,43 @@ +From 9d6cba3750d38b46db3b42252252832484ff05c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Mar 2026 07:22:38 +0000 +Subject: ALSA: usb-audio: Add iface reset and delay quirk for SPACETOUCH USB + Audio + +From: Lianqin Hu + +[ Upstream commit 5182e5ec4355dd690307f5d5c28cbfc5b2c06a97 ] + +Setting up the interface when suspended/resumeing fail on this card. +Adding a reset and delay quirk will eliminate this problem. + +usb 1-1: New USB device found, idVendor=0666, idProduct=0880 +usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +usb 1-1: Product: USB Audio +usb 1-1: Manufacturer: SPACETOUCH +usb 1-1: SerialNumber: 000000000 + +Signed-off-by: Lianqin Hu +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/TYUPR06MB6217ACC80B70BE25D87456B0D247A@TYUPR06MB6217.apcprd06.prod.outlook.com +Signed-off-by: Sasha Levin +--- + sound/usb/quirks.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index caca0e586d832..d87b988516bbf 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -2239,6 +2239,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_IFACE_DELAY | QUIRK_FLAG_FORCE_IFACE_RESET), + DEVICE_FLG(0x0661, 0x0883, /* iBasso DC04 Ultra */ + QUIRK_FLAG_DSD_RAW), ++ DEVICE_FLG(0x0666, 0x0880, /* SPACETOUCH USB Audio */ ++ QUIRK_FLAG_FORCE_IFACE_RESET | QUIRK_FLAG_IFACE_DELAY), + DEVICE_FLG(0x06f8, 0xb000, /* Hercules DJ Console (Windows Edition) */ + QUIRK_FLAG_IGNORE_CTL_ERROR), + DEVICE_FLG(0x06f8, 0xd002, /* Hercules DJ Console (Macintosh Edition) */ +-- +2.51.0 + diff --git a/queue-6.19/asoc-amd-acp-add-acp6.3-match-entries-for-cirrus-log.patch b/queue-6.19/asoc-amd-acp-add-acp6.3-match-entries-for-cirrus-log.patch new file mode 100644 index 0000000000..036f6f7042 --- /dev/null +++ b/queue-6.19/asoc-amd-acp-add-acp6.3-match-entries-for-cirrus-log.patch @@ -0,0 +1,508 @@ +From ec5d0702d587de5c2f2164b8acb77970fede1e88 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Feb 2026 13:03:07 +0000 +Subject: ASoC: amd: acp: Add ACP6.3 match entries for Cirrus Logic parts + +From: Simon Trimmer + +[ Upstream commit fd13fc700e3e239826a46448bf7f01847dd26f5a ] + +This adds some match entries for a few system configurations: + +cs42l43 link 0 UID 0 +cs35l56 link 1 UID 0 +cs35l56 link 1 UID 1 +cs35l56 link 1 UID 2 +cs35l56 link 1 UID 3 + +cs42l45 link 1 UID 0 +cs35l63 link 0 UID 0 +cs35l63 link 0 UID 2 +cs35l63 link 0 UID 4 +cs35l63 link 0 UID 6 + +cs42l45 link 0 UID 0 +cs35l63 link 1 UID 0 +cs35l63 link 1 UID 1 + +cs42l45 link 0 UID 0 +cs35l63 link 1 UID 1 +cs35l63 link 1 UID 3 + +cs42l45 link 1 UID 0 +cs35l63 link 0 UID 0 +cs35l63 link 0 UID 1 + +cs42l43 link 1 UID 0 +cs35l56 link 1 UID 0 +cs35l56 link 1 UID 1 +cs35l56 link 1 UID 2 +cs35l56 link 1 UID 3 + +cs35l56 link 1 UID 0 +cs35l56 link 1 UID 1 +cs35l56 link 1 UID 2 +cs35l56 link 1 UID 3 + +cs35l63 link 0 UID 0 +cs35l63 link 0 UID 2 +cs35l63 link 0 UID 4 +cs35l63 link 0 UID 6 + +cs42l43 link 0 UID 1 + +cs42l43b link 0 UID 1 + +cs42l45 link 0 UID 0 + +cs42l45 link 1 UID 0 + +Signed-off-by: Simon Trimmer +Link: https://patch.msgid.link/20260224130307.526626-1-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/amd/acp/amd-acp63-acpi-match.c | 413 +++++++++++++++++++++++ + 1 file changed, 413 insertions(+) + +diff --git a/sound/soc/amd/acp/amd-acp63-acpi-match.c b/sound/soc/amd/acp/amd-acp63-acpi-match.c +index 9b6a49c051cda..1dbbaba3c75b3 100644 +--- a/sound/soc/amd/acp/amd-acp63-acpi-match.c ++++ b/sound/soc/amd/acp/amd-acp63-acpi-match.c +@@ -30,6 +30,20 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = { + .group_id = 1 + }; + ++static const struct snd_soc_acpi_endpoint spk_2_endpoint = { ++ .num = 0, ++ .aggregated = 1, ++ .group_position = 2, ++ .group_id = 1 ++}; ++ ++static const struct snd_soc_acpi_endpoint spk_3_endpoint = { ++ .num = 0, ++ .aggregated = 1, ++ .group_position = 3, ++ .group_id = 1 ++}; ++ + static const struct snd_soc_acpi_adr_device rt711_rt1316_group_adr[] = { + { + .adr = 0x000030025D071101ull, +@@ -103,6 +117,345 @@ static const struct snd_soc_acpi_adr_device rt722_0_single_adr[] = { + } + }; + ++static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = { ++ { /* Jack Playback Endpoint */ ++ .num = 0, ++ .aggregated = 0, ++ .group_position = 0, ++ .group_id = 0, ++ }, ++ { /* DMIC Capture Endpoint */ ++ .num = 1, ++ .aggregated = 0, ++ .group_position = 0, ++ .group_id = 0, ++ }, ++ { /* Jack Capture Endpoint */ ++ .num = 2, ++ .aggregated = 0, ++ .group_position = 0, ++ .group_id = 0, ++ }, ++ { /* Speaker Playback Endpoint */ ++ .num = 3, ++ .aggregated = 0, ++ .group_position = 0, ++ .group_id = 0, ++ }, ++}; ++ ++static const struct snd_soc_acpi_adr_device cs35l56x4_l1u3210_adr[] = { ++ { ++ .adr = 0x00013301FA355601ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_l_endpoint, ++ .name_prefix = "AMP1" ++ }, ++ { ++ .adr = 0x00013201FA355601ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_r_endpoint, ++ .name_prefix = "AMP2" ++ }, ++ { ++ .adr = 0x00013101FA355601ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_2_endpoint, ++ .name_prefix = "AMP3" ++ }, ++ { ++ .adr = 0x00013001FA355601ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_3_endpoint, ++ .name_prefix = "AMP4" ++ }, ++}; ++ ++static const struct snd_soc_acpi_adr_device cs35l63x2_l0u01_adr[] = { ++ { ++ .adr = 0x00003001FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_l_endpoint, ++ .name_prefix = "AMP1" ++ }, ++ { ++ .adr = 0x00003101FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_r_endpoint, ++ .name_prefix = "AMP2" ++ }, ++}; ++ ++static const struct snd_soc_acpi_adr_device cs35l63x2_l1u01_adr[] = { ++ { ++ .adr = 0x00013001FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_l_endpoint, ++ .name_prefix = "AMP1" ++ }, ++ { ++ .adr = 0x00013101FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_r_endpoint, ++ .name_prefix = "AMP2" ++ }, ++}; ++ ++static const struct snd_soc_acpi_adr_device cs35l63x2_l1u13_adr[] = { ++ { ++ .adr = 0x00013101FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_l_endpoint, ++ .name_prefix = "AMP1" ++ }, ++ { ++ .adr = 0x00013301FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_r_endpoint, ++ .name_prefix = "AMP2" ++ }, ++}; ++ ++static const struct snd_soc_acpi_adr_device cs35l63x4_l0u0246_adr[] = { ++ { ++ .adr = 0x00003001FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_l_endpoint, ++ .name_prefix = "AMP1" ++ }, ++ { ++ .adr = 0x00003201FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_r_endpoint, ++ .name_prefix = "AMP2" ++ }, ++ { ++ .adr = 0x00003401FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_2_endpoint, ++ .name_prefix = "AMP3" ++ }, ++ { ++ .adr = 0x00003601FA356301ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_3_endpoint, ++ .name_prefix = "AMP4" ++ }, ++}; ++ ++static const struct snd_soc_acpi_adr_device cs42l43_l0u0_adr[] = { ++ { ++ .adr = 0x00003001FA424301ull, ++ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), ++ .endpoints = cs42l43_endpoints, ++ .name_prefix = "cs42l43" ++ } ++}; ++ ++static const struct snd_soc_acpi_adr_device cs42l43_l0u1_adr[] = { ++ { ++ .adr = 0x00003101FA424301ull, ++ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), ++ .endpoints = cs42l43_endpoints, ++ .name_prefix = "cs42l43" ++ } ++}; ++ ++static const struct snd_soc_acpi_adr_device cs42l43b_l0u1_adr[] = { ++ { ++ .adr = 0x00003101FA2A3B01ull, ++ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), ++ .endpoints = cs42l43_endpoints, ++ .name_prefix = "cs42l43" ++ } ++}; ++ ++static const struct snd_soc_acpi_adr_device cs42l43_l1u0_cs35l56x4_l1u0123_adr[] = { ++ { ++ .adr = 0x00013001FA424301ull, ++ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), ++ .endpoints = cs42l43_endpoints, ++ .name_prefix = "cs42l43" ++ }, ++ { ++ .adr = 0x00013001FA355601ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_l_endpoint, ++ .name_prefix = "AMP1" ++ }, ++ { ++ .adr = 0x00013101FA355601ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_r_endpoint, ++ .name_prefix = "AMP2" ++ }, ++ { ++ .adr = 0x00013201FA355601ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_2_endpoint, ++ .name_prefix = "AMP3" ++ }, ++ { ++ .adr = 0x00013301FA355601ull, ++ .num_endpoints = 1, ++ .endpoints = &spk_3_endpoint, ++ .name_prefix = "AMP4" ++ }, ++}; ++ ++static const struct snd_soc_acpi_adr_device cs42l45_l0u0_adr[] = { ++ { ++ .adr = 0x00003001FA424501ull, ++ /* Re-use endpoints, but cs42l45 has no speaker */ ++ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints) - 1, ++ .endpoints = cs42l43_endpoints, ++ .name_prefix = "cs42l45" ++ } ++}; ++ ++static const struct snd_soc_acpi_adr_device cs42l45_l1u0_adr[] = { ++ { ++ .adr = 0x00013001FA424501ull, ++ /* Re-use endpoints, but cs42l45 has no speaker */ ++ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints) - 1, ++ .endpoints = cs42l43_endpoints, ++ .name_prefix = "cs42l45" ++ } ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs35l56x4_l1u3210[] = { ++ { ++ .mask = BIT(1), ++ .num_adr = ARRAY_SIZE(cs35l56x4_l1u3210_adr), ++ .adr_d = cs35l56x4_l1u3210_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs35l63x4_l0u0246[] = { ++ { ++ .mask = BIT(0), ++ .num_adr = ARRAY_SIZE(cs35l63x4_l0u0246_adr), ++ .adr_d = cs35l63x4_l0u0246_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l43_l0u1[] = { ++ { ++ .mask = BIT(0), ++ .num_adr = ARRAY_SIZE(cs42l43_l0u1_adr), ++ .adr_d = cs42l43_l0u1_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l43b_l0u1[] = { ++ { ++ .mask = BIT(0), ++ .num_adr = ARRAY_SIZE(cs42l43b_l0u1_adr), ++ .adr_d = cs42l43b_l0u1_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l43_l0u0_cs35l56x4_l1u3210[] = { ++ { ++ .mask = BIT(0), ++ .num_adr = ARRAY_SIZE(cs42l43_l0u0_adr), ++ .adr_d = cs42l43_l0u0_adr, ++ }, ++ { ++ .mask = BIT(1), ++ .num_adr = ARRAY_SIZE(cs35l56x4_l1u3210_adr), ++ .adr_d = cs35l56x4_l1u3210_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l43_l1u0_cs35l56x4_l1u0123[] = { ++ { ++ .mask = BIT(1), ++ .num_adr = ARRAY_SIZE(cs42l43_l1u0_cs35l56x4_l1u0123_adr), ++ .adr_d = cs42l43_l1u0_cs35l56x4_l1u0123_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l45_l0u0[] = { ++ { ++ .mask = BIT(0), ++ .num_adr = ARRAY_SIZE(cs42l45_l0u0_adr), ++ .adr_d = cs42l45_l0u0_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l45_l0u0_cs35l63x2_l1u01[] = { ++ { ++ .mask = BIT(0), ++ .num_adr = ARRAY_SIZE(cs42l45_l0u0_adr), ++ .adr_d = cs42l45_l0u0_adr, ++ }, ++ { ++ .mask = BIT(1), ++ .num_adr = ARRAY_SIZE(cs35l63x2_l1u01_adr), ++ .adr_d = cs35l63x2_l1u01_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l45_l0u0_cs35l63x2_l1u13[] = { ++ { ++ .mask = BIT(0), ++ .num_adr = ARRAY_SIZE(cs42l45_l0u0_adr), ++ .adr_d = cs42l45_l0u0_adr, ++ }, ++ { ++ .mask = BIT(1), ++ .num_adr = ARRAY_SIZE(cs35l63x2_l1u13_adr), ++ .adr_d = cs35l63x2_l1u13_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l45_l1u0[] = { ++ { ++ .mask = BIT(1), ++ .num_adr = ARRAY_SIZE(cs42l45_l1u0_adr), ++ .adr_d = cs42l45_l1u0_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l45_l1u0_cs35l63x2_l0u01[] = { ++ { ++ .mask = BIT(1), ++ .num_adr = ARRAY_SIZE(cs42l45_l1u0_adr), ++ .adr_d = cs42l45_l1u0_adr, ++ }, ++ { ++ .mask = BIT(0), ++ .num_adr = ARRAY_SIZE(cs35l63x2_l0u01_adr), ++ .adr_d = cs35l63x2_l0u01_adr, ++ }, ++ {} ++}; ++ ++static const struct snd_soc_acpi_link_adr acp63_cs42l45_l1u0_cs35l63x4_l0u0246[] = { ++ { ++ .mask = BIT(1), ++ .num_adr = ARRAY_SIZE(cs42l45_l1u0_adr), ++ .adr_d = cs42l45_l1u0_adr, ++ }, ++ { ++ .mask = BIT(0), ++ .num_adr = ARRAY_SIZE(cs35l63x4_l0u0246_adr), ++ .adr_d = cs35l63x4_l0u0246_adr, ++ }, ++ {} ++}; ++ + static const struct snd_soc_acpi_link_adr acp63_rt722_only[] = { + { + .mask = BIT(0), +@@ -135,6 +488,66 @@ struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sdw_machines[] = { + .links = acp63_4_in_1_sdca, + .drv_name = "amd_sdw", + }, ++ { ++ .link_mask = BIT(0) | BIT(1), ++ .links = acp63_cs42l43_l0u0_cs35l56x4_l1u3210, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(0) | BIT(1), ++ .links = acp63_cs42l45_l1u0_cs35l63x4_l0u0246, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(0) | BIT(1), ++ .links = acp63_cs42l45_l0u0_cs35l63x2_l1u01, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(0) | BIT(1), ++ .links = acp63_cs42l45_l0u0_cs35l63x2_l1u13, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(0) | BIT(1), ++ .links = acp63_cs42l45_l1u0_cs35l63x2_l0u01, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(1), ++ .links = acp63_cs42l43_l1u0_cs35l56x4_l1u0123, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(1), ++ .links = acp63_cs35l56x4_l1u3210, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(0), ++ .links = acp63_cs35l63x4_l0u0246, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(0), ++ .links = acp63_cs42l43_l0u1, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(0), ++ .links = acp63_cs42l43b_l0u1, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(0), ++ .links = acp63_cs42l45_l0u0, ++ .drv_name = "amd_sdw", ++ }, ++ { ++ .link_mask = BIT(1), ++ .links = acp63_cs42l45_l1u0, ++ .drv_name = "amd_sdw", ++ }, + {}, + }; + EXPORT_SYMBOL(snd_soc_acpi_amd_acp63_sdw_machines); +-- +2.51.0 + diff --git a/queue-6.19/asoc-cs35l56-only-patch-asp-registers-if-the-dai-is-.patch b/queue-6.19/asoc-cs35l56-only-patch-asp-registers-if-the-dai-is-.patch new file mode 100644 index 0000000000..01b48f6be7 --- /dev/null +++ b/queue-6.19/asoc-cs35l56-only-patch-asp-registers-if-the-dai-is-.patch @@ -0,0 +1,113 @@ +From 661661353a544bb2ec7a94949c51a979f30a0d5b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Feb 2026 11:01:37 +0000 +Subject: ASoC: cs35l56: Only patch ASP registers if the DAI is part of a + DAIlink + +From: Richard Fitzgerald + +[ Upstream commit 9351cf3fd92dc1349bb75f2f7f7324607dcf596f ] + +Move the ASP register patches to a separate struct and apply this from the +ASP DAI probe() function so that the registers are only patched if the DAI +is part of a DAI link. + +Some systems use the ASP as a special-purpose interconnect and on these +systems the ASP registers are configured by a third party (the firmware, +the BIOS, or another device using the amp's secondary host control +interface). + +If the machine driver does not hook up the ASP DAI then the ASP registers +must be omitted from the patch to prevent overwriting the third party +configuration. + +If the machine driver includes the ASP DAI in a DAI link, this implies that +the machine driver and higher components (such as alsa-ucm) are taking +ownership of the ASP. In this case the ASP registers are patched to known +defaults and the machine driver should configure the ASP. + +Signed-off-by: Richard Fitzgerald +Link: https://patch.msgid.link/20260226110137.1664562-1-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + include/sound/cs35l56.h | 1 + + sound/soc/codecs/cs35l56-shared.c | 16 +++++++++++++++- + sound/soc/codecs/cs35l56.c | 8 ++++++++ + 3 files changed, 24 insertions(+), 1 deletion(-) + +diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h +index 5928af539c468..d0ae1ae2ae2a0 100644 +--- a/include/sound/cs35l56.h ++++ b/include/sound/cs35l56.h +@@ -374,6 +374,7 @@ extern const char * const cs35l56_cal_set_status_text[3]; + extern const char * const cs35l56_tx_input_texts[CS35L56_NUM_INPUT_SRC]; + extern const unsigned int cs35l56_tx_input_values[CS35L56_NUM_INPUT_SRC]; + ++int cs35l56_set_asp_patch(struct cs35l56_base *cs35l56_base); + int cs35l56_set_patch(struct cs35l56_base *cs35l56_base); + int cs35l56_mbox_send(struct cs35l56_base *cs35l56_base, unsigned int command); + int cs35l56_firmware_shutdown(struct cs35l56_base *cs35l56_base); +diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-shared.c +index 60100c8f8c952..0ec6a96e80858 100644 +--- a/sound/soc/codecs/cs35l56-shared.c ++++ b/sound/soc/codecs/cs35l56-shared.c +@@ -23,7 +23,7 @@ + + #include "cs35l56.h" + +-static const struct reg_sequence cs35l56_patch[] = { ++static const struct reg_sequence cs35l56_asp_patch[] = { + /* + * Firmware can change these to non-defaults to satisfy SDCA. + * Ensure that they are at known defaults. +@@ -40,6 +40,20 @@ static const struct reg_sequence cs35l56_patch[] = { + { CS35L56_ASP1TX2_INPUT, 0x00000000 }, + { CS35L56_ASP1TX3_INPUT, 0x00000000 }, + { CS35L56_ASP1TX4_INPUT, 0x00000000 }, ++}; ++ ++int cs35l56_set_asp_patch(struct cs35l56_base *cs35l56_base) ++{ ++ return regmap_register_patch(cs35l56_base->regmap, cs35l56_asp_patch, ++ ARRAY_SIZE(cs35l56_asp_patch)); ++} ++EXPORT_SYMBOL_NS_GPL(cs35l56_set_asp_patch, "SND_SOC_CS35L56_SHARED"); ++ ++static const struct reg_sequence cs35l56_patch[] = { ++ /* ++ * Firmware can change these to non-defaults to satisfy SDCA. ++ * Ensure that they are at known defaults. ++ */ + { CS35L56_SWIRE_DP3_CH1_INPUT, 0x00000018 }, + { CS35L56_SWIRE_DP3_CH2_INPUT, 0x00000019 }, + { CS35L56_SWIRE_DP3_CH3_INPUT, 0x00000029 }, +diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c +index 55b4d0d55712a..1c1924c6f4070 100644 +--- a/sound/soc/codecs/cs35l56.c ++++ b/sound/soc/codecs/cs35l56.c +@@ -346,6 +346,13 @@ static int cs35l56_dsp_event(struct snd_soc_dapm_widget *w, + return wm_adsp_event(w, kcontrol, event); + } + ++static int cs35l56_asp_dai_probe(struct snd_soc_dai *codec_dai) ++{ ++ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(codec_dai->component); ++ ++ return cs35l56_set_asp_patch(&cs35l56->base); ++} ++ + static int cs35l56_asp_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) + { + struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(codec_dai->component); +@@ -550,6 +557,7 @@ static int cs35l56_asp_dai_set_sysclk(struct snd_soc_dai *dai, + } + + static const struct snd_soc_dai_ops cs35l56_ops = { ++ .probe = cs35l56_asp_dai_probe, + .set_fmt = cs35l56_asp_dai_set_fmt, + .set_tdm_slot = cs35l56_asp_dai_set_tdm_slot, + .hw_params = cs35l56_asp_dai_hw_params, +-- +2.51.0 + diff --git a/queue-6.19/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch b/queue-6.19/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch new file mode 100644 index 0000000000..19bb51dff3 --- /dev/null +++ b/queue-6.19/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch @@ -0,0 +1,52 @@ +From 0434e3632a3b2c27c227417b3d1954cc4ed5c323 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 00:25:38 +0000 +Subject: ASoC: fsl_easrc: Fix event generation in fsl_easrc_iec958_set_reg() + +From: Mark Brown + +[ Upstream commit 31ddc62c1cd92e51b9db61d7954b85ae2ec224da ] + +ALSA controls should return 1 if the value in the control changed but the +control put operation fsl_easrc_set_reg() only returns 0 or a negative +error code, causing ALSA to not generate any change events. Add a suitable +check by using regmap_update_bits_check() with the underlying regmap, this +is more clearly and simply correct than trying to verify that one of the +generic ops is exactly equivalent to this one. + +Signed-off-by: Mark Brown +Link: https://patch.msgid.link/20260205-asoc-fsl-easrc-fix-events-v1-2-39d4c766918b@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_easrc.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c +index e64a0d97afd0c..733374121196e 100644 +--- a/sound/soc/fsl/fsl_easrc.c ++++ b/sound/soc/fsl/fsl_easrc.c +@@ -93,14 +93,17 @@ static int fsl_easrc_set_reg(struct snd_kcontrol *kcontrol, + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_value; ++ struct fsl_asrc *easrc = snd_soc_component_get_drvdata(component); + unsigned int regval = ucontrol->value.integer.value[0]; ++ bool changed; + int ret; + +- ret = snd_soc_component_write(component, mc->regbase, regval); +- if (ret < 0) ++ ret = regmap_update_bits_check(easrc->regmap, mc->regbase, ++ GENMASK(31, 0), regval, &changed); ++ if (ret != 0) + return ret; + +- return 0; ++ return changed; + } + + #define SOC_SINGLE_REG_RW(xname, xreg) \ +-- +2.51.0 + diff --git a/queue-6.19/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-10911 b/queue-6.19/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-10911 new file mode 100644 index 0000000000..0675a50d66 --- /dev/null +++ b/queue-6.19/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-10911 @@ -0,0 +1,49 @@ +From 6f82eea96924c3b4121c8ca451cff0e631486117 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 00:25:37 +0000 +Subject: ASoC: fsl_easrc: Fix event generation in fsl_easrc_iec958_put_bits() + +From: Mark Brown + +[ Upstream commit 54a86cf48eaa6d1ab5130d756b718775e81e1748 ] + +ALSA controls should return 1 if the value in the control changed but the +control put operation fsl_easrc_iec958_put_bits() unconditionally returns +0, causing ALSA to not generate any change events. This is detected by +mixer-test with large numbers of messages in the form: + + No event generated for Context 3 IEC958 CS5 + Context 3 IEC958 CS5.0 orig 5224 read 5225, is_volatile 0 + +Add a suitable check. + +Signed-off-by: Mark Brown +Link: https://patch.msgid.link/20260205-asoc-fsl-easrc-fix-events-v1-1-39d4c766918b@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_easrc.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c +index 733374121196e..6c56134c60cc8 100644 +--- a/sound/soc/fsl/fsl_easrc.c ++++ b/sound/soc/fsl/fsl_easrc.c +@@ -52,10 +52,13 @@ static int fsl_easrc_iec958_put_bits(struct snd_kcontrol *kcontrol, + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_value; + unsigned int regval = ucontrol->value.integer.value[0]; ++ int ret; ++ ++ ret = (easrc_priv->bps_iec958[mc->regbase] != regval); + + easrc_priv->bps_iec958[mc->regbase] = regval; + +- return 0; ++ return ret; + } + + static int fsl_easrc_iec958_get_bits(struct snd_kcontrol *kcontrol, +-- +2.51.0 + diff --git a/queue-6.19/asoc-intel-sof_sdw-add-quirk-for-alienware-area-51-2.patch b/queue-6.19/asoc-intel-sof_sdw-add-quirk-for-alienware-area-51-2.patch new file mode 100644 index 0000000000..6ce4e64e09 --- /dev/null +++ b/queue-6.19/asoc-intel-sof_sdw-add-quirk-for-alienware-area-51-2.patch @@ -0,0 +1,44 @@ +From 441d8f727f93bf02a48d1f2d98f8b789d1c7dd8b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Feb 2026 20:02:24 +0100 +Subject: ASoC: Intel: sof_sdw: Add quirk for Alienware Area 51 (2025) 0CCD SKU + +From: Oliver Freyermuth + +[ Upstream commit 70eddf6a0a3fc6d3ab6f77251676da97cc7f12ae ] + +This adds the necessary quirk for the Alienware 18 Area 51 (2025). +Complements commit 1b03391d073d ("ASoC: Intel: sof_sdw: Add quirk +for Alienware Area 51 (2025) 0CCC SKU"). + +Signed-off-by: Oliver Freyermuth +Tested-by: Oliver Freyermuth +Link: https://patch.msgid.link/20260224190224.30630-1-o.freyermuth@googlemail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/boards/sof_sdw.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c +index 50b838be24e95..0186c281296ec 100644 +--- a/sound/soc/intel/boards/sof_sdw.c ++++ b/sound/soc/intel/boards/sof_sdw.c +@@ -763,6 +763,14 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { + }, + .driver_data = (void *)(SOC_SDW_CODEC_SPKR), + }, ++ { ++ .callback = sof_sdw_quirk_cb, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CCD") ++ }, ++ .driver_data = (void *)(SOC_SDW_CODEC_SPKR), ++ }, + /* Pantherlake devices*/ + { + .callback = sof_sdw_quirk_cb, +-- +2.51.0 + diff --git a/queue-6.19/asoc-rt1321-fix-dmic-ch2-3-mask-issue.patch b/queue-6.19/asoc-rt1321-fix-dmic-ch2-3-mask-issue.patch new file mode 100644 index 0000000000..72ac1ed7c5 --- /dev/null +++ b/queue-6.19/asoc-rt1321-fix-dmic-ch2-3-mask-issue.patch @@ -0,0 +1,45 @@ +From 7e11c59344e6654a9bd11265dd28a4b666211b51 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Feb 2026 17:12:10 +0800 +Subject: ASoC: rt1321: fix DMIC ch2/3 mask issue + +From: Shuming Fan + +[ Upstream commit 986841dcad257615a6e3f89231bb38e1f3506b77 ] + +This patch fixed the DMIC ch2/3 mask missing problem. + +Signed-off-by: Shuming Fan +Link: https://patch.msgid.link/20260225091210.3648905-1-shumingf@realtek.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/rt1320-sdw.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/rt1320-sdw.c b/sound/soc/codecs/rt1320-sdw.c +index e6142645b9038..4d09dd06f2d83 100644 +--- a/sound/soc/codecs/rt1320-sdw.c ++++ b/sound/soc/codecs/rt1320-sdw.c +@@ -1455,7 +1455,7 @@ static int rt1320_sdw_hw_params(struct snd_pcm_substream *substream, + struct sdw_port_config port_config; + struct sdw_port_config dmic_port_config[2]; + struct sdw_stream_runtime *sdw_stream; +- int retval; ++ int retval, num_channels; + unsigned int sampling_rate; + + dev_dbg(dai->dev, "%s %s", __func__, dai->name); +@@ -1487,7 +1487,8 @@ static int rt1320_sdw_hw_params(struct snd_pcm_substream *substream, + dmic_port_config[1].num = 10; + break; + case RT1321_DEV_ID: +- dmic_port_config[0].ch_mask = BIT(0) | BIT(1); ++ num_channels = params_channels(params); ++ dmic_port_config[0].ch_mask = GENMASK(num_channels - 1, 0); + dmic_port_config[0].num = 8; + break; + default: +-- +2.51.0 + diff --git a/queue-6.19/block-break-pcpu_alloc_mutex-dependency-on-freeze_lo.patch b/queue-6.19/block-break-pcpu_alloc_mutex-dependency-on-freeze_lo.patch new file mode 100644 index 0000000000..43a26f2171 --- /dev/null +++ b/queue-6.19/block-break-pcpu_alloc_mutex-dependency-on-freeze_lo.patch @@ -0,0 +1,129 @@ +From b57cc1c432dea5db4610300eb0dc82a6a9fabc9b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 1 Mar 2026 18:29:43 +0530 +Subject: block: break pcpu_alloc_mutex dependency on freeze_lock + +From: Nilay Shroff + +[ Upstream commit 539d1b47e935e8384977dd7e5cec370c08b7a644 ] + +While nr_hw_update allocates tagset tags it acquires ->pcpu_alloc_mutex +after ->freeze_lock is acquired or queue is frozen. This potentially +creates a circular dependency involving ->fs_reclaim if reclaim is +triggered simultaneously in a code path which first acquires ->pcpu_ +alloc_mutex. As the queue is already frozen while nr_hw_queue update +allocates tagsets, the reclaim can't forward progress and thus it could +cause a potential deadlock as reported in lockdep splat[1]. + +Fix this by pre-allocating tagset tags before we freeze queue during +nr_hw_queue update. Later the allocated tagset tags could be safely +installed and used after queue is frozen. + +Reported-by: Yi Zhang +Closes: https://lore.kernel.org/all/CAHj4cs8F=OV9s3La2kEQ34YndgfZP-B5PHS4Z8_b9euKG6J4mw@mail.gmail.com/ [1] +Signed-off-by: Nilay Shroff +Reviewed-by: Ming Lei +Tested-by: Yi Zhang +Reviewed-by: Yu Kuai +[axboe: fix brace style issue] +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/blk-mq.c | 45 ++++++++++++++++++++++++++++++--------------- + 1 file changed, 30 insertions(+), 15 deletions(-) + +diff --git a/block/blk-mq.c b/block/blk-mq.c +index 968699277c3d5..3b58dd5876114 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -4778,38 +4778,45 @@ static void blk_mq_update_queue_map(struct blk_mq_tag_set *set) + } + } + +-static int blk_mq_realloc_tag_set_tags(struct blk_mq_tag_set *set, +- int new_nr_hw_queues) ++static struct blk_mq_tags **blk_mq_prealloc_tag_set_tags( ++ struct blk_mq_tag_set *set, ++ int new_nr_hw_queues) + { + struct blk_mq_tags **new_tags; + int i; + + if (set->nr_hw_queues >= new_nr_hw_queues) +- goto done; ++ return NULL; + + new_tags = kcalloc_node(new_nr_hw_queues, sizeof(struct blk_mq_tags *), + GFP_KERNEL, set->numa_node); + if (!new_tags) +- return -ENOMEM; ++ return ERR_PTR(-ENOMEM); + + if (set->tags) + memcpy(new_tags, set->tags, set->nr_hw_queues * + sizeof(*set->tags)); +- kfree(set->tags); +- set->tags = new_tags; + + for (i = set->nr_hw_queues; i < new_nr_hw_queues; i++) { +- if (!__blk_mq_alloc_map_and_rqs(set, i)) { +- while (--i >= set->nr_hw_queues) +- __blk_mq_free_map_and_rqs(set, i); +- return -ENOMEM; ++ if (blk_mq_is_shared_tags(set->flags)) { ++ new_tags[i] = set->shared_tags; ++ } else { ++ new_tags[i] = blk_mq_alloc_map_and_rqs(set, i, ++ set->queue_depth); ++ if (!new_tags[i]) ++ goto out_unwind; + } + cond_resched(); + } + +-done: +- set->nr_hw_queues = new_nr_hw_queues; +- return 0; ++ return new_tags; ++out_unwind: ++ while (--i >= set->nr_hw_queues) { ++ if (!blk_mq_is_shared_tags(set->flags)) ++ blk_mq_free_map_and_rqs(set, new_tags[i], i); ++ } ++ kfree(new_tags); ++ return ERR_PTR(-ENOMEM); + } + + /* +@@ -5093,6 +5100,7 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, + unsigned int memflags; + int i; + struct xarray elv_tbl; ++ struct blk_mq_tags **new_tags; + bool queues_frozen = false; + + lockdep_assert_held(&set->tag_list_lock); +@@ -5127,11 +5135,18 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, + if (blk_mq_elv_switch_none(q, &elv_tbl)) + goto switch_back; + ++ new_tags = blk_mq_prealloc_tag_set_tags(set, nr_hw_queues); ++ if (IS_ERR(new_tags)) ++ goto switch_back; ++ + list_for_each_entry(q, &set->tag_list, tag_set_list) + blk_mq_freeze_queue_nomemsave(q); + queues_frozen = true; +- if (blk_mq_realloc_tag_set_tags(set, nr_hw_queues) < 0) +- goto switch_back; ++ if (new_tags) { ++ kfree(set->tags); ++ set->tags = new_tags; ++ } ++ set->nr_hw_queues = nr_hw_queues; + + fallback: + blk_mq_update_queue_map(set); +-- +2.51.0 + diff --git a/queue-6.19/bpf-fix-constant-blinding-for-probe_mem32-stores.patch b/queue-6.19/bpf-fix-constant-blinding-for-probe_mem32-stores.patch new file mode 100644 index 0000000000..25cdab342a --- /dev/null +++ b/queue-6.19/bpf-fix-constant-blinding-for-probe_mem32-stores.patch @@ -0,0 +1,77 @@ +From 24636bc99cf19da071e56ed36a3718bf2899f73f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Mar 2026 18:25:42 +0000 +Subject: bpf: Fix constant blinding for PROBE_MEM32 stores + +From: Sachin Kumar + +[ Upstream commit 2321a9596d2260310267622e0ad8fbfa6f95378f ] + +BPF_ST | BPF_PROBE_MEM32 immediate stores are not handled by +bpf_jit_blind_insn(), allowing user-controlled 32-bit immediates to +survive unblinded into JIT-compiled native code when bpf_jit_harden >= 1. + +The root cause is that convert_ctx_accesses() rewrites BPF_ST|BPF_MEM +to BPF_ST|BPF_PROBE_MEM32 for arena pointer stores during verification, +before bpf_jit_blind_constants() runs during JIT compilation. The +blinding switch only matches BPF_ST|BPF_MEM (mode 0x60), not +BPF_ST|BPF_PROBE_MEM32 (mode 0xa0). The instruction falls through +unblinded. + +Add BPF_ST|BPF_PROBE_MEM32 cases to bpf_jit_blind_insn() alongside the +existing BPF_ST|BPF_MEM cases. The blinding transformation is identical: +load the blinded immediate into BPF_REG_AX via mov+xor, then convert +the immediate store to a register store (BPF_STX). + +The rewritten STX instruction must preserve the BPF_PROBE_MEM32 mode so +the architecture JIT emits the correct arena addressing (R12-based on +x86-64). Cannot use the BPF_STX_MEM() macro here because it hardcodes +BPF_MEM mode; construct the instruction directly instead. + +Fixes: 6082b6c328b5 ("bpf: Recognize addr_space_cast instruction in the verifier.") +Reviewed-by: Puranjay Mohan +Reviewed-by: Emil Tsalapatis +Signed-off-by: Sachin Kumar +Acked-by: Daniel Borkmann +Link: https://lore.kernel.org/r/Y6IT5VvNRchPBLI5D7JZHBzZrU9rb0ycRJPJzJSXGj7kJlX8RJwZFSM2YZjcDxoQKABkxt1T8Os2gi23PYyFuQe6KkZGWVyfz8K5afdy9ak=@protonmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/core.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c +index 85c0feaae0d3c..1b32333d8f8c6 100644 +--- a/kernel/bpf/core.c ++++ b/kernel/bpf/core.c +@@ -1419,6 +1419,27 @@ static int bpf_jit_blind_insn(const struct bpf_insn *from, + *to++ = BPF_ALU64_IMM(BPF_XOR, BPF_REG_AX, imm_rnd); + *to++ = BPF_STX_MEM(from->code, from->dst_reg, BPF_REG_AX, from->off); + break; ++ ++ case BPF_ST | BPF_PROBE_MEM32 | BPF_DW: ++ case BPF_ST | BPF_PROBE_MEM32 | BPF_W: ++ case BPF_ST | BPF_PROBE_MEM32 | BPF_H: ++ case BPF_ST | BPF_PROBE_MEM32 | BPF_B: ++ *to++ = BPF_ALU64_IMM(BPF_MOV, BPF_REG_AX, imm_rnd ^ ++ from->imm); ++ *to++ = BPF_ALU64_IMM(BPF_XOR, BPF_REG_AX, imm_rnd); ++ /* ++ * Cannot use BPF_STX_MEM() macro here as it ++ * hardcodes BPF_MEM mode, losing PROBE_MEM32 ++ * and breaking arena addressing in the JIT. ++ */ ++ *to++ = (struct bpf_insn) { ++ .code = BPF_STX | BPF_PROBE_MEM32 | ++ BPF_SIZE(from->code), ++ .dst_reg = from->dst_reg, ++ .src_reg = BPF_REG_AX, ++ .off = from->off, ++ }; ++ break; + } + out: + return to - to_buff; +-- +2.51.0 + diff --git a/queue-6.19/bpf-fix-exception-exit-lock-checking-for-subprogs.patch b/queue-6.19/bpf-fix-exception-exit-lock-checking-for-subprogs.patch new file mode 100644 index 0000000000..19215616bd --- /dev/null +++ b/queue-6.19/bpf-fix-exception-exit-lock-checking-for-subprogs.patch @@ -0,0 +1,102 @@ +From 94f2a2d4203136932c797597407c980771fda5d5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Mar 2026 17:08:08 -0700 +Subject: bpf: Fix exception exit lock checking for subprogs + +From: Ihor Solodrai + +[ Upstream commit 6c2128505f61b504c79a20b89596feba61388112 ] + +process_bpf_exit_full() passes check_lock = !curframe to +check_resource_leak(), which is false in cases when bpf_throw() is +called from a static subprog. This makes check_resource_leak() to skip +validation of active_rcu_locks, active_preempt_locks, and +active_irq_id on exception exits from subprogs. + +At runtime bpf_throw() unwinds the stack via ORC without releasing any +user-acquired locks, which may cause various issues as the result. + +Fix by setting check_lock = true for exception exits regardless of +curframe, since exceptions bypass all intermediate frame +cleanup. Update the error message prefix to "bpf_throw" for exception +exits to distinguish them from normal BPF_EXIT. + +Fix reject_subprog_with_rcu_read_lock test which was previously +passing for the wrong reason. Test program returned directly from the +subprog call without closing the RCU section, so the error was +triggered by the unclosed RCU lock on normal exit, not by +bpf_throw. Update __msg annotations for affected tests to match the +new "bpf_throw" error prefix. + +The spin_lock case is not affected because they are already checked [1] +at the call site in do_check_insn() before bpf_throw can run. + +[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/bpf/verifier.c?h=v7.0-rc4#n21098 + +Assisted-by: Claude:claude-opus-4-6 +Fixes: f18b03fabaa9 ("bpf: Implement BPF exceptions") +Signed-off-by: Ihor Solodrai +Acked-by: Yonghong Song +Acked-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20260320000809.643798-1-ihor.solodrai@linux.dev +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 3 ++- + tools/testing/selftests/bpf/progs/exceptions_fail.c | 9 ++++++--- + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index bf721a1274799..0160c6c28af1f 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -20319,7 +20319,8 @@ static int process_bpf_exit_full(struct bpf_verifier_env *env, + * state when it exits. + */ + int err = check_resource_leak(env, exception_exit, +- !env->cur_state->curframe, ++ exception_exit || !env->cur_state->curframe, ++ exception_exit ? "bpf_throw" : + "BPF_EXIT instruction in main prog"); + if (err) + return err; +diff --git a/tools/testing/selftests/bpf/progs/exceptions_fail.c b/tools/testing/selftests/bpf/progs/exceptions_fail.c +index 8a0fdff899271..d7f1c492e3dd3 100644 +--- a/tools/testing/selftests/bpf/progs/exceptions_fail.c ++++ b/tools/testing/selftests/bpf/progs/exceptions_fail.c +@@ -8,6 +8,7 @@ + #include "bpf_experimental.h" + + extern void bpf_rcu_read_lock(void) __ksym; ++extern void bpf_rcu_read_unlock(void) __ksym; + + #define private(name) SEC(".bss." #name) __hidden __attribute__((aligned(8))) + +@@ -131,7 +132,7 @@ int reject_subprog_with_lock(void *ctx) + } + + SEC("?tc") +-__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_rcu_read_lock-ed region") ++__failure __msg("bpf_throw cannot be used inside bpf_rcu_read_lock-ed region") + int reject_with_rcu_read_lock(void *ctx) + { + bpf_rcu_read_lock(); +@@ -147,11 +148,13 @@ __noinline static int throwing_subprog(struct __sk_buff *ctx) + } + + SEC("?tc") +-__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_rcu_read_lock-ed region") ++__failure __msg("bpf_throw cannot be used inside bpf_rcu_read_lock-ed region") + int reject_subprog_with_rcu_read_lock(void *ctx) + { + bpf_rcu_read_lock(); +- return throwing_subprog(ctx); ++ throwing_subprog(ctx); ++ bpf_rcu_read_unlock(); ++ return 0; + } + + static bool rbless(struct bpf_rb_node *n1, const struct bpf_rb_node *n2) +-- +2.51.0 + diff --git a/queue-6.19/bpf-fix-u32-s32-bounds-when-ranges-cross-min-max-bou.patch b/queue-6.19/bpf-fix-u32-s32-bounds-when-ranges-cross-min-max-bou.patch new file mode 100644 index 0000000000..d655f40a82 --- /dev/null +++ b/queue-6.19/bpf-fix-u32-s32-bounds-when-ranges-cross-min-max-bou.patch @@ -0,0 +1,205 @@ +From 247bd1e841fac89f2d8d84f78bd5d6b11b390d58 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 16:54:24 -0800 +Subject: bpf: Fix u32/s32 bounds when ranges cross min/max boundary +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Eduard Zingerman + +[ Upstream commit fbc7aef517d8765e4c425d2792409bb9bf2e1f13 ] + +Same as in __reg64_deduce_bounds(), refine s32/u32 ranges +in __reg32_deduce_bounds() in the following situations: + +- s32 range crosses U32_MAX/0 boundary, positive part of the s32 range + overlaps with u32 range: + + 0 U32_MAX + | [xxxxxxxxxxxxxx u32 range xxxxxxxxxxxxxx] | + |----------------------------|----------------------------| + |xxxxx s32 range xxxxxxxxx] [xxxxxxx| + 0 S32_MAX S32_MIN -1 + +- s32 range crosses U32_MAX/0 boundary, negative part of the s32 range + overlaps with u32 range: + + 0 U32_MAX + | [xxxxxxxxxxxxxx u32 range xxxxxxxxxxxxxx] | + |----------------------------|----------------------------| + |xxxxxxxxx] [xxxxxxxxxxxx s32 range | + 0 S32_MAX S32_MIN -1 + +- No refinement if ranges overlap in two intervals. + +This helps for e.g. consider the following program: + + call %[bpf_get_prandom_u32]; + w0 &= 0xffffffff; + if w0 < 0x3 goto 1f; // on fall-through u32 range [3..U32_MAX] + if w0 s> 0x1 goto 1f; // on fall-through s32 range [S32_MIN..1] + if w0 s< 0x0 goto 1f; // range can be narrowed to [S32_MIN..-1] + r10 = 0; +1: ...; + +The reg_bounds.c selftest is updated to incorporate identical logic, +refinement based on non-overflowing range halves: + + ((x ∩ [0, smax]) ∩ (y ∩ [0, smax])) ∪ + ((x ∩ [smin,-1]) ∩ (y ∩ [smin,-1])) + +Reported-by: Andrea Righi +Reported-by: Emil Tsalapatis +Closes: https://lore.kernel.org/bpf/aakqucg4vcujVwif@gpd4/T/ +Reviewed-by: Emil Tsalapatis +Acked-by: Shung-Hsi Yu +Signed-off-by: Eduard Zingerman +Link: https://lore.kernel.org/r/20260306-bpf-32-bit-range-overflow-v3-1-f7f67e060a6b@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 24 +++++++ + .../selftests/bpf/prog_tests/reg_bounds.c | 62 +++++++++++++++++-- + 2 files changed, 82 insertions(+), 4 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index ea312acf7d482..9032c6d4dbbcc 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -2490,6 +2490,30 @@ static void __reg32_deduce_bounds(struct bpf_reg_state *reg) + if ((u32)reg->s32_min_value <= (u32)reg->s32_max_value) { + reg->u32_min_value = max_t(u32, reg->s32_min_value, reg->u32_min_value); + reg->u32_max_value = min_t(u32, reg->s32_max_value, reg->u32_max_value); ++ } else { ++ if (reg->u32_max_value < (u32)reg->s32_min_value) { ++ /* See __reg64_deduce_bounds() for detailed explanation. ++ * Refine ranges in the following situation: ++ * ++ * 0 U32_MAX ++ * | [xxxxxxxxxxxxxx u32 range xxxxxxxxxxxxxx] | ++ * |----------------------------|----------------------------| ++ * |xxxxx s32 range xxxxxxxxx] [xxxxxxx| ++ * 0 S32_MAX S32_MIN -1 ++ */ ++ reg->s32_min_value = (s32)reg->u32_min_value; ++ reg->u32_max_value = min_t(u32, reg->u32_max_value, reg->s32_max_value); ++ } else if ((u32)reg->s32_max_value < reg->u32_min_value) { ++ /* ++ * 0 U32_MAX ++ * | [xxxxxxxxxxxxxx u32 range xxxxxxxxxxxxxx] | ++ * |----------------------------|----------------------------| ++ * |xxxxxxxxx] [xxxxxxxxxxxx s32 range | ++ * 0 S32_MAX S32_MIN -1 ++ */ ++ reg->s32_max_value = (s32)reg->u32_max_value; ++ reg->u32_min_value = max_t(u32, reg->u32_min_value, reg->s32_min_value); ++ } + } + } + +diff --git a/tools/testing/selftests/bpf/prog_tests/reg_bounds.c b/tools/testing/selftests/bpf/prog_tests/reg_bounds.c +index 0322f817d07be..04938d0d431b3 100644 +--- a/tools/testing/selftests/bpf/prog_tests/reg_bounds.c ++++ b/tools/testing/selftests/bpf/prog_tests/reg_bounds.c +@@ -422,15 +422,69 @@ static bool is_valid_range(enum num_t t, struct range x) + } + } + +-static struct range range_improve(enum num_t t, struct range old, struct range new) ++static struct range range_intersection(enum num_t t, struct range old, struct range new) + { + return range(t, max_t(t, old.a, new.a), min_t(t, old.b, new.b)); + } + ++/* ++ * Result is precise when 'x' and 'y' overlap or form a continuous range, ++ * result is an over-approximation if 'x' and 'y' do not overlap. ++ */ ++static struct range range_union(enum num_t t, struct range x, struct range y) ++{ ++ if (!is_valid_range(t, x)) ++ return y; ++ if (!is_valid_range(t, y)) ++ return x; ++ return range(t, min_t(t, x.a, y.a), max_t(t, x.b, y.b)); ++} ++ ++/* ++ * This function attempts to improve x range intersecting it with y. ++ * range_cast(... to_t ...) looses precision for ranges that pass to_t ++ * min/max boundaries. To avoid such precision loses this function ++ * splits both x and y into halves corresponding to non-overflowing ++ * sub-ranges: [0, smin] and [smax, -1]. ++ * Final result is computed as follows: ++ * ++ * ((x ∩ [0, smax]) ∩ (y ∩ [0, smax])) ∪ ++ * ((x ∩ [smin,-1]) ∩ (y ∩ [smin,-1])) ++ * ++ * Precision might still be lost if final union is not a continuous range. ++ */ ++static struct range range_refine_in_halves(enum num_t x_t, struct range x, ++ enum num_t y_t, struct range y) ++{ ++ struct range x_pos, x_neg, y_pos, y_neg, r_pos, r_neg; ++ u64 smax, smin, neg_one; ++ ++ if (t_is_32(x_t)) { ++ smax = (u64)(u32)S32_MAX; ++ smin = (u64)(u32)S32_MIN; ++ neg_one = (u64)(u32)(s32)(-1); ++ } else { ++ smax = (u64)S64_MAX; ++ smin = (u64)S64_MIN; ++ neg_one = U64_MAX; ++ } ++ x_pos = range_intersection(x_t, x, range(x_t, 0, smax)); ++ x_neg = range_intersection(x_t, x, range(x_t, smin, neg_one)); ++ y_pos = range_intersection(y_t, y, range(x_t, 0, smax)); ++ y_neg = range_intersection(y_t, y, range(y_t, smin, neg_one)); ++ r_pos = range_intersection(x_t, x_pos, range_cast(y_t, x_t, y_pos)); ++ r_neg = range_intersection(x_t, x_neg, range_cast(y_t, x_t, y_neg)); ++ return range_union(x_t, r_pos, r_neg); ++ ++} ++ + static struct range range_refine(enum num_t x_t, struct range x, enum num_t y_t, struct range y) + { + struct range y_cast; + ++ if (t_is_32(x_t) == t_is_32(y_t)) ++ x = range_refine_in_halves(x_t, x, y_t, y); ++ + y_cast = range_cast(y_t, x_t, y); + + /* If we know that +@@ -444,7 +498,7 @@ static struct range range_refine(enum num_t x_t, struct range x, enum num_t y_t, + */ + if (x_t == S64 && y_t == S32 && y_cast.a <= S32_MAX && y_cast.b <= S32_MAX && + (s64)x.a >= S32_MIN && (s64)x.b <= S32_MAX) +- return range_improve(x_t, x, y_cast); ++ return range_intersection(x_t, x, y_cast); + + /* the case when new range knowledge, *y*, is a 32-bit subregister + * range, while previous range knowledge, *x*, is a full register +@@ -462,7 +516,7 @@ static struct range range_refine(enum num_t x_t, struct range x, enum num_t y_t, + x_swap = range(x_t, swap_low32(x.a, y_cast.a), swap_low32(x.b, y_cast.b)); + if (!is_valid_range(x_t, x_swap)) + return x; +- return range_improve(x_t, x, x_swap); ++ return range_intersection(x_t, x, x_swap); + } + + if (!t_is_32(x_t) && !t_is_32(y_t) && x_t != y_t) { +@@ -480,7 +534,7 @@ static struct range range_refine(enum num_t x_t, struct range x, enum num_t y_t, + } + + /* otherwise, plain range cast and intersection works */ +- return range_improve(x_t, x, y_cast); ++ return range_intersection(x_t, x, y_cast); + } + + /* ======================= +-- +2.51.0 + diff --git a/queue-6.19/bpf-fix-undefined-behavior-in-interpreter-sdiv-smod-.patch b/queue-6.19/bpf-fix-undefined-behavior-in-interpreter-sdiv-smod-.patch new file mode 100644 index 0000000000..f074a57d7d --- /dev/null +++ b/queue-6.19/bpf-fix-undefined-behavior-in-interpreter-sdiv-smod-.patch @@ -0,0 +1,104 @@ +From 9b499e075b3672da9e00c624a2f4a60815123a77 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Mar 2026 01:11:15 +0000 +Subject: bpf: Fix undefined behavior in interpreter sdiv/smod for INT_MIN + +From: Jenny Guanni Qu + +[ Upstream commit c77b30bd1dcb61f66c640ff7d2757816210c7cb0 ] + +The BPF interpreter's signed 32-bit division and modulo handlers use +the kernel abs() macro on s32 operands. The abs() macro documentation +(include/linux/math.h) explicitly states the result is undefined when +the input is the type minimum. When DST contains S32_MIN (0x80000000), +abs((s32)DST) triggers undefined behavior and returns S32_MIN unchanged +on arm64/x86. This value is then sign-extended to u64 as +0xFFFFFFFF80000000, causing do_div() to compute the wrong result. + +The verifier's abstract interpretation (scalar32_min_max_sdiv) computes +the mathematically correct result for range tracking, creating a +verifier/interpreter mismatch that can be exploited for out-of-bounds +map value access. + +Introduce abs_s32() which handles S32_MIN correctly by casting to u32 +before negating, avoiding signed overflow entirely. Replace all 8 +abs((s32)...) call sites in the interpreter's sdiv32/smod32 handlers. + +s32 is the only affected case -- the s64 division/modulo handlers do +not use abs(). + +Fixes: ec0e2da95f72 ("bpf: Support new signed div/mod instructions.") +Acked-by: Yonghong Song +Acked-by: Mykyta Yatsenko +Signed-off-by: Jenny Guanni Qu +Link: https://lore.kernel.org/r/20260311011116.2108005-2-qguanni@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/core.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c +index 1b32333d8f8c6..5a56bc2ab900d 100644 +--- a/kernel/bpf/core.c ++++ b/kernel/bpf/core.c +@@ -1754,6 +1754,12 @@ bool bpf_opcode_in_insntable(u8 code) + } + + #ifndef CONFIG_BPF_JIT_ALWAYS_ON ++/* Absolute value of s32 without undefined behavior for S32_MIN */ ++static u32 abs_s32(s32 x) ++{ ++ return x >= 0 ? (u32)x : -(u32)x; ++} ++ + /** + * ___bpf_prog_run - run eBPF program on a given context + * @regs: is the array of MAX_BPF_EXT_REG eBPF pseudo-registers +@@ -1918,8 +1924,8 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn) + DST = do_div(AX, (u32) SRC); + break; + case 1: +- AX = abs((s32)DST); +- AX = do_div(AX, abs((s32)SRC)); ++ AX = abs_s32((s32)DST); ++ AX = do_div(AX, abs_s32((s32)SRC)); + if ((s32)DST < 0) + DST = (u32)-AX; + else +@@ -1946,8 +1952,8 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn) + DST = do_div(AX, (u32) IMM); + break; + case 1: +- AX = abs((s32)DST); +- AX = do_div(AX, abs((s32)IMM)); ++ AX = abs_s32((s32)DST); ++ AX = do_div(AX, abs_s32((s32)IMM)); + if ((s32)DST < 0) + DST = (u32)-AX; + else +@@ -1973,8 +1979,8 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn) + DST = (u32) AX; + break; + case 1: +- AX = abs((s32)DST); +- do_div(AX, abs((s32)SRC)); ++ AX = abs_s32((s32)DST); ++ do_div(AX, abs_s32((s32)SRC)); + if (((s32)DST < 0) == ((s32)SRC < 0)) + DST = (u32)AX; + else +@@ -2000,8 +2006,8 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn) + DST = (u32) AX; + break; + case 1: +- AX = abs((s32)DST); +- do_div(AX, abs((s32)IMM)); ++ AX = abs_s32((s32)DST); ++ do_div(AX, abs_s32((s32)IMM)); + if (((s32)DST < 0) == ((s32)IMM < 0)) + DST = (u32)AX; + else +-- +2.51.0 + diff --git a/queue-6.19/bpf-fix-unsound-scalar-forking-in-maybe_fork_scalars.patch b/queue-6.19/bpf-fix-unsound-scalar-forking-in-maybe_fork_scalars.patch new file mode 100644 index 0000000000..bf3d43833a --- /dev/null +++ b/queue-6.19/bpf-fix-unsound-scalar-forking-in-maybe_fork_scalars.patch @@ -0,0 +1,52 @@ +From b77125980a561f7e5549d07b46d8db6202eddd59 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Mar 2026 13:15:20 +1100 +Subject: bpf: Fix unsound scalar forking in maybe_fork_scalars() for BPF_OR + +From: Daniel Wade + +[ Upstream commit c845894ebd6fb43226b3118d6b017942550910c5 ] + +maybe_fork_scalars() is called for both BPF_AND and BPF_OR when the +source operand is a constant. When dst has signed range [-1, 0], it +forks the verifier state: the pushed path gets dst = 0, the current +path gets dst = -1. + +For BPF_AND this is correct: 0 & K == 0. +For BPF_OR this is wrong: 0 | K == K, not 0. + +The pushed path therefore tracks dst as 0 when the runtime value is K, +producing an exploitable verifier/runtime divergence that allows +out-of-bounds map access. + +Fix this by passing env->insn_idx (instead of env->insn_idx + 1) to +push_stack(), so the pushed path re-executes the ALU instruction with +dst = 0 and naturally computes the correct result for any opcode. + +Fixes: bffacdb80b93 ("bpf: Recognize special arithmetic shift in the verifier") +Signed-off-by: Daniel Wade +Reviewed-by: Amery Hung +Acked-by: Eduard Zingerman +Link: https://lore.kernel.org/r/20260314021521.128361-2-danjwade95@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 0160c6c28af1f..ea312acf7d482 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -15593,7 +15593,7 @@ static int maybe_fork_scalars(struct bpf_verifier_env *env, struct bpf_insn *ins + else + return 0; + +- branch = push_stack(env, env->insn_idx + 1, env->insn_idx, false); ++ branch = push_stack(env, env->insn_idx, env->insn_idx, false); + if (IS_ERR(branch)) + return PTR_ERR(branch); + +-- +2.51.0 + diff --git a/queue-6.19/bpf-release-module-btf-idr-before-module-unload.patch b/queue-6.19/bpf-release-module-btf-idr-before-module-unload.patch new file mode 100644 index 0000000000..81412e9c8f --- /dev/null +++ b/queue-6.19/bpf-release-module-btf-idr-before-module-unload.patch @@ -0,0 +1,128 @@ +From f3aeb1139e563a3e2ca1338a8c63f74d83d05fd0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Mar 2026 13:53:07 -0700 +Subject: bpf: Release module BTF IDR before module unload + +From: Kumar Kartikeya Dwivedi + +[ Upstream commit 146bd2a87a65aa407bb17fac70d8d583d19aba06 ] + +Gregory reported in [0] that the global_map_resize test when run in +repeatedly ends up failing during program load. This stems from the fact +that BTF reference has not dropped to zero after the previous run's +module is unloaded, and the older module's BTF is still discoverable and +visible. Later, in libbpf, load_module_btfs() will find the ID for this +stale BTF, open its fd, and then it will be used during program load +where later steps taking module reference using btf_try_get_module() +fail since the underlying module for the BTF is gone. + +Logically, once a module is unloaded, it's associated BTF artifacts +should become hidden. The BTF object inside the kernel may still remain +alive as long its reference counts are alive, but it should no longer be +discoverable. + +To fix this, let us call btf_free_id() from the MODULE_STATE_GOING case +for the module unload to free the BTF associated IDR entry, and disable +its discovery once module unload returns to user space. If a race +happens during unload, the outcome is non-deterministic anyway. However, +user space should be able to rely on the guarantee that once it has +synchronously established a successful module unload, no more stale +artifacts associated with this module can be obtained subsequently. + +Note that we must be careful to not invoke btf_free_id() in btf_put() +when btf_is_module() is true now. There could be a window where the +module unload drops a non-terminal reference, frees the IDR, but the +same ID gets reused and the second unconditional btf_free_id() ends up +releasing an unrelated entry. + +To avoid a special case for btf_is_module() case, set btf->id to zero to +make btf_free_id() idempotent, such that we can unconditionally invoke it +from btf_put(), and also from the MODULE_STATE_GOING case. Since zero is +an invalid IDR, the idr_remove() should be a noop. + +Note that we can be sure that by the time we reach final btf_put() for +btf_is_module() case, the btf_free_id() is already done, since the +module itself holds the BTF reference, and it will call this function +for the BTF before dropping its own reference. + + [0]: https://lore.kernel.org/bpf/cover.1773170190.git.grbell@redhat.com + +Fixes: 36e68442d1af ("bpf: Load and verify kernel module BTFs") +Acked-by: Martin KaFai Lau +Suggested-by: Martin KaFai Lau +Reported-by: Gregory Bell +Reviewed-by: Emil Tsalapatis +Signed-off-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20260312205307.1346991-1-memxor@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/btf.c | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c +index 0de8fc8a0e0b3..75a5df36f9170 100644 +--- a/kernel/bpf/btf.c ++++ b/kernel/bpf/btf.c +@@ -1676,7 +1676,16 @@ static void btf_free_id(struct btf *btf) + * of the _bh() version. + */ + spin_lock_irqsave(&btf_idr_lock, flags); +- idr_remove(&btf_idr, btf->id); ++ if (btf->id) { ++ idr_remove(&btf_idr, btf->id); ++ /* ++ * Clear the id here to make this function idempotent, since it will get ++ * called a couple of times for module BTFs: on module unload, and then ++ * the final btf_put(). btf_alloc_id() starts IDs with 1, so we can use ++ * 0 as sentinel value. ++ */ ++ WRITE_ONCE(btf->id, 0); ++ } + spin_unlock_irqrestore(&btf_idr_lock, flags); + } + +@@ -7995,7 +8004,7 @@ static void bpf_btf_show_fdinfo(struct seq_file *m, struct file *filp) + { + const struct btf *btf = filp->private_data; + +- seq_printf(m, "btf_id:\t%u\n", btf->id); ++ seq_printf(m, "btf_id:\t%u\n", READ_ONCE(btf->id)); + } + #endif + +@@ -8077,7 +8086,7 @@ int btf_get_info_by_fd(const struct btf *btf, + if (copy_from_user(&info, uinfo, info_copy)) + return -EFAULT; + +- info.id = btf->id; ++ info.id = READ_ONCE(btf->id); + ubtf = u64_to_user_ptr(info.btf); + btf_copy = min_t(u32, btf->data_size, info.btf_size); + if (copy_to_user(ubtf, btf->data, btf_copy)) +@@ -8140,7 +8149,7 @@ int btf_get_fd_by_id(u32 id) + + u32 btf_obj_id(const struct btf *btf) + { +- return btf->id; ++ return READ_ONCE(btf->id); + } + + bool btf_is_kernel(const struct btf *btf) +@@ -8262,6 +8271,13 @@ static int btf_module_notify(struct notifier_block *nb, unsigned long op, + if (btf_mod->module != module) + continue; + ++ /* ++ * For modules, we do the freeing of BTF IDR as soon as ++ * module goes away to disable BTF discovery, since the ++ * btf_try_get_module() on such BTFs will fail. This may ++ * be called again on btf_put(), but it's ok to do so. ++ */ ++ btf_free_id(btf_mod->btf); + list_del(&btf_mod->list); + if (btf_mod->sysfs_attr) + sysfs_remove_bin_file(btf_kobj, btf_mod->sysfs_attr); +-- +2.51.0 + diff --git a/queue-6.19/bpf-reset-register-id-for-bpf_end-value-tracking.patch b/queue-6.19/bpf-reset-register-id-for-bpf_end-value-tracking.patch new file mode 100644 index 0000000000..ed1cf9614b --- /dev/null +++ b/queue-6.19/bpf-reset-register-id-for-bpf_end-value-tracking.patch @@ -0,0 +1,62 @@ +From e1b35321f6c8f0b0449d23a958618f0adb7f52b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Mar 2026 16:32:27 +0800 +Subject: bpf: Reset register ID for BPF_END value tracking + +From: Yazhou Tang + +[ Upstream commit a3125bc01884431d30d731461634c8295b6f0529 ] + +When a register undergoes a BPF_END (byte swap) operation, its scalar +value is mutated in-place. If this register previously shared a scalar ID +with another register (e.g., after an `r1 = r0` assignment), this tie must +be broken. + +Currently, the verifier misses resetting `dst_reg->id` to 0 for BPF_END. +Consequently, if a conditional jump checks the swapped register, the +verifier incorrectly propagates the learned bounds to the linked register, +leading to false confidence in the linked register's value and potentially +allowing out-of-bounds memory accesses. + +Fix this by explicitly resetting `dst_reg->id` to 0 in the BPF_END case +to break the scalar tie, similar to how BPF_NEG handles it via +`__mark_reg_known`. + +Fixes: 9d2119984224 ("bpf: Add bitwise tracking for BPF_END") +Closes: https://lore.kernel.org/bpf/AMBPR06MB108683CFEB1CB8D9E02FC95ECF17EA@AMBPR06MB10868.eurprd06.prod.outlook.com/ +Link: https://lore.kernel.org/bpf/4be25f7442a52244d0dd1abb47bc6750e57984c9.camel@gmail.com/ +Reported-by: Guillaume Laporte +Co-developed-by: Tianci Cao +Signed-off-by: Tianci Cao +Co-developed-by: Shenghao Yuan +Signed-off-by: Shenghao Yuan +Signed-off-by: Yazhou Tang +Acked-by: Eduard Zingerman +Link: https://lore.kernel.org/r/20260304083228.142016-2-tangyazhou@zju.edu.cn +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 9c4723cdac700..bf721a1274799 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -15512,6 +15512,13 @@ static void scalar_byte_swap(struct bpf_reg_state *dst_reg, struct bpf_insn *ins + /* Apply bswap if alu64 or switch between big-endian and little-endian machines */ + bool need_bswap = alu64 || (to_le == is_big_endian); + ++ /* ++ * If the register is mutated, manually reset its scalar ID to break ++ * any existing ties and avoid incorrect bounds propagation. ++ */ ++ if (need_bswap || insn->imm == 16 || insn->imm == 32) ++ dst_reg->id = 0; ++ + if (need_bswap) { + if (insn->imm == 16) + dst_reg->var_off = tnum_bswap16(dst_reg->var_off); +-- +2.51.0 + diff --git a/queue-6.19/btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch b/queue-6.19/btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch new file mode 100644 index 0000000000..f65b3e3845 --- /dev/null +++ b/queue-6.19/btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch @@ -0,0 +1,196 @@ +From c46d22466a34f2ec01161623dae0d1e2cfbd1cce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Feb 2026 14:25:35 -0800 +Subject: btrfs: set BTRFS_ROOT_ORPHAN_CLEANUP during subvol create + +From: Boris Burkov + +[ Upstream commit 5131fa077f9bb386a1b901bf5b247041f0ec8f80 ] + +We have recently observed a number of subvolumes with broken dentries. +ls-ing the parent dir looks like: + +drwxrwxrwt 1 root root 16 Jan 23 16:49 . +drwxr-xr-x 1 root root 24 Jan 23 16:48 .. +d????????? ? ? ? ? ? broken_subvol + +and similarly stat-ing the file fails. + +In this state, deleting the subvol fails with ENOENT, but attempting to +create a new file or subvol over it errors out with EEXIST and even +aborts the fs. Which leaves us a bit stuck. + +dmesg contains a single notable error message reading: +"could not do orphan cleanup -2" + +2 is ENOENT and the error comes from the failure handling path of +btrfs_orphan_cleanup(), with the stack leading back up to +btrfs_lookup(). + +btrfs_lookup +btrfs_lookup_dentry +btrfs_orphan_cleanup // prints that message and returns -ENOENT + +After some detailed inspection of the internal state, it became clear +that: +- there are no orphan items for the subvol +- the subvol is otherwise healthy looking, it is not half-deleted or + anything, there is no drop progress, etc. +- the subvol was created a while ago and does the meaningful first + btrfs_orphan_cleanup() call that sets BTRFS_ROOT_ORPHAN_CLEANUP much + later. +- after btrfs_orphan_cleanup() fails, btrfs_lookup_dentry() returns -ENOENT, + which results in a negative dentry for the subvolume via + d_splice_alias(NULL, dentry), leading to the observed behavior. The + bug can be mitigated by dropping the dentry cache, at which point we + can successfully delete the subvolume if we want. + +i.e., +btrfs_lookup() + btrfs_lookup_dentry() + if (!sb_rdonly(inode->vfs_inode)->vfs_inode) + btrfs_orphan_cleanup(sub_root) + test_and_set_bit(BTRFS_ROOT_ORPHAN_CLEANUP) + btrfs_search_slot() // finds orphan item for inode N + ... + prints "could not do orphan cleanup -2" + if (inode == ERR_PTR(-ENOENT)) + inode = NULL; + return d_splice_alias(NULL, dentry) // NEGATIVE DENTRY for valid subvolume + +btrfs_orphan_cleanup() does test_and_set_bit(BTRFS_ROOT_ORPHAN_CLEANUP) +on the root when it runs, so it cannot run more than once on a given +root, so something else must run concurrently. However, the obvious +routes to deleting an orphan when nlinks goes to 0 should not be able to +run without first doing a lookup into the subvolume, which should run +btrfs_orphan_cleanup() and set the bit. + +The final important observation is that create_subvol() calls +d_instantiate_new() but does not set BTRFS_ROOT_ORPHAN_CLEANUP, so if +the dentry cache gets dropped, the next lookup into the subvolume will +make a real call into btrfs_orphan_cleanup() for the first time. This +opens up the possibility of concurrently deleting the inode/orphan items +but most typical evict() paths will be holding a reference on the parent +dentry (child dentry holds parent->d_lockref.count via dget in +d_alloc(), released in __dentry_kill()) and prevent the parent from +being removed from the dentry cache. + +The one exception is delayed iputs. Ordered extent creation calls +igrab() on the inode. If the file is unlinked and closed while those +refs are held, iput() in __dentry_kill() decrements i_count but does +not trigger eviction (i_count > 0). The child dentry is freed and the +subvol dentry's d_lockref.count drops to 0, making it evictable while +the inode is still alive. + +Since there are two races (the race between writeback and unlink and +the race between lookup and delayed iputs), and there are too many moving +parts, the following three diagrams show the complete picture. +(Only the second and third are races) + +Phase 1: +Create Subvol in dentry cache without BTRFS_ROOT_ORPHAN_CLEANUP set + +btrfs_mksubvol() + lookup_one_len() + __lookup_slow() + d_alloc_parallel() + __d_alloc() // d_lockref.count = 1 + create_subvol(dentry) + // doesn't touch the bit.. + d_instantiate_new(dentry, inode) // dentry in cache with d_lockref.count == 1 + +Phase 2: +Create a delayed iput for a file in the subvol but leave the subvol in +state where its dentry can be evicted (d_lockref.count == 0) + +T1 (task) T2 (writeback) T3 (OE workqueue) + +write() // dirty pages + btrfs_writepages() + btrfs_run_delalloc_range() + cow_file_range() + btrfs_alloc_ordered_extent() + igrab() // i_count: 1 -> 2 +btrfs_unlink_inode() + btrfs_orphan_add() +close() + __fput() + dput() + finish_dput() + __dentry_kill() + dentry_unlink_inode() + iput() // 2 -> 1 + --parent->d_lockref.count // 1 -> 0; evictable + finish_ordered_fn() + btrfs_finish_ordered_io() + btrfs_put_ordered_extent() + btrfs_add_delayed_iput() + +Phase 3: +Once the delayed iput is pending and the subvol dentry is evictable, +the shrinker can free it, causing the next lookup to go through +btrfs_lookup() and call btrfs_orphan_cleanup() for the first time. +If the cleaner kthread processes the delayed iput concurrently, the +two race: + + T1 (shrinker) T2 (cleaner kthread) T3 (lookup) + + super_cache_scan() + prune_dcache_sb() + __dentry_kill() + // subvol dentry freed + btrfs_run_delayed_iputs() + iput() // i_count -> 0 + evict() // sets I_FREEING + btrfs_evict_inode() + // truncation loop + btrfs_lookup() + btrfs_lookup_dentry() + btrfs_orphan_cleanup() + // first call (bit never set) + btrfs_iget() + // blocks on I_FREEING + + btrfs_orphan_del() + // inode freed + // returns -ENOENT + btrfs_del_orphan_item() + // -ENOENT + // "could not do orphan cleanup -2" + d_splice_alias(NULL, dentry) + // negative dentry for valid subvol + +The most straightforward fix is to ensure the invariant that a dentry +for a subvolume can exist if and only if that subvolume has +BTRFS_ROOT_ORPHAN_CLEANUP set on its root (and is known to have no +orphans or ran btrfs_orphan_cleanup()). + +Reviewed-by: Filipe Manana +Signed-off-by: Boris Burkov +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/ioctl.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index 1a5d98811f2b2..b78998815ce72 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -672,6 +672,13 @@ static noinline int create_subvol(struct mnt_idmap *idmap, + goto out; + } + ++ /* ++ * Subvolumes have orphans cleaned on first dentry lookup. A new ++ * subvolume cannot have any orphans, so we should set the bit before we ++ * add the subvolume dentry to the dentry cache, so that it is in the ++ * same state as a subvolume after first lookup. ++ */ ++ set_bit(BTRFS_ROOT_ORPHAN_CLEANUP, &new_root->state); + d_instantiate_new(dentry, new_inode_args.inode); + new_inode_args.inode = NULL; + +-- +2.51.0 + diff --git a/queue-6.19/cxl-adjust-the-startup-priority-of-cxl_pmem-to-be-hi.patch b/queue-6.19/cxl-adjust-the-startup-priority-of-cxl_pmem-to-be-hi.patch new file mode 100644 index 0000000000..930bb8a0a9 --- /dev/null +++ b/queue-6.19/cxl-adjust-the-startup-priority-of-cxl_pmem-to-be-hi.patch @@ -0,0 +1,52 @@ +From 5ca1315ba42d73888ff3e7b921aa6b2de90cf459 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Mar 2026 15:45:35 +0800 +Subject: cxl: Adjust the startup priority of cxl_pmem to be higher than that + of cxl_acpi + +From: Cui Chao + +[ Upstream commit be5c5280cf2b20e363dc8e2a424dd200a29b1c77 ] + +During the cxl_acpi probe process, it checks whether the cxl_nvb device +and driver have been attached. Currently, the startup priority of the +cxl_pmem driver is lower than that of the cxl_acpi driver. At this point, +the cxl_nvb driver has not yet been registered on the cxl_bus, causing +the attachment check to fail. This results in a failure to add the root +nvdimm bridge, leading to a cxl_acpi probe failure and ultimately +affecting the subsequent loading of cxl drivers. As a consequence, only +one mem device object exists on the cxl_bus, while the cxl_port device +objects and decoder device objects are missing. + +The solution is to raise the startup priority of cxl_pmem to be higher +than that of cxl_acpi, ensuring that the cxl_pmem driver is registered +before the aforementioned attachment check occurs. + +Co-developed-by: Wang Yinfeng +Signed-off-by: Wang Yinfeng +Signed-off-by: Cui Chao +Fixes: e7e222ad73d9 ("cxl: Move devm_cxl_add_nvdimm_bridge() to cxl_pmem.ko") +Reviewed-by: Dan Williams +Link: https://patch.msgid.link/20260319074535.1709250-1-cuichao1753@phytium.com.cn +Signed-off-by: Dave Jiang +Signed-off-by: Sasha Levin +--- + drivers/cxl/pmem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c +index c00b84b960761..3432fd83b1e2a 100644 +--- a/drivers/cxl/pmem.c ++++ b/drivers/cxl/pmem.c +@@ -554,7 +554,7 @@ static __exit void cxl_pmem_exit(void) + + MODULE_DESCRIPTION("CXL PMEM: Persistent Memory Support"); + MODULE_LICENSE("GPL v2"); +-module_init(cxl_pmem_init); ++subsys_initcall(cxl_pmem_init); + module_exit(cxl_pmem_exit); + MODULE_IMPORT_NS("CXL"); + MODULE_ALIAS_CXL(CXL_DEVICE_NVDIMM_BRIDGE); +-- +2.51.0 + diff --git a/queue-6.19/cxl-hdm-avoid-incorrect-dvsec-fallback-when-hdm-deco.patch b/queue-6.19/cxl-hdm-avoid-incorrect-dvsec-fallback-when-hdm-deco.patch new file mode 100644 index 0000000000..f3e32d9e6e --- /dev/null +++ b/queue-6.19/cxl-hdm-avoid-incorrect-dvsec-fallback-when-hdm-deco.patch @@ -0,0 +1,101 @@ +From 8f07e0f66cebd3e6a0a09b28bcae0381e54bc3db Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Mar 2026 20:19:49 +0000 +Subject: cxl/hdm: Avoid incorrect DVSEC fallback when HDM decoders are enabled + +From: Smita Koralahalli + +[ Upstream commit 75cea0776de502f2a1be5ca02d37c586dc81887e ] + +Check the global CXL_HDM_DECODER_ENABLE bit instead of looping over +per-decoder COMMITTED bits to determine whether to fall back to DVSEC +range emulation. When the HDM decoder capability is globally enabled, +ignore DVSEC range registers regardless of individual decoder commit +state. + +should_emulate_decoders() currently loops over per-decoder COMMITTED +bits, which leads to an incorrect DVSEC fallback when those bits are +zero. One way to trigger this is to destroy a region and bounce the +memdev: + + cxl disable-region region0 + cxl destroy-region region0 + cxl disable-memdev mem0 + cxl enable-memdev mem0 + +Region teardown zeroes the HDM decoder registers including the committed +bits. The subsequent memdev re-probe finds uncommitted decoders and falls +back to DVSEC emulation, even though HDM remains globally enabled. + +Observed failures: + + should_emulate_decoders: cxl_port endpoint6: decoder6.0: committed: 0 base: 0x0_00000000 size: 0x0_00000000 + devm_cxl_setup_hdm: cxl_port endpoint6: Fallback map 1 range register + .. + devm_cxl_add_region: cxl_acpi ACPI0017:00: decoder0.0: created region0 + __construct_region: cxl_pci 0000:e1:00.0: mem1:decoder6.0: + __construct_region region0 res: [mem 0x850000000-0x284fffffff flags 0x200] iw: 1 ig: 4096 + cxl region0: pci0000:e0:port1 cxl_port_setup_targets expected iw: 1 ig: 4096 .. + cxl region0: pci0000:e0:port1 cxl_port_setup_targets got iw: 1 ig: 256 state: disabled .. + cxl_port endpoint6: failed to attach decoder6.0 to region0: -6 + .. + devm_cxl_add_region: cxl_acpi ACPI0017:00: decoder0.0: created region4 + alloc_hpa: cxl region4: HPA allocation error (-34) .. + +Fixes: 52cc48ad2a76 ("cxl/hdm: Limit emulation to the number of range registers") +Signed-off-by: Smita Koralahalli +Reviewed-by: Dan Williams +Link: https://patch.msgid.link/20260316201950.224567-1-Smita.KoralahalliChannabasappa@amd.com +Signed-off-by: Dave Jiang +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/hdm.c | 25 +++++++++---------------- + 1 file changed, 9 insertions(+), 16 deletions(-) + +diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c +index bc4b0c8607258..ce27074bb5c7d 100644 +--- a/drivers/cxl/core/hdm.c ++++ b/drivers/cxl/core/hdm.c +@@ -94,7 +94,6 @@ static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info) + struct cxl_hdm *cxlhdm; + void __iomem *hdm; + u32 ctrl; +- int i; + + if (!info) + return false; +@@ -113,22 +112,16 @@ static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info) + return false; + + /* +- * If any decoders are committed already, there should not be any +- * emulated DVSEC decoders. ++ * If HDM decoders are globally enabled, do not fall back to DVSEC ++ * range emulation. Zeroed decoder registers after region teardown ++ * do not imply absence of HDM capability. ++ * ++ * Falling back to DVSEC here would treat the decoder as AUTO and ++ * may incorrectly latch default interleave settings. + */ +- for (i = 0; i < cxlhdm->decoder_count; i++) { +- ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(i)); +- dev_dbg(&info->port->dev, +- "decoder%d.%d: committed: %ld base: %#x_%.8x size: %#x_%.8x\n", +- info->port->id, i, +- FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl), +- readl(hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET(i)), +- readl(hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(i)), +- readl(hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET(i)), +- readl(hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(i))); +- if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl)) +- return false; +- } ++ ctrl = readl(hdm + CXL_HDM_DECODER_CTRL_OFFSET); ++ if (ctrl & CXL_HDM_DECODER_ENABLE) ++ return false; + + return true; + } +-- +2.51.0 + diff --git a/queue-6.19/cxl-port-fix-use-after-free-of-parent_port-in-cxl_de.patch b/queue-6.19/cxl-port-fix-use-after-free-of-parent_port-in-cxl_de.patch new file mode 100644 index 0000000000..ba719e62db --- /dev/null +++ b/queue-6.19/cxl-port-fix-use-after-free-of-parent_port-in-cxl_de.patch @@ -0,0 +1,96 @@ +From 8c7b353d55ac08b3c84681250e226a46a274d385 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Feb 2026 10:44:36 -0800 +Subject: cxl/port: Fix use after free of parent_port in cxl_detach_ep() + +From: Alison Schofield + +[ Upstream commit 19d2f0b97a131198efc2c4ca3eb7f980bba8c2b4 ] + +cxl_detach_ep() is called during bottom-up removal when all CXL memory +devices beneath a switch port have been removed. For each port in the +hierarchy it locks both the port and its parent, removes the endpoint, +and if the port is now empty, marks it dead and unregisters the port +by calling delete_switch_port(). There are two places during this work +where the parent_port may be used after freeing: + +First, a concurrent detach may have already processed a port by the +time a second worker finds it via bus_find_device(). Without pinning +parent_port, it may already be freed when we discover port->dead and +attempt to unlock the parent_port. In a production kernel that's a +silent memory corruption, with lock debug, it looks like this: + +[]DEBUG_LOCKS_WARN_ON(__owner_task(owner) != get_current()) +[]WARNING: kernel/locking/mutex.c:949 at __mutex_unlock_slowpath+0x1ee/0x310 +[]Call Trace: +[]mutex_unlock+0xd/0x20 +[]cxl_detach_ep+0x180/0x400 [cxl_core] +[]devm_action_release+0x10/0x20 +[]devres_release_all+0xa8/0xe0 +[]device_unbind_cleanup+0xd/0xa0 +[]really_probe+0x1a6/0x3e0 + +Second, delete_switch_port() releases three devm actions registered +against parent_port. The last of those is unregister_port() and it +calls device_unregister() on the child port, which can cascade. If +parent_port is now also empty the device core may unregister and free +it too. So by the time delete_switch_port() returns, parent_port may +be free, and the subsequent device_unlock(&parent_port->dev) operates +on freed memory. The kernel log looks same as above, with a different +offset in cxl_detach_ep(). + +Both of these issues stem from the absence of a lifetime guarantee +between a child port and its parent port. + +Establish a lifetime rule for ports: child ports hold a reference to +their parent device until release. Take the reference when the port +is allocated and drop it when released. This ensures the parent is +valid for the full lifetime of the child and eliminates the use after +free window in cxl_detach_ep(). + +This is easily reproduced with a reload of cxl_acpi in QEMU with CXL +devices present. + +Fixes: 2345df54249c ("cxl/memdev: Fix endpoint port removal") +Reviewed-by: Dave Jiang +Reviewed-by: Li Ming +Signed-off-by: Alison Schofield +Reviewed-by: Jonathan Cameron +Link: https://patch.msgid.link/20260226184439.1732841-1-alison.schofield@intel.com +Signed-off-by: Dave Jiang +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/port.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c +index 4717dcff264be..aa8b47c50c962 100644 +--- a/drivers/cxl/core/port.c ++++ b/drivers/cxl/core/port.c +@@ -552,10 +552,13 @@ static void cxl_port_release(struct device *dev) + xa_destroy(&port->dports); + xa_destroy(&port->regions); + ida_free(&cxl_port_ida, port->id); +- if (is_cxl_root(port)) ++ ++ if (is_cxl_root(port)) { + kfree(to_cxl_root(port)); +- else ++ } else { ++ put_device(dev->parent); + kfree(port); ++ } + } + + static ssize_t decoders_committed_show(struct device *dev, +@@ -721,6 +724,7 @@ static struct cxl_port *cxl_port_alloc(struct device *uport_dev, + struct cxl_port *iter; + + dev->parent = &parent_port->dev; ++ get_device(dev->parent); + port->depth = parent_port->depth + 1; + port->parent_dport = parent_dport; + +-- +2.51.0 + diff --git a/queue-6.19/cxl-region-fix-leakage-in-__construct_region.patch b/queue-6.19/cxl-region-fix-leakage-in-__construct_region.patch new file mode 100644 index 0000000000..345b394750 --- /dev/null +++ b/queue-6.19/cxl-region-fix-leakage-in-__construct_region.patch @@ -0,0 +1,43 @@ +From d87a52aeaff489eaad7bfafc54acf9410eb94a9d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 11:13:30 -0800 +Subject: cxl/region: Fix leakage in __construct_region() + +From: Davidlohr Bueso + +[ Upstream commit 77b310bb7b5ff8c017524df83292e0242ba89791 ] + +Failing the first sysfs_update_group() needs to explicitly +kfree the resource as it is too early for cxl_region_iomem_release() +to do so. + +Signed-off-by: Davidlohr Bueso +Reviewed-by: Ira Weiny +Reviewed-by: Gregory Price +Fixes: d6602e25819d (cxl/region: Add support to indicate region has extended linear cache) +Link: https://patch.msgid.link/20260202191330.245608-1-dave@stgolabs.net +Signed-off-by: Dave Jiang +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/region.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c +index 5bd1213737fa2..a3d06b852d05e 100644 +--- a/drivers/cxl/core/region.c ++++ b/drivers/cxl/core/region.c +@@ -3616,8 +3616,10 @@ static int __construct_region(struct cxl_region *cxlr, + } + + rc = sysfs_update_group(&cxlr->dev.kobj, &cxl_region_group); +- if (rc) ++ if (rc) { ++ kfree(res); + return rc; ++ } + + rc = insert_resource(cxlrd->res, res); + if (rc) { +-- +2.51.0 + diff --git a/queue-6.19/dma-buf-include-ioctl.h-in-uapi-header.patch b/queue-6.19/dma-buf-include-ioctl.h-in-uapi-header.patch new file mode 100644 index 0000000000..60238ae8a2 --- /dev/null +++ b/queue-6.19/dma-buf-include-ioctl.h-in-uapi-header.patch @@ -0,0 +1,44 @@ +From d4070244ac4f0512e630e5339f5ce81f81b76d7d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Mar 2026 16:23:09 -0800 +Subject: dma-buf: Include ioctl.h in UAPI header +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Isaac J. Manjarres + +[ Upstream commit a116bac87118903925108e57781bbfc7a7eea27b ] + +include/uapi/linux/dma-buf.h uses several macros from ioctl.h to define +its ioctl commands. However, it does not include ioctl.h itself. So, +if userspace source code tries to include the dma-buf.h file without +including ioctl.h, it can result in build failures. + +Therefore, include ioctl.h in the dma-buf UAPI header. + +Signed-off-by: Isaac J. Manjarres +Reviewed-by: T.J. Mercier +Reviewed-by: Christian König +Signed-off-by: Christian König +Link: https://lore.kernel.org/r/20260303002309.1401849-1-isaacmanjarres@google.com +Signed-off-by: Sasha Levin +--- + include/uapi/linux/dma-buf.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h +index 5a6fda66d9adf..e827c9d20c5d3 100644 +--- a/include/uapi/linux/dma-buf.h ++++ b/include/uapi/linux/dma-buf.h +@@ -20,6 +20,7 @@ + #ifndef _DMA_BUF_UAPI_H_ + #define _DMA_BUF_UAPI_H_ + ++#include + #include + + /** +-- +2.51.0 + diff --git a/queue-6.19/driver-core-generalize-driver_override-in-struct-dev.patch b/queue-6.19/driver-core-generalize-driver_override-in-struct-dev.patch new file mode 100644 index 0000000000..77642cd8f8 --- /dev/null +++ b/queue-6.19/driver-core-generalize-driver_override-in-struct-dev.patch @@ -0,0 +1,322 @@ +From df430c6f8e5fc4e88c9c113e20f101c06fe884be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Mar 2026 12:53:18 +0100 +Subject: driver core: generalize driver_override in struct device + +From: Danilo Krummrich + +[ Upstream commit cb3d1049f4ea77d5ad93f17d8ac1f2ed4da70501 ] + +Currently, there are 12 busses (including platform and PCI) that +duplicate the driver_override logic for their individual devices. + +All of them seem to be prone to the bug described in [1]. + +While this could be solved for every bus individually using a separate +lock, solving this in the driver-core generically results in less (and +cleaner) changes overall. + +Thus, move driver_override to struct device, provide corresponding +accessors for busses and handle locking with a separate lock internally. + +In particular, add device_set_driver_override(), +device_has_driver_override(), device_match_driver_override() and +generalize the sysfs store() and show() callbacks via a driver_override +feature flag in struct bus_type. + +Until all busses have migrated, keep driver_set_override() in place. + +Note that we can't use the device lock for the reasons described in [2]. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=220789 [1] +Link: https://lore.kernel.org/driver-core/DGRGTIRHA62X.3RY09D9SOK77P@kernel.org/ [2] +Tested-by: Gui-Dong Han +Co-developed-by: Gui-Dong Han +Signed-off-by: Gui-Dong Han +Reviewed-by: Greg Kroah-Hartman +Link: https://patch.msgid.link/20260303115720.48783-2-dakr@kernel.org +[ Use dev->bus instead of sp->bus for consistency; fix commit message to + refer to the struct bus_type's driver_override feature flag. - Danilo ] +Signed-off-by: Danilo Krummrich +Stable-dep-of: 2b38efc05bf7 ("driver core: platform: use generic driver_override infrastructure") +Signed-off-by: Sasha Levin +--- + drivers/base/bus.c | 43 ++++++++++++++++++++++++++- + drivers/base/core.c | 2 ++ + drivers/base/dd.c | 60 ++++++++++++++++++++++++++++++++++++++ + include/linux/device.h | 54 ++++++++++++++++++++++++++++++++++ + include/linux/device/bus.h | 4 +++ + 5 files changed, 162 insertions(+), 1 deletion(-) + +diff --git a/drivers/base/bus.c b/drivers/base/bus.c +index 9eb7771706f01..7c7d8d97215be 100644 +--- a/drivers/base/bus.c ++++ b/drivers/base/bus.c +@@ -504,6 +504,36 @@ int bus_for_each_drv(const struct bus_type *bus, struct device_driver *start, + } + EXPORT_SYMBOL_GPL(bus_for_each_drv); + ++static ssize_t driver_override_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ int ret; ++ ++ ret = __device_set_driver_override(dev, buf, count); ++ if (ret) ++ return ret; ++ ++ return count; ++} ++ ++static ssize_t driver_override_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ guard(spinlock)(&dev->driver_override.lock); ++ return sysfs_emit(buf, "%s\n", dev->driver_override.name); ++} ++static DEVICE_ATTR_RW(driver_override); ++ ++static struct attribute *driver_override_dev_attrs[] = { ++ &dev_attr_driver_override.attr, ++ NULL, ++}; ++ ++static const struct attribute_group driver_override_dev_group = { ++ .attrs = driver_override_dev_attrs, ++}; ++ + /** + * bus_add_device - add device to bus + * @dev: device being added +@@ -537,9 +567,15 @@ int bus_add_device(struct device *dev) + if (error) + goto out_put; + ++ if (dev->bus->driver_override) { ++ error = device_add_group(dev, &driver_override_dev_group); ++ if (error) ++ goto out_groups; ++ } ++ + error = sysfs_create_link(&sp->devices_kset->kobj, &dev->kobj, dev_name(dev)); + if (error) +- goto out_groups; ++ goto out_override; + + error = sysfs_create_link(&dev->kobj, &sp->subsys.kobj, "subsystem"); + if (error) +@@ -550,6 +586,9 @@ int bus_add_device(struct device *dev) + + out_subsys: + sysfs_remove_link(&sp->devices_kset->kobj, dev_name(dev)); ++out_override: ++ if (dev->bus->driver_override) ++ device_remove_group(dev, &driver_override_dev_group); + out_groups: + device_remove_groups(dev, sp->bus->dev_groups); + out_put: +@@ -607,6 +646,8 @@ void bus_remove_device(struct device *dev) + + sysfs_remove_link(&dev->kobj, "subsystem"); + sysfs_remove_link(&sp->devices_kset->kobj, dev_name(dev)); ++ if (dev->bus->driver_override) ++ device_remove_group(dev, &driver_override_dev_group); + device_remove_groups(dev, dev->bus->dev_groups); + if (klist_node_attached(&dev->p->knode_bus)) + klist_del(&dev->p->knode_bus); +diff --git a/drivers/base/core.c b/drivers/base/core.c +index 40de2f51a1b1a..9863bd3705255 100644 +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -2556,6 +2556,7 @@ static void device_release(struct kobject *kobj) + devres_release_all(dev); + + kfree(dev->dma_range_map); ++ kfree(dev->driver_override.name); + + if (dev->release) + dev->release(dev); +@@ -3159,6 +3160,7 @@ void device_initialize(struct device *dev) + kobject_init(&dev->kobj, &device_ktype); + INIT_LIST_HEAD(&dev->dma_pools); + mutex_init(&dev->mutex); ++ spin_lock_init(&dev->driver_override.lock); + lockdep_set_novalidate_class(&dev->mutex); + spin_lock_init(&dev->devres_lock); + INIT_LIST_HEAD(&dev->devres_head); +diff --git a/drivers/base/dd.c b/drivers/base/dd.c +index bea8da5f8a3a9..37c7e54e0e4c7 100644 +--- a/drivers/base/dd.c ++++ b/drivers/base/dd.c +@@ -381,6 +381,66 @@ static void __exit deferred_probe_exit(void) + } + __exitcall(deferred_probe_exit); + ++int __device_set_driver_override(struct device *dev, const char *s, size_t len) ++{ ++ const char *new, *old; ++ char *cp; ++ ++ if (!s) ++ return -EINVAL; ++ ++ /* ++ * The stored value will be used in sysfs show callback (sysfs_emit()), ++ * which has a length limit of PAGE_SIZE and adds a trailing newline. ++ * Thus we can store one character less to avoid truncation during sysfs ++ * show. ++ */ ++ if (len >= (PAGE_SIZE - 1)) ++ return -EINVAL; ++ ++ /* ++ * Compute the real length of the string in case userspace sends us a ++ * bunch of \0 characters like python likes to do. ++ */ ++ len = strlen(s); ++ ++ if (!len) { ++ /* Empty string passed - clear override */ ++ spin_lock(&dev->driver_override.lock); ++ old = dev->driver_override.name; ++ dev->driver_override.name = NULL; ++ spin_unlock(&dev->driver_override.lock); ++ kfree(old); ++ ++ return 0; ++ } ++ ++ cp = strnchr(s, len, '\n'); ++ if (cp) ++ len = cp - s; ++ ++ new = kstrndup(s, len, GFP_KERNEL); ++ if (!new) ++ return -ENOMEM; ++ ++ spin_lock(&dev->driver_override.lock); ++ old = dev->driver_override.name; ++ if (cp != s) { ++ dev->driver_override.name = new; ++ spin_unlock(&dev->driver_override.lock); ++ } else { ++ /* "\n" passed - clear override */ ++ dev->driver_override.name = NULL; ++ spin_unlock(&dev->driver_override.lock); ++ ++ kfree(new); ++ } ++ kfree(old); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(__device_set_driver_override); ++ + /** + * device_is_bound() - Check if device is bound to a driver + * @dev: device to check +diff --git a/include/linux/device.h b/include/linux/device.h +index 0be95294b6e61..e65d564f01cd7 100644 +--- a/include/linux/device.h ++++ b/include/linux/device.h +@@ -483,6 +483,8 @@ struct device_physical_location { + * on. This shrinks the "Board Support Packages" (BSPs) and + * minimizes board-specific #ifdefs in drivers. + * @driver_data: Private pointer for driver specific info. ++ * @driver_override: Driver name to force a match. Do not touch directly; use ++ * device_set_driver_override() instead. + * @links: Links to suppliers and consumers of this device. + * @power: For device power management. + * See Documentation/driver-api/pm/devices.rst for details. +@@ -576,6 +578,10 @@ struct device { + core doesn't touch it */ + void *driver_data; /* Driver data, set and get with + dev_set_drvdata/dev_get_drvdata */ ++ struct { ++ const char *name; ++ spinlock_t lock; ++ } driver_override; + struct mutex mutex; /* mutex to synchronize calls to + * its driver. + */ +@@ -701,6 +707,54 @@ struct device_link { + + #define kobj_to_dev(__kobj) container_of_const(__kobj, struct device, kobj) + ++int __device_set_driver_override(struct device *dev, const char *s, size_t len); ++ ++/** ++ * device_set_driver_override() - Helper to set or clear driver override. ++ * @dev: Device to change ++ * @s: NUL-terminated string, new driver name to force a match, pass empty ++ * string to clear it ("" or "\n", where the latter is only for sysfs ++ * interface). ++ * ++ * Helper to set or clear driver override of a device. ++ * ++ * Returns: 0 on success or a negative error code on failure. ++ */ ++static inline int device_set_driver_override(struct device *dev, const char *s) ++{ ++ return __device_set_driver_override(dev, s, s ? strlen(s) : 0); ++} ++ ++/** ++ * device_has_driver_override() - Check if a driver override has been set. ++ * @dev: device to check ++ * ++ * Returns true if a driver override has been set for this device. ++ */ ++static inline bool device_has_driver_override(struct device *dev) ++{ ++ guard(spinlock)(&dev->driver_override.lock); ++ return !!dev->driver_override.name; ++} ++ ++/** ++ * device_match_driver_override() - Match a driver against the device's driver_override. ++ * @dev: device to check ++ * @drv: driver to match against ++ * ++ * Returns > 0 if a driver override is set and matches the given driver, 0 if a ++ * driver override is set but does not match, or < 0 if a driver override is not ++ * set at all. ++ */ ++static inline int device_match_driver_override(struct device *dev, ++ const struct device_driver *drv) ++{ ++ guard(spinlock)(&dev->driver_override.lock); ++ if (dev->driver_override.name) ++ return !strcmp(dev->driver_override.name, drv->name); ++ return -1; ++} ++ + /** + * device_iommu_mapped - Returns true when the device DMA is translated + * by an IOMMU +diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h +index 99b1002b3e318..f047b40a30b74 100644 +--- a/include/linux/device/bus.h ++++ b/include/linux/device/bus.h +@@ -63,6 +63,9 @@ struct fwnode_handle; + * this bus. + * @pm: Power management operations of this bus, callback the specific + * device driver's pm-ops. ++ * @driver_override: Set to true if this bus supports the driver_override ++ * mechanism, which allows userspace to force a specific ++ * driver to bind to a device via a sysfs attribute. + * @need_parent_lock: When probing or removing a device on this bus, the + * device core should lock the device's parent. + * +@@ -104,6 +107,7 @@ struct bus_type { + + const struct dev_pm_ops *pm; + ++ bool driver_override; + bool need_parent_lock; + }; + +-- +2.51.0 + diff --git a/queue-6.19/driver-core-platform-use-generic-driver_override-inf.patch b/queue-6.19/driver-core-platform-use-generic-driver_override-inf.patch new file mode 100644 index 0000000000..17ef598f1d --- /dev/null +++ b/queue-6.19/driver-core-platform-use-generic-driver_override-inf.patch @@ -0,0 +1,200 @@ +From 05f8ae51d6e3702b5e9ca55fa6c74d45562b329c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Mar 2026 12:53:21 +0100 +Subject: driver core: platform: use generic driver_override infrastructure + +From: Danilo Krummrich + +[ Upstream commit 2b38efc05bf7a8568ec74bfffea0f5cfa62bc01d ] + +When a driver is probed through __driver_attach(), the bus' match() +callback is called without the device lock held, thus accessing the +driver_override field without a lock, which can cause a UAF. + +Fix this by using the driver-core driver_override infrastructure taking +care of proper locking internally. + +Note that calling match() from __driver_attach() without the device lock +held is intentional. [1] + +Link: https://lore.kernel.org/driver-core/DGRGTIRHA62X.3RY09D9SOK77P@kernel.org/ [1] +Reported-by: Gui-Dong Han +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220789 +Fixes: 3d713e0e382e ("driver core: platform: add device binding path 'driver_override'") +Reviewed-by: Greg Kroah-Hartman +Link: https://patch.msgid.link/20260303115720.48783-5-dakr@kernel.org +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + drivers/base/platform.c | 37 +++++---------------------------- + drivers/bus/simple-pm-bus.c | 4 ++-- + drivers/clk/imx/clk-scu.c | 3 +-- + drivers/slimbus/qcom-ngd-ctrl.c | 6 ++---- + include/linux/platform_device.h | 5 ----- + sound/soc/samsung/i2s.c | 6 +++--- + 6 files changed, 13 insertions(+), 48 deletions(-) + +diff --git a/drivers/base/platform.c b/drivers/base/platform.c +index b45d41b018ca6..d44591d52e363 100644 +--- a/drivers/base/platform.c ++++ b/drivers/base/platform.c +@@ -603,7 +603,6 @@ static void platform_device_release(struct device *dev) + kfree(pa->pdev.dev.platform_data); + kfree(pa->pdev.mfd_cell); + kfree(pa->pdev.resource); +- kfree(pa->pdev.driver_override); + kfree(pa); + } + +@@ -1306,38 +1305,9 @@ static ssize_t numa_node_show(struct device *dev, + } + static DEVICE_ATTR_RO(numa_node); + +-static ssize_t driver_override_show(struct device *dev, +- struct device_attribute *attr, char *buf) +-{ +- struct platform_device *pdev = to_platform_device(dev); +- ssize_t len; +- +- device_lock(dev); +- len = sysfs_emit(buf, "%s\n", pdev->driver_override); +- device_unlock(dev); +- +- return len; +-} +- +-static ssize_t driver_override_store(struct device *dev, +- struct device_attribute *attr, +- const char *buf, size_t count) +-{ +- struct platform_device *pdev = to_platform_device(dev); +- int ret; +- +- ret = driver_set_override(dev, &pdev->driver_override, buf, count); +- if (ret) +- return ret; +- +- return count; +-} +-static DEVICE_ATTR_RW(driver_override); +- + static struct attribute *platform_dev_attrs[] = { + &dev_attr_modalias.attr, + &dev_attr_numa_node.attr, +- &dev_attr_driver_override.attr, + NULL, + }; + +@@ -1377,10 +1347,12 @@ static int platform_match(struct device *dev, const struct device_driver *drv) + { + struct platform_device *pdev = to_platform_device(dev); + struct platform_driver *pdrv = to_platform_driver(drv); ++ int ret; + + /* When driver_override is set, only bind to the matching driver */ +- if (pdev->driver_override) +- return !strcmp(pdev->driver_override, drv->name); ++ ret = device_match_driver_override(dev, drv); ++ if (ret >= 0) ++ return ret; + + /* Attempt an OF style match first */ + if (of_driver_match_device(dev, drv)) +@@ -1516,6 +1488,7 @@ static const struct dev_pm_ops platform_dev_pm_ops = { + const struct bus_type platform_bus_type = { + .name = "platform", + .dev_groups = platform_dev_groups, ++ .driver_override = true, + .match = platform_match, + .uevent = platform_uevent, + .probe = platform_probe, +diff --git a/drivers/bus/simple-pm-bus.c b/drivers/bus/simple-pm-bus.c +index 3f00d953fb9a0..c920bd6fbaafd 100644 +--- a/drivers/bus/simple-pm-bus.c ++++ b/drivers/bus/simple-pm-bus.c +@@ -36,7 +36,7 @@ static int simple_pm_bus_probe(struct platform_device *pdev) + * that's not listed in simple_pm_bus_of_match. We don't want to do any + * of the simple-pm-bus tasks for these devices, so return early. + */ +- if (pdev->driver_override) ++ if (device_has_driver_override(&pdev->dev)) + return 0; + + match = of_match_device(dev->driver->of_match_table, dev); +@@ -78,7 +78,7 @@ static void simple_pm_bus_remove(struct platform_device *pdev) + { + const void *data = of_device_get_match_data(&pdev->dev); + +- if (pdev->driver_override || data) ++ if (device_has_driver_override(&pdev->dev) || data) + return; + + dev_dbg(&pdev->dev, "%s\n", __func__); +diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c +index c90d21e05f916..e6b273d8a09ae 100644 +--- a/drivers/clk/imx/clk-scu.c ++++ b/drivers/clk/imx/clk-scu.c +@@ -706,8 +706,7 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name, + if (ret) + goto put_device; + +- ret = driver_set_override(&pdev->dev, &pdev->driver_override, +- "imx-scu-clk", strlen("imx-scu-clk")); ++ ret = device_set_driver_override(&pdev->dev, "imx-scu-clk"); + if (ret) + goto put_device; + +diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c +index ba3d80d12605c..d2d11f6294b70 100644 +--- a/drivers/slimbus/qcom-ngd-ctrl.c ++++ b/drivers/slimbus/qcom-ngd-ctrl.c +@@ -1539,10 +1539,8 @@ static int of_qcom_slim_ngd_register(struct device *parent, + ngd->id = id; + ngd->pdev->dev.parent = parent; + +- ret = driver_set_override(&ngd->pdev->dev, +- &ngd->pdev->driver_override, +- QCOM_SLIM_NGD_DRV_NAME, +- strlen(QCOM_SLIM_NGD_DRV_NAME)); ++ ret = device_set_driver_override(&ngd->pdev->dev, ++ QCOM_SLIM_NGD_DRV_NAME); + if (ret) { + platform_device_put(ngd->pdev); + kfree(ngd); +diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h +index 813da101b5bf8..ed1d50d1c3c15 100644 +--- a/include/linux/platform_device.h ++++ b/include/linux/platform_device.h +@@ -31,11 +31,6 @@ struct platform_device { + struct resource *resource; + + const struct platform_device_id *id_entry; +- /* +- * Driver name to force a match. Do not set directly, because core +- * frees it. Use driver_set_override() to set or clear it. +- */ +- const char *driver_override; + + /* MFD cell pointer */ + struct mfd_cell *mfd_cell; +diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c +index e9964f0e010ae..140907a41a70d 100644 +--- a/sound/soc/samsung/i2s.c ++++ b/sound/soc/samsung/i2s.c +@@ -1360,10 +1360,10 @@ static int i2s_create_secondary_device(struct samsung_i2s_priv *priv) + if (!pdev_sec) + return -ENOMEM; + +- pdev_sec->driver_override = kstrdup("samsung-i2s", GFP_KERNEL); +- if (!pdev_sec->driver_override) { ++ ret = device_set_driver_override(&pdev_sec->dev, "samsung-i2s"); ++ if (ret) { + platform_device_put(pdev_sec); +- return -ENOMEM; ++ return ret; + } + + ret = platform_device_add(pdev_sec); +-- +2.51.0 + diff --git a/queue-6.19/drm-amdgpu-fix-gpu-idle-power-consumption-issue-for-.patch b/queue-6.19/drm-amdgpu-fix-gpu-idle-power-consumption-issue-for-.patch new file mode 100644 index 0000000000..f2a07f67a7 --- /dev/null +++ b/queue-6.19/drm-amdgpu-fix-gpu-idle-power-consumption-issue-for-.patch @@ -0,0 +1,50 @@ +From 38fa5eef98b4b90b307e54f8bed425dcc16468fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Mar 2026 18:45:45 -0500 +Subject: drm/amdgpu: fix gpu idle power consumption issue for gfx v12 + +From: Yang Wang + +[ Upstream commit a6571045cf06c4aa749b4801382ae96650e2f0e1 ] + +Older versions of the MES firmware may cause abnormal GPU power consumption. +When performing inference tasks on the GPU (e.g., with Ollama using ROCm), +the GPU may show abnormal power consumption in idle state and incorrect GPU load information. +This issue has been fixed in firmware version 0x8b and newer. + +Closes: https://github.com/ROCm/ROCm/issues/5706 +Signed-off-by: Yang Wang +Acked-by: Alex Deucher +Signed-off-by: Alex Deucher +(cherry picked from commit 4e22a5fe6ea6e0b057e7f246df4ac3ff8bfbc46a) +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/mes_v12_0.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c +index 231aba48d8d28..dcafbd7066c40 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c +@@ -731,6 +731,9 @@ static int mes_v12_0_set_hw_resources(struct amdgpu_mes *mes, int pipe) + int i; + struct amdgpu_device *adev = mes->adev; + union MESAPI_SET_HW_RESOURCES mes_set_hw_res_pkt; ++ uint32_t mes_rev = (pipe == AMDGPU_MES_SCHED_PIPE) ? ++ (mes->sched_version & AMDGPU_MES_VERSION_MASK) : ++ (mes->kiq_version & AMDGPU_MES_VERSION_MASK); + + memset(&mes_set_hw_res_pkt, 0, sizeof(mes_set_hw_res_pkt)); + +@@ -785,7 +788,7 @@ static int mes_v12_0_set_hw_resources(struct amdgpu_mes *mes, int pipe) + * handling support, other queue will not use the oversubscribe timer. + * handling mode - 0: disabled; 1: basic version; 2: basic+ version + */ +- mes_set_hw_res_pkt.oversubscription_timer = 50; ++ mes_set_hw_res_pkt.oversubscription_timer = mes_rev < 0x8b ? 0 : 50; + mes_set_hw_res_pkt.unmapped_doorbell_handling = 1; + + if (amdgpu_mes_log_enable) { +-- +2.51.0 + diff --git a/queue-6.19/drm-ttm-tests-fix-build-failure-on-preempt_rt.patch b/queue-6.19/drm-ttm-tests-fix-build-failure-on-preempt_rt.patch new file mode 100644 index 0000000000..1d7962d7b0 --- /dev/null +++ b/queue-6.19/drm-ttm-tests-fix-build-failure-on-preempt_rt.patch @@ -0,0 +1,48 @@ +From e4c4ca44b766df152d0418ecba3a712f8b406994 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Mar 2026 09:56:16 +0100 +Subject: drm/ttm/tests: Fix build failure on PREEMPT_RT +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Maarten Lankhorst + +[ Upstream commit a58d487fb1a52579d3c37544ea371da78ed70c45 ] + +Fix a compile error in the kunit tests when CONFIG_PREEMPT_RT is +enabled, and the normal mutex is converted into a rtmutex. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202602261547.3bM6yVAS-lkp@intel.com/ +Reviewed-by: Jouni Högander +Link: https://patch.msgid.link/20260304085616.1216961-1-dev@lankhorst.se +Signed-off-by: Maarten Lankhorst +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/ttm/tests/ttm_bo_test.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/ttm/tests/ttm_bo_test.c b/drivers/gpu/drm/ttm/tests/ttm_bo_test.c +index d468f83220720..f3103307b5df9 100644 +--- a/drivers/gpu/drm/ttm/tests/ttm_bo_test.c ++++ b/drivers/gpu/drm/ttm/tests/ttm_bo_test.c +@@ -222,13 +222,13 @@ static void ttm_bo_reserve_interrupted(struct kunit *test) + KUNIT_FAIL(test, "Couldn't create ttm bo reserve task\n"); + + /* Take a lock so the threaded reserve has to wait */ +- mutex_lock(&bo->base.resv->lock.base); ++ dma_resv_lock(bo->base.resv, NULL); + + wake_up_process(task); + msleep(20); + err = kthread_stop(task); + +- mutex_unlock(&bo->base.resv->lock.base); ++ dma_resv_unlock(bo->base.resv); + + KUNIT_ASSERT_EQ(test, err, -ERESTARTSYS); + } +-- +2.51.0 + diff --git a/queue-6.19/hid-apple-add-epomaker-th87-to-the-non-apple-keyboar.patch b/queue-6.19/hid-apple-add-epomaker-th87-to-the-non-apple-keyboar.patch new file mode 100644 index 0000000000..40ad711680 --- /dev/null +++ b/queue-6.19/hid-apple-add-epomaker-th87-to-the-non-apple-keyboar.patch @@ -0,0 +1,41 @@ +From c66217b4840d7abd2739d69b055a6afddd1683a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Feb 2026 10:00:02 +0100 +Subject: HID: apple: Add EPOMAKER TH87 to the non-apple keyboards list + +From: Takashi Iwai + +[ Upstream commit 7c698de0dc5daa1e1a5fd1f0c6aa1b6bb2f5d867 ] + +EPOMAKER TH87 has the very same ID as Apple Aluminum keyboard +(05ac:024f) although it doesn't work as expected in compatible way. + +Put three entries to the non-apple keyboards list to exclude this +device: one for BT ("TH87"), one for USB ("HFD Epomaker TH87") and one +for dongle ("2.4G Wireless Receiver"). + +Link: https://bugzilla.suse.com/show_bug.cgi?id=1258455 +Signed-off-by: Takashi Iwai +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-apple.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 233e367cce1d1..2f9a2e07c4263 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -365,6 +365,9 @@ static const struct apple_non_apple_keyboard non_apple_keyboards[] = { + { "A3R" }, + { "hfd.cn" }, + { "WKB603" }, ++ { "TH87" }, /* EPOMAKER TH87 BT mode */ ++ { "HFD Epomaker TH87" }, /* EPOMAKER TH87 USB mode */ ++ { "2.4G Wireless Receiver" }, /* EPOMAKER TH87 dongle */ + }; + + static bool apple_is_non_apple_keyboard(struct hid_device *hdev) +-- +2.51.0 + diff --git a/queue-6.19/hid-apple-avoid-memory-leak-in-apple_report_fixup.patch b/queue-6.19/hid-apple-avoid-memory-leak-in-apple_report_fixup.patch new file mode 100644 index 0000000000..2f1ec69d86 --- /dev/null +++ b/queue-6.19/hid-apple-avoid-memory-leak-in-apple_report_fixup.patch @@ -0,0 +1,45 @@ +From b1b6cbfb573c941491e7f1bdedbfe7b6880a146d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Feb 2026 16:43:36 +0100 +Subject: HID: apple: avoid memory leak in apple_report_fixup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Günther Noack + +[ Upstream commit 239c15116d80f67d32f00acc34575f1a6b699613 ] + +The apple_report_fixup() function was returning a +newly kmemdup()-allocated buffer, but never freeing it. + +The caller of report_fixup() does not take ownership of the returned +pointer, but it *is* permitted to return a sub-portion of the input +rdesc, whose lifetime is managed by the caller. + +Assisted-by: Gemini-CLI:Google Gemini 3 +Signed-off-by: Günther Noack +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-apple.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 2f9a2e07c4263..9dcb252c5d6c7 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -689,9 +689,7 @@ static const __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc, + hid_info(hdev, + "fixing up Magic Keyboard battery report descriptor\n"); + *rsize = *rsize - 1; +- rdesc = kmemdup(rdesc + 1, *rsize, GFP_KERNEL); +- if (!rdesc) +- return NULL; ++ rdesc = rdesc + 1; + + rdesc[0] = 0x05; + rdesc[1] = 0x01; +-- +2.51.0 + diff --git a/queue-6.19/hid-asus-add-xg-mobile-2023-external-hardware-suppor.patch b/queue-6.19/hid-asus-add-xg-mobile-2023-external-hardware-suppor.patch new file mode 100644 index 0000000000..7a6a30a53b --- /dev/null +++ b/queue-6.19/hid-asus-add-xg-mobile-2023-external-hardware-suppor.patch @@ -0,0 +1,49 @@ +From 9e25b6c298b1770817d26748217a43ad171426cc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 18:55:38 +0100 +Subject: HID: asus: add xg mobile 2023 external hardware support + +From: Denis Benato + +[ Upstream commit 377f8e788945d45b012ed9cfc35ca56c02e86cd8 ] + +XG mobile stations have the 0x5a endpoint and has to be initialized: +add them to hid-asus. + +Signed-off-by: Denis Benato +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-asus.c | 3 +++ + drivers/hid/hid-ids.h | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index 8487332bf43b0..b1ad4e9f20c85 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -1404,6 +1404,9 @@ static const struct hid_device_id asus_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, + USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X), + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_ALLY_XPAD }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, ++ USB_DEVICE_ID_ASUSTEK_XGM_2023), ++ }, + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, + USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD), + QUIRK_ROG_CLAYMORE_II_KEYBOARD }, +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 85ab1ac511096..7fd67745ee010 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -229,6 +229,7 @@ + #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X 0x1b4c + #define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b + #define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869 ++#define USB_DEVICE_ID_ASUSTEK_XGM_2023 0x1a9a + + #define USB_VENDOR_ID_ATEN 0x0557 + #define USB_DEVICE_ID_ATEN_UC100KM 0x2004 +-- +2.51.0 + diff --git a/queue-6.19/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch b/queue-6.19/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch new file mode 100644 index 0000000000..4449f64bd9 --- /dev/null +++ b/queue-6.19/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch @@ -0,0 +1,65 @@ +From fd069712a07adcd44bdc37628407e7f5193db329 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Feb 2026 16:43:38 +0100 +Subject: HID: asus: avoid memory leak in asus_report_fixup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Günther Noack + +[ Upstream commit 2bad24c17742fc88973d6aea526ce1353f5334a3 ] + +The asus_report_fixup() function was returning a newly allocated +kmemdup()-allocated buffer, but never freeing it. Switch to +devm_kzalloc() to ensure the memory is managed and freed automatically +when the device is removed. + +The caller of report_fixup() does not take ownership of the returned +pointer, but it is permitted to return a pointer whose lifetime is at +least that of the input buffer. + +Also fix a harmless out-of-bounds read by copying only the original +descriptor size. + +Assisted-by: Gemini-CLI:Google Gemini 3 +Signed-off-by: Günther Noack +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-asus.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index 472bca54642b9..8487332bf43b0 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -1306,14 +1306,21 @@ static const __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, + */ + if (*rsize == rsize_orig && + rdesc[offs] == 0x09 && rdesc[offs + 1] == 0x76) { +- *rsize = rsize_orig + 1; +- rdesc = kmemdup(rdesc, *rsize, GFP_KERNEL); +- if (!rdesc) +- return NULL; ++ __u8 *new_rdesc; ++ ++ new_rdesc = devm_kzalloc(&hdev->dev, rsize_orig + 1, ++ GFP_KERNEL); ++ if (!new_rdesc) ++ return rdesc; + + hid_info(hdev, "Fixing up %s keyb report descriptor\n", + drvdata->quirks & QUIRK_T100CHI ? + "T100CHI" : "T90CHI"); ++ ++ memcpy(new_rdesc, rdesc, rsize_orig); ++ *rsize = rsize_orig + 1; ++ rdesc = new_rdesc; ++ + memmove(rdesc + offs + 4, rdesc + offs + 2, 12); + rdesc[offs] = 0x19; + rdesc[offs + 1] = 0x00; +-- +2.51.0 + diff --git a/queue-6.19/hid-intel-ish-hid-ipc-add-nova-lake-h-s-pci-device-i.patch b/queue-6.19/hid-intel-ish-hid-ipc-add-nova-lake-h-s-pci-device-i.patch new file mode 100644 index 0000000000..89d9630ba8 --- /dev/null +++ b/queue-6.19/hid-intel-ish-hid-ipc-add-nova-lake-h-s-pci-device-i.patch @@ -0,0 +1,79 @@ +From 7f5c64a6b4a92141c847f39d798042253d463db6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Feb 2026 08:55:07 +0800 +Subject: HID: intel-ish-hid: ipc: Add Nova Lake-H/S PCI device IDs + +From: Zhang Lixu + +[ Upstream commit 22f8bcec5aeb05104b3eaa950cb5a345e95f0aa8 ] + +Add device IDs of Nova Lake-H and Nova Lake-S into ishtp support list. + +Signed-off-by: Zhang Lixu +Reviewed-by: Andy Shevchenko +Acked-by: Srinivas Pandruvada +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/intel-ish-hid/ipc/hw-ish.h | 2 ++ + drivers/hid/intel-ish-hid/ipc/pci-ish.c | 12 ++++++++++++ + 2 files changed, 14 insertions(+) + +diff --git a/drivers/hid/intel-ish-hid/ipc/hw-ish.h b/drivers/hid/intel-ish-hid/ipc/hw-ish.h +index fa5d68c363134..27389971b96cc 100644 +--- a/drivers/hid/intel-ish-hid/ipc/hw-ish.h ++++ b/drivers/hid/intel-ish-hid/ipc/hw-ish.h +@@ -39,6 +39,8 @@ + #define PCI_DEVICE_ID_INTEL_ISH_PTL_H 0xE345 + #define PCI_DEVICE_ID_INTEL_ISH_PTL_P 0xE445 + #define PCI_DEVICE_ID_INTEL_ISH_WCL 0x4D45 ++#define PCI_DEVICE_ID_INTEL_ISH_NVL_H 0xD354 ++#define PCI_DEVICE_ID_INTEL_ISH_NVL_S 0x6E78 + + #define REVISION_ID_CHT_A0 0x6 + #define REVISION_ID_CHT_Ax_SI 0x0 +diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c +index 1612e8cb23f0c..ed3405c05e73c 100644 +--- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c ++++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c +@@ -28,11 +28,15 @@ enum ishtp_driver_data_index { + ISHTP_DRIVER_DATA_LNL_M, + ISHTP_DRIVER_DATA_PTL, + ISHTP_DRIVER_DATA_WCL, ++ ISHTP_DRIVER_DATA_NVL_H, ++ ISHTP_DRIVER_DATA_NVL_S, + }; + + #define ISH_FW_GEN_LNL_M "lnlm" + #define ISH_FW_GEN_PTL "ptl" + #define ISH_FW_GEN_WCL "wcl" ++#define ISH_FW_GEN_NVL_H "nvlh" ++#define ISH_FW_GEN_NVL_S "nvls" + + #define ISH_FIRMWARE_PATH(gen) "intel/ish/ish_" gen ".bin" + #define ISH_FIRMWARE_PATH_ALL "intel/ish/ish_*.bin" +@@ -47,6 +51,12 @@ static struct ishtp_driver_data ishtp_driver_data[] = { + [ISHTP_DRIVER_DATA_WCL] = { + .fw_generation = ISH_FW_GEN_WCL, + }, ++ [ISHTP_DRIVER_DATA_NVL_H] = { ++ .fw_generation = ISH_FW_GEN_NVL_H, ++ }, ++ [ISHTP_DRIVER_DATA_NVL_S] = { ++ .fw_generation = ISH_FW_GEN_NVL_S, ++ }, + }; + + static const struct pci_device_id ish_pci_tbl[] = { +@@ -76,6 +86,8 @@ static const struct pci_device_id ish_pci_tbl[] = { + {PCI_DEVICE_DATA(INTEL, ISH_PTL_H, ISHTP_DRIVER_DATA_PTL)}, + {PCI_DEVICE_DATA(INTEL, ISH_PTL_P, ISHTP_DRIVER_DATA_PTL)}, + {PCI_DEVICE_DATA(INTEL, ISH_WCL, ISHTP_DRIVER_DATA_WCL)}, ++ {PCI_DEVICE_DATA(INTEL, ISH_NVL_H, ISHTP_DRIVER_DATA_NVL_H)}, ++ {PCI_DEVICE_DATA(INTEL, ISH_NVL_S, ISHTP_DRIVER_DATA_NVL_S)}, + {} + }; + MODULE_DEVICE_TABLE(pci, ish_pci_tbl); +-- +2.51.0 + diff --git a/queue-6.19/hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch b/queue-6.19/hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch new file mode 100644 index 0000000000..72140ffd95 --- /dev/null +++ b/queue-6.19/hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch @@ -0,0 +1,45 @@ +From 5e1a5ae99f9dfff8add46a1a6db6faf4d8a50d25 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Feb 2026 16:43:37 +0100 +Subject: HID: magicmouse: avoid memory leak in magicmouse_report_fixup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Günther Noack + +[ Upstream commit 91e8c6e601bdc1ccdf886479b6513c01c7e51c2c ] + +The magicmouse_report_fixup() function was returning a +newly kmemdup()-allocated buffer, but never freeing it. + +The caller of report_fixup() does not take ownership of the returned +pointer, but it *is* permitted to return a sub-portion of the input +rdesc, whose lifetime is managed by the caller. + +Assisted-by: Gemini-CLI:Google Gemini 3 +Signed-off-by: Günther Noack +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-magicmouse.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index f4cf29c2e8330..9eadf3252d0dc 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -994,9 +994,7 @@ static const __u8 *magicmouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, + hid_info(hdev, + "fixing up magicmouse battery report descriptor\n"); + *rsize = *rsize - 1; +- rdesc = kmemdup(rdesc + 1, *rsize, GFP_KERNEL); +- if (!rdesc) +- return NULL; ++ rdesc = rdesc + 1; + + rdesc[0] = 0x05; + rdesc[1] = 0x01; +-- +2.51.0 + diff --git a/queue-6.19/hid-magicmouse-fix-battery-reporting-for-apple-magic.patch b/queue-6.19/hid-magicmouse-fix-battery-reporting-for-apple-magic.patch new file mode 100644 index 0000000000..b415d5f226 --- /dev/null +++ b/queue-6.19/hid-magicmouse-fix-battery-reporting-for-apple-magic.patch @@ -0,0 +1,41 @@ +From 38f6ba06c2746e65fbb30f500821e5b70bee5bc3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Feb 2026 20:34:21 +0100 +Subject: HID: magicmouse: fix battery reporting for Apple Magic Trackpad 2 + +From: Julius Lehmann + +[ Upstream commit 5f3518d77419255f8b12bb23c8ec22acbeb6bc5b ] + +Battery reporting does not work for the Apple Magic Trackpad 2 if it is +connected via USB. The current hid descriptor fixup code checks for a +hid descriptor length of exactly 83 bytes. If the hid descriptor is +larger, which is the case for newer apple mice, the fixup is not +applied. + +This fix checks for hid descriptor sizes greater/equal 83 bytes which +applies the fixup for newer devices as well. + +Signed-off-by: Julius Lehmann +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-magicmouse.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 91f621ceb924b..f4cf29c2e8330 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -990,7 +990,7 @@ static const __u8 *magicmouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, + */ + if ((is_usb_magicmouse2(hdev->vendor, hdev->product) || + is_usb_magictrackpad2(hdev->vendor, hdev->product)) && +- *rsize == 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) { ++ *rsize >= 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) { + hid_info(hdev, + "fixing up magicmouse battery report descriptor\n"); + *rsize = *rsize - 1; +-- +2.51.0 + diff --git a/queue-6.19/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch b/queue-6.19/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch new file mode 100644 index 0000000000..868120e570 --- /dev/null +++ b/queue-6.19/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch @@ -0,0 +1,41 @@ +From a8e9adeb827018fab9d4d588659a49a69541b793 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 17:32:58 +0100 +Subject: HID: mcp2221: cancel last I2C command on read error + +From: Romain Sioen + +[ Upstream commit e31b556c0ba21f20c298aa61181b96541140b7b9 ] + +When an I2C SMBus read operation fails, the MCP2221 internal state machine +may not reset correctly, causing subsequent transactions to fail. + +By adding a short delay and explicitly cancelling the last command, +we ensure the device is ready for the next operation. + +Fix an issue where i2cdetect was not able to detect all devices correctly +on the bus. + +Signed-off-by: Romain Sioen +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-mcp2221.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c +index 33603b019f975..ef3b5c77c38e3 100644 +--- a/drivers/hid/hid-mcp2221.c ++++ b/drivers/hid/hid-mcp2221.c +@@ -353,6 +353,8 @@ static int mcp_i2c_smbus_read(struct mcp2221 *mcp, + usleep_range(90, 100); + retries++; + } else { ++ usleep_range(980, 1000); ++ mcp_cancel_last_cmd(mcp); + return ret; + } + } else { +-- +2.51.0 + diff --git a/queue-6.19/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch b/queue-6.19/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch new file mode 100644 index 0000000000..00576bc33b --- /dev/null +++ b/queue-6.19/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch @@ -0,0 +1,43 @@ +From 498f6f119024596e4648ec8b4fc4d05f59df8819 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Mar 2026 12:53:20 +0100 +Subject: hwmon: axi-fan: don't use driver_override as IRQ name +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Danilo Krummrich + +[ Upstream commit 813bbc4d33d2ca5b0da63e70ae13b60874f20d37 ] + +Do not use driver_override as IRQ name, as it is not guaranteed to point +to a valid string; use NULL instead (which makes the devm IRQ helpers +use dev_name()). + +Fixes: 8412b410fa5e ("hwmon: Support ADI Fan Control IP") +Reviewed-by: Nuno Sá +Acked-by: Guenter Roeck +Reviewed-by: Greg Kroah-Hartman +Link: https://patch.msgid.link/20260303115720.48783-4-dakr@kernel.org +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + drivers/hwmon/axi-fan-control.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c +index b7bb325c3ad96..01590dfa55e60 100644 +--- a/drivers/hwmon/axi-fan-control.c ++++ b/drivers/hwmon/axi-fan-control.c +@@ -507,7 +507,7 @@ static int axi_fan_control_probe(struct platform_device *pdev) + ret = devm_request_threaded_irq(&pdev->dev, ctl->irq, NULL, + axi_fan_control_irq_handler, + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, +- pdev->driver_override, ctl); ++ NULL, ctl); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "failed to request an irq\n"); +-- +2.51.0 + diff --git a/queue-6.19/i3c-master-dw-i3c-fix-missing-of_node-for-virtual-i2.patch b/queue-6.19/i3c-master-dw-i3c-fix-missing-of_node-for-virtual-i2.patch new file mode 100644 index 0000000000..c79d32ad1d --- /dev/null +++ b/queue-6.19/i3c-master-dw-i3c-fix-missing-of_node-for-virtual-i2.patch @@ -0,0 +1,43 @@ +From edd784a5daf634a63063daf40d8ac60e3f4c366f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Mar 2026 15:56:42 +0800 +Subject: i3c: master: dw-i3c: Fix missing of_node for virtual I2C adapter + +From: Peter Yin + +[ Upstream commit f26ecaa0f0abfe5db173416214098a00d3b7db79 ] + +The DesignWare I3C master driver creates a virtual I2C adapter to +provide backward compatibility with I2C devices. However, the current +implementation does not associate this virtual adapter with any +Device Tree node. + +Propagate the of_node from the I3C master platform device to the +virtual I2C adapter's device structure. This ensures that standard +I2C aliases are correctly resolved and bus numbering remains consistent. + +Signed-off-by: Peter Yin +Reviewed-by: Frank Li +Link: https://patch.msgid.link/20260302075645.1492766-1-peteryin.openbmc@gmail.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/dw-i3c-master.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c +index f9b981abd10c5..1368c834ca5e8 100644 +--- a/drivers/i3c/master/dw-i3c-master.c ++++ b/drivers/i3c/master/dw-i3c-master.c +@@ -1614,6 +1614,8 @@ int dw_i3c_common_probe(struct dw_i3c_master *master, + pm_runtime_get_noresume(&pdev->dev); + + INIT_WORK(&master->hj_work, dw_i3c_hj_work); ++ ++ device_set_of_node_from_dev(&master->base.i2c.dev, &pdev->dev); + ret = i3c_master_register(&master->base, &pdev->dev, + &dw_mipi_i3c_ops, false); + if (ret) +-- +2.51.0 + diff --git a/queue-6.19/kbuild-install-extmod-build-package-resolve_btfids-i.patch b/queue-6.19/kbuild-install-extmod-build-package-resolve_btfids-i.patch new file mode 100644 index 0000000000..3fffe25d84 --- /dev/null +++ b/queue-6.19/kbuild-install-extmod-build-package-resolve_btfids-i.patch @@ -0,0 +1,47 @@ +From 49d96955df110fa6747fc09fd2c6848a92e2572a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Feb 2026 08:41:48 +0100 +Subject: kbuild: install-extmod-build: Package resolve_btfids if necessary +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weißschuh + +[ Upstream commit 459cb3c054c2352bb321648744b620259a716b60 ] + +When CONFIG_DEBUG_INFO_BTF_MODULES is enabled and vmlinux is available, +Makefile.modfinal and gen-btf.sh will try to use resolve_btfids on the +module .ko. install-extmod-build currently does not package +resolve_btfids, so that step fails. + +Package resolve_btfids if it may be used. + +Signed-off-by: Thomas Weißschuh +Reviewed-by: Nicolas Schier +Link: https://patch.msgid.link/20260226-kbuild-resolve_btfids-v1-1-2bf38b93dfe7@linutronix.de +[nathan: Small commit message tweaks] +Signed-off-by: Nathan Chancellor +Signed-off-by: Sasha Levin +--- + scripts/package/install-extmod-build | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/scripts/package/install-extmod-build b/scripts/package/install-extmod-build +index 2576cf7902dbb..f12e1ffe409eb 100755 +--- a/scripts/package/install-extmod-build ++++ b/scripts/package/install-extmod-build +@@ -32,6 +32,10 @@ mkdir -p "${destdir}" + echo tools/objtool/objtool + fi + ++ if is_enabled CONFIG_DEBUG_INFO_BTF_MODULES; then ++ echo tools/bpf/resolve_btfids/resolve_btfids ++ fi ++ + echo Module.symvers + echo "arch/${SRCARCH}/include/generated" + echo include/config/auto.conf +-- +2.51.0 + diff --git a/queue-6.19/livepatch-klp-build-fix-inconsistent-kernel-version.patch b/queue-6.19/livepatch-klp-build-fix-inconsistent-kernel-version.patch new file mode 100644 index 0000000000..714dd74167 --- /dev/null +++ b/queue-6.19/livepatch-klp-build-fix-inconsistent-kernel-version.patch @@ -0,0 +1,55 @@ +From c6e4d406e5f1ed308468026c183f8a8d0a8ccf79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Mar 2026 16:37:48 -0400 +Subject: livepatch/klp-build: Fix inconsistent kernel version + +From: Josh Poimboeuf + +[ Upstream commit 6f93f7b06810d04acc6b106a7d5ecd6000f80545 ] + +If .config hasn't been synced with auto.conf, any recent changes to +CONFIG_LOCALVERSION* may not get reflected in the kernel version name. + +Use "make syncconfig" to force them to sync, and "make -s kernelrelease" +to get the version instead of having to construct it manually. + +Fixes: 24ebfcd65a87 ("livepatch/klp-build: Introduce klp-build script for generating livepatch modules") +Closes: https://lore.kernel.org/20260217160645.3434685-10-joe.lawrence@redhat.com +Reported-by: Joe Lawrence +Signed-off-by: Josh Poimboeuf +Signed-off-by: Joe Lawrence +Acked-by: Song Liu +Link: https://patch.msgid.link/20260310203751.1479229-10-joe.lawrence@redhat.com +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + scripts/livepatch/klp-build | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build +index 809e198a561d5..7b82c7503c2bf 100755 +--- a/scripts/livepatch/klp-build ++++ b/scripts/livepatch/klp-build +@@ -285,15 +285,14 @@ set_module_name() { + # application from appending it with '+' due to a dirty git working tree. + set_kernelversion() { + local file="$SRC/scripts/setlocalversion" +- local localversion ++ local kernelrelease + + stash_file "$file" + +- localversion="$(cd "$SRC" && make --no-print-directory kernelversion)" +- localversion="$(cd "$SRC" && KERNELVERSION="$localversion" ./scripts/setlocalversion)" +- [[ -z "$localversion" ]] && die "setlocalversion failed" ++ kernelrelease="$(cd "$SRC" && make syncconfig &>/dev/null && make -s kernelrelease)" ++ [[ -z "$kernelrelease" ]] && die "failed to get kernel version" + +- sed -i "2i echo $localversion; exit 0" scripts/setlocalversion ++ sed -i "2i echo $kernelrelease; exit 0" scripts/setlocalversion + } + + get_patch_files() { +-- +2.51.0 + diff --git a/queue-6.19/module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch b/queue-6.19/module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch new file mode 100644 index 0000000000..dbacc0b08b --- /dev/null +++ b/queue-6.19/module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch @@ -0,0 +1,80 @@ +From e2e7b4a746ad5e583f0ae3183c883ee5c79095e6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Dec 2025 10:32:08 -0800 +Subject: module: Fix kernel panic when a symbol st_shndx is out of bounds + +From: Ihor Solodrai + +[ Upstream commit f9d69d5e7bde2295eb7488a56f094ac8f5383b92 ] + +The module loader doesn't check for bounds of the ELF section index in +simplify_symbols(): + + for (i = 1; i < symsec->sh_size / sizeof(Elf_Sym); i++) { + const char *name = info->strtab + sym[i].st_name; + + switch (sym[i].st_shndx) { + case SHN_COMMON: + + [...] + + default: + /* Divert to percpu allocation if a percpu var. */ + if (sym[i].st_shndx == info->index.pcpu) + secbase = (unsigned long)mod_percpu(mod); + else + /** HERE --> **/ secbase = info->sechdrs[sym[i].st_shndx].sh_addr; + sym[i].st_value += secbase; + break; + } + } + +A symbol with an out-of-bounds st_shndx value, for example 0xffff +(known as SHN_XINDEX or SHN_HIRESERVE), may cause a kernel panic: + + BUG: unable to handle page fault for address: ... + RIP: 0010:simplify_symbols+0x2b2/0x480 + ... + Kernel panic - not syncing: Fatal exception + +This can happen when module ELF is legitimately using SHN_XINDEX or +when it is corrupted. + +Add a bounds check in simplify_symbols() to validate that st_shndx is +within the valid range before using it. + +This issue was discovered due to a bug in llvm-objcopy, see relevant +discussion for details [1]. + +[1] https://lore.kernel.org/linux-modules/20251224005752.201911-1-ihor.solodrai@linux.dev/ + +Signed-off-by: Ihor Solodrai +Reviewed-by: Daniel Gomez +Reviewed-by: Petr Pavlu +Signed-off-by: Sami Tolvanen +Signed-off-by: Sasha Levin +--- + kernel/module/main.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/kernel/module/main.c b/kernel/module/main.c +index bcd259505c8b3..21c5c0d14fa83 100644 +--- a/kernel/module/main.c ++++ b/kernel/module/main.c +@@ -1568,6 +1568,13 @@ static int simplify_symbols(struct module *mod, const struct load_info *info) + break; + + default: ++ if (sym[i].st_shndx >= info->hdr->e_shnum) { ++ pr_err("%s: Symbol %s has an invalid section index %u (max %u)\n", ++ mod->name, name, sym[i].st_shndx, info->hdr->e_shnum - 1); ++ ret = -ENOEXEC; ++ break; ++ } ++ + /* Divert to percpu allocation if a percpu var. */ + if (sym[i].st_shndx == info->index.pcpu) + secbase = (unsigned long)mod_percpu(mod); +-- +2.51.0 + diff --git a/queue-6.19/net-usb-r8152-add-trendnet-tuc-et2g.patch b/queue-6.19/net-usb-r8152-add-trendnet-tuc-et2g.patch new file mode 100644 index 0000000000..53f67ed017 --- /dev/null +++ b/queue-6.19/net-usb-r8152-add-trendnet-tuc-et2g.patch @@ -0,0 +1,48 @@ +From 84f7259b36395de1ba20d0baa743640f771b0a7d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Feb 2026 20:54:09 +0100 +Subject: net: usb: r8152: add TRENDnet TUC-ET2G + +From: Valentin Spreckels + +[ Upstream commit 15fba71533bcdfaa8eeba69a5a5a2927afdf664a ] + +The TRENDnet TUC-ET2G is a RTL8156 based usb ethernet adapter. Add its +vendor and product IDs. + +Signed-off-by: Valentin Spreckels +Link: https://patch.msgid.link/20260226195409.7891-2-valentin@spreckels.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/usb/r8152.c | 1 + + include/linux/usb/r8152.h | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c +index 6b107cf5f37bd..9eda892beb1f8 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -10062,6 +10062,7 @@ static const struct usb_device_id rtl8152_table[] = { + { USB_DEVICE(VENDOR_ID_DLINK, 0xb301) }, + { USB_DEVICE(VENDOR_ID_DELL, 0xb097) }, + { USB_DEVICE(VENDOR_ID_ASUS, 0x1976) }, ++ { USB_DEVICE(VENDOR_ID_TRENDNET, 0xe02b) }, + {} + }; + +diff --git a/include/linux/usb/r8152.h b/include/linux/usb/r8152.h +index 2ca60828f28bb..1502b2a355f98 100644 +--- a/include/linux/usb/r8152.h ++++ b/include/linux/usb/r8152.h +@@ -32,6 +32,7 @@ + #define VENDOR_ID_DLINK 0x2001 + #define VENDOR_ID_DELL 0x413c + #define VENDOR_ID_ASUS 0x0b05 ++#define VENDOR_ID_TRENDNET 0x20f4 + + #if IS_REACHABLE(CONFIG_USB_RTL8152) + extern u8 rtl8152_get_version(struct usb_interface *intf); +-- +2.51.0 + diff --git a/queue-6.19/nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch b/queue-6.19/nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch new file mode 100644 index 0000000000..8c8dde7f13 --- /dev/null +++ b/queue-6.19/nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch @@ -0,0 +1,40 @@ +From 4f5851df8bf1a92d8229522b85a0cf7620dad4ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 31 Jan 2026 19:08:40 -0800 +Subject: nvme-fabrics: use kfree_sensitive() for DHCHAP secrets + +From: Daniel Hodges + +[ Upstream commit 0a1fc2f301529ac75aec0ce80d5ab9d9e4dc4b16 ] + +The DHCHAP secrets (dhchap_secret and dhchap_ctrl_secret) contain +authentication key material for NVMe-oF. Use kfree_sensitive() instead +of kfree() in nvmf_free_options() to ensure secrets are zeroed before +the memory is freed, preventing recovery from freed pages. + +Reviewed-by: Christoph Hellwig +Signed-off-by: Daniel Hodges +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/fabrics.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c +index 55a8afd2efd50..d37cb140d8323 100644 +--- a/drivers/nvme/host/fabrics.c ++++ b/drivers/nvme/host/fabrics.c +@@ -1290,8 +1290,8 @@ void nvmf_free_options(struct nvmf_ctrl_options *opts) + kfree(opts->subsysnqn); + kfree(opts->host_traddr); + kfree(opts->host_iface); +- kfree(opts->dhchap_secret); +- kfree(opts->dhchap_ctrl_secret); ++ kfree_sensitive(opts->dhchap_secret); ++ kfree_sensitive(opts->dhchap_ctrl_secret); + kfree(opts); + } + EXPORT_SYMBOL_GPL(nvmf_free_options); +-- +2.51.0 + diff --git a/queue-6.19/nvme-pci-cap-queue-creation-to-used-queues.patch b/queue-6.19/nvme-pci-cap-queue-creation-to-used-queues.patch new file mode 100644 index 0000000000..87184fe5ef --- /dev/null +++ b/queue-6.19/nvme-pci-cap-queue-creation-to-used-queues.patch @@ -0,0 +1,45 @@ +From c90579e9577062096cc1f0be4c1237e75737d24a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 11:00:12 -0800 +Subject: nvme-pci: cap queue creation to used queues + +From: Keith Busch + +[ Upstream commit 4735b510a00fb2d4ac9e8d21a8c9552cb281f585 ] + +If the user reduces the special queue count at runtime and resets the +controller, we need to reduce the number of queues and interrupts +requested accordingly rather than start with the pre-allocated queue +count. + +Tested-by: Kanchan Joshi +Reviewed-by: Kanchan Joshi +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 3c83076a57e57..a5eab31c1bb7a 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2778,7 +2778,13 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) + dev->nr_write_queues = write_queues; + dev->nr_poll_queues = poll_queues; + +- nr_io_queues = dev->nr_allocated_queues - 1; ++ /* ++ * The initial number of allocated queue slots may be too large if the ++ * user reduced the special queue parameters. Cap the value to the ++ * number we need for this round. ++ */ ++ nr_io_queues = min(nvme_max_io_queues(dev), ++ dev->nr_allocated_queues - 1); + result = nvme_set_queue_count(&dev->ctrl, &nr_io_queues); + if (result < 0) + return result; +-- +2.51.0 + diff --git a/queue-6.19/nvme-pci-ensure-we-re-polling-a-polled-queue.patch b/queue-6.19/nvme-pci-ensure-we-re-polling-a-polled-queue.patch new file mode 100644 index 0000000000..fb24135ae8 --- /dev/null +++ b/queue-6.19/nvme-pci-ensure-we-re-polling-a-polled-queue.patch @@ -0,0 +1,39 @@ +From 8b37a26b3758b9448edc210e34f32915734b7df5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 09:26:54 -0800 +Subject: nvme-pci: ensure we're polling a polled queue + +From: Keith Busch + +[ Upstream commit 166e31d7dbf6aa44829b98aa446bda5c9580f12a ] + +A user can change the polled queue count at run time. There's a brief +window during a reset where a hipri task may try to poll that queue +before the block layer has updated the queue maps, which would race with +the now interrupt driven queue and may cause double completions. + +Reviewed-by: Christoph Hellwig +Reviewed-by: Kanchan Joshi +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index a5eab31c1bb7a..f6d4f5910bdbc 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1501,7 +1501,8 @@ static int nvme_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob) + struct nvme_queue *nvmeq = hctx->driver_data; + bool found; + +- if (!nvme_cqe_pending(nvmeq)) ++ if (!test_bit(NVMEQ_POLLED, &nvmeq->flags) || ++ !nvme_cqe_pending(nvmeq)) + return 0; + + spin_lock(&nvmeq->cq_poll_lock); +-- +2.51.0 + diff --git a/queue-6.19/nvmet-move-async-event-work-off-nvmet-wq.patch b/queue-6.19/nvmet-move-async-event-work-off-nvmet-wq.patch new file mode 100644 index 0000000000..8f8ef9d90c --- /dev/null +++ b/queue-6.19/nvmet-move-async-event-work-off-nvmet-wq.patch @@ -0,0 +1,178 @@ +From a96a34e1cc0309d6b20b1e9e739465ccdfcc98c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Feb 2026 20:30:03 -0800 +Subject: nvmet: move async event work off nvmet-wq + +From: Chaitanya Kulkarni + +[ Upstream commit 2922e3507f6d5caa7f1d07f145e186fc6f317a4e ] + +For target nvmet_ctrl_free() flushes ctrl->async_event_work. +If nvmet_ctrl_free() runs on nvmet-wq, the flush re-enters workqueue +completion for the same worker:- + +A. Async event work queued on nvmet-wq (prior to disconnect): + nvmet_execute_async_event() + queue_work(nvmet_wq, &ctrl->async_event_work) + + nvmet_add_async_event() + queue_work(nvmet_wq, &ctrl->async_event_work) + +B. Full pre-work chain (RDMA CM path): + nvmet_rdma_cm_handler() + nvmet_rdma_queue_disconnect() + __nvmet_rdma_queue_disconnect() + queue_work(nvmet_wq, &queue->release_work) + process_one_work() + lock((wq_completion)nvmet-wq) <--------- 1st + nvmet_rdma_release_queue_work() + +C. Recursive path (same worker): + nvmet_rdma_release_queue_work() + nvmet_rdma_free_queue() + nvmet_sq_destroy() + nvmet_ctrl_put() + nvmet_ctrl_free() + flush_work(&ctrl->async_event_work) + __flush_work() + touch_wq_lockdep_map() + lock((wq_completion)nvmet-wq) <--------- 2nd + +Lockdep splat: + + ============================================ + WARNING: possible recursive locking detected + 6.19.0-rc3nvme+ #14 Tainted: G N + -------------------------------------------- + kworker/u192:42/44933 is trying to acquire lock: + ffff888118a00948 ((wq_completion)nvmet-wq){+.+.}-{0:0}, at: touch_wq_lockdep_map+0x26/0x90 + + but task is already holding lock: + ffff888118a00948 ((wq_completion)nvmet-wq){+.+.}-{0:0}, at: process_one_work+0x53e/0x660 + + 3 locks held by kworker/u192:42/44933: + #0: ffff888118a00948 ((wq_completion)nvmet-wq){+.+.}-{0:0}, at: process_one_work+0x53e/0x660 + #1: ffffc9000e6cbe28 ((work_completion)(&queue->release_work)){+.+.}-{0:0}, at: process_one_work+0x1c5/0x660 + #2: ffffffff82d4db60 (rcu_read_lock){....}-{1:3}, at: __flush_work+0x62/0x530 + + Workqueue: nvmet-wq nvmet_rdma_release_queue_work [nvmet_rdma] + Call Trace: + __flush_work+0x268/0x530 + nvmet_ctrl_free+0x140/0x310 [nvmet] + nvmet_cq_put+0x74/0x90 [nvmet] + nvmet_rdma_free_queue+0x23/0xe0 [nvmet_rdma] + nvmet_rdma_release_queue_work+0x19/0x50 [nvmet_rdma] + process_one_work+0x206/0x660 + worker_thread+0x184/0x320 + kthread+0x10c/0x240 + ret_from_fork+0x319/0x390 + +Move async event work to a dedicated nvmet-aen-wq to avoid reentrant +flush on nvmet-wq. + +Reviewed-by: Christoph Hellwig +Signed-off-by: Chaitanya Kulkarni +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/admin-cmd.c | 2 +- + drivers/nvme/target/core.c | 14 ++++++++++++-- + drivers/nvme/target/nvmet.h | 1 + + drivers/nvme/target/rdma.c | 1 + + 4 files changed, 15 insertions(+), 3 deletions(-) + +diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c +index 3da31bb1183eb..100d1466ff841 100644 +--- a/drivers/nvme/target/admin-cmd.c ++++ b/drivers/nvme/target/admin-cmd.c +@@ -1586,7 +1586,7 @@ void nvmet_execute_async_event(struct nvmet_req *req) + ctrl->async_event_cmds[ctrl->nr_async_event_cmds++] = req; + mutex_unlock(&ctrl->lock); + +- queue_work(nvmet_wq, &ctrl->async_event_work); ++ queue_work(nvmet_aen_wq, &ctrl->async_event_work); + } + + void nvmet_execute_keep_alive(struct nvmet_req *req) +diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c +index cc88e5a28c8a9..5075f7123358a 100644 +--- a/drivers/nvme/target/core.c ++++ b/drivers/nvme/target/core.c +@@ -26,6 +26,8 @@ static DEFINE_IDA(cntlid_ida); + + struct workqueue_struct *nvmet_wq; + EXPORT_SYMBOL_GPL(nvmet_wq); ++struct workqueue_struct *nvmet_aen_wq; ++EXPORT_SYMBOL_GPL(nvmet_aen_wq); + + /* + * This read/write semaphore is used to synchronize access to configuration +@@ -205,7 +207,7 @@ void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type, + list_add_tail(&aen->entry, &ctrl->async_events); + mutex_unlock(&ctrl->lock); + +- queue_work(nvmet_wq, &ctrl->async_event_work); ++ queue_work(nvmet_aen_wq, &ctrl->async_event_work); + } + + static void nvmet_add_to_changed_ns_log(struct nvmet_ctrl *ctrl, __le32 nsid) +@@ -1958,9 +1960,14 @@ static int __init nvmet_init(void) + if (!nvmet_wq) + goto out_free_buffered_work_queue; + ++ nvmet_aen_wq = alloc_workqueue("nvmet-aen-wq", ++ WQ_MEM_RECLAIM | WQ_UNBOUND, 0); ++ if (!nvmet_aen_wq) ++ goto out_free_nvmet_work_queue; ++ + error = nvmet_init_debugfs(); + if (error) +- goto out_free_nvmet_work_queue; ++ goto out_free_nvmet_aen_work_queue; + + error = nvmet_init_discovery(); + if (error) +@@ -1976,6 +1983,8 @@ static int __init nvmet_init(void) + nvmet_exit_discovery(); + out_exit_debugfs: + nvmet_exit_debugfs(); ++out_free_nvmet_aen_work_queue: ++ destroy_workqueue(nvmet_aen_wq); + out_free_nvmet_work_queue: + destroy_workqueue(nvmet_wq); + out_free_buffered_work_queue: +@@ -1993,6 +2002,7 @@ static void __exit nvmet_exit(void) + nvmet_exit_discovery(); + nvmet_exit_debugfs(); + ida_destroy(&cntlid_ida); ++ destroy_workqueue(nvmet_aen_wq); + destroy_workqueue(nvmet_wq); + destroy_workqueue(buffered_io_wq); + destroy_workqueue(zbd_wq); +diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h +index b664b584fdc8e..319d6a5e9cf05 100644 +--- a/drivers/nvme/target/nvmet.h ++++ b/drivers/nvme/target/nvmet.h +@@ -501,6 +501,7 @@ extern struct kmem_cache *nvmet_bvec_cache; + extern struct workqueue_struct *buffered_io_wq; + extern struct workqueue_struct *zbd_wq; + extern struct workqueue_struct *nvmet_wq; ++extern struct workqueue_struct *nvmet_aen_wq; + + static inline void nvmet_set_result(struct nvmet_req *req, u32 result) + { +diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c +index 9c12b2361a6d7..0384323649671 100644 +--- a/drivers/nvme/target/rdma.c ++++ b/drivers/nvme/target/rdma.c +@@ -2088,6 +2088,7 @@ static void nvmet_rdma_remove_one(struct ib_device *ib_device, void *client_data + mutex_unlock(&nvmet_rdma_queue_mutex); + + flush_workqueue(nvmet_wq); ++ flush_workqueue(nvmet_aen_wq); + } + + static struct ib_client nvmet_rdma_ib_client = { +-- +2.51.0 + diff --git a/queue-6.19/objtool-handle-clang-rsp-musical-chairs.patch b/queue-6.19/objtool-handle-clang-rsp-musical-chairs.patch new file mode 100644 index 0000000000..7d46229eeb --- /dev/null +++ b/queue-6.19/objtool-handle-clang-rsp-musical-chairs.patch @@ -0,0 +1,136 @@ +From 7112a9aa5ab4473e00ae55aba9de7b6b5d8a2b46 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 09:35:06 -0800 +Subject: objtool: Handle Clang RSP musical chairs + +From: Josh Poimboeuf + +[ Upstream commit 7fdaa640c810cb42090a182c33f905bcc47a616a ] + +For no apparent reason (possibly related to CONFIG_KMSAN), Clang can +randomly pass the value of RSP to other registers and then back again to +RSP. Handle that accordingly. + +Fixes the following warnings: + + drivers/input/misc/uinput.o: warning: objtool: uinput_str_to_user+0x165: undefined stack state + drivers/input/misc/uinput.o: warning: objtool: uinput_str_to_user+0x165: unknown CFA base reg -1 + +Reported-by: Arnd Bergmann +Closes: https://lore.kernel.org/90956545-2066-46e3-b547-10c884582eb0@app.fastmail.com +Link: https://patch.msgid.link/240e6a172cc73292499334a3724d02ccb3247fc7.1772818491.git.jpoimboe@kernel.org +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/arch/x86/decode.c | 62 ++++++++++++--------------------- + tools/objtool/check.c | 14 ++++++++ + 2 files changed, 37 insertions(+), 39 deletions(-) + +diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c +index f4af825082284..4544c2cb44400 100644 +--- a/tools/objtool/arch/x86/decode.c ++++ b/tools/objtool/arch/x86/decode.c +@@ -395,52 +395,36 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec + if (!rex_w) + break; + +- if (modrm_reg == CFI_SP) { +- +- if (mod_is_reg()) { +- /* mov %rsp, reg */ +- ADD_OP(op) { +- op->src.type = OP_SRC_REG; +- op->src.reg = CFI_SP; +- op->dest.type = OP_DEST_REG; +- op->dest.reg = modrm_rm; +- } +- break; +- +- } else { +- /* skip RIP relative displacement */ +- if (is_RIP()) +- break; +- +- /* skip nontrivial SIB */ +- if (have_SIB()) { +- modrm_rm = sib_base; +- if (sib_index != CFI_SP) +- break; +- } +- +- /* mov %rsp, disp(%reg) */ +- ADD_OP(op) { +- op->src.type = OP_SRC_REG; +- op->src.reg = CFI_SP; +- op->dest.type = OP_DEST_REG_INDIRECT; +- op->dest.reg = modrm_rm; +- op->dest.offset = ins.displacement.value; +- } +- break; ++ if (mod_is_reg()) { ++ /* mov reg, reg */ ++ ADD_OP(op) { ++ op->src.type = OP_SRC_REG; ++ op->src.reg = modrm_reg; ++ op->dest.type = OP_DEST_REG; ++ op->dest.reg = modrm_rm; + } +- + break; + } + +- if (rm_is_reg(CFI_SP)) { ++ /* skip RIP relative displacement */ ++ if (is_RIP()) ++ break; + +- /* mov reg, %rsp */ ++ /* skip nontrivial SIB */ ++ if (have_SIB()) { ++ modrm_rm = sib_base; ++ if (sib_index != CFI_SP) ++ break; ++ } ++ ++ /* mov %rsp, disp(%reg) */ ++ if (modrm_reg == CFI_SP) { + ADD_OP(op) { + op->src.type = OP_SRC_REG; +- op->src.reg = modrm_reg; +- op->dest.type = OP_DEST_REG; +- op->dest.reg = CFI_SP; ++ op->src.reg = CFI_SP; ++ op->dest.type = OP_DEST_REG_INDIRECT; ++ op->dest.reg = modrm_rm; ++ op->dest.offset = ins.displacement.value; + } + break; + } +diff --git a/tools/objtool/check.c b/tools/objtool/check.c +index eba35bb8c0bdf..30609aed5d37e 100644 +--- a/tools/objtool/check.c ++++ b/tools/objtool/check.c +@@ -2960,6 +2960,20 @@ static int update_cfi_state(struct instruction *insn, + cfi->stack_size += 8; + } + ++ else if (cfi->vals[op->src.reg].base == CFI_CFA) { ++ /* ++ * Clang RSP musical chairs: ++ * ++ * mov %rsp, %rdx [handled above] ++ * ... ++ * mov %rdx, %rbx [handled here] ++ * ... ++ * mov %rbx, %rsp [handled above] ++ */ ++ cfi->vals[op->dest.reg].base = CFI_CFA; ++ cfi->vals[op->dest.reg].offset = cfi->vals[op->src.reg].offset; ++ } ++ + + break; + +-- +2.51.0 + diff --git a/queue-6.19/objtool-klp-disable-unsupported-pr_debug-usage.patch b/queue-6.19/objtool-klp-disable-unsupported-pr_debug-usage.patch new file mode 100644 index 0000000000..27574ac7e3 --- /dev/null +++ b/queue-6.19/objtool-klp-disable-unsupported-pr_debug-usage.patch @@ -0,0 +1,69 @@ +From eb05ae7c89c66008aa5e8706c4f32828c5477e8b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 13:50:10 -0800 +Subject: objtool/klp: Disable unsupported pr_debug() usage + +From: Josh Poimboeuf + +[ Upstream commit e476bb277cf91b7ac3ea803ec78a4f0791bddec3 ] + +Instead of erroring out on unsupported pr_debug() (e.g., when patching a +module), issue a warning and make it inert, similar to how unsupported +tracepoints are currently handled. + +Reviewed-and-tested-by: Song Liu +Link: https://patch.msgid.link/3a7db3a5b7d4abf9b2534803a74e2e7231322738.1770759954.git.jpoimboe@kernel.org +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/klp-diff.c | 23 +++++++++++++++-------- + 1 file changed, 15 insertions(+), 8 deletions(-) + +diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c +index b1847828217ba..b9340ef8d370c 100644 +--- a/tools/objtool/klp-diff.c ++++ b/tools/objtool/klp-diff.c +@@ -1335,18 +1335,18 @@ static bool should_keep_special_sym(struct elf *elf, struct symbol *sym) + * be applied after static branch/call init, resulting in code corruption. + * + * Validate a special section entry to avoid that. Note that an inert +- * tracepoint is harmless enough, in that case just skip the entry and print a +- * warning. Otherwise, return an error. ++ * tracepoint or pr_debug() is harmless enough, in that case just skip the ++ * entry and print a warning. Otherwise, return an error. + * +- * This is only a temporary limitation which will be fixed when livepatch adds +- * support for submodules: fully self-contained modules which are embedded in +- * the top-level livepatch module's data and which can be loaded on demand when +- * their corresponding to-be-patched module gets loaded. Then klp relocs can +- * be retired. ++ * TODO: This is only a temporary limitation which will be fixed when livepatch ++ * adds support for submodules: fully self-contained modules which are embedded ++ * in the top-level livepatch module's data and which can be loaded on demand ++ * when their corresponding to-be-patched module gets loaded. Then klp relocs ++ * can be retired. + * + * Return: + * -1: error: validation failed +- * 1: warning: tracepoint skipped ++ * 1: warning: disabled tracepoint or pr_debug() + * 0: success + */ + static int validate_special_section_klp_reloc(struct elfs *e, struct symbol *sym) +@@ -1404,6 +1404,13 @@ static int validate_special_section_klp_reloc(struct elfs *e, struct symbol *sym + continue; + } + ++ if (strstr(reloc->sym->name, "__UNIQUE_ID_ddebug_")) { ++ WARN("%s: disabling unsupported pr_debug()", ++ code_sym->name); ++ ret = 1; ++ continue; ++ } ++ + ERROR("%s+0x%lx: unsupported static branch key %s. Use static_key_enabled() instead", + code_sym->name, code_offset, reloc->sym->name); + return -1; +-- +2.51.0 + diff --git a/queue-6.19/objtool-klp-fix-data-alignment-in-__clone_symbol.patch b/queue-6.19/objtool-klp-fix-data-alignment-in-__clone_symbol.patch new file mode 100644 index 0000000000..56f946c854 --- /dev/null +++ b/queue-6.19/objtool-klp-fix-data-alignment-in-__clone_symbol.patch @@ -0,0 +1,48 @@ +From 9288c1297479644a2ea03c900782e3481fbade36 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Mar 2026 16:37:40 -0400 +Subject: objtool/klp: fix data alignment in __clone_symbol() + +From: Joe Lawrence + +[ Upstream commit 2f2600decb3004938762a3f2d0eba3ea9e01045b ] + +Commit 356e4b2f5b80 ("objtool: Fix data alignment in elf_add_data()") +corrected the alignment of data within a section (honoring the section's +sh_addralign). Apply the same alignment when klp-diff mode clones a +symbol, adjusting the new symbol's offset for the output section's +sh_addralign. + +Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files") +Signed-off-by: Joe Lawrence +Link: https://patch.msgid.link/20260310203751.1479229-2-joe.lawrence@redhat.com +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/klp-diff.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c +index d94632e809558..b1847828217ba 100644 +--- a/tools/objtool/klp-diff.c ++++ b/tools/objtool/klp-diff.c +@@ -14,6 +14,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -560,7 +561,7 @@ static struct symbol *__clone_symbol(struct elf *elf, struct symbol *patched_sym + } + + if (!is_sec_sym(patched_sym)) +- offset = sec_size(out_sec); ++ offset = ALIGN(sec_size(out_sec), out_sec->sh.sh_addralign); + + if (patched_sym->len || is_sec_sym(patched_sym)) { + void *data = NULL; +-- +2.51.0 + diff --git a/queue-6.19/objtool-use-hostcflags-for-have_xxhash-test.patch b/queue-6.19/objtool-use-hostcflags-for-have_xxhash-test.patch new file mode 100644 index 0000000000..deb5522935 --- /dev/null +++ b/queue-6.19/objtool-use-hostcflags-for-have_xxhash-test.patch @@ -0,0 +1,53 @@ +From 8b04427cb9b1939186c11d7831df92458eca6629 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Mar 2026 01:03:39 +0000 +Subject: objtool: Use HOSTCFLAGS for HAVE_XXHASH test + +From: HONG Yifan + +[ Upstream commit 32234049107d012703d50547e815f198f147968b ] + +Previously, HAVE_XXHASH is tested by invoking HOSTCC without HOSTCFLAGS. + +Consider the following scenario: + +- The host machine has libxxhash installed +- We build the kernel with HOSTCFLAGS containing a --sysroot that does + not have xxhash.h (for hermetic builds) + +In this case, HAVE_XXHASH is set to y, but when it builds objtool with +HOSTCFLAGS, because the --sysroot does not contain xxhash.h, the +following error is raised: + +<...>/common/tools/objtool/include/objtool/checksum_types.h:12:10: fatal error: 'xxhash.h' file not found + 12 | #include + | ^~~~~~~~~~ + +To resolve the error, we test HAVE_XXHASH by invoking HOSTCC with +HOSTCFLAGS. + +Signed-off-by: HONG Yifan +Reviewed-by: Carlos Llamas +Link: https://patch.msgid.link/20260303010340.306164-1-elsk@google.com +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile +index 76bcd4e85de34..b71d1886022e9 100644 +--- a/tools/objtool/Makefile ++++ b/tools/objtool/Makefile +@@ -13,7 +13,7 @@ endif + + ifeq ($(ARCH_HAS_KLP),y) + HAVE_XXHASH = $(shell printf "$(pound)include \nXXH3_state_t *state;int main() {}" | \ +- $(HOSTCC) -xc - -o /dev/null -lxxhash 2> /dev/null && echo y || echo n) ++ $(HOSTCC) $(HOSTCFLAGS) -xc - -o /dev/null -lxxhash 2> /dev/null && echo y || echo n) + ifeq ($(HAVE_XXHASH),y) + BUILD_KLP := y + LIBXXHASH_CFLAGS := $(shell $(HOSTPKG_CONFIG) libxxhash --cflags 2>/dev/null) \ +-- +2.51.0 + diff --git a/queue-6.19/perf-make-sure-to-use-pmu_ctx-pmu-for-groups.patch b/queue-6.19/perf-make-sure-to-use-pmu_ctx-pmu-for-groups.patch new file mode 100644 index 0000000000..045f503ab5 --- /dev/null +++ b/queue-6.19/perf-make-sure-to-use-pmu_ctx-pmu-for-groups.patch @@ -0,0 +1,99 @@ +From 9822a60c87121d6d16cfeff3fd6fa78f2258c5c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Mar 2026 13:55:46 +0100 +Subject: perf: Make sure to use pmu_ctx->pmu for groups + +From: Peter Zijlstra + +[ Upstream commit 4b9ce671960627b2505b3f64742544ae9801df97 ] + +Oliver reported that x86_pmu_del() ended up doing an out-of-bound memory access +when group_sched_in() fails and needs to roll back. + +This *should* be handled by the transaction callbacks, but he found that when +the group leader is a software event, the transaction handlers of the wrong PMU +are used. Despite the move_group case in perf_event_open() and group_sched_in() +using pmu_ctx->pmu. + +Turns out, inherit uses event->pmu to clone the events, effectively undoing the +move_group case for all inherited contexts. Fix this by also making inherit use +pmu_ctx->pmu, ensuring all inherited counters end up in the same pmu context. + +Similarly, __perf_event_read() should use equally use pmu_ctx->pmu for the +group case. + +Fixes: bd2756811766 ("perf: Rewrite core context handling") +Reported-by: Oliver Rosenberg +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Ian Rogers +Link: https://patch.msgid.link/20260309133713.GB606826@noisy.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + kernel/events/core.c | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 84a79e977580e..39b35f280845b 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -4672,7 +4672,7 @@ static void __perf_event_read(void *info) + struct perf_event *sub, *event = data->event; + struct perf_event_context *ctx = event->ctx; + struct perf_cpu_context *cpuctx = this_cpu_ptr(&perf_cpu_context); +- struct pmu *pmu = event->pmu; ++ struct pmu *pmu; + + /* + * If this is a task context, we need to check whether it is +@@ -4684,7 +4684,7 @@ static void __perf_event_read(void *info) + if (ctx->task && cpuctx->task_ctx != ctx) + return; + +- raw_spin_lock(&ctx->lock); ++ guard(raw_spinlock)(&ctx->lock); + ctx_time_update_event(ctx, event); + + perf_event_update_time(event); +@@ -4692,25 +4692,22 @@ static void __perf_event_read(void *info) + perf_event_update_sibling_time(event); + + if (event->state != PERF_EVENT_STATE_ACTIVE) +- goto unlock; ++ return; + + if (!data->group) { +- pmu->read(event); ++ perf_pmu_read(event); + data->ret = 0; +- goto unlock; ++ return; + } + ++ pmu = event->pmu_ctx->pmu; + pmu->start_txn(pmu, PERF_PMU_TXN_READ); + +- pmu->read(event); +- ++ perf_pmu_read(event); + for_each_sibling_event(sub, event) + perf_pmu_read(sub); + + data->ret = pmu->commit_txn(pmu); +- +-unlock: +- raw_spin_unlock(&ctx->lock); + } + + static inline u64 perf_event_count(struct perf_event *event, bool self) +@@ -14461,7 +14458,7 @@ inherit_event(struct perf_event *parent_event, + get_ctx(child_ctx); + child_event->ctx = child_ctx; + +- pmu_ctx = find_get_pmu_context(child_event->pmu, child_ctx, child_event); ++ pmu_ctx = find_get_pmu_context(parent_event->pmu_ctx->pmu, child_ctx, child_event); + if (IS_ERR(pmu_ctx)) { + free_event(child_event); + return ERR_CAST(pmu_ctx); +-- +2.51.0 + diff --git a/queue-6.19/perf-metricgroup-fix-metricgroup__has_metric_or_grou.patch b/queue-6.19/perf-metricgroup-fix-metricgroup__has_metric_or_grou.patch new file mode 100644 index 0000000000..1e2c806e75 --- /dev/null +++ b/queue-6.19/perf-metricgroup-fix-metricgroup__has_metric_or_grou.patch @@ -0,0 +1,46 @@ +From 0bfa68e6e072e05eacd1abcd03cc57dba578e97d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 16:49:56 -0800 +Subject: perf metricgroup: Fix metricgroup__has_metric_or_groups() + +From: Ian Rogers + +[ Upstream commit 8dd1d9a335321d0829aeb85d8e1a897248d0da29 ] + +Use metricgroup__for_each_metric() rather than +pmu_metrics_table__for_each_metric() that combines the +default metric table with, a potentially empty, CPUID table. + +Fixes: cee275edcdb1acfd ("perf metricgroup: Don't early exit if no CPUID table exists") +Reviewed-by: Leo Yan +Signed-off-by: Ian Rogers +Tested-by: Arnaldo Carvalho de Melo +Tested-by: Leo Yan +Cc: Ian Rogers +Signed-off-by: Namhyung Kim +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/util/metricgroup.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c +index a21f2d4969c5c..45bb94da97b99 100644 +--- a/tools/perf/util/metricgroup.c ++++ b/tools/perf/util/metricgroup.c +@@ -1606,9 +1606,9 @@ bool metricgroup__has_metric_or_groups(const char *pmu, const char *metric_or_gr + .metric_or_groups = metric_or_groups, + }; + +- return pmu_metrics_table__for_each_metric(table, +- metricgroup__has_metric_or_groups_callback, +- &data) ++ return metricgroup__for_each_metric(table, ++ metricgroup__has_metric_or_groups_callback, ++ &data) + ? true : false; + } + +-- +2.51.0 + diff --git a/queue-6.19/platform-x86-hp-wmi-add-omen-14-fb1xxx-board-8e41-su.patch b/queue-6.19/platform-x86-hp-wmi-add-omen-14-fb1xxx-board-8e41-su.patch new file mode 100644 index 0000000000..35fbb7a303 --- /dev/null +++ b/queue-6.19/platform-x86-hp-wmi-add-omen-14-fb1xxx-board-8e41-su.patch @@ -0,0 +1,43 @@ +From 8e8f32cf5325aa83efc4cb9f201802d784808bbe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Feb 2026 18:48:32 +0200 +Subject: platform/x86: hp-wmi: add Omen 14-fb1xxx (board 8E41) support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Anton Plotnikov + +[ Upstream commit 729ffcffa73069cb066fd54a2bc7b09e5f782d48 ] + +Reverse engineering of the HP Omen Windows utility shows that for performance +mode it uses the same codes listed in hp_thermal_profile_omen_v1. Therefore it +seems sufficient to add the board model name to omen_thermal_profile_boards. + +Tested on Omen 14-fb1xxx: CPU power in performance profile reaches the Windows +limit (65W), instead of 45W in automatic BIOS mode. Max fan speed was reached +as well. + +Link: https://patch.msgid.link/20260203164832.40514-1-plotnikovanton@gmail.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/hp/hp-wmi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c +index bc550da031fa1..ec87fd96686cf 100644 +--- a/drivers/platform/x86/hp/hp-wmi.c ++++ b/drivers/platform/x86/hp/hp-wmi.c +@@ -133,6 +133,7 @@ static const char * const omen_thermal_profile_boards[] = { + "8900", "8901", "8902", "8912", "8917", "8918", "8949", "894A", "89EB", + "8A15", "8A42", + "8BAD", ++ "8E41", + }; + + /* DMI Board names of Omen laptops that are specifically set to be thermal +-- +2.51.0 + diff --git a/queue-6.19/platform-x86-hp-wmi-add-omen-16-wf0xxx-fan-and-therm.patch b/queue-6.19/platform-x86-hp-wmi-add-omen-16-wf0xxx-fan-and-therm.patch new file mode 100644 index 0000000000..ad3a3df60d --- /dev/null +++ b/queue-6.19/platform-x86-hp-wmi-add-omen-16-wf0xxx-fan-and-therm.patch @@ -0,0 +1,53 @@ +From eaea3183effdd8c145f99d21456ca912b5dd0e16 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 12:50:03 +0530 +Subject: platform/x86: hp-wmi: Add Omen 16-wf0xxx fan and thermal support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Krishna Chomal + +[ Upstream commit 13fa3aaf02edaad9b41fc61d7f6326d2b6a4bf80 ] + +The HP Omen 16-wf0xxx (board ID: 8BAB) has the same WMI interface as +other Victus S boards, but requires quirks for correctly switching +thermal profile (similar to HP Omen 16-wf1xxx, board ID: 8C78). + +Add the DMI board name to victus_s_thermal_profile_boards[] table and +map it to omen_v1_thermal_params. + +Testing on HP Omen 16-wf0xxx confirmed that platform profile is +registered successfully and fan RPMs are readable and controllable. + +Suggested-by: Noah Provenzano +Tested-by: Juan Martin Morales +Reported-by: Juan Martin Morales +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220639 +Signed-off-by: Krishna Chomal +Link: https://patch.msgid.link/20260216072003.90151-1-krishna.chomal108@gmail.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/hp/hp-wmi.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c +index 24d065ddfc6ae..9fcc18635e4e7 100644 +--- a/drivers/platform/x86/hp/hp-wmi.c ++++ b/drivers/platform/x86/hp/hp-wmi.c +@@ -160,6 +160,10 @@ static const char * const victus_thermal_profile_boards[] = { + + /* DMI Board names of Victus 16-r and Victus 16-s laptops */ + static const struct dmi_system_id victus_s_thermal_profile_boards[] __initconst = { ++ { ++ .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BAB") }, ++ .driver_data = (void *)&omen_v1_thermal_params, ++ }, + { + .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BBE") }, + .driver_data = (void *)&victus_s_thermal_params, +-- +2.51.0 + diff --git a/queue-6.19/platform-x86-hp-wmi-add-omen-16-xd0xxx-fan-and-therm.patch b/queue-6.19/platform-x86-hp-wmi-add-omen-16-xd0xxx-fan-and-therm.patch new file mode 100644 index 0000000000..ce232ee5ad --- /dev/null +++ b/queue-6.19/platform-x86-hp-wmi-add-omen-16-xd0xxx-fan-and-therm.patch @@ -0,0 +1,50 @@ +From 5a7d70b04cc4ff4130fce4a8ac4984e873aa76f5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 10:32:35 +0530 +Subject: platform/x86: hp-wmi: Add Omen 16-xd0xxx fan and thermal support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Krishna Chomal + +[ Upstream commit 3c99a545b372c77b5d39715968a141f523eccbf2 ] + +The HP Omen 16-xd0xxx (board ID: 8BCD) has the same WMI interface as +other Victus S boards, but requires quirks for correctly switching +thermal profile (similar to HP Omen 16-wf1xxx, board ID: 8C78). + +Add the DMI board name to victus_s_thermal_profile_boards[] table and +map it to omen_v1_thermal_params. + +Testing on HP Omen 16-xd0xxx confirmed that platform profile is +registered successfully and fan RPMs are readable and controllable. + +Tested-by: Varad Amol Pisale +Signed-off-by: Krishna Chomal +Link: https://patch.msgid.link/20260218050235.94687-1-krishna.chomal108@gmail.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/hp/hp-wmi.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c +index 9fcc18635e4e7..bc550da031fa1 100644 +--- a/drivers/platform/x86/hp/hp-wmi.c ++++ b/drivers/platform/x86/hp/hp-wmi.c +@@ -168,6 +168,10 @@ static const struct dmi_system_id victus_s_thermal_profile_boards[] __initconst + .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BBE") }, + .driver_data = (void *)&victus_s_thermal_params, + }, ++ { ++ .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BCD") }, ++ .driver_data = (void *)&omen_v1_thermal_params, ++ }, + { + .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BD4") }, + .driver_data = (void *)&victus_s_thermal_params, +-- +2.51.0 + diff --git a/queue-6.19/platform-x86-hp-wmi-add-victus-16-d0xxx-support.patch b/queue-6.19/platform-x86-hp-wmi-add-victus-16-d0xxx-support.patch new file mode 100644 index 0000000000..0eadac7555 --- /dev/null +++ b/queue-6.19/platform-x86-hp-wmi-add-victus-16-d0xxx-support.patch @@ -0,0 +1,51 @@ +From 6a063e1b78c615ae173c3a897f875c4e3f98d484 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 00:00:52 +0000 +Subject: platform/x86: hp-wmi: Add Victus 16-d0xxx support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Victor Lattaro Volpini + +[ Upstream commit 249f05e625c6e6c14b27fd34a2f06a1afb9b456d ] + +This patch enables Victus thermal profile support for the HP +Victus 16-d0xxx. It does so by adding model's DMI board name 88F8 to +victus_thermal_profile_boards. + +Tested on a Victus 16-d0xxx: + - Victus thermal profile choices available (quiet, balanced, performance) + instead of the default ones (cool, quiet, balanced, performance); + - Profile switching works correctly; + - About 4% increase in FPS using benchmark Cyberpunk 2077 on + performance profile; + - No noticeable regressions. + +Signed-off-by: Victor Lattaro Volpini +Link: https://patch.msgid.link/20260210000048.250280-1-victorlattaro@proton.me +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/hp/hp-wmi.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c +index ec87fd96686cf..e3a7ac2485d68 100644 +--- a/drivers/platform/x86/hp/hp-wmi.c ++++ b/drivers/platform/x86/hp/hp-wmi.c +@@ -154,8 +154,9 @@ static const char * const omen_timed_thermal_profile_boards[] = { + "8BAD", + }; + +-/* DMI Board names of Victus 16-d1xxx laptops */ ++/* DMI Board names of Victus 16-d laptops */ + static const char * const victus_thermal_profile_boards[] = { ++ "88F8", + "8A25", + }; + +-- +2.51.0 + diff --git a/queue-6.19/platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch b/queue-6.19/platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch new file mode 100644 index 0000000000..a937c702a9 --- /dev/null +++ b/queue-6.19/platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch @@ -0,0 +1,51 @@ +From 221cdd3c9cb09b355e131a4b5805263faf7fedbd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 23:46:27 -0500 +Subject: platform/x86: intel-hid: Add Dell 14 Plus 2-in-1 to + dmi_vgbs_allow_list +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Peter Metz + +[ Upstream commit 6b3fa0615cd8432148581de62a52f83847af3d70 ] + +The Dell 14 Plus 2-in-1 (model DB04250) requires the VGBS allow list +entry to correctly enable the tablet mode switch. Without this, the +chassis state is not reported, and the hinge rotation only emits +unknown scancodes. + +Verified on Dell 14 Plus 2-in-1 DB04250. + +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221090 +Signed-off-by: Peter Metz +Reviewed-by: Hans de Goede +Link: https://patch.msgid.link/20260213044627.203638-1-peter.metz@unarin.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/intel/hid.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c +index 560cc063198e1..5b475a09645a3 100644 +--- a/drivers/platform/x86/intel/hid.c ++++ b/drivers/platform/x86/intel/hid.c +@@ -189,6 +189,12 @@ static const struct dmi_system_id dmi_vgbs_allow_list[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Dell Pro Rugged 12 Tablet RA02260"), + }, + }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Dell 14 Plus 2-in-1 DB04250"), ++ }, ++ }, + { } + }; + +-- +2.51.0 + diff --git a/queue-6.19/platform-x86-intel-hid-enable-5-button-array-on-thin.patch b/queue-6.19/platform-x86-intel-hid-enable-5-button-array-on-thin.patch new file mode 100644 index 0000000000..db6895404a --- /dev/null +++ b/queue-6.19/platform-x86-intel-hid-enable-5-button-array-on-thin.patch @@ -0,0 +1,52 @@ +From e53b08cc48f2fc744fcb8271c7b007c6ed575f58 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 09:56:25 +0100 +Subject: platform/x86: intel-hid: Enable 5-button array on ThinkPad X1 Fold 16 + Gen 1 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Leif Skunberg + +[ Upstream commit b38d478dad79e61e8a65931021bdfd7a71741212 ] + +The Lenovo ThinkPad X1 Fold 16 Gen 1 has physical volume up/down +buttons that are handled through the intel-hid 5-button array +interface. The firmware does not advertise 5-button array support via +HEBC, so the driver relies on a DMI allowlist to enable it. + +Add the ThinkPad X1 Fold 16 Gen 1 to the button_array_table so the +volume buttons work out of the box. + +Signed-off-by: Leif Skunberg +Reviewed-by: Hans de Goede +Link: https://patch.msgid.link/20260210085625.34380-1-diamondback@cohunt.app +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/intel/hid.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c +index 5b475a09645a3..f2b309f6e458a 100644 +--- a/drivers/platform/x86/intel/hid.c ++++ b/drivers/platform/x86/intel/hid.c +@@ -135,6 +135,13 @@ static const struct dmi_system_id button_array_table[] = { + DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Tablet Gen 2"), + }, + }, ++ { ++ .ident = "Lenovo ThinkPad X1 Fold 16 Gen 1", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Fold 16 Gen 1"), ++ }, ++ }, + { + .ident = "Microsoft Surface Go 3", + .matches = { +-- +2.51.0 + diff --git a/queue-6.19/platform-x86-oxpec-add-support-for-aokzoe-a2-pro.patch b/queue-6.19/platform-x86-oxpec-add-support-for-aokzoe-a2-pro.patch new file mode 100644 index 0000000000..d347e17eee --- /dev/null +++ b/queue-6.19/platform-x86-oxpec-add-support-for-aokzoe-a2-pro.patch @@ -0,0 +1,46 @@ +From 6d6c7f6b762c24e173641724a2ae301e63d74003 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Feb 2026 19:29:53 +0100 +Subject: platform/x86: oxpec: Add support for Aokzoe A2 Pro +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Antheas Kapenekakis + +[ Upstream commit cd0883055b04586770dab43c64159348bf480a3e ] + +Aokzoe A2 Pro is an older device that the oxpec driver is missing the +quirk for. It has the same behavior as the AOKZOE A1 devices. Add a +quirk for it to the oxpec driver. + +Signed-off-by: Antheas Kapenekakis +Link: https://patch.msgid.link/20260223183004.2696892-5-lkml@antheas.dev +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/oxpec.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c +index 623d9a452c469..158c545d4efbb 100644 +--- a/drivers/platform/x86/oxpec.c ++++ b/drivers/platform/x86/oxpec.c +@@ -114,6 +114,13 @@ static const struct dmi_system_id dmi_table[] = { + }, + .driver_data = (void *)aok_zoe_a1, + }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "AOKZOE"), ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "AOKZOE A2 Pro"), ++ }, ++ .driver_data = (void *)aok_zoe_a1, ++ }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "AOKZOE"), +-- +2.51.0 + diff --git a/queue-6.19/platform-x86-oxpec-add-support-for-onexplayer-apex.patch b/queue-6.19/platform-x86-oxpec-add-support-for-onexplayer-apex.patch new file mode 100644 index 0000000000..83d53ed521 --- /dev/null +++ b/queue-6.19/platform-x86-oxpec-add-support-for-onexplayer-apex.patch @@ -0,0 +1,54 @@ +From db6a2a6d78b6e8f6bfddf32f479b8737f7dce6a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Feb 2026 19:29:50 +0100 +Subject: platform/x86: oxpec: Add support for OneXPlayer APEX +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Antheas Kapenekakis + +[ Upstream commit 3385ea97c14d271dcb0c6e6fcf16972f819eecd8 ] + +OneXPlayer Apex is a new Strix Halo handheld. It uses the same registers +as the OneXPlayer Fly devices. Add a quirk for it to the oxpec driver. + +Signed-off-by: Antheas Kapenekakis +Link: https://patch.msgid.link/20260223183004.2696892-2-lkml@antheas.dev +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/oxpec.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c +index 144a454103b93..59d6f9d9a9052 100644 +--- a/drivers/platform/x86/oxpec.c ++++ b/drivers/platform/x86/oxpec.c +@@ -11,7 +11,7 @@ + * + * Copyright (C) 2022 Joaquín I. Aramendía + * Copyright (C) 2024 Derek J. Clark +- * Copyright (C) 2025 Antheas Kapenekakis ++ * Copyright (C) 2025-2026 Antheas Kapenekakis + */ + + #include +@@ -142,6 +142,13 @@ static const struct dmi_system_id dmi_table[] = { + }, + .driver_data = (void *)oxp_2, + }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER APEX"), ++ }, ++ .driver_data = (void *)oxp_fly, ++ }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), +-- +2.51.0 + diff --git a/queue-6.19/platform-x86-oxpec-add-support-for-onexplayer-x1-air.patch b/queue-6.19/platform-x86-oxpec-add-support-for-onexplayer-x1-air.patch new file mode 100644 index 0000000000..32a7bc90f9 --- /dev/null +++ b/queue-6.19/platform-x86-oxpec-add-support-for-onexplayer-x1-air.patch @@ -0,0 +1,45 @@ +From f1b80ab97f48251387f4975e59ae78353567a513 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Feb 2026 19:29:52 +0100 +Subject: platform/x86: oxpec: Add support for OneXPlayer X1 Air +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Antheas Kapenekakis + +[ Upstream commit 2a3b4a8c10a64a62c4243007139d253dc1324dfd ] + +X1 Air is an X1 variant with a newer Intel chipset. It uses the same +registers as the X1. Add a quirk for it to the oxpec driver. + +Signed-off-by: Antheas Kapenekakis +Link: https://patch.msgid.link/20260223183004.2696892-4-lkml@antheas.dev +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/oxpec.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c +index 158c545d4efbb..6d4a53a2ed603 100644 +--- a/drivers/platform/x86/oxpec.c ++++ b/drivers/platform/x86/oxpec.c +@@ -247,6 +247,13 @@ static const struct dmi_system_id dmi_table[] = { + }, + .driver_data = (void *)oxp_x1, + }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER X1Air"), ++ }, ++ .driver_data = (void *)oxp_x1, ++ }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), +-- +2.51.0 + diff --git a/queue-6.19/platform-x86-oxpec-add-support-for-onexplayer-x1z.patch b/queue-6.19/platform-x86-oxpec-add-support-for-onexplayer-x1z.patch new file mode 100644 index 0000000000..54d06447d8 --- /dev/null +++ b/queue-6.19/platform-x86-oxpec-add-support-for-onexplayer-x1z.patch @@ -0,0 +1,45 @@ +From 487943f7ad557f6cf03bb3c7c8067fae9c934707 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Feb 2026 19:29:51 +0100 +Subject: platform/x86: oxpec: Add support for OneXPlayer X1z +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Antheas Kapenekakis + +[ Upstream commit 4049c46edb5d44c0de045f6f504371705dd603dd ] + +X1z is a variant of OneXPlayer X1 A with 8840U. It seems that only one +user has this one. Add a quirk for it to the oxpec driver. + +Signed-off-by: Antheas Kapenekakis +Link: https://patch.msgid.link/20260223183004.2696892-3-lkml@antheas.dev +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/oxpec.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c +index 59d6f9d9a9052..623d9a452c469 100644 +--- a/drivers/platform/x86/oxpec.c ++++ b/drivers/platform/x86/oxpec.c +@@ -219,6 +219,13 @@ static const struct dmi_system_id dmi_table[] = { + }, + .driver_data = (void *)oxp_mini_amd_pro, + }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER X1z"), ++ }, ++ .driver_data = (void *)oxp_x1, ++ }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), +-- +2.51.0 + diff --git a/queue-6.19/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch b/queue-6.19/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch new file mode 100644 index 0000000000..fe9e689686 --- /dev/null +++ b/queue-6.19/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch @@ -0,0 +1,71 @@ +From b2e9955841eb10bed544e3944ad1c308244b9b88 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 14:23:46 +0100 +Subject: platform/x86: touchscreen_dmi: Add quirk for y-inverted Goodix + touchscreen on SUPI S10 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Hans de Goede + +[ Upstream commit 7d87ed70fc95482c12edf9493c249b6413be485e ] + +The touchscreen on the SUPI S10 tablet reports inverted Y coordinates, +causing touch input to be mirrored vertically relative to the display. + +Add a quirk to set the "touchscreen-inverted-y" boolean device-property +on the touchscreen device, so that the goodix_ts driver will fixup +the coordinates. + +Reported-by: Yajat Kumar +Closes: https://lore.kernel.org/linux-input/20251230221639.582406-1-yajatapps3@gmail.com/ +Tested-by: Yajat Kumar +Signed-off-by: Hans de Goede +Link: https://patch.msgid.link/20260217132346.34535-1-johannes.goede@oss.qualcomm.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/touchscreen_dmi.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c +index bdc19cd8d3edf..d83c387821ea1 100644 +--- a/drivers/platform/x86/touchscreen_dmi.c ++++ b/drivers/platform/x86/touchscreen_dmi.c +@@ -410,6 +410,16 @@ static const struct ts_dmi_data gdix1002_upside_down_data = { + .properties = gdix1001_upside_down_props, + }; + ++static const struct property_entry gdix1001_y_inverted_props[] = { ++ PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), ++ { } ++}; ++ ++static const struct ts_dmi_data gdix1001_y_inverted_data = { ++ .acpi_name = "GDIX1001", ++ .properties = gdix1001_y_inverted_props, ++}; ++ + static const struct property_entry gp_electronic_t701_props[] = { + PROPERTY_ENTRY_U32("touchscreen-size-x", 960), + PROPERTY_ENTRY_U32("touchscreen-size-y", 640), +@@ -1658,6 +1668,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_SKU, "PN20170413488"), + }, + }, ++ { ++ /* SUPI S10 */ ++ .driver_data = (void *)&gdix1001_y_inverted_data, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "SUPI"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "S10"), ++ }, ++ }, + { + /* Techbite Arc 11.6 */ + .driver_data = (void *)&techbite_arc_11_6_data, +-- +2.51.0 + diff --git a/queue-6.19/powerpc64-ftrace-fix-ool-stub-count-with-clang.patch b/queue-6.19/powerpc64-ftrace-fix-ool-stub-count-with-clang.patch new file mode 100644 index 0000000000..0770aeb93a --- /dev/null +++ b/queue-6.19/powerpc64-ftrace-fix-ool-stub-count-with-clang.patch @@ -0,0 +1,47 @@ +From 65dafd08710a7f10e64eafd2f7a85eb14093de59 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Jan 2026 14:19:25 +0530 +Subject: powerpc64/ftrace: fix OOL stub count with clang + +From: Hari Bathini + +[ Upstream commit 875612a7745013a43c67493cb0583ee3f7476344 ] + +The total number of out-of-line (OOL) stubs required for function +tracing is determined using the following command: + + $(OBJDUMP) -r -j __patchable_function_entries vmlinux.o + +While this works correctly with GNU objdump, llvm-objdump does not +list the expected relocation records for this section. Fix this by +using the -d option and counting R_PPC64_ADDR64 relocation entries. +This works as desired with both objdump and llvm-objdump. + +Signed-off-by: Hari Bathini +Tested-by: Venkat Rao Bagalkote +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20260127084926.34497-3-hbathini@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/tools/ftrace-gen-ool-stubs.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/powerpc/tools/ftrace-gen-ool-stubs.sh b/arch/powerpc/tools/ftrace-gen-ool-stubs.sh +index bac186bdf64a7..9218d43aeb548 100755 +--- a/arch/powerpc/tools/ftrace-gen-ool-stubs.sh ++++ b/arch/powerpc/tools/ftrace-gen-ool-stubs.sh +@@ -15,9 +15,9 @@ if [ -z "$is_64bit" ]; then + RELOCATION=R_PPC_ADDR32 + fi + +-num_ool_stubs_total=$($objdump -r -j __patchable_function_entries "$vmlinux_o" | ++num_ool_stubs_total=$($objdump -r -j __patchable_function_entries -d "$vmlinux_o" | + grep -c "$RELOCATION") +-num_ool_stubs_inittext=$($objdump -r -j __patchable_function_entries "$vmlinux_o" | ++num_ool_stubs_inittext=$($objdump -r -j __patchable_function_entries -d "$vmlinux_o" | + grep -e ".init.text" -e ".text.startup" | grep -c "$RELOCATION") + num_ool_stubs_text=$((num_ool_stubs_total - num_ool_stubs_inittext)) + +-- +2.51.0 + diff --git a/queue-6.19/s390-mm-add-missing-secure-storage-access-fixups-for.patch b/queue-6.19/s390-mm-add-missing-secure-storage-access-fixups-for.patch new file mode 100644 index 0000000000..c12067d255 --- /dev/null +++ b/queue-6.19/s390-mm-add-missing-secure-storage-access-fixups-for.patch @@ -0,0 +1,63 @@ +From 4b4d92d11c25f377195e765d0cc461dfdb569427 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Mar 2026 10:18:37 +0000 +Subject: s390/mm: Add missing secure storage access fixups for donated memory + +From: Janosch Frank + +[ Upstream commit b00be77302d7ec4ad0367bb236494fce7172b730 ] + +There are special cases where secure storage access exceptions happen +in a kernel context for pages that don't have the PG_arch_1 bit +set. That bit is set for non-exported guest secure storage (memory) +but is absent on storage donated to the Ultravisor since the kernel +isn't allowed to export donated pages. + +Prior to this patch we would try to export the page by calling +arch_make_folio_accessible() which would instantly return since the +arch bit is absent signifying that the page was already exported and +no further action is necessary. This leads to secure storage access +exception loops which can never be resolved. + +With this patch we unconditionally try to export and if that fails we +fixup. + +Fixes: 084ea4d611a3 ("s390/mm: add (non)secure page access exceptions handlers") +Reported-by: Heiko Carstens +Suggested-by: Heiko Carstens +Reviewed-by: Claudio Imbrenda +Tested-by: Christian Borntraeger +Signed-off-by: Janosch Frank +Signed-off-by: Christian Borntraeger +Signed-off-by: Sasha Levin +--- + arch/s390/mm/fault.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c +index e2e13778c36a9..b977150443550 100644 +--- a/arch/s390/mm/fault.c ++++ b/arch/s390/mm/fault.c +@@ -441,10 +441,17 @@ void do_secure_storage_access(struct pt_regs *regs) + folio = phys_to_folio(addr); + if (unlikely(!folio_try_get(folio))) + return; +- rc = arch_make_folio_accessible(folio); ++ rc = uv_convert_from_secure(folio_to_phys(folio)); ++ if (!rc) ++ clear_bit(PG_arch_1, &folio->flags.f); + folio_put(folio); ++ /* ++ * There are some valid fixup types for kernel ++ * accesses to donated secure memory. zeropad is one ++ * of them. ++ */ + if (rc) +- BUG(); ++ return handle_fault_error_nolock(regs, 0); + } else { + if (faulthandler_disabled()) + return handle_fault_error_nolock(regs, 0); +-- +2.51.0 + diff --git a/queue-6.19/sched_ext-use-write_once-for-the-write-side-of-dsq-s.patch b/queue-6.19/sched_ext-use-write_once-for-the-write-side-of-dsq-s.patch new file mode 100644 index 0000000000..d4c8056312 --- /dev/null +++ b/queue-6.19/sched_ext-use-write_once-for-the-write-side-of-dsq-s.patch @@ -0,0 +1,53 @@ +From 88e79d33db60120e2490d549e3648f2beeae0cf9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Mar 2026 13:37:30 +0800 +Subject: sched_ext: Use WRITE_ONCE() for the write side of dsq->seq update + +From: zhidao su + +[ Upstream commit 7a8464555d2e5f038758bb19e72ab4710b79e9cd ] + +bpf_iter_scx_dsq_new() reads dsq->seq via READ_ONCE() without holding +any lock, making dsq->seq a lock-free concurrently accessed variable. +However, dispatch_enqueue(), the sole writer of dsq->seq, uses a plain +increment without the matching WRITE_ONCE() on the write side: + + dsq->seq++; + ^^^^^^^^^^^ + plain write -- KCSAN data race + +The KCSAN documentation requires that if one accessor uses READ_ONCE() +or WRITE_ONCE() on a variable to annotate lock-free access, all other +accesses must also use the appropriate accessor. A plain write leaves +the pair incomplete and will trigger KCSAN warnings. + +Fix by using WRITE_ONCE() for the write side of the update: + + WRITE_ONCE(dsq->seq, dsq->seq + 1); + +This is consistent with bpf_iter_scx_dsq_new() and makes the +concurrent access annotation complete and KCSAN-clean. + +Signed-off-by: zhidao su +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/sched/ext.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c +index f7eeccbd893af..2c32e12af435d 100644 +--- a/kernel/sched/ext.c ++++ b/kernel/sched/ext.c +@@ -1097,7 +1097,7 @@ static void dispatch_enqueue(struct scx_sched *sch, struct scx_dispatch_q *dsq, + } + + /* seq records the order tasks are queued, used by BPF DSQ iterator */ +- dsq->seq++; ++ WRITE_ONCE(dsq->seq, dsq->seq + 1); + p->scx.dsq_seq = dsq->seq; + + dsq_mod_nr(dsq, 1); +-- +2.51.0 + diff --git a/queue-6.19/scsi-devinfo-add-blist_skip_io_hints-for-iomega-zip.patch b/queue-6.19/scsi-devinfo-add-blist_skip_io_hints-for-iomega-zip.patch new file mode 100644 index 0000000000..e5cfe48e2c --- /dev/null +++ b/queue-6.19/scsi-devinfo-add-blist_skip_io_hints-for-iomega-zip.patch @@ -0,0 +1,44 @@ +From 47bd7aea72413f609750eab87e60151f2e42c633 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Feb 2026 19:18:23 +0100 +Subject: scsi: devinfo: Add BLIST_SKIP_IO_HINTS for Iomega ZIP + +From: Florian Fuchs + +[ Upstream commit 80bf3b28d32b431f84f244a8469488eb6d96afbb ] + +The Iomega ZIP 100 (Z100P2) can't process IO Advice Hints Grouping mode +page query. It immediately switches to the status phase 0xb8 after +receiving the subpage code 0x05 of MODE_SENSE_10 command, which fails +imm_out() and turns into DID_ERROR of this command, which leads to unusable +device. This was tested with an Iomega ZIP 100 (Z100P2) connected with a +StarTech PEX1P2 AX99100 PCIe parallel port card. + +Prior to this fix, Test Unit Ready fails and the drive can't be used: + IMM: returned SCSI status b8 + sd 7:0:6:0: [sdh] Test Unit Ready failed: Result: hostbyte=0x01 driverbyte=DRIVER_OK + +Signed-off-by: Florian Fuchs +Link: https://patch.msgid.link/20260227181823.892932-1-fuchsfl@gmail.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/scsi_devinfo.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c +index 78346b2b69c91..c51146882a1fa 100644 +--- a/drivers/scsi/scsi_devinfo.c ++++ b/drivers/scsi/scsi_devinfo.c +@@ -190,7 +190,7 @@ static struct { + {"IBM", "2076", NULL, BLIST_NO_VPD_SIZE}, + {"IBM", "2105", NULL, BLIST_RETRY_HWERROR}, + {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN}, +- {"IOMEGA", "ZIP", NULL, BLIST_NOTQ | BLIST_NOLUN}, ++ {"IOMEGA", "ZIP", NULL, BLIST_NOTQ | BLIST_NOLUN | BLIST_SKIP_IO_HINTS}, + {"IOMEGA", "Io20S *F", NULL, BLIST_KEY}, + {"INSITE", "Floptical F*8I", NULL, BLIST_KEY}, + {"INSITE", "I325VM", NULL, BLIST_KEY}, +-- +2.51.0 + diff --git a/queue-6.19/scsi-mpi3mr-clear-reset-history-on-ready-and-recheck.patch b/queue-6.19/scsi-mpi3mr-clear-reset-history-on-ready-and-recheck.patch new file mode 100644 index 0000000000..f96b093619 --- /dev/null +++ b/queue-6.19/scsi-mpi3mr-clear-reset-history-on-ready-and-recheck.patch @@ -0,0 +1,59 @@ +From bc82c8e173844699bd89f5b8b3e78c637903124d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Feb 2026 13:56:22 +0530 +Subject: scsi: mpi3mr: Clear reset history on ready and recheck state after + timeout + +From: Ranjan Kumar + +[ Upstream commit dbd53975ed4132d161b6a97ebe785a262380182d ] + +The driver retains reset history even after the IOC has successfully +reached the READY state. That leaves stale reset information active during +normal operation and can mislead recovery and diagnostics. In addition, if +the IOC becomes READY just as the ready timeout loop exits, the driver +still follows the failure path and may retry or report failure incorrectly. + +Clear reset history once READY is confirmed so driver state matches actual +IOC status. After the timeout loop, recheck the IOC state and treat READY +as success instead of failing. + +Signed-off-by: Ranjan Kumar +Link: https://patch.msgid.link/20260225082622.82588-1-ranjan.kumar@broadcom.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/mpi3mr/mpi3mr_fw.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c +index 8382afed12813..4c8d78b840fc9 100644 +--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c ++++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c +@@ -1530,6 +1530,7 @@ static int mpi3mr_bring_ioc_ready(struct mpi3mr_ioc *mrioc) + ioc_info(mrioc, + "successfully transitioned to %s state\n", + mpi3mr_iocstate_name(ioc_state)); ++ mpi3mr_clear_reset_history(mrioc); + return 0; + } + ioc_status = readl(&mrioc->sysif_regs->ioc_status); +@@ -1549,6 +1550,15 @@ static int mpi3mr_bring_ioc_ready(struct mpi3mr_ioc *mrioc) + elapsed_time_sec = jiffies_to_msecs(jiffies - start_time)/1000; + } while (elapsed_time_sec < mrioc->ready_timeout); + ++ ioc_state = mpi3mr_get_iocstate(mrioc); ++ if (ioc_state == MRIOC_STATE_READY) { ++ ioc_info(mrioc, ++ "successfully transitioned to %s state after %llu seconds\n", ++ mpi3mr_iocstate_name(ioc_state), elapsed_time_sec); ++ mpi3mr_clear_reset_history(mrioc); ++ return 0; ++ } ++ + out_failed: + elapsed_time_sec = jiffies_to_msecs(jiffies - start_time)/1000; + if ((retry < 2) && (elapsed_time_sec < (mrioc->ready_timeout - 60))) { +-- +2.51.0 + diff --git a/queue-6.19/series b/queue-6.19/series new file mode 100644 index 0000000000..3c27f20d18 --- /dev/null +++ b/queue-6.19/series @@ -0,0 +1,77 @@ +cxl-port-fix-use-after-free-of-parent_port-in-cxl_de.patch +cxl-region-fix-leakage-in-__construct_region.patch +bpf-reset-register-id-for-bpf_end-value-tracking.patch +bpf-fix-constant-blinding-for-probe_mem32-stores.patch +x86-perf-make-sure-to-program-the-counter-value-for-.patch +perf-make-sure-to-use-pmu_ctx-pmu-for-groups.patch +s390-mm-add-missing-secure-storage-access-fixups-for.patch +objtool-klp-fix-data-alignment-in-__clone_symbol.patch +livepatch-klp-build-fix-inconsistent-kernel-version.patch +cxl-hdm-avoid-incorrect-dvsec-fallback-when-hdm-deco.patch +hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch +sh-platform_early-remove-pdev-driver_override-check.patch +driver-core-generalize-driver_override-in-struct-dev.patch +driver-core-platform-use-generic-driver_override-inf.patch +perf-metricgroup-fix-metricgroup__has_metric_or_grou.patch +bpf-release-module-btf-idr-before-module-unload.patch +cxl-adjust-the-startup-priority-of-cxl_pmem-to-be-hi.patch +bpf-fix-exception-exit-lock-checking-for-subprogs.patch +bpf-fix-undefined-behavior-in-interpreter-sdiv-smod-.patch +bpf-fix-unsound-scalar-forking-in-maybe_fork_scalars.patch +tracing-revert-tracing-remove-pid-in-task_rename-tra.patch +platform-x86-hp-wmi-add-omen-16-wf0xxx-fan-and-therm.patch +hid-asus-avoid-memory-leak-in-asus_report_fixup.patch +platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch +nvme-pci-cap-queue-creation-to-used-queues.patch +nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch +platform-x86-hp-wmi-add-omen-16-xd0xxx-fan-and-therm.patch +platform-x86-intel-hid-enable-5-button-array-on-thin.patch +platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch +platform-x86-hp-wmi-add-omen-14-fb1xxx-board-8e41-su.patch +nvme-pci-ensure-we-re-polling-a-polled-queue.patch +hid-magicmouse-fix-battery-reporting-for-apple-magic.patch +hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch +platform-x86-hp-wmi-add-victus-16-d0xxx-support.patch +hid-intel-ish-hid-ipc-add-nova-lake-h-s-pci-device-i.patch +platform-x86-oxpec-add-support-for-onexplayer-apex.patch +hid-apple-add-epomaker-th87-to-the-non-apple-keyboar.patch +platform-x86-oxpec-add-support-for-onexplayer-x1z.patch +net-usb-r8152-add-trendnet-tuc-et2g.patch +kbuild-install-extmod-build-package-resolve_btfids-i.patch +platform-x86-oxpec-add-support-for-aokzoe-a2-pro.patch +platform-x86-oxpec-add-support-for-onexplayer-x1-air.patch +hid-mcp2221-cancel-last-i2c-command-on-read-error.patch +hid-asus-add-xg-mobile-2023-external-hardware-suppor.patch +module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch +asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch +scsi-mpi3mr-clear-reset-history-on-ready-and-recheck.patch +asoc-rt1321-fix-dmic-ch2-3-mask-issue.patch +scsi-devinfo-add-blist_skip_io_hints-for-iomega-zip.patch +asoc-intel-sof_sdw-add-quirk-for-alienware-area-51-2.patch +alsa-hda-hdmi-add-tegra238-hda-codec-device-id.patch +asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-10911 +asoc-cs35l56-only-patch-asp-registers-if-the-dai-is-.patch +spi-spi-dw-dma-fix-print-error-log-when-wait-finish-.patch +dma-buf-include-ioctl.h-in-uapi-header.patch +block-break-pcpu_alloc_mutex-dependency-on-freeze_lo.patch +alsa-hda-senary-ensure-eapd-is-enabled-during-init.patch +drm-ttm-tests-fix-build-failure-on-preempt_rt.patch +asoc-amd-acp-add-acp6.3-match-entries-for-cirrus-log.patch +bpf-fix-u32-s32-bounds-when-ranges-cross-min-max-bou.patch +hid-apple-avoid-memory-leak-in-apple_report_fixup.patch +sched_ext-use-write_once-for-the-write-side-of-dsq-s.patch +btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch +objtool-use-hostcflags-for-have_xxhash-test.patch +powerpc64-ftrace-fix-ool-stub-count-with-clang.patch +alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch +objtool-klp-disable-unsupported-pr_debug-usage.patch +alsa-hda-realtek-add-quirk-for-gigabyte-technology-t.patch +alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch +objtool-handle-clang-rsp-musical-chairs.patch +nvmet-move-async-event-work-off-nvmet-wq.patch +drm-amdgpu-fix-gpu-idle-power-consumption-issue-for-.patch +usb-core-new-quirk-to-handle-devices-with-zero-confi.patch +spi-intel-pci-add-support-for-nova-lake-mobile-spi-f.patch +alsa-usb-audio-add-iface-reset-and-delay-quirk-for-s.patch +alsa-hda-realtek-add-quirk-for-asus-um6702rc.patch +i3c-master-dw-i3c-fix-missing-of_node-for-virtual-i2.patch diff --git a/queue-6.19/sh-platform_early-remove-pdev-driver_override-check.patch b/queue-6.19/sh-platform_early-remove-pdev-driver_override-check.patch new file mode 100644 index 0000000000..a26aa488f8 --- /dev/null +++ b/queue-6.19/sh-platform_early-remove-pdev-driver_override-check.patch @@ -0,0 +1,45 @@ +From 30089e1c23eea9736bbe2888b379c2b5b00b7fdb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Mar 2026 00:37:15 +0100 +Subject: sh: platform_early: remove pdev->driver_override check + +From: Danilo Krummrich + +[ Upstream commit c5f60e3f07b6609562d21efda878e83ce8860728 ] + +In commit 507fd01d5333 ("drivers: move the early platform device support to +arch/sh") platform_match() was copied over to the sh platform_early +code, accidentally including the driver_override check. + +This check does not make sense for platform_early, as sysfs is not even +available in first place at this point in the boot process, hence remove +the check. + +Reviewed-by: Greg Kroah-Hartman +Reviewed-by: Geert Uytterhoeven +Fixes: 507fd01d5333 ("drivers: move the early platform device support to arch/sh") +Link: https://lore.kernel.org/all/DH4M3DJ4P58T.1BGVAVXN71Z09@kernel.org/ +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + arch/sh/drivers/platform_early.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c +index 143747c45206f..48ddbc547bd9a 100644 +--- a/arch/sh/drivers/platform_early.c ++++ b/arch/sh/drivers/platform_early.c +@@ -26,10 +26,6 @@ static int platform_match(struct device *dev, struct device_driver *drv) + struct platform_device *pdev = to_platform_device(dev); + struct platform_driver *pdrv = to_platform_driver(drv); + +- /* When driver_override is set, only bind to the matching driver */ +- if (pdev->driver_override) +- return !strcmp(pdev->driver_override, drv->name); +- + /* Then try to match against the id table */ + if (pdrv->id_table) + return platform_match_id(pdrv->id_table, pdev) != NULL; +-- +2.51.0 + diff --git a/queue-6.19/spi-intel-pci-add-support-for-nova-lake-mobile-spi-f.patch b/queue-6.19/spi-intel-pci-add-support-for-nova-lake-mobile-spi-f.patch new file mode 100644 index 0000000000..4a0b31a0e8 --- /dev/null +++ b/queue-6.19/spi-intel-pci-add-support-for-nova-lake-mobile-spi-f.patch @@ -0,0 +1,36 @@ +From 7450a52cbba69a31dfb6f5dc14771db206009b41 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Mar 2026 16:37:03 +0100 +Subject: spi: intel-pci: Add support for Nova Lake mobile SPI flash + +From: Alan Borzeszkowski + +[ Upstream commit 85b731ad4bbf6eb3fedf267ab00be3596f148432 ] + +Add Intel Nova Lake PCD-H SPI serial flash PCI ID to the list of +supported devices. + +Signed-off-by: Alan Borzeszkowski +Acked-by: Mika Westerberg +Link: https://patch.msgid.link/20260309153703.74282-1-alan.borzeszkowski@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-intel-pci.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/spi/spi-intel-pci.c b/drivers/spi/spi-intel-pci.c +index bce3d149bea18..d8ef8f89330ac 100644 +--- a/drivers/spi/spi-intel-pci.c ++++ b/drivers/spi/spi-intel-pci.c +@@ -96,6 +96,7 @@ static const struct pci_device_id intel_spi_pci_ids[] = { + { PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xa823), (unsigned long)&cnl_info }, ++ { PCI_VDEVICE(INTEL, 0xd323), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xe323), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xe423), (unsigned long)&cnl_info }, + { }, +-- +2.51.0 + diff --git a/queue-6.19/spi-spi-dw-dma-fix-print-error-log-when-wait-finish-.patch b/queue-6.19/spi-spi-dw-dma-fix-print-error-log-when-wait-finish-.patch new file mode 100644 index 0000000000..d619a2f6e1 --- /dev/null +++ b/queue-6.19/spi-spi-dw-dma-fix-print-error-log-when-wait-finish-.patch @@ -0,0 +1,38 @@ +From d46fe0192518c07842bc95b1119be1b1d3a539cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Mar 2026 01:20:17 +0300 +Subject: spi: spi-dw-dma: fix print error log when wait finish transaction + +From: Vladimir Yakovlev + +[ Upstream commit 3b46d61890632c8f8b117147b6923bff4b42ccb7 ] + +If an error occurs, the device may not have a current message. In this +case, the system will crash. + +In this case, it's better to use dev from the struct ctlr (struct spi_controller*). + +Signed-off-by: Vladimir Yakovlev +Link: https://patch.msgid.link/20260302222017.992228-2-vovchkir@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-dw-dma.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c +index 65adec7c7524b..fe726b9b1780d 100644 +--- a/drivers/spi/spi-dw-dma.c ++++ b/drivers/spi/spi-dw-dma.c +@@ -271,7 +271,7 @@ static int dw_spi_dma_wait(struct dw_spi *dws, unsigned int len, u32 speed) + msecs_to_jiffies(ms)); + + if (ms == 0) { +- dev_err(&dws->ctlr->cur_msg->spi->dev, ++ dev_err(&dws->ctlr->dev, + "DMA transaction timed out\n"); + return -ETIMEDOUT; + } +-- +2.51.0 + diff --git a/queue-6.19/tracing-revert-tracing-remove-pid-in-task_rename-tra.patch b/queue-6.19/tracing-revert-tracing-remove-pid-in-task_rename-tra.patch new file mode 100644 index 0000000000..c08730618b --- /dev/null +++ b/queue-6.19/tracing-revert-tracing-remove-pid-in-task_rename-tra.patch @@ -0,0 +1,74 @@ +From b7dc70d46bad3ef71422538c0526ed5267cd55f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 15:59:54 +0800 +Subject: tracing: Revert "tracing: Remove pid in task_rename tracing output" + +From: Xuewen Yan + +[ Upstream commit a6f22e50c7d51aa225c392c62c33f0fae11f734d ] + +This reverts commit e3f6a42272e028c46695acc83fc7d7c42f2750ad. + +The commit says that the tracepoint only deals with the current task, +however the following case is not current task: + +comm_write() { + p = get_proc_task(inode); + if (!p) + return -ESRCH; + + if (same_thread_group(current, p)) + set_task_comm(p, buffer); +} +where set_task_comm() calls __set_task_comm() which records +the update of p and not current. + +So revert the patch to show pid. + +Cc: +Cc: +Cc: +Cc: +Link: https://patch.msgid.link/20260306075954.4533-1-xuewen.yan@unisoc.com +Fixes: e3f6a42272e0 ("tracing: Remove pid in task_rename tracing output") +Reported-by: Guohua Yan +Signed-off-by: Xuewen Yan +Reviewed-by: Steven Rostedt (Google) +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Sasha Levin +--- + include/trace/events/task.h | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/include/trace/events/task.h b/include/trace/events/task.h +index 4f0759634306c..b9a129eb54d9e 100644 +--- a/include/trace/events/task.h ++++ b/include/trace/events/task.h +@@ -38,19 +38,22 @@ TRACE_EVENT(task_rename, + TP_ARGS(task, comm), + + TP_STRUCT__entry( ++ __field( pid_t, pid) + __array( char, oldcomm, TASK_COMM_LEN) + __array( char, newcomm, TASK_COMM_LEN) + __field( short, oom_score_adj) + ), + + TP_fast_assign( ++ __entry->pid = task->pid; + memcpy(entry->oldcomm, task->comm, TASK_COMM_LEN); + strscpy(entry->newcomm, comm, TASK_COMM_LEN); + __entry->oom_score_adj = task->signal->oom_score_adj; + ), + +- TP_printk("oldcomm=%s newcomm=%s oom_score_adj=%hd", +- __entry->oldcomm, __entry->newcomm, __entry->oom_score_adj) ++ TP_printk("pid=%d oldcomm=%s newcomm=%s oom_score_adj=%hd", ++ __entry->pid, __entry->oldcomm, ++ __entry->newcomm, __entry->oom_score_adj) + ); + + /** +-- +2.51.0 + diff --git a/queue-6.19/usb-core-new-quirk-to-handle-devices-with-zero-confi.patch b/queue-6.19/usb-core-new-quirk-to-handle-devices-with-zero-confi.patch new file mode 100644 index 0000000000..8fd7be34dd --- /dev/null +++ b/queue-6.19/usb-core-new-quirk-to-handle-devices-with-zero-confi.patch @@ -0,0 +1,107 @@ +From 2ed60e41b6163fca8a5d190df61837cfd61afaeb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Feb 2026 16:49:31 +0800 +Subject: usb: core: new quirk to handle devices with zero configurations + +From: Jie Deng + +[ Upstream commit 9f6a983cfa22ac662c86e60816d3a357d4b551e9 ] + +Some USB devices incorrectly report bNumConfigurations as 0 in their +device descriptor, which causes the USB core to reject them during +enumeration. +logs: +usb 1-2: device descriptor read/64, error -71 +usb 1-2: no configurations +usb 1-2: can't read configurations, error -22 + +However, these devices actually work correctly when +treated as having a single configuration. + +Add a new quirk USB_QUIRK_FORCE_ONE_CONFIG to handle such devices. +When this quirk is set, assume the device has 1 configuration instead +of failing with -EINVAL. + +This quirk is applied to the device with VID:PID 5131:2007 which +exhibits this behavior. + +Signed-off-by: Jie Deng +Link: https://patch.msgid.link/20260227084931.1527461-1-dengjie03@kylinos.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + Documentation/admin-guide/kernel-parameters.txt | 3 +++ + drivers/usb/core/config.c | 6 +++++- + drivers/usb/core/quirks.c | 5 +++++ + include/linux/usb/quirks.h | 3 +++ + 4 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index aa0031108bc1d..f31e9e4c598fc 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -8090,6 +8090,9 @@ Kernel parameters + p = USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT + (Reduce timeout of the SET_ADDRESS + request from 5000 ms to 500 ms); ++ q = USB_QUIRK_FORCE_ONE_CONFIG (Device ++ claims zero configurations, ++ forcing to 1); + Example: quirks=0781:5580:bk,0a5c:5834:gij + + usbhid.mousepoll= +diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c +index 2bb1ceb9d621a..3067e18ec4d8a 100644 +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -927,7 +927,11 @@ int usb_get_configuration(struct usb_device *dev) + dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG; + } + +- if (ncfg < 1) { ++ if (ncfg < 1 && dev->quirks & USB_QUIRK_FORCE_ONE_CONFIG) { ++ dev_info(ddev, "Device claims zero configurations, forcing to 1\n"); ++ dev->descriptor.bNumConfigurations = 1; ++ ncfg = 1; ++ } else if (ncfg < 1) { + dev_err(ddev, "no configurations\n"); + return -EINVAL; + } +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 9fef2f4d604a5..65168eb89295c 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -141,6 +141,8 @@ static int quirks_param_set(const char *value, const struct kernel_param *kp) + case 'p': + flags |= USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT; + break; ++ case 'q': ++ flags |= USB_QUIRK_FORCE_ONE_CONFIG; + /* Ignore unrecognized flag characters */ + } + } +@@ -597,6 +599,9 @@ static const struct usb_device_id usb_quirk_list[] = { + /* VCOM device */ + { USB_DEVICE(0x4296, 0x7570), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS }, + ++ /* Noji-MCS SmartCard Reader */ ++ { USB_DEVICE(0x5131, 0x2007), .driver_info = USB_QUIRK_FORCE_ONE_CONFIG }, ++ + /* INTEL VALUE SSD */ + { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, + +diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h +index 2f7bd2fdc6164..b3cc7beab4a3c 100644 +--- a/include/linux/usb/quirks.h ++++ b/include/linux/usb/quirks.h +@@ -78,4 +78,7 @@ + /* skip BOS descriptor request */ + #define USB_QUIRK_NO_BOS BIT(17) + ++/* Device claims zero configurations, forcing to 1 */ ++#define USB_QUIRK_FORCE_ONE_CONFIG BIT(18) ++ + #endif /* __LINUX_USB_QUIRKS_H */ +-- +2.51.0 + diff --git a/queue-6.19/x86-perf-make-sure-to-program-the-counter-value-for-.patch b/queue-6.19/x86-perf-make-sure-to-program-the-counter-value-for-.patch new file mode 100644 index 0000000000..1806a24227 --- /dev/null +++ b/queue-6.19/x86-perf-make-sure-to-program-the-counter-value-for-.patch @@ -0,0 +1,51 @@ +From 064e7f2c26b28676bbe02dcc81144904c0953460 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Mar 2026 21:29:14 +0100 +Subject: x86/perf: Make sure to program the counter value for stopped events + on migration + +From: Peter Zijlstra + +[ Upstream commit f1cac6ac62d28a9a57b17f51ac5795bf250c12d3 ] + +Both Mi Dapeng and Ian Rogers noted that not everything that sets HES_STOPPED +is required to EF_UPDATE. Specifically the 'step 1' loop of rescheduling +explicitly does EF_UPDATE to ensure the counter value is read. + +However, then 'step 2' simply leaves the new counter uninitialized when +HES_STOPPED, even though, as noted above, the thing that stopped them might not +be aware it needs to EF_RELOAD -- since it didn't EF_UPDATE on stop. + +One such location that is affected is throttling, throttle does pmu->stop(, 0); +and unthrottle does pmu->start(, 0); possibly restarting an uninitialized counter. + +Fixes: a4eaf7f14675 ("perf: Rework the PMU methods") +Reported-by: Dapeng Mi +Reported-by: Ian Rogers +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Dapeng Mi +Link: https://patch.msgid.link/20260311204035.GX606826@noisy.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + arch/x86/events/core.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c +index 818de24921a48..7a6b15b0f1c66 100644 +--- a/arch/x86/events/core.c ++++ b/arch/x86/events/core.c +@@ -1371,8 +1371,10 @@ static void x86_pmu_enable(struct pmu *pmu) + + cpuc->events[hwc->idx] = event; + +- if (hwc->state & PERF_HES_ARCH) ++ if (hwc->state & PERF_HES_ARCH) { ++ static_call(x86_pmu_set_period)(event); + continue; ++ } + + /* + * if cpuc->enabled = 0, then no wrmsr as +-- +2.51.0 + diff --git a/queue-6.6/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch b/queue-6.6/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch new file mode 100644 index 0000000000..c0fabc7817 --- /dev/null +++ b/queue-6.6/alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch @@ -0,0 +1,43 @@ +From 11063ae3dd802789b6511a65ef2e435a78d94b90 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Mar 2026 06:29:06 +0500 +Subject: ALSA: hda/realtek: Add headset jack quirk for Thinkpad X390 + +From: Uzair Mughal + +[ Upstream commit 542127f6528ca7cc3cf61e1651d6ccb58495f953 ] + +The Lenovo ThinkPad X390 (ALC257 codec, subsystem ID 0x17aa2288) +does not report headset button press events. Headphone insertion is +detected (SW_HEADPHONE_INSERT), but pressing the inline microphone +button on a headset produces no input events. + +Add a SND_PCI_QUIRK entry that maps this subsystem ID to +ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, which enables +headset jack button detection through alc_fixup_headset_jack() +and ThinkPad ACPI integration. This is the same fixup used by +similar ThinkPad models (P1 Gen 3, X1 Extreme Gen 3). + +Signed-off-by: Uzair Mughal +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20260307012906.20093-1-contact@uzair.is-a.dev +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 908028d060c8d..1a5e2fb0c842b 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10520,6 +10520,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), + SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), + SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), ++ SND_PCI_QUIRK(0x17aa, 0x2288, "Thinkpad X390", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x22c1, "Thinkpad P1 Gen 3", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), +-- +2.51.0 + diff --git a/queue-6.6/alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch b/queue-6.6/alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch new file mode 100644 index 0000000000..b0fd600b83 --- /dev/null +++ b/queue-6.6/alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch @@ -0,0 +1,38 @@ +From 4ecd6836c19777dfb7e52a7058e8ca9732537e61 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Mar 2026 11:27:27 +0800 +Subject: ALSA: hda/realtek: add HP Laptop 14s-dr5xxx mute LED quirk + +From: Liucheng Lu + +[ Upstream commit 178dd118c0f07fd63a9ed74cfbd8c31ae50e33af ] + +HP Laptop 14s-dr5xxx with ALC236 codec does not handle the toggling of +the mute LED. +This patch adds a quirk entry for subsystem ID 0x8a1f using +ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 fixup, enabling correct mute LED +behavior. + +Signed-off-by: Liucheng Lu +Link: https://patch.msgid.link/PAVPR03MB9774F3FCE9CCD181C585281AE37BA@PAVPR03MB9774.eurprd03.prod.outlook.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 5b836a91135cc..908028d060c8d 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10175,6 +10175,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x89d3, "HP EliteBook 645 G9 (MB 89D2)", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x8a0f, "HP Pavilion 14-ec1xxx", ALC287_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8a1f, "HP Laptop 14s-dr5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), + SND_PCI_QUIRK(0x103c, 0x8a78, "HP Dev One", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), +-- +2.51.0 + diff --git a/queue-6.6/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch b/queue-6.6/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch new file mode 100644 index 0000000000..a43b0c0e0a --- /dev/null +++ b/queue-6.6/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch @@ -0,0 +1,52 @@ +From 551d769a883086ef9a9549e9fee2e07ec9fe0bc9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 00:25:38 +0000 +Subject: ASoC: fsl_easrc: Fix event generation in fsl_easrc_iec958_set_reg() + +From: Mark Brown + +[ Upstream commit 31ddc62c1cd92e51b9db61d7954b85ae2ec224da ] + +ALSA controls should return 1 if the value in the control changed but the +control put operation fsl_easrc_set_reg() only returns 0 or a negative +error code, causing ALSA to not generate any change events. Add a suitable +check by using regmap_update_bits_check() with the underlying regmap, this +is more clearly and simply correct than trying to verify that one of the +generic ops is exactly equivalent to this one. + +Signed-off-by: Mark Brown +Link: https://patch.msgid.link/20260205-asoc-fsl-easrc-fix-events-v1-2-39d4c766918b@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_easrc.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c +index ec53bda46a467..c3d81cab2556d 100644 +--- a/sound/soc/fsl/fsl_easrc.c ++++ b/sound/soc/fsl/fsl_easrc.c +@@ -93,14 +93,17 @@ static int fsl_easrc_set_reg(struct snd_kcontrol *kcontrol, + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_value; ++ struct fsl_asrc *easrc = snd_soc_component_get_drvdata(component); + unsigned int regval = ucontrol->value.integer.value[0]; ++ bool changed; + int ret; + +- ret = snd_soc_component_write(component, mc->regbase, regval); +- if (ret < 0) ++ ret = regmap_update_bits_check(easrc->regmap, mc->regbase, ++ GENMASK(31, 0), regval, &changed); ++ if (ret != 0) + return ret; + +- return 0; ++ return changed; + } + + #define SOC_SINGLE_REG_RW(xname, xreg) \ +-- +2.51.0 + diff --git a/queue-6.6/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-670 b/queue-6.6/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-670 new file mode 100644 index 0000000000..94cfede701 --- /dev/null +++ b/queue-6.6/asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-670 @@ -0,0 +1,49 @@ +From 1fe88e47d18fedb8d47e2e2b590b64e3c3cdde48 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 00:25:37 +0000 +Subject: ASoC: fsl_easrc: Fix event generation in fsl_easrc_iec958_put_bits() + +From: Mark Brown + +[ Upstream commit 54a86cf48eaa6d1ab5130d756b718775e81e1748 ] + +ALSA controls should return 1 if the value in the control changed but the +control put operation fsl_easrc_iec958_put_bits() unconditionally returns +0, causing ALSA to not generate any change events. This is detected by +mixer-test with large numbers of messages in the form: + + No event generated for Context 3 IEC958 CS5 + Context 3 IEC958 CS5.0 orig 5224 read 5225, is_volatile 0 + +Add a suitable check. + +Signed-off-by: Mark Brown +Link: https://patch.msgid.link/20260205-asoc-fsl-easrc-fix-events-v1-1-39d4c766918b@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_easrc.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c +index c3d81cab2556d..13396a167b8ac 100644 +--- a/sound/soc/fsl/fsl_easrc.c ++++ b/sound/soc/fsl/fsl_easrc.c +@@ -52,10 +52,13 @@ static int fsl_easrc_iec958_put_bits(struct snd_kcontrol *kcontrol, + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_value; + unsigned int regval = ucontrol->value.integer.value[0]; ++ int ret; ++ ++ ret = (easrc_priv->bps_iec958[mc->regbase] != regval); + + easrc_priv->bps_iec958[mc->regbase] = regval; + +- return 0; ++ return ret; + } + + static int fsl_easrc_iec958_get_bits(struct snd_kcontrol *kcontrol, +-- +2.51.0 + diff --git a/queue-6.6/bpf-fix-undefined-behavior-in-interpreter-sdiv-smod-.patch b/queue-6.6/bpf-fix-undefined-behavior-in-interpreter-sdiv-smod-.patch new file mode 100644 index 0000000000..bb0510964a --- /dev/null +++ b/queue-6.6/bpf-fix-undefined-behavior-in-interpreter-sdiv-smod-.patch @@ -0,0 +1,104 @@ +From 7d11f7ebe4e6f67643caaa9a010ccea7a3a4b052 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Mar 2026 01:11:15 +0000 +Subject: bpf: Fix undefined behavior in interpreter sdiv/smod for INT_MIN + +From: Jenny Guanni Qu + +[ Upstream commit c77b30bd1dcb61f66c640ff7d2757816210c7cb0 ] + +The BPF interpreter's signed 32-bit division and modulo handlers use +the kernel abs() macro on s32 operands. The abs() macro documentation +(include/linux/math.h) explicitly states the result is undefined when +the input is the type minimum. When DST contains S32_MIN (0x80000000), +abs((s32)DST) triggers undefined behavior and returns S32_MIN unchanged +on arm64/x86. This value is then sign-extended to u64 as +0xFFFFFFFF80000000, causing do_div() to compute the wrong result. + +The verifier's abstract interpretation (scalar32_min_max_sdiv) computes +the mathematically correct result for range tracking, creating a +verifier/interpreter mismatch that can be exploited for out-of-bounds +map value access. + +Introduce abs_s32() which handles S32_MIN correctly by casting to u32 +before negating, avoiding signed overflow entirely. Replace all 8 +abs((s32)...) call sites in the interpreter's sdiv32/smod32 handlers. + +s32 is the only affected case -- the s64 division/modulo handlers do +not use abs(). + +Fixes: ec0e2da95f72 ("bpf: Support new signed div/mod instructions.") +Acked-by: Yonghong Song +Acked-by: Mykyta Yatsenko +Signed-off-by: Jenny Guanni Qu +Link: https://lore.kernel.org/r/20260311011116.2108005-2-qguanni@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/core.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c +index a343248c35ded..3011add7c4a88 100644 +--- a/kernel/bpf/core.c ++++ b/kernel/bpf/core.c +@@ -1667,6 +1667,12 @@ bool bpf_opcode_in_insntable(u8 code) + } + + #ifndef CONFIG_BPF_JIT_ALWAYS_ON ++/* Absolute value of s32 without undefined behavior for S32_MIN */ ++static u32 abs_s32(s32 x) ++{ ++ return x >= 0 ? (u32)x : -(u32)x; ++} ++ + /** + * ___bpf_prog_run - run eBPF program on a given context + * @regs: is the array of MAX_BPF_EXT_REG eBPF pseudo-registers +@@ -1831,8 +1837,8 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn) + DST = do_div(AX, (u32) SRC); + break; + case 1: +- AX = abs((s32)DST); +- AX = do_div(AX, abs((s32)SRC)); ++ AX = abs_s32((s32)DST); ++ AX = do_div(AX, abs_s32((s32)SRC)); + if ((s32)DST < 0) + DST = (u32)-AX; + else +@@ -1859,8 +1865,8 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn) + DST = do_div(AX, (u32) IMM); + break; + case 1: +- AX = abs((s32)DST); +- AX = do_div(AX, abs((s32)IMM)); ++ AX = abs_s32((s32)DST); ++ AX = do_div(AX, abs_s32((s32)IMM)); + if ((s32)DST < 0) + DST = (u32)-AX; + else +@@ -1886,8 +1892,8 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn) + DST = (u32) AX; + break; + case 1: +- AX = abs((s32)DST); +- do_div(AX, abs((s32)SRC)); ++ AX = abs_s32((s32)DST); ++ do_div(AX, abs_s32((s32)SRC)); + if (((s32)DST < 0) == ((s32)SRC < 0)) + DST = (u32)AX; + else +@@ -1913,8 +1919,8 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn) + DST = (u32) AX; + break; + case 1: +- AX = abs((s32)DST); +- do_div(AX, abs((s32)IMM)); ++ AX = abs_s32((s32)DST); ++ do_div(AX, abs_s32((s32)IMM)); + if (((s32)DST < 0) == ((s32)IMM < 0)) + DST = (u32)AX; + else +-- +2.51.0 + diff --git a/queue-6.6/bpf-release-module-btf-idr-before-module-unload.patch b/queue-6.6/bpf-release-module-btf-idr-before-module-unload.patch new file mode 100644 index 0000000000..aea9e4f1b7 --- /dev/null +++ b/queue-6.6/bpf-release-module-btf-idr-before-module-unload.patch @@ -0,0 +1,128 @@ +From 0cc918fd353fba50b0432324ea9a3062c255bad7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Mar 2026 13:53:07 -0700 +Subject: bpf: Release module BTF IDR before module unload + +From: Kumar Kartikeya Dwivedi + +[ Upstream commit 146bd2a87a65aa407bb17fac70d8d583d19aba06 ] + +Gregory reported in [0] that the global_map_resize test when run in +repeatedly ends up failing during program load. This stems from the fact +that BTF reference has not dropped to zero after the previous run's +module is unloaded, and the older module's BTF is still discoverable and +visible. Later, in libbpf, load_module_btfs() will find the ID for this +stale BTF, open its fd, and then it will be used during program load +where later steps taking module reference using btf_try_get_module() +fail since the underlying module for the BTF is gone. + +Logically, once a module is unloaded, it's associated BTF artifacts +should become hidden. The BTF object inside the kernel may still remain +alive as long its reference counts are alive, but it should no longer be +discoverable. + +To fix this, let us call btf_free_id() from the MODULE_STATE_GOING case +for the module unload to free the BTF associated IDR entry, and disable +its discovery once module unload returns to user space. If a race +happens during unload, the outcome is non-deterministic anyway. However, +user space should be able to rely on the guarantee that once it has +synchronously established a successful module unload, no more stale +artifacts associated with this module can be obtained subsequently. + +Note that we must be careful to not invoke btf_free_id() in btf_put() +when btf_is_module() is true now. There could be a window where the +module unload drops a non-terminal reference, frees the IDR, but the +same ID gets reused and the second unconditional btf_free_id() ends up +releasing an unrelated entry. + +To avoid a special case for btf_is_module() case, set btf->id to zero to +make btf_free_id() idempotent, such that we can unconditionally invoke it +from btf_put(), and also from the MODULE_STATE_GOING case. Since zero is +an invalid IDR, the idr_remove() should be a noop. + +Note that we can be sure that by the time we reach final btf_put() for +btf_is_module() case, the btf_free_id() is already done, since the +module itself holds the BTF reference, and it will call this function +for the BTF before dropping its own reference. + + [0]: https://lore.kernel.org/bpf/cover.1773170190.git.grbell@redhat.com + +Fixes: 36e68442d1af ("bpf: Load and verify kernel module BTFs") +Acked-by: Martin KaFai Lau +Suggested-by: Martin KaFai Lau +Reported-by: Gregory Bell +Reviewed-by: Emil Tsalapatis +Signed-off-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20260312205307.1346991-1-memxor@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/btf.c | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c +index 14361b3b9edd0..1ace7faa59cfd 100644 +--- a/kernel/bpf/btf.c ++++ b/kernel/bpf/btf.c +@@ -1636,7 +1636,16 @@ static void btf_free_id(struct btf *btf) + * of the _bh() version. + */ + spin_lock_irqsave(&btf_idr_lock, flags); +- idr_remove(&btf_idr, btf->id); ++ if (btf->id) { ++ idr_remove(&btf_idr, btf->id); ++ /* ++ * Clear the id here to make this function idempotent, since it will get ++ * called a couple of times for module BTFs: on module unload, and then ++ * the final btf_put(). btf_alloc_id() starts IDs with 1, so we can use ++ * 0 as sentinel value. ++ */ ++ WRITE_ONCE(btf->id, 0); ++ } + spin_unlock_irqrestore(&btf_idr_lock, flags); + } + +@@ -7158,7 +7167,7 @@ static void bpf_btf_show_fdinfo(struct seq_file *m, struct file *filp) + { + const struct btf *btf = filp->private_data; + +- seq_printf(m, "btf_id:\t%u\n", btf->id); ++ seq_printf(m, "btf_id:\t%u\n", READ_ONCE(btf->id)); + } + #endif + +@@ -7250,7 +7259,7 @@ int btf_get_info_by_fd(const struct btf *btf, + if (copy_from_user(&info, uinfo, info_copy)) + return -EFAULT; + +- info.id = btf->id; ++ info.id = READ_ONCE(btf->id); + ubtf = u64_to_user_ptr(info.btf); + btf_copy = min_t(u32, btf->data_size, info.btf_size); + if (copy_to_user(ubtf, btf->data, btf_copy)) +@@ -7313,7 +7322,7 @@ int btf_get_fd_by_id(u32 id) + + u32 btf_obj_id(const struct btf *btf) + { +- return btf->id; ++ return READ_ONCE(btf->id); + } + + bool btf_is_kernel(const struct btf *btf) +@@ -7445,6 +7454,13 @@ static int btf_module_notify(struct notifier_block *nb, unsigned long op, + if (btf_mod->module != module) + continue; + ++ /* ++ * For modules, we do the freeing of BTF IDR as soon as ++ * module goes away to disable BTF discovery, since the ++ * btf_try_get_module() on such BTFs will fail. This may ++ * be called again on btf_put(), but it's ok to do so. ++ */ ++ btf_free_id(btf_mod->btf); + list_del(&btf_mod->list); + if (btf_mod->sysfs_attr) + sysfs_remove_bin_file(btf_kobj, btf_mod->sysfs_attr); +-- +2.51.0 + diff --git a/queue-6.6/btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch b/queue-6.6/btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch new file mode 100644 index 0000000000..3c0c5ed9e1 --- /dev/null +++ b/queue-6.6/btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch @@ -0,0 +1,196 @@ +From fec17e64cebef9bede282312f9ba814f57211d35 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Feb 2026 14:25:35 -0800 +Subject: btrfs: set BTRFS_ROOT_ORPHAN_CLEANUP during subvol create + +From: Boris Burkov + +[ Upstream commit 5131fa077f9bb386a1b901bf5b247041f0ec8f80 ] + +We have recently observed a number of subvolumes with broken dentries. +ls-ing the parent dir looks like: + +drwxrwxrwt 1 root root 16 Jan 23 16:49 . +drwxr-xr-x 1 root root 24 Jan 23 16:48 .. +d????????? ? ? ? ? ? broken_subvol + +and similarly stat-ing the file fails. + +In this state, deleting the subvol fails with ENOENT, but attempting to +create a new file or subvol over it errors out with EEXIST and even +aborts the fs. Which leaves us a bit stuck. + +dmesg contains a single notable error message reading: +"could not do orphan cleanup -2" + +2 is ENOENT and the error comes from the failure handling path of +btrfs_orphan_cleanup(), with the stack leading back up to +btrfs_lookup(). + +btrfs_lookup +btrfs_lookup_dentry +btrfs_orphan_cleanup // prints that message and returns -ENOENT + +After some detailed inspection of the internal state, it became clear +that: +- there are no orphan items for the subvol +- the subvol is otherwise healthy looking, it is not half-deleted or + anything, there is no drop progress, etc. +- the subvol was created a while ago and does the meaningful first + btrfs_orphan_cleanup() call that sets BTRFS_ROOT_ORPHAN_CLEANUP much + later. +- after btrfs_orphan_cleanup() fails, btrfs_lookup_dentry() returns -ENOENT, + which results in a negative dentry for the subvolume via + d_splice_alias(NULL, dentry), leading to the observed behavior. The + bug can be mitigated by dropping the dentry cache, at which point we + can successfully delete the subvolume if we want. + +i.e., +btrfs_lookup() + btrfs_lookup_dentry() + if (!sb_rdonly(inode->vfs_inode)->vfs_inode) + btrfs_orphan_cleanup(sub_root) + test_and_set_bit(BTRFS_ROOT_ORPHAN_CLEANUP) + btrfs_search_slot() // finds orphan item for inode N + ... + prints "could not do orphan cleanup -2" + if (inode == ERR_PTR(-ENOENT)) + inode = NULL; + return d_splice_alias(NULL, dentry) // NEGATIVE DENTRY for valid subvolume + +btrfs_orphan_cleanup() does test_and_set_bit(BTRFS_ROOT_ORPHAN_CLEANUP) +on the root when it runs, so it cannot run more than once on a given +root, so something else must run concurrently. However, the obvious +routes to deleting an orphan when nlinks goes to 0 should not be able to +run without first doing a lookup into the subvolume, which should run +btrfs_orphan_cleanup() and set the bit. + +The final important observation is that create_subvol() calls +d_instantiate_new() but does not set BTRFS_ROOT_ORPHAN_CLEANUP, so if +the dentry cache gets dropped, the next lookup into the subvolume will +make a real call into btrfs_orphan_cleanup() for the first time. This +opens up the possibility of concurrently deleting the inode/orphan items +but most typical evict() paths will be holding a reference on the parent +dentry (child dentry holds parent->d_lockref.count via dget in +d_alloc(), released in __dentry_kill()) and prevent the parent from +being removed from the dentry cache. + +The one exception is delayed iputs. Ordered extent creation calls +igrab() on the inode. If the file is unlinked and closed while those +refs are held, iput() in __dentry_kill() decrements i_count but does +not trigger eviction (i_count > 0). The child dentry is freed and the +subvol dentry's d_lockref.count drops to 0, making it evictable while +the inode is still alive. + +Since there are two races (the race between writeback and unlink and +the race between lookup and delayed iputs), and there are too many moving +parts, the following three diagrams show the complete picture. +(Only the second and third are races) + +Phase 1: +Create Subvol in dentry cache without BTRFS_ROOT_ORPHAN_CLEANUP set + +btrfs_mksubvol() + lookup_one_len() + __lookup_slow() + d_alloc_parallel() + __d_alloc() // d_lockref.count = 1 + create_subvol(dentry) + // doesn't touch the bit.. + d_instantiate_new(dentry, inode) // dentry in cache with d_lockref.count == 1 + +Phase 2: +Create a delayed iput for a file in the subvol but leave the subvol in +state where its dentry can be evicted (d_lockref.count == 0) + +T1 (task) T2 (writeback) T3 (OE workqueue) + +write() // dirty pages + btrfs_writepages() + btrfs_run_delalloc_range() + cow_file_range() + btrfs_alloc_ordered_extent() + igrab() // i_count: 1 -> 2 +btrfs_unlink_inode() + btrfs_orphan_add() +close() + __fput() + dput() + finish_dput() + __dentry_kill() + dentry_unlink_inode() + iput() // 2 -> 1 + --parent->d_lockref.count // 1 -> 0; evictable + finish_ordered_fn() + btrfs_finish_ordered_io() + btrfs_put_ordered_extent() + btrfs_add_delayed_iput() + +Phase 3: +Once the delayed iput is pending and the subvol dentry is evictable, +the shrinker can free it, causing the next lookup to go through +btrfs_lookup() and call btrfs_orphan_cleanup() for the first time. +If the cleaner kthread processes the delayed iput concurrently, the +two race: + + T1 (shrinker) T2 (cleaner kthread) T3 (lookup) + + super_cache_scan() + prune_dcache_sb() + __dentry_kill() + // subvol dentry freed + btrfs_run_delayed_iputs() + iput() // i_count -> 0 + evict() // sets I_FREEING + btrfs_evict_inode() + // truncation loop + btrfs_lookup() + btrfs_lookup_dentry() + btrfs_orphan_cleanup() + // first call (bit never set) + btrfs_iget() + // blocks on I_FREEING + + btrfs_orphan_del() + // inode freed + // returns -ENOENT + btrfs_del_orphan_item() + // -ENOENT + // "could not do orphan cleanup -2" + d_splice_alias(NULL, dentry) + // negative dentry for valid subvol + +The most straightforward fix is to ensure the invariant that a dentry +for a subvolume can exist if and only if that subvolume has +BTRFS_ROOT_ORPHAN_CLEANUP set on its root (and is known to have no +orphans or ran btrfs_orphan_cleanup()). + +Reviewed-by: Filipe Manana +Signed-off-by: Boris Burkov +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/ioctl.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index a441b49962a3e..4723013995f5b 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -759,6 +759,13 @@ static noinline int create_subvol(struct mnt_idmap *idmap, + goto out; + } + ++ /* ++ * Subvolumes have orphans cleaned on first dentry lookup. A new ++ * subvolume cannot have any orphans, so we should set the bit before we ++ * add the subvolume dentry to the dentry cache, so that it is in the ++ * same state as a subvolume after first lookup. ++ */ ++ set_bit(BTRFS_ROOT_ORPHAN_CLEANUP, &new_root->state); + d_instantiate_new(dentry, new_inode_args.inode); + new_inode_args.inode = NULL; + +-- +2.51.0 + diff --git a/queue-6.6/cxl-hdm-avoid-incorrect-dvsec-fallback-when-hdm-deco.patch b/queue-6.6/cxl-hdm-avoid-incorrect-dvsec-fallback-when-hdm-deco.patch new file mode 100644 index 0000000000..b70e1a8259 --- /dev/null +++ b/queue-6.6/cxl-hdm-avoid-incorrect-dvsec-fallback-when-hdm-deco.patch @@ -0,0 +1,101 @@ +From 52261e7688be8f9794f89a7dad200e176720c20b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Mar 2026 20:19:49 +0000 +Subject: cxl/hdm: Avoid incorrect DVSEC fallback when HDM decoders are enabled + +From: Smita Koralahalli + +[ Upstream commit 75cea0776de502f2a1be5ca02d37c586dc81887e ] + +Check the global CXL_HDM_DECODER_ENABLE bit instead of looping over +per-decoder COMMITTED bits to determine whether to fall back to DVSEC +range emulation. When the HDM decoder capability is globally enabled, +ignore DVSEC range registers regardless of individual decoder commit +state. + +should_emulate_decoders() currently loops over per-decoder COMMITTED +bits, which leads to an incorrect DVSEC fallback when those bits are +zero. One way to trigger this is to destroy a region and bounce the +memdev: + + cxl disable-region region0 + cxl destroy-region region0 + cxl disable-memdev mem0 + cxl enable-memdev mem0 + +Region teardown zeroes the HDM decoder registers including the committed +bits. The subsequent memdev re-probe finds uncommitted decoders and falls +back to DVSEC emulation, even though HDM remains globally enabled. + +Observed failures: + + should_emulate_decoders: cxl_port endpoint6: decoder6.0: committed: 0 base: 0x0_00000000 size: 0x0_00000000 + devm_cxl_setup_hdm: cxl_port endpoint6: Fallback map 1 range register + .. + devm_cxl_add_region: cxl_acpi ACPI0017:00: decoder0.0: created region0 + __construct_region: cxl_pci 0000:e1:00.0: mem1:decoder6.0: + __construct_region region0 res: [mem 0x850000000-0x284fffffff flags 0x200] iw: 1 ig: 4096 + cxl region0: pci0000:e0:port1 cxl_port_setup_targets expected iw: 1 ig: 4096 .. + cxl region0: pci0000:e0:port1 cxl_port_setup_targets got iw: 1 ig: 256 state: disabled .. + cxl_port endpoint6: failed to attach decoder6.0 to region0: -6 + .. + devm_cxl_add_region: cxl_acpi ACPI0017:00: decoder0.0: created region4 + alloc_hpa: cxl region4: HPA allocation error (-34) .. + +Fixes: 52cc48ad2a76 ("cxl/hdm: Limit emulation to the number of range registers") +Signed-off-by: Smita Koralahalli +Reviewed-by: Dan Williams +Link: https://patch.msgid.link/20260316201950.224567-1-Smita.KoralahalliChannabasappa@amd.com +Signed-off-by: Dave Jiang +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/hdm.c | 25 +++++++++---------------- + 1 file changed, 9 insertions(+), 16 deletions(-) + +diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c +index f9738c863df0e..dc4dff7a2d38d 100644 +--- a/drivers/cxl/core/hdm.c ++++ b/drivers/cxl/core/hdm.c +@@ -119,7 +119,6 @@ static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info) + struct cxl_hdm *cxlhdm; + void __iomem *hdm; + u32 ctrl; +- int i; + + if (!info) + return false; +@@ -138,22 +137,16 @@ static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info) + return false; + + /* +- * If any decoders are committed already, there should not be any +- * emulated DVSEC decoders. ++ * If HDM decoders are globally enabled, do not fall back to DVSEC ++ * range emulation. Zeroed decoder registers after region teardown ++ * do not imply absence of HDM capability. ++ * ++ * Falling back to DVSEC here would treat the decoder as AUTO and ++ * may incorrectly latch default interleave settings. + */ +- for (i = 0; i < cxlhdm->decoder_count; i++) { +- ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(i)); +- dev_dbg(&info->port->dev, +- "decoder%d.%d: committed: %ld base: %#x_%.8x size: %#x_%.8x\n", +- info->port->id, i, +- FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl), +- readl(hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET(i)), +- readl(hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(i)), +- readl(hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET(i)), +- readl(hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(i))); +- if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl)) +- return false; +- } ++ ctrl = readl(hdm + CXL_HDM_DECODER_CTRL_OFFSET); ++ if (ctrl & CXL_HDM_DECODER_ENABLE) ++ return false; + + return true; + } +-- +2.51.0 + diff --git a/queue-6.6/dma-buf-include-ioctl.h-in-uapi-header.patch b/queue-6.6/dma-buf-include-ioctl.h-in-uapi-header.patch new file mode 100644 index 0000000000..9c4b5d8d6c --- /dev/null +++ b/queue-6.6/dma-buf-include-ioctl.h-in-uapi-header.patch @@ -0,0 +1,44 @@ +From c1d50a77e6c98e5a3a8bd5ca9b5b25cc4b9ef982 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Mar 2026 16:23:09 -0800 +Subject: dma-buf: Include ioctl.h in UAPI header +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Isaac J. Manjarres + +[ Upstream commit a116bac87118903925108e57781bbfc7a7eea27b ] + +include/uapi/linux/dma-buf.h uses several macros from ioctl.h to define +its ioctl commands. However, it does not include ioctl.h itself. So, +if userspace source code tries to include the dma-buf.h file without +including ioctl.h, it can result in build failures. + +Therefore, include ioctl.h in the dma-buf UAPI header. + +Signed-off-by: Isaac J. Manjarres +Reviewed-by: T.J. Mercier +Reviewed-by: Christian König +Signed-off-by: Christian König +Link: https://lore.kernel.org/r/20260303002309.1401849-1-isaacmanjarres@google.com +Signed-off-by: Sasha Levin +--- + include/uapi/linux/dma-buf.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h +index 5a6fda66d9adf..e827c9d20c5d3 100644 +--- a/include/uapi/linux/dma-buf.h ++++ b/include/uapi/linux/dma-buf.h +@@ -20,6 +20,7 @@ + #ifndef _DMA_BUF_UAPI_H_ + #define _DMA_BUF_UAPI_H_ + ++#include + #include + + /** +-- +2.51.0 + diff --git a/queue-6.6/hid-apple-avoid-memory-leak-in-apple_report_fixup.patch b/queue-6.6/hid-apple-avoid-memory-leak-in-apple_report_fixup.patch new file mode 100644 index 0000000000..70490febb3 --- /dev/null +++ b/queue-6.6/hid-apple-avoid-memory-leak-in-apple_report_fixup.patch @@ -0,0 +1,45 @@ +From f62403e1e382b9f0824e004579b0624f2ec000e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Feb 2026 16:43:36 +0100 +Subject: HID: apple: avoid memory leak in apple_report_fixup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Günther Noack + +[ Upstream commit 239c15116d80f67d32f00acc34575f1a6b699613 ] + +The apple_report_fixup() function was returning a +newly kmemdup()-allocated buffer, but never freeing it. + +The caller of report_fixup() does not take ownership of the returned +pointer, but it *is* permitted to return a sub-portion of the input +rdesc, whose lifetime is managed by the caller. + +Assisted-by: Gemini-CLI:Google Gemini 3 +Signed-off-by: Günther Noack +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-apple.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 9dd5c698fefe0..6fae3427218fc 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -645,9 +645,7 @@ static __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc, + hid_info(hdev, + "fixing up Magic Keyboard battery report descriptor\n"); + *rsize = *rsize - 1; +- rdesc = kmemdup(rdesc + 1, *rsize, GFP_KERNEL); +- if (!rdesc) +- return NULL; ++ rdesc = rdesc + 1; + + rdesc[0] = 0x05; + rdesc[1] = 0x01; +-- +2.51.0 + diff --git a/queue-6.6/hid-asus-add-xg-mobile-2023-external-hardware-suppor.patch b/queue-6.6/hid-asus-add-xg-mobile-2023-external-hardware-suppor.patch new file mode 100644 index 0000000000..e00be926aa --- /dev/null +++ b/queue-6.6/hid-asus-add-xg-mobile-2023-external-hardware-suppor.patch @@ -0,0 +1,49 @@ +From 2fefc8184539c54015c8d7b9967a4fde4340da9e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 18:55:38 +0100 +Subject: HID: asus: add xg mobile 2023 external hardware support + +From: Denis Benato + +[ Upstream commit 377f8e788945d45b012ed9cfc35ca56c02e86cd8 ] + +XG mobile stations have the 0x5a endpoint and has to be initialized: +add them to hid-asus. + +Signed-off-by: Denis Benato +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-asus.c | 3 +++ + drivers/hid/hid-ids.h | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index 529b23b67ec4b..544b74eda284a 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -1298,6 +1298,9 @@ static const struct hid_device_id asus_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, + USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X), + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, ++ USB_DEVICE_ID_ASUSTEK_XGM_2023), ++ }, + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, + USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD), + QUIRK_ROG_CLAYMORE_II_KEYBOARD }, +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index a1910e12f7e05..2057546b26823 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -219,6 +219,7 @@ + #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X 0x1b4c + #define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b + #define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869 ++#define USB_DEVICE_ID_ASUSTEK_XGM_2023 0x1a9a + + #define USB_VENDOR_ID_ATEN 0x0557 + #define USB_DEVICE_ID_ATEN_UC100KM 0x2004 +-- +2.51.0 + diff --git a/queue-6.6/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch b/queue-6.6/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch new file mode 100644 index 0000000000..f4f0d7e48e --- /dev/null +++ b/queue-6.6/hid-asus-avoid-memory-leak-in-asus_report_fixup.patch @@ -0,0 +1,65 @@ +From 661dc8bdd8e727e36ccdfc4b696cfa984c4fa222 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Feb 2026 16:43:38 +0100 +Subject: HID: asus: avoid memory leak in asus_report_fixup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Günther Noack + +[ Upstream commit 2bad24c17742fc88973d6aea526ce1353f5334a3 ] + +The asus_report_fixup() function was returning a newly allocated +kmemdup()-allocated buffer, but never freeing it. Switch to +devm_kzalloc() to ensure the memory is managed and freed automatically +when the device is removed. + +The caller of report_fixup() does not take ownership of the returned +pointer, but it is permitted to return a pointer whose lifetime is at +least that of the input buffer. + +Also fix a harmless out-of-bounds read by copying only the original +descriptor size. + +Assisted-by: Gemini-CLI:Google Gemini 3 +Signed-off-by: Günther Noack +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-asus.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index d971e339b5eac..529b23b67ec4b 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -1200,14 +1200,21 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, + */ + if (*rsize == rsize_orig && + rdesc[offs] == 0x09 && rdesc[offs + 1] == 0x76) { +- *rsize = rsize_orig + 1; +- rdesc = kmemdup(rdesc, *rsize, GFP_KERNEL); +- if (!rdesc) +- return NULL; ++ __u8 *new_rdesc; ++ ++ new_rdesc = devm_kzalloc(&hdev->dev, rsize_orig + 1, ++ GFP_KERNEL); ++ if (!new_rdesc) ++ return rdesc; + + hid_info(hdev, "Fixing up %s keyb report descriptor\n", + drvdata->quirks & QUIRK_T100CHI ? + "T100CHI" : "T90CHI"); ++ ++ memcpy(new_rdesc, rdesc, rsize_orig); ++ *rsize = rsize_orig + 1; ++ rdesc = new_rdesc; ++ + memmove(rdesc + offs + 4, rdesc + offs + 2, 12); + rdesc[offs] = 0x19; + rdesc[offs + 1] = 0x00; +-- +2.51.0 + diff --git a/queue-6.6/hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch b/queue-6.6/hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch new file mode 100644 index 0000000000..0315e345f4 --- /dev/null +++ b/queue-6.6/hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch @@ -0,0 +1,45 @@ +From 6aa19efa4fbeac7c2ec26c59a6cff649e19ad12f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Feb 2026 16:43:37 +0100 +Subject: HID: magicmouse: avoid memory leak in magicmouse_report_fixup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Günther Noack + +[ Upstream commit 91e8c6e601bdc1ccdf886479b6513c01c7e51c2c ] + +The magicmouse_report_fixup() function was returning a +newly kmemdup()-allocated buffer, but never freeing it. + +The caller of report_fixup() does not take ownership of the returned +pointer, but it *is* permitted to return a sub-portion of the input +rdesc, whose lifetime is managed by the caller. + +Assisted-by: Gemini-CLI:Google Gemini 3 +Signed-off-by: Günther Noack +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-magicmouse.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index bb725dfcef196..d5df2745f3da4 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -967,9 +967,7 @@ static __u8 *magicmouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, + hid_info(hdev, + "fixing up magicmouse battery report descriptor\n"); + *rsize = *rsize - 1; +- rdesc = kmemdup(rdesc + 1, *rsize, GFP_KERNEL); +- if (!rdesc) +- return NULL; ++ rdesc = rdesc + 1; + + rdesc[0] = 0x05; + rdesc[1] = 0x01; +-- +2.51.0 + diff --git a/queue-6.6/hid-magicmouse-fix-battery-reporting-for-apple-magic.patch b/queue-6.6/hid-magicmouse-fix-battery-reporting-for-apple-magic.patch new file mode 100644 index 0000000000..fa5e0e3e62 --- /dev/null +++ b/queue-6.6/hid-magicmouse-fix-battery-reporting-for-apple-magic.patch @@ -0,0 +1,41 @@ +From 4e57f33109067013ad2c0198d5b2efa58702dbdc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Feb 2026 20:34:21 +0100 +Subject: HID: magicmouse: fix battery reporting for Apple Magic Trackpad 2 + +From: Julius Lehmann + +[ Upstream commit 5f3518d77419255f8b12bb23c8ec22acbeb6bc5b ] + +Battery reporting does not work for the Apple Magic Trackpad 2 if it is +connected via USB. The current hid descriptor fixup code checks for a +hid descriptor length of exactly 83 bytes. If the hid descriptor is +larger, which is the case for newer apple mice, the fixup is not +applied. + +This fix checks for hid descriptor sizes greater/equal 83 bytes which +applies the fixup for newer devices as well. + +Signed-off-by: Julius Lehmann +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-magicmouse.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 99d0dbf62af37..bb725dfcef196 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -963,7 +963,7 @@ static __u8 *magicmouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, + */ + if ((is_usb_magicmouse2(hdev->vendor, hdev->product) || + is_usb_magictrackpad2(hdev->vendor, hdev->product)) && +- *rsize == 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) { ++ *rsize >= 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) { + hid_info(hdev, + "fixing up magicmouse battery report descriptor\n"); + *rsize = *rsize - 1; +-- +2.51.0 + diff --git a/queue-6.6/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch b/queue-6.6/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch new file mode 100644 index 0000000000..53957aa09a --- /dev/null +++ b/queue-6.6/hid-mcp2221-cancel-last-i2c-command-on-read-error.patch @@ -0,0 +1,41 @@ +From 52f2f0cd372032eba54af7ab97e13086f82bcc11 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 17:32:58 +0100 +Subject: HID: mcp2221: cancel last I2C command on read error + +From: Romain Sioen + +[ Upstream commit e31b556c0ba21f20c298aa61181b96541140b7b9 ] + +When an I2C SMBus read operation fails, the MCP2221 internal state machine +may not reset correctly, causing subsequent transactions to fail. + +By adding a short delay and explicitly cancelling the last command, +we ensure the device is ready for the next operation. + +Fix an issue where i2cdetect was not able to detect all devices correctly +on the bus. + +Signed-off-by: Romain Sioen +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-mcp2221.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c +index d2d413c829f44..99af0b541316b 100644 +--- a/drivers/hid/hid-mcp2221.c ++++ b/drivers/hid/hid-mcp2221.c +@@ -337,6 +337,8 @@ static int mcp_i2c_smbus_read(struct mcp2221 *mcp, + usleep_range(90, 100); + retries++; + } else { ++ usleep_range(980, 1000); ++ mcp_cancel_last_cmd(mcp); + return ret; + } + } else { +-- +2.51.0 + diff --git a/queue-6.6/hwmon-axi-fan-control-make-use-of-dev_err_probe.patch b/queue-6.6/hwmon-axi-fan-control-make-use-of-dev_err_probe.patch new file mode 100644 index 0000000000..3d72172c18 --- /dev/null +++ b/queue-6.6/hwmon-axi-fan-control-make-use-of-dev_err_probe.patch @@ -0,0 +1,91 @@ +From 8c6778a693cf59d57b43b62ae0755c3fed9ce813 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Feb 2024 15:36:45 +0100 +Subject: hwmon: (axi-fan-control) Make use of dev_err_probe() + +From: Nuno Sa + +[ Upstream commit ec823656c1e0e5f49e92ed86cee9fb26585da18e ] + +Use dev_err_probe() to slightly simplify printing errors during probe. +No functional changes intended. + +Signed-off-by: Nuno Sa +Link: https://lore.kernel.org/r/20240214-axi-fan-control-no-of-v1-3-43ca656fe2e3@analog.com +Signed-off-by: Guenter Roeck +Stable-dep-of: 813bbc4d33d2 ("hwmon: axi-fan: don't use driver_override as IRQ name") +Signed-off-by: Sasha Levin +--- + drivers/hwmon/axi-fan-control.c | 40 +++++++++++++++------------------ + 1 file changed, 18 insertions(+), 22 deletions(-) + +diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c +index 8dfe3b6c5a177..df99cad16b208 100644 +--- a/drivers/hwmon/axi-fan-control.c ++++ b/drivers/hwmon/axi-fan-control.c +@@ -466,10 +466,9 @@ static int axi_fan_control_probe(struct platform_device *pdev) + return PTR_ERR(ctl->base); + + clk = devm_clk_get_enabled(&pdev->dev, NULL); +- if (IS_ERR(clk)) { +- dev_err(&pdev->dev, "clk_get failed with %ld\n", PTR_ERR(clk)); +- return PTR_ERR(clk); +- } ++ if (IS_ERR(clk)) ++ return dev_err_probe(&pdev->dev, PTR_ERR(clk), ++ "clk_get failed\n"); + + ctl->clk_rate = clk_get_rate(clk); + if (!ctl->clk_rate) +@@ -477,22 +476,20 @@ static int axi_fan_control_probe(struct platform_device *pdev) + + version = axi_ioread(ADI_AXI_REG_VERSION, ctl); + if (ADI_AXI_PCORE_VER_MAJOR(version) != +- ADI_AXI_PCORE_VER_MAJOR((*id))) { +- dev_err(&pdev->dev, "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", +- ADI_AXI_PCORE_VER_MAJOR(*id), +- ADI_AXI_PCORE_VER_MINOR(*id), +- ADI_AXI_PCORE_VER_PATCH(*id), +- ADI_AXI_PCORE_VER_MAJOR(version), +- ADI_AXI_PCORE_VER_MINOR(version), +- ADI_AXI_PCORE_VER_PATCH(version)); +- return -ENODEV; +- } ++ ADI_AXI_PCORE_VER_MAJOR((*id))) ++ return dev_err_probe(&pdev->dev, -ENODEV, ++ "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", ++ ADI_AXI_PCORE_VER_MAJOR(*id), ++ ADI_AXI_PCORE_VER_MINOR(*id), ++ ADI_AXI_PCORE_VER_PATCH(*id), ++ ADI_AXI_PCORE_VER_MAJOR(version), ++ ADI_AXI_PCORE_VER_MINOR(version), ++ ADI_AXI_PCORE_VER_PATCH(version)); + + ret = axi_fan_control_init(ctl, &pdev->dev); +- if (ret) { +- dev_err(&pdev->dev, "Failed to initialize device\n"); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(&pdev->dev, ret, ++ "Failed to initialize device\n"); + + ctl->hdev = devm_hwmon_device_register_with_info(&pdev->dev, + name, +@@ -511,10 +508,9 @@ static int axi_fan_control_probe(struct platform_device *pdev) + axi_fan_control_irq_handler, + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, + pdev->driver_override, ctl); +- if (ret) { +- dev_err(&pdev->dev, "failed to request an irq, %d", ret); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(&pdev->dev, ret, ++ "failed to request an irq\n"); + + return 0; + } +-- +2.51.0 + diff --git a/queue-6.6/hwmon-axi-fan-control-use-device-firmware-agnostic-a.patch b/queue-6.6/hwmon-axi-fan-control-use-device-firmware-agnostic-a.patch new file mode 100644 index 0000000000..82eedde5eb --- /dev/null +++ b/queue-6.6/hwmon-axi-fan-control-use-device-firmware-agnostic-a.patch @@ -0,0 +1,126 @@ +From 04def3bdbcc705bdd5e72a82571a44387db789d4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Feb 2024 15:36:43 +0100 +Subject: hwmon: (axi-fan-control) Use device firmware agnostic API + +From: Nuno Sa + +[ Upstream commit 1b5239f70fcd2d7fe86f0f5473006c2896db07a8 ] + +Don't directly use OF and use device property APIs. In addition, this +makes the probe() code neater and also allow us to move the +of_device_id table to it's natural place. + +While at it, make sure to explicitly include mod_devicetable.h for the +of_device_id table. + +Signed-off-by: Nuno Sa +Link: https://lore.kernel.org/r/20240214-axi-fan-control-no-of-v1-1-43ca656fe2e3@analog.com +Signed-off-by: Guenter Roeck +Stable-dep-of: 813bbc4d33d2 ("hwmon: axi-fan: don't use driver_override as IRQ name") +Signed-off-by: Sasha Levin +--- + drivers/hwmon/axi-fan-control.c | 39 +++++++++++++++++---------------- + 1 file changed, 20 insertions(+), 19 deletions(-) + +diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c +index 19b9bf3d75ef9..8dfe3b6c5a177 100644 +--- a/drivers/hwmon/axi-fan-control.c ++++ b/drivers/hwmon/axi-fan-control.c +@@ -13,8 +13,9 @@ + #include + #include + #include +-#include ++#include + #include ++#include + + /* register map */ + #define ADI_REG_RSTN 0x0080 +@@ -368,12 +369,12 @@ static irqreturn_t axi_fan_control_irq_handler(int irq, void *data) + } + + static int axi_fan_control_init(struct axi_fan_control_data *ctl, +- const struct device_node *np) ++ const struct device *dev) + { + int ret; + + /* get fan pulses per revolution */ +- ret = of_property_read_u32(np, "pulses-per-revolution", &ctl->ppr); ++ ret = device_property_read_u32(dev, "pulses-per-revolution", &ctl->ppr); + if (ret) + return ret; + +@@ -443,25 +444,16 @@ static struct attribute *axi_fan_control_attrs[] = { + }; + ATTRIBUTE_GROUPS(axi_fan_control); + +-static const u32 version_1_0_0 = ADI_AXI_PCORE_VER(1, 0, 'a'); +- +-static const struct of_device_id axi_fan_control_of_match[] = { +- { .compatible = "adi,axi-fan-control-1.00.a", +- .data = (void *)&version_1_0_0}, +- {}, +-}; +-MODULE_DEVICE_TABLE(of, axi_fan_control_of_match); +- + static int axi_fan_control_probe(struct platform_device *pdev) + { + struct axi_fan_control_data *ctl; + struct clk *clk; +- const struct of_device_id *id; ++ const unsigned int *id; + const char *name = "axi_fan_control"; + u32 version; + int ret; + +- id = of_match_node(axi_fan_control_of_match, pdev->dev.of_node); ++ id = device_get_match_data(&pdev->dev); + if (!id) + return -EINVAL; + +@@ -485,18 +477,18 @@ static int axi_fan_control_probe(struct platform_device *pdev) + + version = axi_ioread(ADI_AXI_REG_VERSION, ctl); + if (ADI_AXI_PCORE_VER_MAJOR(version) != +- ADI_AXI_PCORE_VER_MAJOR((*(u32 *)id->data))) { ++ ADI_AXI_PCORE_VER_MAJOR((*id))) { + dev_err(&pdev->dev, "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", +- ADI_AXI_PCORE_VER_MAJOR((*(u32 *)id->data)), +- ADI_AXI_PCORE_VER_MINOR((*(u32 *)id->data)), +- ADI_AXI_PCORE_VER_PATCH((*(u32 *)id->data)), ++ ADI_AXI_PCORE_VER_MAJOR(*id), ++ ADI_AXI_PCORE_VER_MINOR(*id), ++ ADI_AXI_PCORE_VER_PATCH(*id), + ADI_AXI_PCORE_VER_MAJOR(version), + ADI_AXI_PCORE_VER_MINOR(version), + ADI_AXI_PCORE_VER_PATCH(version)); + return -ENODEV; + } + +- ret = axi_fan_control_init(ctl, pdev->dev.of_node); ++ ret = axi_fan_control_init(ctl, &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "Failed to initialize device\n"); + return ret; +@@ -527,6 +519,15 @@ static int axi_fan_control_probe(struct platform_device *pdev) + return 0; + } + ++static const u32 version_1_0_0 = ADI_AXI_PCORE_VER(1, 0, 'a'); ++ ++static const struct of_device_id axi_fan_control_of_match[] = { ++ { .compatible = "adi,axi-fan-control-1.00.a", ++ .data = (void *)&version_1_0_0}, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, axi_fan_control_of_match); ++ + static struct platform_driver axi_fan_control_driver = { + .driver = { + .name = "axi_fan_control_driver", +-- +2.51.0 + diff --git a/queue-6.6/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch b/queue-6.6/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch new file mode 100644 index 0000000000..4f90de2ae9 --- /dev/null +++ b/queue-6.6/hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch @@ -0,0 +1,43 @@ +From ebcb712b5e80fd10815adb8928e3534d87ce3bf6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Mar 2026 12:53:20 +0100 +Subject: hwmon: axi-fan: don't use driver_override as IRQ name +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Danilo Krummrich + +[ Upstream commit 813bbc4d33d2ca5b0da63e70ae13b60874f20d37 ] + +Do not use driver_override as IRQ name, as it is not guaranteed to point +to a valid string; use NULL instead (which makes the devm IRQ helpers +use dev_name()). + +Fixes: 8412b410fa5e ("hwmon: Support ADI Fan Control IP") +Reviewed-by: Nuno Sá +Acked-by: Guenter Roeck +Reviewed-by: Greg Kroah-Hartman +Link: https://patch.msgid.link/20260303115720.48783-4-dakr@kernel.org +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + drivers/hwmon/axi-fan-control.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c +index df99cad16b208..641cc06c77aff 100644 +--- a/drivers/hwmon/axi-fan-control.c ++++ b/drivers/hwmon/axi-fan-control.c +@@ -507,7 +507,7 @@ static int axi_fan_control_probe(struct platform_device *pdev) + ret = devm_request_threaded_irq(&pdev->dev, ctl->irq, NULL, + axi_fan_control_irq_handler, + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, +- pdev->driver_override, ctl); ++ NULL, ctl); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "failed to request an irq\n"); +-- +2.51.0 + diff --git a/queue-6.6/module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch b/queue-6.6/module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch new file mode 100644 index 0000000000..5b5cad02db --- /dev/null +++ b/queue-6.6/module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch @@ -0,0 +1,80 @@ +From 9c1ce4ad9b498be1c36dcf2a8ef988fa330f4366 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Dec 2025 10:32:08 -0800 +Subject: module: Fix kernel panic when a symbol st_shndx is out of bounds + +From: Ihor Solodrai + +[ Upstream commit f9d69d5e7bde2295eb7488a56f094ac8f5383b92 ] + +The module loader doesn't check for bounds of the ELF section index in +simplify_symbols(): + + for (i = 1; i < symsec->sh_size / sizeof(Elf_Sym); i++) { + const char *name = info->strtab + sym[i].st_name; + + switch (sym[i].st_shndx) { + case SHN_COMMON: + + [...] + + default: + /* Divert to percpu allocation if a percpu var. */ + if (sym[i].st_shndx == info->index.pcpu) + secbase = (unsigned long)mod_percpu(mod); + else + /** HERE --> **/ secbase = info->sechdrs[sym[i].st_shndx].sh_addr; + sym[i].st_value += secbase; + break; + } + } + +A symbol with an out-of-bounds st_shndx value, for example 0xffff +(known as SHN_XINDEX or SHN_HIRESERVE), may cause a kernel panic: + + BUG: unable to handle page fault for address: ... + RIP: 0010:simplify_symbols+0x2b2/0x480 + ... + Kernel panic - not syncing: Fatal exception + +This can happen when module ELF is legitimately using SHN_XINDEX or +when it is corrupted. + +Add a bounds check in simplify_symbols() to validate that st_shndx is +within the valid range before using it. + +This issue was discovered due to a bug in llvm-objcopy, see relevant +discussion for details [1]. + +[1] https://lore.kernel.org/linux-modules/20251224005752.201911-1-ihor.solodrai@linux.dev/ + +Signed-off-by: Ihor Solodrai +Reviewed-by: Daniel Gomez +Reviewed-by: Petr Pavlu +Signed-off-by: Sami Tolvanen +Signed-off-by: Sasha Levin +--- + kernel/module/main.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/kernel/module/main.c b/kernel/module/main.c +index 627680e568fcc..76d90c20de674 100644 +--- a/kernel/module/main.c ++++ b/kernel/module/main.c +@@ -1424,6 +1424,13 @@ static int simplify_symbols(struct module *mod, const struct load_info *info) + break; + + default: ++ if (sym[i].st_shndx >= info->hdr->e_shnum) { ++ pr_err("%s: Symbol %s has an invalid section index %u (max %u)\n", ++ mod->name, name, sym[i].st_shndx, info->hdr->e_shnum - 1); ++ ret = -ENOEXEC; ++ break; ++ } ++ + /* Divert to percpu allocation if a percpu var. */ + if (sym[i].st_shndx == info->index.pcpu) + secbase = (unsigned long)mod_percpu(mod); +-- +2.51.0 + diff --git a/queue-6.6/net-usb-r8152-add-trendnet-tuc-et2g.patch b/queue-6.6/net-usb-r8152-add-trendnet-tuc-et2g.patch new file mode 100644 index 0000000000..dd42007c58 --- /dev/null +++ b/queue-6.6/net-usb-r8152-add-trendnet-tuc-et2g.patch @@ -0,0 +1,48 @@ +From 009ff7e2ec8cd3d4f961d10e45b085dfe5a52884 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Feb 2026 20:54:09 +0100 +Subject: net: usb: r8152: add TRENDnet TUC-ET2G + +From: Valentin Spreckels + +[ Upstream commit 15fba71533bcdfaa8eeba69a5a5a2927afdf664a ] + +The TRENDnet TUC-ET2G is a RTL8156 based usb ethernet adapter. Add its +vendor and product IDs. + +Signed-off-by: Valentin Spreckels +Link: https://patch.msgid.link/20260226195409.7891-2-valentin@spreckels.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/usb/r8152.c | 1 + + include/linux/usb/r8152.h | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c +index a2e3f9583def7..91cf24fb5531f 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -10036,6 +10036,7 @@ static const struct usb_device_id rtl8152_table[] = { + { USB_DEVICE(VENDOR_ID_DLINK, 0xb301) }, + { USB_DEVICE(VENDOR_ID_DELL, 0xb097) }, + { USB_DEVICE(VENDOR_ID_ASUS, 0x1976) }, ++ { USB_DEVICE(VENDOR_ID_TRENDNET, 0xe02b) }, + {} + }; + +diff --git a/include/linux/usb/r8152.h b/include/linux/usb/r8152.h +index 2ca60828f28bb..1502b2a355f98 100644 +--- a/include/linux/usb/r8152.h ++++ b/include/linux/usb/r8152.h +@@ -32,6 +32,7 @@ + #define VENDOR_ID_DLINK 0x2001 + #define VENDOR_ID_DELL 0x413c + #define VENDOR_ID_ASUS 0x0b05 ++#define VENDOR_ID_TRENDNET 0x20f4 + + #if IS_REACHABLE(CONFIG_USB_RTL8152) + extern u8 rtl8152_get_version(struct usb_interface *intf); +-- +2.51.0 + diff --git a/queue-6.6/nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch b/queue-6.6/nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch new file mode 100644 index 0000000000..a2b0c23d04 --- /dev/null +++ b/queue-6.6/nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch @@ -0,0 +1,40 @@ +From dc82a5d56afde9b3545b0571a1fe870caa44358e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 31 Jan 2026 19:08:40 -0800 +Subject: nvme-fabrics: use kfree_sensitive() for DHCHAP secrets + +From: Daniel Hodges + +[ Upstream commit 0a1fc2f301529ac75aec0ce80d5ab9d9e4dc4b16 ] + +The DHCHAP secrets (dhchap_secret and dhchap_ctrl_secret) contain +authentication key material for NVMe-oF. Use kfree_sensitive() instead +of kfree() in nvmf_free_options() to ensure secrets are zeroed before +the memory is freed, preventing recovery from freed pages. + +Reviewed-by: Christoph Hellwig +Signed-off-by: Daniel Hodges +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/fabrics.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c +index 5963e8b695ffc..cf6fb2d51886d 100644 +--- a/drivers/nvme/host/fabrics.c ++++ b/drivers/nvme/host/fabrics.c +@@ -1179,8 +1179,8 @@ void nvmf_free_options(struct nvmf_ctrl_options *opts) + kfree(opts->subsysnqn); + kfree(opts->host_traddr); + kfree(opts->host_iface); +- kfree(opts->dhchap_secret); +- kfree(opts->dhchap_ctrl_secret); ++ kfree_sensitive(opts->dhchap_secret); ++ kfree_sensitive(opts->dhchap_ctrl_secret); + kfree(opts); + } + EXPORT_SYMBOL_GPL(nvmf_free_options); +-- +2.51.0 + diff --git a/queue-6.6/nvme-pci-cap-queue-creation-to-used-queues.patch b/queue-6.6/nvme-pci-cap-queue-creation-to-used-queues.patch new file mode 100644 index 0000000000..57964020c4 --- /dev/null +++ b/queue-6.6/nvme-pci-cap-queue-creation-to-used-queues.patch @@ -0,0 +1,45 @@ +From 8604bb5f0ffd216039ca6fd0e1f0bdb56a83c6c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 11:00:12 -0800 +Subject: nvme-pci: cap queue creation to used queues + +From: Keith Busch + +[ Upstream commit 4735b510a00fb2d4ac9e8d21a8c9552cb281f585 ] + +If the user reduces the special queue count at runtime and resets the +controller, we need to reduce the number of queues and interrupts +requested accordingly rather than start with the pre-allocated queue +count. + +Tested-by: Kanchan Joshi +Reviewed-by: Kanchan Joshi +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 03a2ca3edb9c3..820e211feded2 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2355,7 +2355,13 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) + dev->nr_write_queues = write_queues; + dev->nr_poll_queues = poll_queues; + +- nr_io_queues = dev->nr_allocated_queues - 1; ++ /* ++ * The initial number of allocated queue slots may be too large if the ++ * user reduced the special queue parameters. Cap the value to the ++ * number we need for this round. ++ */ ++ nr_io_queues = min(nvme_max_io_queues(dev), ++ dev->nr_allocated_queues - 1); + result = nvme_set_queue_count(&dev->ctrl, &nr_io_queues); + if (result < 0) + return result; +-- +2.51.0 + diff --git a/queue-6.6/nvme-pci-ensure-we-re-polling-a-polled-queue.patch b/queue-6.6/nvme-pci-ensure-we-re-polling-a-polled-queue.patch new file mode 100644 index 0000000000..6dcbfc1c37 --- /dev/null +++ b/queue-6.6/nvme-pci-ensure-we-re-polling-a-polled-queue.patch @@ -0,0 +1,39 @@ +From fb0a1330f5106e5c6d5d00faed3838748367a972 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 09:26:54 -0800 +Subject: nvme-pci: ensure we're polling a polled queue + +From: Keith Busch + +[ Upstream commit 166e31d7dbf6aa44829b98aa446bda5c9580f12a ] + +A user can change the polled queue count at run time. There's a brief +window during a reset where a hipri task may try to poll that queue +before the block layer has updated the queue maps, which would race with +the now interrupt driven queue and may cause double completions. + +Reviewed-by: Christoph Hellwig +Reviewed-by: Kanchan Joshi +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 820e211feded2..6f78577fb70da 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1120,7 +1120,8 @@ static int nvme_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob) + struct nvme_queue *nvmeq = hctx->driver_data; + bool found; + +- if (!nvme_cqe_pending(nvmeq)) ++ if (!test_bit(NVMEQ_POLLED, &nvmeq->flags) || ++ !nvme_cqe_pending(nvmeq)) + return 0; + + spin_lock(&nvmeq->cq_poll_lock); +-- +2.51.0 + diff --git a/queue-6.6/objtool-handle-clang-rsp-musical-chairs.patch b/queue-6.6/objtool-handle-clang-rsp-musical-chairs.patch new file mode 100644 index 0000000000..fb04b4ee6b --- /dev/null +++ b/queue-6.6/objtool-handle-clang-rsp-musical-chairs.patch @@ -0,0 +1,136 @@ +From 7f19c5f14c900b56d55e587171f179f8170a32cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 09:35:06 -0800 +Subject: objtool: Handle Clang RSP musical chairs + +From: Josh Poimboeuf + +[ Upstream commit 7fdaa640c810cb42090a182c33f905bcc47a616a ] + +For no apparent reason (possibly related to CONFIG_KMSAN), Clang can +randomly pass the value of RSP to other registers and then back again to +RSP. Handle that accordingly. + +Fixes the following warnings: + + drivers/input/misc/uinput.o: warning: objtool: uinput_str_to_user+0x165: undefined stack state + drivers/input/misc/uinput.o: warning: objtool: uinput_str_to_user+0x165: unknown CFA base reg -1 + +Reported-by: Arnd Bergmann +Closes: https://lore.kernel.org/90956545-2066-46e3-b547-10c884582eb0@app.fastmail.com +Link: https://patch.msgid.link/240e6a172cc73292499334a3724d02ccb3247fc7.1772818491.git.jpoimboe@kernel.org +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/arch/x86/decode.c | 62 ++++++++++++--------------------- + tools/objtool/check.c | 14 ++++++++ + 2 files changed, 37 insertions(+), 39 deletions(-) + +diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c +index c0f25d00181ec..40a5aa02bd831 100644 +--- a/tools/objtool/arch/x86/decode.c ++++ b/tools/objtool/arch/x86/decode.c +@@ -325,52 +325,36 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec + if (!rex_w) + break; + +- if (modrm_reg == CFI_SP) { +- +- if (mod_is_reg()) { +- /* mov %rsp, reg */ +- ADD_OP(op) { +- op->src.type = OP_SRC_REG; +- op->src.reg = CFI_SP; +- op->dest.type = OP_DEST_REG; +- op->dest.reg = modrm_rm; +- } +- break; +- +- } else { +- /* skip RIP relative displacement */ +- if (is_RIP()) +- break; +- +- /* skip nontrivial SIB */ +- if (have_SIB()) { +- modrm_rm = sib_base; +- if (sib_index != CFI_SP) +- break; +- } +- +- /* mov %rsp, disp(%reg) */ +- ADD_OP(op) { +- op->src.type = OP_SRC_REG; +- op->src.reg = CFI_SP; +- op->dest.type = OP_DEST_REG_INDIRECT; +- op->dest.reg = modrm_rm; +- op->dest.offset = ins.displacement.value; +- } +- break; ++ if (mod_is_reg()) { ++ /* mov reg, reg */ ++ ADD_OP(op) { ++ op->src.type = OP_SRC_REG; ++ op->src.reg = modrm_reg; ++ op->dest.type = OP_DEST_REG; ++ op->dest.reg = modrm_rm; + } +- + break; + } + +- if (rm_is_reg(CFI_SP)) { ++ /* skip RIP relative displacement */ ++ if (is_RIP()) ++ break; + +- /* mov reg, %rsp */ ++ /* skip nontrivial SIB */ ++ if (have_SIB()) { ++ modrm_rm = sib_base; ++ if (sib_index != CFI_SP) ++ break; ++ } ++ ++ /* mov %rsp, disp(%reg) */ ++ if (modrm_reg == CFI_SP) { + ADD_OP(op) { + op->src.type = OP_SRC_REG; +- op->src.reg = modrm_reg; +- op->dest.type = OP_DEST_REG; +- op->dest.reg = CFI_SP; ++ op->src.reg = CFI_SP; ++ op->dest.type = OP_DEST_REG_INDIRECT; ++ op->dest.reg = modrm_rm; ++ op->dest.offset = ins.displacement.value; + } + break; + } +diff --git a/tools/objtool/check.c b/tools/objtool/check.c +index c021798ba8372..6497c80fd6f77 100644 +--- a/tools/objtool/check.c ++++ b/tools/objtool/check.c +@@ -2969,6 +2969,20 @@ static int update_cfi_state(struct instruction *insn, + cfi->stack_size += 8; + } + ++ else if (cfi->vals[op->src.reg].base == CFI_CFA) { ++ /* ++ * Clang RSP musical chairs: ++ * ++ * mov %rsp, %rdx [handled above] ++ * ... ++ * mov %rdx, %rbx [handled here] ++ * ... ++ * mov %rbx, %rsp [handled above] ++ */ ++ cfi->vals[op->dest.reg].base = CFI_CFA; ++ cfi->vals[op->dest.reg].offset = cfi->vals[op->src.reg].offset; ++ } ++ + + break; + +-- +2.51.0 + diff --git a/queue-6.6/perf-extract-a-few-helpers.patch b/queue-6.6/perf-extract-a-few-helpers.patch new file mode 100644 index 0000000000..8ca15e4b53 --- /dev/null +++ b/queue-6.6/perf-extract-a-few-helpers.patch @@ -0,0 +1,103 @@ +From e51e9cd2d673f644f0ff60fd5618c051dbccc6e5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Aug 2024 13:29:26 +0200 +Subject: perf: Extract a few helpers + +From: Peter Zijlstra + +[ Upstream commit 9a32bd9901fe5b1dcf544389dbf04f3b0a2fbab4 ] + +The context time update code is repeated verbatim a few times. + +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Kan Liang +Reviewed-by: Namhyung Kim +Link: https://lore.kernel.org/r/20240807115550.031212518@infradead.org +Stable-dep-of: 4b9ce6719606 ("perf: Make sure to use pmu_ctx->pmu for groups") +Signed-off-by: Sasha Levin +--- + kernel/events/core.c | 39 ++++++++++++++++++++++----------------- + 1 file changed, 22 insertions(+), 17 deletions(-) + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 652baf91c629e..53cb9ee145746 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -2349,6 +2349,24 @@ group_sched_out(struct perf_event *group_event, struct perf_event_context *ctx) + event_sched_out(event, ctx); + } + ++static inline void ++ctx_time_update(struct perf_cpu_context *cpuctx, struct perf_event_context *ctx) ++{ ++ if (ctx->is_active & EVENT_TIME) { ++ update_context_time(ctx); ++ update_cgrp_time_from_cpuctx(cpuctx, false); ++ } ++} ++ ++static inline void ++ctx_time_update_event(struct perf_event_context *ctx, struct perf_event *event) ++{ ++ if (ctx->is_active & EVENT_TIME) { ++ update_context_time(ctx); ++ update_cgrp_time_from_event(event); ++ } ++} ++ + #define DETACH_GROUP 0x01UL + #define DETACH_CHILD 0x02UL + #define DETACH_DEAD 0x04UL +@@ -2370,10 +2388,7 @@ __perf_remove_from_context(struct perf_event *event, + enum perf_event_state state = PERF_EVENT_STATE_OFF; + unsigned long flags = (unsigned long)info; + +- if (ctx->is_active & EVENT_TIME) { +- update_context_time(ctx); +- update_cgrp_time_from_cpuctx(cpuctx, false); +- } ++ ctx_time_update(cpuctx, ctx); + + /* + * Ensure event_sched_out() switches to OFF, at the very least +@@ -2470,12 +2485,8 @@ static void __perf_event_disable(struct perf_event *event, + if (event->state < PERF_EVENT_STATE_INACTIVE) + return; + +- if (ctx->is_active & EVENT_TIME) { +- update_context_time(ctx); +- update_cgrp_time_from_event(event); +- } +- + perf_pmu_disable(event->pmu_ctx->pmu); ++ ctx_time_update_event(ctx, event); + + /* + * When disabling a group leader, the whole group becomes ineligible +@@ -4534,10 +4545,7 @@ static void __perf_event_read(void *info) + return; + + raw_spin_lock(&ctx->lock); +- if (ctx->is_active & EVENT_TIME) { +- update_context_time(ctx); +- update_cgrp_time_from_event(event); +- } ++ ctx_time_update_event(ctx, event); + + perf_event_update_time(event); + if (data->group) +@@ -4718,10 +4726,7 @@ static int perf_event_read(struct perf_event *event, bool group) + * May read while context is not active (e.g., thread is + * blocked), in that case we cannot update context time + */ +- if (ctx->is_active & EVENT_TIME) { +- update_context_time(ctx); +- update_cgrp_time_from_event(event); +- } ++ ctx_time_update_event(ctx, event); + + perf_event_update_time(event); + if (group) +-- +2.51.0 + diff --git a/queue-6.6/perf-make-sure-to-use-pmu_ctx-pmu-for-groups.patch b/queue-6.6/perf-make-sure-to-use-pmu_ctx-pmu-for-groups.patch new file mode 100644 index 0000000000..fc6cdc13f6 --- /dev/null +++ b/queue-6.6/perf-make-sure-to-use-pmu_ctx-pmu-for-groups.patch @@ -0,0 +1,99 @@ +From c52388622ecce1e330c288182dd5229645002097 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Mar 2026 13:55:46 +0100 +Subject: perf: Make sure to use pmu_ctx->pmu for groups + +From: Peter Zijlstra + +[ Upstream commit 4b9ce671960627b2505b3f64742544ae9801df97 ] + +Oliver reported that x86_pmu_del() ended up doing an out-of-bound memory access +when group_sched_in() fails and needs to roll back. + +This *should* be handled by the transaction callbacks, but he found that when +the group leader is a software event, the transaction handlers of the wrong PMU +are used. Despite the move_group case in perf_event_open() and group_sched_in() +using pmu_ctx->pmu. + +Turns out, inherit uses event->pmu to clone the events, effectively undoing the +move_group case for all inherited contexts. Fix this by also making inherit use +pmu_ctx->pmu, ensuring all inherited counters end up in the same pmu context. + +Similarly, __perf_event_read() should use equally use pmu_ctx->pmu for the +group case. + +Fixes: bd2756811766 ("perf: Rewrite core context handling") +Reported-by: Oliver Rosenberg +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Ian Rogers +Link: https://patch.msgid.link/20260309133713.GB606826@noisy.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + kernel/events/core.c | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 53cb9ee145746..eba5eb6fcb876 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -4532,7 +4532,7 @@ static void __perf_event_read(void *info) + struct perf_event *sub, *event = data->event; + struct perf_event_context *ctx = event->ctx; + struct perf_cpu_context *cpuctx = this_cpu_ptr(&perf_cpu_context); +- struct pmu *pmu = event->pmu; ++ struct pmu *pmu; + + /* + * If this is a task context, we need to check whether it is +@@ -4544,7 +4544,7 @@ static void __perf_event_read(void *info) + if (ctx->task && cpuctx->task_ctx != ctx) + return; + +- raw_spin_lock(&ctx->lock); ++ guard(raw_spinlock)(&ctx->lock); + ctx_time_update_event(ctx, event); + + perf_event_update_time(event); +@@ -4552,25 +4552,22 @@ static void __perf_event_read(void *info) + perf_event_update_sibling_time(event); + + if (event->state != PERF_EVENT_STATE_ACTIVE) +- goto unlock; ++ return; + + if (!data->group) { +- pmu->read(event); ++ perf_pmu_read(event); + data->ret = 0; +- goto unlock; ++ return; + } + ++ pmu = event->pmu_ctx->pmu; + pmu->start_txn(pmu, PERF_PMU_TXN_READ); + +- pmu->read(event); +- ++ perf_pmu_read(event); + for_each_sibling_event(sub, event) + perf_pmu_read(sub); + + data->ret = pmu->commit_txn(pmu); +- +-unlock: +- raw_spin_unlock(&ctx->lock); + } + + static inline u64 perf_event_count(struct perf_event *event) +@@ -13541,7 +13538,7 @@ inherit_event(struct perf_event *parent_event, + get_ctx(child_ctx); + child_event->ctx = child_ctx; + +- pmu_ctx = find_get_pmu_context(child_event->pmu, child_ctx, child_event); ++ pmu_ctx = find_get_pmu_context(parent_event->pmu_ctx->pmu, child_ctx, child_event); + if (IS_ERR(pmu_ctx)) { + free_event(child_event); + return ERR_CAST(pmu_ctx); +-- +2.51.0 + diff --git a/queue-6.6/platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch b/queue-6.6/platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch new file mode 100644 index 0000000000..1bbe7b94e4 --- /dev/null +++ b/queue-6.6/platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch @@ -0,0 +1,51 @@ +From 9bb673468924bcf35101f9fdfb24d4119eb34744 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 23:46:27 -0500 +Subject: platform/x86: intel-hid: Add Dell 14 Plus 2-in-1 to + dmi_vgbs_allow_list +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Peter Metz + +[ Upstream commit 6b3fa0615cd8432148581de62a52f83847af3d70 ] + +The Dell 14 Plus 2-in-1 (model DB04250) requires the VGBS allow list +entry to correctly enable the tablet mode switch. Without this, the +chassis state is not reported, and the hinge rotation only emits +unknown scancodes. + +Verified on Dell 14 Plus 2-in-1 DB04250. + +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221090 +Signed-off-by: Peter Metz +Reviewed-by: Hans de Goede +Link: https://patch.msgid.link/20260213044627.203638-1-peter.metz@unarin.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/intel/hid.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c +index ac88119a73b84..7937ad20c2941 100644 +--- a/drivers/platform/x86/intel/hid.c ++++ b/drivers/platform/x86/intel/hid.c +@@ -175,6 +175,12 @@ static const struct dmi_system_id dmi_vgbs_allow_list[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Dell Pro Rugged 12 Tablet RA02260"), + }, + }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Dell 14 Plus 2-in-1 DB04250"), ++ }, ++ }, + { } + }; + +-- +2.51.0 + diff --git a/queue-6.6/platform-x86-intel-hid-enable-5-button-array-on-thin.patch b/queue-6.6/platform-x86-intel-hid-enable-5-button-array-on-thin.patch new file mode 100644 index 0000000000..ba5d8ba358 --- /dev/null +++ b/queue-6.6/platform-x86-intel-hid-enable-5-button-array-on-thin.patch @@ -0,0 +1,52 @@ +From 9ceada966a24a8b07dbaabd9efc75f2778288b88 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 09:56:25 +0100 +Subject: platform/x86: intel-hid: Enable 5-button array on ThinkPad X1 Fold 16 + Gen 1 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Leif Skunberg + +[ Upstream commit b38d478dad79e61e8a65931021bdfd7a71741212 ] + +The Lenovo ThinkPad X1 Fold 16 Gen 1 has physical volume up/down +buttons that are handled through the intel-hid 5-button array +interface. The firmware does not advertise 5-button array support via +HEBC, so the driver relies on a DMI allowlist to enable it. + +Add the ThinkPad X1 Fold 16 Gen 1 to the button_array_table so the +volume buttons work out of the box. + +Signed-off-by: Leif Skunberg +Reviewed-by: Hans de Goede +Link: https://patch.msgid.link/20260210085625.34380-1-diamondback@cohunt.app +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/intel/hid.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c +index 7937ad20c2941..79390e9e888a7 100644 +--- a/drivers/platform/x86/intel/hid.c ++++ b/drivers/platform/x86/intel/hid.c +@@ -121,6 +121,13 @@ static const struct dmi_system_id button_array_table[] = { + DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Tablet Gen 2"), + }, + }, ++ { ++ .ident = "Lenovo ThinkPad X1 Fold 16 Gen 1", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Fold 16 Gen 1"), ++ }, ++ }, + { + .ident = "Microsoft Surface Go 3", + .matches = { +-- +2.51.0 + diff --git a/queue-6.6/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch b/queue-6.6/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch new file mode 100644 index 0000000000..b8a130ab44 --- /dev/null +++ b/queue-6.6/platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch @@ -0,0 +1,71 @@ +From 6cfa9571d2b56c4f901046639f406124aa5b8fdd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 14:23:46 +0100 +Subject: platform/x86: touchscreen_dmi: Add quirk for y-inverted Goodix + touchscreen on SUPI S10 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Hans de Goede + +[ Upstream commit 7d87ed70fc95482c12edf9493c249b6413be485e ] + +The touchscreen on the SUPI S10 tablet reports inverted Y coordinates, +causing touch input to be mirrored vertically relative to the display. + +Add a quirk to set the "touchscreen-inverted-y" boolean device-property +on the touchscreen device, so that the goodix_ts driver will fixup +the coordinates. + +Reported-by: Yajat Kumar +Closes: https://lore.kernel.org/linux-input/20251230221639.582406-1-yajatapps3@gmail.com/ +Tested-by: Yajat Kumar +Signed-off-by: Hans de Goede +Link: https://patch.msgid.link/20260217132346.34535-1-johannes.goede@oss.qualcomm.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/touchscreen_dmi.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c +index 30c05a9948319..b8f2cb2f84320 100644 +--- a/drivers/platform/x86/touchscreen_dmi.c ++++ b/drivers/platform/x86/touchscreen_dmi.c +@@ -430,6 +430,16 @@ static const struct ts_dmi_data gdix1002_00_upside_down_data = { + .properties = gdix1001_upside_down_props, + }; + ++static const struct property_entry gdix1001_y_inverted_props[] = { ++ PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), ++ { } ++}; ++ ++static const struct ts_dmi_data gdix1001_y_inverted_data = { ++ .acpi_name = "GDIX1001", ++ .properties = gdix1001_y_inverted_props, ++}; ++ + static const struct property_entry gp_electronic_t701_props[] = { + PROPERTY_ENTRY_U32("touchscreen-size-x", 960), + PROPERTY_ENTRY_U32("touchscreen-size-y", 640), +@@ -1691,6 +1701,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_SKU, "PN20170413488"), + }, + }, ++ { ++ /* SUPI S10 */ ++ .driver_data = (void *)&gdix1001_y_inverted_data, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "SUPI"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "S10"), ++ }, ++ }, + { + /* Techbite Arc 11.6 */ + .driver_data = (void *)&techbite_arc_11_6_data, +-- +2.51.0 + diff --git a/queue-6.6/series b/queue-6.6/series new file mode 100644 index 0000000000..cd2af8ce46 --- /dev/null +++ b/queue-6.6/series @@ -0,0 +1,32 @@ +perf-extract-a-few-helpers.patch +perf-make-sure-to-use-pmu_ctx-pmu-for-groups.patch +cxl-hdm-avoid-incorrect-dvsec-fallback-when-hdm-deco.patch +hwmon-axi-fan-control-use-device-firmware-agnostic-a.patch +hwmon-axi-fan-control-make-use-of-dev_err_probe.patch +hwmon-axi-fan-don-t-use-driver_override-as-irq-name.patch +sh-platform_early-remove-pdev-driver_override-check.patch +bpf-release-module-btf-idr-before-module-unload.patch +bpf-fix-undefined-behavior-in-interpreter-sdiv-smod-.patch +hid-asus-avoid-memory-leak-in-asus_report_fixup.patch +platform-x86-intel-hid-add-dell-14-plus-2-in-1-to-dm.patch +nvme-pci-cap-queue-creation-to-used-queues.patch +nvme-fabrics-use-kfree_sensitive-for-dhchap-secrets.patch +platform-x86-intel-hid-enable-5-button-array-on-thin.patch +platform-x86-touchscreen_dmi-add-quirk-for-y-inverte.patch +nvme-pci-ensure-we-re-polling-a-polled-queue.patch +hid-magicmouse-fix-battery-reporting-for-apple-magic.patch +hid-magicmouse-avoid-memory-leak-in-magicmouse_repor.patch +net-usb-r8152-add-trendnet-tuc-et2g.patch +hid-mcp2221-cancel-last-i2c-command-on-read-error.patch +hid-asus-add-xg-mobile-2023-external-hardware-suppor.patch +module-fix-kernel-panic-when-a-symbol-st_shndx-is-ou.patch +asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch +asoc-fsl_easrc-fix-event-generation-in-fsl_easrc_iec.patch-670 +dma-buf-include-ioctl.h-in-uapi-header.patch +hid-apple-avoid-memory-leak-in-apple_report_fixup.patch +btrfs-set-btrfs_root_orphan_cleanup-during-subvol-cr.patch +alsa-hda-realtek-add-hp-laptop-14s-dr5xxx-mute-led-q.patch +alsa-hda-realtek-add-headset-jack-quirk-for-thinkpad.patch +objtool-handle-clang-rsp-musical-chairs.patch +usb-core-new-quirk-to-handle-devices-with-zero-confi.patch +spi-intel-pci-add-support-for-nova-lake-mobile-spi-f.patch diff --git a/queue-6.6/sh-platform_early-remove-pdev-driver_override-check.patch b/queue-6.6/sh-platform_early-remove-pdev-driver_override-check.patch new file mode 100644 index 0000000000..e08fa5b318 --- /dev/null +++ b/queue-6.6/sh-platform_early-remove-pdev-driver_override-check.patch @@ -0,0 +1,45 @@ +From 35f225310acb1c77b59a5c11fb6874df6e3345c7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Mar 2026 00:37:15 +0100 +Subject: sh: platform_early: remove pdev->driver_override check + +From: Danilo Krummrich + +[ Upstream commit c5f60e3f07b6609562d21efda878e83ce8860728 ] + +In commit 507fd01d5333 ("drivers: move the early platform device support to +arch/sh") platform_match() was copied over to the sh platform_early +code, accidentally including the driver_override check. + +This check does not make sense for platform_early, as sysfs is not even +available in first place at this point in the boot process, hence remove +the check. + +Reviewed-by: Greg Kroah-Hartman +Reviewed-by: Geert Uytterhoeven +Fixes: 507fd01d5333 ("drivers: move the early platform device support to arch/sh") +Link: https://lore.kernel.org/all/DH4M3DJ4P58T.1BGVAVXN71Z09@kernel.org/ +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + arch/sh/drivers/platform_early.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c +index 143747c45206f..48ddbc547bd9a 100644 +--- a/arch/sh/drivers/platform_early.c ++++ b/arch/sh/drivers/platform_early.c +@@ -26,10 +26,6 @@ static int platform_match(struct device *dev, struct device_driver *drv) + struct platform_device *pdev = to_platform_device(dev); + struct platform_driver *pdrv = to_platform_driver(drv); + +- /* When driver_override is set, only bind to the matching driver */ +- if (pdev->driver_override) +- return !strcmp(pdev->driver_override, drv->name); +- + /* Then try to match against the id table */ + if (pdrv->id_table) + return platform_match_id(pdrv->id_table, pdev) != NULL; +-- +2.51.0 + diff --git a/queue-6.6/spi-intel-pci-add-support-for-nova-lake-mobile-spi-f.patch b/queue-6.6/spi-intel-pci-add-support-for-nova-lake-mobile-spi-f.patch new file mode 100644 index 0000000000..5612cebdff --- /dev/null +++ b/queue-6.6/spi-intel-pci-add-support-for-nova-lake-mobile-spi-f.patch @@ -0,0 +1,36 @@ +From 40eee37d8dd370c6247a3edb614c825617664d1b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Mar 2026 16:37:03 +0100 +Subject: spi: intel-pci: Add support for Nova Lake mobile SPI flash + +From: Alan Borzeszkowski + +[ Upstream commit 85b731ad4bbf6eb3fedf267ab00be3596f148432 ] + +Add Intel Nova Lake PCD-H SPI serial flash PCI ID to the list of +supported devices. + +Signed-off-by: Alan Borzeszkowski +Acked-by: Mika Westerberg +Link: https://patch.msgid.link/20260309153703.74282-1-alan.borzeszkowski@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-intel-pci.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/spi/spi-intel-pci.c b/drivers/spi/spi-intel-pci.c +index 5c0dec90eec1d..43692315ea305 100644 +--- a/drivers/spi/spi-intel-pci.c ++++ b/drivers/spi/spi-intel-pci.c +@@ -86,6 +86,7 @@ static const struct pci_device_id intel_spi_pci_ids[] = { + { PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xa823), (unsigned long)&cnl_info }, ++ { PCI_VDEVICE(INTEL, 0xd323), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xe323), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xe423), (unsigned long)&cnl_info }, + { }, +-- +2.51.0 + diff --git a/queue-6.6/usb-core-new-quirk-to-handle-devices-with-zero-confi.patch b/queue-6.6/usb-core-new-quirk-to-handle-devices-with-zero-confi.patch new file mode 100644 index 0000000000..73c196b99e --- /dev/null +++ b/queue-6.6/usb-core-new-quirk-to-handle-devices-with-zero-confi.patch @@ -0,0 +1,107 @@ +From 7f04ec6f371b108e70f228c21ea1775ea7e604ed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Feb 2026 16:49:31 +0800 +Subject: usb: core: new quirk to handle devices with zero configurations + +From: Jie Deng + +[ Upstream commit 9f6a983cfa22ac662c86e60816d3a357d4b551e9 ] + +Some USB devices incorrectly report bNumConfigurations as 0 in their +device descriptor, which causes the USB core to reject them during +enumeration. +logs: +usb 1-2: device descriptor read/64, error -71 +usb 1-2: no configurations +usb 1-2: can't read configurations, error -22 + +However, these devices actually work correctly when +treated as having a single configuration. + +Add a new quirk USB_QUIRK_FORCE_ONE_CONFIG to handle such devices. +When this quirk is set, assume the device has 1 configuration instead +of failing with -EINVAL. + +This quirk is applied to the device with VID:PID 5131:2007 which +exhibits this behavior. + +Signed-off-by: Jie Deng +Link: https://patch.msgid.link/20260227084931.1527461-1-dengjie03@kylinos.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + Documentation/admin-guide/kernel-parameters.txt | 3 +++ + drivers/usb/core/config.c | 6 +++++- + drivers/usb/core/quirks.c | 5 +++++ + include/linux/usb/quirks.h | 3 +++ + 4 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index fff3ca50c6c26..fdbc2749fbb37 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -6901,6 +6901,9 @@ + p = USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT + (Reduce timeout of the SET_ADDRESS + request from 5000 ms to 500 ms); ++ q = USB_QUIRK_FORCE_ONE_CONFIG (Device ++ claims zero configurations, ++ forcing to 1); + Example: quirks=0781:5580:bk,0a5c:5834:gij + + usbhid.mousepoll= +diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c +index 10a1bc059ea1f..9cd263b6cdee8 100644 +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -891,7 +891,11 @@ int usb_get_configuration(struct usb_device *dev) + dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG; + } + +- if (ncfg < 1) { ++ if (ncfg < 1 && dev->quirks & USB_QUIRK_FORCE_ONE_CONFIG) { ++ dev_info(ddev, "Device claims zero configurations, forcing to 1\n"); ++ dev->descriptor.bNumConfigurations = 1; ++ ncfg = 1; ++ } else if (ncfg < 1) { + dev_err(ddev, "no configurations\n"); + return -EINVAL; + } +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index c12942a533ce2..53b08d6cf7824 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -141,6 +141,8 @@ static int quirks_param_set(const char *value, const struct kernel_param *kp) + case 'p': + flags |= USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT; + break; ++ case 'q': ++ flags |= USB_QUIRK_FORCE_ONE_CONFIG; + /* Ignore unrecognized flag characters */ + } + } +@@ -594,6 +596,9 @@ static const struct usb_device_id usb_quirk_list[] = { + /* VCOM device */ + { USB_DEVICE(0x4296, 0x7570), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS }, + ++ /* Noji-MCS SmartCard Reader */ ++ { USB_DEVICE(0x5131, 0x2007), .driver_info = USB_QUIRK_FORCE_ONE_CONFIG }, ++ + /* INTEL VALUE SSD */ + { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, + +diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h +index 2f7bd2fdc6164..b3cc7beab4a3c 100644 +--- a/include/linux/usb/quirks.h ++++ b/include/linux/usb/quirks.h +@@ -78,4 +78,7 @@ + /* skip BOS descriptor request */ + #define USB_QUIRK_NO_BOS BIT(17) + ++/* Device claims zero configurations, forcing to 1 */ ++#define USB_QUIRK_FORCE_ONE_CONFIG BIT(18) ++ + #endif /* __LINUX_USB_QUIRKS_H */ +-- +2.51.0 +