--- /dev/null
+From 627369d09f2299832b30a0b6580e70d99dfaedd0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jul 2025 08:30:49 +0200
+Subject: ALSA: compress_offload: tighten ioctl command number checks
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 19c4096ccdd809c6213e2e62b0d4f57c880138cd ]
+
+The snd_compr_ioctl() ignores the upper 24 bits of the ioctl command
+number and only compares the number of the ioctl command, which can
+cause unintended behavior if an application tries to use an unsupprted
+command that happens to have the same _IOC_NR() value.
+
+Remove the truncation to the low bits and compare the entire ioctl
+command code like every other driver does.
+
+Fixes: b21c60a4edd2 ("ALSA: core: add support for compress_offload")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Vinod Koul <vkoul@kernel.org>
+Link: https://patch.msgid.link/20250710063059.2683476-1-arnd@kernel.org
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/core/compress_offload.c | 48 +++++++++++++++++------------------
+ 1 file changed, 24 insertions(+), 24 deletions(-)
+
+diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
+index 840bb9cfe7890..a66f258cafaa8 100644
+--- a/sound/core/compress_offload.c
++++ b/sound/core/compress_offload.c
+@@ -1269,62 +1269,62 @@ static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
+ stream = &data->stream;
+
+ guard(mutex)(&stream->device->lock);
+- switch (_IOC_NR(cmd)) {
+- case _IOC_NR(SNDRV_COMPRESS_IOCTL_VERSION):
++ switch (cmd) {
++ case SNDRV_COMPRESS_IOCTL_VERSION:
+ return put_user(SNDRV_COMPRESS_VERSION,
+ (int __user *)arg) ? -EFAULT : 0;
+- case _IOC_NR(SNDRV_COMPRESS_GET_CAPS):
++ case SNDRV_COMPRESS_GET_CAPS:
+ return snd_compr_get_caps(stream, arg);
+ #ifndef COMPR_CODEC_CAPS_OVERFLOW
+- case _IOC_NR(SNDRV_COMPRESS_GET_CODEC_CAPS):
++ case SNDRV_COMPRESS_GET_CODEC_CAPS:
+ return snd_compr_get_codec_caps(stream, arg);
+ #endif
+- case _IOC_NR(SNDRV_COMPRESS_SET_PARAMS):
++ case SNDRV_COMPRESS_SET_PARAMS:
+ return snd_compr_set_params(stream, arg);
+- case _IOC_NR(SNDRV_COMPRESS_GET_PARAMS):
++ case SNDRV_COMPRESS_GET_PARAMS:
+ return snd_compr_get_params(stream, arg);
+- case _IOC_NR(SNDRV_COMPRESS_SET_METADATA):
++ case SNDRV_COMPRESS_SET_METADATA:
+ return snd_compr_set_metadata(stream, arg);
+- case _IOC_NR(SNDRV_COMPRESS_GET_METADATA):
++ case SNDRV_COMPRESS_GET_METADATA:
+ return snd_compr_get_metadata(stream, arg);
+ }
+
+ if (stream->direction == SND_COMPRESS_ACCEL) {
+ #if IS_ENABLED(CONFIG_SND_COMPRESS_ACCEL)
+- switch (_IOC_NR(cmd)) {
+- case _IOC_NR(SNDRV_COMPRESS_TASK_CREATE):
++ switch (cmd) {
++ case SNDRV_COMPRESS_TASK_CREATE:
+ return snd_compr_task_create(stream, arg);
+- case _IOC_NR(SNDRV_COMPRESS_TASK_FREE):
++ case SNDRV_COMPRESS_TASK_FREE:
+ return snd_compr_task_seq(stream, arg, snd_compr_task_free_one);
+- case _IOC_NR(SNDRV_COMPRESS_TASK_START):
++ case SNDRV_COMPRESS_TASK_START:
+ return snd_compr_task_start_ioctl(stream, arg);
+- case _IOC_NR(SNDRV_COMPRESS_TASK_STOP):
++ case SNDRV_COMPRESS_TASK_STOP:
+ return snd_compr_task_seq(stream, arg, snd_compr_task_stop_one);
+- case _IOC_NR(SNDRV_COMPRESS_TASK_STATUS):
++ case SNDRV_COMPRESS_TASK_STATUS:
+ return snd_compr_task_status_ioctl(stream, arg);
+ }
+ #endif
+ return -ENOTTY;
+ }
+
+- switch (_IOC_NR(cmd)) {
+- case _IOC_NR(SNDRV_COMPRESS_TSTAMP):
++ switch (cmd) {
++ case SNDRV_COMPRESS_TSTAMP:
+ return snd_compr_tstamp(stream, arg);
+- case _IOC_NR(SNDRV_COMPRESS_AVAIL):
++ case SNDRV_COMPRESS_AVAIL:
+ return snd_compr_ioctl_avail(stream, arg);
+- case _IOC_NR(SNDRV_COMPRESS_PAUSE):
++ case SNDRV_COMPRESS_PAUSE:
+ return snd_compr_pause(stream);
+- case _IOC_NR(SNDRV_COMPRESS_RESUME):
++ case SNDRV_COMPRESS_RESUME:
+ return snd_compr_resume(stream);
+- case _IOC_NR(SNDRV_COMPRESS_START):
++ case SNDRV_COMPRESS_START:
+ return snd_compr_start(stream);
+- case _IOC_NR(SNDRV_COMPRESS_STOP):
++ case SNDRV_COMPRESS_STOP:
+ return snd_compr_stop(stream);
+- case _IOC_NR(SNDRV_COMPRESS_DRAIN):
++ case SNDRV_COMPRESS_DRAIN:
+ return snd_compr_drain(stream);
+- case _IOC_NR(SNDRV_COMPRESS_PARTIAL_DRAIN):
++ case SNDRV_COMPRESS_PARTIAL_DRAIN:
+ return snd_compr_partial_drain(stream);
+- case _IOC_NR(SNDRV_COMPRESS_NEXT_TRACK):
++ case SNDRV_COMPRESS_NEXT_TRACK:
+ return snd_compr_next_track(stream);
+ }
+
+--
+2.39.5
+
--- /dev/null
+From b3a355da77cf276258c3c965eb8ea382509afc9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 May 2025 16:34:32 +0800
+Subject: arm64: dts: imx95-15x15-evk: fix the overshoot issue of NETC
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit e0322ac2a3cf7013b7af73b1293670f1e163c92e ]
+
+The overshoot of MDIO, MDC, ENET1_TDx and ENET2_TDx is too high, so
+reduce the drive strength of these pins.
+
+Fixes: e3e8b199aff8 ("arm64: dts: imx95: Add imx95-15x15-evk support")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../boot/dts/freescale/imx95-15x15-evk.dts | 20 +++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
+index 514f2429dcbc2..3ab4d27de1a22 100644
+--- a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
++++ b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
+@@ -558,17 +558,17 @@
+ &scmi_iomuxc {
+ pinctrl_emdio: emdiogrp {
+ fsl,pins = <
+- IMX95_PAD_ENET2_MDC__NETCMIX_TOP_NETC_MDC 0x57e
+- IMX95_PAD_ENET2_MDIO__NETCMIX_TOP_NETC_MDIO 0x97e
++ IMX95_PAD_ENET2_MDC__NETCMIX_TOP_NETC_MDC 0x50e
++ IMX95_PAD_ENET2_MDIO__NETCMIX_TOP_NETC_MDIO 0x90e
+ >;
+ };
+
+ pinctrl_enetc0: enetc0grp {
+ fsl,pins = <
+- IMX95_PAD_ENET1_TD3__NETCMIX_TOP_ETH0_RGMII_TD3 0x57e
+- IMX95_PAD_ENET1_TD2__NETCMIX_TOP_ETH0_RGMII_TD2 0x57e
+- IMX95_PAD_ENET1_TD1__NETCMIX_TOP_ETH0_RGMII_TD1 0x57e
+- IMX95_PAD_ENET1_TD0__NETCMIX_TOP_ETH0_RGMII_TD0 0x57e
++ IMX95_PAD_ENET1_TD3__NETCMIX_TOP_ETH0_RGMII_TD3 0x50e
++ IMX95_PAD_ENET1_TD2__NETCMIX_TOP_ETH0_RGMII_TD2 0x50e
++ IMX95_PAD_ENET1_TD1__NETCMIX_TOP_ETH0_RGMII_TD1 0x50e
++ IMX95_PAD_ENET1_TD0__NETCMIX_TOP_ETH0_RGMII_TD0 0x50e
+ IMX95_PAD_ENET1_TX_CTL__NETCMIX_TOP_ETH0_RGMII_TX_CTL 0x57e
+ IMX95_PAD_ENET1_TXC__NETCMIX_TOP_ETH0_RGMII_TX_CLK 0x58e
+ IMX95_PAD_ENET1_RX_CTL__NETCMIX_TOP_ETH0_RGMII_RX_CTL 0x57e
+@@ -582,10 +582,10 @@
+
+ pinctrl_enetc1: enetc1grp {
+ fsl,pins = <
+- IMX95_PAD_ENET2_TD3__NETCMIX_TOP_ETH1_RGMII_TD3 0x57e
+- IMX95_PAD_ENET2_TD2__NETCMIX_TOP_ETH1_RGMII_TD2 0x57e
+- IMX95_PAD_ENET2_TD1__NETCMIX_TOP_ETH1_RGMII_TD1 0x57e
+- IMX95_PAD_ENET2_TD0__NETCMIX_TOP_ETH1_RGMII_TD0 0x57e
++ IMX95_PAD_ENET2_TD3__NETCMIX_TOP_ETH1_RGMII_TD3 0x50e
++ IMX95_PAD_ENET2_TD2__NETCMIX_TOP_ETH1_RGMII_TD2 0x50e
++ IMX95_PAD_ENET2_TD1__NETCMIX_TOP_ETH1_RGMII_TD1 0x50e
++ IMX95_PAD_ENET2_TD0__NETCMIX_TOP_ETH1_RGMII_TD0 0x50e
+ IMX95_PAD_ENET2_TX_CTL__NETCMIX_TOP_ETH1_RGMII_TX_CTL 0x57e
+ IMX95_PAD_ENET2_TXC__NETCMIX_TOP_ETH1_RGMII_TX_CLK 0x58e
+ IMX95_PAD_ENET2_RX_CTL__NETCMIX_TOP_ETH1_RGMII_RX_CTL 0x57e
+--
+2.39.5
+
--- /dev/null
+From ed9649bd5a7471c7c6c72a08642a2566d02fa0b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 May 2025 16:34:31 +0800
+Subject: arm64: dts: imx95-19x19-evk: fix the overshoot issue of NETC
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit 36c2bf42b6f02ded87a381edc6b500cd6aac5018 ]
+
+The overshoot of MDIO, MDC and ENET1_TDx is too high, so reduce the drive
+strength these pins.
+
+Fixes: 025cf78938c2 ("arm64: dts: imx95-19x19-evk: add ENETC 0 support")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
+index 25ac331f03183..9a4d5f7f9e7f9 100644
+--- a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
++++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
+@@ -536,17 +536,17 @@
+ &scmi_iomuxc {
+ pinctrl_emdio: emdiogrp{
+ fsl,pins = <
+- IMX95_PAD_ENET1_MDC__NETCMIX_TOP_NETC_MDC 0x57e
+- IMX95_PAD_ENET1_MDIO__NETCMIX_TOP_NETC_MDIO 0x97e
++ IMX95_PAD_ENET1_MDC__NETCMIX_TOP_NETC_MDC 0x50e
++ IMX95_PAD_ENET1_MDIO__NETCMIX_TOP_NETC_MDIO 0x90e
+ >;
+ };
+
+ pinctrl_enetc0: enetc0grp {
+ fsl,pins = <
+- IMX95_PAD_ENET1_TD3__NETCMIX_TOP_ETH0_RGMII_TD3 0x57e
+- IMX95_PAD_ENET1_TD2__NETCMIX_TOP_ETH0_RGMII_TD2 0x57e
+- IMX95_PAD_ENET1_TD1__NETCMIX_TOP_ETH0_RGMII_TD1 0x57e
+- IMX95_PAD_ENET1_TD0__NETCMIX_TOP_ETH0_RGMII_TD0 0x57e
++ IMX95_PAD_ENET1_TD3__NETCMIX_TOP_ETH0_RGMII_TD3 0x50e
++ IMX95_PAD_ENET1_TD2__NETCMIX_TOP_ETH0_RGMII_TD2 0x50e
++ IMX95_PAD_ENET1_TD1__NETCMIX_TOP_ETH0_RGMII_TD1 0x50e
++ IMX95_PAD_ENET1_TD0__NETCMIX_TOP_ETH0_RGMII_TD0 0x50e
+ IMX95_PAD_ENET1_TX_CTL__NETCMIX_TOP_ETH0_RGMII_TX_CTL 0x57e
+ IMX95_PAD_ENET1_TXC__NETCMIX_TOP_ETH0_RGMII_TX_CLK 0x58e
+ IMX95_PAD_ENET1_RX_CTL__NETCMIX_TOP_ETH0_RGMII_RX_CTL 0x57e
+--
+2.39.5
+
--- /dev/null
+From e63912a657bdeecf3b6dddc94804b2f1d6a56a09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jun 2025 17:11:27 +0800
+Subject: arm64: dts: imx95: Correct the DMA interrupter number of pcie0_ep
+
+From: Richard Zhu <hongxing.zhu@nxp.com>
+
+[ Upstream commit 61f1065272ea3721c20c4c0a6877d346b0e237c3 ]
+
+Correct the DMA interrupter number of pcie0_ep from 317 to 311.
+
+Fixes: 3b1d5deb29ff ("arm64: dts: imx95: add pcie[0,1] and pcie-ep[0,1] support")
+Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx95.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
+index 59f057ba6fa7f..7ad9adfb26533 100644
+--- a/arch/arm64/boot/dts/freescale/imx95.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
+@@ -1678,7 +1678,7 @@
+ <0x9 0 1 0>;
+ reg-names = "dbi","atu", "dbi2", "app", "dma", "addr_space";
+ num-lanes = <1>;
+- interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>;
++ interrupts = <GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dma";
+ clocks = <&scmi_clk IMX95_CLK_HSIO>,
+ <&scmi_clk IMX95_CLK_HSIOPLL>,
+--
+2.39.5
+
--- /dev/null
+From 3971f77111a4dee5003434dc6f53ad08a1324d04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 May 2025 14:42:12 +0800
+Subject: arm64: dts: rockchip: Add cd-gpios for sdcard detect on Cool Pi CM5
+
+From: Andy Yan <andyshrk@163.com>
+
+[ Upstream commit e625e284172d235be5cd906a98c6c91c365bb9b1 ]
+
+cd-gpios is used for sdcard detects for sdmmc.
+
+Fixes: 791c154c3982 ("arm64: dts: rockchip: Add support for rk3588 based board Cool Pi CM5 EVB")
+Signed-off-by: Andy Yan <andyshrk@163.com>
+Link: https://lore.kernel.org/r/20250524064223.5741-1-andyshrk@163.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi
+index cc37f082adea0..b07543315f878 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi
+@@ -321,6 +321,7 @@
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
++ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ max-frequency = <150000000>;
+ no-sdio;
+--
+2.39.5
+
--- /dev/null
+From 94507a18f6be9fbfcd05757a522b1949dfee45f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 May 2025 14:42:13 +0800
+Subject: arm64: dts: rockchip: Add cd-gpios for sdcard detect on Cool Pi 4B
+
+From: Andy Yan <andyshrk@163.com>
+
+[ Upstream commit 98570e8cb8b0c0893810f285b4a3b1a3ab81a556 ]
+
+cd-gpios is used for sdcard detects for sdmmc.
+
+Fixes: 3f5d336d64d6 ("arm64: dts: rockchip: Add support for rk3588s based board Cool Pi 4B")
+Signed-off-by: Andy Yan <andyshrk@163.com>
+Link: https://lore.kernel.org/r/20250524064223.5741-2-andyshrk@163.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts b/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
+index 8b717c4017a46..b2947b36fadaf 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
+@@ -474,6 +474,7 @@
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
++ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ max-frequency = <150000000>;
+ no-sdio;
+--
+2.39.5
+
--- /dev/null
+From 8f37ad51e95ee69d52e8743e1d8a27453dba8d42 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Jul 2025 16:30:09 +0800
+Subject: block: fix kobject leak in blk_unregister_queue
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 3051247e4faa32a3d90c762a243c2c62dde310db ]
+
+The kobject for the queue, `disk->queue_kobj`, is initialized with a
+reference count of 1 via `kobject_init()` in `blk_register_queue()`.
+While `kobject_del()` is called during the unregister path to remove
+the kobject from sysfs, the initial reference is never released.
+
+Add a call to `kobject_put()` in `blk_unregister_queue()` to properly
+decrement the reference count and fix the leak.
+
+Fixes: 2bd85221a625 ("block: untangle request_queue refcounting from sysfs")
+Cc: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20250711083009.2574432-1-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-sysfs.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
+index 1f9b45b0b9ee7..12a5059089a2f 100644
+--- a/block/blk-sysfs.c
++++ b/block/blk-sysfs.c
+@@ -964,4 +964,5 @@ void blk_unregister_queue(struct gendisk *disk)
+ kobject_del(&disk->queue_kobj);
+
+ blk_debugfs_remove(disk);
++ kobject_put(&disk->queue_kobj);
+ }
+--
+2.39.5
+
--- /dev/null
+From d8bc4c847496bbbbdfb838717c2a3b2da495df5a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Jul 2025 20:40:13 +0800
+Subject: Bluetooth: btusb: QCA: Fix downloading wrong NVM for WCN6855 GF
+ variant without board ID
+
+From: Zijun Hu <zijun.hu@oss.qualcomm.com>
+
+[ Upstream commit 43015955795a619f7ca4ae69b9c0ffc994c82818 ]
+
+For GF variant of WCN6855 without board ID programmed
+btusb_generate_qca_nvm_name() will chose wrong NVM
+'qca/nvm_usb_00130201.bin' to download.
+
+Fix by choosing right NVM 'qca/nvm_usb_00130201_gf.bin'.
+Also simplify NVM choice logic of btusb_generate_qca_nvm_name().
+
+Fixes: d6cba4e6d0e2 ("Bluetooth: btusb: Add support using different nvm for variant WCN6855 controller")
+Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 78 ++++++++++++++++++++++-----------------
+ 1 file changed, 44 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 42350212db082..6f2fd043fd3fa 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -3230,6 +3230,32 @@ static const struct qca_device_info qca_devices_table[] = {
+ { 0x00190200, 40, 4, 16 }, /* WCN785x 2.0 */
+ };
+
++static u16 qca_extract_board_id(const struct qca_version *ver)
++{
++ u16 flag = le16_to_cpu(ver->flag);
++ u16 board_id = 0;
++
++ if (((flag >> 8) & 0xff) == QCA_FLAG_MULTI_NVM) {
++ /* The board_id should be split into two bytes
++ * The 1st byte is chip ID, and the 2nd byte is platform ID
++ * For example, board ID 0x010A, 0x01 is platform ID. 0x0A is chip ID
++ * we have several platforms, and platform IDs are continuously added
++ * Platform ID:
++ * 0x00 is for Mobile
++ * 0x01 is for X86
++ * 0x02 is for Automotive
++ * 0x03 is for Consumer electronic
++ */
++ board_id = (ver->chip_id << 8) + ver->platform_id;
++ }
++
++ /* Take 0xffff as invalid board ID */
++ if (board_id == 0xffff)
++ board_id = 0;
++
++ return board_id;
++}
++
+ static int btusb_qca_send_vendor_req(struct usb_device *udev, u8 request,
+ void *data, u16 size)
+ {
+@@ -3386,44 +3412,28 @@ static void btusb_generate_qca_nvm_name(char *fwname, size_t max_size,
+ const struct qca_version *ver)
+ {
+ u32 rom_version = le32_to_cpu(ver->rom_version);
+- u16 flag = le16_to_cpu(ver->flag);
++ const char *variant;
++ int len;
++ u16 board_id;
+
+- if (((flag >> 8) & 0xff) == QCA_FLAG_MULTI_NVM) {
+- /* The board_id should be split into two bytes
+- * The 1st byte is chip ID, and the 2nd byte is platform ID
+- * For example, board ID 0x010A, 0x01 is platform ID. 0x0A is chip ID
+- * we have several platforms, and platform IDs are continuously added
+- * Platform ID:
+- * 0x00 is for Mobile
+- * 0x01 is for X86
+- * 0x02 is for Automotive
+- * 0x03 is for Consumer electronic
+- */
+- u16 board_id = (ver->chip_id << 8) + ver->platform_id;
+- const char *variant;
++ board_id = qca_extract_board_id(ver);
+
+- switch (le32_to_cpu(ver->ram_version)) {
+- case WCN6855_2_0_RAM_VERSION_GF:
+- case WCN6855_2_1_RAM_VERSION_GF:
+- variant = "_gf";
+- break;
+- default:
+- variant = "";
+- break;
+- }
+-
+- if (board_id == 0) {
+- snprintf(fwname, max_size, "qca/nvm_usb_%08x%s.bin",
+- rom_version, variant);
+- } else {
+- snprintf(fwname, max_size, "qca/nvm_usb_%08x%s_%04x.bin",
+- rom_version, variant, board_id);
+- }
+- } else {
+- snprintf(fwname, max_size, "qca/nvm_usb_%08x.bin",
+- rom_version);
++ switch (le32_to_cpu(ver->ram_version)) {
++ case WCN6855_2_0_RAM_VERSION_GF:
++ case WCN6855_2_1_RAM_VERSION_GF:
++ variant = "_gf";
++ break;
++ default:
++ variant = NULL;
++ break;
+ }
+
++ len = snprintf(fwname, max_size, "qca/nvm_usb_%08x", rom_version);
++ if (variant)
++ len += snprintf(fwname + len, max_size - len, "%s", variant);
++ if (board_id)
++ len += snprintf(fwname + len, max_size - len, "_%04x", board_id);
++ len += snprintf(fwname + len, max_size - len, ".bin");
+ }
+
+ static int btusb_setup_qca_load_nvm(struct hci_dev *hdev,
+--
+2.39.5
+
--- /dev/null
+From 80e8c2e62c069f3b5babfcc330ff5c55e46d5337 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jul 2025 19:28:29 +0000
+Subject: Bluetooth: Fix null-ptr-deref in l2cap_sock_resume_cb()
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit a0075accbf0d76c2dad1ad3993d2e944505d99a0 ]
+
+syzbot reported null-ptr-deref in l2cap_sock_resume_cb(). [0]
+
+l2cap_sock_resume_cb() has a similar problem that was fixed by commit
+1bff51ea59a9 ("Bluetooth: fix use-after-free error in lock_sock_nested()").
+
+Since both l2cap_sock_kill() and l2cap_sock_resume_cb() are executed
+under l2cap_sock_resume_cb(), we can avoid the issue simply by checking
+if chan->data is NULL.
+
+Let's not access to the killed socket in l2cap_sock_resume_cb().
+
+[0]:
+BUG: KASAN: null-ptr-deref in instrument_atomic_write include/linux/instrumented.h:82 [inline]
+BUG: KASAN: null-ptr-deref in clear_bit include/asm-generic/bitops/instrumented-atomic.h:41 [inline]
+BUG: KASAN: null-ptr-deref in l2cap_sock_resume_cb+0xb4/0x17c net/bluetooth/l2cap_sock.c:1711
+Write of size 8 at addr 0000000000000570 by task kworker/u9:0/52
+
+CPU: 1 UID: 0 PID: 52 Comm: kworker/u9:0 Not tainted 6.16.0-rc4-syzkaller-g7482bb149b9f #0 PREEMPT
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/07/2025
+Workqueue: hci0 hci_rx_work
+Call trace:
+ show_stack+0x2c/0x3c arch/arm64/kernel/stacktrace.c:501 (C)
+ __dump_stack+0x30/0x40 lib/dump_stack.c:94
+ dump_stack_lvl+0xd8/0x12c lib/dump_stack.c:120
+ print_report+0x58/0x84 mm/kasan/report.c:524
+ kasan_report+0xb0/0x110 mm/kasan/report.c:634
+ check_region_inline mm/kasan/generic.c:-1 [inline]
+ kasan_check_range+0x264/0x2a4 mm/kasan/generic.c:189
+ __kasan_check_write+0x20/0x30 mm/kasan/shadow.c:37
+ instrument_atomic_write include/linux/instrumented.h:82 [inline]
+ clear_bit include/asm-generic/bitops/instrumented-atomic.h:41 [inline]
+ l2cap_sock_resume_cb+0xb4/0x17c net/bluetooth/l2cap_sock.c:1711
+ l2cap_security_cfm+0x524/0xea0 net/bluetooth/l2cap_core.c:7357
+ hci_auth_cfm include/net/bluetooth/hci_core.h:2092 [inline]
+ hci_auth_complete_evt+0x2e8/0xa4c net/bluetooth/hci_event.c:3514
+ hci_event_func net/bluetooth/hci_event.c:7511 [inline]
+ hci_event_packet+0x650/0xe9c net/bluetooth/hci_event.c:7565
+ hci_rx_work+0x320/0xb18 net/bluetooth/hci_core.c:4070
+ process_one_work+0x7e8/0x155c kernel/workqueue.c:3238
+ process_scheduled_works kernel/workqueue.c:3321 [inline]
+ worker_thread+0x958/0xed8 kernel/workqueue.c:3402
+ kthread+0x5fc/0x75c kernel/kthread.c:464
+ ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:847
+
+Fixes: d97c899bde33 ("Bluetooth: Introduce L2CAP channel callback for resuming")
+Reported-by: syzbot+e4d73b165c3892852d22@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/686c12bd.a70a0220.29fe6c.0b13.GAE@google.com/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_sock.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
+index 5aa55fa695943..82d943c4cb505 100644
+--- a/net/bluetooth/l2cap_sock.c
++++ b/net/bluetooth/l2cap_sock.c
+@@ -1703,6 +1703,9 @@ static void l2cap_sock_resume_cb(struct l2cap_chan *chan)
+ {
+ struct sock *sk = chan->data;
+
++ if (!sk)
++ return;
++
+ if (test_and_clear_bit(FLAG_PENDING_SECURITY, &chan->flags)) {
+ sk->sk_state = BT_CONNECTED;
+ chan->state = BT_CONNECTED;
+--
+2.39.5
+
--- /dev/null
+From 12ffc110297eb6ef47fd2907d35df6b8823f46de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jul 2025 22:27:44 +0200
+Subject: Bluetooth: hci_core: add missing braces when using macro parameters
+
+From: Christian Eggers <ceggers@arri.de>
+
+[ Upstream commit cdee6a4416b2a57c89082929cc60e2275bb32a3a ]
+
+Macro parameters should always be put into braces when accessing it.
+
+Fixes: 4fc9857ab8c6 ("Bluetooth: hci_sync: Add check simultaneous roles support")
+Signed-off-by: Christian Eggers <ceggers@arri.de>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_core.h | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index 08cc5db8240ed..f7f7e1974dddb 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -825,20 +825,20 @@ extern struct mutex hci_cb_list_lock;
+ #define hci_dev_test_and_clear_flag(hdev, nr) test_and_clear_bit((nr), (hdev)->dev_flags)
+ #define hci_dev_test_and_change_flag(hdev, nr) test_and_change_bit((nr), (hdev)->dev_flags)
+
+-#define hci_dev_clear_volatile_flags(hdev) \
+- do { \
+- hci_dev_clear_flag(hdev, HCI_LE_SCAN); \
+- hci_dev_clear_flag(hdev, HCI_LE_ADV); \
+- hci_dev_clear_flag(hdev, HCI_LL_RPA_RESOLUTION);\
+- hci_dev_clear_flag(hdev, HCI_PERIODIC_INQ); \
+- hci_dev_clear_flag(hdev, HCI_QUALITY_REPORT); \
++#define hci_dev_clear_volatile_flags(hdev) \
++ do { \
++ hci_dev_clear_flag((hdev), HCI_LE_SCAN); \
++ hci_dev_clear_flag((hdev), HCI_LE_ADV); \
++ hci_dev_clear_flag((hdev), HCI_LL_RPA_RESOLUTION); \
++ hci_dev_clear_flag((hdev), HCI_PERIODIC_INQ); \
++ hci_dev_clear_flag((hdev), HCI_QUALITY_REPORT); \
+ } while (0)
+
+ #define hci_dev_le_state_simultaneous(hdev) \
+- (!test_bit(HCI_QUIRK_BROKEN_LE_STATES, &hdev->quirks) && \
+- (hdev->le_states[4] & 0x08) && /* Central */ \
+- (hdev->le_states[4] & 0x40) && /* Peripheral */ \
+- (hdev->le_states[3] & 0x10)) /* Simultaneous */
++ (!test_bit(HCI_QUIRK_BROKEN_LE_STATES, &(hdev)->quirks) && \
++ ((hdev)->le_states[4] & 0x08) && /* Central */ \
++ ((hdev)->le_states[4] & 0x40) && /* Peripheral */ \
++ ((hdev)->le_states[3] & 0x10)) /* Simultaneous */
+
+ /* ----- HCI interface to upper protocols ----- */
+ int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr);
+--
+2.39.5
+
--- /dev/null
+From eadaebf3b3a5584bca57705c33ac2a1bbe54e221 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jul 2025 22:27:43 +0200
+Subject: Bluetooth: hci_core: fix typos in macros
+
+From: Christian Eggers <ceggers@arri.de>
+
+[ Upstream commit dfef8d87a031ac1a46dde3de804e0fcf3c3a6afd ]
+
+The provided macro parameter is named 'dev' (rather than 'hdev', which
+may be a variable on the stack where the macro is used).
+
+Fixes: a9a830a676a9 ("Bluetooth: hci_event: Fix sending HCI_OP_READ_ENC_KEY_SIZE")
+Fixes: 6126ffabba6b ("Bluetooth: Introduce HCI_CONN_FLAG_DEVICE_PRIVACY device flag")
+Signed-off-by: Christian Eggers <ceggers@arri.de>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_core.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index 1cf60ed7ac89b..08cc5db8240ed 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -1934,11 +1934,11 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
+ #define ll_privacy_capable(dev) ((dev)->le_features[0] & HCI_LE_LL_PRIVACY)
+
+ #define privacy_mode_capable(dev) (ll_privacy_capable(dev) && \
+- (hdev->commands[39] & 0x04))
++ ((dev)->commands[39] & 0x04))
+
+ #define read_key_size_capable(dev) \
+ ((dev)->commands[20] & 0x10 && \
+- !test_bit(HCI_QUIRK_BROKEN_READ_ENC_KEY_SIZE, &hdev->quirks))
++ !test_bit(HCI_QUIRK_BROKEN_READ_ENC_KEY_SIZE, &(dev)->quirks))
+
+ #define read_voice_setting_capable(dev) \
+ ((dev)->commands[9] & 0x04 && \
+--
+2.39.5
+
--- /dev/null
+From 25e3db7ff4285e15415247e3e5d6376bb80ea8e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jul 2025 22:27:45 +0200
+Subject: Bluetooth: hci_dev: replace 'quirks' integer by 'quirk_flags' bitmap
+
+From: Christian Eggers <ceggers@arri.de>
+
+[ Upstream commit 6851a0c228fc040dce8e4c393004209e7372e0a3 ]
+
+The 'quirks' member already ran out of bits on some platforms some time
+ago. Replace the integer member by a bitmap in order to have enough bits
+in future. Replace raw bit operations by accessor macros.
+
+Fixes: ff26b2dd6568 ("Bluetooth: Add quirk for broken READ_VOICE_SETTING")
+Fixes: 127881334eaa ("Bluetooth: Add quirk for broken READ_PAGE_SCAN_TYPE")
+Suggested-by: Pauli Virtanen <pav@iki.fi>
+Tested-by: Ivan Pravdin <ipravdin.official@gmail.com>
+Signed-off-by: Kiran K <kiran.k@intel.com>
+Signed-off-by: Christian Eggers <ceggers@arri.de>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/bfusb.c | 2 +-
+ drivers/bluetooth/bpa10x.c | 2 +-
+ drivers/bluetooth/btbcm.c | 8 ++--
+ drivers/bluetooth/btintel.c | 28 ++++++-------
+ drivers/bluetooth/btintel_pcie.c | 8 ++--
+ drivers/bluetooth/btmtksdio.c | 4 +-
+ drivers/bluetooth/btmtkuart.c | 2 +-
+ drivers/bluetooth/btnxpuart.c | 2 +-
+ drivers/bluetooth/btqca.c | 2 +-
+ drivers/bluetooth/btqcomsmd.c | 2 +-
+ drivers/bluetooth/btrtl.c | 10 ++---
+ drivers/bluetooth/btsdio.c | 2 +-
+ drivers/bluetooth/btusb.c | 70 ++++++++++++++++----------------
+ drivers/bluetooth/hci_aml.c | 2 +-
+ drivers/bluetooth/hci_bcm.c | 4 +-
+ drivers/bluetooth/hci_bcm4377.c | 10 ++---
+ drivers/bluetooth/hci_intel.c | 2 +-
+ drivers/bluetooth/hci_ldisc.c | 6 +--
+ drivers/bluetooth/hci_ll.c | 4 +-
+ drivers/bluetooth/hci_nokia.c | 2 +-
+ drivers/bluetooth/hci_qca.c | 14 +++----
+ drivers/bluetooth/hci_serdev.c | 8 ++--
+ drivers/bluetooth/hci_vhci.c | 8 ++--
+ drivers/bluetooth/virtio_bt.c | 10 ++---
+ include/net/bluetooth/hci.h | 2 +
+ include/net/bluetooth/hci_core.h | 28 +++++++------
+ net/bluetooth/hci_core.c | 4 +-
+ net/bluetooth/hci_debugfs.c | 8 ++--
+ net/bluetooth/hci_event.c | 19 ++++-----
+ net/bluetooth/hci_sync.c | 59 +++++++++++++--------------
+ net/bluetooth/mgmt.c | 38 ++++++++---------
+ net/bluetooth/msft.c | 2 +-
+ 32 files changed, 187 insertions(+), 185 deletions(-)
+
+diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
+index 0d6ad50da0466..8df310983bf6b 100644
+--- a/drivers/bluetooth/bfusb.c
++++ b/drivers/bluetooth/bfusb.c
+@@ -670,7 +670,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
+ hdev->flush = bfusb_flush;
+ hdev->send = bfusb_send_frame;
+
+- set_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_LOCAL_COMMANDS);
+
+ if (hci_register_dev(hdev) < 0) {
+ BT_ERR("Can't register HCI device");
+diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
+index 1fa58c059cbf5..8b43dfc755de1 100644
+--- a/drivers/bluetooth/bpa10x.c
++++ b/drivers/bluetooth/bpa10x.c
+@@ -398,7 +398,7 @@ static int bpa10x_probe(struct usb_interface *intf,
+ hdev->send = bpa10x_send_frame;
+ hdev->set_diag = bpa10x_set_diag;
+
+- set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_RESET_ON_CLOSE);
+
+ err = hci_register_dev(hdev);
+ if (err < 0) {
+diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c
+index 0a60660fc8ce8..3a3a56ddbb06d 100644
+--- a/drivers/bluetooth/btbcm.c
++++ b/drivers/bluetooth/btbcm.c
+@@ -135,7 +135,7 @@ int btbcm_check_bdaddr(struct hci_dev *hdev)
+ if (btbcm_set_bdaddr_from_efi(hdev) != 0) {
+ bt_dev_info(hdev, "BCM: Using default device address (%pMR)",
+ &bda->bdaddr);
+- set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_INVALID_BDADDR);
+ }
+ }
+
+@@ -467,7 +467,7 @@ static int btbcm_print_controller_features(struct hci_dev *hdev)
+
+ /* Read DMI and disable broken Read LE Min/Max Tx Power */
+ if (dmi_first_match(disable_broken_read_transmit_power))
+- set_bit(HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER);
+
+ return 0;
+ }
+@@ -706,7 +706,7 @@ int btbcm_finalize(struct hci_dev *hdev, bool *fw_load_done, bool use_autobaud_m
+
+ btbcm_check_bdaddr(hdev);
+
+- set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_STRICT_DUPLICATE_FILTER);
+
+ return 0;
+ }
+@@ -769,7 +769,7 @@ int btbcm_setup_apple(struct hci_dev *hdev)
+ kfree_skb(skb);
+ }
+
+- set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_STRICT_DUPLICATE_FILTER);
+
+ return 0;
+ }
+diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
+index c66bf13c19a5c..99e6603b773f2 100644
+--- a/drivers/bluetooth/btintel.c
++++ b/drivers/bluetooth/btintel.c
+@@ -88,7 +88,7 @@ int btintel_check_bdaddr(struct hci_dev *hdev)
+ if (!bacmp(&bda->bdaddr, BDADDR_INTEL)) {
+ bt_dev_err(hdev, "Found Intel default device address (%pMR)",
+ &bda->bdaddr);
+- set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_INVALID_BDADDR);
+ }
+
+ kfree_skb(skb);
+@@ -2027,7 +2027,7 @@ static int btintel_download_fw(struct hci_dev *hdev,
+ */
+ if (!bacmp(¶ms->otp_bdaddr, BDADDR_ANY)) {
+ bt_dev_info(hdev, "No device address configured");
+- set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_INVALID_BDADDR);
+ }
+
+ download:
+@@ -2295,7 +2295,7 @@ static int btintel_prepare_fw_download_tlv(struct hci_dev *hdev,
+ */
+ if (!bacmp(&ver->otp_bd_addr, BDADDR_ANY)) {
+ bt_dev_info(hdev, "No device address configured");
+- set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_INVALID_BDADDR);
+ }
+ }
+
+@@ -3435,9 +3435,9 @@ static int btintel_setup_combined(struct hci_dev *hdev)
+ }
+
+ /* Apply the common HCI quirks for Intel device */
+- set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
+- set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
+- set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_STRICT_DUPLICATE_FILTER);
++ hci_set_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY);
++ hci_set_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_DIAG);
+
+ /* Set up the quality report callback for Intel devices */
+ hdev->set_quality_report = btintel_set_quality_report;
+@@ -3475,8 +3475,8 @@ static int btintel_setup_combined(struct hci_dev *hdev)
+ */
+ if (!btintel_test_flag(hdev,
+ INTEL_ROM_LEGACY_NO_WBS_SUPPORT))
+- set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
+- &hdev->quirks);
++ hci_set_quirk(hdev,
++ HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED);
+
+ err = btintel_legacy_rom_setup(hdev, &ver);
+ break;
+@@ -3491,11 +3491,11 @@ static int btintel_setup_combined(struct hci_dev *hdev)
+ *
+ * All Legacy bootloader devices support WBS
+ */
+- set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
+- &hdev->quirks);
++ hci_set_quirk(hdev,
++ HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED);
+
+ /* These variants don't seem to support LE Coded PHY */
+- set_bit(HCI_QUIRK_BROKEN_LE_CODED, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_LE_CODED);
+
+ /* Setup MSFT Extension support */
+ btintel_set_msft_opcode(hdev, ver.hw_variant);
+@@ -3571,10 +3571,10 @@ static int btintel_setup_combined(struct hci_dev *hdev)
+ *
+ * All Legacy bootloader devices support WBS
+ */
+- set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED);
+
+ /* These variants don't seem to support LE Coded PHY */
+- set_bit(HCI_QUIRK_BROKEN_LE_CODED, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_LE_CODED);
+
+ /* Setup MSFT Extension support */
+ btintel_set_msft_opcode(hdev, ver.hw_variant);
+@@ -3600,7 +3600,7 @@ static int btintel_setup_combined(struct hci_dev *hdev)
+ *
+ * All TLV based devices support WBS
+ */
+- set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED);
+
+ /* Setup MSFT Extension support */
+ btintel_set_msft_opcode(hdev,
+diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
+index 385e29367dd1d..24d73bae14ec9 100644
+--- a/drivers/bluetooth/btintel_pcie.c
++++ b/drivers/bluetooth/btintel_pcie.c
+@@ -1941,9 +1941,9 @@ static int btintel_pcie_setup_internal(struct hci_dev *hdev)
+ }
+
+ /* Apply the common HCI quirks for Intel device */
+- set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
+- set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
+- set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_STRICT_DUPLICATE_FILTER);
++ hci_set_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY);
++ hci_set_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_DIAG);
+
+ /* Set up the quality report callback for Intel devices */
+ hdev->set_quality_report = btintel_set_quality_report;
+@@ -1983,7 +1983,7 @@ static int btintel_pcie_setup_internal(struct hci_dev *hdev)
+ *
+ * All TLV based devices support WBS
+ */
+- set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED);
+
+ /* Setup MSFT Extension support */
+ btintel_set_msft_opcode(hdev,
+diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
+index c16a3518b8ffa..4fc673640bfce 100644
+--- a/drivers/bluetooth/btmtksdio.c
++++ b/drivers/bluetooth/btmtksdio.c
+@@ -1141,7 +1141,7 @@ static int btmtksdio_setup(struct hci_dev *hdev)
+ }
+
+ /* Enable WBS with mSBC codec */
+- set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED);
+
+ /* Enable GPIO reset mechanism */
+ if (bdev->reset) {
+@@ -1384,7 +1384,7 @@ static int btmtksdio_probe(struct sdio_func *func,
+ SET_HCIDEV_DEV(hdev, &func->dev);
+
+ hdev->manufacturer = 70;
+- set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_SETUP);
+
+ sdio_set_drvdata(func, bdev);
+
+diff --git a/drivers/bluetooth/btmtkuart.c b/drivers/bluetooth/btmtkuart.c
+index c97e260fcb0c3..51400a891f6e6 100644
+--- a/drivers/bluetooth/btmtkuart.c
++++ b/drivers/bluetooth/btmtkuart.c
+@@ -872,7 +872,7 @@ static int btmtkuart_probe(struct serdev_device *serdev)
+ SET_HCIDEV_DEV(hdev, &serdev->dev);
+
+ hdev->manufacturer = 70;
+- set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_SETUP);
+
+ if (btmtkuart_is_standalone(bdev)) {
+ err = clk_prepare_enable(bdev->osc);
+diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
+index 604ab2bba231c..43a212cc032ec 100644
+--- a/drivers/bluetooth/btnxpuart.c
++++ b/drivers/bluetooth/btnxpuart.c
+@@ -1769,7 +1769,7 @@ static int nxp_serdev_probe(struct serdev_device *serdev)
+ "local-bd-address",
+ (u8 *)&ba, sizeof(ba));
+ if (bacmp(&ba, BDADDR_ANY))
+- set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_USE_BDADDR_PROPERTY);
+
+ if (hci_register_dev(hdev) < 0) {
+ dev_err(&serdev->dev, "Can't register HCI device\n");
+diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
+index edefb9dc76aa1..7c958d6065bec 100644
+--- a/drivers/bluetooth/btqca.c
++++ b/drivers/bluetooth/btqca.c
+@@ -739,7 +739,7 @@ static int qca_check_bdaddr(struct hci_dev *hdev, const struct qca_fw_config *co
+
+ bda = (struct hci_rp_read_bd_addr *)skb->data;
+ if (!bacmp(&bda->bdaddr, &config->bdaddr))
+- set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_USE_BDADDR_PROPERTY);
+
+ kfree_skb(skb);
+
+diff --git a/drivers/bluetooth/btqcomsmd.c b/drivers/bluetooth/btqcomsmd.c
+index c0eb71d6ffd3b..d2e13fcb6babf 100644
+--- a/drivers/bluetooth/btqcomsmd.c
++++ b/drivers/bluetooth/btqcomsmd.c
+@@ -117,7 +117,7 @@ static int btqcomsmd_setup(struct hci_dev *hdev)
+ /* Devices do not have persistent storage for BD address. Retrieve
+ * it from the firmware node property.
+ */
+- set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_USE_BDADDR_PROPERTY);
+
+ return 0;
+ }
+diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c
+index 7838c89e529e0..4d182cf6e0372 100644
+--- a/drivers/bluetooth/btrtl.c
++++ b/drivers/bluetooth/btrtl.c
+@@ -1287,7 +1287,7 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
+ /* Enable controller to do both LE scan and BR/EDR inquiry
+ * simultaneously.
+ */
+- set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY);
+
+ /* Enable central-peripheral role (able to create new connections with
+ * an existing connection in slave role).
+@@ -1301,7 +1301,7 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
+ case CHIP_ID_8851B:
+ case CHIP_ID_8922A:
+ case CHIP_ID_8852BT:
+- set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED);
+
+ /* RTL8852C needs to transmit mSBC data continuously without
+ * the zero length of USB packets for the ALT 6 supported chips
+@@ -1312,7 +1312,8 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
+ if (btrtl_dev->project_id == CHIP_ID_8852A ||
+ btrtl_dev->project_id == CHIP_ID_8852B ||
+ btrtl_dev->project_id == CHIP_ID_8852C)
+- set_bit(HCI_QUIRK_USE_MSFT_EXT_ADDRESS_FILTER, &hdev->quirks);
++ hci_set_quirk(hdev,
++ HCI_QUIRK_USE_MSFT_EXT_ADDRESS_FILTER);
+
+ hci_set_aosp_capable(hdev);
+ break;
+@@ -1331,8 +1332,7 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
+ * but it doesn't support any features from page 2 -
+ * it either responds with garbage or with error status
+ */
+- set_bit(HCI_QUIRK_BROKEN_LOCAL_EXT_FEATURES_PAGE_2,
+- &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_LOCAL_EXT_FEATURES_PAGE_2);
+ break;
+ default:
+ break;
+diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c
+index a69feb08486a5..8325655ce6aa8 100644
+--- a/drivers/bluetooth/btsdio.c
++++ b/drivers/bluetooth/btsdio.c
+@@ -327,7 +327,7 @@ static int btsdio_probe(struct sdio_func *func,
+ hdev->send = btsdio_send_frame;
+
+ if (func->vendor == 0x0104 && func->device == 0x00c5)
+- set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_RESET_ON_CLOSE);
+
+ err = hci_register_dev(hdev);
+ if (err < 0) {
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index ef9689f877691..42350212db082 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -2510,18 +2510,18 @@ static int btusb_setup_csr(struct hci_dev *hdev)
+ * Probably will need to be expanded in the future;
+ * without these the controller will lock up.
+ */
+- set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
+- set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
+- set_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks);
+- set_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks);
+- set_bit(HCI_QUIRK_BROKEN_READ_VOICE_SETTING, &hdev->quirks);
+- set_bit(HCI_QUIRK_BROKEN_READ_PAGE_SCAN_TYPE, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_STORED_LINK_KEY);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_ERR_DATA_REPORTING);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL);
++ hci_set_quirk(hdev, HCI_QUIRK_NO_SUSPEND_NOTIFIER);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_READ_VOICE_SETTING);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_READ_PAGE_SCAN_TYPE);
+
+ /* Clear the reset quirk since this is not an actual
+ * early Bluetooth 1.1 device from CSR.
+ */
+- clear_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
+- clear_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
++ hci_clear_quirk(hdev, HCI_QUIRK_RESET_ON_CLOSE);
++ hci_clear_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY);
+
+ /*
+ * Special workaround for these BT 4.0 chip clones, and potentially more:
+@@ -3532,7 +3532,7 @@ static int btusb_setup_qca(struct hci_dev *hdev)
+ /* Mark HCI_OP_ENHANCED_SETUP_SYNC_CONN as broken as it doesn't seem to
+ * work with the likes of HSP/HFP mSBC.
+ */
+- set_bit(HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN);
+
+ return 0;
+ }
+@@ -3943,10 +3943,10 @@ static int btusb_probe(struct usb_interface *intf,
+ }
+ #endif
+ if (id->driver_info & BTUSB_CW6622)
+- set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_STORED_LINK_KEY);
+
+ if (id->driver_info & BTUSB_BCM2045)
+- set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_STORED_LINK_KEY);
+
+ if (id->driver_info & BTUSB_BCM92035)
+ hdev->setup = btusb_setup_bcm92035;
+@@ -4003,8 +4003,8 @@ static int btusb_probe(struct usb_interface *intf,
+ hdev->reset = btmtk_reset_sync;
+ hdev->set_bdaddr = btmtk_set_bdaddr;
+ hdev->send = btusb_send_frame_mtk;
+- set_bit(HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN, &hdev->quirks);
+- set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN);
++ hci_set_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_SETUP);
+ data->recv_acl = btmtk_usb_recv_acl;
+ data->suspend = btmtk_usb_suspend;
+ data->resume = btmtk_usb_resume;
+@@ -4012,20 +4012,20 @@ static int btusb_probe(struct usb_interface *intf,
+ }
+
+ if (id->driver_info & BTUSB_SWAVE) {
+- set_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks);
+- set_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_FIXUP_INQUIRY_MODE);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_LOCAL_COMMANDS);
+ }
+
+ if (id->driver_info & BTUSB_INTEL_BOOT) {
+ hdev->manufacturer = 2;
+- set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_RAW_DEVICE);
+ }
+
+ if (id->driver_info & BTUSB_ATH3012) {
+ data->setup_on_usb = btusb_setup_qca;
+ hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
+- set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
+- set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY);
++ hci_set_quirk(hdev, HCI_QUIRK_STRICT_DUPLICATE_FILTER);
+ }
+
+ if (id->driver_info & BTUSB_QCA_ROME) {
+@@ -4033,7 +4033,7 @@ static int btusb_probe(struct usb_interface *intf,
+ hdev->shutdown = btusb_shutdown_qca;
+ hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
+ hdev->reset = btusb_qca_reset;
+- set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY);
+ btusb_check_needs_reset_resume(intf);
+ }
+
+@@ -4047,7 +4047,7 @@ static int btusb_probe(struct usb_interface *intf,
+ hdev->shutdown = btusb_shutdown_qca;
+ hdev->set_bdaddr = btusb_set_bdaddr_wcn6855;
+ hdev->reset = btusb_qca_reset;
+- set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY);
+ hci_set_msft_opcode(hdev, 0xFD70);
+ }
+
+@@ -4075,35 +4075,35 @@ static int btusb_probe(struct usb_interface *intf,
+
+ if (id->driver_info & BTUSB_ACTIONS_SEMI) {
+ /* Support is advertised, but not implemented */
+- set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
+- set_bit(HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER, &hdev->quirks);
+- set_bit(HCI_QUIRK_BROKEN_SET_RPA_TIMEOUT, &hdev->quirks);
+- set_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &hdev->quirks);
+- set_bit(HCI_QUIRK_BROKEN_READ_ENC_KEY_SIZE, &hdev->quirks);
+- set_bit(HCI_QUIRK_BROKEN_EXT_CREATE_CONN, &hdev->quirks);
+- set_bit(HCI_QUIRK_BROKEN_WRITE_AUTH_PAYLOAD_TIMEOUT, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_ERR_DATA_REPORTING);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_SET_RPA_TIMEOUT);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_EXT_SCAN);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_READ_ENC_KEY_SIZE);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_EXT_CREATE_CONN);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_WRITE_AUTH_PAYLOAD_TIMEOUT);
+ }
+
+ if (!reset)
+- set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_RESET_ON_CLOSE);
+
+ if (force_scofix || id->driver_info & BTUSB_WRONG_SCO_MTU) {
+ if (!disable_scofix)
+- set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_FIXUP_BUFFER_SIZE);
+ }
+
+ if (id->driver_info & BTUSB_BROKEN_ISOC)
+ data->isoc = NULL;
+
+ if (id->driver_info & BTUSB_WIDEBAND_SPEECH)
+- set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED);
+
+ if (id->driver_info & BTUSB_INVALID_LE_STATES)
+- set_bit(HCI_QUIRK_BROKEN_LE_STATES, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_LE_STATES);
+
+ if (id->driver_info & BTUSB_DIGIANSWER) {
+ data->cmdreq_type = USB_TYPE_VENDOR;
+- set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_RESET_ON_CLOSE);
+ }
+
+ if (id->driver_info & BTUSB_CSR) {
+@@ -4112,10 +4112,10 @@ static int btusb_probe(struct usb_interface *intf,
+
+ /* Old firmware would otherwise execute USB reset */
+ if (bcdDevice < 0x117)
+- set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_RESET_ON_CLOSE);
+
+ /* This must be set first in case we disable it for fakes */
+- set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY);
+
+ /* Fake CSR devices with broken commands */
+ if (le16_to_cpu(udev->descriptor.idVendor) == 0x0a12 &&
+@@ -4128,7 +4128,7 @@ static int btusb_probe(struct usb_interface *intf,
+
+ /* New sniffer firmware has crippled HCI interface */
+ if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
+- set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_RAW_DEVICE);
+ }
+
+ if (id->driver_info & BTUSB_INTEL_BOOT) {
+diff --git a/drivers/bluetooth/hci_aml.c b/drivers/bluetooth/hci_aml.c
+index dc9541e76d819..ecdc61126c9b0 100644
+--- a/drivers/bluetooth/hci_aml.c
++++ b/drivers/bluetooth/hci_aml.c
+@@ -425,7 +425,7 @@ static int aml_check_bdaddr(struct hci_dev *hdev)
+
+ if (!bacmp(&paddr->bdaddr, AML_BDADDR_DEFAULT)) {
+ bt_dev_info(hdev, "amlbt using default bdaddr (%pM)", &paddr->bdaddr);
+- set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_INVALID_BDADDR);
+ }
+
+ exit:
+diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
+index 9684eb16059bb..f96617b85d877 100644
+--- a/drivers/bluetooth/hci_bcm.c
++++ b/drivers/bluetooth/hci_bcm.c
+@@ -643,8 +643,8 @@ static int bcm_setup(struct hci_uart *hu)
+ * Allow the bootloader to set a valid address through the
+ * device tree.
+ */
+- if (test_bit(HCI_QUIRK_INVALID_BDADDR, &hu->hdev->quirks))
+- set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hu->hdev->quirks);
++ if (hci_test_quirk(hu->hdev, HCI_QUIRK_INVALID_BDADDR))
++ hci_set_quirk(hu->hdev, HCI_QUIRK_USE_BDADDR_PROPERTY);
+
+ if (!bcm_request_irq(bcm))
+ err = bcm_setup_sleep(hu);
+diff --git a/drivers/bluetooth/hci_bcm4377.c b/drivers/bluetooth/hci_bcm4377.c
+index 9bce53e49cfa6..8a9aa33776b03 100644
+--- a/drivers/bluetooth/hci_bcm4377.c
++++ b/drivers/bluetooth/hci_bcm4377.c
+@@ -1435,7 +1435,7 @@ static int bcm4377_check_bdaddr(struct bcm4377_data *bcm4377)
+
+ bda = (struct hci_rp_read_bd_addr *)skb->data;
+ if (!bcm4377_is_valid_bdaddr(bcm4377, &bda->bdaddr))
+- set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &bcm4377->hdev->quirks);
++ hci_set_quirk(bcm4377->hdev, HCI_QUIRK_USE_BDADDR_PROPERTY);
+
+ kfree_skb(skb);
+ return 0;
+@@ -2389,13 +2389,13 @@ static int bcm4377_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ hdev->setup = bcm4377_hci_setup;
+
+ if (bcm4377->hw->broken_mws_transport_config)
+- set_bit(HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG);
+ if (bcm4377->hw->broken_ext_scan)
+- set_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_EXT_SCAN);
+ if (bcm4377->hw->broken_le_coded)
+- set_bit(HCI_QUIRK_BROKEN_LE_CODED, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_LE_CODED);
+ if (bcm4377->hw->broken_le_ext_adv_report_phy)
+- set_bit(HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY);
+
+ pci_set_drvdata(pdev, bcm4377);
+ hci_set_drvdata(hdev, bcm4377);
+diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c
+index 811f33701f847..d22fbb7f9fc5e 100644
+--- a/drivers/bluetooth/hci_intel.c
++++ b/drivers/bluetooth/hci_intel.c
+@@ -660,7 +660,7 @@ static int intel_setup(struct hci_uart *hu)
+ */
+ if (!bacmp(¶ms.otp_bdaddr, BDADDR_ANY)) {
+ bt_dev_info(hdev, "No device address configured");
+- set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_INVALID_BDADDR);
+ }
+
+ /* With this Intel bootloader only the hardware variant and device
+diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
+index acba83156de9a..d0adae3267b41 100644
+--- a/drivers/bluetooth/hci_ldisc.c
++++ b/drivers/bluetooth/hci_ldisc.c
+@@ -667,13 +667,13 @@ static int hci_uart_register_dev(struct hci_uart *hu)
+ SET_HCIDEV_DEV(hdev, hu->tty->dev);
+
+ if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags))
+- set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_RAW_DEVICE);
+
+ if (test_bit(HCI_UART_EXT_CONFIG, &hu->hdev_flags))
+- set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_EXTERNAL_CONFIG);
+
+ if (!test_bit(HCI_UART_RESET_ON_INIT, &hu->hdev_flags))
+- set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_RESET_ON_CLOSE);
+
+ /* Only call open() for the protocol after hdev is fully initialized as
+ * open() (or a timer/workqueue it starts) may attempt to reference it.
+diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
+index e19e9bd495556..7044c86325ced 100644
+--- a/drivers/bluetooth/hci_ll.c
++++ b/drivers/bluetooth/hci_ll.c
+@@ -649,11 +649,11 @@ static int ll_setup(struct hci_uart *hu)
+ /* This means that there was an error getting the BD address
+ * during probe, so mark the device as having a bad address.
+ */
+- set_bit(HCI_QUIRK_INVALID_BDADDR, &hu->hdev->quirks);
++ hci_set_quirk(hu->hdev, HCI_QUIRK_INVALID_BDADDR);
+ } else if (bacmp(&lldev->bdaddr, BDADDR_ANY)) {
+ err = ll_set_bdaddr(hu->hdev, &lldev->bdaddr);
+ if (err)
+- set_bit(HCI_QUIRK_INVALID_BDADDR, &hu->hdev->quirks);
++ hci_set_quirk(hu->hdev, HCI_QUIRK_INVALID_BDADDR);
+ }
+
+ /* Operational speed if any */
+diff --git a/drivers/bluetooth/hci_nokia.c b/drivers/bluetooth/hci_nokia.c
+index 9fc10a16fd962..cd7575c20f653 100644
+--- a/drivers/bluetooth/hci_nokia.c
++++ b/drivers/bluetooth/hci_nokia.c
+@@ -439,7 +439,7 @@ static int nokia_setup(struct hci_uart *hu)
+
+ if (btdev->man_id == NOKIA_ID_BCM2048) {
+ hu->hdev->set_bdaddr = btbcm_set_bdaddr;
+- set_bit(HCI_QUIRK_INVALID_BDADDR, &hu->hdev->quirks);
++ hci_set_quirk(hu->hdev, HCI_QUIRK_INVALID_BDADDR);
+ dev_dbg(dev, "bcm2048 has invalid bluetooth address!");
+ }
+
+diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
+index 976ec88a0f62a..4badab1e86a35 100644
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -1892,7 +1892,7 @@ static int qca_setup(struct hci_uart *hu)
+ /* Enable controller to do both LE scan and BR/EDR inquiry
+ * simultaneously.
+ */
+- set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY);
+
+ switch (soc_type) {
+ case QCA_QCA2066:
+@@ -1944,7 +1944,7 @@ static int qca_setup(struct hci_uart *hu)
+ case QCA_WCN7850:
+ qcadev = serdev_device_get_drvdata(hu->serdev);
+ if (qcadev->bdaddr_property_broken)
+- set_bit(HCI_QUIRK_BDADDR_PROPERTY_BROKEN, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_BDADDR_PROPERTY_BROKEN);
+
+ hci_set_aosp_capable(hdev);
+
+@@ -2487,7 +2487,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
+ hdev = qcadev->serdev_hu.hdev;
+
+ if (power_ctrl_enabled) {
+- set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_SETUP);
+ hdev->shutdown = qca_power_off;
+ }
+
+@@ -2496,11 +2496,11 @@ static int qca_serdev_probe(struct serdev_device *serdev)
+ * be queried via hci. Same with the valid le states quirk.
+ */
+ if (data->capabilities & QCA_CAP_WIDEBAND_SPEECH)
+- set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
+- &hdev->quirks);
++ hci_set_quirk(hdev,
++ HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED);
+
+ if (!(data->capabilities & QCA_CAP_VALID_LE_STATES))
+- set_bit(HCI_QUIRK_BROKEN_LE_STATES, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_BROKEN_LE_STATES);
+ }
+
+ return 0;
+@@ -2550,7 +2550,7 @@ static void qca_serdev_shutdown(struct device *dev)
+ * invoked and the SOC is already in the initial state, so
+ * don't also need to send the VSC.
+ */
+- if (test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks) ||
++ if (hci_test_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_SETUP) ||
+ hci_dev_test_flag(hdev, HCI_SETUP))
+ return;
+
+diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c
+index 89a22e9b3253a..593d9cefbbf92 100644
+--- a/drivers/bluetooth/hci_serdev.c
++++ b/drivers/bluetooth/hci_serdev.c
+@@ -152,7 +152,7 @@ static int hci_uart_close(struct hci_dev *hdev)
+ * BT SOC is completely powered OFF during BT OFF, holding port
+ * open may drain the battery.
+ */
+- if (test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks)) {
++ if (hci_test_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_SETUP)) {
+ clear_bit(HCI_UART_PROTO_READY, &hu->flags);
+ serdev_device_close(hu->serdev);
+ }
+@@ -358,13 +358,13 @@ int hci_uart_register_device_priv(struct hci_uart *hu,
+ SET_HCIDEV_DEV(hdev, &hu->serdev->dev);
+
+ if (test_bit(HCI_UART_NO_SUSPEND_NOTIFIER, &hu->flags))
+- set_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_NO_SUSPEND_NOTIFIER);
+
+ if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags))
+- set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_RAW_DEVICE);
+
+ if (test_bit(HCI_UART_EXT_CONFIG, &hu->hdev_flags))
+- set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_EXTERNAL_CONFIG);
+
+ if (test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags))
+ return 0;
+diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
+index 59f4d7bdffdcb..f7d8c3c00655a 100644
+--- a/drivers/bluetooth/hci_vhci.c
++++ b/drivers/bluetooth/hci_vhci.c
+@@ -415,16 +415,16 @@ static int __vhci_create_device(struct vhci_data *data, __u8 opcode)
+ hdev->get_codec_config_data = vhci_get_codec_config_data;
+ hdev->wakeup = vhci_wakeup;
+ hdev->setup = vhci_setup;
+- set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
+- set_bit(HCI_QUIRK_SYNC_FLOWCTL_SUPPORTED, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_SETUP);
++ hci_set_quirk(hdev, HCI_QUIRK_SYNC_FLOWCTL_SUPPORTED);
+
+ /* bit 6 is for external configuration */
+ if (opcode & 0x40)
+- set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_EXTERNAL_CONFIG);
+
+ /* bit 7 is for raw device */
+ if (opcode & 0x80)
+- set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_RAW_DEVICE);
+
+ if (hci_register_dev(hdev) < 0) {
+ BT_ERR("Can't register HCI device");
+diff --git a/drivers/bluetooth/virtio_bt.c b/drivers/bluetooth/virtio_bt.c
+index 756f292df9e87..6f1a37e85c6a4 100644
+--- a/drivers/bluetooth/virtio_bt.c
++++ b/drivers/bluetooth/virtio_bt.c
+@@ -327,17 +327,17 @@ static int virtbt_probe(struct virtio_device *vdev)
+ hdev->setup = virtbt_setup_intel;
+ hdev->shutdown = virtbt_shutdown_generic;
+ hdev->set_bdaddr = virtbt_set_bdaddr_intel;
+- set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
+- set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
+- set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_STRICT_DUPLICATE_FILTER);
++ hci_set_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY);
++ hci_set_quirk(hdev, HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED);
+ break;
+
+ case VIRTIO_BT_CONFIG_VENDOR_REALTEK:
+ hdev->manufacturer = 93;
+ hdev->setup = virtbt_setup_realtek;
+ hdev->shutdown = virtbt_shutdown_generic;
+- set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
+- set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
++ hci_set_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY);
++ hci_set_quirk(hdev, HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED);
+ break;
+ }
+ }
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index 521a9d0acac69..f47dfb8b5be79 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -377,6 +377,8 @@ enum {
+ * This quirk must be set before hci_register_dev is called.
+ */
+ HCI_QUIRK_BROKEN_READ_PAGE_SCAN_TYPE,
++
++ __HCI_NUM_QUIRKS,
+ };
+
+ /* HCI device flags */
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index f7f7e1974dddb..d22468bb4341c 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -462,7 +462,7 @@ struct hci_dev {
+
+ unsigned int auto_accept_delay;
+
+- unsigned long quirks;
++ DECLARE_BITMAP(quirk_flags, __HCI_NUM_QUIRKS);
+
+ atomic_t cmd_cnt;
+ unsigned int acl_cnt;
+@@ -652,6 +652,10 @@ struct hci_dev {
+ u8 (*classify_pkt_type)(struct hci_dev *hdev, struct sk_buff *skb);
+ };
+
++#define hci_set_quirk(hdev, nr) set_bit((nr), (hdev)->quirk_flags)
++#define hci_clear_quirk(hdev, nr) clear_bit((nr), (hdev)->quirk_flags)
++#define hci_test_quirk(hdev, nr) test_bit((nr), (hdev)->quirk_flags)
++
+ #define HCI_PHY_HANDLE(handle) (handle & 0xff)
+
+ enum conn_reasons {
+@@ -835,7 +839,7 @@ extern struct mutex hci_cb_list_lock;
+ } while (0)
+
+ #define hci_dev_le_state_simultaneous(hdev) \
+- (!test_bit(HCI_QUIRK_BROKEN_LE_STATES, &(hdev)->quirks) && \
++ (!hci_test_quirk((hdev), HCI_QUIRK_BROKEN_LE_STATES) && \
+ ((hdev)->le_states[4] & 0x08) && /* Central */ \
+ ((hdev)->le_states[4] & 0x40) && /* Peripheral */ \
+ ((hdev)->le_states[3] & 0x10)) /* Simultaneous */
+@@ -1925,8 +1929,8 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
+ ((dev)->le_rx_def_phys & HCI_LE_SET_PHY_2M))
+
+ #define le_coded_capable(dev) (((dev)->le_features[1] & HCI_LE_PHY_CODED) && \
+- !test_bit(HCI_QUIRK_BROKEN_LE_CODED, \
+- &(dev)->quirks))
++ !hci_test_quirk((dev), \
++ HCI_QUIRK_BROKEN_LE_CODED))
+
+ #define scan_coded(dev) (((dev)->le_tx_def_phys & HCI_LE_SET_PHY_CODED) || \
+ ((dev)->le_rx_def_phys & HCI_LE_SET_PHY_CODED))
+@@ -1938,27 +1942,27 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
+
+ #define read_key_size_capable(dev) \
+ ((dev)->commands[20] & 0x10 && \
+- !test_bit(HCI_QUIRK_BROKEN_READ_ENC_KEY_SIZE, &(dev)->quirks))
++ !hci_test_quirk((dev), HCI_QUIRK_BROKEN_READ_ENC_KEY_SIZE))
+
+ #define read_voice_setting_capable(dev) \
+ ((dev)->commands[9] & 0x04 && \
+- !test_bit(HCI_QUIRK_BROKEN_READ_VOICE_SETTING, &(dev)->quirks))
++ !hci_test_quirk((dev), HCI_QUIRK_BROKEN_READ_VOICE_SETTING))
+
+ /* Use enhanced synchronous connection if command is supported and its quirk
+ * has not been set.
+ */
+ #define enhanced_sync_conn_capable(dev) \
+ (((dev)->commands[29] & 0x08) && \
+- !test_bit(HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN, &(dev)->quirks))
++ !hci_test_quirk((dev), HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN))
+
+ /* Use ext scanning if set ext scan param and ext scan enable is supported */
+ #define use_ext_scan(dev) (((dev)->commands[37] & 0x20) && \
+ ((dev)->commands[37] & 0x40) && \
+- !test_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &(dev)->quirks))
++ !hci_test_quirk((dev), HCI_QUIRK_BROKEN_EXT_SCAN))
+
+ /* Use ext create connection if command is supported */
+ #define use_ext_conn(dev) (((dev)->commands[37] & 0x80) && \
+- !test_bit(HCI_QUIRK_BROKEN_EXT_CREATE_CONN, &(dev)->quirks))
++ !hci_test_quirk((dev), HCI_QUIRK_BROKEN_EXT_CREATE_CONN))
+ /* Extended advertising support */
+ #define ext_adv_capable(dev) (((dev)->le_features[1] & HCI_LE_EXT_ADV))
+
+@@ -1973,8 +1977,8 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
+ */
+ #define use_enhanced_conn_complete(dev) ((ll_privacy_capable(dev) || \
+ ext_adv_capable(dev)) && \
+- !test_bit(HCI_QUIRK_BROKEN_EXT_CREATE_CONN, \
+- &(dev)->quirks))
++ !hci_test_quirk((dev), \
++ HCI_QUIRK_BROKEN_EXT_CREATE_CONN))
+
+ /* Periodic advertising support */
+ #define per_adv_capable(dev) (((dev)->le_features[1] & HCI_LE_PERIODIC_ADV))
+@@ -1991,7 +1995,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
+ #define sync_recv_capable(dev) ((dev)->le_features[3] & HCI_LE_ISO_SYNC_RECEIVER)
+
+ #define mws_transport_config_capable(dev) (((dev)->commands[30] & 0x08) && \
+- (!test_bit(HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG, &(dev)->quirks)))
++ (!hci_test_quirk((dev), HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG)))
+
+ /* ----- HCI protocols ----- */
+ #define HCI_PROTO_DEFER 0x01
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index abff4690cb88f..2f209e4421d7b 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -2640,7 +2640,7 @@ int hci_register_dev(struct hci_dev *hdev)
+ /* Devices that are marked for raw-only usage are unconfigured
+ * and should not be included in normal operation.
+ */
+- if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
++ if (hci_test_quirk(hdev, HCI_QUIRK_RAW_DEVICE))
+ hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
+
+ /* Mark Remote Wakeup connection flag as supported if driver has wakeup
+@@ -2770,7 +2770,7 @@ int hci_register_suspend_notifier(struct hci_dev *hdev)
+ int ret = 0;
+
+ if (!hdev->suspend_notifier.notifier_call &&
+- !test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
++ !hci_test_quirk(hdev, HCI_QUIRK_NO_SUSPEND_NOTIFIER)) {
+ hdev->suspend_notifier.notifier_call = hci_suspend_notifier;
+ ret = register_pm_notifier(&hdev->suspend_notifier);
+ }
+diff --git a/net/bluetooth/hci_debugfs.c b/net/bluetooth/hci_debugfs.c
+index f625074d1f002..99e2e9fc70e8c 100644
+--- a/net/bluetooth/hci_debugfs.c
++++ b/net/bluetooth/hci_debugfs.c
+@@ -38,7 +38,7 @@ static ssize_t __name ## _read(struct file *file, \
+ struct hci_dev *hdev = file->private_data; \
+ char buf[3]; \
+ \
+- buf[0] = test_bit(__quirk, &hdev->quirks) ? 'Y' : 'N'; \
++ buf[0] = test_bit(__quirk, hdev->quirk_flags) ? 'Y' : 'N'; \
+ buf[1] = '\n'; \
+ buf[2] = '\0'; \
+ return simple_read_from_buffer(user_buf, count, ppos, buf, 2); \
+@@ -59,10 +59,10 @@ static ssize_t __name ## _write(struct file *file, \
+ if (err) \
+ return err; \
+ \
+- if (enable == test_bit(__quirk, &hdev->quirks)) \
++ if (enable == test_bit(__quirk, hdev->quirk_flags)) \
+ return -EALREADY; \
+ \
+- change_bit(__quirk, &hdev->quirks); \
++ change_bit(__quirk, hdev->quirk_flags); \
+ \
+ return count; \
+ } \
+@@ -1356,7 +1356,7 @@ static ssize_t vendor_diag_write(struct file *file, const char __user *user_buf,
+ * for the vendor callback. Instead just store the desired value and
+ * the setting will be programmed when the controller gets powered on.
+ */
+- if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) &&
++ if (hci_test_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_DIAG) &&
+ (!test_bit(HCI_RUNNING, &hdev->flags) ||
+ hci_dev_test_flag(hdev, HCI_USER_CHANNEL)))
+ goto done;
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 992131f88a456..cf4b30ac9e0e5 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -908,8 +908,8 @@ static u8 hci_cc_read_local_ext_features(struct hci_dev *hdev, void *data,
+ return rp->status;
+
+ if (hdev->max_page < rp->max_page) {
+- if (test_bit(HCI_QUIRK_BROKEN_LOCAL_EXT_FEATURES_PAGE_2,
+- &hdev->quirks))
++ if (hci_test_quirk(hdev,
++ HCI_QUIRK_BROKEN_LOCAL_EXT_FEATURES_PAGE_2))
+ bt_dev_warn(hdev, "broken local ext features page 2");
+ else
+ hdev->max_page = rp->max_page;
+@@ -936,7 +936,7 @@ static u8 hci_cc_read_buffer_size(struct hci_dev *hdev, void *data,
+ hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
+ hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
+
+- if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
++ if (hci_test_quirk(hdev, HCI_QUIRK_FIXUP_BUFFER_SIZE)) {
+ hdev->sco_mtu = 64;
+ hdev->sco_pkts = 8;
+ }
+@@ -2971,7 +2971,7 @@ static void hci_inquiry_complete_evt(struct hci_dev *hdev, void *data,
+ * state to indicate completion.
+ */
+ if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
+- !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks))
++ !hci_test_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY))
+ hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+ goto unlock;
+ }
+@@ -2990,7 +2990,7 @@ static void hci_inquiry_complete_evt(struct hci_dev *hdev, void *data,
+ * state to indicate completion.
+ */
+ if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
+- !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks))
++ !hci_test_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY))
+ hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+ }
+
+@@ -3614,8 +3614,7 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data,
+ /* We skip the WRITE_AUTH_PAYLOAD_TIMEOUT for ATS2851 based controllers
+ * to avoid unexpected SMP command errors when pairing.
+ */
+- if (test_bit(HCI_QUIRK_BROKEN_WRITE_AUTH_PAYLOAD_TIMEOUT,
+- &hdev->quirks))
++ if (hci_test_quirk(hdev, HCI_QUIRK_BROKEN_WRITE_AUTH_PAYLOAD_TIMEOUT))
+ goto notify;
+
+ /* Set the default Authenticated Payload Timeout after
+@@ -5914,7 +5913,7 @@ static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
+ * while we have an existing one in peripheral role.
+ */
+ if (hdev->conn_hash.le_num_peripheral > 0 &&
+- (test_bit(HCI_QUIRK_BROKEN_LE_STATES, &hdev->quirks) ||
++ (hci_test_quirk(hdev, HCI_QUIRK_BROKEN_LE_STATES) ||
+ !(hdev->le_states[3] & 0x10)))
+ return NULL;
+
+@@ -6310,8 +6309,8 @@ static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, void *data,
+ evt_type = __le16_to_cpu(info->type) & LE_EXT_ADV_EVT_TYPE_MASK;
+ legacy_evt_type = ext_evt_type_to_legacy(hdev, evt_type);
+
+- if (test_bit(HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY,
+- &hdev->quirks)) {
++ if (hci_test_quirk(hdev,
++ HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY)) {
+ info->primary_phy &= 0x1f;
+ info->secondary_phy &= 0x1f;
+ }
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 5b3211e7530a5..0972167c1d062 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -393,7 +393,7 @@ static void le_scan_disable(struct work_struct *work)
+ if (hdev->discovery.type != DISCOV_TYPE_INTERLEAVED)
+ goto _return;
+
+- if (test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks)) {
++ if (hci_test_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY)) {
+ if (!test_bit(HCI_INQUIRY, &hdev->flags) &&
+ hdev->discovery.state != DISCOVERY_RESOLVING)
+ goto discov_stopped;
+@@ -3573,7 +3573,7 @@ static void hci_dev_get_bd_addr_from_property(struct hci_dev *hdev)
+ if (ret < 0 || !bacmp(&ba, BDADDR_ANY))
+ return;
+
+- if (test_bit(HCI_QUIRK_BDADDR_PROPERTY_BROKEN, &hdev->quirks))
++ if (hci_test_quirk(hdev, HCI_QUIRK_BDADDR_PROPERTY_BROKEN))
+ baswap(&hdev->public_addr, &ba);
+ else
+ bacpy(&hdev->public_addr, &ba);
+@@ -3648,7 +3648,7 @@ static int hci_init0_sync(struct hci_dev *hdev)
+ bt_dev_dbg(hdev, "");
+
+ /* Reset */
+- if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
++ if (!hci_test_quirk(hdev, HCI_QUIRK_RESET_ON_CLOSE)) {
+ err = hci_reset_sync(hdev);
+ if (err)
+ return err;
+@@ -3661,7 +3661,7 @@ static int hci_unconf_init_sync(struct hci_dev *hdev)
+ {
+ int err;
+
+- if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
++ if (hci_test_quirk(hdev, HCI_QUIRK_RAW_DEVICE))
+ return 0;
+
+ err = hci_init0_sync(hdev);
+@@ -3704,7 +3704,7 @@ static int hci_read_local_cmds_sync(struct hci_dev *hdev)
+ * supported commands.
+ */
+ if (hdev->hci_ver > BLUETOOTH_VER_1_1 &&
+- !test_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks))
++ !hci_test_quirk(hdev, HCI_QUIRK_BROKEN_LOCAL_COMMANDS))
+ return __hci_cmd_sync_status(hdev, HCI_OP_READ_LOCAL_COMMANDS,
+ 0, NULL, HCI_CMD_TIMEOUT);
+
+@@ -3718,7 +3718,7 @@ static int hci_init1_sync(struct hci_dev *hdev)
+ bt_dev_dbg(hdev, "");
+
+ /* Reset */
+- if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
++ if (!hci_test_quirk(hdev, HCI_QUIRK_RESET_ON_CLOSE)) {
+ err = hci_reset_sync(hdev);
+ if (err)
+ return err;
+@@ -3781,7 +3781,7 @@ static int hci_set_event_filter_sync(struct hci_dev *hdev, u8 flt_type,
+ if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
+ return 0;
+
+- if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
++ if (hci_test_quirk(hdev, HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL))
+ return 0;
+
+ memset(&cp, 0, sizeof(cp));
+@@ -3808,7 +3808,7 @@ static int hci_clear_event_filter_sync(struct hci_dev *hdev)
+ * a hci_set_event_filter_sync() call succeeds, but we do
+ * the check both for parity and as a future reminder.
+ */
+- if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
++ if (hci_test_quirk(hdev, HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL))
+ return 0;
+
+ return hci_set_event_filter_sync(hdev, HCI_FLT_CLEAR_ALL, 0x00,
+@@ -3832,7 +3832,7 @@ static int hci_write_sync_flowctl_sync(struct hci_dev *hdev)
+
+ /* Check if the controller supports SCO and HCI_OP_WRITE_SYNC_FLOWCTL */
+ if (!lmp_sco_capable(hdev) || !(hdev->commands[10] & BIT(4)) ||
+- !test_bit(HCI_QUIRK_SYNC_FLOWCTL_SUPPORTED, &hdev->quirks))
++ !hci_test_quirk(hdev, HCI_QUIRK_SYNC_FLOWCTL_SUPPORTED))
+ return 0;
+
+ memset(&cp, 0, sizeof(cp));
+@@ -3907,7 +3907,7 @@ static int hci_write_inquiry_mode_sync(struct hci_dev *hdev)
+ u8 mode;
+
+ if (!lmp_inq_rssi_capable(hdev) &&
+- !test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks))
++ !hci_test_quirk(hdev, HCI_QUIRK_FIXUP_INQUIRY_MODE))
+ return 0;
+
+ /* If Extended Inquiry Result events are supported, then
+@@ -4097,7 +4097,7 @@ static int hci_set_event_mask_sync(struct hci_dev *hdev)
+ }
+
+ if (lmp_inq_rssi_capable(hdev) ||
+- test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks))
++ hci_test_quirk(hdev, HCI_QUIRK_FIXUP_INQUIRY_MODE))
+ events[4] |= 0x02; /* Inquiry Result with RSSI */
+
+ if (lmp_ext_feat_capable(hdev))
+@@ -4149,7 +4149,7 @@ static int hci_read_stored_link_key_sync(struct hci_dev *hdev)
+ struct hci_cp_read_stored_link_key cp;
+
+ if (!(hdev->commands[6] & 0x20) ||
+- test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks))
++ hci_test_quirk(hdev, HCI_QUIRK_BROKEN_STORED_LINK_KEY))
+ return 0;
+
+ memset(&cp, 0, sizeof(cp));
+@@ -4198,7 +4198,7 @@ static int hci_read_def_err_data_reporting_sync(struct hci_dev *hdev)
+ {
+ if (!(hdev->commands[18] & 0x04) ||
+ !(hdev->features[0][6] & LMP_ERR_DATA_REPORTING) ||
+- test_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks))
++ hci_test_quirk(hdev, HCI_QUIRK_BROKEN_ERR_DATA_REPORTING))
+ return 0;
+
+ return __hci_cmd_sync_status(hdev, HCI_OP_READ_DEF_ERR_DATA_REPORTING,
+@@ -4212,7 +4212,7 @@ static int hci_read_page_scan_type_sync(struct hci_dev *hdev)
+ * this command in the bit mask of supported commands.
+ */
+ if (!(hdev->commands[13] & 0x01) ||
+- test_bit(HCI_QUIRK_BROKEN_READ_PAGE_SCAN_TYPE, &hdev->quirks))
++ hci_test_quirk(hdev, HCI_QUIRK_BROKEN_READ_PAGE_SCAN_TYPE))
+ return 0;
+
+ return __hci_cmd_sync_status(hdev, HCI_OP_READ_PAGE_SCAN_TYPE,
+@@ -4407,7 +4407,7 @@ static int hci_le_read_adv_tx_power_sync(struct hci_dev *hdev)
+ static int hci_le_read_tx_power_sync(struct hci_dev *hdev)
+ {
+ if (!(hdev->commands[38] & 0x80) ||
+- test_bit(HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER, &hdev->quirks))
++ hci_test_quirk(hdev, HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER))
+ return 0;
+
+ return __hci_cmd_sync_status(hdev, HCI_OP_LE_READ_TRANSMIT_POWER,
+@@ -4450,7 +4450,7 @@ static int hci_le_set_rpa_timeout_sync(struct hci_dev *hdev)
+ __le16 timeout = cpu_to_le16(hdev->rpa_timeout);
+
+ if (!(hdev->commands[35] & 0x04) ||
+- test_bit(HCI_QUIRK_BROKEN_SET_RPA_TIMEOUT, &hdev->quirks))
++ hci_test_quirk(hdev, HCI_QUIRK_BROKEN_SET_RPA_TIMEOUT))
+ return 0;
+
+ return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_RPA_TIMEOUT,
+@@ -4595,7 +4595,7 @@ static int hci_delete_stored_link_key_sync(struct hci_dev *hdev)
+ * just disable this command.
+ */
+ if (!(hdev->commands[6] & 0x80) ||
+- test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks))
++ hci_test_quirk(hdev, HCI_QUIRK_BROKEN_STORED_LINK_KEY))
+ return 0;
+
+ memset(&cp, 0, sizeof(cp));
+@@ -4721,7 +4721,7 @@ static int hci_set_err_data_report_sync(struct hci_dev *hdev)
+
+ if (!(hdev->commands[18] & 0x08) ||
+ !(hdev->features[0][6] & LMP_ERR_DATA_REPORTING) ||
+- test_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks))
++ hci_test_quirk(hdev, HCI_QUIRK_BROKEN_ERR_DATA_REPORTING))
+ return 0;
+
+ if (enabled == hdev->err_data_reporting)
+@@ -4934,7 +4934,7 @@ static int hci_dev_setup_sync(struct hci_dev *hdev)
+ size_t i;
+
+ if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
+- !test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks))
++ !hci_test_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_SETUP))
+ return 0;
+
+ bt_dev_dbg(hdev, "");
+@@ -4945,7 +4945,7 @@ static int hci_dev_setup_sync(struct hci_dev *hdev)
+ ret = hdev->setup(hdev);
+
+ for (i = 0; i < ARRAY_SIZE(hci_broken_table); i++) {
+- if (test_bit(hci_broken_table[i].quirk, &hdev->quirks))
++ if (hci_test_quirk(hdev, hci_broken_table[i].quirk))
+ bt_dev_warn(hdev, "%s", hci_broken_table[i].desc);
+ }
+
+@@ -4953,10 +4953,10 @@ static int hci_dev_setup_sync(struct hci_dev *hdev)
+ * BD_ADDR invalid before creating the HCI device or in
+ * its setup callback.
+ */
+- invalid_bdaddr = test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks) ||
+- test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
++ invalid_bdaddr = hci_test_quirk(hdev, HCI_QUIRK_INVALID_BDADDR) ||
++ hci_test_quirk(hdev, HCI_QUIRK_USE_BDADDR_PROPERTY);
+ if (!ret) {
+- if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks) &&
++ if (hci_test_quirk(hdev, HCI_QUIRK_USE_BDADDR_PROPERTY) &&
+ !bacmp(&hdev->public_addr, BDADDR_ANY))
+ hci_dev_get_bd_addr_from_property(hdev);
+
+@@ -4978,7 +4978,7 @@ static int hci_dev_setup_sync(struct hci_dev *hdev)
+ * In case any of them is set, the controller has to
+ * start up as unconfigured.
+ */
+- if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
++ if (hci_test_quirk(hdev, HCI_QUIRK_EXTERNAL_CONFIG) ||
+ invalid_bdaddr)
+ hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
+
+@@ -5038,7 +5038,7 @@ static int hci_dev_init_sync(struct hci_dev *hdev)
+ * then they need to be reprogrammed after the init procedure
+ * completed.
+ */
+- if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) &&
++ if (hci_test_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_DIAG) &&
+ !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
+ hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag)
+ ret = hdev->set_diag(hdev, true);
+@@ -5295,7 +5295,7 @@ int hci_dev_close_sync(struct hci_dev *hdev)
+ /* Reset device */
+ skb_queue_purge(&hdev->cmd_q);
+ atomic_set(&hdev->cmd_cnt, 1);
+- if (test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks) &&
++ if (hci_test_quirk(hdev, HCI_QUIRK_RESET_ON_CLOSE) &&
+ !auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
+ set_bit(HCI_INIT, &hdev->flags);
+ hci_reset_sync(hdev);
+@@ -5945,7 +5945,7 @@ static int hci_active_scan_sync(struct hci_dev *hdev, uint16_t interval)
+ own_addr_type = ADDR_LE_DEV_PUBLIC;
+
+ if (hci_is_adv_monitoring(hdev) ||
+- (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks) &&
++ (hci_test_quirk(hdev, HCI_QUIRK_STRICT_DUPLICATE_FILTER) &&
+ hdev->discovery.result_filtering)) {
+ /* Duplicate filter should be disabled when some advertisement
+ * monitor is activated, otherwise AdvMon can only receive one
+@@ -6008,8 +6008,7 @@ int hci_start_discovery_sync(struct hci_dev *hdev)
+ * and LE scanning are done sequentially with separate
+ * timeouts.
+ */
+- if (test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY,
+- &hdev->quirks)) {
++ if (hci_test_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY)) {
+ timeout = msecs_to_jiffies(DISCOV_LE_TIMEOUT);
+ /* During simultaneous discovery, we double LE scan
+ * interval. We must leave some time for the controller
+@@ -6086,7 +6085,7 @@ static int hci_update_event_filter_sync(struct hci_dev *hdev)
+ /* Some fake CSR controllers lock up after setting this type of
+ * filter, so avoid sending the request altogether.
+ */
+- if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
++ if (hci_test_quirk(hdev, HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL))
+ return 0;
+
+ /* Always clear event filter when starting */
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 1485b455ade46..63dba0503653b 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -464,7 +464,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
+ /* Devices marked as raw-only are neither configured
+ * nor unconfigured controllers.
+ */
+- if (test_bit(HCI_QUIRK_RAW_DEVICE, &d->quirks))
++ if (hci_test_quirk(d, HCI_QUIRK_RAW_DEVICE))
+ continue;
+
+ if (!hci_dev_test_flag(d, HCI_UNCONFIGURED)) {
+@@ -522,7 +522,7 @@ static int read_unconf_index_list(struct sock *sk, struct hci_dev *hdev,
+ /* Devices marked as raw-only are neither configured
+ * nor unconfigured controllers.
+ */
+- if (test_bit(HCI_QUIRK_RAW_DEVICE, &d->quirks))
++ if (hci_test_quirk(d, HCI_QUIRK_RAW_DEVICE))
+ continue;
+
+ if (hci_dev_test_flag(d, HCI_UNCONFIGURED)) {
+@@ -576,7 +576,7 @@ static int read_ext_index_list(struct sock *sk, struct hci_dev *hdev,
+ /* Devices marked as raw-only are neither configured
+ * nor unconfigured controllers.
+ */
+- if (test_bit(HCI_QUIRK_RAW_DEVICE, &d->quirks))
++ if (hci_test_quirk(d, HCI_QUIRK_RAW_DEVICE))
+ continue;
+
+ if (hci_dev_test_flag(d, HCI_UNCONFIGURED))
+@@ -612,12 +612,12 @@ static int read_ext_index_list(struct sock *sk, struct hci_dev *hdev,
+
+ static bool is_configured(struct hci_dev *hdev)
+ {
+- if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) &&
++ if (hci_test_quirk(hdev, HCI_QUIRK_EXTERNAL_CONFIG) &&
+ !hci_dev_test_flag(hdev, HCI_EXT_CONFIGURED))
+ return false;
+
+- if ((test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks) ||
+- test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks)) &&
++ if ((hci_test_quirk(hdev, HCI_QUIRK_INVALID_BDADDR) ||
++ hci_test_quirk(hdev, HCI_QUIRK_USE_BDADDR_PROPERTY)) &&
+ !bacmp(&hdev->public_addr, BDADDR_ANY))
+ return false;
+
+@@ -628,12 +628,12 @@ static __le32 get_missing_options(struct hci_dev *hdev)
+ {
+ u32 options = 0;
+
+- if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) &&
++ if (hci_test_quirk(hdev, HCI_QUIRK_EXTERNAL_CONFIG) &&
+ !hci_dev_test_flag(hdev, HCI_EXT_CONFIGURED))
+ options |= MGMT_OPTION_EXTERNAL_CONFIG;
+
+- if ((test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks) ||
+- test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks)) &&
++ if ((hci_test_quirk(hdev, HCI_QUIRK_INVALID_BDADDR) ||
++ hci_test_quirk(hdev, HCI_QUIRK_USE_BDADDR_PROPERTY)) &&
+ !bacmp(&hdev->public_addr, BDADDR_ANY))
+ options |= MGMT_OPTION_PUBLIC_ADDRESS;
+
+@@ -669,7 +669,7 @@ static int read_config_info(struct sock *sk, struct hci_dev *hdev,
+ memset(&rp, 0, sizeof(rp));
+ rp.manufacturer = cpu_to_le16(hdev->manufacturer);
+
+- if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks))
++ if (hci_test_quirk(hdev, HCI_QUIRK_EXTERNAL_CONFIG))
+ options |= MGMT_OPTION_EXTERNAL_CONFIG;
+
+ if (hdev->set_bdaddr)
+@@ -828,8 +828,7 @@ static u32 get_supported_settings(struct hci_dev *hdev)
+ if (lmp_sc_capable(hdev))
+ settings |= MGMT_SETTING_SECURE_CONN;
+
+- if (test_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
+- &hdev->quirks))
++ if (hci_test_quirk(hdev, HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED))
+ settings |= MGMT_SETTING_WIDEBAND_SPEECH;
+ }
+
+@@ -841,8 +840,7 @@ static u32 get_supported_settings(struct hci_dev *hdev)
+ settings |= MGMT_SETTING_ADVERTISING;
+ }
+
+- if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
+- hdev->set_bdaddr)
++ if (hci_test_quirk(hdev, HCI_QUIRK_EXTERNAL_CONFIG) || hdev->set_bdaddr)
+ settings |= MGMT_SETTING_CONFIGURATION;
+
+ if (cis_central_capable(hdev))
+@@ -4307,7 +4305,7 @@ static int set_wideband_speech(struct sock *sk, struct hci_dev *hdev,
+
+ bt_dev_dbg(hdev, "sock %p", sk);
+
+- if (!test_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks))
++ if (!hci_test_quirk(hdev, HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED))
+ return mgmt_cmd_status(sk, hdev->id,
+ MGMT_OP_SET_WIDEBAND_SPEECH,
+ MGMT_STATUS_NOT_SUPPORTED);
+@@ -7935,7 +7933,7 @@ static int set_external_config(struct sock *sk, struct hci_dev *hdev,
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG,
+ MGMT_STATUS_INVALID_PARAMS);
+
+- if (!test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks))
++ if (!hci_test_quirk(hdev, HCI_QUIRK_EXTERNAL_CONFIG))
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG,
+ MGMT_STATUS_NOT_SUPPORTED);
+
+@@ -9338,7 +9336,7 @@ void mgmt_index_added(struct hci_dev *hdev)
+ {
+ struct mgmt_ev_ext_index ev;
+
+- if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
++ if (hci_test_quirk(hdev, HCI_QUIRK_RAW_DEVICE))
+ return;
+
+ if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
+@@ -9362,7 +9360,7 @@ void mgmt_index_removed(struct hci_dev *hdev)
+ struct mgmt_ev_ext_index ev;
+ struct cmd_lookup match = { NULL, hdev, MGMT_STATUS_INVALID_INDEX };
+
+- if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
++ if (hci_test_quirk(hdev, HCI_QUIRK_RAW_DEVICE))
+ return;
+
+ mgmt_pending_foreach(0, hdev, true, cmd_complete_rsp, &match);
+@@ -10089,7 +10087,7 @@ static bool is_filter_match(struct hci_dev *hdev, s8 rssi, u8 *eir,
+ if (hdev->discovery.rssi != HCI_RSSI_INVALID &&
+ (rssi == HCI_RSSI_INVALID ||
+ (rssi < hdev->discovery.rssi &&
+- !test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks))))
++ !hci_test_quirk(hdev, HCI_QUIRK_STRICT_DUPLICATE_FILTER))))
+ return false;
+
+ if (hdev->discovery.uuid_count != 0) {
+@@ -10107,7 +10105,7 @@ static bool is_filter_match(struct hci_dev *hdev, s8 rssi, u8 *eir,
+ /* If duplicate filtering does not report RSSI changes, then restart
+ * scanning to ensure updated result with updated RSSI values.
+ */
+- if (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks)) {
++ if (hci_test_quirk(hdev, HCI_QUIRK_STRICT_DUPLICATE_FILTER)) {
+ /* Validate RSSI value against the RSSI threshold once more. */
+ if (hdev->discovery.rssi != HCI_RSSI_INVALID &&
+ rssi < hdev->discovery.rssi)
+diff --git a/net/bluetooth/msft.c b/net/bluetooth/msft.c
+index 5a8ccc491b144..c560d84676696 100644
+--- a/net/bluetooth/msft.c
++++ b/net/bluetooth/msft.c
+@@ -989,7 +989,7 @@ static void msft_monitor_device_evt(struct hci_dev *hdev, struct sk_buff *skb)
+
+ handle_data = msft_find_handle_data(hdev, ev->monitor_handle, false);
+
+- if (!test_bit(HCI_QUIRK_USE_MSFT_EXT_ADDRESS_FILTER, &hdev->quirks)) {
++ if (!hci_test_quirk(hdev, HCI_QUIRK_USE_MSFT_EXT_ADDRESS_FILTER)) {
+ if (!handle_data)
+ return;
+ mgmt_handle = handle_data->mgmt_handle;
+--
+2.39.5
+
--- /dev/null
+From 0ec8faa7ae9537216f4c2e5a69a9e0c8497f9b5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Jul 2025 09:53:11 +0200
+Subject: Bluetooth: hci_sync: fix connectable extended advertising when using
+ static random address
+
+From: Alessandro Gasbarroni <alex.gasbarroni@gmail.com>
+
+[ Upstream commit d85edab911a4c1fcbe3f08336eff5c7feec567d0 ]
+
+Currently, the connectable flag used by the setup of an extended
+advertising instance drives whether we require privacy when trying to pass
+a random address to the advertising parameters (Own Address).
+If privacy is not required, then it automatically falls back to using the
+controller's public address. This can cause problems when using controllers
+that do not have a public address set, but instead use a static random
+address.
+
+e.g. Assume a BLE controller that does not have a public address set.
+The controller upon powering is set with a random static address by default
+by the kernel.
+
+ < HCI Command: LE Set Random Address (0x08|0x0005) plen 6
+ Address: E4:AF:26:D8:3E:3A (Static)
+ > HCI Event: Command Complete (0x0e) plen 4
+ LE Set Random Address (0x08|0x0005) ncmd 1
+ Status: Success (0x00)
+
+Setting non-connectable extended advertisement parameters in bluetoothctl
+mgmt
+
+ add-ext-adv-params -r 0x801 -x 0x802 -P 2M -g 1
+
+correctly sets Own address type as Random
+
+ < HCI Command: LE Set Extended Advertising Parameters (0x08|0x0036)
+ plen 25
+ ...
+ Own address type: Random (0x01)
+
+Setting connectable extended advertisement parameters in bluetoothctl mgmt
+
+ add-ext-adv-params -r 0x801 -x 0x802 -P 2M -g -c 1
+
+mistakenly sets Own address type to Public (which causes to use Public
+Address 00:00:00:00:00:00)
+
+ < HCI Command: LE Set Extended Advertising Parameters (0x08|0x0036)
+ plen 25
+ ...
+ Own address type: Public (0x00)
+
+This causes either the controller to emit an Invalid Parameters error or to
+mishandle the advertising.
+
+This patch makes sure that we use the already set static random address
+when requesting a connectable extended advertising when we don't require
+privacy and our public address is not set (00:00:00:00:00:00).
+
+Fixes: 3fe318ee72c5 ("Bluetooth: move hci_get_random_address() to hci_sync")
+Signed-off-by: Alessandro Gasbarroni <alex.gasbarroni@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sync.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 3ac8d436e3e3a..5b3211e7530a5 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -6801,8 +6801,8 @@ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
+ return 0;
+ }
+
+- /* No privacy so use a public address. */
+- *own_addr_type = ADDR_LE_DEV_PUBLIC;
++ /* No privacy, use the current address */
++ hci_copy_identity_address(hdev, rand_addr, own_addr_type);
+
+ return 0;
+ }
+--
+2.39.5
+
--- /dev/null
+From 8078551aa29650bfa5d8160d4ceb8230b253ed4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jul 2025 09:40:49 -0400
+Subject: Bluetooth: L2CAP: Fix attempting to adjust outgoing MTU
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit d24e4a7fedae121d33fb32ad785b87046527eedb ]
+
+Configuration request only configure the incoming direction of the peer
+initiating the request, so using the MTU is the other direction shall
+not be used, that said the spec allows the peer responding to adjust:
+
+Bluetooth Core 6.1, Vol 3, Part A, Section 4.5
+
+ 'Each configuration parameter value (if any is present) in an
+ L2CAP_CONFIGURATION_RSP packet reflects an ‘adjustment’ to a
+ configuration parameter value that has been sent (or, in case of
+ default values, implied) in the corresponding
+ L2CAP_CONFIGURATION_REQ packet.'
+
+That said adjusting the MTU in the response shall be limited to ERTM
+channels only as for older modes the remote stack may not be able to
+detect the adjustment causing it to silently drop packets.
+
+Link: https://github.com/bluez/bluez/issues/1422
+Link: https://gitlab.archlinux.org/archlinux/packaging/packages/linux/-/issues/149
+Link: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4793
+Fixes: 042bb9603c44 ("Bluetooth: L2CAP: Fix L2CAP MTU negotiation")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 26 +++++++++++++++++++++-----
+ 1 file changed, 21 insertions(+), 5 deletions(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 40daa38276f35..805c752ac0a9d 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -3520,12 +3520,28 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data
+ /* Configure output options and let the other side know
+ * which ones we don't like. */
+
+- /* If MTU is not provided in configure request, use the most recently
+- * explicitly or implicitly accepted value for the other direction,
+- * or the default value.
++ /* If MTU is not provided in configure request, try adjusting it
++ * to the current output MTU if it has been set
++ *
++ * Bluetooth Core 6.1, Vol 3, Part A, Section 4.5
++ *
++ * Each configuration parameter value (if any is present) in an
++ * L2CAP_CONFIGURATION_RSP packet reflects an ‘adjustment’ to a
++ * configuration parameter value that has been sent (or, in case
++ * of default values, implied) in the corresponding
++ * L2CAP_CONFIGURATION_REQ packet.
+ */
+- if (mtu == 0)
+- mtu = chan->imtu ? chan->imtu : L2CAP_DEFAULT_MTU;
++ if (!mtu) {
++ /* Only adjust for ERTM channels as for older modes the
++ * remote stack may not be able to detect that the
++ * adjustment causing it to silently drop packets.
++ */
++ if (chan->mode == L2CAP_MODE_ERTM &&
++ chan->omtu && chan->omtu != L2CAP_DEFAULT_MTU)
++ mtu = chan->omtu;
++ else
++ mtu = L2CAP_DEFAULT_MTU;
++ }
+
+ if (mtu < L2CAP_DEFAULT_MIN_MTU)
+ result = L2CAP_CONF_UNACCEPT;
+--
+2.39.5
+
--- /dev/null
+From 3bba9834d0aa141fb61fddb48d837a336fa01d97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Jul 2025 11:53:40 -0400
+Subject: Bluetooth: SMP: Fix using HCI_ERROR_REMOTE_USER_TERM on timeout
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 6ef99c917688a8510259e565bd1b168b7146295a ]
+
+This replaces the usage of HCI_ERROR_REMOTE_USER_TERM, which as the name
+suggest is to indicate a regular disconnection initiated by an user,
+with HCI_ERROR_AUTH_FAILURE to indicate the session has timeout thus any
+pairing shall be considered as failed.
+
+Fixes: 1e91c29eb60c ("Bluetooth: Use hci_disconnect for immediate disconnection from SMP")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/smp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
+index a3a4ffee25c80..8115d42fc15b0 100644
+--- a/net/bluetooth/smp.c
++++ b/net/bluetooth/smp.c
+@@ -1379,7 +1379,7 @@ static void smp_timeout(struct work_struct *work)
+
+ bt_dev_dbg(conn->hcon->hdev, "conn %p", conn);
+
+- hci_disconnect(conn->hcon, HCI_ERROR_REMOTE_USER_TERM);
++ hci_disconnect(conn->hcon, HCI_ERROR_AUTH_FAILURE);
+ }
+
+ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
+--
+2.39.5
+
--- /dev/null
+From 00b336fcc2c963e2142a78e1dd69b609716326fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Jun 2025 14:42:23 -0400
+Subject: Bluetooth: SMP: If an unallowed command is received consider it a
+ failure
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit fe4840df0bdf341f376885271b7680764fe6b34e ]
+
+If a command is received while a bonding is ongoing consider it a
+pairing failure so the session is cleanup properly and the device is
+disconnected immediately instead of continuing with other commands that
+may result in the session to get stuck without ever completing such as
+the case bellow:
+
+> ACL Data RX: Handle 2048 flags 0x02 dlen 21
+ SMP: Identity Information (0x08) len 16
+ Identity resolving key[16]: d7e08edef97d3e62cd2331f82d8073b0
+> ACL Data RX: Handle 2048 flags 0x02 dlen 21
+ SMP: Signing Information (0x0a) len 16
+ Signature key[16]: 1716c536f94e843a9aea8b13ffde477d
+Bluetooth: hci0: unexpected SMP command 0x0a from XX:XX:XX:XX:XX:XX
+> ACL Data RX: Handle 2048 flags 0x02 dlen 12
+ SMP: Identity Address Information (0x09) len 7
+ Address: XX:XX:XX:XX:XX:XX (Intel Corporate)
+
+While accourding to core spec 6.1 the expected order is always BD_ADDR
+first first then CSRK:
+
+When using LE legacy pairing, the keys shall be distributed in the
+following order:
+
+ LTK by the Peripheral
+
+ EDIV and Rand by the Peripheral
+
+ IRK by the Peripheral
+
+ BD_ADDR by the Peripheral
+
+ CSRK by the Peripheral
+
+ LTK by the Central
+
+ EDIV and Rand by the Central
+
+ IRK by the Central
+
+ BD_ADDR by the Central
+
+ CSRK by the Central
+
+When using LE Secure Connections, the keys shall be distributed in the
+following order:
+
+ IRK by the Peripheral
+
+ BD_ADDR by the Peripheral
+
+ CSRK by the Peripheral
+
+ IRK by the Central
+
+ BD_ADDR by the Central
+
+ CSRK by the Central
+
+According to the Core 6.1 for commands used for key distribution "Key
+Rejected" can be used:
+
+ '3.6.1. Key distribution and generation
+
+ A device may reject a distributed key by sending the Pairing Failed command
+ with the reason set to "Key Rejected".
+
+Fixes: b28b4943660f ("Bluetooth: Add strict checks for allowed SMP PDUs")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/smp.c | 19 ++++++++++++++++++-
+ net/bluetooth/smp.h | 1 +
+ 2 files changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
+index 47f359f24d1fd..a3a4ffee25c80 100644
+--- a/net/bluetooth/smp.c
++++ b/net/bluetooth/smp.c
+@@ -2977,8 +2977,25 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
+ if (code > SMP_CMD_MAX)
+ goto drop;
+
+- if (smp && !test_and_clear_bit(code, &smp->allow_cmd))
++ if (smp && !test_and_clear_bit(code, &smp->allow_cmd)) {
++ /* If there is a context and the command is not allowed consider
++ * it a failure so the session is cleanup properly.
++ */
++ switch (code) {
++ case SMP_CMD_IDENT_INFO:
++ case SMP_CMD_IDENT_ADDR_INFO:
++ case SMP_CMD_SIGN_INFO:
++ /* 3.6.1. Key distribution and generation
++ *
++ * A device may reject a distributed key by sending the
++ * Pairing Failed command with the reason set to
++ * "Key Rejected".
++ */
++ smp_failure(conn, SMP_KEY_REJECTED);
++ break;
++ }
+ goto drop;
++ }
+
+ /* If we don't have a context the only allowed commands are
+ * pairing request and security request.
+diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h
+index 87a59ec2c9f02..c5da53dfab04f 100644
+--- a/net/bluetooth/smp.h
++++ b/net/bluetooth/smp.h
+@@ -138,6 +138,7 @@ struct smp_cmd_keypress_notify {
+ #define SMP_NUMERIC_COMP_FAILED 0x0c
+ #define SMP_BREDR_PAIRING_IN_PROGRESS 0x0d
+ #define SMP_CROSS_TRANSP_NOT_ALLOWED 0x0e
++#define SMP_KEY_REJECTED 0x0f
+
+ #define SMP_MIN_ENC_KEY_SIZE 7
+ #define SMP_MAX_ENC_KEY_SIZE 16
+--
+2.39.5
+
--- /dev/null
+From 52ebf19a4966b022a9e92dd5319a108777815a82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Jul 2025 21:47:30 +0200
+Subject: bpf: Reject %p% format string in bprintf-like helpers
+
+From: Paul Chaignon <paul.chaignon@gmail.com>
+
+[ Upstream commit f8242745871f81a3ac37f9f51853d12854fd0b58 ]
+
+static const char fmt[] = "%p%";
+ bpf_trace_printk(fmt, sizeof(fmt));
+
+The above BPF program isn't rejected and causes a kernel warning at
+runtime:
+
+ Please remove unsupported %\x00 in format string
+ WARNING: CPU: 1 PID: 7244 at lib/vsprintf.c:2680 format_decode+0x49c/0x5d0
+
+This happens because bpf_bprintf_prepare skips over the second %,
+detected as punctuation, while processing %p. This patch fixes it by
+not skipping over punctuation. %\x00 is then processed in the next
+iteration and rejected.
+
+Reported-by: syzbot+e2c932aec5c8a6e1d31c@syzkaller.appspotmail.com
+Fixes: 48cac3f4a96d ("bpf: Implement formatted output helpers with bstr_printf")
+Acked-by: Yonghong Song <yonghong.song@linux.dev>
+Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
+Link: https://lore.kernel.org/r/a0e06cc479faec9e802ae51ba5d66420523251ee.1751395489.git.paul.chaignon@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/helpers.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
+index a71aa4cb85fae..52d02bc0abb2b 100644
+--- a/kernel/bpf/helpers.c
++++ b/kernel/bpf/helpers.c
+@@ -883,6 +883,13 @@ int bpf_bprintf_prepare(char *fmt, u32 fmt_size, const u64 *raw_args,
+ if (fmt[i] == 'p') {
+ sizeof_cur_arg = sizeof(long);
+
++ if (fmt[i + 1] == 0 || isspace(fmt[i + 1]) ||
++ ispunct(fmt[i + 1])) {
++ if (tmp_buf)
++ cur_arg = raw_args[num_spec];
++ goto nocopy_fmt;
++ }
++
+ if ((fmt[i + 1] == 'k' || fmt[i + 1] == 'u') &&
+ fmt[i + 2] == 's') {
+ fmt_ptype = fmt[i + 1];
+@@ -890,11 +897,9 @@ int bpf_bprintf_prepare(char *fmt, u32 fmt_size, const u64 *raw_args,
+ goto fmt_str;
+ }
+
+- if (fmt[i + 1] == 0 || isspace(fmt[i + 1]) ||
+- ispunct(fmt[i + 1]) || fmt[i + 1] == 'K' ||
++ if (fmt[i + 1] == 'K' ||
+ fmt[i + 1] == 'x' || fmt[i + 1] == 's' ||
+ fmt[i + 1] == 'S') {
+- /* just kernel pointers */
+ if (tmp_buf)
+ cur_arg = raw_args[num_spec];
+ i++;
+--
+2.39.5
+
--- /dev/null
+From 12c3fd5d4d54ad6d3677a50dc63f1229d6899597 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Jul 2025 10:44:18 +0800
+Subject: cachefiles: Fix the incorrect return value in __cachefiles_write()
+
+From: Zizhi Wo <wozizhi@huawei.com>
+
+[ Upstream commit 6b89819b06d8d339da414f06ef3242f79508be5e ]
+
+In __cachefiles_write(), if the return value of the write operation > 0, it
+is set to 0. This makes it impossible to distinguish scenarios where a
+partial write has occurred, and will affect the outer calling functions:
+
+ 1) cachefiles_write_complete() will call "term_func" such as
+netfs_write_subrequest_terminated(). When "ret" in __cachefiles_write()
+is used as the "transferred_or_error" of this function, it can not
+distinguish the amount of data written, makes the WARN meaningless.
+
+ 2) cachefiles_ondemand_fd_write_iter() can only assume all writes were
+successful by default when "ret" is 0, and unconditionally return the full
+length specified by user space.
+
+Fix it by modifying "ret" to reflect the actual number of bytes written.
+Furthermore, returning a value greater than 0 from __cachefiles_write()
+does not affect other call paths, such as cachefiles_issue_write() and
+fscache_write().
+
+Fixes: 047487c947e8 ("cachefiles: Implement the I/O routines")
+Signed-off-by: Zizhi Wo <wozizhi@huawei.com>
+Link: https://lore.kernel.org/20250703024418.2809353-1-wozizhi@huaweicloud.com
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cachefiles/io.c | 2 --
+ fs/cachefiles/ondemand.c | 4 +---
+ 2 files changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c
+index c08e4a66ac07a..3e0576d9db1d2 100644
+--- a/fs/cachefiles/io.c
++++ b/fs/cachefiles/io.c
+@@ -347,8 +347,6 @@ int __cachefiles_write(struct cachefiles_object *object,
+ default:
+ ki->was_async = false;
+ cachefiles_write_complete(&ki->iocb, ret);
+- if (ret > 0)
+- ret = 0;
+ break;
+ }
+
+diff --git a/fs/cachefiles/ondemand.c b/fs/cachefiles/ondemand.c
+index d9bc671761282..a7ed86fa98bb8 100644
+--- a/fs/cachefiles/ondemand.c
++++ b/fs/cachefiles/ondemand.c
+@@ -83,10 +83,8 @@ static ssize_t cachefiles_ondemand_fd_write_iter(struct kiocb *kiocb,
+
+ trace_cachefiles_ondemand_fd_write(object, file_inode(file), pos, len);
+ ret = __cachefiles_write(object, file, pos, iter, NULL, NULL);
+- if (!ret) {
+- ret = len;
++ if (ret > 0)
+ kiocb->ki_pos += ret;
+- }
+
+ out:
+ fput(file);
+--
+2.39.5
+
--- /dev/null
+From f9bb581e8857e0f31973c5bb0384a28e6cac025f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Jul 2025 09:17:28 -0500
+Subject: can: tcan4x5x: fix reset gpio usage during probe
+
+From: Brett Werling <brett.werling@garmin.com>
+
+[ Upstream commit 0f97a7588db7a545ea07ee0d512789bfad4931d8 ]
+
+Fixes reset GPIO usage during probe by ensuring we retrieve the GPIO and
+take the device out of reset (if it defaults to being in reset) before
+we attempt to communicate with the device. This is achieved by moving
+the call to tcan4x5x_get_gpios() before tcan4x5x_find_version() and
+avoiding any device communication while getting the GPIOs. Once we
+determine the version, we can then take the knowledge of which GPIOs we
+obtained and use it to decide whether we need to disable the wake or
+state pin functions within the device.
+
+This change is necessary in a situation where the reset GPIO is pulled
+high externally before the CPU takes control of it, meaning we need to
+explicitly bring the device out of reset before we can start
+communicating with it at all.
+
+This also has the effect of fixing an issue where a reset of the device
+would occur after having called tcan4x5x_disable_wake(), making the
+original behavior not actually disable the wake. This patch should now
+disable wake or state pin functions well after the reset occurs.
+
+Signed-off-by: Brett Werling <brett.werling@garmin.com>
+Link: https://patch.msgid.link/20250711141728.1826073-1-brett.werling@garmin.com
+Cc: Markus Schneider-Pargmann <msp@baylibre.com>
+Fixes: 142c6dc6d9d7 ("can: tcan4x5x: Add support for tcan4552/4553")
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/m_can/tcan4x5x-core.c | 61 ++++++++++++++++++---------
+ 1 file changed, 41 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/net/can/m_can/tcan4x5x-core.c b/drivers/net/can/m_can/tcan4x5x-core.c
+index 8edaa339d590b..39b0b5277b11f 100644
+--- a/drivers/net/can/m_can/tcan4x5x-core.c
++++ b/drivers/net/can/m_can/tcan4x5x-core.c
+@@ -343,21 +343,19 @@ static void tcan4x5x_get_dt_data(struct m_can_classdev *cdev)
+ of_property_read_bool(cdev->dev->of_node, "ti,nwkrq-voltage-vio");
+ }
+
+-static int tcan4x5x_get_gpios(struct m_can_classdev *cdev,
+- const struct tcan4x5x_version_info *version_info)
++static int tcan4x5x_get_gpios(struct m_can_classdev *cdev)
+ {
+ struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev);
+ int ret;
+
+- if (version_info->has_wake_pin) {
+- tcan4x5x->device_wake_gpio = devm_gpiod_get(cdev->dev, "device-wake",
+- GPIOD_OUT_HIGH);
+- if (IS_ERR(tcan4x5x->device_wake_gpio)) {
+- if (PTR_ERR(tcan4x5x->device_wake_gpio) == -EPROBE_DEFER)
+- return -EPROBE_DEFER;
++ tcan4x5x->device_wake_gpio = devm_gpiod_get_optional(cdev->dev,
++ "device-wake",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(tcan4x5x->device_wake_gpio)) {
++ if (PTR_ERR(tcan4x5x->device_wake_gpio) == -EPROBE_DEFER)
++ return -EPROBE_DEFER;
+
+- tcan4x5x_disable_wake(cdev);
+- }
++ tcan4x5x->device_wake_gpio = NULL;
+ }
+
+ tcan4x5x->reset_gpio = devm_gpiod_get_optional(cdev->dev, "reset",
+@@ -369,14 +367,31 @@ static int tcan4x5x_get_gpios(struct m_can_classdev *cdev,
+ if (ret)
+ return ret;
+
+- if (version_info->has_state_pin) {
+- tcan4x5x->device_state_gpio = devm_gpiod_get_optional(cdev->dev,
+- "device-state",
+- GPIOD_IN);
+- if (IS_ERR(tcan4x5x->device_state_gpio)) {
+- tcan4x5x->device_state_gpio = NULL;
+- tcan4x5x_disable_state(cdev);
+- }
++ tcan4x5x->device_state_gpio = devm_gpiod_get_optional(cdev->dev,
++ "device-state",
++ GPIOD_IN);
++ if (IS_ERR(tcan4x5x->device_state_gpio))
++ tcan4x5x->device_state_gpio = NULL;
++
++ return 0;
++}
++
++static int tcan4x5x_check_gpios(struct m_can_classdev *cdev,
++ const struct tcan4x5x_version_info *version_info)
++{
++ struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev);
++ int ret;
++
++ if (version_info->has_wake_pin && !tcan4x5x->device_wake_gpio) {
++ ret = tcan4x5x_disable_wake(cdev);
++ if (ret)
++ return ret;
++ }
++
++ if (version_info->has_state_pin && !tcan4x5x->device_state_gpio) {
++ ret = tcan4x5x_disable_state(cdev);
++ if (ret)
++ return ret;
+ }
+
+ return 0;
+@@ -468,15 +483,21 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
+ goto out_m_can_class_free_dev;
+ }
+
++ ret = tcan4x5x_get_gpios(mcan_class);
++ if (ret) {
++ dev_err(&spi->dev, "Getting gpios failed %pe\n", ERR_PTR(ret));
++ goto out_power;
++ }
++
+ version_info = tcan4x5x_find_version(priv);
+ if (IS_ERR(version_info)) {
+ ret = PTR_ERR(version_info);
+ goto out_power;
+ }
+
+- ret = tcan4x5x_get_gpios(mcan_class, version_info);
++ ret = tcan4x5x_check_gpios(mcan_class, version_info);
+ if (ret) {
+- dev_err(&spi->dev, "Getting gpios failed %pe\n", ERR_PTR(ret));
++ dev_err(&spi->dev, "Checking gpios failed %pe\n", ERR_PTR(ret));
+ goto out_power;
+ }
+
+--
+2.39.5
+
--- /dev/null
+From c3d1cbac0cc15118b2165b09067617dc4826baac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jun 2025 19:31:41 +0800
+Subject: drm/mediatek: Add wait_event_timeout when disabling plane
+
+From: Jason-JH Lin <jason-jh.lin@mediatek.com>
+
+[ Upstream commit d208261e9f7c66960587b10473081dc1cecbe50b ]
+
+Our hardware registers are set through GCE, not by the CPU.
+DRM might assume the hardware is disabled immediately after calling
+atomic_disable() of drm_plane, but it is only truly disabled after the
+GCE IRQ is triggered.
+
+Additionally, the cursor plane in DRM uses async_commit, so DRM will
+not wait for vblank and will free the buffer immediately after calling
+atomic_disable().
+
+To prevent the framebuffer from being freed before the layer disable
+settings are configured into the hardware, which can cause an IOMMU
+fault error, a wait_event_timeout has been added to wait for the
+ddp_cmdq_cb() callback,indicating that the GCE IRQ has been triggered.
+
+Fixes: 2f965be7f900 ("drm/mediatek: apply CMDQ control flow")
+Signed-off-by: Jason-JH Lin <jason-jh.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20250624113223.443274-1-jason-jh.lin@mediatek.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_crtc.c | 33 ++++++++++++++++++++++++++++
+ drivers/gpu/drm/mediatek/mtk_crtc.h | 1 +
+ drivers/gpu/drm/mediatek/mtk_plane.c | 5 +++++
+ 3 files changed, 39 insertions(+)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c
+index 8f6fba4217ece..6916c8925b412 100644
+--- a/drivers/gpu/drm/mediatek/mtk_crtc.c
++++ b/drivers/gpu/drm/mediatek/mtk_crtc.c
+@@ -719,6 +719,39 @@ int mtk_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
+ return 0;
+ }
+
++void mtk_crtc_plane_disable(struct drm_crtc *crtc, struct drm_plane *plane)
++{
++#if IS_REACHABLE(CONFIG_MTK_CMDQ)
++ struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
++ struct mtk_plane_state *plane_state = to_mtk_plane_state(plane->state);
++ int i;
++
++ /* no need to wait for disabling the plane by CPU */
++ if (!mtk_crtc->cmdq_client.chan)
++ return;
++
++ if (!mtk_crtc->enabled)
++ return;
++
++ /* set pending plane state to disabled */
++ for (i = 0; i < mtk_crtc->layer_nr; i++) {
++ struct drm_plane *mtk_plane = &mtk_crtc->planes[i];
++ struct mtk_plane_state *mtk_plane_state = to_mtk_plane_state(mtk_plane->state);
++
++ if (mtk_plane->index == plane->index) {
++ memcpy(mtk_plane_state, plane_state, sizeof(*plane_state));
++ break;
++ }
++ }
++ mtk_crtc_update_config(mtk_crtc, false);
++
++ /* wait for planes to be disabled by CMDQ */
++ wait_event_timeout(mtk_crtc->cb_blocking_queue,
++ mtk_crtc->cmdq_vblank_cnt == 0,
++ msecs_to_jiffies(500));
++#endif
++}
++
+ void mtk_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
+ struct drm_atomic_state *state)
+ {
+diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.h b/drivers/gpu/drm/mediatek/mtk_crtc.h
+index 388e900b6f4de..828f109b83e78 100644
+--- a/drivers/gpu/drm/mediatek/mtk_crtc.h
++++ b/drivers/gpu/drm/mediatek/mtk_crtc.h
+@@ -21,6 +21,7 @@ int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,
+ unsigned int num_conn_routes);
+ int mtk_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
+ struct mtk_plane_state *state);
++void mtk_crtc_plane_disable(struct drm_crtc *crtc, struct drm_plane *plane);
+ void mtk_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
+ struct drm_atomic_state *plane_state);
+ struct device *mtk_crtc_dma_dev_get(struct drm_crtc *crtc);
+diff --git a/drivers/gpu/drm/mediatek/mtk_plane.c b/drivers/gpu/drm/mediatek/mtk_plane.c
+index 655106bbb76d3..59edbe26f01ee 100644
+--- a/drivers/gpu/drm/mediatek/mtk_plane.c
++++ b/drivers/gpu/drm/mediatek/mtk_plane.c
+@@ -285,9 +285,14 @@ static void mtk_plane_atomic_disable(struct drm_plane *plane,
+ struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
+ plane);
+ struct mtk_plane_state *mtk_plane_state = to_mtk_plane_state(new_state);
++ struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
++ plane);
++
+ mtk_plane_state->pending.enable = false;
+ wmb(); /* Make sure the above parameter is set before update */
+ mtk_plane_state->pending.dirty = true;
++
++ mtk_crtc_plane_disable(old_state->crtc, plane);
+ }
+
+ static void mtk_plane_atomic_update(struct drm_plane *plane,
+--
+2.39.5
+
--- /dev/null
+From e755507b3485bd39729b01900eb1945340c31573 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 31 May 2025 20:11:40 +0800
+Subject: drm/mediatek: only announce AFBC if really supported
+
+From: Icenowy Zheng <uwu@icenowy.me>
+
+[ Upstream commit 8d121a82fa564e0c8bd86ce4ec56b2a43b9b016e ]
+
+Currently even the SoC's OVL does not declare the support of AFBC, AFBC
+is still announced to the userspace within the IN_FORMATS blob, which
+breaks modern Wayland compositors like KWin Wayland and others.
+
+Gate passing modifiers to drm_universal_plane_init() behind querying the
+driver of the hardware block for AFBC support.
+
+Fixes: c410fa9b07c3 ("drm/mediatek: Add AFBC support to Mediatek DRM driver")
+Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
+Reviewed-by: CK Hu <ck.hu@medaitek.com>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20250531121140.387661-1-uwu@icenowy.me/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_crtc.c | 3 ++-
+ drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 1 +
+ drivers/gpu/drm/mediatek/mtk_ddp_comp.h | 9 +++++++++
+ drivers/gpu/drm/mediatek/mtk_disp_drv.h | 1 +
+ drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 7 +++++++
+ drivers/gpu/drm/mediatek/mtk_plane.c | 7 +++++--
+ drivers/gpu/drm/mediatek/mtk_plane.h | 3 ++-
+ 7 files changed, 27 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c
+index 6916c8925b412..bc7527542fdc6 100644
+--- a/drivers/gpu/drm/mediatek/mtk_crtc.c
++++ b/drivers/gpu/drm/mediatek/mtk_crtc.c
+@@ -963,7 +963,8 @@ static int mtk_crtc_init_comp_planes(struct drm_device *drm_dev,
+ mtk_ddp_comp_supported_rotations(comp),
+ mtk_ddp_comp_get_blend_modes(comp),
+ mtk_ddp_comp_get_formats(comp),
+- mtk_ddp_comp_get_num_formats(comp), i);
++ mtk_ddp_comp_get_num_formats(comp),
++ mtk_ddp_comp_is_afbc_supported(comp), i);
+ if (ret)
+ return ret;
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
+index edc6417639e64..ac6620e10262e 100644
+--- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
++++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
+@@ -366,6 +366,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl = {
+ .get_blend_modes = mtk_ovl_get_blend_modes,
+ .get_formats = mtk_ovl_get_formats,
+ .get_num_formats = mtk_ovl_get_num_formats,
++ .is_afbc_supported = mtk_ovl_is_afbc_supported,
+ };
+
+ static const struct mtk_ddp_comp_funcs ddp_postmask = {
+diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
+index 39720b27f4e9e..7289b3dcf22f2 100644
+--- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
++++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
+@@ -83,6 +83,7 @@ struct mtk_ddp_comp_funcs {
+ u32 (*get_blend_modes)(struct device *dev);
+ const u32 *(*get_formats)(struct device *dev);
+ size_t (*get_num_formats)(struct device *dev);
++ bool (*is_afbc_supported)(struct device *dev);
+ void (*connect)(struct device *dev, struct device *mmsys_dev, unsigned int next);
+ void (*disconnect)(struct device *dev, struct device *mmsys_dev, unsigned int next);
+ void (*add)(struct device *dev, struct mtk_mutex *mutex);
+@@ -294,6 +295,14 @@ size_t mtk_ddp_comp_get_num_formats(struct mtk_ddp_comp *comp)
+ return 0;
+ }
+
++static inline bool mtk_ddp_comp_is_afbc_supported(struct mtk_ddp_comp *comp)
++{
++ if (comp->funcs && comp->funcs->is_afbc_supported)
++ return comp->funcs->is_afbc_supported(comp->dev);
++
++ return false;
++}
++
+ static inline bool mtk_ddp_comp_add(struct mtk_ddp_comp *comp, struct mtk_mutex *mutex)
+ {
+ if (comp->funcs && comp->funcs->add) {
+diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+index 04217a36939cd..679d413bf10be 100644
+--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
++++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+@@ -106,6 +106,7 @@ void mtk_ovl_disable_vblank(struct device *dev);
+ u32 mtk_ovl_get_blend_modes(struct device *dev);
+ const u32 *mtk_ovl_get_formats(struct device *dev);
+ size_t mtk_ovl_get_num_formats(struct device *dev);
++bool mtk_ovl_is_afbc_supported(struct device *dev);
+
+ void mtk_ovl_adaptor_add_comp(struct device *dev, struct mtk_mutex *mutex);
+ void mtk_ovl_adaptor_remove_comp(struct device *dev, struct mtk_mutex *mutex);
+diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+index d0581c4e3c999..e0236353d4997 100644
+--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
++++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+@@ -236,6 +236,13 @@ size_t mtk_ovl_get_num_formats(struct device *dev)
+ return ovl->data->num_formats;
+ }
+
++bool mtk_ovl_is_afbc_supported(struct device *dev)
++{
++ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
++
++ return ovl->data->supports_afbc;
++}
++
+ int mtk_ovl_clk_enable(struct device *dev)
+ {
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+diff --git a/drivers/gpu/drm/mediatek/mtk_plane.c b/drivers/gpu/drm/mediatek/mtk_plane.c
+index 59edbe26f01ee..cbc4f37da8ba8 100644
+--- a/drivers/gpu/drm/mediatek/mtk_plane.c
++++ b/drivers/gpu/drm/mediatek/mtk_plane.c
+@@ -326,7 +326,8 @@ static const struct drm_plane_helper_funcs mtk_plane_helper_funcs = {
+ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
+ unsigned long possible_crtcs, enum drm_plane_type type,
+ unsigned int supported_rotations, const u32 blend_modes,
+- const u32 *formats, size_t num_formats, unsigned int plane_idx)
++ const u32 *formats, size_t num_formats,
++ bool supports_afbc, unsigned int plane_idx)
+ {
+ int err;
+
+@@ -337,7 +338,9 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
+
+ err = drm_universal_plane_init(dev, plane, possible_crtcs,
+ &mtk_plane_funcs, formats,
+- num_formats, modifiers, type, NULL);
++ num_formats,
++ supports_afbc ? modifiers : NULL,
++ type, NULL);
+ if (err) {
+ DRM_ERROR("failed to initialize plane\n");
+ return err;
+diff --git a/drivers/gpu/drm/mediatek/mtk_plane.h b/drivers/gpu/drm/mediatek/mtk_plane.h
+index 3b13b89989c7e..95c5fa5295d8a 100644
+--- a/drivers/gpu/drm/mediatek/mtk_plane.h
++++ b/drivers/gpu/drm/mediatek/mtk_plane.h
+@@ -49,5 +49,6 @@ to_mtk_plane_state(struct drm_plane_state *state)
+ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
+ unsigned long possible_crtcs, enum drm_plane_type type,
+ unsigned int supported_rotations, const u32 blend_modes,
+- const u32 *formats, size_t num_formats, unsigned int plane_idx);
++ const u32 *formats, size_t num_formats,
++ bool supports_afbc, unsigned int plane_idx);
+ #endif
+--
+2.39.5
+
--- /dev/null
+From 30cd8dd6867dba92feb92131114cbb2230b083e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Jul 2025 09:24:53 +0200
+Subject: drm/nouveau: check ioctl command codes better
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit e5478166dffb51fa64e76cdbb5c24421f22f2d43 ]
+
+nouveau_drm_ioctl() only checks the _IOC_NR() bits in the
+DRM_NOUVEAU_NVIF command, but ignores the type and direction bits, so any
+command with '7' in the low eight bits gets passed into
+nouveau_abi16_ioctl() instead of drm_ioctl().
+
+Check for all the bits except the size that is handled inside of the
+handler.
+
+Fixes: 27111a23d01c ("drm/nouveau: expose the full object/event interfaces to userspace")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+[ Fix up two checkpatch warnings and a typo. - Danilo ]
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20250711072458.2665325-1-arnd@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/nouveau/nouveau_drm.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
+index ba18abd9643e0..6bce4c4786e9f 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
++++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
+@@ -1279,6 +1279,9 @@ nouveau_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(NOUVEAU_EXEC, nouveau_exec_ioctl_exec, DRM_RENDER_ALLOW),
+ };
+
++#define DRM_IOCTL_NOUVEAU_NVIF _IOC(_IOC_READ | _IOC_WRITE, DRM_IOCTL_BASE, \
++ DRM_COMMAND_BASE + DRM_NOUVEAU_NVIF, 0)
++
+ long
+ nouveau_drm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ {
+@@ -1292,14 +1295,10 @@ nouveau_drm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ return ret;
+ }
+
+- switch (_IOC_NR(cmd) - DRM_COMMAND_BASE) {
+- case DRM_NOUVEAU_NVIF:
++ if ((cmd & ~IOCSIZE_MASK) == DRM_IOCTL_NOUVEAU_NVIF)
+ ret = nouveau_abi16_ioctl(filp, (void __user *)arg, _IOC_SIZE(cmd));
+- break;
+- default:
++ else
+ ret = drm_ioctl(file, cmd, arg);
+- break;
+- }
+
+ pm_runtime_mark_last_busy(dev->dev);
+ pm_runtime_put_autosuspend(dev->dev);
+--
+2.39.5
+
--- /dev/null
+From 561d53187bf81925023b5e0a821d41d26bd857a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jul 2025 10:29:45 +0530
+Subject: drm/xe: Dont skip TLB invalidations on VF
+
+From: Tejas Upadhyay <tejas.upadhyay@intel.com>
+
+[ Upstream commit fd25fa90edcfd4db5bf69c11621021a7cfd11d53 ]
+
+Skipping TLB invalidations on VF causing unrecoverable
+faults. Probable reason for skipping TLB invalidations
+on SRIOV could be lack of support for instruction
+MI_FLUSH_DW_STORE_INDEX. Add back TLB flush with some
+additional handling.
+
+Helps in resolving,
+[ 704.913454] xe 0000:00:02.1: [drm:pf_queue_work_func [xe]]
+ ASID: 0
+ VFID: 0
+ PDATA: 0x0d92
+ Faulted Address: 0x0000000002fa0000
+ FaultType: 0
+ AccessType: 1
+ FaultLevel: 0
+ EngineClass: 3 bcs
+ EngineInstance: 8
+[ 704.913551] xe 0000:00:02.1: [drm:pf_queue_work_func [xe]] Fault response: Unsuccessful -22
+
+V2:
+ - Use Xmas tree (MichalW)
+
+Suggested-by: Matthew Brost <matthew.brost@intel.com>
+Fixes: 97515d0b3ed92 ("drm/xe/vf: Don't emit access to Global HWSP if VF")
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250710045945.1023840-1-tejas.upadhyay@intel.com
+Signed-off-by: Tejas Upadhyay <tejas.upadhyay@intel.com>
+(cherry picked from commit b528e896fa570844d654b5a4617a97fa770a1030)
+Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_ring_ops.c | 22 ++++++++++------------
+ 1 file changed, 10 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_ring_ops.c b/drivers/gpu/drm/xe/xe_ring_ops.c
+index bc1689db4cd71..7b50c7c1ee21d 100644
+--- a/drivers/gpu/drm/xe/xe_ring_ops.c
++++ b/drivers/gpu/drm/xe/xe_ring_ops.c
+@@ -110,13 +110,14 @@ static int emit_bb_start(u64 batch_addr, u32 ppgtt_flag, u32 *dw, int i)
+ return i;
+ }
+
+-static int emit_flush_invalidate(u32 *dw, int i)
++static int emit_flush_invalidate(u32 addr, u32 val, u32 *dw, int i)
+ {
+ dw[i++] = MI_FLUSH_DW | MI_INVALIDATE_TLB | MI_FLUSH_DW_OP_STOREDW |
+- MI_FLUSH_IMM_DW | MI_FLUSH_DW_STORE_INDEX;
+- dw[i++] = LRC_PPHWSP_FLUSH_INVAL_SCRATCH_ADDR;
+- dw[i++] = 0;
++ MI_FLUSH_IMM_DW;
++
++ dw[i++] = addr | MI_FLUSH_DW_USE_GTT;
+ dw[i++] = 0;
++ dw[i++] = val;
+
+ return i;
+ }
+@@ -397,23 +398,20 @@ static void __emit_job_gen12_render_compute(struct xe_sched_job *job,
+ static void emit_migration_job_gen12(struct xe_sched_job *job,
+ struct xe_lrc *lrc, u32 seqno)
+ {
++ u32 saddr = xe_lrc_start_seqno_ggtt_addr(lrc);
+ u32 dw[MAX_JOB_SIZE_DW], i = 0;
+
+ i = emit_copy_timestamp(lrc, dw, i);
+
+- i = emit_store_imm_ggtt(xe_lrc_start_seqno_ggtt_addr(lrc),
+- seqno, dw, i);
++ i = emit_store_imm_ggtt(saddr, seqno, dw, i);
+
+ dw[i++] = MI_ARB_ON_OFF | MI_ARB_DISABLE; /* Enabled again below */
+
+ i = emit_bb_start(job->ptrs[0].batch_addr, BIT(8), dw, i);
+
+- if (!IS_SRIOV_VF(gt_to_xe(job->q->gt))) {
+- /* XXX: Do we need this? Leaving for now. */
+- dw[i++] = preparser_disable(true);
+- i = emit_flush_invalidate(dw, i);
+- dw[i++] = preparser_disable(false);
+- }
++ dw[i++] = preparser_disable(true);
++ i = emit_flush_invalidate(saddr, seqno, dw, i);
++ dw[i++] = preparser_disable(false);
+
+ i = emit_bb_start(job->ptrs[1].batch_addr, BIT(8), dw, i);
+
+--
+2.39.5
+
--- /dev/null
+From 84d0b2eb4ac20a5caaee011280b781edca491d2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Jul 2025 21:33:11 +0200
+Subject: drm/xe/pf: Prepare to stop SR-IOV support prior GT reset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michal Wajdeczko <michal.wajdeczko@intel.com>
+
+[ Upstream commit 81dccec448d204e448ae83e1fe60e8aaeaadadb8 ]
+
+As part of the resume or GT reset, the PF driver schedules work
+which is then used to complete restarting of the SR-IOV support,
+including resending to the GuC configurations of provisioned VFs.
+
+However, in case of short delay between those two actions, which
+could be seen by triggering a GT reset on the suspened device:
+
+ $ echo 1 > /sys/kernel/debug/dri/0000:00:02.0/gt0/force_reset
+
+this PF worker might be still busy, which lead to errors due to
+just stopped or disabled GuC CTB communication:
+
+ [ ] xe 0000:00:02.0: [drm:xe_gt_resume [xe]] GT0: resumed
+ [ ] xe 0000:00:02.0: [drm] GT0: trying reset from force_reset_show [xe]
+ [ ] xe 0000:00:02.0: [drm] GT0: reset queued
+ [ ] xe 0000:00:02.0: [drm] GT0: reset started
+ [ ] xe 0000:00:02.0: [drm:guc_ct_change_state [xe]] GT0: GuC CT communication channel stopped
+ [ ] xe 0000:00:02.0: [drm:guc_ct_send_recv [xe]] GT0: H2G request 0x5503 canceled!
+ [ ] xe 0000:00:02.0: [drm] GT0: PF: Failed to push VF1 12 config KLVs (-ECANCELED)
+ [ ] xe 0000:00:02.0: [drm] GT0: PF: Failed to push VF1 configuration (-ECANCELED)
+ [ ] xe 0000:00:02.0: [drm:guc_ct_change_state [xe]] GT0: GuC CT communication channel disabled
+ [ ] xe 0000:00:02.0: [drm] GT0: PF: Failed to push VF2 12 config KLVs (-ENODEV)
+ [ ] xe 0000:00:02.0: [drm] GT0: PF: Failed to push VF2 configuration (-ENODEV)
+ [ ] xe 0000:00:02.0: [drm] GT0: PF: Failed to push 2 of 2 VFs configurations
+ [ ] xe 0000:00:02.0: [drm:pf_worker_restart_func [xe]] GT0: PF: restart completed
+
+While this VFs reprovisioning will be successful during next spin
+of the worker, to avoid those errors, make sure to cancel restart
+worker if we are about to trigger next reset.
+
+Fixes: 411220808cee ("drm/xe/pf: Restart VFs provisioning after GT reset")
+Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Reviewed-by: Piotr Piórkowski <piotr.piorkowski@intel.com>
+Link: https://lore.kernel.org/r/20250711193316.1920-2-michal.wajdeczko@intel.com
+(cherry picked from commit 9f50b729dd61dfb9f4d7c66900d22a7c7353a8c0)
+Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_gt.c | 3 +++
+ drivers/gpu/drm/xe/xe_gt_sriov_pf.c | 19 +++++++++++++++++++
+ drivers/gpu/drm/xe/xe_gt_sriov_pf.h | 5 +++++
+ 3 files changed, 27 insertions(+)
+
+diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c
+index 4bad8894fa12c..7b8556fa17435 100644
+--- a/drivers/gpu/drm/xe/xe_gt.c
++++ b/drivers/gpu/drm/xe/xe_gt.c
+@@ -797,6 +797,9 @@ static int gt_reset(struct xe_gt *gt)
+ goto err_out;
+ }
+
++ if (IS_SRIOV_PF(gt_to_xe(gt)))
++ xe_gt_sriov_pf_stop_prepare(gt);
++
+ xe_uc_gucrc_disable(>->uc);
+ xe_uc_stop_prepare(>->uc);
+ xe_gt_pagefault_reset(gt);
+diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf.c
+index c08efca6420e7..35489fa818259 100644
+--- a/drivers/gpu/drm/xe/xe_gt_sriov_pf.c
++++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf.c
+@@ -172,6 +172,25 @@ void xe_gt_sriov_pf_sanitize_hw(struct xe_gt *gt, unsigned int vfid)
+ pf_clear_vf_scratch_regs(gt, vfid);
+ }
+
++static void pf_cancel_restart(struct xe_gt *gt)
++{
++ xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
++
++ if (cancel_work_sync(>->sriov.pf.workers.restart))
++ xe_gt_sriov_dbg_verbose(gt, "pending restart canceled!\n");
++}
++
++/**
++ * xe_gt_sriov_pf_stop_prepare() - Prepare to stop SR-IOV support.
++ * @gt: the &xe_gt
++ *
++ * This function can only be called on the PF.
++ */
++void xe_gt_sriov_pf_stop_prepare(struct xe_gt *gt)
++{
++ pf_cancel_restart(gt);
++}
++
+ static void pf_restart(struct xe_gt *gt)
+ {
+ struct xe_device *xe = gt_to_xe(gt);
+diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf.h
+index f474509411c0c..e2b2ff8132dc5 100644
+--- a/drivers/gpu/drm/xe/xe_gt_sriov_pf.h
++++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf.h
+@@ -13,6 +13,7 @@ int xe_gt_sriov_pf_init_early(struct xe_gt *gt);
+ int xe_gt_sriov_pf_init(struct xe_gt *gt);
+ void xe_gt_sriov_pf_init_hw(struct xe_gt *gt);
+ void xe_gt_sriov_pf_sanitize_hw(struct xe_gt *gt, unsigned int vfid);
++void xe_gt_sriov_pf_stop_prepare(struct xe_gt *gt);
+ void xe_gt_sriov_pf_restart(struct xe_gt *gt);
+ #else
+ static inline int xe_gt_sriov_pf_init_early(struct xe_gt *gt)
+@@ -29,6 +30,10 @@ static inline void xe_gt_sriov_pf_init_hw(struct xe_gt *gt)
+ {
+ }
+
++static inline void xe_gt_sriov_pf_stop_prepare(struct xe_gt *gt)
++{
++}
++
+ static inline void xe_gt_sriov_pf_restart(struct xe_gt *gt)
+ {
+ }
+--
+2.39.5
+
--- /dev/null
+From da9907e8e86bf47578a2d86abb18c6428905e639 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Jul 2025 21:33:12 +0200
+Subject: drm/xe/pf: Resend PF provisioning after GT reset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michal Wajdeczko <michal.wajdeczko@intel.com>
+
+[ Upstream commit 5c244eeca57ff4e47e1f60310d059346d1b86b9b ]
+
+If we reload the GuC due to suspend/resume or GT reset then we
+have to resend not only any VFs provisioning data, but also PF
+configuration, like scheduling parameters (EQ, PT), as otherwise
+GuC will continue to use default values.
+
+Fixes: 411220808cee ("drm/xe/pf: Restart VFs provisioning after GT reset")
+Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Reviewed-by: Piotr Piórkowski <piotr.piorkowski@intel.com>
+Link: https://lore.kernel.org/r/20250711193316.1920-3-michal.wajdeczko@intel.com
+(cherry picked from commit 1c38dd6afa4a8ecce28e94da794fd1d205c30f51)
+Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c | 27 ++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
+index 10be109bf357f..96289195a3d3e 100644
+--- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
++++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
+@@ -2356,6 +2356,21 @@ int xe_gt_sriov_pf_config_restore(struct xe_gt *gt, unsigned int vfid,
+ return err;
+ }
+
++static int pf_push_self_config(struct xe_gt *gt)
++{
++ int err;
++
++ err = pf_push_full_vf_config(gt, PFID);
++ if (err) {
++ xe_gt_sriov_err(gt, "Failed to push self configuration (%pe)\n",
++ ERR_PTR(err));
++ return err;
++ }
++
++ xe_gt_sriov_dbg_verbose(gt, "self configuration completed\n");
++ return 0;
++}
++
+ static void fini_config(void *arg)
+ {
+ struct xe_gt *gt = arg;
+@@ -2379,9 +2394,17 @@ static void fini_config(void *arg)
+ int xe_gt_sriov_pf_config_init(struct xe_gt *gt)
+ {
+ struct xe_device *xe = gt_to_xe(gt);
++ int err;
+
+ xe_gt_assert(gt, IS_SRIOV_PF(xe));
+
++ mutex_lock(xe_gt_sriov_pf_master_mutex(gt));
++ err = pf_push_self_config(gt);
++ mutex_unlock(xe_gt_sriov_pf_master_mutex(gt));
++
++ if (err)
++ return err;
++
+ return devm_add_action_or_reset(xe->drm.dev, fini_config, gt);
+ }
+
+@@ -2399,6 +2422,10 @@ void xe_gt_sriov_pf_config_restart(struct xe_gt *gt)
+ unsigned int n, total_vfs = xe_sriov_pf_get_totalvfs(gt_to_xe(gt));
+ unsigned int fail = 0, skip = 0;
+
++ mutex_lock(xe_gt_sriov_pf_master_mutex(gt));
++ pf_push_self_config(gt);
++ mutex_unlock(xe_gt_sriov_pf_master_mutex(gt));
++
+ for (n = 1; n <= total_vfs; n++) {
+ if (xe_gt_sriov_pf_config_is_empty(gt, n))
+ skip++;
+--
+2.39.5
+
--- /dev/null
+From 08501e4838aaf38d895c3107322d1ca09bb72e81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jul 2025 08:23:12 -0700
+Subject: efivarfs: Fix memory leak of efivarfs_fs_info in fs_context error
+ paths
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 64e135f1eaba0bbb0cdee859af3328c68d5b9789 ]
+
+When processing mount options, efivarfs allocates efivarfs_fs_info (sfi)
+early in fs_context initialization. However, sfi is associated with the
+superblock and typically freed when the superblock is destroyed. If the
+fs_context is released (final put) before fill_super is called—such as
+on error paths or during reconfiguration—the sfi structure would leak,
+as ownership never transfers to the superblock.
+
+Implement the .free callback in efivarfs_context_ops to ensure any
+allocated sfi is properly freed if the fs_context is torn down before
+fill_super, preventing this memory leak.
+
+Suggested-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Fixes: 5329aa5101f73c ("efivarfs: Add uid/gid mount options")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/efivarfs/super.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
+index 0486e9b68bc6e..f681814fe8bb0 100644
+--- a/fs/efivarfs/super.c
++++ b/fs/efivarfs/super.c
+@@ -387,10 +387,16 @@ static int efivarfs_reconfigure(struct fs_context *fc)
+ return 0;
+ }
+
++static void efivarfs_free(struct fs_context *fc)
++{
++ kfree(fc->s_fs_info);
++}
++
+ static const struct fs_context_operations efivarfs_context_ops = {
+ .get_tree = efivarfs_get_tree,
+ .parse_param = efivarfs_parse_param,
+ .reconfigure = efivarfs_reconfigure,
++ .free = efivarfs_free,
+ };
+
+ struct efivarfs_ctx {
+--
+2.39.5
+
--- /dev/null
+From 931c12c717cdebea52a5d6010fc4bb1ad8e278de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Jul 2025 18:18:43 +0100
+Subject: fix a leak in fcntl_dirnotify()
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+[ Upstream commit fdfe0133473a528e3f5da69c35419ce6711d6b89 ]
+
+[into #fixes, unless somebody objects]
+
+Lifetime of new_dn_mark is controlled by that of its ->fsn_mark,
+pointed to by new_fsn_mark. Unfortunately, a failure exit had
+been inserted between the allocation of new_dn_mark and the
+call of fsnotify_init_mark(), ending up with a leak.
+
+Fixes: 1934b212615d "file: reclaim 24 bytes from f_owner"
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Link: https://lore.kernel.org/20250712171843.GB1880847@ZenIV
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/notify/dnotify/dnotify.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c
+index c4cdaf5fa7eda..9fb73bafd41d2 100644
+--- a/fs/notify/dnotify/dnotify.c
++++ b/fs/notify/dnotify/dnotify.c
+@@ -308,6 +308,10 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned int arg)
+ goto out_err;
+ }
+
++ error = file_f_owner_allocate(filp);
++ if (error)
++ goto out_err;
++
+ /* new fsnotify mark, we expect most fcntl calls to add a new mark */
+ new_dn_mark = kmem_cache_alloc(dnotify_mark_cache, GFP_KERNEL);
+ if (!new_dn_mark) {
+@@ -315,10 +319,6 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned int arg)
+ goto out_err;
+ }
+
+- error = file_f_owner_allocate(filp);
+- if (error)
+- goto out_err;
+-
+ /* set up the new_fsn_mark and new_dn_mark */
+ new_fsn_mark = &new_dn_mark->fsn_mark;
+ fsnotify_init_mark(new_fsn_mark, dnotify_group);
+--
+2.39.5
+
--- /dev/null
+From ed3215458709c2b581dc347dc089ce7a1335f3c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jul 2025 08:26:05 +0800
+Subject: hv_netvsc: Set VF priv_flags to IFF_NO_ADDRCONF before open to
+ prevent IPv6 addrconf
+
+From: Li Tian <litian@redhat.com>
+
+[ Upstream commit d7501e076d859d2f381d57bd984ff6db13172727 ]
+
+Set an additional flag IFF_NO_ADDRCONF to prevent ipv6 addrconf.
+
+Commit under Fixes added a new flag change that was not made
+to hv_netvsc resulting in the VF being assinged an IPv6.
+
+Fixes: 8a321cf7becc ("net: add IFF_NO_ADDRCONF and use it in bonding to prevent ipv6 addrconf")
+Suggested-by: Cathy Avery <cavery@redhat.com>
+Signed-off-by: Li Tian <litian@redhat.com>
+Reviewed-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20250716002607.4927-1-litian@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/hyperv/netvsc_drv.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+index 31242921c8285..8c73f71051020 100644
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -2317,8 +2317,11 @@ static int netvsc_prepare_bonding(struct net_device *vf_netdev)
+ if (!ndev)
+ return NOTIFY_DONE;
+
+- /* set slave flag before open to prevent IPv6 addrconf */
++ /* Set slave flag and no addrconf flag before open
++ * to prevent IPv6 addrconf.
++ */
+ vf_netdev->flags |= IFF_SLAVE;
++ vf_netdev->priv_flags |= IFF_NO_ADDRCONF;
+ return NOTIFY_DONE;
+ }
+
+--
+2.39.5
+
--- /dev/null
+From 0ab816dabc9bdc5f1730c3d21c02076d8b7a06fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Jun 2025 15:27:47 +0200
+Subject: hwmon: (corsair-cpro) Validate the size of the received input buffer
+
+From: Marius Zachmann <mail@mariuszachmann.de>
+
+[ Upstream commit 495a4f0dce9c8c4478c242209748f1ee9e4d5820 ]
+
+Add buffer_recv_size to store the size of the received bytes.
+Validate buffer_recv_size in send_usb_cmd().
+
+Reported-by: syzbot+3bbbade4e1a7ab45ca3b@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/linux-hwmon/61233ba1-e5ad-4d7a-ba31-3b5d0adcffcc@roeck-us.net
+Fixes: 40c3a4454225 ("hwmon: add Corsair Commander Pro driver")
+Signed-off-by: Marius Zachmann <mail@mariuszachmann.de>
+Link: https://lore.kernel.org/r/20250619132817.39764-5-mail@mariuszachmann.de
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/corsair-cpro.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/hwmon/corsair-cpro.c b/drivers/hwmon/corsair-cpro.c
+index e1a7f7aa7f804..b7b911f8359c7 100644
+--- a/drivers/hwmon/corsair-cpro.c
++++ b/drivers/hwmon/corsair-cpro.c
+@@ -89,6 +89,7 @@ struct ccp_device {
+ struct mutex mutex; /* whenever buffer is used, lock before send_usb_cmd */
+ u8 *cmd_buffer;
+ u8 *buffer;
++ int buffer_recv_size; /* number of received bytes in buffer */
+ int target[6];
+ DECLARE_BITMAP(temp_cnct, NUM_TEMP_SENSORS);
+ DECLARE_BITMAP(fan_cnct, NUM_FANS);
+@@ -146,6 +147,9 @@ static int send_usb_cmd(struct ccp_device *ccp, u8 command, u8 byte1, u8 byte2,
+ if (!t)
+ return -ETIMEDOUT;
+
++ if (ccp->buffer_recv_size != IN_BUFFER_SIZE)
++ return -EPROTO;
++
+ return ccp_get_errno(ccp);
+ }
+
+@@ -157,6 +161,7 @@ static int ccp_raw_event(struct hid_device *hdev, struct hid_report *report, u8
+ spin_lock(&ccp->wait_input_report_lock);
+ if (!completion_done(&ccp->wait_input_report)) {
+ memcpy(ccp->buffer, data, min(IN_BUFFER_SIZE, size));
++ ccp->buffer_recv_size = size;
+ complete_all(&ccp->wait_input_report);
+ }
+ spin_unlock(&ccp->wait_input_report_lock);
+--
+2.39.5
+
--- /dev/null
+From 91305d91998035f389fd65175995a887af773b1f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 May 2025 13:16:57 -0400
+Subject: ice: add NULL check in eswitch lag check
+
+From: Dave Ertman <david.m.ertman@intel.com>
+
+[ Upstream commit 3ce58b01ada408b372f15b7c992ed0519840e3cf ]
+
+The function ice_lag_is_switchdev_running() is being called from outside of
+the LAG event handler code. This results in the lag->upper_netdev being
+NULL sometimes. To avoid a NULL-pointer dereference, there needs to be a
+check before it is dereferenced.
+
+Fixes: 776fe19953b0 ("ice: block default rule setting on LAG interface")
+Signed-off-by: Dave Ertman <david.m.ertman@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Tested-by: Sujai Buvaneswaran <sujai.buvaneswaran@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_lag.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_lag.c b/drivers/net/ethernet/intel/ice/ice_lag.c
+index 2410aee59fb2d..d132eb4775513 100644
+--- a/drivers/net/ethernet/intel/ice/ice_lag.c
++++ b/drivers/net/ethernet/intel/ice/ice_lag.c
+@@ -2226,7 +2226,8 @@ bool ice_lag_is_switchdev_running(struct ice_pf *pf)
+ struct ice_lag *lag = pf->lag;
+ struct net_device *tmp_nd;
+
+- if (!ice_is_feature_supported(pf, ICE_F_SRIOV_LAG) || !lag)
++ if (!ice_is_feature_supported(pf, ICE_F_SRIOV_LAG) ||
++ !lag || !lag->upper_netdev)
+ return false;
+
+ rcu_read_lock();
+--
+2.39.5
+
--- /dev/null
+From dd3cb7ca80372f03a9b1300b75d25064ca3bbfe6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jun 2025 11:26:36 +0200
+Subject: ice: check correct pointer in fwlog debugfs
+
+From: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+
+[ Upstream commit bedd0330a19b3a4448e67941732153ce04d3fb9b ]
+
+pf->ice_debugfs_pf_fwlog should be checked for an error here.
+
+Fixes: 96a9a9341cda ("ice: configure FW logging")
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_debugfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_debugfs.c b/drivers/net/ethernet/intel/ice/ice_debugfs.c
+index 9fc0fd95a13d8..cb71eca6a85bf 100644
+--- a/drivers/net/ethernet/intel/ice/ice_debugfs.c
++++ b/drivers/net/ethernet/intel/ice/ice_debugfs.c
+@@ -606,7 +606,7 @@ void ice_debugfs_fwlog_init(struct ice_pf *pf)
+
+ pf->ice_debugfs_pf_fwlog = debugfs_create_dir("fwlog",
+ pf->ice_debugfs_pf);
+- if (IS_ERR(pf->ice_debugfs_pf))
++ if (IS_ERR(pf->ice_debugfs_pf_fwlog))
+ goto err_create_module_files;
+
+ fw_modules_dir = debugfs_create_dir("modules",
+--
+2.39.5
+
--- /dev/null
+From 00a818065e6fe29bb38939c24af867561ad46a42 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jul 2025 22:19:57 +0800
+Subject: ipv6: mcast: Delay put pmc->idev in mld_del_delrec()
+
+From: Yue Haibing <yuehaibing@huawei.com>
+
+[ Upstream commit ae3264a25a4635531264728859dbe9c659fad554 ]
+
+pmc->idev is still used in ip6_mc_clear_src(), so as mld_clear_delrec()
+does, the reference should be put after ip6_mc_clear_src() return.
+
+Fixes: 63ed8de4be81 ("mld: add mc_lock for protecting per-interface mld data")
+Signed-off-by: Yue Haibing <yuehaibing@huawei.com>
+Link: https://patch.msgid.link/20250714141957.3301871-1-yuehaibing@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/mcast.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
+index 65831b4fee1fd..616bf4c0c8fd9 100644
+--- a/net/ipv6/mcast.c
++++ b/net/ipv6/mcast.c
+@@ -807,8 +807,8 @@ static void mld_del_delrec(struct inet6_dev *idev, struct ifmcaddr6 *im)
+ } else {
+ im->mca_crcount = idev->mc_qrv;
+ }
+- in6_dev_put(pmc->idev);
+ ip6_mc_clear_src(pmc);
++ in6_dev_put(pmc->idev);
+ kfree_rcu(pmc, rcu);
+ }
+ }
+--
+2.39.5
+
--- /dev/null
+From a454a7d4f104b5fb8bfc432413d09372b91927ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jul 2025 17:10:09 -0700
+Subject: libbpf: Fix handling of BPF arena relocations
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit 0238c45fbbf8228f52aa4642f0cdc21c570d1dfe ]
+
+Initial __arena global variable support implementation in libbpf
+contains a bug: it remembers struct bpf_map pointer for arena, which is
+used later on to process relocations. Recording this pointer is
+problematic because map pointers are not stable during ELF relocation
+collection phase, as an array of struct bpf_map's can be reallocated,
+invalidating all the pointers. Libbpf is dealing with similar issues by
+using a stable internal map index, though for BPF arena map specifically
+this approach wasn't used due to an oversight.
+
+The resulting behavior is non-deterministic issue which depends on exact
+layout of ELF object file, number of actual maps, etc. We didn't hit
+this until very recently, when this bug started triggering crash in BPF
+CI when validating one of sched-ext BPF programs.
+
+The fix is rather straightforward: we just follow an established pattern
+of remembering map index (just like obj->kconfig_map_idx, for example)
+instead of `struct bpf_map *`, and resolving index to a pointer at the
+point where map information is necessary.
+
+While at it also add debug-level message for arena-related relocation
+resolution information, which we already have for all other kinds of
+maps.
+
+Fixes: 2e7ba4f8fd1f ("libbpf: Recognize __arena global variables.")
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Tested-by: Eduard Zingerman <eddyz87@gmail.com>
+Link: https://lore.kernel.org/r/20250718001009.610955-1-andrii@kernel.org
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/libbpf.c | 20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index 97605ea8093ff..c8e29c52d28c0 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -735,7 +735,7 @@ struct bpf_object {
+
+ struct usdt_manager *usdt_man;
+
+- struct bpf_map *arena_map;
++ int arena_map_idx;
+ void *arena_data;
+ size_t arena_data_sz;
+
+@@ -1517,6 +1517,7 @@ static struct bpf_object *bpf_object__new(const char *path,
+ obj->efile.obj_buf_sz = obj_buf_sz;
+ obj->efile.btf_maps_shndx = -1;
+ obj->kconfig_map_idx = -1;
++ obj->arena_map_idx = -1;
+
+ obj->kern_version = get_kernel_version();
+ obj->state = OBJ_OPEN;
+@@ -2964,7 +2965,7 @@ static int init_arena_map_data(struct bpf_object *obj, struct bpf_map *map,
+ const long page_sz = sysconf(_SC_PAGE_SIZE);
+ size_t mmap_sz;
+
+- mmap_sz = bpf_map_mmap_sz(obj->arena_map);
++ mmap_sz = bpf_map_mmap_sz(map);
+ if (roundup(data_sz, page_sz) > mmap_sz) {
+ pr_warn("elf: sec '%s': declared ARENA map size (%zu) is too small to hold global __arena variables of size %zu\n",
+ sec_name, mmap_sz, data_sz);
+@@ -3038,12 +3039,12 @@ static int bpf_object__init_user_btf_maps(struct bpf_object *obj, bool strict,
+ if (map->def.type != BPF_MAP_TYPE_ARENA)
+ continue;
+
+- if (obj->arena_map) {
++ if (obj->arena_map_idx >= 0) {
+ pr_warn("map '%s': only single ARENA map is supported (map '%s' is also ARENA)\n",
+- map->name, obj->arena_map->name);
++ map->name, obj->maps[obj->arena_map_idx].name);
+ return -EINVAL;
+ }
+- obj->arena_map = map;
++ obj->arena_map_idx = i;
+
+ if (obj->efile.arena_data) {
+ err = init_arena_map_data(obj, map, ARENA_SEC, obj->efile.arena_data_shndx,
+@@ -3053,7 +3054,7 @@ static int bpf_object__init_user_btf_maps(struct bpf_object *obj, bool strict,
+ return err;
+ }
+ }
+- if (obj->efile.arena_data && !obj->arena_map) {
++ if (obj->efile.arena_data && obj->arena_map_idx < 0) {
+ pr_warn("elf: sec '%s': to use global __arena variables the ARENA map should be explicitly declared in SEC(\".maps\")\n",
+ ARENA_SEC);
+ return -ENOENT;
+@@ -4583,8 +4584,13 @@ static int bpf_program__record_reloc(struct bpf_program *prog,
+ if (shdr_idx == obj->efile.arena_data_shndx) {
+ reloc_desc->type = RELO_DATA;
+ reloc_desc->insn_idx = insn_idx;
+- reloc_desc->map_idx = obj->arena_map - obj->maps;
++ reloc_desc->map_idx = obj->arena_map_idx;
+ reloc_desc->sym_off = sym->st_value;
++
++ map = &obj->maps[obj->arena_map_idx];
++ pr_debug("prog '%s': found arena map %d (%s, sec %d, off %zu) for insn %u\n",
++ prog->name, obj->arena_map_idx, map->name, map->sec_idx,
++ map->sec_offset, insn_idx);
+ return 0;
+ }
+
+--
+2.39.5
+
--- /dev/null
+From d20edc2e8be1cf99ab52d1097b68a917cb84f594 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jul 2025 19:48:08 +0800
+Subject: loop: use kiocb helpers to fix lockdep warning
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit c4706c5058a7bd7d7c20f3b24a8f523ecad44e83 ]
+
+The lockdep tool can report a circular lock dependency warning in the loop
+driver's AIO read/write path:
+
+```
+[ 6540.587728] kworker/u96:5/72779 is trying to acquire lock:
+[ 6540.593856] ff110001b5968440 (sb_writers#9){.+.+}-{0:0}, at: loop_process_work+0x11a/0xf70 [loop]
+[ 6540.603786]
+[ 6540.603786] but task is already holding lock:
+[ 6540.610291] ff110001b5968440 (sb_writers#9){.+.+}-{0:0}, at: loop_process_work+0x11a/0xf70 [loop]
+[ 6540.620210]
+[ 6540.620210] other info that might help us debug this:
+[ 6540.627499] Possible unsafe locking scenario:
+[ 6540.627499]
+[ 6540.634110] CPU0
+[ 6540.636841] ----
+[ 6540.639574] lock(sb_writers#9);
+[ 6540.643281] lock(sb_writers#9);
+[ 6540.646988]
+[ 6540.646988] *** DEADLOCK ***
+```
+
+This patch fixes the issue by using the AIO-specific helpers
+`kiocb_start_write()` and `kiocb_end_write()`. These functions are
+designed to be used with a `kiocb` and manage write sequencing
+correctly for asynchronous I/O without introducing the problematic
+lock dependency.
+
+The `kiocb` is already part of the `loop_cmd` struct, so this change
+also simplifies the completion function `lo_rw_aio_do_completion()` by
+using the `iocb` from the `cmd` struct directly, instead of retrieving
+the loop device from the request queue.
+
+Fixes: 39d86db34e41 ("loop: add file_start_write() and file_end_write()")
+Cc: Changhui Zhong <czhong@redhat.com>
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20250716114808.3159657-1-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/loop.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c
+index f8d136684109a..3999056877572 100644
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -308,14 +308,13 @@ static void lo_complete_rq(struct request *rq)
+ static void lo_rw_aio_do_completion(struct loop_cmd *cmd)
+ {
+ struct request *rq = blk_mq_rq_from_pdu(cmd);
+- struct loop_device *lo = rq->q->queuedata;
+
+ if (!atomic_dec_and_test(&cmd->ref))
+ return;
+ kfree(cmd->bvec);
+ cmd->bvec = NULL;
+ if (req_op(rq) == REQ_OP_WRITE)
+- file_end_write(lo->lo_backing_file);
++ kiocb_end_write(&cmd->iocb);
+ if (likely(!blk_should_fake_timeout(rq->q)))
+ blk_mq_complete_request(rq);
+ }
+@@ -391,7 +390,7 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
+ }
+
+ if (rw == ITER_SOURCE) {
+- file_start_write(lo->lo_backing_file);
++ kiocb_start_write(&cmd->iocb);
+ ret = file->f_op->write_iter(&cmd->iocb, &iter);
+ } else
+ ret = file->f_op->read_iter(&cmd->iocb, &iter);
+--
+2.39.5
+
--- /dev/null
+From 3cf39bb5bccdbbeb271873b1c70e9d99ff5dd81b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Jul 2025 07:30:58 -0700
+Subject: net: airoha: fix potential use-after-free in airoha_npu_get()
+
+From: Alok Tiwari <alok.a.tiwari@oracle.com>
+
+[ Upstream commit 3cd582e7d0787506990ef0180405eb6224fa90a6 ]
+
+np->name was being used after calling of_node_put(np), which
+releases the node and can lead to a use-after-free bug.
+Previously, of_node_put(np) was called unconditionally after
+of_find_device_by_node(np), which could result in a use-after-free if
+pdev is NULL.
+
+This patch moves of_node_put(np) after the error check to ensure
+the node is only released after both the error and success cases
+are handled appropriately, preventing potential resource issues.
+
+Fixes: 23290c7bc190 ("net: airoha: Introduce Airoha NPU support")
+Signed-off-by: Alok Tiwari <alok.a.tiwari@oracle.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250715143102.3458286-1-alok.a.tiwari@oracle.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_npu.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/airoha/airoha_npu.c b/drivers/net/ethernet/airoha/airoha_npu.c
+index ead0625e781f5..760367c2c033b 100644
+--- a/drivers/net/ethernet/airoha/airoha_npu.c
++++ b/drivers/net/ethernet/airoha/airoha_npu.c
+@@ -344,12 +344,13 @@ struct airoha_npu *airoha_npu_get(struct device *dev)
+ return ERR_PTR(-ENODEV);
+
+ pdev = of_find_device_by_node(np);
+- of_node_put(np);
+
+ if (!pdev) {
+ dev_err(dev, "cannot find device node %s\n", np->name);
++ of_node_put(np);
+ return ERR_PTR(-ENODEV);
+ }
++ of_node_put(np);
+
+ if (!try_module_get(THIS_MODULE)) {
+ dev_err(dev, "failed to get the device driver module\n");
+--
+2.39.5
+
--- /dev/null
+From e8a94b7309a921ea5c7692353385ade872511fdc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jul 2025 11:35:50 -0400
+Subject: net: bridge: Do not offload IGMP/MLD messages
+
+From: Joseph Huang <Joseph.Huang@garmin.com>
+
+[ Upstream commit 683dc24da8bf199bb7446e445ad7f801c79a550e ]
+
+Do not offload IGMP/MLD messages as it could lead to IGMP/MLD Reports
+being unintentionally flooded to Hosts. Instead, let the bridge decide
+where to send these IGMP/MLD messages.
+
+Consider the case where the local host is sending out reports in response
+to a remote querier like the following:
+
+ mcast-listener-process (IP_ADD_MEMBERSHIP)
+ \
+ br0
+ / \
+ swp1 swp2
+ | |
+ QUERIER SOME-OTHER-HOST
+
+In the above setup, br0 will want to br_forward() reports for
+mcast-listener-process's group(s) via swp1 to QUERIER; but since the
+source hwdom is 0, the report is eligible for tx offloading, and is
+flooded by hardware to both swp1 and swp2, reaching SOME-OTHER-HOST as
+well. (Example and illustration provided by Tobias.)
+
+Fixes: 472111920f1c ("net: bridge: switchdev: allow the TX data plane forwarding to be offloaded")
+Signed-off-by: Joseph Huang <Joseph.Huang@garmin.com>
+Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20250716153551.1830255-1-Joseph.Huang@garmin.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/br_switchdev.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c
+index 7b41ee8740cbb..f10bd6a233dcf 100644
+--- a/net/bridge/br_switchdev.c
++++ b/net/bridge/br_switchdev.c
+@@ -17,6 +17,9 @@ static bool nbp_switchdev_can_offload_tx_fwd(const struct net_bridge_port *p,
+ if (!static_branch_unlikely(&br_switchdev_tx_fwd_offload))
+ return false;
+
++ if (br_multicast_igmp_type(skb))
++ return false;
++
+ return (p->flags & BR_TX_FWD_OFFLOAD) &&
+ (p->hwdom != BR_INPUT_SKB_CB(skb)->src_hwdom);
+ }
+--
+2.39.5
+
--- /dev/null
+From c93aeec620f846810401794d9cd16ceb59c6a889 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jul 2025 10:38:46 -0700
+Subject: net: emaclite: Fix missing pointer increment in aligned_read()
+
+From: Alok Tiwari <alok.a.tiwari@oracle.com>
+
+[ Upstream commit 7727ec1523d7973defa1dff8f9c0aad288d04008 ]
+
+Add missing post-increment operators for byte pointers in the
+loop that copies remaining bytes in xemaclite_aligned_read().
+Without the increment, the same byte was written repeatedly
+to the destination.
+This update aligns with xemaclite_aligned_write()
+
+Fixes: bb81b2ddfa19 ("net: add Xilinx emac lite device driver")
+Signed-off-by: Alok Tiwari <alok.a.tiwari@oracle.com>
+Link: https://patch.msgid.link/20250710173849.2381003-1-alok.a.tiwari@oracle.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/xilinx/xilinx_emaclite.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+index ecf47107146dc..4719d40a63ba3 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+@@ -286,7 +286,7 @@ static void xemaclite_aligned_read(u32 *src_ptr, u8 *dest_ptr,
+
+ /* Read the remaining data */
+ for (; length > 0; length--)
+- *to_u8_ptr = *from_u8_ptr;
++ *to_u8_ptr++ = *from_u8_ptr++;
+ }
+ }
+
+--
+2.39.5
+
--- /dev/null
+From d8568813c731bdbb002ded070f357f6661fa0061 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Jul 2025 17:06:21 +0200
+Subject: net: fix segmentation after TCP/UDP fraglist GRO
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit 9f735b6f8a77d7be7f8b0765dc93587774832cb1 ]
+
+Since "net: gro: use cb instead of skb->network_header", the skb network
+header is no longer set in the GRO path.
+This breaks fraglist segmentation, which relies on ip_hdr()/tcp_hdr()
+to check for address/port changes.
+Fix this regression by selectively setting the network header for merged
+segment skbs.
+
+Fixes: 186b1ea73ad8 ("net: gro: use cb instead of skb->network_header")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20250705150622.10699-1-nbd@nbd.name
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_offload.c | 1 +
+ net/ipv4/udp_offload.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c
+index d293087b426df..be5c2294610e5 100644
+--- a/net/ipv4/tcp_offload.c
++++ b/net/ipv4/tcp_offload.c
+@@ -359,6 +359,7 @@ struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb,
+ flush |= skb->ip_summed != p->ip_summed;
+ flush |= skb->csum_level != p->csum_level;
+ flush |= NAPI_GRO_CB(p)->count >= 64;
++ skb_set_network_header(skb, skb_gro_receive_network_offset(skb));
+
+ if (flush || skb_gro_receive_list(p, skb))
+ mss = 1;
+diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
+index 9b295b2878bef..a1aca63086777 100644
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -604,6 +604,7 @@ static struct sk_buff *udp_gro_receive_segment(struct list_head *head,
+ NAPI_GRO_CB(skb)->flush = 1;
+ return NULL;
+ }
++ skb_set_network_header(skb, skb_gro_receive_network_offset(skb));
+ ret = skb_gro_receive_list(p, skb);
+ } else {
+ skb_gro_postpull_rcsum(skb, uh,
+--
+2.39.5
+
--- /dev/null
+From d00687f9a7449a499a9fe8a19be5a10e7d4a0e50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Jul 2025 13:20:53 -0700
+Subject: net/mlx5: Correctly set gso_size when LRO is used
+
+From: Christoph Paasch <cpaasch@openai.com>
+
+[ Upstream commit 531d0d32de3e1b6b77a87bd37de0c2c6e17b496a ]
+
+gso_size is expected by the networking stack to be the size of the
+payload (thus, not including ethernet/IP/TCP-headers). However, cqe_bcnt
+is the full sized frame (including the headers). Dividing cqe_bcnt by
+lro_num_seg will then give incorrect results.
+
+For example, running a bpftrace higher up in the TCP-stack
+(tcp_event_data_recv), we commonly have gso_size set to 1450 or 1451 even
+though in reality the payload was only 1448 bytes.
+
+This can have unintended consequences:
+- In tcp_measure_rcv_mss() len will be for example 1450, but. rcv_mss
+will be 1448 (because tp->advmss is 1448). Thus, we will always
+recompute scaling_ratio each time an LRO-packet is received.
+- In tcp_gro_receive(), it will interfere with the decision whether or
+not to flush and thus potentially result in less gro'ed packets.
+
+So, we need to discount the protocol headers from cqe_bcnt so we can
+actually divide the payload by lro_num_seg to get the real gso_size.
+
+v2:
+ - Use "(unsigned char *)tcp + tcp->doff * 4 - skb->data)" to compute header-len
+ (Tariq Toukan <tariqt@nvidia.com>)
+ - Improve commit-message (Gal Pressman <gal@nvidia.com>)
+
+Fixes: e586b3b0baee ("net/mlx5: Ethernet Datapath files")
+Signed-off-by: Christoph Paasch <cpaasch@openai.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Gal Pressman <gal@nvidia.com>
+Link: https://patch.msgid.link/20250715-cpaasch-pf-925-investigate-incorrect-gso_size-on-cx-7-nic-v2-1-e06c3475f3ac@openai.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+index 5fd70b4d55beb..e37cf4f754c48 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+@@ -1154,8 +1154,9 @@ static void mlx5e_lro_update_tcp_hdr(struct mlx5_cqe64 *cqe, struct tcphdr *tcp)
+ }
+ }
+
+-static void mlx5e_lro_update_hdr(struct sk_buff *skb, struct mlx5_cqe64 *cqe,
+- u32 cqe_bcnt)
++static unsigned int mlx5e_lro_update_hdr(struct sk_buff *skb,
++ struct mlx5_cqe64 *cqe,
++ u32 cqe_bcnt)
+ {
+ struct ethhdr *eth = (struct ethhdr *)(skb->data);
+ struct tcphdr *tcp;
+@@ -1205,6 +1206,8 @@ static void mlx5e_lro_update_hdr(struct sk_buff *skb, struct mlx5_cqe64 *cqe,
+ tcp->check = tcp_v6_check(payload_len, &ipv6->saddr,
+ &ipv6->daddr, check);
+ }
++
++ return (unsigned int)((unsigned char *)tcp + tcp->doff * 4 - skb->data);
+ }
+
+ static void *mlx5e_shampo_get_packet_hd(struct mlx5e_rq *rq, u16 header_index)
+@@ -1561,8 +1564,9 @@ static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
+ mlx5e_macsec_offload_handle_rx_skb(netdev, skb, cqe);
+
+ if (lro_num_seg > 1) {
+- mlx5e_lro_update_hdr(skb, cqe, cqe_bcnt);
+- skb_shinfo(skb)->gso_size = DIV_ROUND_UP(cqe_bcnt, lro_num_seg);
++ unsigned int hdrlen = mlx5e_lro_update_hdr(skb, cqe, cqe_bcnt);
++
++ skb_shinfo(skb)->gso_size = DIV_ROUND_UP(cqe_bcnt - hdrlen, lro_num_seg);
+ /* Subtract one since we already counted this as one
+ * "regular" packet in mlx5e_complete_rx_cqe()
+ */
+--
+2.39.5
+
--- /dev/null
+From 2f55225e9c33c766dedb791ba7458489337e3509 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jul 2025 15:58:03 -0400
+Subject: net: phy: Don't register LEDs for genphy
+
+From: Sean Anderson <sean.anderson@linux.dev>
+
+[ Upstream commit f0f2b992d8185a0366be951685e08643aae17d6d ]
+
+If a PHY has no driver, the genphy driver is probed/removed directly in
+phy_attach/detach. If the PHY's ofnode has an "leds" subnode, then the
+LEDs will be (un)registered when probing/removing the genphy driver.
+This could occur if the leds are for a non-generic driver that isn't
+loaded for whatever reason. Synchronously removing the PHY device in
+phy_detach leads to the following deadlock:
+
+rtnl_lock()
+ndo_close()
+ ...
+ phy_detach()
+ phy_remove()
+ phy_leds_unregister()
+ led_classdev_unregister()
+ led_trigger_set()
+ netdev_trigger_deactivate()
+ unregister_netdevice_notifier()
+ rtnl_lock()
+
+There is a corresponding deadlock on the open/register side of things
+(and that one is reported by lockdep), but it requires a race while this
+one is deterministic.
+
+Generic PHYs do not support LEDs anyway, so don't bother registering
+them.
+
+Fixes: 01e5b728e9e4 ("net: phy: Add a binding for PHY LEDs")
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Link: https://patch.msgid.link/20250707195803.666097-1-sean.anderson@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/phy_device.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index 7d5e76a3db0e9..2f5bb4d0911d2 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -3391,7 +3391,8 @@ static int phy_probe(struct device *dev)
+ /* Get the LEDs from the device tree, and instantiate standard
+ * LEDs for them.
+ */
+- if (IS_ENABLED(CONFIG_PHYLIB_LEDS))
++ if (IS_ENABLED(CONFIG_PHYLIB_LEDS) && !phy_driver_is_genphy(phydev) &&
++ !phy_driver_is_genphy_10g(phydev))
+ err = of_phy_leds(phydev);
+
+ out:
+@@ -3408,7 +3409,8 @@ static int phy_remove(struct device *dev)
+
+ cancel_delayed_work_sync(&phydev->state_queue);
+
+- if (IS_ENABLED(CONFIG_PHYLIB_LEDS))
++ if (IS_ENABLED(CONFIG_PHYLIB_LEDS) && !phy_driver_is_genphy(phydev) &&
++ !phy_driver_is_genphy_10g(phydev))
+ phy_leds_unregister(phydev);
+
+ phydev->state = PHY_DOWN;
+--
+2.39.5
+
--- /dev/null
+From 1f98d940ba947d9b68005dcc8b5a4a0debe429bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jul 2025 02:28:38 +0000
+Subject: net/sched: Return NULL when htb_lookup_leaf encounters an empty
+ rbtree
+
+From: William Liu <will@willsroot.io>
+
+[ Upstream commit 0e1d5d9b5c5966e2e42e298670808590db5ed628 ]
+
+htb_lookup_leaf has a BUG_ON that can trigger with the following:
+
+tc qdisc del dev lo root
+tc qdisc add dev lo root handle 1: htb default 1
+tc class add dev lo parent 1: classid 1:1 htb rate 64bit
+tc qdisc add dev lo parent 1:1 handle 2: netem
+tc qdisc add dev lo parent 2:1 handle 3: blackhole
+ping -I lo -c1 -W0.001 127.0.0.1
+
+The root cause is the following:
+
+1. htb_dequeue calls htb_dequeue_tree which calls the dequeue handler on
+ the selected leaf qdisc
+2. netem_dequeue calls enqueue on the child qdisc
+3. blackhole_enqueue drops the packet and returns a value that is not
+ just NET_XMIT_SUCCESS
+4. Because of this, netem_dequeue calls qdisc_tree_reduce_backlog, and
+ since qlen is now 0, it calls htb_qlen_notify -> htb_deactivate ->
+ htb_deactiviate_prios -> htb_remove_class_from_row -> htb_safe_rb_erase
+5. As this is the only class in the selected hprio rbtree,
+ __rb_change_child in __rb_erase_augmented sets the rb_root pointer to
+ NULL
+6. Because blackhole_dequeue returns NULL, netem_dequeue returns NULL,
+ which causes htb_dequeue_tree to call htb_lookup_leaf with the same
+ hprio rbtree, and fail the BUG_ON
+
+The function graph for this scenario is shown here:
+ 0) | htb_enqueue() {
+ 0) + 13.635 us | netem_enqueue();
+ 0) 4.719 us | htb_activate_prios();
+ 0) # 2249.199 us | }
+ 0) | htb_dequeue() {
+ 0) 2.355 us | htb_lookup_leaf();
+ 0) | netem_dequeue() {
+ 0) + 11.061 us | blackhole_enqueue();
+ 0) | qdisc_tree_reduce_backlog() {
+ 0) | qdisc_lookup_rcu() {
+ 0) 1.873 us | qdisc_match_from_root();
+ 0) 6.292 us | }
+ 0) 1.894 us | htb_search();
+ 0) | htb_qlen_notify() {
+ 0) 2.655 us | htb_deactivate_prios();
+ 0) 6.933 us | }
+ 0) + 25.227 us | }
+ 0) 1.983 us | blackhole_dequeue();
+ 0) + 86.553 us | }
+ 0) # 2932.761 us | qdisc_warn_nonwc();
+ 0) | htb_lookup_leaf() {
+ 0) | BUG_ON();
+ ------------------------------------------
+
+The full original bug report can be seen here [1].
+
+We can fix this just by returning NULL instead of the BUG_ON,
+as htb_dequeue_tree returns NULL when htb_lookup_leaf returns
+NULL.
+
+[1] https://lore.kernel.org/netdev/pF5XOOIim0IuEfhI-SOxTgRvNoDwuux7UHKnE_Y5-zVd4wmGvNk2ceHjKb8ORnzw0cGwfmVu42g9dL7XyJLf1NEzaztboTWcm0Ogxuojoeo=@willsroot.io/
+
+Fixes: 512bb43eb542 ("pkt_sched: sch_htb: Optimize WARN_ONs in htb_dequeue_tree() etc.")
+Signed-off-by: William Liu <will@willsroot.io>
+Signed-off-by: Savino Dicanosa <savy@syst3mfailure.io>
+Link: https://patch.msgid.link/20250717022816.221364-1-will@willsroot.io
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_htb.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
+index 14bf71f570570..c968ea7637746 100644
+--- a/net/sched/sch_htb.c
++++ b/net/sched/sch_htb.c
+@@ -821,7 +821,9 @@ static struct htb_class *htb_lookup_leaf(struct htb_prio *hprio, const int prio)
+ u32 *pid;
+ } stk[TC_HTB_MAXDEPTH], *sp = stk;
+
+- BUG_ON(!hprio->row.rb_node);
++ if (unlikely(!hprio->row.rb_node))
++ return NULL;
++
+ sp->root = hprio->row.rb_node;
+ sp->pptr = &hprio->ptr;
+ sp->pid = &hprio->last_ptr_id;
+--
+2.39.5
+
--- /dev/null
+From 8027b5a09f001570e9554ebcf9ee16d033f9b31a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jul 2025 03:09:42 -0700
+Subject: net/sched: sch_qfq: Fix race condition on qfq_aggregate
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit 5e28d5a3f774f118896aec17a3a20a9c5c9dfc64 ]
+
+A race condition can occur when 'agg' is modified in qfq_change_agg
+(called during qfq_enqueue) while other threads access it
+concurrently. For example, qfq_dump_class may trigger a NULL
+dereference, and qfq_delete_class may cause a use-after-free.
+
+This patch addresses the issue by:
+
+1. Moved qfq_destroy_class into the critical section.
+
+2. Added sch_tree_lock protection to qfq_dump_class and
+qfq_dump_class_stats.
+
+Fixes: 462dbc9101ac ("pkt_sched: QFQ Plus: fair-queueing service at DRR cost")
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Reviewed-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_qfq.c | 30 +++++++++++++++++++++---------
+ 1 file changed, 21 insertions(+), 9 deletions(-)
+
+diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
+index bf1282cb22eba..2b1b025c31a33 100644
+--- a/net/sched/sch_qfq.c
++++ b/net/sched/sch_qfq.c
+@@ -412,7 +412,7 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
+ bool existing = false;
+ struct nlattr *tb[TCA_QFQ_MAX + 1];
+ struct qfq_aggregate *new_agg = NULL;
+- u32 weight, lmax, inv_w;
++ u32 weight, lmax, inv_w, old_weight, old_lmax;
+ int err;
+ int delta_w;
+
+@@ -443,12 +443,16 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
+ inv_w = ONE_FP / weight;
+ weight = ONE_FP / inv_w;
+
+- if (cl != NULL &&
+- lmax == cl->agg->lmax &&
+- weight == cl->agg->class_weight)
+- return 0; /* nothing to change */
++ if (cl != NULL) {
++ sch_tree_lock(sch);
++ old_weight = cl->agg->class_weight;
++ old_lmax = cl->agg->lmax;
++ sch_tree_unlock(sch);
++ if (lmax == old_lmax && weight == old_weight)
++ return 0; /* nothing to change */
++ }
+
+- delta_w = weight - (cl ? cl->agg->class_weight : 0);
++ delta_w = weight - (cl ? old_weight : 0);
+
+ if (q->wsum + delta_w > QFQ_MAX_WSUM) {
+ NL_SET_ERR_MSG_FMT_MOD(extack,
+@@ -555,10 +559,10 @@ static int qfq_delete_class(struct Qdisc *sch, unsigned long arg,
+
+ qdisc_purge_queue(cl->qdisc);
+ qdisc_class_hash_remove(&q->clhash, &cl->common);
++ qfq_destroy_class(sch, cl);
+
+ sch_tree_unlock(sch);
+
+- qfq_destroy_class(sch, cl);
+ return 0;
+ }
+
+@@ -625,6 +629,7 @@ static int qfq_dump_class(struct Qdisc *sch, unsigned long arg,
+ {
+ struct qfq_class *cl = (struct qfq_class *)arg;
+ struct nlattr *nest;
++ u32 class_weight, lmax;
+
+ tcm->tcm_parent = TC_H_ROOT;
+ tcm->tcm_handle = cl->common.classid;
+@@ -633,8 +638,13 @@ static int qfq_dump_class(struct Qdisc *sch, unsigned long arg,
+ nest = nla_nest_start_noflag(skb, TCA_OPTIONS);
+ if (nest == NULL)
+ goto nla_put_failure;
+- if (nla_put_u32(skb, TCA_QFQ_WEIGHT, cl->agg->class_weight) ||
+- nla_put_u32(skb, TCA_QFQ_LMAX, cl->agg->lmax))
++
++ sch_tree_lock(sch);
++ class_weight = cl->agg->class_weight;
++ lmax = cl->agg->lmax;
++ sch_tree_unlock(sch);
++ if (nla_put_u32(skb, TCA_QFQ_WEIGHT, class_weight) ||
++ nla_put_u32(skb, TCA_QFQ_LMAX, lmax))
+ goto nla_put_failure;
+ return nla_nest_end(skb, nest);
+
+@@ -651,8 +661,10 @@ static int qfq_dump_class_stats(struct Qdisc *sch, unsigned long arg,
+
+ memset(&xstats, 0, sizeof(xstats));
+
++ sch_tree_lock(sch);
+ xstats.weight = cl->agg->class_weight;
+ xstats.lmax = cl->agg->lmax;
++ sch_tree_unlock(sch);
+
+ if (gnet_stats_copy_basic(d, NULL, &cl->bstats, true) < 0 ||
+ gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 ||
+--
+2.39.5
+
--- /dev/null
+From 639bf3b19841cb576abfdcb038ee2d7623cd3d9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jul 2025 11:45:03 +0800
+Subject: net: vlan: fix VLAN 0 refcount imbalance of toggling filtering during
+ runtime
+
+From: Dong Chenchen <dongchenchen2@huawei.com>
+
+[ Upstream commit 579d4f9ca9a9a605184a9b162355f6ba131f678d ]
+
+Assuming the "rx-vlan-filter" feature is enabled on a net device, the
+8021q module will automatically add or remove VLAN 0 when the net device
+is put administratively up or down, respectively. There are a couple of
+problems with the above scheme.
+
+The first problem is a memory leak that can happen if the "rx-vlan-filter"
+feature is disabled while the device is running:
+
+ # ip link add bond1 up type bond mode 0
+ # ethtool -K bond1 rx-vlan-filter off
+ # ip link del dev bond1
+
+When the device is put administratively down the "rx-vlan-filter"
+feature is disabled, so the 8021q module will not remove VLAN 0 and the
+memory will be leaked [1].
+
+Another problem that can happen is that the kernel can automatically
+delete VLAN 0 when the device is put administratively down despite not
+adding it when the device was put administratively up since during that
+time the "rx-vlan-filter" feature was disabled. null-ptr-unref or
+bug_on[2] will be triggered by unregister_vlan_dev() for refcount
+imbalance if toggling filtering during runtime:
+
+$ ip link add bond0 type bond mode 0
+$ ip link add link bond0 name vlan0 type vlan id 0 protocol 802.1q
+$ ethtool -K bond0 rx-vlan-filter off
+$ ifconfig bond0 up
+$ ethtool -K bond0 rx-vlan-filter on
+$ ifconfig bond0 down
+$ ip link del vlan0
+
+Root cause is as below:
+step1: add vlan0 for real_dev, such as bond, team.
+register_vlan_dev
+ vlan_vid_add(real_dev,htons(ETH_P_8021Q),0) //refcnt=1
+step2: disable vlan filter feature and enable real_dev
+step3: change filter from 0 to 1
+vlan_device_event
+ vlan_filter_push_vids
+ ndo_vlan_rx_add_vid //No refcnt added to real_dev vlan0
+step4: real_dev down
+vlan_device_event
+ vlan_vid_del(dev, htons(ETH_P_8021Q), 0); //refcnt=0
+ vlan_info_rcu_free //free vlan0
+step5: delete vlan0
+unregister_vlan_dev
+ BUG_ON(!vlan_info); //vlan_info is null
+
+Fix both problems by noting in the VLAN info whether VLAN 0 was
+automatically added upon NETDEV_UP and based on that decide whether it
+should be deleted upon NETDEV_DOWN, regardless of the state of the
+"rx-vlan-filter" feature.
+
+[1]
+unreferenced object 0xffff8880068e3100 (size 256):
+ comm "ip", pid 384, jiffies 4296130254
+ hex dump (first 32 bytes):
+ 00 20 30 0d 80 88 ff ff 00 00 00 00 00 00 00 00 . 0.............
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ backtrace (crc 81ce31fa):
+ __kmalloc_cache_noprof+0x2b5/0x340
+ vlan_vid_add+0x434/0x940
+ vlan_device_event.cold+0x75/0xa8
+ notifier_call_chain+0xca/0x150
+ __dev_notify_flags+0xe3/0x250
+ rtnl_configure_link+0x193/0x260
+ rtnl_newlink_create+0x383/0x8e0
+ __rtnl_newlink+0x22c/0xa40
+ rtnl_newlink+0x627/0xb00
+ rtnetlink_rcv_msg+0x6fb/0xb70
+ netlink_rcv_skb+0x11f/0x350
+ netlink_unicast+0x426/0x710
+ netlink_sendmsg+0x75a/0xc20
+ __sock_sendmsg+0xc1/0x150
+ ____sys_sendmsg+0x5aa/0x7b0
+ ___sys_sendmsg+0xfc/0x180
+
+[2]
+kernel BUG at net/8021q/vlan.c:99!
+Oops: invalid opcode: 0000 [#1] SMP KASAN PTI
+CPU: 0 UID: 0 PID: 382 Comm: ip Not tainted 6.16.0-rc3 #61 PREEMPT(voluntary)
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
+BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
+RIP: 0010:unregister_vlan_dev (net/8021q/vlan.c:99 (discriminator 1))
+RSP: 0018:ffff88810badf310 EFLAGS: 00010246
+RAX: 0000000000000000 RBX: ffff88810da84000 RCX: ffffffffb47ceb9a
+RDX: dffffc0000000000 RSI: 0000000000000008 RDI: ffff88810e8b43c8
+RBP: 0000000000000000 R08: 0000000000000000 R09: fffffbfff6cefe80
+R10: ffffffffb677f407 R11: ffff88810badf3c0 R12: ffff88810e8b4000
+R13: 0000000000000000 R14: ffff88810642a5c0 R15: 000000000000017e
+FS: 00007f1ff68c20c0(0000) GS:ffff888163a24000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f1ff5dad240 CR3: 0000000107e56000 CR4: 00000000000006f0
+Call Trace:
+ <TASK>
+rtnl_dellink (net/core/rtnetlink.c:3511 net/core/rtnetlink.c:3553)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6945)
+netlink_rcv_skb (net/netlink/af_netlink.c:2535)
+netlink_unicast (net/netlink/af_netlink.c:1314 net/netlink/af_netlink.c:1339)
+netlink_sendmsg (net/netlink/af_netlink.c:1883)
+____sys_sendmsg (net/socket.c:712 net/socket.c:727 net/socket.c:2566)
+___sys_sendmsg (net/socket.c:2622)
+__sys_sendmsg (net/socket.c:2652)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+
+Fixes: ad1afb003939 ("vlan_dev: VLAN 0 should be treated as "no vlan tag" (802.1p packet)")
+Reported-by: syzbot+a8b046e462915c65b10b@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=a8b046e462915c65b10b
+Suggested-by: Ido Schimmel <idosch@idosch.org>
+Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20250716034504.2285203-2-dongchenchen2@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/8021q/vlan.c | 42 +++++++++++++++++++++++++++++++++---------
+ net/8021q/vlan.h | 1 +
+ 2 files changed, 34 insertions(+), 9 deletions(-)
+
+diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
+index 41be38264493d..49a6d49c23dc5 100644
+--- a/net/8021q/vlan.c
++++ b/net/8021q/vlan.c
+@@ -358,6 +358,35 @@ static int __vlan_device_event(struct net_device *dev, unsigned long event)
+ return err;
+ }
+
++static void vlan_vid0_add(struct net_device *dev)
++{
++ struct vlan_info *vlan_info;
++ int err;
++
++ if (!(dev->features & NETIF_F_HW_VLAN_CTAG_FILTER))
++ return;
++
++ pr_info("adding VLAN 0 to HW filter on device %s\n", dev->name);
++
++ err = vlan_vid_add(dev, htons(ETH_P_8021Q), 0);
++ if (err)
++ return;
++
++ vlan_info = rtnl_dereference(dev->vlan_info);
++ vlan_info->auto_vid0 = true;
++}
++
++static void vlan_vid0_del(struct net_device *dev)
++{
++ struct vlan_info *vlan_info = rtnl_dereference(dev->vlan_info);
++
++ if (!vlan_info || !vlan_info->auto_vid0)
++ return;
++
++ vlan_info->auto_vid0 = false;
++ vlan_vid_del(dev, htons(ETH_P_8021Q), 0);
++}
++
+ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
+ void *ptr)
+ {
+@@ -379,15 +408,10 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
+ return notifier_from_errno(err);
+ }
+
+- if ((event == NETDEV_UP) &&
+- (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) {
+- pr_info("adding VLAN 0 to HW filter on device %s\n",
+- dev->name);
+- vlan_vid_add(dev, htons(ETH_P_8021Q), 0);
+- }
+- if (event == NETDEV_DOWN &&
+- (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER))
+- vlan_vid_del(dev, htons(ETH_P_8021Q), 0);
++ if (event == NETDEV_UP)
++ vlan_vid0_add(dev);
++ else if (event == NETDEV_DOWN)
++ vlan_vid0_del(dev);
+
+ vlan_info = rtnl_dereference(dev->vlan_info);
+ if (!vlan_info)
+diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h
+index 5eaf38875554b..c7ffe591d5936 100644
+--- a/net/8021q/vlan.h
++++ b/net/8021q/vlan.h
+@@ -33,6 +33,7 @@ struct vlan_info {
+ struct vlan_group grp;
+ struct list_head vid_list;
+ unsigned int nr_vids;
++ bool auto_vid0;
+ struct rcu_head rcu;
+ };
+
+--
+2.39.5
+
--- /dev/null
+From 08e2c01b21881528fddadf60cc30deeb6bbbbb20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jul 2025 20:39:14 +0200
+Subject: netfilter: nf_conntrack: fix crash due to removal of uninitialised
+ entry
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 2d72afb340657f03f7261e9243b44457a9228ac7 ]
+
+A crash in conntrack was reported while trying to unlink the conntrack
+entry from the hash bucket list:
+ [exception RIP: __nf_ct_delete_from_lists+172]
+ [..]
+ #7 [ff539b5a2b043aa0] nf_ct_delete at ffffffffc124d421 [nf_conntrack]
+ #8 [ff539b5a2b043ad0] nf_ct_gc_expired at ffffffffc124d999 [nf_conntrack]
+ #9 [ff539b5a2b043ae0] __nf_conntrack_find_get at ffffffffc124efbc [nf_conntrack]
+ [..]
+
+The nf_conn struct is marked as allocated from slab but appears to be in
+a partially initialised state:
+
+ ct hlist pointer is garbage; looks like the ct hash value
+ (hence crash).
+ ct->status is equal to IPS_CONFIRMED|IPS_DYING, which is expected
+ ct->timeout is 30000 (=30s), which is unexpected.
+
+Everything else looks like normal udp conntrack entry. If we ignore
+ct->status and pretend its 0, the entry matches those that are newly
+allocated but not yet inserted into the hash:
+ - ct hlist pointers are overloaded and store/cache the raw tuple hash
+ - ct->timeout matches the relative time expected for a new udp flow
+ rather than the absolute 'jiffies' value.
+
+If it were not for the presence of IPS_CONFIRMED,
+__nf_conntrack_find_get() would have skipped the entry.
+
+Theory is that we did hit following race:
+
+cpu x cpu y cpu z
+ found entry E found entry E
+ E is expired <preemption>
+ nf_ct_delete()
+ return E to rcu slab
+ init_conntrack
+ E is re-inited,
+ ct->status set to 0
+ reply tuplehash hnnode.pprev
+ stores hash value.
+
+cpu y found E right before it was deleted on cpu x.
+E is now re-inited on cpu z. cpu y was preempted before
+checking for expiry and/or confirm bit.
+
+ ->refcnt set to 1
+ E now owned by skb
+ ->timeout set to 30000
+
+If cpu y were to resume now, it would observe E as
+expired but would skip E due to missing CONFIRMED bit.
+
+ nf_conntrack_confirm gets called
+ sets: ct->status |= CONFIRMED
+ This is wrong: E is not yet added
+ to hashtable.
+
+cpu y resumes, it observes E as expired but CONFIRMED:
+ <resumes>
+ nf_ct_expired()
+ -> yes (ct->timeout is 30s)
+ confirmed bit set.
+
+cpu y will try to delete E from the hashtable:
+ nf_ct_delete() -> set DYING bit
+ __nf_ct_delete_from_lists
+
+Even this scenario doesn't guarantee a crash:
+cpu z still holds the table bucket lock(s) so y blocks:
+
+ wait for spinlock held by z
+
+ CONFIRMED is set but there is no
+ guarantee ct will be added to hash:
+ "chaintoolong" or "clash resolution"
+ logic both skip the insert step.
+ reply hnnode.pprev still stores the
+ hash value.
+
+ unlocks spinlock
+ return NF_DROP
+ <unblocks, then
+ crashes on hlist_nulls_del_rcu pprev>
+
+In case CPU z does insert the entry into the hashtable, cpu y will unlink
+E again right away but no crash occurs.
+
+Without 'cpu y' race, 'garbage' hlist is of no consequence:
+ct refcnt remains at 1, eventually skb will be free'd and E gets
+destroyed via: nf_conntrack_put -> nf_conntrack_destroy -> nf_ct_destroy.
+
+To resolve this, move the IPS_CONFIRMED assignment after the table
+insertion but before the unlock.
+
+Pablo points out that the confirm-bit-store could be reordered to happen
+before hlist add resp. the timeout fixup, so switch to set_bit and
+before_atomic memory barrier to prevent this.
+
+It doesn't matter if other CPUs can observe a newly inserted entry right
+before the CONFIRMED bit was set:
+
+Such event cannot be distinguished from above "E is the old incarnation"
+case: the entry will be skipped.
+
+Also change nf_ct_should_gc() to first check the confirmed bit.
+
+The gc sequence is:
+ 1. Check if entry has expired, if not skip to next entry
+ 2. Obtain a reference to the expired entry.
+ 3. Call nf_ct_should_gc() to double-check step 1.
+
+nf_ct_should_gc() is thus called only for entries that already failed an
+expiry check. After this patch, once the confirmed bit check passes
+ct->timeout has been altered to reflect the absolute 'best before' date
+instead of a relative time. Step 3 will therefore not remove the entry.
+
+Without this change to nf_ct_should_gc() we could still get this sequence:
+
+ 1. Check if entry has expired.
+ 2. Obtain a reference.
+ 3. Call nf_ct_should_gc() to double-check step 1:
+ 4 - entry is still observed as expired
+ 5 - meanwhile, ct->timeout is corrected to absolute value on other CPU
+ and confirm bit gets set
+ 6 - confirm bit is seen
+ 7 - valid entry is removed again
+
+First do check 6), then 4) so the gc expiry check always picks up either
+confirmed bit unset (entry gets skipped) or expiry re-check failure for
+re-inited conntrack objects.
+
+This change cannot be backported to releases before 5.19. Without
+commit 8a75a2c17410 ("netfilter: conntrack: remove unconfirmed list")
+|= IPS_CONFIRMED line cannot be moved without further changes.
+
+Cc: Razvan Cojocaru <rzvncj@gmail.com>
+Link: https://lore.kernel.org/netfilter-devel/20250627142758.25664-1-fw@strlen.de/
+Link: https://lore.kernel.org/netfilter-devel/4239da15-83ff-4ca4-939d-faef283471bb@gmail.com/
+Fixes: 1397af5bfd7d ("netfilter: conntrack: remove the percpu dying list")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netfilter/nf_conntrack.h | 15 +++++++++++++--
+ net/netfilter/nf_conntrack_core.c | 26 ++++++++++++++++++++------
+ 2 files changed, 33 insertions(+), 8 deletions(-)
+
+diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
+index 3f02a45773e81..ca26274196b99 100644
+--- a/include/net/netfilter/nf_conntrack.h
++++ b/include/net/netfilter/nf_conntrack.h
+@@ -306,8 +306,19 @@ static inline bool nf_ct_is_expired(const struct nf_conn *ct)
+ /* use after obtaining a reference count */
+ static inline bool nf_ct_should_gc(const struct nf_conn *ct)
+ {
+- return nf_ct_is_expired(ct) && nf_ct_is_confirmed(ct) &&
+- !nf_ct_is_dying(ct);
++ if (!nf_ct_is_confirmed(ct))
++ return false;
++
++ /* load ct->timeout after is_confirmed() test.
++ * Pairs with __nf_conntrack_confirm() which:
++ * 1. Increases ct->timeout value
++ * 2. Inserts ct into rcu hlist
++ * 3. Sets the confirmed bit
++ * 4. Unlocks the hlist lock
++ */
++ smp_acquire__after_ctrl_dep();
++
++ return nf_ct_is_expired(ct) && !nf_ct_is_dying(ct);
+ }
+
+ #define NF_CT_DAY (86400 * HZ)
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index 7f8b245e287ae..e720505177607 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -1121,6 +1121,12 @@ static int nf_ct_resolve_clash_harder(struct sk_buff *skb, u32 repl_idx)
+
+ hlist_nulls_add_head_rcu(&loser_ct->tuplehash[IP_CT_DIR_REPLY].hnnode,
+ &nf_conntrack_hash[repl_idx]);
++ /* confirmed bit must be set after hlist add, not before:
++ * loser_ct can still be visible to other cpu due to
++ * SLAB_TYPESAFE_BY_RCU.
++ */
++ smp_mb__before_atomic();
++ set_bit(IPS_CONFIRMED_BIT, &loser_ct->status);
+
+ NF_CT_STAT_INC(net, clash_resolve);
+ return NF_ACCEPT;
+@@ -1257,8 +1263,6 @@ __nf_conntrack_confirm(struct sk_buff *skb)
+ * user context, else we insert an already 'dead' hash, blocking
+ * further use of that particular connection -JM.
+ */
+- ct->status |= IPS_CONFIRMED;
+-
+ if (unlikely(nf_ct_is_dying(ct))) {
+ NF_CT_STAT_INC(net, insert_failed);
+ goto dying;
+@@ -1290,7 +1294,7 @@ __nf_conntrack_confirm(struct sk_buff *skb)
+ }
+ }
+
+- /* Timer relative to confirmation time, not original
++ /* Timeout is relative to confirmation time, not original
+ setting time, otherwise we'd get timer wrap in
+ weird delay cases. */
+ ct->timeout += nfct_time_stamp;
+@@ -1298,11 +1302,21 @@ __nf_conntrack_confirm(struct sk_buff *skb)
+ __nf_conntrack_insert_prepare(ct);
+
+ /* Since the lookup is lockless, hash insertion must be done after
+- * starting the timer and setting the CONFIRMED bit. The RCU barriers
+- * guarantee that no other CPU can find the conntrack before the above
+- * stores are visible.
++ * setting ct->timeout. The RCU barriers guarantee that no other CPU
++ * can find the conntrack before the above stores are visible.
+ */
+ __nf_conntrack_hash_insert(ct, hash, reply_hash);
++
++ /* IPS_CONFIRMED unset means 'ct not (yet) in hash', conntrack lookups
++ * skip entries that lack this bit. This happens when a CPU is looking
++ * at a stale entry that is being recycled due to SLAB_TYPESAFE_BY_RCU
++ * or when another CPU encounters this entry right after the insertion
++ * but before the set-confirm-bit below. This bit must not be set until
++ * after __nf_conntrack_hash_insert().
++ */
++ smp_mb__before_atomic();
++ set_bit(IPS_CONFIRMED_BIT, &ct->status);
++
+ nf_conntrack_double_unlock(hash, reply_hash);
+ local_bh_enable();
+
+--
+2.39.5
+
--- /dev/null
+From 8d4114500a3e42a60d3302fff8a9c90ae3f4a3f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Jun 2025 16:21:53 +0000
+Subject: nvme: fix endianness of command word prints in
+ nvme_log_err_passthru()
+
+From: John Garry <john.g.garry@oracle.com>
+
+[ Upstream commit dd8e34afd6709cb2f9c0e63340f567e6c066ed8e ]
+
+The command word members of struct nvme_common_command are __le32 type,
+so use helper le32_to_cpu() to read them properly.
+
+Fixes: 9f079dda1433 ("nvme: allow passthru cmd error logging")
+Signed-off-by: John Garry <john.g.garry@oracle.com>
+Reviewed-by: Alan Adamson <alan.adamson@oracle.com>
+Reviewed-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 300e33e4742a5..8ba56017f917e 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -377,12 +377,12 @@ static void nvme_log_err_passthru(struct request *req)
+ nr->status & NVME_SC_MASK, /* Status Code */
+ nr->status & NVME_STATUS_MORE ? "MORE " : "",
+ nr->status & NVME_STATUS_DNR ? "DNR " : "",
+- nr->cmd->common.cdw10,
+- nr->cmd->common.cdw11,
+- nr->cmd->common.cdw12,
+- nr->cmd->common.cdw13,
+- nr->cmd->common.cdw14,
+- nr->cmd->common.cdw15);
++ le32_to_cpu(nr->cmd->common.cdw10),
++ le32_to_cpu(nr->cmd->common.cdw11),
++ le32_to_cpu(nr->cmd->common.cdw12),
++ le32_to_cpu(nr->cmd->common.cdw13),
++ le32_to_cpu(nr->cmd->common.cdw14),
++ le32_to_cpu(nr->cmd->common.cdw15));
+ }
+
+ enum nvme_disposition {
+--
+2.39.5
+
--- /dev/null
+From 4110b5abaa04b85592b553f19e46cd735a3f12dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Jul 2025 15:17:17 +0800
+Subject: nvme: fix inconsistent RCU list manipulation in
+ nvme_ns_add_to_ctrl_list()
+
+From: Zheng Qixing <zhengqixing@huawei.com>
+
+[ Upstream commit 80d7762e0a42307ee31b21f090e21349b98c14f6 ]
+
+When inserting a namespace into the controller's namespace list, the
+function uses list_add_rcu() when the namespace is inserted in the middle
+of the list, but falls back to a regular list_add() when adding at the
+head of the list.
+
+This inconsistency could lead to race conditions during concurrent
+access, as users might observe a partially updated list. Fix this by
+consistently using list_add_rcu() in both code paths to ensure proper
+RCU protection throughout the entire function.
+
+Fixes: be647e2c76b2 ("nvme: use srcu for iterating namespace list")
+Signed-off-by: Zheng Qixing <zhengqixing@huawei.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index ae584c97f5284..300e33e4742a5 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -3889,7 +3889,7 @@ static void nvme_ns_add_to_ctrl_list(struct nvme_ns *ns)
+ return;
+ }
+ }
+- list_add(&ns->list, &ns->ctrl->namespaces);
++ list_add_rcu(&ns->list, &ns->ctrl->namespaces);
+ }
+
+ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, struct nvme_ns_info *info)
+--
+2.39.5
+
--- /dev/null
+From 134e3e8296baacbc0b25d91c53ddced0ded69141 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Jul 2025 09:28:12 +0800
+Subject: nvme: fix misaccounting of nvme-mpath inflight I/O
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 71257925e83eae1cb6913d65ca71927d2220e6d1 ]
+
+Procedures for nvme-mpath IO accounting:
+
+ 1) initialize nvme_request and clear flags;
+ 2) set NVME_MPATH_IO_STATS and increase inflight counter when IO
+ started;
+ 3) check NVME_MPATH_IO_STATS and decrease inflight counter when IO is
+ done;
+
+However, for the case nvme_fail_nonready_command(), both step 1) and 2)
+are skipped, and if old nvme_request set NVME_MPATH_IO_STATS and then
+request is reused, step 3) will still be executed, causing inflight I/O
+counter to be negative.
+
+Fix the problem by clearing nvme_request in nvme_fail_nonready_command().
+
+Fixes: ea5e5f42cd2c ("nvme-fabrics: avoid double completions in nvmf_fail_nonready_command")
+Reported-by: Yi Zhang <yi.zhang@redhat.com>
+Closes: https://lore.kernel.org/all/CAHj4cs_+dauobyYyP805t33WMJVzOWj=7+51p4_j9rA63D9sog@mail.gmail.com/
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 89a0f2a6c6268..88fec86b8baae 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -759,6 +759,10 @@ blk_status_t nvme_fail_nonready_command(struct nvme_ctrl *ctrl,
+ !test_bit(NVME_CTRL_FAILFAST_EXPIRED, &ctrl->flags) &&
+ !blk_noretry_request(rq) && !(rq->cmd_flags & REQ_NVME_MPATH))
+ return BLK_STS_RESOURCE;
++
++ if (!(rq->rq_flags & RQF_DONTPREP))
++ nvme_clear_nvme_request(rq);
++
+ return nvme_host_path_error(rq);
+ }
+ EXPORT_SYMBOL_GPL(nvme_fail_nonready_command);
+--
+2.39.5
+
--- /dev/null
+From dc0c5fdb780b73a8d9ddb59f9662917691e50a91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Jul 2025 11:54:08 +0200
+Subject: nvme: revert the cross-controller atomic write size validation
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 1fc09f2961f5c6d8bb53bc989f17b12fdc6bc93d ]
+
+This was originally added by commit 8695f060a029 ("nvme: all namespaces
+in a subsystem must adhere to a common atomic write size") to check
+the all controllers in a subsystem report the same atomic write size,
+but the check wasn't quite correct and caused problems for devices
+with multiple namespaces that report different LBA sizes. Commit
+f46d273449ba ("nvme: fix atomic write size validation") tried to fix
+this, but then caused problems for namespace rediscovery after a
+format with an LBA size change that changes the AWUPF value.
+
+This drops the validation and essentially reverts those two commits while
+keeping the cleanup that went in between the two. We'll need to figure
+out how to properly check for the mouse trap that nvme left us, but for
+now revert the check to keep devices working for users who couldn't care
+less about the atomic write feature.
+
+Fixes: 8695f060a029 ("nvme: all namespaces in a subsystem must adhere to a common atomic write size")
+Fixes: f46d273449ba ("nvme: fix atomic write size validation")
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Alan Adamson <alan.adamson@oracle.com>
+Reviewed-by: Keith Busch <kbusch@kernel.org>
+Reviewed-by: John Garry <john.g.garry@oracle.com>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Tested-by: Alan Adamson <alan.adamson@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 9 ---------
+ 1 file changed, 9 deletions(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 8ba56017f917e..89a0f2a6c6268 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -3354,15 +3354,6 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl)
+ if (ret)
+ goto out_free;
+ }
+-
+- if (le16_to_cpu(id->awupf) != ctrl->subsys->awupf) {
+- dev_err_ratelimited(ctrl->device,
+- "inconsistent AWUPF, controller not added (%u/%u).\n",
+- le16_to_cpu(id->awupf), ctrl->subsys->awupf);
+- ret = -EINVAL;
+- goto out_free;
+- }
+-
+ memcpy(ctrl->subsys->firmware_rev, id->fr,
+ sizeof(ctrl->subsys->firmware_rev));
+
+--
+2.39.5
+
--- /dev/null
+From e224988e87b0998f67d69ab7397dee724ead76e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Jul 2025 16:44:54 +0200
+Subject: nvmet-tcp: fix callback lock for TLS handshake
+
+From: Maurizio Lombardi <mlombard@redhat.com>
+
+[ Upstream commit 0523c6cc87e558c50ff4489c87c54c55068b1169 ]
+
+When restoring the default socket callbacks during a TLS handshake, we
+need to acquire a write lock on sk_callback_lock. Previously, a read
+lock was used, which is insufficient for modifying sk_user_data and
+sk_data_ready.
+
+Fixes: 675b453e0241 ("nvmet-tcp: enable TLS handshake upcall")
+Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/tcp.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
+index 12a5cb8641ca3..de70ff9102538 100644
+--- a/drivers/nvme/target/tcp.c
++++ b/drivers/nvme/target/tcp.c
+@@ -1967,10 +1967,10 @@ static void nvmet_tcp_alloc_queue(struct nvmet_tcp_port *port,
+ struct sock *sk = queue->sock->sk;
+
+ /* Restore the default callbacks before starting upcall */
+- read_lock_bh(&sk->sk_callback_lock);
++ write_lock_bh(&sk->sk_callback_lock);
+ sk->sk_user_data = NULL;
+ sk->sk_data_ready = port->data_ready;
+- read_unlock_bh(&sk->sk_callback_lock);
++ write_unlock_bh(&sk->sk_callback_lock);
+ if (!nvmet_tcp_try_peek_pdu(queue)) {
+ if (!nvmet_tcp_tls_handshake(queue))
+ return;
+--
+2.39.5
+
--- /dev/null
+From 2ad8b537e297bd61129ba5d4b12b933cb6c967d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Jun 2025 14:25:49 +0300
+Subject: phy: use per-PHY lockdep keys
+
+From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+
+[ Upstream commit cf0233491b3a15933234a26efd9ecbc1c0764674 ]
+
+If the PHY driver uses another PHY internally (e.g. in case of eUSB2,
+repeaters are represented as PHYs), then it would trigger the following
+lockdep splat because all PHYs use a single static lockdep key and thus
+lockdep can not identify whether there is a dependency or not and
+reports a false positive.
+
+Make PHY subsystem use dynamic lockdep keys, assigning each driver a
+separate key. This way lockdep can correctly identify dependency graph
+between mutexes.
+
+ ============================================
+ WARNING: possible recursive locking detected
+ 6.15.0-rc7-next-20250522-12896-g3932f283970c #3455 Not tainted
+ --------------------------------------------
+ kworker/u51:0/78 is trying to acquire lock:
+ ffff0008116554f0 (&phy->mutex){+.+.}-{4:4}, at: phy_init+0x4c/0x12c
+
+ but task is already holding lock:
+ ffff000813c10cf0 (&phy->mutex){+.+.}-{4:4}, at: phy_init+0x4c/0x12c
+
+ other info that might help us debug this:
+ Possible unsafe locking scenario:
+
+ CPU0
+ ----
+ lock(&phy->mutex);
+ lock(&phy->mutex);
+
+ *** DEADLOCK ***
+
+ May be due to missing lock nesting notation
+
+ 4 locks held by kworker/u51:0/78:
+ #0: ffff000800010948 ((wq_completion)events_unbound){+.+.}-{0:0}, at: process_one_work+0x18c/0x5ec
+ #1: ffff80008036bdb0 (deferred_probe_work){+.+.}-{0:0}, at: process_one_work+0x1b4/0x5ec
+ #2: ffff0008094ac8f8 (&dev->mutex){....}-{4:4}, at: __device_attach+0x38/0x188
+ #3: ffff000813c10cf0 (&phy->mutex){+.+.}-{4:4}, at: phy_init+0x4c/0x12c
+
+ stack backtrace:
+ CPU: 0 UID: 0 PID: 78 Comm: kworker/u51:0 Not tainted 6.15.0-rc7-next-20250522-12896-g3932f283970c #3455 PREEMPT
+ Hardware name: Qualcomm CRD, BIOS 6.0.240904.BOOT.MXF.2.4-00528.1-HAMOA-1 09/ 4/2024
+ Workqueue: events_unbound deferred_probe_work_func
+ Call trace:
+ show_stack+0x18/0x24 (C)
+ dump_stack_lvl+0x90/0xd0
+ dump_stack+0x18/0x24
+ print_deadlock_bug+0x258/0x348
+ __lock_acquire+0x10fc/0x1f84
+ lock_acquire+0x1c8/0x338
+ __mutex_lock+0xb8/0x59c
+ mutex_lock_nested+0x24/0x30
+ phy_init+0x4c/0x12c
+ snps_eusb2_hsphy_init+0x54/0x1a0
+ phy_init+0xe0/0x12c
+ dwc3_core_init+0x450/0x10b4
+ dwc3_core_probe+0xce4/0x15fc
+ dwc3_probe+0x64/0xb0
+ platform_probe+0x68/0xc4
+ really_probe+0xbc/0x298
+ __driver_probe_device+0x78/0x12c
+ driver_probe_device+0x3c/0x160
+ __device_attach_driver+0xb8/0x138
+ bus_for_each_drv+0x84/0xe0
+ __device_attach+0x9c/0x188
+ device_initial_probe+0x14/0x20
+ bus_probe_device+0xac/0xb0
+ deferred_probe_work_func+0x8c/0xc8
+ process_one_work+0x208/0x5ec
+ worker_thread+0x1c0/0x368
+ kthread+0x14c/0x20c
+ ret_from_fork+0x10/0x20
+
+Fixes: 3584f6392f09 ("phy: qcom: phy-qcom-snps-eusb2: Add support for eUSB2 repeater")
+Fixes: e2463559ff1d ("phy: amlogic: Add Amlogic AXG PCIE PHY Driver")
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Reported-by: Johan Hovold <johan+linaro@kernel.org>
+Link: https://lore.kernel.org/lkml/ZnpoAVGJMG4Zu-Jw@hovoldconsulting.com/
+Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
+Tested-by: Johan Hovold <johan+linaro@kernel.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250605-phy-subinit-v3-1-1e1e849e10cd@oss.qualcomm.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/phy-core.c | 5 ++++-
+ include/linux/phy/phy.h | 2 ++
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
+index 8e2daea81666b..04a5a34e7a950 100644
+--- a/drivers/phy/phy-core.c
++++ b/drivers/phy/phy-core.c
+@@ -994,7 +994,8 @@ struct phy *phy_create(struct device *dev, struct device_node *node,
+ }
+
+ device_initialize(&phy->dev);
+- mutex_init(&phy->mutex);
++ lockdep_register_key(&phy->lockdep_key);
++ mutex_init_with_key(&phy->mutex, &phy->lockdep_key);
+
+ phy->dev.class = &phy_class;
+ phy->dev.parent = dev;
+@@ -1259,6 +1260,8 @@ static void phy_release(struct device *dev)
+ dev_vdbg(dev, "releasing '%s'\n", dev_name(dev));
+ debugfs_remove_recursive(phy->debugfs);
+ regulator_put(phy->pwr);
++ mutex_destroy(&phy->mutex);
++ lockdep_unregister_key(&phy->lockdep_key);
+ ida_free(&phy_ida, phy->id);
+ kfree(phy);
+ }
+diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
+index e63e6e70e8604..51f781b565655 100644
+--- a/include/linux/phy/phy.h
++++ b/include/linux/phy/phy.h
+@@ -149,6 +149,7 @@ struct phy_attrs {
+ * @id: id of the phy device
+ * @ops: function pointers for performing phy operations
+ * @mutex: mutex to protect phy_ops
++ * @lockdep_key: lockdep information for this mutex
+ * @init_count: used to protect when the PHY is used by multiple consumers
+ * @power_count: used to protect when the PHY is used by multiple consumers
+ * @attrs: used to specify PHY specific attributes
+@@ -160,6 +161,7 @@ struct phy {
+ int id;
+ const struct phy_ops *ops;
+ struct mutex mutex;
++ struct lock_class_key lockdep_key;
+ int init_count;
+ int power_count;
+ struct phy_attrs attrs;
+--
+2.39.5
+
--- /dev/null
+From ee09694849a570cbc32015b5329b7c2f3f778748 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jul 2025 08:55:50 +0000
+Subject: Revert "cgroup_freezer: cgroup_freezing: Check if not frozen"
+
+From: Chen Ridong <chenridong@huawei.com>
+
+[ Upstream commit 14a67b42cb6f3ab66f41603c062c5056d32ea7dd ]
+
+This reverts commit cff5f49d433fcd0063c8be7dd08fa5bf190c6c37.
+
+Commit cff5f49d433f ("cgroup_freezer: cgroup_freezing: Check if not
+frozen") modified the cgroup_freezing() logic to verify that the FROZEN
+flag is not set, affecting the return value of the freezing() function,
+in order to address a warning in __thaw_task.
+
+A race condition exists that may allow tasks to escape being frozen. The
+following scenario demonstrates this issue:
+
+CPU 0 (get_signal path) CPU 1 (freezer.state reader)
+try_to_freeze read freezer.state
+__refrigerator freezer_read
+ update_if_frozen
+WRITE_ONCE(current->__state, TASK_FROZEN);
+ ...
+ /* Task is now marked frozen */
+ /* frozen(task) == true */
+ /* Assuming other tasks are frozen */
+ freezer->state |= CGROUP_FROZEN;
+/* freezing(current) returns false */
+/* because cgroup is frozen (not freezing) */
+break out
+__set_current_state(TASK_RUNNING);
+/* Bug: Task resumes running when it should remain frozen */
+
+The existing !frozen(p) check in __thaw_task makes the
+WARN_ON_ONCE(freezing(p)) warning redundant. Removing this warning enables
+reverting the commit cff5f49d433f ("cgroup_freezer: cgroup_freezing: Check
+if not frozen") to resolve the issue.
+
+The warning has been removed in the previous patch. This patch revert the
+commit cff5f49d433f ("cgroup_freezer: cgroup_freezing: Check if not
+frozen") to complete the fix.
+
+Fixes: cff5f49d433f ("cgroup_freezer: cgroup_freezing: Check if not frozen")
+Reported-by: Zhong Jiawei<zhongjiawei1@huawei.com>
+Signed-off-by: Chen Ridong <chenridong@huawei.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/cgroup/legacy_freezer.c | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+diff --git a/kernel/cgroup/legacy_freezer.c b/kernel/cgroup/legacy_freezer.c
+index 507b8f19a262e..dd9417425d929 100644
+--- a/kernel/cgroup/legacy_freezer.c
++++ b/kernel/cgroup/legacy_freezer.c
+@@ -66,15 +66,9 @@ static struct freezer *parent_freezer(struct freezer *freezer)
+ bool cgroup_freezing(struct task_struct *task)
+ {
+ bool ret;
+- unsigned int state;
+
+ rcu_read_lock();
+- /* Check if the cgroup is still FREEZING, but not FROZEN. The extra
+- * !FROZEN check is required, because the FREEZING bit is not cleared
+- * when the state FROZEN is reached.
+- */
+- state = task_freezer(task)->state;
+- ret = (state & CGROUP_FREEZING) && !(state & CGROUP_FROZEN);
++ ret = task_freezer(task)->state & CGROUP_FREEZING;
+ rcu_read_unlock();
+
+ return ret;
+--
+2.39.5
+
--- /dev/null
+From fcea664074eca2651b8b66c02401a02e03626254 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Jun 2025 10:56:30 +0200
+Subject: riscv: Enable interrupt during exception handling
+
+From: Nam Cao <namcao@linutronix.de>
+
+[ Upstream commit 969f028bf2c40573ef18061f702ede3ebfe12b42 ]
+
+force_sig_fault() takes a spinlock, which is a sleeping lock with
+CONFIG_PREEMPT_RT=y. However, exception handling calls force_sig_fault()
+with interrupt disabled, causing a sleeping in atomic context warning.
+
+This can be reproduced using userspace programs such as:
+ int main() { asm ("ebreak"); }
+or
+ int main() { asm ("unimp"); }
+
+There is no reason that interrupt must be disabled while handling
+exceptions from userspace.
+
+Enable interrupt while handling user exceptions. This also has the added
+benefit of avoiding unnecessary delays in interrupt handling.
+
+Fixes: f0bddf50586d ("riscv: entry: Convert to generic entry")
+Suggested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Nam Cao <namcao@linutronix.de>
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Link: https://lore.kernel.org/r/20250625085630.3649485-1-namcao@linutronix.de
+Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/traps.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
+index 9c83848797a78..80230de167def 100644
+--- a/arch/riscv/kernel/traps.c
++++ b/arch/riscv/kernel/traps.c
+@@ -6,6 +6,7 @@
+ #include <linux/cpu.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
++#include <linux/irqflags.h>
+ #include <linux/randomize_kstack.h>
+ #include <linux/sched.h>
+ #include <linux/sched/debug.h>
+@@ -151,7 +152,9 @@ asmlinkage __visible __trap_section void name(struct pt_regs *regs) \
+ { \
+ if (user_mode(regs)) { \
+ irqentry_enter_from_user_mode(regs); \
++ local_irq_enable(); \
+ do_trap_error(regs, signo, code, regs->epc, "Oops - " str); \
++ local_irq_disable(); \
+ irqentry_exit_to_user_mode(regs); \
+ } else { \
+ irqentry_state_t state = irqentry_nmi_enter(regs); \
+@@ -173,17 +176,14 @@ asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *re
+
+ if (user_mode(regs)) {
+ irqentry_enter_from_user_mode(regs);
+-
+ local_irq_enable();
+
+ handled = riscv_v_first_use_handler(regs);
+-
+- local_irq_disable();
+-
+ if (!handled)
+ do_trap_error(regs, SIGILL, ILL_ILLOPC, regs->epc,
+ "Oops - illegal instruction");
+
++ local_irq_disable();
+ irqentry_exit_to_user_mode(regs);
+ } else {
+ irqentry_state_t state = irqentry_nmi_enter(regs);
+@@ -308,9 +308,11 @@ asmlinkage __visible __trap_section void do_trap_break(struct pt_regs *regs)
+ {
+ if (user_mode(regs)) {
+ irqentry_enter_from_user_mode(regs);
++ local_irq_enable();
+
+ handle_break(regs);
+
++ local_irq_disable();
+ irqentry_exit_to_user_mode(regs);
+ } else {
+ irqentry_state_t state = irqentry_nmi_enter(regs);
+--
+2.39.5
+
--- /dev/null
+From 77051acd365c3e504bf2e9ce54297e57d323d8fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jul 2025 15:32:18 +0200
+Subject: riscv: traps_misaligned: properly sign extend value in misaligned
+ load handler
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Andreas Schwab <schwab@suse.de>
+
+[ Upstream commit b3510183ab7d63c71a3f5c89043d31686a76a34c ]
+
+Add missing cast to signed long.
+
+Signed-off-by: Andreas Schwab <schwab@suse.de>
+Fixes: 956d705dd279 ("riscv: Unaligned load/store handling for M_MODE")
+Tested-by: Clément Léger <cleger@rivosinc.com>
+Link: https://lore.kernel.org/r/mvmikk0goil.fsf@suse.de
+Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/traps_misaligned.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/kernel/traps_misaligned.c b/arch/riscv/kernel/traps_misaligned.c
+index fe0ab912014ba..f3123f1d20505 100644
+--- a/arch/riscv/kernel/traps_misaligned.c
++++ b/arch/riscv/kernel/traps_misaligned.c
+@@ -460,7 +460,7 @@ static int handle_scalar_misaligned_load(struct pt_regs *regs)
+ }
+
+ if (!fp)
+- SET_RD(insn, regs, val.data_ulong << shift >> shift);
++ SET_RD(insn, regs, (long)(val.data_ulong << shift) >> shift);
+ else if (len == 8)
+ set_f64_rd(insn, regs, val.data_u64);
+ else
+--
+2.39.5
+
--- /dev/null
+From b8ec08d6c29239ec8b5c7fe26cd75b00ce3a1d23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Jul 2025 18:21:19 +0000
+Subject: rpl: Fix use-after-free in rpl_do_srh_inline().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit b640daa2822a39ff76e70200cb2b7b892b896dce ]
+
+Running lwt_dst_cache_ref_loop.sh in selftest with KASAN triggers
+the splat below [0].
+
+rpl_do_srh_inline() fetches ipv6_hdr(skb) and accesses it after
+skb_cow_head(), which is illegal as the header could be freed then.
+
+Let's fix it by making oldhdr to a local struct instead of a pointer.
+
+[0]:
+[root@fedora net]# ./lwt_dst_cache_ref_loop.sh
+...
+TEST: rpl (input)
+[ 57.631529] ==================================================================
+BUG: KASAN: slab-use-after-free in rpl_do_srh_inline.isra.0 (net/ipv6/rpl_iptunnel.c:174)
+Read of size 40 at addr ffff888122bf96d8 by task ping6/1543
+
+CPU: 50 UID: 0 PID: 1543 Comm: ping6 Not tainted 6.16.0-rc5-01302-gfadd1e6231b1 #23 PREEMPT(voluntary)
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+ <IRQ>
+ dump_stack_lvl (lib/dump_stack.c:122)
+ print_report (mm/kasan/report.c:409 mm/kasan/report.c:521)
+ kasan_report (mm/kasan/report.c:221 mm/kasan/report.c:636)
+ kasan_check_range (mm/kasan/generic.c:175 (discriminator 1) mm/kasan/generic.c:189 (discriminator 1))
+ __asan_memmove (mm/kasan/shadow.c:94 (discriminator 2))
+ rpl_do_srh_inline.isra.0 (net/ipv6/rpl_iptunnel.c:174)
+ rpl_input (net/ipv6/rpl_iptunnel.c:201 net/ipv6/rpl_iptunnel.c:282)
+ lwtunnel_input (net/core/lwtunnel.c:459)
+ ipv6_rcv (./include/net/dst.h:471 (discriminator 1) ./include/net/dst.h:469 (discriminator 1) net/ipv6/ip6_input.c:79 (discriminator 1) ./include/linux/netfilter.h:317 (discriminator 1) ./include/linux/netfilter.h:311 (discriminator 1) net/ipv6/ip6_input.c:311 (discriminator 1))
+ __netif_receive_skb_one_core (net/core/dev.c:5967)
+ process_backlog (./include/linux/rcupdate.h:869 net/core/dev.c:6440)
+ __napi_poll.constprop.0 (net/core/dev.c:7452)
+ net_rx_action (net/core/dev.c:7518 net/core/dev.c:7643)
+ handle_softirqs (kernel/softirq.c:579)
+ do_softirq (kernel/softirq.c:480 (discriminator 20))
+ </IRQ>
+ <TASK>
+ __local_bh_enable_ip (kernel/softirq.c:407)
+ __dev_queue_xmit (net/core/dev.c:4740)
+ ip6_finish_output2 (./include/linux/netdevice.h:3358 ./include/net/neighbour.h:526 ./include/net/neighbour.h:540 net/ipv6/ip6_output.c:141)
+ ip6_finish_output (net/ipv6/ip6_output.c:215 net/ipv6/ip6_output.c:226)
+ ip6_output (./include/linux/netfilter.h:306 net/ipv6/ip6_output.c:248)
+ ip6_send_skb (net/ipv6/ip6_output.c:1983)
+ rawv6_sendmsg (net/ipv6/raw.c:588 net/ipv6/raw.c:918)
+ __sys_sendto (net/socket.c:714 (discriminator 1) net/socket.c:729 (discriminator 1) net/socket.c:2228 (discriminator 1))
+ __x64_sys_sendto (net/socket.c:2231)
+ do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1))
+ entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
+RIP: 0033:0x7f68cffb2a06
+Code: 5d e8 41 8b 93 08 03 00 00 59 5e 48 83 f8 fc 75 19 83 e2 39 83 fa 08 75 11 e8 26 ff ff ff 66 0f 1f 44 00 00 48 8b 45 10 0f 05 <48> 8b 5d f8 c9 c3 0f 1f 40 00 f3 0f 1e fa 55 48 89 e5 48 83 ec 08
+RSP: 002b:00007ffefb7c53d0 EFLAGS: 00000202 ORIG_RAX: 000000000000002c
+RAX: ffffffffffffffda RBX: 0000564cd69f10a0 RCX: 00007f68cffb2a06
+RDX: 0000000000000040 RSI: 0000564cd69f10a4 RDI: 0000000000000003
+RBP: 00007ffefb7c53f0 R08: 0000564cd6a032ac R09: 000000000000001c
+R10: 0000000000000000 R11: 0000000000000202 R12: 0000564cd69f10a4
+R13: 0000000000000040 R14: 00007ffefb7c66e0 R15: 0000564cd69f10a0
+ </TASK>
+
+Allocated by task 1543:
+ kasan_save_stack (mm/kasan/common.c:48)
+ kasan_save_track (mm/kasan/common.c:60 (discriminator 1) mm/kasan/common.c:69 (discriminator 1))
+ __kasan_slab_alloc (mm/kasan/common.c:319 mm/kasan/common.c:345)
+ kmem_cache_alloc_node_noprof (./include/linux/kasan.h:250 mm/slub.c:4148 mm/slub.c:4197 mm/slub.c:4249)
+ kmalloc_reserve (net/core/skbuff.c:581 (discriminator 88))
+ __alloc_skb (net/core/skbuff.c:669)
+ __ip6_append_data (net/ipv6/ip6_output.c:1672 (discriminator 1))
+ ip6_append_data (net/ipv6/ip6_output.c:1859)
+ rawv6_sendmsg (net/ipv6/raw.c:911)
+ __sys_sendto (net/socket.c:714 (discriminator 1) net/socket.c:729 (discriminator 1) net/socket.c:2228 (discriminator 1))
+ __x64_sys_sendto (net/socket.c:2231)
+ do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1))
+ entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
+
+Freed by task 1543:
+ kasan_save_stack (mm/kasan/common.c:48)
+ kasan_save_track (mm/kasan/common.c:60 (discriminator 1) mm/kasan/common.c:69 (discriminator 1))
+ kasan_save_free_info (mm/kasan/generic.c:579 (discriminator 1))
+ __kasan_slab_free (mm/kasan/common.c:271)
+ kmem_cache_free (mm/slub.c:4643 (discriminator 3) mm/slub.c:4745 (discriminator 3))
+ pskb_expand_head (net/core/skbuff.c:2274)
+ rpl_do_srh_inline.isra.0 (net/ipv6/rpl_iptunnel.c:158 (discriminator 1))
+ rpl_input (net/ipv6/rpl_iptunnel.c:201 net/ipv6/rpl_iptunnel.c:282)
+ lwtunnel_input (net/core/lwtunnel.c:459)
+ ipv6_rcv (./include/net/dst.h:471 (discriminator 1) ./include/net/dst.h:469 (discriminator 1) net/ipv6/ip6_input.c:79 (discriminator 1) ./include/linux/netfilter.h:317 (discriminator 1) ./include/linux/netfilter.h:311 (discriminator 1) net/ipv6/ip6_input.c:311 (discriminator 1))
+ __netif_receive_skb_one_core (net/core/dev.c:5967)
+ process_backlog (./include/linux/rcupdate.h:869 net/core/dev.c:6440)
+ __napi_poll.constprop.0 (net/core/dev.c:7452)
+ net_rx_action (net/core/dev.c:7518 net/core/dev.c:7643)
+ handle_softirqs (kernel/softirq.c:579)
+ do_softirq (kernel/softirq.c:480 (discriminator 20))
+ __local_bh_enable_ip (kernel/softirq.c:407)
+ __dev_queue_xmit (net/core/dev.c:4740)
+ ip6_finish_output2 (./include/linux/netdevice.h:3358 ./include/net/neighbour.h:526 ./include/net/neighbour.h:540 net/ipv6/ip6_output.c:141)
+ ip6_finish_output (net/ipv6/ip6_output.c:215 net/ipv6/ip6_output.c:226)
+ ip6_output (./include/linux/netfilter.h:306 net/ipv6/ip6_output.c:248)
+ ip6_send_skb (net/ipv6/ip6_output.c:1983)
+ rawv6_sendmsg (net/ipv6/raw.c:588 net/ipv6/raw.c:918)
+ __sys_sendto (net/socket.c:714 (discriminator 1) net/socket.c:729 (discriminator 1) net/socket.c:2228 (discriminator 1))
+ __x64_sys_sendto (net/socket.c:2231)
+ do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1))
+ entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
+
+The buggy address belongs to the object at ffff888122bf96c0
+ which belongs to the cache skbuff_small_head of size 704
+The buggy address is located 24 bytes inside of
+ freed 704-byte region [ffff888122bf96c0, ffff888122bf9980)
+
+The buggy address belongs to the physical page:
+page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x122bf8
+head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
+flags: 0x200000000000040(head|node=0|zone=2)
+page_type: f5(slab)
+raw: 0200000000000040 ffff888101fc0a00 ffffea000464dc00 0000000000000002
+raw: 0000000000000000 0000000080270027 00000000f5000000 0000000000000000
+head: 0200000000000040 ffff888101fc0a00 ffffea000464dc00 0000000000000002
+head: 0000000000000000 0000000080270027 00000000f5000000 0000000000000000
+head: 0200000000000003 ffffea00048afe01 00000000ffffffff 00000000ffffffff
+head: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
+page dumped because: kasan: bad access detected
+
+Memory state around the buggy address:
+ ffff888122bf9580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ffff888122bf9600: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
+>ffff888122bf9680: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
+ ^
+ ffff888122bf9700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ffff888122bf9780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+
+Fixes: a7a29f9c361f8 ("net: ipv6: add rpl sr tunnel")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/rpl_iptunnel.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv6/rpl_iptunnel.c b/net/ipv6/rpl_iptunnel.c
+index 7c05ac846646f..eccfa4203e96b 100644
+--- a/net/ipv6/rpl_iptunnel.c
++++ b/net/ipv6/rpl_iptunnel.c
+@@ -129,13 +129,13 @@ static int rpl_do_srh_inline(struct sk_buff *skb, const struct rpl_lwt *rlwt,
+ struct dst_entry *cache_dst)
+ {
+ struct ipv6_rpl_sr_hdr *isrh, *csrh;
+- const struct ipv6hdr *oldhdr;
++ struct ipv6hdr oldhdr;
+ struct ipv6hdr *hdr;
+ unsigned char *buf;
+ size_t hdrlen;
+ int err;
+
+- oldhdr = ipv6_hdr(skb);
++ memcpy(&oldhdr, ipv6_hdr(skb), sizeof(oldhdr));
+
+ buf = kcalloc(struct_size(srh, segments.addr, srh->segments_left), 2, GFP_ATOMIC);
+ if (!buf)
+@@ -147,7 +147,7 @@ static int rpl_do_srh_inline(struct sk_buff *skb, const struct rpl_lwt *rlwt,
+ memcpy(isrh, srh, sizeof(*isrh));
+ memcpy(isrh->rpl_segaddr, &srh->rpl_segaddr[1],
+ (srh->segments_left - 1) * 16);
+- isrh->rpl_segaddr[srh->segments_left - 1] = oldhdr->daddr;
++ isrh->rpl_segaddr[srh->segments_left - 1] = oldhdr.daddr;
+
+ ipv6_rpl_srh_compress(csrh, isrh, &srh->rpl_segaddr[0],
+ isrh->segments_left - 1);
+@@ -169,7 +169,7 @@ static int rpl_do_srh_inline(struct sk_buff *skb, const struct rpl_lwt *rlwt,
+ skb_mac_header_rebuild(skb);
+
+ hdr = ipv6_hdr(skb);
+- memmove(hdr, oldhdr, sizeof(*hdr));
++ memmove(hdr, &oldhdr, sizeof(*hdr));
+ isrh = (void *)hdr + sizeof(*hdr);
+ memcpy(isrh, csrh, hdrlen);
+
+--
+2.39.5
+
--- /dev/null
+From 4cfe7659526b92da924199ea022786ca1253ff98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jul 2025 08:43:41 +0100
+Subject: rxrpc: Fix irq-disabled in local_bh_enable()
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit e4d2878369d590bf8455e3678a644e503172eafa ]
+
+The rxrpc_assess_MTU_size() function calls down into the IP layer to find
+out the MTU size for a route. When accepting an incoming call, this is
+called from rxrpc_new_incoming_call() which holds interrupts disabled
+across the code that calls down to it. Unfortunately, the IP layer uses
+local_bh_enable() which, config dependent, throws a warning if IRQs are
+enabled:
+
+WARNING: CPU: 1 PID: 5544 at kernel/softirq.c:387 __local_bh_enable_ip+0x43/0xd0
+...
+RIP: 0010:__local_bh_enable_ip+0x43/0xd0
+...
+Call Trace:
+ <TASK>
+ rt_cache_route+0x7e/0xa0
+ rt_set_nexthop.isra.0+0x3b3/0x3f0
+ __mkroute_output+0x43a/0x460
+ ip_route_output_key_hash+0xf7/0x140
+ ip_route_output_flow+0x1b/0x90
+ rxrpc_assess_MTU_size.isra.0+0x2a0/0x590
+ rxrpc_new_incoming_peer+0x46/0x120
+ rxrpc_alloc_incoming_call+0x1b1/0x400
+ rxrpc_new_incoming_call+0x1da/0x5e0
+ rxrpc_input_packet+0x827/0x900
+ rxrpc_io_thread+0x403/0xb60
+ kthread+0x2f7/0x310
+ ret_from_fork+0x2a/0x230
+ ret_from_fork_asm+0x1a/0x30
+...
+hardirqs last enabled at (23): _raw_spin_unlock_irq+0x24/0x50
+hardirqs last disabled at (24): _raw_read_lock_irq+0x17/0x70
+softirqs last enabled at (0): copy_process+0xc61/0x2730
+softirqs last disabled at (25): rt_add_uncached_list+0x3c/0x90
+
+Fix this by moving the call to rxrpc_assess_MTU_size() out of
+rxrpc_init_peer() and further up the stack where it can be done without
+interrupts disabled.
+
+It shouldn't be a problem for rxrpc_new_incoming_call() to do it after the
+locks are dropped as pmtud is going to be performed by the I/O thread - and
+we're in the I/O thread at this point.
+
+Fixes: a2ea9a907260 ("rxrpc: Use irq-disabling spinlocks between app and I/O thread")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Jeffrey Altman <jaltman@auristor.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Junvyyang, Tencent Zhuque Lab <zhuque@tencent.com>
+cc: LePremierHomme <kwqcheii@proton.me>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+Link: https://patch.msgid.link/20250717074350.3767366-2-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rxrpc/ar-internal.h | 1 +
+ net/rxrpc/call_accept.c | 1 +
+ net/rxrpc/peer_object.c | 6 ++----
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
+index 3cc3af15086ff..b2d64586958fb 100644
+--- a/net/rxrpc/ar-internal.h
++++ b/net/rxrpc/ar-internal.h
+@@ -1315,6 +1315,7 @@ struct rxrpc_peer *rxrpc_lookup_peer_rcu(struct rxrpc_local *,
+ const struct sockaddr_rxrpc *);
+ struct rxrpc_peer *rxrpc_lookup_peer(struct rxrpc_local *local,
+ struct sockaddr_rxrpc *srx, gfp_t gfp);
++void rxrpc_assess_MTU_size(struct rxrpc_local *local, struct rxrpc_peer *peer);
+ struct rxrpc_peer *rxrpc_alloc_peer(struct rxrpc_local *, gfp_t,
+ enum rxrpc_peer_trace);
+ void rxrpc_new_incoming_peer(struct rxrpc_local *local, struct rxrpc_peer *peer);
+diff --git a/net/rxrpc/call_accept.c b/net/rxrpc/call_accept.c
+index 0b51f3ccf0358..bbed314b7d963 100644
+--- a/net/rxrpc/call_accept.c
++++ b/net/rxrpc/call_accept.c
+@@ -404,6 +404,7 @@ bool rxrpc_new_incoming_call(struct rxrpc_local *local,
+
+ spin_unlock(&rx->incoming_lock);
+ read_unlock_irq(&local->services_lock);
++ rxrpc_assess_MTU_size(local, call->peer);
+
+ if (hlist_unhashed(&call->error_link)) {
+ spin_lock_irq(&call->peer->lock);
+diff --git a/net/rxrpc/peer_object.c b/net/rxrpc/peer_object.c
+index 71b6e07bf1616..7df8d984a96ac 100644
+--- a/net/rxrpc/peer_object.c
++++ b/net/rxrpc/peer_object.c
+@@ -149,8 +149,7 @@ struct rxrpc_peer *rxrpc_lookup_peer_rcu(struct rxrpc_local *local,
+ * assess the MTU size for the network interface through which this peer is
+ * reached
+ */
+-static void rxrpc_assess_MTU_size(struct rxrpc_local *local,
+- struct rxrpc_peer *peer)
++void rxrpc_assess_MTU_size(struct rxrpc_local *local, struct rxrpc_peer *peer)
+ {
+ struct net *net = local->net;
+ struct dst_entry *dst;
+@@ -277,8 +276,6 @@ static void rxrpc_init_peer(struct rxrpc_local *local, struct rxrpc_peer *peer,
+
+ peer->hdrsize += sizeof(struct rxrpc_wire_header);
+ peer->max_data = peer->if_mtu - peer->hdrsize;
+-
+- rxrpc_assess_MTU_size(local, peer);
+ }
+
+ /*
+@@ -297,6 +294,7 @@ static struct rxrpc_peer *rxrpc_create_peer(struct rxrpc_local *local,
+ if (peer) {
+ memcpy(&peer->srx, srx, sizeof(*srx));
+ rxrpc_init_peer(local, peer, hash_key);
++ rxrpc_assess_MTU_size(local, peer);
+ }
+
+ _leave(" = %p", peer);
+--
+2.39.5
+
--- /dev/null
+From e699b87425d01278184a8bd91a90a5b19da02d9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jul 2025 08:43:43 +0100
+Subject: rxrpc: Fix notification vs call-release vs recvmsg
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 2fd895842d49c23137ae48252dd211e5d6d8a3ed ]
+
+When a call is released, rxrpc takes the spinlock and removes it from
+->recvmsg_q in an effort to prevent racing recvmsg() invocations from
+seeing the same call. Now, rxrpc_recvmsg() only takes the spinlock when
+actually removing a call from the queue; it doesn't, however, take it in
+the lead up to that when it checks to see if the queue is empty. It *does*
+hold the socket lock, which prevents a recvmsg/recvmsg race - but this
+doesn't prevent sendmsg from ending the call because sendmsg() drops the
+socket lock and relies on the call->user_mutex.
+
+Fix this by firstly removing the bit in rxrpc_release_call() that dequeues
+the released call and, instead, rely on recvmsg() to simply discard
+released calls (done in a preceding fix).
+
+Secondly, rxrpc_notify_socket() is abandoned if the call is already marked
+as released rather than trying to be clever by setting both pointers in
+call->recvmsg_link to NULL to trick list_empty(). This isn't perfect and
+can still race, resulting in a released call on the queue, but recvmsg()
+will now clean that up.
+
+Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Jeffrey Altman <jaltman@auristor.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Junvyyang, Tencent Zhuque Lab <zhuque@tencent.com>
+cc: LePremierHomme <kwqcheii@proton.me>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+Link: https://patch.msgid.link/20250717074350.3767366-4-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/trace/events/rxrpc.h | 3 ++-
+ net/rxrpc/call_object.c | 28 ++++++++++++----------------
+ net/rxrpc/recvmsg.c | 4 ++++
+ 3 files changed, 18 insertions(+), 17 deletions(-)
+
+diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h
+index a785b177c6927..f2ef106b61969 100644
+--- a/include/trace/events/rxrpc.h
++++ b/include/trace/events/rxrpc.h
+@@ -275,10 +275,10 @@
+ EM(rxrpc_call_put_kernel, "PUT kernel ") \
+ EM(rxrpc_call_put_poke, "PUT poke ") \
+ EM(rxrpc_call_put_recvmsg, "PUT recvmsg ") \
++ EM(rxrpc_call_put_release_recvmsg_q, "PUT rls-rcmq") \
+ EM(rxrpc_call_put_release_sock, "PUT rls-sock") \
+ EM(rxrpc_call_put_release_sock_tba, "PUT rls-sk-a") \
+ EM(rxrpc_call_put_sendmsg, "PUT sendmsg ") \
+- EM(rxrpc_call_put_unnotify, "PUT unnotify") \
+ EM(rxrpc_call_put_userid_exists, "PUT u-exists") \
+ EM(rxrpc_call_put_userid, "PUT user-id ") \
+ EM(rxrpc_call_see_accept, "SEE accept ") \
+@@ -291,6 +291,7 @@
+ EM(rxrpc_call_see_disconnected, "SEE disconn ") \
+ EM(rxrpc_call_see_distribute_error, "SEE dist-err") \
+ EM(rxrpc_call_see_input, "SEE input ") \
++ EM(rxrpc_call_see_notify_released, "SEE nfy-rlsd") \
+ EM(rxrpc_call_see_recvmsg, "SEE recvmsg ") \
+ EM(rxrpc_call_see_release, "SEE release ") \
+ EM(rxrpc_call_see_userid_exists, "SEE u-exists") \
+diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c
+index fce58be65e7cf..4be3713a5a339 100644
+--- a/net/rxrpc/call_object.c
++++ b/net/rxrpc/call_object.c
+@@ -561,7 +561,7 @@ static void rxrpc_cleanup_rx_buffers(struct rxrpc_call *call)
+ void rxrpc_release_call(struct rxrpc_sock *rx, struct rxrpc_call *call)
+ {
+ struct rxrpc_connection *conn = call->conn;
+- bool put = false, putu = false;
++ bool putu = false;
+
+ _enter("{%d,%d}", call->debug_id, refcount_read(&call->ref));
+
+@@ -573,23 +573,13 @@ void rxrpc_release_call(struct rxrpc_sock *rx, struct rxrpc_call *call)
+
+ rxrpc_put_call_slot(call);
+
+- /* Make sure we don't get any more notifications */
++ /* Note that at this point, the call may still be on or may have been
++ * added back on to the socket receive queue. recvmsg() must discard
++ * released calls. The CALL_RELEASED flag should prevent further
++ * notifications.
++ */
+ spin_lock_irq(&rx->recvmsg_lock);
+-
+- if (!list_empty(&call->recvmsg_link)) {
+- _debug("unlinking once-pending call %p { e=%lx f=%lx }",
+- call, call->events, call->flags);
+- list_del(&call->recvmsg_link);
+- put = true;
+- }
+-
+- /* list_empty() must return false in rxrpc_notify_socket() */
+- call->recvmsg_link.next = NULL;
+- call->recvmsg_link.prev = NULL;
+-
+ spin_unlock_irq(&rx->recvmsg_lock);
+- if (put)
+- rxrpc_put_call(call, rxrpc_call_put_unnotify);
+
+ write_lock(&rx->call_lock);
+
+@@ -638,6 +628,12 @@ void rxrpc_release_calls_on_socket(struct rxrpc_sock *rx)
+ rxrpc_put_call(call, rxrpc_call_put_release_sock);
+ }
+
++ while ((call = list_first_entry_or_null(&rx->recvmsg_q,
++ struct rxrpc_call, recvmsg_link))) {
++ list_del_init(&call->recvmsg_link);
++ rxrpc_put_call(call, rxrpc_call_put_release_recvmsg_q);
++ }
++
+ _leave("");
+ }
+
+diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c
+index 1668495e4ae63..89dc612fb89e0 100644
+--- a/net/rxrpc/recvmsg.c
++++ b/net/rxrpc/recvmsg.c
+@@ -29,6 +29,10 @@ void rxrpc_notify_socket(struct rxrpc_call *call)
+
+ if (!list_empty(&call->recvmsg_link))
+ return;
++ if (test_bit(RXRPC_CALL_RELEASED, &call->flags)) {
++ rxrpc_see_call(call, rxrpc_call_see_notify_released);
++ return;
++ }
+
+ rcu_read_lock();
+
+--
+2.39.5
+
--- /dev/null
+From aaf492ee1188447a3d47210628f76ad0318f5e11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jul 2025 08:43:42 +0100
+Subject: rxrpc: Fix recv-recv race of completed call
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 962fb1f651c2cf2083e0c3ef53ba69e3b96d3fbc ]
+
+If a call receives an event (such as incoming data), the call gets placed
+on the socket's queue and a thread in recvmsg can be awakened to go and
+process it. Once the thread has picked up the call off of the queue,
+further events will cause it to be requeued, and once the socket lock is
+dropped (recvmsg uses call->user_mutex to allow the socket to be used in
+parallel), a second thread can come in and its recvmsg can pop the call off
+the socket queue again.
+
+In such a case, the first thread will be receiving stuff from the call and
+the second thread will be blocked on call->user_mutex. The first thread
+can, at this point, process both the event that it picked call for and the
+event that the second thread picked the call for and may see the call
+terminate - in which case the call will be "released", decoupling the call
+from the user call ID assigned to it (RXRPC_USER_CALL_ID in the control
+message).
+
+The first thread will return okay, but then the second thread will wake up
+holding the user_mutex and, if it sees that the call has been released by
+the first thread, it will BUG thusly:
+
+ kernel BUG at net/rxrpc/recvmsg.c:474!
+
+Fix this by just dequeuing the call and ignoring it if it is seen to be
+already released. We can't tell userspace about it anyway as the user call
+ID has become stale.
+
+Fixes: 248f219cb8bc ("rxrpc: Rewrite the data and ack handling code")
+Reported-by: Junvyyang, Tencent Zhuque Lab <zhuque@tencent.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Jeffrey Altman <jaltman@auristor.com>
+cc: LePremierHomme <kwqcheii@proton.me>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+Link: https://patch.msgid.link/20250717074350.3767366-3-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/trace/events/rxrpc.h | 3 +++
+ net/rxrpc/call_accept.c | 1 +
+ net/rxrpc/recvmsg.c | 19 +++++++++++++++++--
+ 3 files changed, 21 insertions(+), 2 deletions(-)
+
+diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h
+index cad50d91077ef..a785b177c6927 100644
+--- a/include/trace/events/rxrpc.h
++++ b/include/trace/events/rxrpc.h
+@@ -283,12 +283,15 @@
+ EM(rxrpc_call_put_userid, "PUT user-id ") \
+ EM(rxrpc_call_see_accept, "SEE accept ") \
+ EM(rxrpc_call_see_activate_client, "SEE act-clnt") \
++ EM(rxrpc_call_see_already_released, "SEE alrdy-rl") \
+ EM(rxrpc_call_see_connect_failed, "SEE con-fail") \
+ EM(rxrpc_call_see_connected, "SEE connect ") \
+ EM(rxrpc_call_see_conn_abort, "SEE conn-abt") \
++ EM(rxrpc_call_see_discard, "SEE discard ") \
+ EM(rxrpc_call_see_disconnected, "SEE disconn ") \
+ EM(rxrpc_call_see_distribute_error, "SEE dist-err") \
+ EM(rxrpc_call_see_input, "SEE input ") \
++ EM(rxrpc_call_see_recvmsg, "SEE recvmsg ") \
+ EM(rxrpc_call_see_release, "SEE release ") \
+ EM(rxrpc_call_see_userid_exists, "SEE u-exists") \
+ EM(rxrpc_call_see_waiting_call, "SEE q-conn ") \
+diff --git a/net/rxrpc/call_accept.c b/net/rxrpc/call_accept.c
+index bbed314b7d963..978f0c6ee3c8a 100644
+--- a/net/rxrpc/call_accept.c
++++ b/net/rxrpc/call_accept.c
+@@ -219,6 +219,7 @@ void rxrpc_discard_prealloc(struct rxrpc_sock *rx)
+ tail = b->call_backlog_tail;
+ while (CIRC_CNT(head, tail, size) > 0) {
+ struct rxrpc_call *call = b->call_backlog[tail];
++ rxrpc_see_call(call, rxrpc_call_see_discard);
+ rcu_assign_pointer(call->socket, rx);
+ if (rx->discard_new_call) {
+ _debug("discard %lx", call->user_call_ID);
+diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c
+index 32cd5f1d541db..1668495e4ae63 100644
+--- a/net/rxrpc/recvmsg.c
++++ b/net/rxrpc/recvmsg.c
+@@ -351,6 +351,16 @@ int rxrpc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
+ goto try_again;
+ }
+
++ rxrpc_see_call(call, rxrpc_call_see_recvmsg);
++ if (test_bit(RXRPC_CALL_RELEASED, &call->flags)) {
++ rxrpc_see_call(call, rxrpc_call_see_already_released);
++ list_del_init(&call->recvmsg_link);
++ spin_unlock_irq(&rx->recvmsg_lock);
++ release_sock(&rx->sk);
++ trace_rxrpc_recvmsg(call->debug_id, rxrpc_recvmsg_unqueue, 0);
++ rxrpc_put_call(call, rxrpc_call_put_recvmsg);
++ goto try_again;
++ }
+ if (!(flags & MSG_PEEK))
+ list_del_init(&call->recvmsg_link);
+ else
+@@ -374,8 +384,13 @@ int rxrpc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
+
+ release_sock(&rx->sk);
+
+- if (test_bit(RXRPC_CALL_RELEASED, &call->flags))
+- BUG();
++ if (test_bit(RXRPC_CALL_RELEASED, &call->flags)) {
++ rxrpc_see_call(call, rxrpc_call_see_already_released);
++ mutex_unlock(&call->user_mutex);
++ if (!(flags & MSG_PEEK))
++ rxrpc_put_call(call, rxrpc_call_put_recvmsg);
++ goto try_again;
++ }
+
+ if (test_bit(RXRPC_CALL_HAS_USERID, &call->flags)) {
+ if (flags & MSG_CMSG_COMPAT) {
+--
+2.39.5
+
--- /dev/null
+From 68eac52b6a438ace0db0824847d101c0596d9b07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jul 2025 08:43:45 +0100
+Subject: rxrpc: Fix to use conn aborts for conn-wide failures
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit f0295678ad304195927829b1dbf06553aa2187b0 ]
+
+Fix rxrpc to use connection-level aborts for things that affect the whole
+connection, such as the service ID not matching a local service.
+
+Fixes: 57af281e5389 ("rxrpc: Tidy up abort generation infrastructure")
+Reported-by: Jeffrey Altman <jaltman@auristor.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Jeffrey Altman <jaltman@auristor.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+Link: https://patch.msgid.link/20250717074350.3767366-6-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rxrpc/ar-internal.h | 3 +++
+ net/rxrpc/call_accept.c | 12 ++++++------
+ net/rxrpc/io_thread.c | 14 ++++++++++++++
+ net/rxrpc/output.c | 19 ++++++++++---------
+ net/rxrpc/security.c | 8 ++++----
+ 5 files changed, 37 insertions(+), 19 deletions(-)
+
+diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
+index b2d64586958fb..c4891a538ded0 100644
+--- a/net/rxrpc/ar-internal.h
++++ b/net/rxrpc/ar-internal.h
+@@ -42,6 +42,7 @@ enum rxrpc_skb_mark {
+ RXRPC_SKB_MARK_SERVICE_CONN_SECURED, /* Service connection response has been verified */
+ RXRPC_SKB_MARK_REJECT_BUSY, /* Reject with BUSY */
+ RXRPC_SKB_MARK_REJECT_ABORT, /* Reject with ABORT (code in skb->priority) */
++ RXRPC_SKB_MARK_REJECT_CONN_ABORT, /* Reject with connection ABORT (code in skb->priority) */
+ };
+
+ /*
+@@ -1197,6 +1198,8 @@ int rxrpc_encap_rcv(struct sock *, struct sk_buff *);
+ void rxrpc_error_report(struct sock *);
+ bool rxrpc_direct_abort(struct sk_buff *skb, enum rxrpc_abort_reason why,
+ s32 abort_code, int err);
++bool rxrpc_direct_conn_abort(struct sk_buff *skb, enum rxrpc_abort_reason why,
++ s32 abort_code, int err);
+ int rxrpc_io_thread(void *data);
+ static inline void rxrpc_wake_up_io_thread(struct rxrpc_local *local)
+ {
+diff --git a/net/rxrpc/call_accept.c b/net/rxrpc/call_accept.c
+index 978f0c6ee3c8a..3259916c926ae 100644
+--- a/net/rxrpc/call_accept.c
++++ b/net/rxrpc/call_accept.c
+@@ -373,8 +373,8 @@ bool rxrpc_new_incoming_call(struct rxrpc_local *local,
+ spin_lock(&rx->incoming_lock);
+ if (rx->sk.sk_state == RXRPC_SERVER_LISTEN_DISABLED ||
+ rx->sk.sk_state == RXRPC_CLOSE) {
+- rxrpc_direct_abort(skb, rxrpc_abort_shut_down,
+- RX_INVALID_OPERATION, -ESHUTDOWN);
++ rxrpc_direct_conn_abort(skb, rxrpc_abort_shut_down,
++ RX_INVALID_OPERATION, -ESHUTDOWN);
+ goto no_call;
+ }
+
+@@ -420,12 +420,12 @@ bool rxrpc_new_incoming_call(struct rxrpc_local *local,
+
+ unsupported_service:
+ read_unlock_irq(&local->services_lock);
+- return rxrpc_direct_abort(skb, rxrpc_abort_service_not_offered,
+- RX_INVALID_OPERATION, -EOPNOTSUPP);
++ return rxrpc_direct_conn_abort(skb, rxrpc_abort_service_not_offered,
++ RX_INVALID_OPERATION, -EOPNOTSUPP);
+ unsupported_security:
+ read_unlock_irq(&local->services_lock);
+- return rxrpc_direct_abort(skb, rxrpc_abort_service_not_offered,
+- RX_INVALID_OPERATION, -EKEYREJECTED);
++ return rxrpc_direct_conn_abort(skb, rxrpc_abort_service_not_offered,
++ RX_INVALID_OPERATION, -EKEYREJECTED);
+ no_call:
+ spin_unlock(&rx->incoming_lock);
+ read_unlock_irq(&local->services_lock);
+diff --git a/net/rxrpc/io_thread.c b/net/rxrpc/io_thread.c
+index 64f8d77b87312..23dbcc4819990 100644
+--- a/net/rxrpc/io_thread.c
++++ b/net/rxrpc/io_thread.c
+@@ -97,6 +97,20 @@ bool rxrpc_direct_abort(struct sk_buff *skb, enum rxrpc_abort_reason why,
+ return false;
+ }
+
++/*
++ * Directly produce a connection abort from a packet.
++ */
++bool rxrpc_direct_conn_abort(struct sk_buff *skb, enum rxrpc_abort_reason why,
++ s32 abort_code, int err)
++{
++ struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
++
++ trace_rxrpc_abort(0, why, sp->hdr.cid, 0, sp->hdr.seq, abort_code, err);
++ skb->mark = RXRPC_SKB_MARK_REJECT_CONN_ABORT;
++ skb->priority = abort_code;
++ return false;
++}
++
+ static bool rxrpc_bad_message(struct sk_buff *skb, enum rxrpc_abort_reason why)
+ {
+ return rxrpc_direct_abort(skb, why, RX_PROTOCOL_ERROR, -EBADMSG);
+diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
+index d0d04ee9667ef..a480e7e2325eb 100644
+--- a/net/rxrpc/output.c
++++ b/net/rxrpc/output.c
+@@ -829,7 +829,13 @@ void rxrpc_reject_packet(struct rxrpc_local *local, struct sk_buff *skb)
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+
+- memset(&whdr, 0, sizeof(whdr));
++ whdr = (struct rxrpc_wire_header) {
++ .epoch = htonl(sp->hdr.epoch),
++ .cid = htonl(sp->hdr.cid),
++ .callNumber = htonl(sp->hdr.callNumber),
++ .serviceId = htons(sp->hdr.serviceId),
++ .flags = ~sp->hdr.flags & RXRPC_CLIENT_INITIATED,
++ };
+
+ switch (skb->mark) {
+ case RXRPC_SKB_MARK_REJECT_BUSY:
+@@ -837,6 +843,9 @@ void rxrpc_reject_packet(struct rxrpc_local *local, struct sk_buff *skb)
+ size = sizeof(whdr);
+ ioc = 1;
+ break;
++ case RXRPC_SKB_MARK_REJECT_CONN_ABORT:
++ whdr.callNumber = 0;
++ fallthrough;
+ case RXRPC_SKB_MARK_REJECT_ABORT:
+ whdr.type = RXRPC_PACKET_TYPE_ABORT;
+ code = htonl(skb->priority);
+@@ -850,14 +859,6 @@ void rxrpc_reject_packet(struct rxrpc_local *local, struct sk_buff *skb)
+ if (rxrpc_extract_addr_from_skb(&srx, skb) == 0) {
+ msg.msg_namelen = srx.transport_len;
+
+- whdr.epoch = htonl(sp->hdr.epoch);
+- whdr.cid = htonl(sp->hdr.cid);
+- whdr.callNumber = htonl(sp->hdr.callNumber);
+- whdr.serviceId = htons(sp->hdr.serviceId);
+- whdr.flags = sp->hdr.flags;
+- whdr.flags ^= RXRPC_CLIENT_INITIATED;
+- whdr.flags &= RXRPC_CLIENT_INITIATED;
+-
+ iov_iter_kvec(&msg.msg_iter, WRITE, iov, ioc, size);
+ ret = do_udp_sendmsg(local->socket, &msg, size);
+ if (ret < 0)
+diff --git a/net/rxrpc/security.c b/net/rxrpc/security.c
+index 9784adc8f2759..7a48fee3a6b1a 100644
+--- a/net/rxrpc/security.c
++++ b/net/rxrpc/security.c
+@@ -137,15 +137,15 @@ const struct rxrpc_security *rxrpc_get_incoming_security(struct rxrpc_sock *rx,
+
+ sec = rxrpc_security_lookup(sp->hdr.securityIndex);
+ if (!sec) {
+- rxrpc_direct_abort(skb, rxrpc_abort_unsupported_security,
+- RX_INVALID_OPERATION, -EKEYREJECTED);
++ rxrpc_direct_conn_abort(skb, rxrpc_abort_unsupported_security,
++ RX_INVALID_OPERATION, -EKEYREJECTED);
+ return NULL;
+ }
+
+ if (sp->hdr.securityIndex != RXRPC_SECURITY_NONE &&
+ !rx->securities) {
+- rxrpc_direct_abort(skb, rxrpc_abort_no_service_key,
+- sec->no_key_abort, -EKEYREJECTED);
++ rxrpc_direct_conn_abort(skb, rxrpc_abort_no_service_key,
++ sec->no_key_abort, -EKEYREJECTED);
+ return NULL;
+ }
+
+--
+2.39.5
+
--- /dev/null
+From 798ccc1201f1978b1697dd7a689aec29a37486c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jul 2025 08:43:44 +0100
+Subject: rxrpc: Fix transmission of an abort in response to an abort
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit e9c0b96ec0a34fcacdf9365713578d83cecac34c ]
+
+Under some circumstances, such as when a server socket is closing, ABORT
+packets will be generated in response to incoming packets. Unfortunately,
+this also may include generating aborts in response to incoming aborts -
+which may cause a cycle. It appears this may be made possible by giving
+the client a multicast address.
+
+Fix this such that rxrpc_reject_packet() will refuse to generate aborts in
+response to aborts.
+
+Fixes: 248f219cb8bc ("rxrpc: Rewrite the data and ack handling code")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Jeffrey Altman <jaltman@auristor.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Junvyyang, Tencent Zhuque Lab <zhuque@tencent.com>
+cc: LePremierHomme <kwqcheii@proton.me>
+cc: Linus Torvalds <torvalds@linux-foundation.org>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+Link: https://patch.msgid.link/20250717074350.3767366-5-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rxrpc/output.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
+index 95905b85a8d71..d0d04ee9667ef 100644
+--- a/net/rxrpc/output.c
++++ b/net/rxrpc/output.c
+@@ -814,6 +814,9 @@ void rxrpc_reject_packet(struct rxrpc_local *local, struct sk_buff *skb)
+ __be32 code;
+ int ret, ioc;
+
++ if (sp->hdr.type == RXRPC_PACKET_TYPE_ABORT)
++ return; /* Never abort an abort. */
++
+ rxrpc_see_skb(skb, rxrpc_skb_see_reject);
+
+ iov[0].iov_base = &whdr;
+--
+2.39.5
+
--- /dev/null
+From 93a5e6bb62dc315886da1433fa14f1c58f67acd9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jul 2025 18:04:50 +0200
+Subject: selftests: net: increase inter-packet timeout in udpgro.sh
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit 0e9418961f897be59b1fab6e31ae1b09a0bae902 ]
+
+The mentioned test is not very stable when running on top of
+debug kernel build. Increase the inter-packet timeout to allow
+more slack in such environments.
+
+Fixes: 3327a9c46352 ("selftests: add functionals test for UDP GRO")
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/b0370c06ddb3235debf642c17de0284b2cd3c652.1752163107.git.pabeni@redhat.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/udpgro.sh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/tools/testing/selftests/net/udpgro.sh b/tools/testing/selftests/net/udpgro.sh
+index d5ffd8c9172e1..799dbc2b4b01c 100755
+--- a/tools/testing/selftests/net/udpgro.sh
++++ b/tools/testing/selftests/net/udpgro.sh
+@@ -48,7 +48,7 @@ run_one() {
+
+ cfg_veth
+
+- ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 1000 -R 10 ${rx_args} &
++ ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 1000 -R 100 ${rx_args} &
+ local PID1=$!
+
+ wait_local_port_listen ${PEER_NS} 8000 udp
+@@ -95,7 +95,7 @@ run_one_nat() {
+ # will land on the 'plain' one
+ ip netns exec "${PEER_NS}" ./udpgso_bench_rx -G ${family} -b ${addr1} -n 0 &
+ local PID1=$!
+- ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 1000 -R 10 ${family} -b ${addr2%/*} ${rx_args} &
++ ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 1000 -R 100 ${family} -b ${addr2%/*} ${rx_args} &
+ local PID2=$!
+
+ wait_local_port_listen "${PEER_NS}" 8000 udp
+@@ -117,9 +117,9 @@ run_one_2sock() {
+
+ cfg_veth
+
+- ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 1000 -R 10 ${rx_args} -p 12345 &
++ ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 1000 -R 100 ${rx_args} -p 12345 &
+ local PID1=$!
+- ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 2000 -R 10 ${rx_args} &
++ ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 2000 -R 100 ${rx_args} &
+ local PID2=$!
+
+ wait_local_port_listen "${PEER_NS}" 12345 udp
+--
+2.39.5
+
--- /dev/null
+From acd1e723a6d48e2816620eb5680bb9565d1d6456 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Jul 2025 08:08:45 +0200
+Subject: selftests/sched_ext: Fix exit selftest hang on UP
+
+From: Andrea Righi <arighi@nvidia.com>
+
+[ Upstream commit 7980ad7e4ca80f6c255f4473fba82a475342035a ]
+
+On single-CPU systems, ops.select_cpu() is never called, causing the
+EXIT_SELECT_CPU test case to wait indefinitely.
+
+Avoid the stall by skipping this specific sub-test when only one CPU is
+available.
+
+Reported-by: Phil Auld <pauld@redhat.com>
+Fixes: a5db7817af780 ("sched_ext: Add selftests")
+Signed-off-by: Andrea Righi <arighi@nvidia.com>
+Reviewed-by: Phil Auld <pauld@redhat.com>
+Tested-by: Phil Auld <pauld@redhat.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/sched_ext/exit.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/tools/testing/selftests/sched_ext/exit.c b/tools/testing/selftests/sched_ext/exit.c
+index 9451782689de1..ee25824b1cbe6 100644
+--- a/tools/testing/selftests/sched_ext/exit.c
++++ b/tools/testing/selftests/sched_ext/exit.c
+@@ -22,6 +22,14 @@ static enum scx_test_status run(void *ctx)
+ struct bpf_link *link;
+ char buf[16];
+
++ /*
++ * On single-CPU systems, ops.select_cpu() is never
++ * invoked, so skip this test to avoid getting stuck
++ * indefinitely.
++ */
++ if (tc == EXIT_SELECT_CPU && libbpf_num_possible_cpus() == 1)
++ continue;
++
+ skel = exit__open();
+ SCX_ENUM_INIT(skel);
+ skel->rodata->exit_point = tc;
+--
+2.39.5
+
comedi-fix-some-signed-shift-left-operations.patch
comedi-fix-use-of-uninitialized-data-in-insn_rw_emulate_bits.patch
comedi-fix-initialization-of-data-for-instructions-that-write-to-subdevice.patch
+arm64-dts-rockchip-add-cd-gpios-for-sdcard-detect-on.patch
+arm64-dts-rockchip-add-cd-gpios-for-sdcard-detect-on.patch-14455
+soundwire-amd-fix-for-handling-slave-alerts-after-li.patch
+phy-use-per-phy-lockdep-keys.patch
+soundwire-amd-fix-for-clearing-command-status-regist.patch
+arm64-dts-imx95-19x19-evk-fix-the-overshoot-issue-of.patch
+arm64-dts-imx95-15x15-evk-fix-the-overshoot-issue-of.patch
+arm64-dts-imx95-correct-the-dma-interrupter-number-o.patch
+bpf-reject-p-format-string-in-bprintf-like-helpers.patch
+selftests-sched_ext-fix-exit-selftest-hang-on-up.patch
+wifi-iwlwifi-mask-reserved-bits-in-chan_state_active.patch
+cachefiles-fix-the-incorrect-return-value-in-__cache.patch
+alsa-compress_offload-tighten-ioctl-command-number-c.patch
+drm-nouveau-check-ioctl-command-codes-better.patch
+net-emaclite-fix-missing-pointer-increment-in-aligne.patch
+block-fix-kobject-leak-in-blk_unregister_queue.patch
+net-sched-sch_qfq-fix-race-condition-on-qfq_aggregat.patch
+rpl-fix-use-after-free-in-rpl_do_srh_inline.patch
+smb-client-fix-use-after-free-in-cifs_oplock_break.patch
+fix-a-leak-in-fcntl_dirnotify.patch
+nvme-fix-inconsistent-rcu-list-manipulation-in-nvme_.patch
+nvme-fix-endianness-of-command-word-prints-in-nvme_l.patch
+smc-fix-various-oops-due-to-inet_sock-type-confusion.patch
+net-phy-don-t-register-leds-for-genphy.patch
+nvme-revert-the-cross-controller-atomic-write-size-v.patch
+nvme-fix-misaccounting-of-nvme-mpath-inflight-i-o.patch
+nvmet-tcp-fix-callback-lock-for-tls-handshake.patch
+wifi-cfg80211-remove-scan-request-n_channels-counted.patch
+can-tcan4x5x-fix-reset-gpio-usage-during-probe.patch
+selftests-net-increase-inter-packet-timeout-in-udpgr.patch
+hwmon-corsair-cpro-validate-the-size-of-the-received.patch
+ice-add-null-check-in-eswitch-lag-check.patch
+ice-check-correct-pointer-in-fwlog-debugfs.patch
+usb-net-sierra-check-for-no-status-endpoint.patch
+loop-use-kiocb-helpers-to-fix-lockdep-warning.patch
+riscv-enable-interrupt-during-exception-handling.patch
+riscv-traps_misaligned-properly-sign-extend-value-in.patch
+bluetooth-fix-null-ptr-deref-in-l2cap_sock_resume_cb.patch
+bluetooth-hci_sync-fix-connectable-extended-advertis.patch
+bluetooth-smp-if-an-unallowed-command-is-received-co.patch
+bluetooth-smp-fix-using-hci_error_remote_user_term-o.patch
+bluetooth-hci_core-fix-typos-in-macros.patch
+bluetooth-hci_core-add-missing-braces-when-using-mac.patch
+bluetooth-hci_dev-replace-quirks-integer-by-quirk_fl.patch
+bluetooth-btusb-qca-fix-downloading-wrong-nvm-for-wc.patch
+net-mlx5-correctly-set-gso_size-when-lro-is-used.patch
+net-airoha-fix-potential-use-after-free-in-airoha_np.patch
+ipv6-mcast-delay-put-pmc-idev-in-mld_del_delrec.patch
+net-fix-segmentation-after-tcp-udp-fraglist-gro.patch
+netfilter-nf_conntrack-fix-crash-due-to-removal-of-u.patch
+drm-xe-dont-skip-tlb-invalidations-on-vf.patch
+drm-xe-pf-prepare-to-stop-sr-iov-support-prior-gt-re.patch
+drm-xe-pf-resend-pf-provisioning-after-gt-reset.patch
+bluetooth-l2cap-fix-attempting-to-adjust-outgoing-mt.patch
+hv_netvsc-set-vf-priv_flags-to-iff_no_addrconf-befor.patch
+virtio-net-fix-recursived-rtnl_lock-during-probe.patch
+tls-always-refresh-the-queue-when-reading-sock.patch
+net-vlan-fix-vlan-0-refcount-imbalance-of-toggling-f.patch
+net-bridge-do-not-offload-igmp-mld-messages.patch
+net-sched-return-null-when-htb_lookup_leaf-encounter.patch
+rxrpc-fix-irq-disabled-in-local_bh_enable.patch
+rxrpc-fix-recv-recv-race-of-completed-call.patch
+rxrpc-fix-notification-vs-call-release-vs-recvmsg.patch
+rxrpc-fix-transmission-of-an-abort-in-response-to-an.patch
+rxrpc-fix-to-use-conn-aborts-for-conn-wide-failures.patch
+revert-cgroup_freezer-cgroup_freezing-check-if-not-f.patch
+drm-mediatek-add-wait_event_timeout-when-disabling-p.patch
+drm-mediatek-only-announce-afbc-if-really-supported.patch
+libbpf-fix-handling-of-bpf-arena-relocations.patch
+efivarfs-fix-memory-leak-of-efivarfs_fs_info-in-fs_c.patch
--- /dev/null
+From d7d53f4b132f2307cccd3f3bb9896aced150829c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jul 2025 09:09:26 +0800
+Subject: smb: client: fix use-after-free in cifs_oplock_break
+
+From: Wang Zhaolong <wangzhaolong@huaweicloud.com>
+
+[ Upstream commit 705c79101ccf9edea5a00d761491a03ced314210 ]
+
+A race condition can occur in cifs_oplock_break() leading to a
+use-after-free of the cinode structure when unmounting:
+
+ cifs_oplock_break()
+ _cifsFileInfo_put(cfile)
+ cifsFileInfo_put_final()
+ cifs_sb_deactive()
+ [last ref, start releasing sb]
+ kill_sb()
+ kill_anon_super()
+ generic_shutdown_super()
+ evict_inodes()
+ dispose_list()
+ evict()
+ destroy_inode()
+ call_rcu(&inode->i_rcu, i_callback)
+ spin_lock(&cinode->open_file_lock) <- OK
+ [later] i_callback()
+ cifs_free_inode()
+ kmem_cache_free(cinode)
+ spin_unlock(&cinode->open_file_lock) <- UAF
+ cifs_done_oplock_break(cinode) <- UAF
+
+The issue occurs when umount has already released its reference to the
+superblock. When _cifsFileInfo_put() calls cifs_sb_deactive(), this
+releases the last reference, triggering the immediate cleanup of all
+inodes under RCU. However, cifs_oplock_break() continues to access the
+cinode after this point, resulting in use-after-free.
+
+Fix this by holding an extra reference to the superblock during the
+entire oplock break operation. This ensures that the superblock and
+its inodes remain valid until the oplock break completes.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=220309
+Fixes: b98749cac4a6 ("CIFS: keep FileInfo handle live during oplock break")
+Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
+Signed-off-by: Wang Zhaolong <wangzhaolong@huaweicloud.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/file.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
+index 9835672267d27..3819378b10129 100644
+--- a/fs/smb/client/file.c
++++ b/fs/smb/client/file.c
+@@ -3084,7 +3084,8 @@ void cifs_oplock_break(struct work_struct *work)
+ struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
+ oplock_break);
+ struct inode *inode = d_inode(cfile->dentry);
+- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
++ struct super_block *sb = inode->i_sb;
++ struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+ struct cifsInodeInfo *cinode = CIFS_I(inode);
+ struct cifs_tcon *tcon;
+ struct TCP_Server_Info *server;
+@@ -3094,6 +3095,12 @@ void cifs_oplock_break(struct work_struct *work)
+ __u64 persistent_fid, volatile_fid;
+ __u16 net_fid;
+
++ /*
++ * Hold a reference to the superblock to prevent it and its inodes from
++ * being freed while we are accessing cinode. Otherwise, _cifsFileInfo_put()
++ * may release the last reference to the sb and trigger inode eviction.
++ */
++ cifs_sb_active(sb);
+ wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS,
+ TASK_UNINTERRUPTIBLE);
+
+@@ -3166,6 +3173,7 @@ void cifs_oplock_break(struct work_struct *work)
+ cifs_put_tlink(tlink);
+ out:
+ cifs_done_oplock_break(cinode);
++ cifs_sb_deactive(sb);
+ }
+
+ static int cifs_swap_activate(struct swap_info_struct *sis,
+--
+2.39.5
+
--- /dev/null
+From 1d8d405f71aa9421b0611610264d058dc4d7854d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Jul 2025 06:07:52 +0000
+Subject: smc: Fix various oops due to inet_sock type confusion.
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit 60ada4fe644edaa6c2da97364184b0425e8aeaf5 ]
+
+syzbot reported weird splats [0][1] in cipso_v4_sock_setattr() while
+freeing inet_sk(sk)->inet_opt.
+
+The address was freed multiple times even though it was read-only memory.
+
+cipso_v4_sock_setattr() did nothing wrong, and the root cause was type
+confusion.
+
+The cited commit made it possible to create smc_sock as an INET socket.
+
+The issue is that struct smc_sock does not have struct inet_sock as the
+first member but hijacks AF_INET and AF_INET6 sk_family, which confuses
+various places.
+
+In this case, inet_sock.inet_opt was actually smc_sock.clcsk_data_ready(),
+which is an address of a function in the text segment.
+
+ $ pahole -C inet_sock vmlinux
+ struct inet_sock {
+ ...
+ struct ip_options_rcu * inet_opt; /* 784 8 */
+
+ $ pahole -C smc_sock vmlinux
+ struct smc_sock {
+ ...
+ void (*clcsk_data_ready)(struct sock *); /* 784 8 */
+
+The same issue for another field was reported before. [2][3]
+
+At that time, an ugly hack was suggested [4], but it makes both INET
+and SMC code error-prone and hard to change.
+
+Also, yet another variant was fixed by a hacky commit 98d4435efcbf3
+("net/smc: prevent NULL pointer dereference in txopt_get").
+
+Instead of papering over the root cause by such hacks, we should not
+allow non-INET socket to reuse the INET infra.
+
+Let's add inet_sock as the first member of smc_sock.
+
+[0]:
+kvfree_call_rcu(): Double-freed call. rcu_head 000000006921da73
+WARNING: CPU: 0 PID: 6718 at mm/slab_common.c:1956 kvfree_call_rcu+0x94/0x3f0 mm/slab_common.c:1955
+Modules linked in:
+CPU: 0 UID: 0 PID: 6718 Comm: syz.0.17 Tainted: G W 6.16.0-rc4-syzkaller-g7482bb149b9f #0 PREEMPT
+Tainted: [W]=WARN
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/07/2025
+pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+pc : kvfree_call_rcu+0x94/0x3f0 mm/slab_common.c:1955
+lr : kvfree_call_rcu+0x94/0x3f0 mm/slab_common.c:1955
+sp : ffff8000a03a7730
+x29: ffff8000a03a7730 x28: 00000000fffffff5 x27: 1fffe000184823d3
+x26: dfff800000000000 x25: ffff0000c2411e9e x24: ffff0000dd88da00
+x23: ffff8000891ac9a0 x22: 00000000ffffffea x21: ffff8000891ac9a0
+x20: ffff8000891ac9a0 x19: ffff80008afc2480 x18: 00000000ffffffff
+x17: 0000000000000000 x16: ffff80008ae642c8 x15: ffff700011ede14c
+x14: 1ffff00011ede14c x13: 0000000000000004 x12: ffffffffffffffff
+x11: ffff700011ede14c x10: 0000000000ff0100 x9 : 5fa3c1ffaf0ff000
+x8 : 5fa3c1ffaf0ff000 x7 : 0000000000000001 x6 : 0000000000000001
+x5 : ffff8000a03a7078 x4 : ffff80008f766c20 x3 : ffff80008054d360
+x2 : 0000000000000000 x1 : 0000000000000201 x0 : 0000000000000000
+Call trace:
+ kvfree_call_rcu+0x94/0x3f0 mm/slab_common.c:1955 (P)
+ cipso_v4_sock_setattr+0x2f0/0x3f4 net/ipv4/cipso_ipv4.c:1914
+ netlbl_sock_setattr+0x240/0x334 net/netlabel/netlabel_kapi.c:1000
+ smack_netlbl_add+0xa8/0x158 security/smack/smack_lsm.c:2581
+ smack_inode_setsecurity+0x378/0x430 security/smack/smack_lsm.c:2912
+ security_inode_setsecurity+0x118/0x3c0 security/security.c:2706
+ __vfs_setxattr_noperm+0x174/0x5c4 fs/xattr.c:251
+ __vfs_setxattr_locked+0x1ec/0x218 fs/xattr.c:295
+ vfs_setxattr+0x158/0x2ac fs/xattr.c:321
+ do_setxattr fs/xattr.c:636 [inline]
+ file_setxattr+0x1b8/0x294 fs/xattr.c:646
+ path_setxattrat+0x2ac/0x320 fs/xattr.c:711
+ __do_sys_fsetxattr fs/xattr.c:761 [inline]
+ __se_sys_fsetxattr fs/xattr.c:758 [inline]
+ __arm64_sys_fsetxattr+0xc0/0xdc fs/xattr.c:758
+ __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
+ invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:49
+ el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:132
+ do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:151
+ el0_svc+0x58/0x180 arch/arm64/kernel/entry-common.c:879
+ el0t_64_sync_handler+0x84/0x12c arch/arm64/kernel/entry-common.c:898
+ el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:600
+
+[1]:
+Unable to handle kernel write to read-only memory at virtual address ffff8000891ac9a8
+KASAN: probably user-memory-access in range [0x0000000448d64d40-0x0000000448d64d47]
+Mem abort info:
+ ESR = 0x000000009600004e
+ EC = 0x25: DABT (current EL), IL = 32 bits
+ SET = 0, FnV = 0
+ EA = 0, S1PTW = 0
+ FSC = 0x0e: level 2 permission fault
+Data abort info:
+ ISV = 0, ISS = 0x0000004e, ISS2 = 0x00000000
+ CM = 0, WnR = 1, TnD = 0, TagAccess = 0
+ GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000207144000
+[ffff8000891ac9a8] pgd=0000000000000000, p4d=100000020f950003, pud=100000020f951003, pmd=0040000201000781
+Internal error: Oops: 000000009600004e [#1] SMP
+Modules linked in:
+CPU: 0 UID: 0 PID: 6946 Comm: syz.0.69 Not tainted 6.16.0-rc4-syzkaller-g7482bb149b9f #0 PREEMPT
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/07/2025
+pstate: 604000c5 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+pc : kvfree_call_rcu+0x31c/0x3f0 mm/slab_common.c:1971
+lr : add_ptr_to_bulk_krc_lock mm/slab_common.c:1838 [inline]
+lr : kvfree_call_rcu+0xfc/0x3f0 mm/slab_common.c:1963
+sp : ffff8000a28a7730
+x29: ffff8000a28a7730 x28: 00000000fffffff5 x27: 1fffe00018b09bb3
+x26: 0000000000000001 x25: ffff80008f66e000 x24: ffff00019beaf498
+x23: ffff00019beaf4c0 x22: 0000000000000000 x21: ffff8000891ac9a0
+x20: ffff8000891ac9a0 x19: 0000000000000000 x18: 00000000ffffffff
+x17: ffff800093363000 x16: ffff80008052c6e4 x15: ffff700014514ecc
+x14: 1ffff00014514ecc x13: 0000000000000004 x12: ffffffffffffffff
+x11: ffff700014514ecc x10: 0000000000000001 x9 : 0000000000000001
+x8 : ffff00019beaf7b4 x7 : ffff800080a94154 x6 : 0000000000000000
+x5 : ffff8000935efa60 x4 : 0000000000000008 x3 : ffff80008052c7fc
+x2 : 0000000000000001 x1 : ffff8000891ac9a0 x0 : 0000000000000001
+Call trace:
+ kvfree_call_rcu+0x31c/0x3f0 mm/slab_common.c:1967 (P)
+ cipso_v4_sock_setattr+0x2f0/0x3f4 net/ipv4/cipso_ipv4.c:1914
+ netlbl_sock_setattr+0x240/0x334 net/netlabel/netlabel_kapi.c:1000
+ smack_netlbl_add+0xa8/0x158 security/smack/smack_lsm.c:2581
+ smack_inode_setsecurity+0x378/0x430 security/smack/smack_lsm.c:2912
+ security_inode_setsecurity+0x118/0x3c0 security/security.c:2706
+ __vfs_setxattr_noperm+0x174/0x5c4 fs/xattr.c:251
+ __vfs_setxattr_locked+0x1ec/0x218 fs/xattr.c:295
+ vfs_setxattr+0x158/0x2ac fs/xattr.c:321
+ do_setxattr fs/xattr.c:636 [inline]
+ file_setxattr+0x1b8/0x294 fs/xattr.c:646
+ path_setxattrat+0x2ac/0x320 fs/xattr.c:711
+ __do_sys_fsetxattr fs/xattr.c:761 [inline]
+ __se_sys_fsetxattr fs/xattr.c:758 [inline]
+ __arm64_sys_fsetxattr+0xc0/0xdc fs/xattr.c:758
+ __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
+ invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:49
+ el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:132
+ do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:151
+ el0_svc+0x58/0x180 arch/arm64/kernel/entry-common.c:879
+ el0t_64_sync_handler+0x84/0x12c arch/arm64/kernel/entry-common.c:898
+ el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:600
+Code: aa1f03e2 52800023 97ee1e8d b4000195 (f90006b4)
+
+Fixes: d25a92ccae6b ("net/smc: Introduce IPPROTO_SMC")
+Reported-by: syzbot+40bf00346c3fe40f90f2@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/686d9b50.050a0220.1ffab7.0020.GAE@google.com/
+Tested-by: syzbot+40bf00346c3fe40f90f2@syzkaller.appspotmail.com
+Reported-by: syzbot+f22031fad6cbe52c70e7@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/686da0f3.050a0220.1ffab7.0022.GAE@google.com/
+Reported-by: syzbot+271fed3ed6f24600c364@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=271fed3ed6f24600c364 # [2]
+Link: https://lore.kernel.org/netdev/99f284be-bf1d-4bc4-a629-77b268522fff@huawei.com/ # [3]
+Link: https://lore.kernel.org/netdev/20250331081003.1503211-1-wangliang74@huawei.com/ # [4]
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: D. Wythe <alibuda@linux.alibaba.com>
+Reviewed-by: Wang Liang <wangliang74@huawei.com>
+Link: https://patch.msgid.link/20250711060808.2977529-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/af_smc.c | 14 ++++++++++++++
+ net/smc/smc.h | 8 ++++----
+ 2 files changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index 3760131f14845..1882bab8e00e7 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -30,6 +30,10 @@
+ #include <linux/splice.h>
+
+ #include <net/sock.h>
++#include <net/inet_common.h>
++#if IS_ENABLED(CONFIG_IPV6)
++#include <net/ipv6.h>
++#endif
+ #include <net/tcp.h>
+ #include <net/smc.h>
+ #include <asm/ioctls.h>
+@@ -360,6 +364,16 @@ static void smc_destruct(struct sock *sk)
+ return;
+ if (!sock_flag(sk, SOCK_DEAD))
+ return;
++ switch (sk->sk_family) {
++ case AF_INET:
++ inet_sock_destruct(sk);
++ break;
++#if IS_ENABLED(CONFIG_IPV6)
++ case AF_INET6:
++ inet6_sock_destruct(sk);
++ break;
++#endif
++ }
+ }
+
+ static struct lock_class_key smc_key;
+diff --git a/net/smc/smc.h b/net/smc/smc.h
+index 78ae10d06ed2e..2c90849637398 100644
+--- a/net/smc/smc.h
++++ b/net/smc/smc.h
+@@ -283,10 +283,10 @@ struct smc_connection {
+ };
+
+ struct smc_sock { /* smc sock container */
+- struct sock sk;
+-#if IS_ENABLED(CONFIG_IPV6)
+- struct ipv6_pinfo *pinet6;
+-#endif
++ union {
++ struct sock sk;
++ struct inet_sock icsk_inet;
++ };
+ struct socket *clcsock; /* internal tcp socket */
+ void (*clcsk_state_change)(struct sock *sk);
+ /* original stat_change fct. */
+--
+2.39.5
+
--- /dev/null
+From dbad7ae4e00a647c800eec4a4897c0a08a0605d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Jun 2025 15:55:19 +0530
+Subject: soundwire: amd: fix for clearing command status register
+
+From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+[ Upstream commit a628e69b6412dc02757a6a23f7f16ce0c14d71f1 ]
+
+To clear the valid result status, 1 should be written to
+ACP_SDW_IMM_CMD_STS register. Update the ACP_SW_IMM_CMD_STS register value
+as 1.
+
+Fixes: d8f48fbdfd9a ("soundwire: amd: Add support for AMD Manager driver")
+Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Link: https://lore.kernel.org/r/20250620102617.73437-1-Vijendar.Mukunda@amd.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/amd_manager.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/soundwire/amd_manager.c b/drivers/soundwire/amd_manager.c
+index a9a57cb6257cc..7a671a7861979 100644
+--- a/drivers/soundwire/amd_manager.c
++++ b/drivers/soundwire/amd_manager.c
+@@ -238,7 +238,7 @@ static u64 amd_sdw_send_cmd_get_resp(struct amd_sdw_manager *amd_manager, u32 lo
+
+ if (sts & AMD_SDW_IMM_RES_VALID) {
+ dev_err(amd_manager->dev, "SDW%x manager is in bad state\n", amd_manager->instance);
+- writel(0x00, amd_manager->mmio + ACP_SW_IMM_CMD_STS);
++ writel(AMD_SDW_IMM_RES_VALID, amd_manager->mmio + ACP_SW_IMM_CMD_STS);
+ }
+ writel(upper_data, amd_manager->mmio + ACP_SW_IMM_CMD_UPPER_WORD);
+ writel(lower_data, amd_manager->mmio + ACP_SW_IMM_CMD_LOWER_QWORD);
+--
+2.39.5
+
--- /dev/null
+From ae98b517cdf3b680e7ab9032eff732a12e280be3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 May 2025 11:13:39 +0530
+Subject: soundwire: amd: fix for handling slave alerts after link is down
+
+From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+[ Upstream commit 86a4371b76976158be875dc654ceee35c574b27b ]
+
+Sometimes, its observed that during system level suspend callback
+execution, after link is down, handling pending slave status workqueue
+results in mipi register access failures as shown below.
+
+soundwire sdw-master-0-0: trf on Slave 1 failed:-110 read addr 0 count 1
+rt722-sdca sdw:0:0:025d:0722:01: SDW_DP0_INT recheck read failed:-110
+rt722-sdca sdw:0:0:025d:0722:01: Slave 1 alert handling failed: -110
+amd_sdw_manager amd_sdw_manager.0: SDW0 cmd response timeout occurred
+amd_sdw_manager amd_sdw_manager.0: command timeout for Slave 1
+soundwire sdw-master-0-0: trf on Slave 1 failed:-110 write addr 5c count 1
+amd_sdw_manager amd_sdw_manager.0: SDW0 previous cmd status clear failed
+amd_sdw_manager amd_sdw_manager.0: command timeout for Slave 1
+soundwire sdw-master-0-0: trf on Slave 1 failed:-110 write addr 5d count 1
+amd_sdw_manager amd_sdw_manager.0: SDW0 previous cmd status clear failed
+amd_sdw_manager amd_sdw_manager.0: command timeout for Slave 1
+
+Cancel the pending slave status workqueue prior to initiating clock stop
+sequence during suspend callback execution for both the power modes.
+
+Fixes: 9cf1efc5ed2d ("soundwire: amd: add pm_prepare callback and pm ops support")
+Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Link: https://lore.kernel.org/r/20250530054447.1645807-2-Vijendar.Mukunda@amd.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/amd_manager.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/soundwire/amd_manager.c b/drivers/soundwire/amd_manager.c
+index a12c68b93b1c3..a9a57cb6257cc 100644
+--- a/drivers/soundwire/amd_manager.c
++++ b/drivers/soundwire/amd_manager.c
+@@ -1209,6 +1209,7 @@ static int __maybe_unused amd_suspend(struct device *dev)
+ }
+
+ if (amd_manager->power_mode_mask & AMD_SDW_CLK_STOP_MODE) {
++ cancel_work_sync(&amd_manager->amd_sdw_work);
+ amd_sdw_wake_enable(amd_manager, false);
+ if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) {
+ ret = amd_sdw_host_wake_enable(amd_manager, false);
+@@ -1219,6 +1220,7 @@ static int __maybe_unused amd_suspend(struct device *dev)
+ if (ret)
+ return ret;
+ } else if (amd_manager->power_mode_mask & AMD_SDW_POWER_OFF_MODE) {
++ cancel_work_sync(&amd_manager->amd_sdw_work);
+ amd_sdw_wake_enable(amd_manager, false);
+ if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) {
+ ret = amd_sdw_host_wake_enable(amd_manager, false);
+--
+2.39.5
+
--- /dev/null
+From 40a45ea8b63982c70531f5fc7c7e1cfec15f5b44 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jul 2025 07:38:50 -0700
+Subject: tls: always refresh the queue when reading sock
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 4ab26bce3969f8fd925fe6f6f551e4d1a508c68b ]
+
+After recent changes in net-next TCP compacts skbs much more
+aggressively. This unearthed a bug in TLS where we may try
+to operate on an old skb when checking if all skbs in the
+queue have matching decrypt state and geometry.
+
+ BUG: KASAN: slab-use-after-free in tls_strp_check_rcv+0x898/0x9a0 [tls]
+ (net/tls/tls_strp.c:436 net/tls/tls_strp.c:530 net/tls/tls_strp.c:544)
+ Read of size 4 at addr ffff888013085750 by task tls/13529
+
+ CPU: 2 UID: 0 PID: 13529 Comm: tls Not tainted 6.16.0-rc5-virtme
+ Call Trace:
+ kasan_report+0xca/0x100
+ tls_strp_check_rcv+0x898/0x9a0 [tls]
+ tls_rx_rec_wait+0x2c9/0x8d0 [tls]
+ tls_sw_recvmsg+0x40f/0x1aa0 [tls]
+ inet_recvmsg+0x1c3/0x1f0
+
+Always reload the queue, fast path is to have the record in the queue
+when we wake, anyway (IOW the path going down "if !strp->stm.full_len").
+
+Fixes: 0d87bbd39d7f ("tls: strp: make sure the TCP skbs do not have overlapping data")
+Link: https://patch.msgid.link/20250716143850.1520292-1-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tls/tls_strp.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/net/tls/tls_strp.c b/net/tls/tls_strp.c
+index 65b0da6fdf6a7..095cf31bae0ba 100644
+--- a/net/tls/tls_strp.c
++++ b/net/tls/tls_strp.c
+@@ -512,9 +512,8 @@ static int tls_strp_read_sock(struct tls_strparser *strp)
+ if (inq < strp->stm.full_len)
+ return tls_strp_read_copy(strp, true);
+
++ tls_strp_load_anchor_with_queue(strp, inq);
+ if (!strp->stm.full_len) {
+- tls_strp_load_anchor_with_queue(strp, inq);
+-
+ sz = tls_rx_msg_size(strp, strp->anchor);
+ if (sz < 0) {
+ tls_strp_abort_strp(strp, sz);
+--
+2.39.5
+
--- /dev/null
+From 104f3e928f797c0d82affd10e9fd3a27792f8f86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jul 2025 13:12:56 +0200
+Subject: usb: net: sierra: check for no status endpoint
+
+From: Oliver Neukum <oneukum@suse.com>
+
+[ Upstream commit 4c4ca3c46167518f8534ed70f6e3b4bf86c4d158 ]
+
+The driver checks for having three endpoints and
+having bulk in and out endpoints, but not that
+the third endpoint is interrupt input.
+Rectify the omission.
+
+Reported-by: syzbot+3f89ec3d1d0842e95d50@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/linux-usb/686d5a9f.050a0220.1ffab7.0017.GAE@google.com/
+Tested-by: syzbot+3f89ec3d1d0842e95d50@syzkaller.appspotmail.com
+Fixes: eb4fd8cd355c8 ("net/usb: add sierra_net.c driver")
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Link: https://patch.msgid.link/20250714111326.258378-1-oneukum@suse.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/sierra_net.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c
+index dec6e82eb0e03..fc9e560e197d4 100644
+--- a/drivers/net/usb/sierra_net.c
++++ b/drivers/net/usb/sierra_net.c
+@@ -689,6 +689,10 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)
+ status);
+ return -ENODEV;
+ }
++ if (!dev->status) {
++ dev_err(&dev->udev->dev, "No status endpoint found");
++ return -ENODEV;
++ }
+ /* Initialize sierra private data */
+ priv = kzalloc(sizeof *priv, GFP_KERNEL);
+ if (!priv)
+--
+2.39.5
+
--- /dev/null
+From 658d3ca51d180192b746b88bf858ff41d7d795e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jul 2025 19:57:17 +0800
+Subject: virtio-net: fix recursived rtnl_lock() during probe()
+
+From: Zigit Zo <zuozhijie@bytedance.com>
+
+[ Upstream commit be5dcaed694e4255dc02dd0acfe036708c535def ]
+
+The deadlock appears in a stack trace like:
+
+ virtnet_probe()
+ rtnl_lock()
+ virtio_config_changed_work()
+ netdev_notify_peers()
+ rtnl_lock()
+
+It happens if the VMM sends a VIRTIO_NET_S_ANNOUNCE request while the
+virtio-net driver is still probing.
+
+The config_work in probe() will get scheduled until virtnet_open() enables
+the config change notification via virtio_config_driver_enable().
+
+Fixes: df28de7b0050 ("virtio-net: synchronize operstate with admin state on up/down")
+Signed-off-by: Zigit Zo <zuozhijie@bytedance.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Link: https://patch.msgid.link/20250716115717.1472430-1-zuozhijie@bytedance.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/virtio_net.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
+index d5be73a964708..c69c241948019 100644
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -7074,7 +7074,7 @@ static int virtnet_probe(struct virtio_device *vdev)
+ otherwise get link status from config. */
+ netif_carrier_off(dev);
+ if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
+- virtnet_config_changed_work(&vi->config_work);
++ virtio_config_changed(vi->vdev);
+ } else {
+ vi->status = VIRTIO_NET_S_LINK_UP;
+ virtnet_update_settings(vi);
+--
+2.39.5
+
--- /dev/null
+From 3599916579359467b1bc3b391d2f6ab9481b3901 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jul 2025 14:21:30 +0200
+Subject: wifi: cfg80211: remove scan request n_channels counted_by
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 444020f4bf06fb86805ee7e7ceec0375485fd94d ]
+
+This reverts commit e3eac9f32ec0 ("wifi: cfg80211: Annotate struct
+cfg80211_scan_request with __counted_by").
+
+This really has been a completely failed experiment. There were
+no actual bugs found, and yet at this point we already have four
+"fixes" to it, with nothing to show for but code churn, and it
+never even made the code any safer.
+
+In all of the cases that ended up getting "fixed", the structure
+is also internally inconsistent after the n_channels setting as
+the channel list isn't actually filled yet. You cannot scan with
+such a structure, that's just wrong. In mac80211, the struct is
+also reused multiple times, so initializing it once is no good.
+
+Some previous "fixes" (e.g. one in brcm80211) are also just setting
+n_channels before accessing the array, under the assumption that the
+code is correct and the array can be accessed, further showing that
+the whole thing is just pointless when the allocation count and use
+count are not separate.
+
+If we really wanted to fix it, we'd need to separately track the
+number of channels allocated and the number of channels currently
+used, but given that no bugs were found despite the numerous syzbot
+reports, that'd just be a waste of time.
+
+Remove the __counted_by() annotation. We really should also remove
+a number of the n_channels settings that are setting up a structure
+that's inconsistent, but that can wait.
+
+Reported-by: syzbot+e834e757bd9b3d3e1251@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=e834e757bd9b3d3e1251
+Fixes: e3eac9f32ec0 ("wifi: cfg80211: Annotate struct cfg80211_scan_request with __counted_by")
+Link: https://patch.msgid.link/20250714142130.9b0bbb7e1f07.I09112ccde72d445e11348fc2bef68942cb2ffc94@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/cfg80211.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index efbd79c67be21..75f2e5782887f 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -2720,7 +2720,7 @@ struct cfg80211_scan_request {
+ s8 tsf_report_link_id;
+
+ /* keep last */
+- struct ieee80211_channel *channels[] __counted_by(n_channels);
++ struct ieee80211_channel *channels[];
+ };
+
+ static inline void get_random_mask_addr(u8 *buf, const u8 *addr, const u8 *mask)
+--
+2.39.5
+
--- /dev/null
+From 2788e5439939404761cbe5138c62fbcdc578b409 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Jul 2025 06:56:39 +0300
+Subject: wifi: iwlwifi: mask reserved bits in chan_state_active_bitmap
+
+From: Pagadala Yesu Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
+
+[ Upstream commit 5fde0fcbd7608dd5f97a5c0c23a316074d6f17f5 ]
+
+Mask the reserved bits as firmware will assert if reserved bits are set.
+
+Fixes: ef7ddf4e2f94 ("wifi: iwlwifi: Add support for LARI_CONFIG_CHANGE_CMD v12")
+Signed-off-by: Pagadala Yesu Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20250709065608.7a72c70bdc9d.Ic9be0a3fc3aabde0c4b88568f3bb7b76e375f8d4@changeid
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h | 5 +++--
+ drivers/net/wireless/intel/iwlwifi/fw/regulatory.c | 1 +
+ drivers/net/wireless/intel/iwlwifi/mld/regulatory.c | 4 +++-
+ 3 files changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
+index 5cdc09d465d4f..e90f3187e55c4 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+ /*
+- * Copyright (C) 2012-2014, 2018-2024 Intel Corporation
++ * Copyright (C) 2012-2014, 2018-2025 Intel Corporation
+ * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
+ * Copyright (C) 2016-2017 Intel Deutschland GmbH
+ */
+@@ -754,7 +754,7 @@ struct iwl_lari_config_change_cmd_v10 {
+ * according to the BIOS definitions.
+ * For LARI cmd version 11 - bits 0:4 are supported.
+ * For LARI cmd version 12 - bits 0:6 are supported and bits 7:31 are
+- * reserved. No need to mask out the reserved bits.
++ * reserved.
+ * @force_disable_channels_bitmap: Bitmap of disabled bands/channels.
+ * Each bit represents a set of channels in a specific band that should be
+ * disabled
+@@ -787,6 +787,7 @@ struct iwl_lari_config_change_cmd {
+ /* Activate UNII-1 (5.2GHz) for World Wide */
+ #define ACTIVATE_5G2_IN_WW_MASK BIT(4)
+ #define CHAN_STATE_ACTIVE_BITMAP_CMD_V11 0x1F
++#define CHAN_STATE_ACTIVE_BITMAP_CMD_V12 0x7F
+
+ /**
+ * struct iwl_pnvm_init_complete_ntfy - PNVM initialization complete
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
+index 6adcfa6e214a0..9947ab7c2f4b3 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
++++ b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
+@@ -603,6 +603,7 @@ int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt,
+
+ ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ACTIVATE_CHANNEL, &value);
+ if (!ret) {
++ value &= CHAN_STATE_ACTIVE_BITMAP_CMD_V12;
+ if (cmd_ver < 8)
+ value &= ~ACTIVATE_5G2_IN_WW_MASK;
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c
+index a75af8c1e8ab0..2116b717b9267 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c
++++ b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c
+@@ -251,8 +251,10 @@ void iwl_mld_configure_lari(struct iwl_mld *mld)
+ cpu_to_le32(value &= DSM_UNII4_ALLOW_BITMAP);
+
+ ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ACTIVATE_CHANNEL, &value);
+- if (!ret)
++ if (!ret) {
++ value &= CHAN_STATE_ACTIVE_BITMAP_CMD_V12;
+ cmd.chan_state_active_bitmap = cpu_to_le32(value);
++ }
+
+ ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_6E, &value);
+ if (!ret)
+--
+2.39.5
+