--- /dev/null
+From 3d61e28b9f55a839781906c9ba40111caf5067c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Jan 2023 13:49:30 +0100
+Subject: affs: initialize fsdata in affs_truncate()
+
+From: Alexander Potapenko <glider@google.com>
+
+[ Upstream commit eef034ac6690118c88f357b00e2b3239c9d8575d ]
+
+When aops->write_begin() does not initialize fsdata, KMSAN may report
+an error passing the latter to aops->write_end().
+
+Fix this by unconditionally initializing fsdata.
+
+Fixes: f2b6a16eb8f5 ("fs: affs convert to new aops")
+Suggested-by: Eric Biggers <ebiggers@kernel.org>
+Signed-off-by: Alexander Potapenko <glider@google.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/affs/file.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/affs/file.c b/fs/affs/file.c
+index 75ebd2b576ca..25d480ea797b 100644
+--- a/fs/affs/file.c
++++ b/fs/affs/file.c
+@@ -881,7 +881,7 @@ affs_truncate(struct inode *inode)
+ if (inode->i_size > AFFS_I(inode)->mmu_private) {
+ struct address_space *mapping = inode->i_mapping;
+ struct page *page;
+- void *fsdata;
++ void *fsdata = NULL;
+ loff_t isize = inode->i_size;
+ int res;
+
+--
+2.39.0
+
--- /dev/null
+From 30b389e791d90d50a884989e1719279b72cd7fbc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 22:58:52 +0530
+Subject: amd-xgbe: Delay AN timeout during KR training
+
+From: Raju Rangoju <Raju.Rangoju@amd.com>
+
+[ Upstream commit 926446ae24c03311a480fb96eb78f0ce7ea6d091 ]
+
+AN restart triggered during KR training not only aborts the KR training
+process but also move the HW to unstable state. Driver has to wait upto
+500ms or until the KR training is completed before restarting AN cycle.
+
+Fixes: 7c12aa08779c ("amd-xgbe: Move the PHY support into amd-xgbe")
+Co-developed-by: Sudheesh Mavila <sudheesh.mavila@amd.com>
+Signed-off-by: Sudheesh Mavila <sudheesh.mavila@amd.com>
+Signed-off-by: Raju Rangoju <Raju.Rangoju@amd.com>
+Acked-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/amd/xgbe/xgbe-mdio.c | 24 +++++++++++++++++++++++
+ drivers/net/ethernet/amd/xgbe/xgbe.h | 2 ++
+ 2 files changed, 26 insertions(+)
+
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+index 0c5c1b155683..43fdd111235a 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+@@ -496,6 +496,7 @@ static enum xgbe_an xgbe_an73_tx_training(struct xgbe_prv_data *pdata,
+ reg |= XGBE_KR_TRAINING_ENABLE;
+ reg |= XGBE_KR_TRAINING_START;
+ XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
++ pdata->kr_start_time = jiffies;
+
+ netif_dbg(pdata, link, pdata->netdev,
+ "KR training initiated\n");
+@@ -632,6 +633,8 @@ static enum xgbe_an xgbe_an73_incompat_link(struct xgbe_prv_data *pdata)
+
+ xgbe_switch_mode(pdata);
+
++ pdata->an_result = XGBE_AN_READY;
++
+ xgbe_an_restart(pdata);
+
+ return XGBE_AN_INCOMPAT_LINK;
+@@ -1275,9 +1278,30 @@ static bool xgbe_phy_aneg_done(struct xgbe_prv_data *pdata)
+ static void xgbe_check_link_timeout(struct xgbe_prv_data *pdata)
+ {
+ unsigned long link_timeout;
++ unsigned long kr_time;
++ int wait;
+
+ link_timeout = pdata->link_check + (XGBE_LINK_TIMEOUT * HZ);
+ if (time_after(jiffies, link_timeout)) {
++ if ((xgbe_cur_mode(pdata) == XGBE_MODE_KR) &&
++ pdata->phy.autoneg == AUTONEG_ENABLE) {
++ /* AN restart should not happen while KR training is in progress.
++ * The while loop ensures no AN restart during KR training,
++ * waits up to 500ms and AN restart is triggered only if KR
++ * training is failed.
++ */
++ wait = XGBE_KR_TRAINING_WAIT_ITER;
++ while (wait--) {
++ kr_time = pdata->kr_start_time +
++ msecs_to_jiffies(XGBE_AN_MS_TIMEOUT);
++ if (time_after(jiffies, kr_time))
++ break;
++ /* AN restart is not required, if AN result is COMPLETE */
++ if (pdata->an_result == XGBE_AN_COMPLETE)
++ return;
++ usleep_range(10000, 11000);
++ }
++ }
+ netif_dbg(pdata, link, pdata->netdev, "AN link timeout\n");
+ xgbe_phy_config_aneg(pdata);
+ }
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
+index 3305979a9f7c..e0b8f3c4cc0b 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
++++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
+@@ -289,6 +289,7 @@
+ /* Auto-negotiation */
+ #define XGBE_AN_MS_TIMEOUT 500
+ #define XGBE_LINK_TIMEOUT 5
++#define XGBE_KR_TRAINING_WAIT_ITER 50
+
+ #define XGBE_SGMII_AN_LINK_STATUS BIT(1)
+ #define XGBE_SGMII_AN_LINK_SPEED (BIT(2) | BIT(3))
+@@ -1253,6 +1254,7 @@ struct xgbe_prv_data {
+ unsigned int parallel_detect;
+ unsigned int fec_ability;
+ unsigned long an_start;
++ unsigned long kr_start_time;
+ enum xgbe_an_mode an_mode;
+
+ /* I2C support */
+--
+2.39.0
+
--- /dev/null
+From a0067348e04625d72e7d9eccf59617b81059e059 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 22:58:51 +0530
+Subject: amd-xgbe: TX Flow Ctrl Registers are h/w ver dependent
+
+From: Raju Rangoju <Raju.Rangoju@amd.com>
+
+[ Upstream commit 579923d84b04abb6cd4cd1fd9974096a2dd1832b ]
+
+There is difference in the TX Flow Control registers (TFCR) between the
+revisions of the hardware. The older revisions of hardware used to have
+single register per queue. Whereas, the newer revision of hardware (from
+ver 30H onwards) have one register per priority.
+
+Update the driver to use the TFCR based on the reported version of the
+hardware.
+
+Fixes: c5aa9e3b8156 ("amd-xgbe: Initial AMD 10GbE platform driver")
+Co-developed-by: Ajith Nayak <Ajith.Nayak@amd.com>
+Signed-off-by: Ajith Nayak <Ajith.Nayak@amd.com>
+Signed-off-by: Raju Rangoju <Raju.Rangoju@amd.com>
+Acked-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 23 +++++++++++++++--------
+ 1 file changed, 15 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+index d5fd49dd25f3..decc1c09a031 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+@@ -524,19 +524,28 @@ static void xgbe_disable_vxlan(struct xgbe_prv_data *pdata)
+ netif_dbg(pdata, drv, pdata->netdev, "VXLAN acceleration disabled\n");
+ }
+
++static unsigned int xgbe_get_fc_queue_count(struct xgbe_prv_data *pdata)
++{
++ unsigned int max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
++
++ /* From MAC ver 30H the TFCR is per priority, instead of per queue */
++ if (XGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER) >= 0x30)
++ return max_q_count;
++ else
++ return min_t(unsigned int, pdata->tx_q_count, max_q_count);
++}
++
+ static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata)
+ {
+- unsigned int max_q_count, q_count;
+ unsigned int reg, reg_val;
+- unsigned int i;
++ unsigned int i, q_count;
+
+ /* Clear MTL flow control */
+ for (i = 0; i < pdata->rx_q_count; i++)
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 0);
+
+ /* Clear MAC flow control */
+- max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
+- q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count);
++ q_count = xgbe_get_fc_queue_count(pdata);
+ reg = MAC_Q0TFCR;
+ for (i = 0; i < q_count; i++) {
+ reg_val = XGMAC_IOREAD(pdata, reg);
+@@ -553,9 +562,8 @@ static int xgbe_enable_tx_flow_control(struct xgbe_prv_data *pdata)
+ {
+ struct ieee_pfc *pfc = pdata->pfc;
+ struct ieee_ets *ets = pdata->ets;
+- unsigned int max_q_count, q_count;
+ unsigned int reg, reg_val;
+- unsigned int i;
++ unsigned int i, q_count;
+
+ /* Set MTL flow control */
+ for (i = 0; i < pdata->rx_q_count; i++) {
+@@ -579,8 +587,7 @@ static int xgbe_enable_tx_flow_control(struct xgbe_prv_data *pdata)
+ }
+
+ /* Set MAC flow control */
+- max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
+- q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count);
++ q_count = xgbe_get_fc_queue_count(pdata);
+ reg = MAC_Q0TFCR;
+ for (i = 0; i < q_count; i++) {
+ reg_val = XGMAC_IOREAD(pdata, reg);
+--
+2.39.0
+
--- /dev/null
+From c60e662af4b142efed74d4168c1c72f64f8b5c0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 13:52:41 +0200
+Subject: ARM: dts: at91: sam9x60: fix the ddr clock for sam9x60
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit 9bfa2544dbd1133f0b0af4e967de3bb9c1e3a497 ]
+
+The 2nd DDR clock for sam9x60 DDR controller is peripheral clock with
+id 49.
+
+Fixes: 1e5f532c2737 ("ARM: dts: at91: sam9x60: add device tree for soc and board")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20221208115241.36312-1-claudiu.beznea@microchip.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/sam9x60.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/sam9x60.dtsi b/arch/arm/boot/dts/sam9x60.dtsi
+index ec45ced3cde6..e1e0dec8cc1f 100644
+--- a/arch/arm/boot/dts/sam9x60.dtsi
++++ b/arch/arm/boot/dts/sam9x60.dtsi
+@@ -567,7 +567,7 @@ pmecc: ecc-engine@ffffe000 {
+ mpddrc: mpddrc@ffffe800 {
+ compatible = "microchip,sam9x60-ddramc", "atmel,sama5d3-ddramc";
+ reg = <0xffffe800 0x200>;
+- clocks = <&pmc PMC_TYPE_SYSTEM 2>, <&pmc PMC_TYPE_CORE PMC_MCK>;
++ clocks = <&pmc PMC_TYPE_SYSTEM 2>, <&pmc PMC_TYPE_PERIPHERAL 49>;
+ clock-names = "ddrck", "mpddr";
+ };
+
+--
+2.39.0
+
--- /dev/null
+From 9bfd1e73c0a422fceb0f9cb0005546c861a90f75 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 17:22:59 -0300
+Subject: ARM: dts: imx6qdl-gw560x: Remove incorrect 'uart-has-rtscts'
+
+From: Fabio Estevam <festevam@denx.de>
+
+[ Upstream commit 9dfbc72256b5de608ad10989bcbafdbbd1ac8d4e ]
+
+The following build warning is seen when running:
+
+make dtbs_check DT_SCHEMA_FILES=fsl-imx-uart.yaml
+
+arch/arm/boot/dts/imx6dl-gw560x.dtb: serial@2020000: rts-gpios: False schema does not allow [[20, 1, 0]]
+ From schema: Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml
+
+The imx6qdl-gw560x board does not expose the UART RTS and CTS
+as native UART pins, so 'uart-has-rtscts' should not be used.
+
+Using 'uart-has-rtscts' with 'rts-gpios' is an invalid combination
+detected by serial.yaml.
+
+Fix the problem by removing the incorrect 'uart-has-rtscts' property.
+
+Fixes: b8a559feffb2 ("ARM: dts: imx: add Gateworks Ventana GW5600 support")
+Signed-off-by: Fabio Estevam <festevam@denx.de>
+Acked-by: Tim Harvey <tharvey@gateworks.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6qdl-gw560x.dtsi | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/imx6qdl-gw560x.dtsi b/arch/arm/boot/dts/imx6qdl-gw560x.dtsi
+index 4bc4371e6bae..4b81a975c979 100644
+--- a/arch/arm/boot/dts/imx6qdl-gw560x.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-gw560x.dtsi
+@@ -632,7 +632,6 @@ &ssi1 {
+ &uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+- uart-has-rtscts;
+ rts-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+--
+2.39.0
+
--- /dev/null
+From 092bb82b31280eece90913e9eabfa6dd5ef6e4c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 13:31:23 -0300
+Subject: ARM: dts: imx6ul-pico-dwarf: Use 'clock-frequency'
+
+From: Fabio Estevam <festevam@denx.de>
+
+[ Upstream commit 94e2cf1e0db5b06c7a6ae0878c5cbec925819a8a ]
+
+'clock_frequency' is not a valid property.
+
+Use the correct 'clock-frequency' instead.
+
+Fixes: 47246fafef84 ("ARM: dts: imx6ul-pico: Add support for the dwarf baseboard")
+Signed-off-by: Fabio Estevam <festevam@denx.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6ul-pico-dwarf.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/imx6ul-pico-dwarf.dts b/arch/arm/boot/dts/imx6ul-pico-dwarf.dts
+index 162dc259edc8..5a74c7f68eb6 100644
+--- a/arch/arm/boot/dts/imx6ul-pico-dwarf.dts
++++ b/arch/arm/boot/dts/imx6ul-pico-dwarf.dts
+@@ -32,7 +32,7 @@ sys_mclk: clock-sys-mclk {
+ };
+
+ &i2c2 {
+- clock_frequency = <100000>;
++ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+--
+2.39.0
+
--- /dev/null
+From 7fc62323573dac6094d12698ff36323dd88923bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 13:31:24 -0300
+Subject: ARM: dts: imx7d-pico: Use 'clock-frequency'
+
+From: Fabio Estevam <festevam@denx.de>
+
+[ Upstream commit f4dd0845c4f1f5371f1e06fef0e4a1734a2db964 ]
+
+'clock_frequency' is not a valid property.
+
+Use the correct 'clock-frequency' instead.
+
+Fixes: 8b646cfb84c3 ("ARM: dts: imx7d-pico: Add support for the dwarf baseboard")
+Fixes: 6418fd92417f ("ARM: dts: imx7d-pico: Add support for the nymph baseboard")
+Signed-off-by: Fabio Estevam <festevam@denx.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx7d-pico-dwarf.dts | 4 ++--
+ arch/arm/boot/dts/imx7d-pico-nymph.dts | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/boot/dts/imx7d-pico-dwarf.dts b/arch/arm/boot/dts/imx7d-pico-dwarf.dts
+index 5162fe227d1e..fdc10563f147 100644
+--- a/arch/arm/boot/dts/imx7d-pico-dwarf.dts
++++ b/arch/arm/boot/dts/imx7d-pico-dwarf.dts
+@@ -32,7 +32,7 @@ sys_mclk: clock-sys-mclk {
+ };
+
+ &i2c1 {
+- clock_frequency = <100000>;
++ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+@@ -52,7 +52,7 @@ pressure-sensor@60 {
+ };
+
+ &i2c4 {
+- clock_frequency = <100000>;
++ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+diff --git a/arch/arm/boot/dts/imx7d-pico-nymph.dts b/arch/arm/boot/dts/imx7d-pico-nymph.dts
+index 104a85254adb..5afb1674e012 100644
+--- a/arch/arm/boot/dts/imx7d-pico-nymph.dts
++++ b/arch/arm/boot/dts/imx7d-pico-nymph.dts
+@@ -43,7 +43,7 @@ sys_mclk: clock-sys-mclk {
+ };
+
+ &i2c1 {
+- clock_frequency = <100000>;
++ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+@@ -64,7 +64,7 @@ adc@52 {
+ };
+
+ &i2c2 {
+- clock_frequency = <100000>;
++ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+--
+2.39.0
+
--- /dev/null
+From 9ae44b5f5525833bb09e99e0a524538e30364581 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 17:54:03 +0100
+Subject: ARM: imx: add missing of_node_put()
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit 87b30c4b0efb6a194a7b8eac2568a3da520d905f ]
+
+Calling of_find_compatible_node() returns a node pointer with refcount
+incremented. Use of_node_put() on it when done.
+The patch fixes the same problem on different i.MX platforms.
+
+Fixes: 8b88f7ef31dde ("ARM: mx25: Retrieve IIM base from dt")
+Fixes: 94b2bec1b0e05 ("ARM: imx27: Retrieve the SYSCTRL base address from devicetree")
+Fixes: 3172225d45bd9 ("ARM: imx31: Retrieve the IIM base address from devicetree")
+Fixes: f68ea682d1da7 ("ARM: imx35: Retrieve the IIM base address from devicetree")
+Fixes: ee18a7154ee08 ("ARM: imx5: retrieve iim base from device tree")
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Reviewed-by: Fabio Estevam <festevam@gmail.com>
+Reviewed-by: Martin Kaiser <martin@kaiser.cx>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-imx/cpu-imx25.c | 1 +
+ arch/arm/mach-imx/cpu-imx27.c | 1 +
+ arch/arm/mach-imx/cpu-imx31.c | 1 +
+ arch/arm/mach-imx/cpu-imx35.c | 1 +
+ arch/arm/mach-imx/cpu-imx5.c | 1 +
+ 5 files changed, 5 insertions(+)
+
+diff --git a/arch/arm/mach-imx/cpu-imx25.c b/arch/arm/mach-imx/cpu-imx25.c
+index b2e1963f473d..2ee2d2813d57 100644
+--- a/arch/arm/mach-imx/cpu-imx25.c
++++ b/arch/arm/mach-imx/cpu-imx25.c
+@@ -23,6 +23,7 @@ static int mx25_read_cpu_rev(void)
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx25-iim");
+ iim_base = of_iomap(np, 0);
++ of_node_put(np);
+ BUG_ON(!iim_base);
+ rev = readl(iim_base + MXC_IIMSREV);
+ iounmap(iim_base);
+diff --git a/arch/arm/mach-imx/cpu-imx27.c b/arch/arm/mach-imx/cpu-imx27.c
+index bf70e13bbe9e..1d2893908368 100644
+--- a/arch/arm/mach-imx/cpu-imx27.c
++++ b/arch/arm/mach-imx/cpu-imx27.c
+@@ -28,6 +28,7 @@ static int mx27_read_cpu_rev(void)
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx27-ccm");
+ ccm_base = of_iomap(np, 0);
++ of_node_put(np);
+ BUG_ON(!ccm_base);
+ /*
+ * now we have access to the IO registers. As we need
+diff --git a/arch/arm/mach-imx/cpu-imx31.c b/arch/arm/mach-imx/cpu-imx31.c
+index b9c24b851d1a..35c544924e50 100644
+--- a/arch/arm/mach-imx/cpu-imx31.c
++++ b/arch/arm/mach-imx/cpu-imx31.c
+@@ -39,6 +39,7 @@ static int mx31_read_cpu_rev(void)
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx31-iim");
+ iim_base = of_iomap(np, 0);
++ of_node_put(np);
+ BUG_ON(!iim_base);
+
+ /* read SREV register from IIM module */
+diff --git a/arch/arm/mach-imx/cpu-imx35.c b/arch/arm/mach-imx/cpu-imx35.c
+index 80e7d8ab9f1b..1fe75b39c2d9 100644
+--- a/arch/arm/mach-imx/cpu-imx35.c
++++ b/arch/arm/mach-imx/cpu-imx35.c
+@@ -21,6 +21,7 @@ static int mx35_read_cpu_rev(void)
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx35-iim");
+ iim_base = of_iomap(np, 0);
++ of_node_put(np);
+ BUG_ON(!iim_base);
+
+ rev = imx_readl(iim_base + MXC_IIMSREV);
+diff --git a/arch/arm/mach-imx/cpu-imx5.c b/arch/arm/mach-imx/cpu-imx5.c
+index ad56263778f9..a67c89bf155d 100644
+--- a/arch/arm/mach-imx/cpu-imx5.c
++++ b/arch/arm/mach-imx/cpu-imx5.c
+@@ -28,6 +28,7 @@ static u32 imx5_read_srev_reg(const char *compat)
+
+ np = of_find_compatible_node(NULL, NULL, compat);
+ iim_base = of_iomap(np, 0);
++ of_node_put(np);
+ WARN_ON(!iim_base);
+
+ srev = readl(iim_base + IIM_SREV) & 0xff;
+--
+2.39.0
+
--- /dev/null
+From 1b8237dcb5e95a210123b25766870fd144b38bfa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Dec 2022 13:10:37 -0600
+Subject: arm64: dts: imx8mm-beacon: Fix ecspi2 pinmux
+
+From: Adam Ford <aford173@gmail.com>
+
+[ Upstream commit 5225ba9db112ec4ed67da5e4d8b72e618573955e ]
+
+Early hardware did not support hardware handshaking on the UART, but
+final production hardware did. When the hardware was updated the chip
+select was changed to facilitate hardware handshaking on UART3. Fix the
+ecspi2 pin mux to eliminate a pin conflict with UART3 and allow the
+EEPROM to operate again.
+
+Fixes: 4ce01ce36d77 ("arm64: dts: imx8mm-beacon: Enable RTS-CTS on UART3")
+Signed-off-by: Adam Ford <aford173@gmail.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi
+index 94e5fa8ca957..bb18354c10f0 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi
+@@ -70,7 +70,7 @@ sound {
+ &ecspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_espi2>;
+- cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
++ cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ eeprom@0 {
+@@ -186,7 +186,7 @@ pinctrl_espi2: espi2grp {
+ MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x82
+ MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x82
+ MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x82
+- MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x41
++ MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x41
+ >;
+ };
+
+--
+2.39.0
+
--- /dev/null
+From 738311ce1eed2d0d1ae808c37835759a91c81a81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Dec 2022 12:26:06 -0800
+Subject: arm64: dts: imx8mm-venice-gw7901: fix USB2 controller OC polarity
+
+From: Tim Harvey <tharvey@gateworks.com>
+
+[ Upstream commit ae066f374687d7dd06bb8c732f66d6ab3c3fd480 ]
+
+The GW7901 has USB2 routed to a USB VBUS supply with over-current
+protection via an active-low pin. Define the OC pin polarity properly.
+
+Fixes: 2b1649a83afc ("arm64: dts: imx: Add i.mx8mm Gateworks gw7901 dts support")
+Signed-off-by: Tim Harvey <tharvey@gateworks.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
+index bafd5c8ea4e2..f7e41e5c2c7b 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
+@@ -675,6 +675,7 @@ &usbotg1 {
+ &usbotg2 {
+ dr_mode = "host";
+ vbus-supply = <®_usb2_vbus>;
++ over-current-active-low;
+ status = "okay";
+ };
+
+--
+2.39.0
+
--- /dev/null
+From 220bea57c785f9e312f2b1167a905454e261c16d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Sep 2022 22:54:23 +0800
+Subject: arm64: dts: imx8mp: correct usb clocks
+
+From: Li Jun <jun.li@nxp.com>
+
+[ Upstream commit 8a1ed98fe0f2e7669f0409de0f46f317b275f8be ]
+
+After commit cf7f3f4fa9e5 ("clk: imx8mp: fix usb_root_clk parent"),
+usb_root_clk is no longer for suspend clock so update dts accordingly
+to use right bus clock and suspend clock.
+
+Fixes: fb8587a2c165 ("arm64: dtsi: imx8mp: add usb nodes")
+Cc: stable@vger.kernel.org # ed1f4ccfe947: clk: imx: imx8mp: add shared clk gate for usb suspend clk
+Cc: stable@vger.kernel.org # v5.19+
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Signed-off-by: Li Jun <jun.li@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mp.dtsi | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+index 664177ed38d3..25d9c58475ae 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+@@ -890,7 +890,7 @@ usb3_0: usb@32f10100 {
+ compatible = "fsl,imx8mp-dwc3";
+ reg = <0x32f10100 0x8>;
+ clocks = <&clk IMX8MP_CLK_HSIO_ROOT>,
+- <&clk IMX8MP_CLK_USB_ROOT>;
++ <&clk IMX8MP_CLK_USB_SUSP>;
+ clock-names = "hsio", "suspend";
+ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+@@ -902,9 +902,9 @@ usb3_0: usb@32f10100 {
+ usb_dwc3_0: usb@38100000 {
+ compatible = "snps,dwc3";
+ reg = <0x38100000 0x10000>;
+- clocks = <&clk IMX8MP_CLK_HSIO_AXI>,
++ clocks = <&clk IMX8MP_CLK_USB_ROOT>,
+ <&clk IMX8MP_CLK_USB_CORE_REF>,
+- <&clk IMX8MP_CLK_USB_ROOT>;
++ <&clk IMX8MP_CLK_USB_SUSP>;
+ clock-names = "bus_early", "ref", "suspend";
+ assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>;
+@@ -931,7 +931,7 @@ usb3_1: usb@32f10108 {
+ compatible = "fsl,imx8mp-dwc3";
+ reg = <0x32f10108 0x8>;
+ clocks = <&clk IMX8MP_CLK_HSIO_ROOT>,
+- <&clk IMX8MP_CLK_USB_ROOT>;
++ <&clk IMX8MP_CLK_USB_SUSP>;
+ clock-names = "hsio", "suspend";
+ interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+@@ -943,9 +943,9 @@ usb3_1: usb@32f10108 {
+ usb_dwc3_1: usb@38200000 {
+ compatible = "snps,dwc3";
+ reg = <0x38200000 0x10000>;
+- clocks = <&clk IMX8MP_CLK_HSIO_AXI>,
++ clocks = <&clk IMX8MP_CLK_USB_ROOT>,
+ <&clk IMX8MP_CLK_USB_CORE_REF>,
+- <&clk IMX8MP_CLK_USB_ROOT>;
++ <&clk IMX8MP_CLK_USB_SUSP>;
+ clock-names = "bus_early", "ref", "suspend";
+ assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>;
+--
+2.39.0
+
--- /dev/null
+From 8f42f6198022ece2567eec68b8c24740c3cc7c23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 13:29:11 -0300
+Subject: arm64: dts: imx8mp-phycore-som: Remove invalid PMIC property
+
+From: Fabio Estevam <festevam@denx.de>
+
+[ Upstream commit cfd04dd1c4b6c33afc2a934b957d71cf8ddd1539 ]
+
+'regulator-compatible' is not a valid property according to
+nxp,pca9450-regulator.yaml and causes the following warning:
+
+ DTC_CHK arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dtb
+...
+pmic@25: regulators:LDO1: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
+
+Remove the invalid 'regulator-compatible' property.
+
+Cc: Teresa Remmet <t.remmet@phytec.de>
+Fixes: 88f7f6bcca37 ("arm64: dts: freescale: Add support for phyBOARD-Pollux-i.MX8MP")
+Signed-off-by: Fabio Estevam <festevam@denx.de>
+Reviewed-by: Teresa Remmet <t.remmet@phytec.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
+index fc178eebf8aa..8e189d899794 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
+@@ -98,7 +98,6 @@ pmic: pmic@25 {
+
+ regulators {
+ buck1: BUCK1 {
+- regulator-compatible = "BUCK1";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-boot-on;
+@@ -107,7 +106,6 @@ buck1: BUCK1 {
+ };
+
+ buck2: BUCK2 {
+- regulator-compatible = "BUCK2";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-boot-on;
+@@ -116,7 +114,6 @@ buck2: BUCK2 {
+ };
+
+ buck4: BUCK4 {
+- regulator-compatible = "BUCK4";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+@@ -124,7 +121,6 @@ buck4: BUCK4 {
+ };
+
+ buck5: BUCK5 {
+- regulator-compatible = "BUCK5";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+@@ -132,7 +128,6 @@ buck5: BUCK5 {
+ };
+
+ buck6: BUCK6 {
+- regulator-compatible = "BUCK6";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+@@ -140,7 +135,6 @@ buck6: BUCK6 {
+ };
+
+ ldo1: LDO1 {
+- regulator-compatible = "LDO1";
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+@@ -148,7 +142,6 @@ ldo1: LDO1 {
+ };
+
+ ldo2: LDO2 {
+- regulator-compatible = "LDO2";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-boot-on;
+@@ -156,7 +149,6 @@ ldo2: LDO2 {
+ };
+
+ ldo3: LDO3 {
+- regulator-compatible = "LDO3";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+@@ -164,7 +156,6 @@ ldo3: LDO3 {
+ };
+
+ ldo4: LDO4 {
+- regulator-compatible = "LDO4";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+@@ -172,7 +163,6 @@ ldo4: LDO4 {
+ };
+
+ ldo5: LDO5 {
+- regulator-compatible = "LDO5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+--
+2.39.0
+
--- /dev/null
+From d63c79e9d3ac351770bf8d3181d2719a7177dbc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Dec 2022 14:19:17 +0100
+Subject: arm64: dts: qcom: msm8992: Don't use sfpb mutex
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 2bd5ab93335bf2c4d22c8db427822ae637ed8dc3 ]
+
+MSM8992 uses the same mutex hardware as MSM8994. This was wrong
+from the start, but never presented as an issue until the sfpb
+compatible was given different driver data.
+
+Fixes: 6a6d1978f9c0 ("arm64: dts: msm8992 SoC and LG Bullhead (Nexus 5X) support")
+Reported-by: Eugene Lepshy <fekz115@gmail.com>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221219131918.446587-1-konrad.dybcio@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8992.dtsi | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8992.dtsi b/arch/arm64/boot/dts/qcom/msm8992.dtsi
+index 58fe58cc7703..765e1f1989b5 100644
+--- a/arch/arm64/boot/dts/qcom/msm8992.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8992.dtsi
+@@ -14,10 +14,6 @@ &rpmcc {
+ compatible = "qcom,rpmcc-msm8992";
+ };
+
+-&tcsr_mutex {
+- compatible = "qcom,sfpb-mutex";
+-};
+-
+ &timer {
+ interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+--
+2.39.0
+
--- /dev/null
+From fda4357aaa44877e5e9bb214b8934574f8b83d68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Mar 2022 18:46:32 +0100
+Subject: arm64: dts: qcom: msm8992-libra: Add CPU regulators
+
+From: Konrad Dybcio <konrad.dybcio@somainline.org>
+
+[ Upstream commit 13cff03303676148bc8f0bbe73a6d40d5fdd020e ]
+
+Specify CPU regulator voltages for both VDD_APC rails.
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220319174645.340379-3-konrad.dybcio@somainline.org
+Stable-dep-of: 69876bc6fd4d ("arm64: dts: qcom: msm8992-libra: Fix the memory map")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../boot/dts/qcom/msm8992-xiaomi-libra.dts | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts
+index a3d6340a0c55..d55de06447f6 100644
+--- a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts
++++ b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts
+@@ -125,6 +125,23 @@ &peripheral_region {
+ no-map;
+ };
+
++&pm8994_spmi_regulators {
++ VDD_APC0: s8 {
++ regulator-min-microvolt = <680000>;
++ regulator-max-microvolt = <1180000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ /* APC1 is 3-phase, but quoting downstream, s11 is "the gang leader" */
++ VDD_APC1: s11 {
++ regulator-min-microvolt = <700000>;
++ regulator-max-microvolt = <1225000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++};
++
+ &rpm_requests {
+ pm8994-regulators {
+ compatible = "qcom,rpm-pm8994-regulators";
+--
+2.39.0
+
--- /dev/null
+From 7b4632d0ea2d9ed3fe0ec2dbd9cdc32894197885 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Dec 2022 14:19:18 +0100
+Subject: arm64: dts: qcom: msm8992-libra: Fix the memory map
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 69876bc6fd4de3ad2dc7826fe269e91fa2c1807f ]
+
+The memory map was wrong. Fix it to prevent the device from randomly
+rebooting.
+
+Fixes: 0f5cdb31e850 ("arm64: dts: qcom: Add Xiaomi Libra (Mi 4C) device tree")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221219131918.446587-2-konrad.dybcio@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../boot/dts/qcom/msm8992-xiaomi-libra.dts | 77 +++++++++++++++----
+ 1 file changed, 60 insertions(+), 17 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts
+index d55de06447f6..d08659c606b9 100644
+--- a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts
++++ b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts
+@@ -11,6 +11,12 @@
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/input/gpio-keys.h>
+
++/delete-node/ &adsp_mem;
++/delete-node/ &audio_mem;
++/delete-node/ &mpss_mem;
++/delete-node/ &peripheral_region;
++/delete-node/ &rmtfs_mem;
++
+ / {
+ model = "Xiaomi Mi 4C";
+ compatible = "xiaomi,libra", "qcom,msm8992";
+@@ -60,25 +66,67 @@ reserved-memory {
+ #size-cells = <2>;
+ ranges;
+
+- /* This is for getting crash logs using Android downstream kernels */
+- ramoops@dfc00000 {
+- compatible = "ramoops";
+- reg = <0x0 0xdfc00000 0x0 0x40000>;
+- console-size = <0x10000>;
+- record-size = <0x10000>;
+- ftrace-size = <0x10000>;
+- pmsg-size = <0x20000>;
++ memory_hole: hole@6400000 {
++ reg = <0 0x06400000 0 0x600000>;
++ no-map;
++ };
++
++ memory_hole2: hole2@6c00000 {
++ reg = <0 0x06c00000 0 0x2400000>;
++ no-map;
++ };
++
++ mpss_mem: mpss@9000000 {
++ reg = <0 0x09000000 0 0x5a00000>;
++ no-map;
++ };
++
++ tzapp: tzapp@ea00000 {
++ reg = <0 0x0ea00000 0 0x1900000>;
++ no-map;
++ };
++
++ mdm_rfsa_mem: mdm-rfsa@ca0b0000 {
++ reg = <0 0xca0b0000 0 0x10000>;
++ no-map;
++ };
++
++ rmtfs_mem: rmtfs@ca100000 {
++ compatible = "qcom,rmtfs-mem";
++ reg = <0 0xca100000 0 0x180000>;
++ no-map;
++
++ qcom,client-id = <1>;
+ };
+
+- modem_region: modem_region@9000000 {
+- reg = <0x0 0x9000000 0x0 0x5a00000>;
++ audio_mem: audio@cb400000 {
++ reg = <0 0xcb000000 0 0x400000>;
++ no-mem;
++ };
++
++ qseecom_mem: qseecom@cb400000 {
++ reg = <0 0xcb400000 0 0x1c00000>;
++ no-mem;
++ };
++
++ adsp_rfsa_mem: adsp-rfsa@cd000000 {
++ reg = <0 0xcd000000 0 0x10000>;
+ no-map;
+ };
+
+- tzapp: modem_region@ea00000 {
+- reg = <0x0 0xea00000 0x0 0x1900000>;
++ sensor_rfsa_mem: sensor-rfsa@cd010000 {
++ reg = <0 0xcd010000 0 0x10000>;
+ no-map;
+ };
++
++ ramoops@dfc00000 {
++ compatible = "ramoops";
++ reg = <0 0xdfc00000 0 0x40000>;
++ console-size = <0x10000>;
++ record-size = <0x10000>;
++ ftrace-size = <0x10000>;
++ pmsg-size = <0x20000>;
++ };
+ };
+ };
+
+@@ -120,11 +168,6 @@ &blsp2_uart2 {
+ status = "okay";
+ };
+
+-&peripheral_region {
+- reg = <0x0 0x7400000 0x0 0x1c00000>;
+- no-map;
+-};
+-
+ &pm8994_spmi_regulators {
+ VDD_APC0: s8 {
+ regulator-min-microvolt = <680000>;
+--
+2.39.0
+
--- /dev/null
+From 9ff0e2bcaaee8dd330a11efe9217fbc11318b59f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Jan 2023 23:15:07 +0000
+Subject: ASoC: fsl-asoc-card: Fix naming of AC'97 CODEC widgets
+
+From: Mark Brown <broonie@kernel.org>
+
+[ Upstream commit 242fc66ae6e1e2b8519daacc7590a73cd0e8a6e4 ]
+
+The fsl-asoc-card AC'97 support currently tries to route to Playback and
+Capture widgets provided by the AC'97 CODEC. This doesn't work since the
+generic AC'97 driver registers with an "AC97" at the front of the stream
+and hence widget names, update to reflect reality. It's not clear to me
+if or how this ever worked.
+
+Acked-by: Shengjiu Wang <shengjiu.wang@gmail.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20230106-asoc-udoo-probe-v1-2-a5d7469d4f67@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl-asoc-card.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
+index 978496c2fc09..5000d779aade 100644
+--- a/sound/soc/fsl/fsl-asoc-card.c
++++ b/sound/soc/fsl/fsl-asoc-card.c
+@@ -120,8 +120,8 @@ static const struct snd_soc_dapm_route audio_map[] = {
+
+ static const struct snd_soc_dapm_route audio_map_ac97[] = {
+ /* 1st half -- Normal DAPM routes */
+- {"Playback", NULL, "CPU AC97 Playback"},
+- {"CPU AC97 Capture", NULL, "Capture"},
++ {"AC97 Playback", NULL, "CPU AC97 Playback"},
++ {"CPU AC97 Capture", NULL, "AC97 Capture"},
+ /* 2nd half -- ASRC DAPM routes */
+ {"CPU AC97 Playback", NULL, "ASRC-Playback"},
+ {"ASRC-Capture", NULL, "CPU AC97 Capture"},
+--
+2.39.0
+
--- /dev/null
+From 97a1fe5d9e0f9feac14d042039c1be3ab16b19d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Jan 2023 10:57:54 +0800
+Subject: ASoC: fsl_micfil: Correct the number of steps on SX controls
+
+From: Chancel Liu <chancel.liu@nxp.com>
+
+[ Upstream commit cdfa92eb90f5770b26a79824ef213ebdbbd988b1 ]
+
+The parameter "max" of SOC_SINGLE_SX_TLV() means the number of steps
+rather than maximum value. This patch corrects the minimum value to -8
+and the number of steps to 15.
+
+Signed-off-by: Chancel Liu <chancel.liu@nxp.com>
+Acked-by: Shengjiu Wang <shengjiu.wang@gmail.com>
+Link: https://lore.kernel.org/r/20230104025754.3019235-1-chancel.liu@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_micfil.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
+index d1cd104f8584..38d4d1b7cfe3 100644
+--- a/sound/soc/fsl/fsl_micfil.c
++++ b/sound/soc/fsl/fsl_micfil.c
+@@ -88,21 +88,21 @@ static DECLARE_TLV_DB_SCALE(gain_tlv, 0, 100, 0);
+
+ static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = {
+ SOC_SINGLE_SX_TLV("CH0 Volume", REG_MICFIL_OUT_CTRL,
+- MICFIL_OUTGAIN_CHX_SHIFT(0), 0xF, 0x7, gain_tlv),
++ MICFIL_OUTGAIN_CHX_SHIFT(0), 0x8, 0xF, gain_tlv),
+ SOC_SINGLE_SX_TLV("CH1 Volume", REG_MICFIL_OUT_CTRL,
+- MICFIL_OUTGAIN_CHX_SHIFT(1), 0xF, 0x7, gain_tlv),
++ MICFIL_OUTGAIN_CHX_SHIFT(1), 0x8, 0xF, gain_tlv),
+ SOC_SINGLE_SX_TLV("CH2 Volume", REG_MICFIL_OUT_CTRL,
+- MICFIL_OUTGAIN_CHX_SHIFT(2), 0xF, 0x7, gain_tlv),
++ MICFIL_OUTGAIN_CHX_SHIFT(2), 0x8, 0xF, gain_tlv),
+ SOC_SINGLE_SX_TLV("CH3 Volume", REG_MICFIL_OUT_CTRL,
+- MICFIL_OUTGAIN_CHX_SHIFT(3), 0xF, 0x7, gain_tlv),
++ MICFIL_OUTGAIN_CHX_SHIFT(3), 0x8, 0xF, gain_tlv),
+ SOC_SINGLE_SX_TLV("CH4 Volume", REG_MICFIL_OUT_CTRL,
+- MICFIL_OUTGAIN_CHX_SHIFT(4), 0xF, 0x7, gain_tlv),
++ MICFIL_OUTGAIN_CHX_SHIFT(4), 0x8, 0xF, gain_tlv),
+ SOC_SINGLE_SX_TLV("CH5 Volume", REG_MICFIL_OUT_CTRL,
+- MICFIL_OUTGAIN_CHX_SHIFT(5), 0xF, 0x7, gain_tlv),
++ MICFIL_OUTGAIN_CHX_SHIFT(5), 0x8, 0xF, gain_tlv),
+ SOC_SINGLE_SX_TLV("CH6 Volume", REG_MICFIL_OUT_CTRL,
+- MICFIL_OUTGAIN_CHX_SHIFT(6), 0xF, 0x7, gain_tlv),
++ MICFIL_OUTGAIN_CHX_SHIFT(6), 0x8, 0xF, gain_tlv),
+ SOC_SINGLE_SX_TLV("CH7 Volume", REG_MICFIL_OUT_CTRL,
+- MICFIL_OUTGAIN_CHX_SHIFT(7), 0xF, 0x7, gain_tlv),
++ MICFIL_OUTGAIN_CHX_SHIFT(7), 0x8, 0xF, gain_tlv),
+ SOC_ENUM_EXT("MICFIL Quality Select",
+ fsl_micfil_quality_enum,
+ snd_soc_get_enum_double, snd_soc_put_enum_double),
+--
+2.39.0
+
--- /dev/null
+From b2e0f4828107841f85197cbcce929829fbcc7220 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Jan 2023 23:15:06 +0000
+Subject: ASoC: fsl_ssi: Rename AC'97 streams to avoid collisions with AC'97
+ CODEC
+
+From: Mark Brown <broonie@kernel.org>
+
+[ Upstream commit 8c6a42b5b0ed6f96624f56954e93eeae107440a6 ]
+
+The SSI driver calls the AC'97 playback and transmit streams "AC97 Playback"
+and "AC97 Capture" respectively. This is the same name used by the generic
+AC'97 CODEC driver in ASoC, creating confusion for the Freescale ASoC card
+when it attempts to use these widgets in routing. Add a "CPU" in the name
+like the regular DAIs registered by the driver to disambiguate.
+
+Acked-by: Shengjiu Wang <shengjiu.wang@gmail.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20230106-asoc-udoo-probe-v1-1-a5d7469d4f67@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl-asoc-card.c | 8 ++++----
+ sound/soc/fsl/fsl_ssi.c | 4 ++--
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
+index c72a156737e6..978496c2fc09 100644
+--- a/sound/soc/fsl/fsl-asoc-card.c
++++ b/sound/soc/fsl/fsl-asoc-card.c
+@@ -120,11 +120,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
+
+ static const struct snd_soc_dapm_route audio_map_ac97[] = {
+ /* 1st half -- Normal DAPM routes */
+- {"Playback", NULL, "AC97 Playback"},
+- {"AC97 Capture", NULL, "Capture"},
++ {"Playback", NULL, "CPU AC97 Playback"},
++ {"CPU AC97 Capture", NULL, "Capture"},
+ /* 2nd half -- ASRC DAPM routes */
+- {"AC97 Playback", NULL, "ASRC-Playback"},
+- {"ASRC-Capture", NULL, "AC97 Capture"},
++ {"CPU AC97 Playback", NULL, "ASRC-Playback"},
++ {"ASRC-Capture", NULL, "CPU AC97 Capture"},
+ };
+
+ static const struct snd_soc_dapm_route audio_map_tx[] = {
+diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
+index ecbc1c365d5b..0c73c2e9dce0 100644
+--- a/sound/soc/fsl/fsl_ssi.c
++++ b/sound/soc/fsl/fsl_ssi.c
+@@ -1160,14 +1160,14 @@ static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
+ .symmetric_channels = 1,
+ .probe = fsl_ssi_dai_probe,
+ .playback = {
+- .stream_name = "AC97 Playback",
++ .stream_name = "CPU AC97 Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_S20,
+ },
+ .capture = {
+- .stream_name = "AC97 Capture",
++ .stream_name = "CPU AC97 Capture",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_48000,
+--
+2.39.0
+
--- /dev/null
+From 888092ae3cdacba3d684d40a1917087e1ee94dfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 03:16:14 +0000
+Subject: Bluetooth: Fix possible deadlock in rfcomm_sk_state_change
+
+From: Ying Hsu <yinghsu@chromium.org>
+
+[ Upstream commit 1d80d57ffcb55488f0ec0b77928d4f82d16b6a90 ]
+
+syzbot reports a possible deadlock in rfcomm_sk_state_change [1].
+While rfcomm_sock_connect acquires the sk lock and waits for
+the rfcomm lock, rfcomm_sock_release could have the rfcomm
+lock and hit a deadlock for acquiring the sk lock.
+Here's a simplified flow:
+
+rfcomm_sock_connect:
+ lock_sock(sk)
+ rfcomm_dlc_open:
+ rfcomm_lock()
+
+rfcomm_sock_release:
+ rfcomm_sock_shutdown:
+ rfcomm_lock()
+ __rfcomm_dlc_close:
+ rfcomm_k_state_change:
+ lock_sock(sk)
+
+This patch drops the sk lock before calling rfcomm_dlc_open to
+avoid the possible deadlock and holds sk's reference count to
+prevent use-after-free after rfcomm_dlc_open completes.
+
+Reported-by: syzbot+d7ce59...@syzkaller.appspotmail.com
+Fixes: 1804fdf6e494 ("Bluetooth: btintel: Combine setting up MSFT extension")
+Link: https://syzkaller.appspot.com/bug?extid=d7ce59b06b3eb14fd218 [1]
+
+Signed-off-by: Ying Hsu <yinghsu@chromium.org>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/rfcomm/sock.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
+index 21e24da4847f..4397e14ff560 100644
+--- a/net/bluetooth/rfcomm/sock.c
++++ b/net/bluetooth/rfcomm/sock.c
+@@ -391,6 +391,7 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
+ addr->sa_family != AF_BLUETOOTH)
+ return -EINVAL;
+
++ sock_hold(sk);
+ lock_sock(sk);
+
+ if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) {
+@@ -410,14 +411,18 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
+ d->sec_level = rfcomm_pi(sk)->sec_level;
+ d->role_switch = rfcomm_pi(sk)->role_switch;
+
++ /* Drop sock lock to avoid potential deadlock with the RFCOMM lock */
++ release_sock(sk);
+ err = rfcomm_dlc_open(d, &rfcomm_pi(sk)->src, &sa->rc_bdaddr,
+ sa->rc_channel);
+- if (!err)
++ lock_sock(sk);
++ if (!err && !sock_flag(sk, SOCK_ZAPPED))
+ err = bt_sock_wait_state(sk, BT_CONNECTED,
+ sock_sndtimeo(sk, flags & O_NONBLOCK));
+
+ done:
+ release_sock(sk);
++ sock_put(sk);
+ return err;
+ }
+
+--
+2.39.0
+
--- /dev/null
+From 9515b63fddd8c96797b0513c8d6509a9cc767611 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Sep 2022 15:38:26 +0800
+Subject: bpf: Always use raw spinlock for hash bucket lock
+
+From: Hou Tao <houtao1@huawei.com>
+
+[ Upstream commit 1d8b82c613297f24354b4d750413a7456b5cd92c ]
+
+For a non-preallocated hash map on RT kernel, regular spinlock instead
+of raw spinlock is used for bucket lock. The reason is that on RT kernel
+memory allocation is forbidden under atomic context and regular spinlock
+is sleepable under RT.
+
+Now hash map has been fully converted to use bpf_map_alloc, and there
+will be no synchronous memory allocation for non-preallocated hash map,
+so it is safe to always use raw spinlock for bucket lock on RT. So
+removing the usage of htab_use_raw_lock() and updating the comments
+accordingly.
+
+Signed-off-by: Hou Tao <houtao1@huawei.com>
+Link: https://lore.kernel.org/r/20220921073826.2365800-1-houtao@huaweicloud.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Stable-dep-of: 9f907439dc80 ("bpf: hash map, avoid deadlock with suitable hash mask")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/hashtab.c | 66 ++++++++++----------------------------------
+ 1 file changed, 14 insertions(+), 52 deletions(-)
+
+diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
+index e7f45a966e6b..ea2051a913fb 100644
+--- a/kernel/bpf/hashtab.c
++++ b/kernel/bpf/hashtab.c
+@@ -66,24 +66,16 @@
+ * In theory the BPF locks could be converted to regular spinlocks as well,
+ * but the bucket locks and percpu_freelist locks can be taken from
+ * arbitrary contexts (perf, kprobes, tracepoints) which are required to be
+- * atomic contexts even on RT. These mechanisms require preallocated maps,
+- * so there is no need to invoke memory allocations within the lock held
+- * sections.
+- *
+- * BPF maps which need dynamic allocation are only used from (forced)
+- * thread context on RT and can therefore use regular spinlocks which in
+- * turn allows to invoke memory allocations from the lock held section.
+- *
+- * On a non RT kernel this distinction is neither possible nor required.
+- * spinlock maps to raw_spinlock and the extra code is optimized out by the
+- * compiler.
++ * atomic contexts even on RT. Before the introduction of bpf_mem_alloc,
++ * it is only safe to use raw spinlock for preallocated hash map on a RT kernel,
++ * because there is no memory allocation within the lock held sections. However
++ * after hash map was fully converted to use bpf_mem_alloc, there will be
++ * non-synchronous memory allocation for non-preallocated hash map, so it is
++ * safe to always use raw spinlock for bucket lock.
+ */
+ struct bucket {
+ struct hlist_nulls_head head;
+- union {
+- raw_spinlock_t raw_lock;
+- spinlock_t lock;
+- };
++ raw_spinlock_t raw_lock;
+ };
+
+ #define HASHTAB_MAP_LOCK_COUNT 8
+@@ -132,26 +124,15 @@ static inline bool htab_is_prealloc(const struct bpf_htab *htab)
+ return !(htab->map.map_flags & BPF_F_NO_PREALLOC);
+ }
+
+-static inline bool htab_use_raw_lock(const struct bpf_htab *htab)
+-{
+- return (!IS_ENABLED(CONFIG_PREEMPT_RT) || htab_is_prealloc(htab));
+-}
+-
+ static void htab_init_buckets(struct bpf_htab *htab)
+ {
+ unsigned i;
+
+ for (i = 0; i < htab->n_buckets; i++) {
+ INIT_HLIST_NULLS_HEAD(&htab->buckets[i].head, i);
+- if (htab_use_raw_lock(htab)) {
+- raw_spin_lock_init(&htab->buckets[i].raw_lock);
+- lockdep_set_class(&htab->buckets[i].raw_lock,
++ raw_spin_lock_init(&htab->buckets[i].raw_lock);
++ lockdep_set_class(&htab->buckets[i].raw_lock,
+ &htab->lockdep_key);
+- } else {
+- spin_lock_init(&htab->buckets[i].lock);
+- lockdep_set_class(&htab->buckets[i].lock,
+- &htab->lockdep_key);
+- }
+ cond_resched();
+ }
+ }
+@@ -161,28 +142,17 @@ static inline int htab_lock_bucket(const struct bpf_htab *htab,
+ unsigned long *pflags)
+ {
+ unsigned long flags;
+- bool use_raw_lock;
+
+ hash = hash & HASHTAB_MAP_LOCK_MASK;
+
+- use_raw_lock = htab_use_raw_lock(htab);
+- if (use_raw_lock)
+- preempt_disable();
+- else
+- migrate_disable();
++ preempt_disable();
+ if (unlikely(__this_cpu_inc_return(*(htab->map_locked[hash])) != 1)) {
+ __this_cpu_dec(*(htab->map_locked[hash]));
+- if (use_raw_lock)
+- preempt_enable();
+- else
+- migrate_enable();
++ preempt_enable();
+ return -EBUSY;
+ }
+
+- if (use_raw_lock)
+- raw_spin_lock_irqsave(&b->raw_lock, flags);
+- else
+- spin_lock_irqsave(&b->lock, flags);
++ raw_spin_lock_irqsave(&b->raw_lock, flags);
+ *pflags = flags;
+
+ return 0;
+@@ -192,18 +162,10 @@ static inline void htab_unlock_bucket(const struct bpf_htab *htab,
+ struct bucket *b, u32 hash,
+ unsigned long flags)
+ {
+- bool use_raw_lock = htab_use_raw_lock(htab);
+-
+ hash = hash & HASHTAB_MAP_LOCK_MASK;
+- if (use_raw_lock)
+- raw_spin_unlock_irqrestore(&b->raw_lock, flags);
+- else
+- spin_unlock_irqrestore(&b->lock, flags);
++ raw_spin_unlock_irqrestore(&b->raw_lock, flags);
+ __this_cpu_dec(*(htab->map_locked[hash]));
+- if (use_raw_lock)
+- preempt_enable();
+- else
+- migrate_enable();
++ preempt_enable();
+ }
+
+ static bool htab_lru_map_delete_node(void *arg, struct bpf_lru_node *node);
+--
+2.39.0
+
--- /dev/null
+From 8851b5f04ed06ccf50942e4071cad87f288867a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 16:05:46 +0100
+Subject: bpf: Fix pointer-leak due to insufficient speculative store bypass
+ mitigation
+
+From: Luis Gerhorst <gerhorst@cs.fau.de>
+
+[ Upstream commit e4f4db47794c9f474b184ee1418f42e6a07412b6 ]
+
+To mitigate Spectre v4, 2039f26f3aca ("bpf: Fix leakage due to
+insufficient speculative store bypass mitigation") inserts lfence
+instructions after 1) initializing a stack slot and 2) spilling a
+pointer to the stack.
+
+However, this does not cover cases where a stack slot is first
+initialized with a pointer (subject to sanitization) but then
+overwritten with a scalar (not subject to sanitization because
+the slot was already initialized). In this case, the second write
+may be subject to speculative store bypass (SSB) creating a
+speculative pointer-as-scalar type confusion. This allows the
+program to subsequently leak the numerical pointer value using,
+for example, a branch-based cache side channel.
+
+To fix this, also sanitize scalars if they write a stack slot
+that previously contained a pointer. Assuming that pointer-spills
+are only generated by LLVM on register-pressure, the performance
+impact on most real-world BPF programs should be small.
+
+The following unprivileged BPF bytecode drafts a minimal exploit
+and the mitigation:
+
+ [...]
+ // r6 = 0 or 1 (skalar, unknown user input)
+ // r7 = accessible ptr for side channel
+ // r10 = frame pointer (fp), to be leaked
+ //
+ r9 = r10 # fp alias to encourage ssb
+ *(u64 *)(r9 - 8) = r10 // fp[-8] = ptr, to be leaked
+ // lfence added here because of pointer spill to stack.
+ //
+ // Ommitted: Dummy bpf_ringbuf_output() here to train alias predictor
+ // for no r9-r10 dependency.
+ //
+ *(u64 *)(r10 - 8) = r6 // fp[-8] = scalar, overwrites ptr
+ // 2039f26f3aca: no lfence added because stack slot was not STACK_INVALID,
+ // store may be subject to SSB
+ //
+ // fix: also add an lfence when the slot contained a ptr
+ //
+ r8 = *(u64 *)(r9 - 8)
+ // r8 = architecturally a scalar, speculatively a ptr
+ //
+ // leak ptr using branch-based cache side channel:
+ r8 &= 1 // choose bit to leak
+ if r8 == 0 goto SLOW // no mispredict
+ // architecturally dead code if input r6 is 0,
+ // only executes speculatively iff ptr bit is 1
+ r8 = *(u64 *)(r7 + 0) # encode bit in cache (0: slow, 1: fast)
+SLOW:
+ [...]
+
+After running this, the program can time the access to *(r7 + 0) to
+determine whether the chosen pointer bit was 0 or 1. Repeat this 64
+times to recover the whole address on amd64.
+
+In summary, sanitization can only be skipped if one scalar is
+overwritten with another scalar. Scalar-confusion due to speculative
+store bypass can not lead to invalid accesses because the pointer
+bounds deducted during verification are enforced using branchless
+logic. See 979d63d50c0c ("bpf: prevent out of bounds speculation on
+pointer arithmetic") for details.
+
+Do not make the mitigation depend on !env->allow_{uninit_stack,ptr_leaks}
+because speculative leaks are likely unexpected if these were enabled.
+For example, leaking the address to a protected log file may be acceptable
+while disabling the mitigation might unintentionally leak the address
+into the cached-state of a map that is accessible to unprivileged
+processes.
+
+Fixes: 2039f26f3aca ("bpf: Fix leakage due to insufficient speculative store bypass mitigation")
+Signed-off-by: Luis Gerhorst <gerhorst@cs.fau.de>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Henriette Hofmeier <henriette.hofmeier@rub.de>
+Link: https://lore.kernel.org/bpf/edc95bad-aada-9cfc-ffe2-fa9bb206583c@cs.fau.de
+Link: https://lore.kernel.org/bpf/20230109150544.41465-1-gerhorst@cs.fau.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 488225bb42f6..49e51fc0c2f4 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -2653,7 +2653,9 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
+ bool sanitize = reg && is_spillable_regtype(reg->type);
+
+ for (i = 0; i < size; i++) {
+- if (state->stack[spi].slot_type[i] == STACK_INVALID) {
++ u8 type = state->stack[spi].slot_type[i];
++
++ if (type != STACK_MISC && type != STACK_ZERO) {
+ sanitize = true;
+ break;
+ }
+--
+2.39.0
+
--- /dev/null
+From db3e423d05b76c2d43e763e79e5273c2988212a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 17:29:01 +0800
+Subject: bpf: hash map, avoid deadlock with suitable hash mask
+
+From: Tonghao Zhang <tong@infragraf.org>
+
+[ Upstream commit 9f907439dc80e4a2fcfb949927b36c036468dbb3 ]
+
+The deadlock still may occur while accessed in NMI and non-NMI
+context. Because in NMI, we still may access the same bucket but with
+different map_locked index.
+
+For example, on the same CPU, .max_entries = 2, we update the hash map,
+with key = 4, while running bpf prog in NMI nmi_handle(), to update
+hash map with key = 20, so it will have the same bucket index but have
+different map_locked index.
+
+To fix this issue, using min mask to hash again.
+
+Fixes: 20b6cc34ea74 ("bpf: Avoid hashtab deadlock with map_locked")
+Signed-off-by: Tonghao Zhang <tong@infragraf.org>
+Cc: Alexei Starovoitov <ast@kernel.org>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Andrii Nakryiko <andrii@kernel.org>
+Cc: Martin KaFai Lau <martin.lau@linux.dev>
+Cc: Song Liu <song@kernel.org>
+Cc: Yonghong Song <yhs@fb.com>
+Cc: John Fastabend <john.fastabend@gmail.com>
+Cc: KP Singh <kpsingh@kernel.org>
+Cc: Stanislav Fomichev <sdf@google.com>
+Cc: Hao Luo <haoluo@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Hou Tao <houtao1@huawei.com>
+Acked-by: Yonghong Song <yhs@fb.com>
+Acked-by: Hou Tao <houtao1@huawei.com>
+Link: https://lore.kernel.org/r/20230111092903.92389-1-tong@infragraf.org
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/hashtab.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
+index ea2051a913fb..06461ce9363e 100644
+--- a/kernel/bpf/hashtab.c
++++ b/kernel/bpf/hashtab.c
+@@ -143,7 +143,7 @@ static inline int htab_lock_bucket(const struct bpf_htab *htab,
+ {
+ unsigned long flags;
+
+- hash = hash & HASHTAB_MAP_LOCK_MASK;
++ hash = hash & min_t(u32, HASHTAB_MAP_LOCK_MASK, htab->n_buckets - 1);
+
+ preempt_disable();
+ if (unlikely(__this_cpu_inc_return(*(htab->map_locked[hash])) != 1)) {
+@@ -162,7 +162,7 @@ static inline void htab_unlock_bucket(const struct bpf_htab *htab,
+ struct bucket *b, u32 hash,
+ unsigned long flags)
+ {
+- hash = hash & HASHTAB_MAP_LOCK_MASK;
++ hash = hash & min_t(u32, HASHTAB_MAP_LOCK_MASK, htab->n_buckets - 1);
+ raw_spin_unlock_irqrestore(&b->raw_lock, flags);
+ __this_cpu_dec(*(htab->map_locked[hash]));
+ preempt_enable();
+--
+2.39.0
+
--- /dev/null
+From 00214eb243c3dae7fc4a7e7e69cec451b4349963 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Jan 2023 19:00:37 -0300
+Subject: cifs: fix potential deadlock in cache_refresh_path()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Paulo Alcantara <pc@cjr.nz>
+
+[ Upstream commit 9fb0db40513e27537fde63287aea920b60557a69 ]
+
+Avoid getting DFS referral from an exclusive lock in
+cache_refresh_path() because the tcon IPC used for getting the
+referral could be disconnected and thus causing a deadlock as shown
+below:
+
+task A task B
+====== ======
+cifs_demultiplex_thread() dfs_cache_find()
+ cifs_handle_standard() cache_refresh_path()
+ reconnect_dfs_server() down_write()
+ dfs_cache_noreq_find() get_dfs_referral()
+ down_read() <- deadlock smb2_get_dfs_refer()
+ SMB2_ioctl()
+ cifs_send_recv()
+ compound_send_recv()
+ wait_for_response()
+
+where task A cannot wake up task B because it is blocked on
+down_read() due to the exclusive lock held in cache_refresh_path() and
+therefore not being able to make progress.
+
+Fixes: c9f711039905 ("cifs: keep referral server sessions alive")
+Reviewed-by: Aurélien Aptel <aurelien.aptel@gmail.com>
+Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/dfs_cache.c | 42 +++++++++++++++++++++++-------------------
+ 1 file changed, 23 insertions(+), 19 deletions(-)
+
+diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c
+index 1f3efa7821a0..8c98fa507768 100644
+--- a/fs/cifs/dfs_cache.c
++++ b/fs/cifs/dfs_cache.c
+@@ -792,26 +792,27 @@ static int get_dfs_referral(const unsigned int xid, struct cifs_ses *ses, const
+ */
+ static int cache_refresh_path(const unsigned int xid, struct cifs_ses *ses, const char *path)
+ {
+- int rc;
+- struct cache_entry *ce;
+ struct dfs_info3_param *refs = NULL;
++ struct cache_entry *ce;
+ int numrefs = 0;
+- bool newent = false;
++ int rc;
+
+ cifs_dbg(FYI, "%s: search path: %s\n", __func__, path);
+
+- down_write(&htable_rw_lock);
++ down_read(&htable_rw_lock);
+
+ ce = lookup_cache_entry(path);
+- if (!IS_ERR(ce)) {
+- if (!cache_entry_expired(ce)) {
+- dump_ce(ce);
+- up_write(&htable_rw_lock);
+- return 0;
+- }
+- } else {
+- newent = true;
++ if (!IS_ERR(ce) && !cache_entry_expired(ce)) {
++ up_read(&htable_rw_lock);
++ return 0;
+ }
++ /*
++ * Unlock shared access as we don't want to hold any locks while getting
++ * a new referral. The @ses used for performing the I/O could be
++ * reconnecting and it acquires @htable_rw_lock to look up the dfs cache
++ * in order to failover -- if necessary.
++ */
++ up_read(&htable_rw_lock);
+
+ /*
+ * Either the entry was not found, or it is expired.
+@@ -819,19 +820,22 @@ static int cache_refresh_path(const unsigned int xid, struct cifs_ses *ses, cons
+ */
+ rc = get_dfs_referral(xid, ses, path, &refs, &numrefs);
+ if (rc)
+- goto out_unlock;
++ goto out;
+
+ dump_refs(refs, numrefs);
+
+- if (!newent) {
+- rc = update_cache_entry_locked(ce, refs, numrefs);
+- goto out_unlock;
++ down_write(&htable_rw_lock);
++ /* Re-check as another task might have it added or refreshed already */
++ ce = lookup_cache_entry(path);
++ if (!IS_ERR(ce)) {
++ if (cache_entry_expired(ce))
++ rc = update_cache_entry_locked(ce, refs, numrefs);
++ } else {
++ rc = add_cache_entry_locked(refs, numrefs);
+ }
+
+- rc = add_cache_entry_locked(refs, numrefs);
+-
+-out_unlock:
+ up_write(&htable_rw_lock);
++out:
+ free_dfs_info_array(refs, numrefs);
+ return rc;
+ }
+--
+2.39.0
+
--- /dev/null
+From adac329f25006bbdee4fbf9908b6f3365cca51e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jan 2023 18:11:29 +0100
+Subject: cpufreq: Add SM6375 to cpufreq-dt-platdev blocklist
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit faf28e240dd118d9521c68aeb9388b9b8f02d9d0 ]
+
+The Qualcomm SM6375 platform uses the qcom-cpufreq-hw driver, so add
+it to the cpufreq-dt-platdev driver's blocklist.
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/cpufreq-dt-platdev.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
+index 27a3b8800a35..e1b5975c7daa 100644
+--- a/drivers/cpufreq/cpufreq-dt-platdev.c
++++ b/drivers/cpufreq/cpufreq-dt-platdev.c
+@@ -144,6 +144,7 @@ static const struct of_device_id blocklist[] __initconst = {
+ { .compatible = "qcom,sc8180x", },
+ { .compatible = "qcom,sdm845", },
+ { .compatible = "qcom,sm6350", },
++ { .compatible = "qcom,sm6375", },
+ { .compatible = "qcom,sm8150", },
+ { .compatible = "qcom,sm8250", },
+ { .compatible = "qcom,sm8350", },
+--
+2.39.0
+
--- /dev/null
+From 4b71a61a0a4b5c8dd5f9fc57f5208aae47b21704 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Dec 2022 21:32:37 +0530
+Subject: cpufreq: Add Tegra234 to cpufreq-dt-platdev blocklist
+
+From: Sumit Gupta <sumitg@nvidia.com>
+
+[ Upstream commit 01c5bb0cc2a39fbc56ff9a5ef28b79447f0c2351 ]
+
+Tegra234 platform uses the tegra194-cpufreq driver, so add it
+to the blocklist in cpufreq-dt-platdev driver to avoid the cpufreq
+driver registration from there.
+
+Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/cpufreq-dt-platdev.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
+index ca1d103ec449..27a3b8800a35 100644
+--- a/drivers/cpufreq/cpufreq-dt-platdev.c
++++ b/drivers/cpufreq/cpufreq-dt-platdev.c
+@@ -133,6 +133,7 @@ static const struct of_device_id blocklist[] __initconst = {
+ { .compatible = "nvidia,tegra30", },
+ { .compatible = "nvidia,tegra124", },
+ { .compatible = "nvidia,tegra210", },
++ { .compatible = "nvidia,tegra234", },
+
+ { .compatible = "qcom,apq8096", },
+ { .compatible = "qcom,msm8996", },
+--
+2.39.0
+
--- /dev/null
+From 385726c1178725c71158b1bc315586ac745f3d9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Jan 2023 11:12:52 +0800
+Subject: cpufreq: armada-37xx: stop using 0 as NULL pointer
+
+From: Miles Chen <miles.chen@mediatek.com>
+
+[ Upstream commit 08f0adb193c008de640fde34a2e00a666c01d77c ]
+
+Use NULL for NULL pointer to fix the following sparse warning:
+drivers/cpufreq/armada-37xx-cpufreq.c:448:32: sparse: warning: Using plain integer as NULL pointer
+
+Signed-off-by: Miles Chen <miles.chen@mediatek.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/armada-37xx-cpufreq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c
+index c10fc33b29b1..b74289a95a17 100644
+--- a/drivers/cpufreq/armada-37xx-cpufreq.c
++++ b/drivers/cpufreq/armada-37xx-cpufreq.c
+@@ -445,7 +445,7 @@ static int __init armada37xx_cpufreq_driver_init(void)
+ return -ENODEV;
+ }
+
+- clk = clk_get(cpu_dev, 0);
++ clk = clk_get(cpu_dev, NULL);
+ if (IS_ERR(clk)) {
+ dev_err(cpu_dev, "Cannot get clock for CPU0\n");
+ return PTR_ERR(clk);
+--
+2.39.0
+
--- /dev/null
+From 99112c7021adecda4f8ecf70f718c3fba294d3aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 10:25:42 +0800
+Subject: device property: fix of node refcount leak in
+ fwnode_graph_get_next_endpoint()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 39af728649b05e88a2b40e714feeee6451c3f18e ]
+
+The 'parent' returned by fwnode_graph_get_port_parent()
+with refcount incremented when 'prev' is not NULL, it
+needs be put when finish using it.
+
+Because the parent is const, introduce a new variable to
+store the returned fwnode, then put it before returning
+from fwnode_graph_get_next_endpoint().
+
+Fixes: b5b41ab6b0c1 ("device property: Check fwnode->secondary in fwnode_graph_get_next_endpoint()")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-and-tested-by: Daniel Scally <djrscally@gmail.com>
+Link: https://lore.kernel.org/r/20221123022542.2999510-1-yangyingliang@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/property.c | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/base/property.c b/drivers/base/property.c
+index 735a23db1b5e..17a648d64356 100644
+--- a/drivers/base/property.c
++++ b/drivers/base/property.c
+@@ -1055,26 +1055,32 @@ struct fwnode_handle *
+ fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
+ struct fwnode_handle *prev)
+ {
++ struct fwnode_handle *ep, *port_parent = NULL;
+ const struct fwnode_handle *parent;
+- struct fwnode_handle *ep;
+
+ /*
+ * If this function is in a loop and the previous iteration returned
+ * an endpoint from fwnode->secondary, then we need to use the secondary
+ * as parent rather than @fwnode.
+ */
+- if (prev)
+- parent = fwnode_graph_get_port_parent(prev);
+- else
++ if (prev) {
++ port_parent = fwnode_graph_get_port_parent(prev);
++ parent = port_parent;
++ } else {
+ parent = fwnode;
++ }
+ if (IS_ERR_OR_NULL(parent))
+ return NULL;
+
+ ep = fwnode_call_ptr_op(parent, graph_get_next_endpoint, prev);
+ if (ep)
+- return ep;
++ goto out_put_port_parent;
++
++ ep = fwnode_graph_get_next_endpoint(parent->secondary, NULL);
+
+- return fwnode_graph_get_next_endpoint(parent->secondary, NULL);
++out_put_port_parent:
++ fwnode_handle_put(port_parent);
++ return ep;
+ }
+ EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);
+
+--
+2.39.0
+
--- /dev/null
+From dfe426b9286965403c6e1ef23d52cd56eba4d941 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Dec 2022 11:00:50 +0800
+Subject: dmaengine: Fix double increment of client_count in dma_chan_get()
+
+From: Koba Ko <koba.ko@canonical.com>
+
+[ Upstream commit f3dc1b3b4750851a94212dba249703dd0e50bb20 ]
+
+The first time dma_chan_get() is called for a channel the channel
+client_count is incorrectly incremented twice for public channels,
+first in balance_ref_count(), and again prior to returning. This
+results in an incorrect client count which will lead to the
+channel resources not being freed when they should be. A simple
+ test of repeated module load and unload of async_tx on a Dell
+ Power Edge R7425 also shows this resulting in a kref underflow
+ warning.
+
+[ 124.329662] async_tx: api initialized (async)
+[ 129.000627] async_tx: api initialized (async)
+[ 130.047839] ------------[ cut here ]------------
+[ 130.052472] refcount_t: underflow; use-after-free.
+[ 130.057279] WARNING: CPU: 3 PID: 19364 at lib/refcount.c:28
+refcount_warn_saturate+0xba/0x110
+[ 130.065811] Modules linked in: async_tx(-) rfkill intel_rapl_msr
+intel_rapl_common amd64_edac edac_mce_amd ipmi_ssif kvm_amd dcdbas kvm
+mgag200 drm_shmem_helper acpi_ipmi irqbypass drm_kms_helper ipmi_si
+syscopyarea sysfillrect rapl pcspkr ipmi_devintf sysimgblt fb_sys_fops
+k10temp i2c_piix4 ipmi_msghandler acpi_power_meter acpi_cpufreq vfat
+fat drm fuse xfs libcrc32c sd_mod t10_pi sg ahci crct10dif_pclmul
+libahci crc32_pclmul crc32c_intel ghash_clmulni_intel igb megaraid_sas
+i40e libata i2c_algo_bit ccp sp5100_tco dca dm_mirror dm_region_hash
+dm_log dm_mod [last unloaded: async_tx]
+[ 130.117361] CPU: 3 PID: 19364 Comm: modprobe Kdump: loaded Not
+tainted 5.14.0-185.el9.x86_64 #1
+[ 130.126091] Hardware name: Dell Inc. PowerEdge R7425/02MJ3T, BIOS
+1.18.0 01/17/2022
+[ 130.133806] RIP: 0010:refcount_warn_saturate+0xba/0x110
+[ 130.139041] Code: 01 01 e8 6d bd 55 00 0f 0b e9 72 9d 8a 00 80 3d
+26 18 9c 01 00 75 85 48 c7 c7 f8 a3 03 9d c6 05 16 18 9c 01 01 e8 4a
+bd 55 00 <0f> 0b e9 4f 9d 8a 00 80 3d 01 18 9c 01 00 0f 85 5e ff ff ff
+48 c7
+[ 130.157807] RSP: 0018:ffffbf98898afe68 EFLAGS: 00010286
+[ 130.163036] RAX: 0000000000000000 RBX: ffff9da06028e598 RCX: 0000000000000000
+[ 130.170172] RDX: ffff9daf9de26480 RSI: ffff9daf9de198a0 RDI: ffff9daf9de198a0
+[ 130.177316] RBP: ffff9da7cddf3970 R08: 0000000000000000 R09: 00000000ffff7fff
+[ 130.184459] R10: ffffbf98898afd00 R11: ffffffff9d9e8c28 R12: ffff9da7cddf1970
+[ 130.191596] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
+[ 130.198739] FS: 00007f646435c740(0000) GS:ffff9daf9de00000(0000)
+knlGS:0000000000000000
+[ 130.206832] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 130.212586] CR2: 00007f6463b214f0 CR3: 00000008ab98c000 CR4: 00000000003506e0
+[ 130.219729] Call Trace:
+[ 130.222192] <TASK>
+[ 130.224305] dma_chan_put+0x10d/0x110
+[ 130.227988] dmaengine_put+0x7a/0xa0
+[ 130.231575] __do_sys_delete_module.constprop.0+0x178/0x280
+[ 130.237157] ? syscall_trace_enter.constprop.0+0x145/0x1d0
+[ 130.242652] do_syscall_64+0x5c/0x90
+[ 130.246240] ? exc_page_fault+0x62/0x150
+[ 130.250178] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+[ 130.255243] RIP: 0033:0x7f6463a3f5ab
+[ 130.258830] Code: 73 01 c3 48 8b 0d 75 a8 1b 00 f7 d8 64 89 01 48
+83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 b0 00 00
+00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 45 a8 1b 00 f7 d8 64 89
+01 48
+[ 130.277591] RSP: 002b:00007fff22f972c8 EFLAGS: 00000206 ORIG_RAX:
+00000000000000b0
+[ 130.285164] RAX: ffffffffffffffda RBX: 000055b6786edd40 RCX: 00007f6463a3f5ab
+[ 130.292303] RDX: 0000000000000000 RSI: 0000000000000800 RDI: 000055b6786edda8
+[ 130.299443] RBP: 000055b6786edd40 R08: 0000000000000000 R09: 0000000000000000
+[ 130.306584] R10: 00007f6463b9eac0 R11: 0000000000000206 R12: 000055b6786edda8
+[ 130.313731] R13: 0000000000000000 R14: 000055b6786edda8 R15: 00007fff22f995f8
+[ 130.320875] </TASK>
+[ 130.323081] ---[ end trace eff7156d56b5cf25 ]---
+
+cat /sys/class/dma/dma0chan*/in_use would get the wrong result.
+2
+2
+2
+
+Fixes: d2f4f99db3e9 ("dmaengine: Rework dma_chan_get")
+Signed-off-by: Koba Ko <koba.ko@canonical.com>
+Reviewed-by: Jie Hai <haijie1@huawei.com>
+Test-by: Jie Hai <haijie1@huawei.com>
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Tested-by: Joel Savitz <jsavitz@redhat.com>
+Link: https://lore.kernel.org/r/20221201030050.978595-1-koba.ko@canonical.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/dmaengine.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
+index af3ee288bc11..4ec7bb58c195 100644
+--- a/drivers/dma/dmaengine.c
++++ b/drivers/dma/dmaengine.c
+@@ -451,7 +451,8 @@ static int dma_chan_get(struct dma_chan *chan)
+ /* The channel is already in use, update client count */
+ if (chan->client_count) {
+ __module_get(owner);
+- goto out;
++ chan->client_count++;
++ return 0;
+ }
+
+ if (!try_module_get(owner))
+@@ -470,11 +471,11 @@ static int dma_chan_get(struct dma_chan *chan)
+ goto err_out;
+ }
+
++ chan->client_count++;
++
+ if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask))
+ balance_ref_count(chan);
+
+-out:
+- chan->client_count++;
+ return 0;
+
+ err_out:
+--
+2.39.0
+
--- /dev/null
+From 0f4576981be9e80d2e86f9571d30f990ca8d735c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 14:20:05 +0530
+Subject: dmaengine: ti: k3-udma: Do conditional decrement of
+ UDMA_CHAN_RT_PEER_BCNT_REG
+
+From: Jayesh Choudhary <j-choudhary@ti.com>
+
+[ Upstream commit efab25894a41a920d9581183741e7fadba00719c ]
+
+PSIL_EP_NATIVE endpoints may not have PEER registers for BCNT and thus
+udma_decrement_byte_counters() should not try to decrement these counters.
+This fixes the issue of crypto IPERF testing where the client side (EVM)
+hangs without transfer of packets to the server side, seen since this
+function was added.
+
+Fixes: 7c94dcfa8fcf ("dmaengine: ti: k3-udma: Reset UDMA_CHAN_RT byte counters to prevent overflow")
+Signed-off-by: Jayesh Choudhary <j-choudhary@ti.com>
+Acked-by: Peter Ujfalusi <peter.ujfalusi@gmail.com>
+Link: https://lore.kernel.org/r/20221128085005.489964-1-j-choudhary@ti.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/ti/k3-udma.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
+index 75f2a0006c73..d796e50dfe99 100644
+--- a/drivers/dma/ti/k3-udma.c
++++ b/drivers/dma/ti/k3-udma.c
+@@ -760,11 +760,12 @@ static void udma_decrement_byte_counters(struct udma_chan *uc, u32 val)
+ if (uc->desc->dir == DMA_DEV_TO_MEM) {
+ udma_rchanrt_write(uc, UDMA_CHAN_RT_BCNT_REG, val);
+ udma_rchanrt_write(uc, UDMA_CHAN_RT_SBCNT_REG, val);
+- udma_rchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val);
++ if (uc->config.ep_type != PSIL_EP_NATIVE)
++ udma_rchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val);
+ } else {
+ udma_tchanrt_write(uc, UDMA_CHAN_RT_BCNT_REG, val);
+ udma_tchanrt_write(uc, UDMA_CHAN_RT_SBCNT_REG, val);
+- if (!uc->bchan)
++ if (!uc->bchan && uc->config.ep_type != PSIL_EP_NATIVE)
+ udma_tchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val);
+ }
+ }
+--
+2.39.0
+
--- /dev/null
+From 650b9f96e69ca668bd9384ca9e59fa95160a5ed2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 10:16:12 +0800
+Subject: dmaengine: xilinx_dma: call of_node_put() when breaking out of
+ for_each_child_of_node()
+
+From: Liu Shixin <liushixin2@huawei.com>
+
+[ Upstream commit 596b53ccc36a546ab28e8897315c5b4d1d5a0200 ]
+
+Since for_each_child_of_node() will increase the refcount of node, we need
+to call of_node_put() manually when breaking out of the iteration.
+
+Fixes: 9cd4360de609 ("dma: Add Xilinx AXI Video Direct Memory Access Engine driver support")
+Signed-off-by: Liu Shixin <liushixin2@huawei.com>
+Acked-by: Peter Korsgaard <peter@korsgaard.com>
+Link: https://lore.kernel.org/r/20221122021612.1908866-1-liushixin2@huawei.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/xilinx/xilinx_dma.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
+index 4273150b68dc..edc2bb8f0523 100644
+--- a/drivers/dma/xilinx/xilinx_dma.c
++++ b/drivers/dma/xilinx/xilinx_dma.c
+@@ -3138,8 +3138,10 @@ static int xilinx_dma_probe(struct platform_device *pdev)
+ /* Initialize the channels */
+ for_each_child_of_node(node, child) {
+ err = xilinx_dma_child_probe(xdev, child);
+- if (err < 0)
++ if (err < 0) {
++ of_node_put(child);
+ goto error;
++ }
+ }
+
+ if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) {
+--
+2.39.0
+
--- /dev/null
+From 65872506e156c3ae8e887b73639ebaaffaad88d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Nov 2022 14:35:41 +0800
+Subject: driver core: Fix test_async_probe_init saves device in wrong array
+
+From: Chen Zhongjin <chenzhongjin@huawei.com>
+
+[ Upstream commit 9be182da0a7526f1b9a3777a336f83baa2e64d23 ]
+
+In test_async_probe_init, second set of asynchronous devices are saved
+in sync_dev[sync_id], which should be async_dev[async_id].
+This makes these devices not unregistered when exit.
+
+> modprobe test_async_driver_probe && \
+> modprobe -r test_async_driver_probe && \
+> modprobe test_async_driver_probe
+ ...
+> sysfs: cannot create duplicate filename '/devices/platform/test_async_driver.4'
+> kobject_add_internal failed for test_async_driver.4 with -EEXIST,
+ don't try to register things with the same name in the same directory.
+
+Fixes: 57ea974fb871 ("driver core: Rewrite test_async_driver_probe to cover serialization and NUMA affinity")
+Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
+Link: https://lore.kernel.org/r/20221125063541.241328-1-chenzhongjin@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/test/test_async_driver_probe.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/base/test/test_async_driver_probe.c b/drivers/base/test/test_async_driver_probe.c
+index 3bb7beb127a9..c157a912d673 100644
+--- a/drivers/base/test/test_async_driver_probe.c
++++ b/drivers/base/test/test_async_driver_probe.c
+@@ -146,7 +146,7 @@ static int __init test_async_probe_init(void)
+ calltime = ktime_get();
+ for_each_online_cpu(cpu) {
+ nid = cpu_to_node(cpu);
+- pdev = &sync_dev[sync_id];
++ pdev = &async_dev[async_id];
+
+ *pdev = test_platform_device_register_node("test_async_driver",
+ async_id,
+--
+2.39.0
+
--- /dev/null
+From 3dd6e53dadd1f9c5ad2e457bab6f170b387f4717 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Dec 2022 15:58:26 -0500
+Subject: drm: Add orientation quirk for Lenovo ideapad D330-10IGL
+
+From: Patrick Thompson <ptf@google.com>
+
+[ Upstream commit 0688773f0710528e1ab302c3d6317e269f2e2e6e ]
+
+Panel is 800x1280 but mounted on a detachable form factor sideways.
+
+Signed-off-by: Patrick Thompson <ptf@google.com>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://patchwork.freedesktop.org/patch/msgid/20221220205826.178008-1-ptf@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_panel_orientation_quirks.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+index ca0fefeaab20..ce739ba45c55 100644
+--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c
++++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+@@ -272,6 +272,12 @@ static const struct dmi_system_id orientation_data[] = {
+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"),
+ },
+ .driver_data = (void *)&lcd1200x1920_rightside_up,
++ }, { /* Lenovo Ideapad D330-10IGL (HD) */
++ .matches = {
++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGL"),
++ },
++ .driver_data = (void *)&lcd800x1280_rightside_up,
+ }, { /* Lenovo Yoga Book X90F / X91F / X91L */
+ .matches = {
+ /* Non exact match to match all versions */
+--
+2.39.0
+
--- /dev/null
+From 68b15d355f8b0621728415581e8d0f61d760c077 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Jan 2023 15:12:49 -0500
+Subject: drm/amd/display: fix issues with driver unload
+
+From: Hamza Mahfooz <hamza.mahfooz@amd.com>
+
+[ Upstream commit e433adc60f7f847e734c56246b09291532f29b6d ]
+
+Currently, we run into a number of WARN()s when attempting to unload the
+amdgpu driver (e.g. using "modprobe -r amdgpu"). These all stem from
+calling drm_encoder_cleanup() too early. So, to fix this we can stop
+calling drm_encoder_cleanup() from amdgpu_dm_fini() and instead have it
+be called from amdgpu_dm_encoder_destroy(). Also, we don't need to free
+in amdgpu_dm_encoder_destroy() since mst_encoders[] isn't explicitly
+allocated by the slab allocator.
+
+Fixes: f74367e492ba ("drm/amdgpu/display: create fake mst encoders ahead of time (v4)")
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ----
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 1 -
+ 2 files changed, 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 409739ee5ba0..a2d9e0af0654 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1688,10 +1688,6 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
+ }
+ #endif
+
+- for (i = 0; i < adev->dm.display_indexes_num; i++) {
+- drm_encoder_cleanup(&adev->dm.mst_encoders[i].base);
+- }
+-
+ amdgpu_dm_destroy_drm_device(&adev->dm);
+
+ #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+index 652cf108b3c2..bc02e3e0d17d 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+@@ -385,7 +385,6 @@ static const struct drm_connector_helper_funcs dm_dp_mst_connector_helper_funcs
+ static void amdgpu_dm_encoder_destroy(struct drm_encoder *encoder)
+ {
+ drm_encoder_cleanup(encoder);
+- kfree(encoder);
+ }
+
+ static const struct drm_encoder_funcs amdgpu_dm_encoder_funcs = {
+--
+2.39.0
+
--- /dev/null
+From 5b47b40faf5801184265e0469a7159035b95b5db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Jan 2023 12:54:23 +0100
+Subject: drm/i915: Allow switching away via vga-switcheroo if uninitialized
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit a273e95721e96885971a05f1b34cb6d093904d9d ]
+
+Always allow switching away via vga-switcheroo if the display is
+uninitalized. Instead prevent switching to i915 if the device has
+not been initialized.
+
+This issue was introduced by commit 5df7bd130818 ("drm/i915: skip
+display initialization when there is no display") protected, which
+protects code paths from being executed on uninitialized devices.
+In the case of vga-switcheroo, we want to allow a switch away from
+i915's device. So run vga_switcheroo_process_delayed_switch() and
+test in the switcheroo callbacks if the i915 device is available.
+
+Fixes: 5df7bd130818 ("drm/i915: skip display initialization when there is no display")
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
+Cc: Lucas De Marchi <lucas.demarchi@intel.com>
+Cc: José Roberto de Souza <jose.souza@intel.com>
+Cc: Jani Nikula <jani.nikula@intel.com>
+Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Cc: Jani Nikula <jani.nikula@linux.intel.com>
+Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
+Cc: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
+Cc: Manasi Navare <manasi.d.navare@intel.com>
+Cc: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
+Cc: Imre Deak <imre.deak@intel.com>
+Cc: "Jouni Högander" <jouni.hogander@intel.com>
+Cc: Uma Shankar <uma.shankar@intel.com>
+Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
+Cc: "Jason A. Donenfeld" <Jason@zx2c4.com>
+Cc: Matt Roper <matthew.d.roper@intel.com>
+Cc: Ramalingam C <ramalingam.c@intel.com>
+Cc: Thomas Zimmermann <tzimmermann@suse.de>
+Cc: Andi Shyti <andi.shyti@linux.intel.com>
+Cc: Andrzej Hajda <andrzej.hajda@intel.com>
+Cc: "José Roberto de Souza" <jose.souza@intel.com>
+Cc: Julia Lawall <Julia.Lawall@inria.fr>
+Cc: intel-gfx@lists.freedesktop.org
+Cc: <stable@vger.kernel.org> # v5.14+
+Link: https://patchwork.freedesktop.org/patch/msgid/20230116115425.13484-2-tzimmermann@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/i915_drv.c | 3 +--
+ drivers/gpu/drm/i915/i915_switcheroo.c | 6 +++++-
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
+index 59fb4c710c8c..20b9e58de155 100644
+--- a/drivers/gpu/drm/i915/i915_drv.c
++++ b/drivers/gpu/drm/i915/i915_drv.c
+@@ -990,8 +990,7 @@ static void i915_driver_lastclose(struct drm_device *dev)
+
+ intel_fbdev_restore_mode(dev);
+
+- if (HAS_DISPLAY(i915))
+- vga_switcheroo_process_delayed_switch();
++ vga_switcheroo_process_delayed_switch();
+ }
+
+ static void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
+diff --git a/drivers/gpu/drm/i915/i915_switcheroo.c b/drivers/gpu/drm/i915/i915_switcheroo.c
+index de0e224b56ce..f1ce9f591efa 100644
+--- a/drivers/gpu/drm/i915/i915_switcheroo.c
++++ b/drivers/gpu/drm/i915/i915_switcheroo.c
+@@ -18,6 +18,10 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev,
+ dev_err(&pdev->dev, "DRM not initialized, aborting switch.\n");
+ return;
+ }
++ if (!HAS_DISPLAY(i915)) {
++ dev_err(&pdev->dev, "Device state not initialized, aborting switch.\n");
++ return;
++ }
+
+ if (state == VGA_SWITCHEROO_ON) {
+ drm_info(&i915->drm, "switched on\n");
+@@ -43,7 +47,7 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev)
+ * locking inversion with the driver load path. And the access here is
+ * completely racy anyway. So don't bother with locking for now.
+ */
+- return i915 && atomic_read(&i915->drm.open_count) == 0;
++ return i915 && HAS_DISPLAY(i915) && atomic_read(&i915->drm.open_count) == 0;
+ }
+
+ static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
+--
+2.39.0
+
--- /dev/null
+From be43bace9dc6924d7348597a1f0399a481436fa6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Jan 2023 17:44:43 +0100
+Subject: drm/panfrost: fix GENERIC_ATOMIC64 dependency
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 6437a549ae178a3f5a5c03e983f291ebcdc2bbc7 ]
+
+On ARMv5 and earlier, a randconfig build can still run into
+
+WARNING: unmet direct dependencies detected for IOMMU_IO_PGTABLE_LPAE
+ Depends on [n]: IOMMU_SUPPORT [=y] && (ARM [=y] || ARM64 || COMPILE_TEST [=y]) && !GENERIC_ATOMIC64 [=y]
+ Selected by [y]:
+ - DRM_PANFROST [=y] && HAS_IOMEM [=y] && DRM [=y] && (ARM [=y] || ARM64 || COMPILE_TEST [=y] && !GENERIC_ATOMIC64 [=y]) && MMU [=y]
+
+Rework the dependencies to always require a working cmpxchg64.
+
+Fixes: db594ba3fcf9 ("drm/panfrost: depend on !GENERIC_ATOMIC64 when using COMPILE_TEST")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Steven Price <steven.price@arm.com>
+Signed-off-by: Steven Price <steven.price@arm.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230117164456.1591901-1-arnd@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panfrost/Kconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/panfrost/Kconfig b/drivers/gpu/drm/panfrost/Kconfig
+index 86cdc0ce79e6..77f4d32e5204 100644
+--- a/drivers/gpu/drm/panfrost/Kconfig
++++ b/drivers/gpu/drm/panfrost/Kconfig
+@@ -3,7 +3,8 @@
+ config DRM_PANFROST
+ tristate "Panfrost (DRM support for ARM Mali Midgard/Bifrost GPUs)"
+ depends on DRM
+- depends on ARM || ARM64 || (COMPILE_TEST && !GENERIC_ATOMIC64)
++ depends on ARM || ARM64 || COMPILE_TEST
++ depends on !GENERIC_ATOMIC64 # for IOMMU_IO_PGTABLE_LPAE
+ depends on MMU
+ select DRM_SCHED
+ select IOMMU_SUPPORT
+--
+2.39.0
+
--- /dev/null
+From af295057c06c0e08cc82df036497b488cbdac8bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Dec 2022 09:48:24 +0400
+Subject: EDAC/highbank: Fix memory leak in highbank_mc_probe()
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit e7a293658c20a7945014570e1921bf7d25d68a36 ]
+
+When devres_open_group() fails, it returns -ENOMEM without freeing memory
+allocated by edac_mc_alloc().
+
+Call edac_mc_free() on the error handling path to avoid a memory leak.
+
+ [ bp: Massage commit message. ]
+
+Fixes: a1b01edb2745 ("edac: add support for Calxeda highbank memory controller")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Reviewed-by: Andre Przywara <andre.przywara@arm.com>
+Link: https://lore.kernel.org/r/20221229054825.1361993-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/highbank_mc_edac.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/edac/highbank_mc_edac.c b/drivers/edac/highbank_mc_edac.c
+index 61b76ec226af..19fba258ae10 100644
+--- a/drivers/edac/highbank_mc_edac.c
++++ b/drivers/edac/highbank_mc_edac.c
+@@ -174,8 +174,10 @@ static int highbank_mc_probe(struct platform_device *pdev)
+ drvdata = mci->pvt_info;
+ platform_set_drvdata(pdev, mci);
+
+- if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL))
+- return -ENOMEM;
++ if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) {
++ res = -ENOMEM;
++ goto free;
++ }
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+@@ -243,6 +245,7 @@ static int highbank_mc_probe(struct platform_device *pdev)
+ edac_mc_del_mc(&pdev->dev);
+ err:
+ devres_release_group(&pdev->dev, NULL);
++free:
+ edac_mc_free(mci);
+ return res;
+ }
+--
+2.39.0
+
--- /dev/null
+From 79050b1c1943c776a58a3c82b9064f2b893df9a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Dec 2022 18:38:20 +0000
+Subject: firmware: arm_scmi: Harden shared memory access in fetch_response
+
+From: Cristian Marussi <cristian.marussi@arm.com>
+
+[ Upstream commit ad78b81a1077f7d956952cd8bdfe1e61504e3eb8 ]
+
+A misbheaving SCMI platform firmware could reply with out-of-spec messages,
+shorter than the mimimum size comprising a header and a status field.
+
+Harden shmem_fetch_response to properly truncate such a bad messages.
+
+Fixes: 5c8a47a5a91d ("firmware: arm_scmi: Make scmi core independent of the transport type")
+Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
+Link: https://lore.kernel.org/r/20221222183823.518856-3-cristian.marussi@arm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/shmem.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/firmware/arm_scmi/shmem.c b/drivers/firmware/arm_scmi/shmem.c
+index 0e3eaea5d852..415ef7df8fc3 100644
+--- a/drivers/firmware/arm_scmi/shmem.c
++++ b/drivers/firmware/arm_scmi/shmem.c
+@@ -58,10 +58,11 @@ u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem)
+ void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
+ struct scmi_xfer *xfer)
+ {
++ size_t len = ioread32(&shmem->length);
++
+ xfer->hdr.status = ioread32(shmem->msg_payload);
+ /* Skip the length of header and status in shmem area i.e 8 bytes */
+- xfer->rx.len = min_t(size_t, xfer->rx.len,
+- ioread32(&shmem->length) - 8);
++ xfer->rx.len = min_t(size_t, xfer->rx.len, len > 8 ? len - 8 : 0);
+
+ /* Take a copy to the rx buffer.. */
+ memcpy_fromio(xfer->rx.buf, shmem->msg_payload + 4, xfer->rx.len);
+--
+2.39.0
+
--- /dev/null
+From 884a682462787aab11d30ad6dcbb4fd8cd701d00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Dec 2022 18:38:21 +0000
+Subject: firmware: arm_scmi: Harden shared memory access in fetch_notification
+
+From: Cristian Marussi <cristian.marussi@arm.com>
+
+[ Upstream commit 9bae076cd4e3e3c3dc185cae829d80b2dddec86e ]
+
+A misbheaving SCMI platform firmware could reply with out-of-spec
+notifications, shorter than the mimimum size comprising a header.
+
+Fixes: d5141f37c42e ("firmware: arm_scmi: Add notifications support in transport layer")
+Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
+Link: https://lore.kernel.org/r/20221222183823.518856-4-cristian.marussi@arm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/shmem.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/arm_scmi/shmem.c b/drivers/firmware/arm_scmi/shmem.c
+index 415ef7df8fc3..56a1f61aa3ff 100644
+--- a/drivers/firmware/arm_scmi/shmem.c
++++ b/drivers/firmware/arm_scmi/shmem.c
+@@ -71,8 +71,10 @@ void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
+ void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem,
+ size_t max_len, struct scmi_xfer *xfer)
+ {
++ size_t len = ioread32(&shmem->length);
++
+ /* Skip only the length of header in shmem area i.e 4 bytes */
+- xfer->rx.len = min_t(size_t, max_len, ioread32(&shmem->length) - 4);
++ xfer->rx.len = min_t(size_t, max_len, len > 4 ? len - 4 : 0);
+
+ /* Take a copy to the rx buffer.. */
+ memcpy_fromio(xfer->rx.buf, shmem->msg_payload, xfer->rx.len);
+--
+2.39.0
+
--- /dev/null
+From baf181bede28637853aa05c8a82a035208a2bf18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Jan 2023 15:03:16 -0800
+Subject: firmware: coreboot: Check size of table entry and use flex-array
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 3b293487b8752cc42c1cbf8a0447bc6076c075fa ]
+
+The memcpy() of the data following a coreboot_table_entry couldn't
+be evaluated by the compiler under CONFIG_FORTIFY_SOURCE. To make it
+easier to reason about, add an explicit flexible array member to struct
+coreboot_device so the entire entry can be copied at once. Additionally,
+validate the sizes before copying. Avoids this run-time false positive
+warning:
+
+ memcpy: detected field-spanning write (size 168) of single field "&device->entry" at drivers/firmware/google/coreboot_table.c:103 (size 8)
+
+Reported-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Link: https://lore.kernel.org/all/03ae2704-8c30-f9f0-215b-7cdf4ad35a9a@molgen.mpg.de/
+Cc: Jack Rosenthal <jrosenth@chromium.org>
+Cc: Guenter Roeck <groeck@chromium.org>
+Cc: Julius Werner <jwerner@chromium.org>
+Cc: Brian Norris <briannorris@chromium.org>
+Cc: Stephen Boyd <swboyd@chromium.org>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Reviewed-by: Julius Werner <jwerner@chromium.org>
+Reviewed-by: Guenter Roeck <groeck@chromium.org>
+Link: https://lore.kernel.org/r/20230107031406.gonna.761-kees@kernel.org
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Reviewed-by: Jack Rosenthal <jrosenth@chromium.org>
+Link: https://lore.kernel.org/r/20230112230312.give.446-kees@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/google/coreboot_table.c | 9 +++++++--
+ drivers/firmware/google/coreboot_table.h | 1 +
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c
+index 9ca21feb9d45..f3694d347801 100644
+--- a/drivers/firmware/google/coreboot_table.c
++++ b/drivers/firmware/google/coreboot_table.c
+@@ -93,7 +93,12 @@ static int coreboot_table_populate(struct device *dev, void *ptr)
+ for (i = 0; i < header->table_entries; i++) {
+ entry = ptr_entry;
+
+- device = kzalloc(sizeof(struct device) + entry->size, GFP_KERNEL);
++ if (entry->size < sizeof(*entry)) {
++ dev_warn(dev, "coreboot table entry too small!\n");
++ return -EINVAL;
++ }
++
++ device = kzalloc(sizeof(device->dev) + entry->size, GFP_KERNEL);
+ if (!device)
+ return -ENOMEM;
+
+@@ -101,7 +106,7 @@ static int coreboot_table_populate(struct device *dev, void *ptr)
+ device->dev.parent = dev;
+ device->dev.bus = &coreboot_bus_type;
+ device->dev.release = coreboot_device_release;
+- memcpy(&device->entry, ptr_entry, entry->size);
++ memcpy(device->raw, ptr_entry, entry->size);
+
+ ret = device_register(&device->dev);
+ if (ret) {
+diff --git a/drivers/firmware/google/coreboot_table.h b/drivers/firmware/google/coreboot_table.h
+index beb778674acd..4a89277b99a3 100644
+--- a/drivers/firmware/google/coreboot_table.h
++++ b/drivers/firmware/google/coreboot_table.h
+@@ -66,6 +66,7 @@ struct coreboot_device {
+ struct coreboot_table_entry entry;
+ struct lb_cbmem_ref cbmem_ref;
+ struct lb_framebuffer framebuffer;
++ DECLARE_FLEX_ARRAY(u8, raw);
+ };
+ };
+
+--
+2.39.0
+
--- /dev/null
+From 470389839b76631f5cb7f59f5f78ce1a10f5a1af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Jan 2023 10:49:57 +0100
+Subject: gpio: mxc: Always set GPIOs used as interrupt source to INPUT mode
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 8e88a0feebb241cab0253698b2f7358b6ebec802 ]
+
+Always configure GPIO pins which are used as interrupt source as INPUTs.
+In case the default pin configuration is OUTPUT, or the prior stage does
+configure the pins as OUTPUT, then Linux will not reconfigure the pin as
+INPUT and no interrupts are received.
+
+Always configure the interrupt source GPIO pin as input to fix the above case.
+
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Fixes: 07bd1a6cc7cbb ("MXC arch: Add gpio support for the whole platform")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-mxc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
+index 6cc98a5684ae..dd91908c72f1 100644
+--- a/drivers/gpio/gpio-mxc.c
++++ b/drivers/gpio/gpio-mxc.c
+@@ -210,7 +210,7 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
+
+ raw_spin_unlock_irqrestore(&port->gc.bgpio_lock, flags);
+
+- return 0;
++ return port->gc.direction_input(&port->gc, gpio_idx);
+ }
+
+ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
+--
+2.39.0
+
--- /dev/null
+From 4739869649df55cda03489ec5a427f3c6483b85c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Jan 2023 10:49:56 +0100
+Subject: gpio: mxc: Protect GPIO irqchip RMW with bgpio spinlock
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit e5464277625c1aca5c002e0f470377cdd6816dcf ]
+
+The driver currently performs register read-modify-write without locking
+in its irqchip part, this could lead to a race condition when configuring
+interrupt mode setting. Add the missing bgpio spinlock lock/unlock around
+the register read-modify-write.
+
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Reviewed-by: Marc Zyngier <maz@kernel.org>
+Fixes: 07bd1a6cc7cbb ("MXC arch: Add gpio support for the whole platform")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-mxc.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
+index c871602fc5ba..6cc98a5684ae 100644
+--- a/drivers/gpio/gpio-mxc.c
++++ b/drivers/gpio/gpio-mxc.c
+@@ -18,6 +18,7 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/slab.h>
++#include <linux/spinlock.h>
+ #include <linux/syscore_ops.h>
+ #include <linux/gpio/driver.h>
+ #include <linux/of.h>
+@@ -147,6 +148,7 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
+ {
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct mxc_gpio_port *port = gc->private;
++ unsigned long flags;
+ u32 bit, val;
+ u32 gpio_idx = d->hwirq;
+ int edge;
+@@ -185,6 +187,8 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
+ return -EINVAL;
+ }
+
++ raw_spin_lock_irqsave(&port->gc.bgpio_lock, flags);
++
+ if (GPIO_EDGE_SEL >= 0) {
+ val = readl(port->base + GPIO_EDGE_SEL);
+ if (edge == GPIO_INT_BOTH_EDGES)
+@@ -204,15 +208,20 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
+
+ writel(1 << gpio_idx, port->base + GPIO_ISR);
+
++ raw_spin_unlock_irqrestore(&port->gc.bgpio_lock, flags);
++
+ return 0;
+ }
+
+ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
+ {
+ void __iomem *reg = port->base;
++ unsigned long flags;
+ u32 bit, val;
+ int edge;
+
++ raw_spin_lock_irqsave(&port->gc.bgpio_lock, flags);
++
+ reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
+ bit = gpio & 0xf;
+ val = readl(reg);
+@@ -230,6 +239,8 @@ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
+ return;
+ }
+ writel(val | (edge << (bit << 1)), reg);
++
++ raw_spin_unlock_irqrestore(&port->gc.bgpio_lock, flags);
+ }
+
+ /* handle 32 interrupts in one status register */
+--
+2.39.0
+
--- /dev/null
+From 35a81432d93eea1ed177f4943abd9c2641ca7b8a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Apr 2022 09:28:10 +0800
+Subject: gpio: use raw spinlock for gpio chip shadowed data
+
+From: Schspa Shi <schspa@gmail.com>
+
+[ Upstream commit 3c938cc5cebcbd2291fe97f523c0705a2c24c77d ]
+
+In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency
+as the lockdep report shows.
+
+__irq_set_handler
+ irq_get_desc_buslock
+ __irq_get_desc_lock
+ raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here
+ __irq_do_set_handler
+ mask_ack_irq
+ dwapb_irq_ack
+ spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock
+ irq_put_desc_busunlock
+
+Replace with a raw lock to avoid BUGs. This lock is only used to access
+registers, and It's safe to replace with the raw lock without bad
+influence.
+
+[ 15.090359][ T1] =============================
+[ 15.090365][ T1] [ BUG: Invalid wait context ]
+[ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted
+[ 15.090386][ T1] -----------------------------
+[ 15.090392][ T1] swapper/0/1 is trying to lock:
+[ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28
+[ 15.090470][ T1] other info that might help us debug this:
+[ 15.090477][ T1] context-{5:5}
+[ 15.090485][ T1] 3 locks held by swapper/0/1:
+[ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104
+[ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4
+[ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28
+[ 15.090654][ T1] stack backtrace:
+[ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3
+[ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT)
+[ 15.090692][ T1] Call trace:
+......
+[ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28
+[ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300
+[ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c
+[ 15.090864][ T1] __irq_set_handler+0x74/0x114
+[ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58
+[ 15.090900][ T1] gpiochip_irq_map+0x210/0x644
+
+Signed-off-by: Schspa Shi <schspa@gmail.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Acked-by: Linus Walleij <linus.walleij@linaro.org>
+Acked-by: Doug Berger <opendmb@gmail.com>
+Acked-by: Serge Semin <fancer.lancer@gmail.com>
+Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Stable-dep-of: e5464277625c ("gpio: mxc: Protect GPIO irqchip RMW with bgpio spinlock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-amdpt.c | 10 +++----
+ drivers/gpio/gpio-brcmstb.c | 12 ++++----
+ drivers/gpio/gpio-cadence.c | 12 ++++----
+ drivers/gpio/gpio-dwapb.c | 36 +++++++++++------------
+ drivers/gpio/gpio-grgpio.c | 30 +++++++++----------
+ drivers/gpio/gpio-hlwd.c | 18 ++++++------
+ drivers/gpio/gpio-idt3243x.c | 12 ++++----
+ drivers/gpio/gpio-ixp4xx.c | 4 +--
+ drivers/gpio/gpio-loongson1.c | 8 ++---
+ drivers/gpio/gpio-menz127.c | 8 ++---
+ drivers/gpio/gpio-mlxbf2.c | 6 ++--
+ drivers/gpio/gpio-mmio.c | 22 +++++++-------
+ drivers/gpio/gpio-sifive.c | 12 ++++----
+ drivers/gpio/gpio-tb10x.c | 4 +--
+ drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 8 ++---
+ include/linux/gpio/driver.h | 2 +-
+ 16 files changed, 102 insertions(+), 102 deletions(-)
+
+diff --git a/drivers/gpio/gpio-amdpt.c b/drivers/gpio/gpio-amdpt.c
+index 44398992ae15..dba4836a18f8 100644
+--- a/drivers/gpio/gpio-amdpt.c
++++ b/drivers/gpio/gpio-amdpt.c
+@@ -35,19 +35,19 @@ static int pt_gpio_request(struct gpio_chip *gc, unsigned offset)
+
+ dev_dbg(gc->parent, "pt_gpio_request offset=%x\n", offset);
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+
+ using_pins = readl(pt_gpio->reg_base + PT_SYNC_REG);
+ if (using_pins & BIT(offset)) {
+ dev_warn(gc->parent, "PT GPIO pin %x reconfigured\n",
+ offset);
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ return -EINVAL;
+ }
+
+ writel(using_pins | BIT(offset), pt_gpio->reg_base + PT_SYNC_REG);
+
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+
+ return 0;
+ }
+@@ -58,13 +58,13 @@ static void pt_gpio_free(struct gpio_chip *gc, unsigned offset)
+ unsigned long flags;
+ u32 using_pins;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+
+ using_pins = readl(pt_gpio->reg_base + PT_SYNC_REG);
+ using_pins &= ~BIT(offset);
+ writel(using_pins, pt_gpio->reg_base + PT_SYNC_REG);
+
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+
+ dev_dbg(gc->parent, "pt_gpio_free offset=%x\n", offset);
+ }
+diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c
+index 895a79936248..c5d85e931f2a 100644
+--- a/drivers/gpio/gpio-brcmstb.c
++++ b/drivers/gpio/gpio-brcmstb.c
+@@ -92,9 +92,9 @@ brcmstb_gpio_get_active_irqs(struct brcmstb_gpio_bank *bank)
+ unsigned long status;
+ unsigned long flags;
+
+- spin_lock_irqsave(&bank->gc.bgpio_lock, flags);
++ raw_spin_lock_irqsave(&bank->gc.bgpio_lock, flags);
+ status = __brcmstb_gpio_get_active_irqs(bank);
+- spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags);
+
+ return status;
+ }
+@@ -114,14 +114,14 @@ static void brcmstb_gpio_set_imask(struct brcmstb_gpio_bank *bank,
+ u32 imask;
+ unsigned long flags;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+ imask = gc->read_reg(priv->reg_base + GIO_MASK(bank->id));
+ if (enable)
+ imask |= mask;
+ else
+ imask &= ~mask;
+ gc->write_reg(priv->reg_base + GIO_MASK(bank->id), imask);
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ }
+
+ static int brcmstb_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+@@ -204,7 +204,7 @@ static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+ return -EINVAL;
+ }
+
+- spin_lock_irqsave(&bank->gc.bgpio_lock, flags);
++ raw_spin_lock_irqsave(&bank->gc.bgpio_lock, flags);
+
+ iedge_config = bank->gc.read_reg(priv->reg_base +
+ GIO_EC(bank->id)) & ~mask;
+@@ -220,7 +220,7 @@ static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+ bank->gc.write_reg(priv->reg_base + GIO_LEVEL(bank->id),
+ ilevel | level);
+
+- spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags);
+ return 0;
+ }
+
+diff --git a/drivers/gpio/gpio-cadence.c b/drivers/gpio/gpio-cadence.c
+index 562f8f7e7d1f..137aea49ba02 100644
+--- a/drivers/gpio/gpio-cadence.c
++++ b/drivers/gpio/gpio-cadence.c
+@@ -41,12 +41,12 @@ static int cdns_gpio_request(struct gpio_chip *chip, unsigned int offset)
+ struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
+ unsigned long flags;
+
+- spin_lock_irqsave(&chip->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&chip->bgpio_lock, flags);
+
+ iowrite32(ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE) & ~BIT(offset),
+ cgpio->regs + CDNS_GPIO_BYPASS_MODE);
+
+- spin_unlock_irqrestore(&chip->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags);
+ return 0;
+ }
+
+@@ -55,13 +55,13 @@ static void cdns_gpio_free(struct gpio_chip *chip, unsigned int offset)
+ struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
+ unsigned long flags;
+
+- spin_lock_irqsave(&chip->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&chip->bgpio_lock, flags);
+
+ iowrite32(ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE) |
+ (BIT(offset) & cgpio->bypass_orig),
+ cgpio->regs + CDNS_GPIO_BYPASS_MODE);
+
+- spin_unlock_irqrestore(&chip->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags);
+ }
+
+ static void cdns_gpio_irq_mask(struct irq_data *d)
+@@ -90,7 +90,7 @@ static int cdns_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+ u32 mask = BIT(d->hwirq);
+ int ret = 0;
+
+- spin_lock_irqsave(&chip->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&chip->bgpio_lock, flags);
+
+ int_value = ioread32(cgpio->regs + CDNS_GPIO_IRQ_VALUE) & ~mask;
+ int_type = ioread32(cgpio->regs + CDNS_GPIO_IRQ_TYPE) & ~mask;
+@@ -115,7 +115,7 @@ static int cdns_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+ iowrite32(int_type, cgpio->regs + CDNS_GPIO_IRQ_TYPE);
+
+ err_irq_type:
+- spin_unlock_irqrestore(&chip->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags);
+ return ret;
+ }
+
+diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
+index e981e7a46fc1..a503f37001eb 100644
+--- a/drivers/gpio/gpio-dwapb.c
++++ b/drivers/gpio/gpio-dwapb.c
+@@ -242,9 +242,9 @@ static void dwapb_irq_ack(struct irq_data *d)
+ u32 val = BIT(irqd_to_hwirq(d));
+ unsigned long flags;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+ dwapb_write(gpio, GPIO_PORTA_EOI, val);
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ }
+
+ static void dwapb_irq_mask(struct irq_data *d)
+@@ -254,10 +254,10 @@ static void dwapb_irq_mask(struct irq_data *d)
+ unsigned long flags;
+ u32 val;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+ val = dwapb_read(gpio, GPIO_INTMASK) | BIT(irqd_to_hwirq(d));
+ dwapb_write(gpio, GPIO_INTMASK, val);
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ }
+
+ static void dwapb_irq_unmask(struct irq_data *d)
+@@ -267,10 +267,10 @@ static void dwapb_irq_unmask(struct irq_data *d)
+ unsigned long flags;
+ u32 val;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+ val = dwapb_read(gpio, GPIO_INTMASK) & ~BIT(irqd_to_hwirq(d));
+ dwapb_write(gpio, GPIO_INTMASK, val);
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ }
+
+ static void dwapb_irq_enable(struct irq_data *d)
+@@ -280,11 +280,11 @@ static void dwapb_irq_enable(struct irq_data *d)
+ unsigned long flags;
+ u32 val;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+ val = dwapb_read(gpio, GPIO_INTEN);
+ val |= BIT(irqd_to_hwirq(d));
+ dwapb_write(gpio, GPIO_INTEN, val);
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ }
+
+ static void dwapb_irq_disable(struct irq_data *d)
+@@ -294,11 +294,11 @@ static void dwapb_irq_disable(struct irq_data *d)
+ unsigned long flags;
+ u32 val;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+ val = dwapb_read(gpio, GPIO_INTEN);
+ val &= ~BIT(irqd_to_hwirq(d));
+ dwapb_write(gpio, GPIO_INTEN, val);
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ }
+
+ static int dwapb_irq_set_type(struct irq_data *d, u32 type)
+@@ -308,7 +308,7 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)
+ irq_hw_number_t bit = irqd_to_hwirq(d);
+ unsigned long level, polarity, flags;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+ level = dwapb_read(gpio, GPIO_INTTYPE_LEVEL);
+ polarity = dwapb_read(gpio, GPIO_INT_POLARITY);
+
+@@ -343,7 +343,7 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)
+ dwapb_write(gpio, GPIO_INTTYPE_LEVEL, level);
+ if (type != IRQ_TYPE_EDGE_BOTH)
+ dwapb_write(gpio, GPIO_INT_POLARITY, polarity);
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+
+ return 0;
+ }
+@@ -373,7 +373,7 @@ static int dwapb_gpio_set_debounce(struct gpio_chip *gc,
+ unsigned long flags, val_deb;
+ unsigned long mask = BIT(offset);
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+
+ val_deb = dwapb_read(gpio, GPIO_PORTA_DEBOUNCE);
+ if (debounce)
+@@ -382,7 +382,7 @@ static int dwapb_gpio_set_debounce(struct gpio_chip *gc,
+ val_deb &= ~mask;
+ dwapb_write(gpio, GPIO_PORTA_DEBOUNCE, val_deb);
+
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+
+ return 0;
+ }
+@@ -738,7 +738,7 @@ static int dwapb_gpio_suspend(struct device *dev)
+ unsigned long flags;
+ int i;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+ for (i = 0; i < gpio->nr_ports; i++) {
+ unsigned int offset;
+ unsigned int idx = gpio->ports[i].idx;
+@@ -765,7 +765,7 @@ static int dwapb_gpio_suspend(struct device *dev)
+ dwapb_write(gpio, GPIO_INTMASK, ~ctx->wake_en);
+ }
+ }
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+
+ clk_bulk_disable_unprepare(DWAPB_NR_CLOCKS, gpio->clks);
+
+@@ -785,7 +785,7 @@ static int dwapb_gpio_resume(struct device *dev)
+ return err;
+ }
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+ for (i = 0; i < gpio->nr_ports; i++) {
+ unsigned int offset;
+ unsigned int idx = gpio->ports[i].idx;
+@@ -812,7 +812,7 @@ static int dwapb_gpio_resume(struct device *dev)
+ dwapb_write(gpio, GPIO_PORTA_EOI, 0xffffffff);
+ }
+ }
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+
+ return 0;
+ }
+diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c
+index f954359c9544..21204a5dca3d 100644
+--- a/drivers/gpio/gpio-grgpio.c
++++ b/drivers/gpio/gpio-grgpio.c
+@@ -145,7 +145,7 @@ static int grgpio_irq_set_type(struct irq_data *d, unsigned int type)
+ return -EINVAL;
+ }
+
+- spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
++ raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
+
+ ipol = priv->gc.read_reg(priv->regs + GRGPIO_IPOL) & ~mask;
+ iedge = priv->gc.read_reg(priv->regs + GRGPIO_IEDGE) & ~mask;
+@@ -153,7 +153,7 @@ static int grgpio_irq_set_type(struct irq_data *d, unsigned int type)
+ priv->gc.write_reg(priv->regs + GRGPIO_IPOL, ipol | pol);
+ priv->gc.write_reg(priv->regs + GRGPIO_IEDGE, iedge | edge);
+
+- spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
+
+ return 0;
+ }
+@@ -164,11 +164,11 @@ static void grgpio_irq_mask(struct irq_data *d)
+ int offset = d->hwirq;
+ unsigned long flags;
+
+- spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
++ raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
+
+ grgpio_set_imask(priv, offset, 0);
+
+- spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
+ }
+
+ static void grgpio_irq_unmask(struct irq_data *d)
+@@ -177,11 +177,11 @@ static void grgpio_irq_unmask(struct irq_data *d)
+ int offset = d->hwirq;
+ unsigned long flags;
+
+- spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
++ raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
+
+ grgpio_set_imask(priv, offset, 1);
+
+- spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
+ }
+
+ static struct irq_chip grgpio_irq_chip = {
+@@ -199,7 +199,7 @@ static irqreturn_t grgpio_irq_handler(int irq, void *dev)
+ int i;
+ int match = 0;
+
+- spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
++ raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
+
+ /*
+ * For each gpio line, call its interrupt handler if it its underlying
+@@ -215,7 +215,7 @@ static irqreturn_t grgpio_irq_handler(int irq, void *dev)
+ }
+ }
+
+- spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
+
+ if (!match)
+ dev_warn(priv->dev, "No gpio line matched irq %d\n", irq);
+@@ -247,13 +247,13 @@ static int grgpio_irq_map(struct irq_domain *d, unsigned int irq,
+ dev_dbg(priv->dev, "Mapping irq %d for gpio line %d\n",
+ irq, offset);
+
+- spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
++ raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
+
+ /* Request underlying irq if not already requested */
+ lirq->irq = irq;
+ uirq = &priv->uirqs[lirq->index];
+ if (uirq->refcnt == 0) {
+- spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
+ ret = request_irq(uirq->uirq, grgpio_irq_handler, 0,
+ dev_name(priv->dev), priv);
+ if (ret) {
+@@ -262,11 +262,11 @@ static int grgpio_irq_map(struct irq_domain *d, unsigned int irq,
+ uirq->uirq);
+ return ret;
+ }
+- spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
++ raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
+ }
+ uirq->refcnt++;
+
+- spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
+
+ /* Setup irq */
+ irq_set_chip_data(irq, priv);
+@@ -290,7 +290,7 @@ static void grgpio_irq_unmap(struct irq_domain *d, unsigned int irq)
+ irq_set_chip_and_handler(irq, NULL, NULL);
+ irq_set_chip_data(irq, NULL);
+
+- spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
++ raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
+
+ /* Free underlying irq if last user unmapped */
+ index = -1;
+@@ -309,13 +309,13 @@ static void grgpio_irq_unmap(struct irq_domain *d, unsigned int irq)
+ uirq = &priv->uirqs[lirq->index];
+ uirq->refcnt--;
+ if (uirq->refcnt == 0) {
+- spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
+ free_irq(uirq->uirq, priv);
+ return;
+ }
+ }
+
+- spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
+ }
+
+ static const struct irq_domain_ops grgpio_irq_domain_ops = {
+diff --git a/drivers/gpio/gpio-hlwd.c b/drivers/gpio/gpio-hlwd.c
+index 641719a96a1a..4e13e937f832 100644
+--- a/drivers/gpio/gpio-hlwd.c
++++ b/drivers/gpio/gpio-hlwd.c
+@@ -65,7 +65,7 @@ static void hlwd_gpio_irqhandler(struct irq_desc *desc)
+ int hwirq;
+ u32 emulated_pending;
+
+- spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
++ raw_spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
+ pending = ioread32be(hlwd->regs + HW_GPIOB_INTFLAG);
+ pending &= ioread32be(hlwd->regs + HW_GPIOB_INTMASK);
+
+@@ -93,7 +93,7 @@ static void hlwd_gpio_irqhandler(struct irq_desc *desc)
+ /* Mark emulated interrupts as pending */
+ pending |= rising | falling;
+ }
+- spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
+
+ chained_irq_enter(chip, desc);
+
+@@ -118,11 +118,11 @@ static void hlwd_gpio_irq_mask(struct irq_data *data)
+ unsigned long flags;
+ u32 mask;
+
+- spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
++ raw_spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
+ mask = ioread32be(hlwd->regs + HW_GPIOB_INTMASK);
+ mask &= ~BIT(data->hwirq);
+ iowrite32be(mask, hlwd->regs + HW_GPIOB_INTMASK);
+- spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
+ }
+
+ static void hlwd_gpio_irq_unmask(struct irq_data *data)
+@@ -132,11 +132,11 @@ static void hlwd_gpio_irq_unmask(struct irq_data *data)
+ unsigned long flags;
+ u32 mask;
+
+- spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
++ raw_spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
+ mask = ioread32be(hlwd->regs + HW_GPIOB_INTMASK);
+ mask |= BIT(data->hwirq);
+ iowrite32be(mask, hlwd->regs + HW_GPIOB_INTMASK);
+- spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
+ }
+
+ static void hlwd_gpio_irq_enable(struct irq_data *data)
+@@ -173,7 +173,7 @@ static int hlwd_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
+ unsigned long flags;
+ u32 level;
+
+- spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
++ raw_spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
+
+ hlwd->edge_emulation &= ~BIT(data->hwirq);
+
+@@ -194,11 +194,11 @@ static int hlwd_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
+ hlwd_gpio_irq_setup_emulation(hlwd, data->hwirq, flow_type);
+ break;
+ default:
+- spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
+ return -EINVAL;
+ }
+
+- spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
+ return 0;
+ }
+
+diff --git a/drivers/gpio/gpio-idt3243x.c b/drivers/gpio/gpio-idt3243x.c
+index 52b8b72ded77..1cafdf46f875 100644
+--- a/drivers/gpio/gpio-idt3243x.c
++++ b/drivers/gpio/gpio-idt3243x.c
+@@ -57,7 +57,7 @@ static int idt_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)
+ if (sense == IRQ_TYPE_NONE || (sense & IRQ_TYPE_EDGE_BOTH))
+ return -EINVAL;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+
+ ilevel = readl(ctrl->gpio + IDT_GPIO_ILEVEL);
+ if (sense & IRQ_TYPE_LEVEL_HIGH)
+@@ -68,7 +68,7 @@ static int idt_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)
+ writel(ilevel, ctrl->gpio + IDT_GPIO_ILEVEL);
+ irq_set_handler_locked(d, handle_level_irq);
+
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ return 0;
+ }
+
+@@ -86,12 +86,12 @@ static void idt_gpio_mask(struct irq_data *d)
+ struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
+ unsigned long flags;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+
+ ctrl->mask_cache |= BIT(d->hwirq);
+ writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK);
+
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ }
+
+ static void idt_gpio_unmask(struct irq_data *d)
+@@ -100,12 +100,12 @@ static void idt_gpio_unmask(struct irq_data *d)
+ struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
+ unsigned long flags;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+
+ ctrl->mask_cache &= ~BIT(d->hwirq);
+ writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK);
+
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ }
+
+ static int idt_gpio_irq_init_hw(struct gpio_chip *gc)
+diff --git a/drivers/gpio/gpio-ixp4xx.c b/drivers/gpio/gpio-ixp4xx.c
+index b3b050604e0b..6b184502fa3f 100644
+--- a/drivers/gpio/gpio-ixp4xx.c
++++ b/drivers/gpio/gpio-ixp4xx.c
+@@ -128,7 +128,7 @@ static int ixp4xx_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+ int_reg = IXP4XX_REG_GPIT1;
+ }
+
+- spin_lock_irqsave(&g->gc.bgpio_lock, flags);
++ raw_spin_lock_irqsave(&g->gc.bgpio_lock, flags);
+
+ /* Clear the style for the appropriate pin */
+ val = __raw_readl(g->base + int_reg);
+@@ -147,7 +147,7 @@ static int ixp4xx_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+ val |= BIT(d->hwirq);
+ __raw_writel(val, g->base + IXP4XX_REG_GPOE);
+
+- spin_unlock_irqrestore(&g->gc.bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&g->gc.bgpio_lock, flags);
+
+ /* This parent only accept level high (asserted) */
+ return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH);
+diff --git a/drivers/gpio/gpio-loongson1.c b/drivers/gpio/gpio-loongson1.c
+index 1b1ee94eeab4..5d90b3bc5a25 100644
+--- a/drivers/gpio/gpio-loongson1.c
++++ b/drivers/gpio/gpio-loongson1.c
+@@ -25,10 +25,10 @@ static int ls1x_gpio_request(struct gpio_chip *gc, unsigned int offset)
+ {
+ unsigned long flags;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+ __raw_writel(__raw_readl(gpio_reg_base + GPIO_CFG) | BIT(offset),
+ gpio_reg_base + GPIO_CFG);
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+
+ return 0;
+ }
+@@ -37,10 +37,10 @@ static void ls1x_gpio_free(struct gpio_chip *gc, unsigned int offset)
+ {
+ unsigned long flags;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+ __raw_writel(__raw_readl(gpio_reg_base + GPIO_CFG) & ~BIT(offset),
+ gpio_reg_base + GPIO_CFG);
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ }
+
+ static int ls1x_gpio_probe(struct platform_device *pdev)
+diff --git a/drivers/gpio/gpio-menz127.c b/drivers/gpio/gpio-menz127.c
+index 1e21c661d79d..a035a9bcb57c 100644
+--- a/drivers/gpio/gpio-menz127.c
++++ b/drivers/gpio/gpio-menz127.c
+@@ -64,7 +64,7 @@ static int men_z127_debounce(struct gpio_chip *gc, unsigned gpio,
+ debounce /= 50;
+ }
+
+- spin_lock(&gc->bgpio_lock);
++ raw_spin_lock(&gc->bgpio_lock);
+
+ db_en = readl(priv->reg_base + MEN_Z127_DBER);
+
+@@ -79,7 +79,7 @@ static int men_z127_debounce(struct gpio_chip *gc, unsigned gpio,
+ writel(db_en, priv->reg_base + MEN_Z127_DBER);
+ writel(db_cnt, priv->reg_base + GPIO_TO_DBCNT_REG(gpio));
+
+- spin_unlock(&gc->bgpio_lock);
++ raw_spin_unlock(&gc->bgpio_lock);
+
+ return 0;
+ }
+@@ -91,7 +91,7 @@ static int men_z127_set_single_ended(struct gpio_chip *gc,
+ struct men_z127_gpio *priv = gpiochip_get_data(gc);
+ u32 od_en;
+
+- spin_lock(&gc->bgpio_lock);
++ raw_spin_lock(&gc->bgpio_lock);
+ od_en = readl(priv->reg_base + MEN_Z127_ODER);
+
+ if (param == PIN_CONFIG_DRIVE_OPEN_DRAIN)
+@@ -101,7 +101,7 @@ static int men_z127_set_single_ended(struct gpio_chip *gc,
+ od_en &= ~BIT(offset);
+
+ writel(od_en, priv->reg_base + MEN_Z127_ODER);
+- spin_unlock(&gc->bgpio_lock);
++ raw_spin_unlock(&gc->bgpio_lock);
+
+ return 0;
+ }
+diff --git a/drivers/gpio/gpio-mlxbf2.c b/drivers/gpio/gpio-mlxbf2.c
+index 40a052bc6784..5a09070e5f78 100644
+--- a/drivers/gpio/gpio-mlxbf2.c
++++ b/drivers/gpio/gpio-mlxbf2.c
+@@ -120,7 +120,7 @@ static int mlxbf2_gpio_lock_acquire(struct mlxbf2_gpio_context *gs)
+ u32 arm_gpio_lock_val;
+
+ mutex_lock(yu_arm_gpio_lock_param.lock);
+- spin_lock(&gs->gc.bgpio_lock);
++ raw_spin_lock(&gs->gc.bgpio_lock);
+
+ arm_gpio_lock_val = readl(yu_arm_gpio_lock_param.io);
+
+@@ -128,7 +128,7 @@ static int mlxbf2_gpio_lock_acquire(struct mlxbf2_gpio_context *gs)
+ * When lock active bit[31] is set, ModeX is write enabled
+ */
+ if (YU_LOCK_ACTIVE_BIT(arm_gpio_lock_val)) {
+- spin_unlock(&gs->gc.bgpio_lock);
++ raw_spin_unlock(&gs->gc.bgpio_lock);
+ mutex_unlock(yu_arm_gpio_lock_param.lock);
+ return -EINVAL;
+ }
+@@ -146,7 +146,7 @@ static void mlxbf2_gpio_lock_release(struct mlxbf2_gpio_context *gs)
+ __releases(yu_arm_gpio_lock_param.lock)
+ {
+ writel(YU_ARM_GPIO_LOCK_RELEASE, yu_arm_gpio_lock_param.io);
+- spin_unlock(&gs->gc.bgpio_lock);
++ raw_spin_unlock(&gs->gc.bgpio_lock);
+ mutex_unlock(yu_arm_gpio_lock_param.lock);
+ }
+
+diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c
+index c335a0309ba3..d9dff3dc92ae 100644
+--- a/drivers/gpio/gpio-mmio.c
++++ b/drivers/gpio/gpio-mmio.c
+@@ -220,7 +220,7 @@ static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
+ unsigned long mask = bgpio_line2mask(gc, gpio);
+ unsigned long flags;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+
+ if (val)
+ gc->bgpio_data |= mask;
+@@ -229,7 +229,7 @@ static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
+
+ gc->write_reg(gc->reg_dat, gc->bgpio_data);
+
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ }
+
+ static void bgpio_set_with_clear(struct gpio_chip *gc, unsigned int gpio,
+@@ -248,7 +248,7 @@ static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val)
+ unsigned long mask = bgpio_line2mask(gc, gpio);
+ unsigned long flags;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+
+ if (val)
+ gc->bgpio_data |= mask;
+@@ -257,7 +257,7 @@ static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val)
+
+ gc->write_reg(gc->reg_set, gc->bgpio_data);
+
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ }
+
+ static void bgpio_multiple_get_masks(struct gpio_chip *gc,
+@@ -286,7 +286,7 @@ static void bgpio_set_multiple_single_reg(struct gpio_chip *gc,
+ unsigned long flags;
+ unsigned long set_mask, clear_mask;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+
+ bgpio_multiple_get_masks(gc, mask, bits, &set_mask, &clear_mask);
+
+@@ -295,7 +295,7 @@ static void bgpio_set_multiple_single_reg(struct gpio_chip *gc,
+
+ gc->write_reg(reg, gc->bgpio_data);
+
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ }
+
+ static void bgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
+@@ -347,7 +347,7 @@ static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
+ {
+ unsigned long flags;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+
+ gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio);
+
+@@ -356,7 +356,7 @@ static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
+ if (gc->reg_dir_out)
+ gc->write_reg(gc->reg_dir_out, gc->bgpio_dir);
+
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+
+ return 0;
+ }
+@@ -387,7 +387,7 @@ static void bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
+ {
+ unsigned long flags;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+
+ gc->bgpio_dir |= bgpio_line2mask(gc, gpio);
+
+@@ -396,7 +396,7 @@ static void bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
+ if (gc->reg_dir_out)
+ gc->write_reg(gc->reg_dir_out, gc->bgpio_dir);
+
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ }
+
+ static int bgpio_dir_out_dir_first(struct gpio_chip *gc, unsigned int gpio,
+@@ -610,7 +610,7 @@ int bgpio_init(struct gpio_chip *gc, struct device *dev,
+ if (gc->bgpio_bits > BITS_PER_LONG)
+ return -EINVAL;
+
+- spin_lock_init(&gc->bgpio_lock);
++ raw_spin_lock_init(&gc->bgpio_lock);
+ gc->parent = dev;
+ gc->label = dev_name(dev);
+ gc->base = -1;
+diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c
+index f50236e68e88..f41123de69c5 100644
+--- a/drivers/gpio/gpio-sifive.c
++++ b/drivers/gpio/gpio-sifive.c
+@@ -44,7 +44,7 @@ static void sifive_gpio_set_ie(struct sifive_gpio *chip, unsigned int offset)
+ unsigned long flags;
+ unsigned int trigger;
+
+- spin_lock_irqsave(&chip->gc.bgpio_lock, flags);
++ raw_spin_lock_irqsave(&chip->gc.bgpio_lock, flags);
+ trigger = (chip->irq_state & BIT(offset)) ? chip->trigger[offset] : 0;
+ regmap_update_bits(chip->regs, SIFIVE_GPIO_RISE_IE, BIT(offset),
+ (trigger & IRQ_TYPE_EDGE_RISING) ? BIT(offset) : 0);
+@@ -54,7 +54,7 @@ static void sifive_gpio_set_ie(struct sifive_gpio *chip, unsigned int offset)
+ (trigger & IRQ_TYPE_LEVEL_HIGH) ? BIT(offset) : 0);
+ regmap_update_bits(chip->regs, SIFIVE_GPIO_LOW_IE, BIT(offset),
+ (trigger & IRQ_TYPE_LEVEL_LOW) ? BIT(offset) : 0);
+- spin_unlock_irqrestore(&chip->gc.bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&chip->gc.bgpio_lock, flags);
+ }
+
+ static int sifive_gpio_irq_set_type(struct irq_data *d, unsigned int trigger)
+@@ -84,13 +84,13 @@ static void sifive_gpio_irq_enable(struct irq_data *d)
+ /* Switch to input */
+ gc->direction_input(gc, offset);
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+ /* Clear any sticky pending interrupts */
+ regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit);
+ regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit);
+ regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit);
+ regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit);
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+
+ /* Enable interrupts */
+ assign_bit(offset, &chip->irq_state, 1);
+@@ -116,13 +116,13 @@ static void sifive_gpio_irq_eoi(struct irq_data *d)
+ u32 bit = BIT(offset);
+ unsigned long flags;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+ /* Clear all pending interrupts */
+ regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit);
+ regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit);
+ regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit);
+ regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit);
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+
+ irq_chip_eoi_parent(d);
+ }
+diff --git a/drivers/gpio/gpio-tb10x.c b/drivers/gpio/gpio-tb10x.c
+index 718a508d3b2f..de6afa3f9716 100644
+--- a/drivers/gpio/gpio-tb10x.c
++++ b/drivers/gpio/gpio-tb10x.c
+@@ -62,14 +62,14 @@ static inline void tb10x_set_bits(struct tb10x_gpio *gpio, unsigned int offs,
+ u32 r;
+ unsigned long flags;
+
+- spin_lock_irqsave(&gpio->gc.bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gpio->gc.bgpio_lock, flags);
+
+ r = tb10x_reg_read(gpio, offs);
+ r = (r & ~mask) | (val & mask);
+
+ tb10x_reg_write(gpio, offs, r);
+
+- spin_unlock_irqrestore(&gpio->gc.bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gpio->gc.bgpio_lock, flags);
+ }
+
+ static int tb10x_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
+index 41136f63014a..e4a0d16b58cc 100644
+--- a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
++++ b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
+@@ -104,12 +104,12 @@ static void npcm_gpio_set(struct gpio_chip *gc, void __iomem *reg,
+ unsigned long flags;
+ unsigned long val;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+
+ val = ioread32(reg) | pinmask;
+ iowrite32(val, reg);
+
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ }
+
+ static void npcm_gpio_clr(struct gpio_chip *gc, void __iomem *reg,
+@@ -118,12 +118,12 @@ static void npcm_gpio_clr(struct gpio_chip *gc, void __iomem *reg,
+ unsigned long flags;
+ unsigned long val;
+
+- spin_lock_irqsave(&gc->bgpio_lock, flags);
++ raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
+
+ val = ioread32(reg) & ~pinmask;
+ iowrite32(val, reg);
+
+- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++ raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+ }
+
+ static void npcmgpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
+index ad479db8f0aa..11c26ae7b4fa 100644
+--- a/include/linux/gpio/driver.h
++++ b/include/linux/gpio/driver.h
+@@ -425,7 +425,7 @@ struct gpio_chip {
+ void __iomem *reg_dir_in;
+ bool bgpio_dir_unreadable;
+ int bgpio_bits;
+- spinlock_t bgpio_lock;
++ raw_spinlock_t bgpio_lock;
+ unsigned long bgpio_data;
+ unsigned long bgpio_dir;
+ #endif /* CONFIG_GPIO_GENERIC */
+--
+2.39.0
+
--- /dev/null
+From c8d5817a7e586572fa924671fc6580098efa4059 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 18:12:16 +0000
+Subject: HID: betop: check shape of output reports
+
+From: Pietro Borrello <borrello@diag.uniroma1.it>
+
+[ Upstream commit 3782c0d6edf658b71354a64d60aa7a296188fc90 ]
+
+betopff_init() only checks the total sum of the report counts for each
+report field to be at least 4, but hid_betopff_play() expects 4 report
+fields.
+A device advertising an output report with one field and 4 report counts
+would pass the check but crash the kernel with a NULL pointer dereference
+in hid_betopff_play().
+
+Fixes: 52cd7785f3cd ("HID: betop: add drivers/hid/hid-betopff.c")
+Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-betopff.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/hid/hid-betopff.c b/drivers/hid/hid-betopff.c
+index 467d789f9bc2..25ed7b9a917e 100644
+--- a/drivers/hid/hid-betopff.c
++++ b/drivers/hid/hid-betopff.c
+@@ -60,7 +60,6 @@ static int betopff_init(struct hid_device *hid)
+ struct list_head *report_list =
+ &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct input_dev *dev;
+- int field_count = 0;
+ int error;
+ int i, j;
+
+@@ -86,19 +85,21 @@ static int betopff_init(struct hid_device *hid)
+ * -----------------------------------------
+ * Do init them with default value.
+ */
++ if (report->maxfield < 4) {
++ hid_err(hid, "not enough fields in the report: %d\n",
++ report->maxfield);
++ return -ENODEV;
++ }
+ for (i = 0; i < report->maxfield; i++) {
++ if (report->field[i]->report_count < 1) {
++ hid_err(hid, "no values in the field\n");
++ return -ENODEV;
++ }
+ for (j = 0; j < report->field[i]->report_count; j++) {
+ report->field[i]->value[j] = 0x00;
+- field_count++;
+ }
+ }
+
+- if (field_count < 4) {
+- hid_err(hid, "not enough fields in the report: %d\n",
+- field_count);
+- return -ENODEV;
+- }
+-
+ betopff = kzalloc(sizeof(*betopff), GFP_KERNEL);
+ if (!betopff)
+ return -ENOMEM;
+--
+2.39.0
+
--- /dev/null
+From 41418409309bce452c63953b3a92b00794010d3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Jan 2023 11:11:25 +0000
+Subject: HID: check empty report_list in bigben_probe()
+
+From: Pietro Borrello <borrello@diag.uniroma1.it>
+
+[ Upstream commit c7bf714f875531f227f2ef1fdcc8f4d44e7c7d9d ]
+
+Add a check for empty report_list in bigben_probe().
+The missing check causes a type confusion when issuing a list_entry()
+on an empty report_list.
+The problem is caused by the assumption that the device must
+have valid report_list. While this will be true for all normal HID
+devices, a suitably malicious device can violate the assumption.
+
+Fixes: 256a90ed9e46 ("HID: hid-bigbenff: driver for BigBen Interactive PS3OFMINIPAD gamepad")
+Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-bigbenff.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/hid/hid-bigbenff.c b/drivers/hid/hid-bigbenff.c
+index e8c5e3ac9fff..e8b16665860d 100644
+--- a/drivers/hid/hid-bigbenff.c
++++ b/drivers/hid/hid-bigbenff.c
+@@ -344,6 +344,11 @@ static int bigben_probe(struct hid_device *hid,
+ }
+
+ report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
++ if (list_empty(report_list)) {
++ hid_err(hid, "no output report found\n");
++ error = -ENODEV;
++ goto error_hw_stop;
++ }
+ bigben->report = list_entry(report_list->next,
+ struct hid_report, list);
+
+--
+2.39.0
+
--- /dev/null
+From f8dc74f92d035f87647484dce634ebee816a84bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Jan 2023 11:11:24 +0000
+Subject: HID: check empty report_list in hid_validate_values()
+
+From: Pietro Borrello <borrello@diag.uniroma1.it>
+
+[ Upstream commit b12fece4c64857e5fab4290bf01b2e0317a88456 ]
+
+Add a check for empty report_list in hid_validate_values().
+The missing check causes a type confusion when issuing a list_entry()
+on an empty report_list.
+The problem is caused by the assumption that the device must
+have valid report_list. While this will be true for all normal HID
+devices, a suitably malicious device can violate the assumption.
+
+Fixes: 1b15d2e5b807 ("HID: core: fix validation of report id 0")
+Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index ef9c799fa371..2e475bd426b8 100644
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -988,8 +988,8 @@ struct hid_report *hid_validate_values(struct hid_device *hid,
+ * Validating on id 0 means we should examine the first
+ * report in the list.
+ */
+- report = list_entry(
+- hid->report_enum[type].report_list.next,
++ report = list_first_entry_or_null(
++ &hid->report_enum[type].report_list,
+ struct hid_report, list);
+ } else {
+ report = hid->report_enum[type].report_id_hash[id];
+--
+2.39.0
+
--- /dev/null
+From 96e5a9fac3b3a5c6a5a99d308c8c7e1a2005e02c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 21:48:23 +0800
+Subject: HID: intel_ish-hid: Add check for ishtp_dma_tx_map
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit b3d40c3ec3dc4ad78017de6c3a38979f57aaaab8 ]
+
+As the kcalloc may return NULL pointer,
+it should be better to check the ishtp_dma_tx_map
+before use in order to avoid NULL pointer dereference.
+
+Fixes: 3703f53b99e4 ("HID: intel_ish-hid: ISH Transport layer")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/intel-ish-hid/ishtp/dma-if.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/hid/intel-ish-hid/ishtp/dma-if.c b/drivers/hid/intel-ish-hid/ishtp/dma-if.c
+index 40554c8daca0..00046cbfd4ed 100644
+--- a/drivers/hid/intel-ish-hid/ishtp/dma-if.c
++++ b/drivers/hid/intel-ish-hid/ishtp/dma-if.c
+@@ -104,6 +104,11 @@ void *ishtp_cl_get_dma_send_buf(struct ishtp_device *dev,
+ int required_slots = (size / DMA_SLOT_SIZE)
+ + 1 * (size % DMA_SLOT_SIZE != 0);
+
++ if (!dev->ishtp_dma_tx_map) {
++ dev_err(dev->devc, "Fail to allocate Tx map\n");
++ return NULL;
++ }
++
+ spin_lock_irqsave(&dev->ishtp_dma_tx_lock, flags);
+ for (i = 0; i <= (dev->ishtp_dma_num_slots - required_slots); i++) {
+ free = 1;
+@@ -150,6 +155,11 @@ void ishtp_cl_release_dma_acked_mem(struct ishtp_device *dev,
+ return;
+ }
+
++ if (!dev->ishtp_dma_tx_map) {
++ dev_err(dev->devc, "Fail to allocate Tx map\n");
++ return;
++ }
++
+ i = (msg_addr - dev->ishtp_host_dma_tx_buf) / DMA_SLOT_SIZE;
+ spin_lock_irqsave(&dev->ishtp_dma_tx_lock, flags);
+ for (j = 0; j < acked_slots; j++) {
+--
+2.39.0
+
--- /dev/null
+From a8c2af32d7adf83bcee84ba8cc00eae1700ed281 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Jan 2023 15:41:40 +0100
+Subject: HID: revert CHERRY_MOUSE_000C quirk
+
+From: Jiri Kosina <jkosina@suse.cz>
+
+[ Upstream commit cbf44580ce6b310272a73e3e794233fd064330bd ]
+
+This partially reverts commit f6d910a89a2391 ("HID: usbhid: Add ALWAYS_POLL quirk
+for some mice"), as it turns out to break reboot on some platforms for reason
+yet to be understood.
+
+Fixes: f6d910a89a2391 ("HID: usbhid: Add ALWAYS_POLL quirk for some mice")
+Reported-by: Christian Zigotzky <chzigotzky@xenosoft.de>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-ids.h | 1 -
+ drivers/hid/hid-quirks.c | 1 -
+ 2 files changed, 2 deletions(-)
+
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 8698d49edaa3..fa1aa22547ea 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -261,7 +261,6 @@
+ #define USB_DEVICE_ID_CH_AXIS_295 0x001c
+
+ #define USB_VENDOR_ID_CHERRY 0x046a
+-#define USB_DEVICE_ID_CHERRY_MOUSE_000C 0x000c
+ #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
+ #define USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR 0x0027
+
+diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
+index fc1e061900bc..184029cad014 100644
+--- a/drivers/hid/hid-quirks.c
++++ b/drivers/hid/hid-quirks.c
+@@ -54,7 +54,6 @@ static const struct hid_device_id hid_quirks[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE), HID_QUIRK_NOGET },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS), HID_QUIRK_NOGET },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_THROTTLE), HID_QUIRK_NOGET },
+- { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_MOUSE_000C), HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB), HID_QUIRK_NO_INIT_REPORTS },
+--
+2.39.0
+
--- /dev/null
+From c24d2401ea60fe5298c84a867df851e6036346fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 12:31:21 -0500
+Subject: IB/hfi1: Fix expected receive setup error exit issues
+
+From: Dean Luick <dean.luick@cornelisnetworks.com>
+
+[ Upstream commit e0c4a422f5246abefbf7c178ef99a1f2dc3c5f62 ]
+
+Fix three error exit issues in expected receive setup.
+Re-arrange error exits to increase readability.
+
+Issues and fixes:
+1. Possible missed page unpin if tidlist copyout fails and
+ not all pinned pages where made part of a TID.
+ Fix: Unpin the unused pages.
+
+2. Return success with unset return values tidcnt and length
+ when no pages were pinned.
+ Fix: Return -ENOSPC if no pages were pinned.
+
+3. Return success with unset return values tidcnt and length when
+ no rcvarray entries available.
+ Fix: Return -ENOSPC if no rcvarray entries are available.
+
+Fixes: 7e7a436ecb6e ("staging/hfi1: Add TID entry program function body")
+Fixes: 97736f36dbeb ("IB/hfi1: Validate page aligned for a given virtual addres")
+Fixes: f404ca4c7ea8 ("IB/hfi1: Refactor hfi_user_exp_rcv_setup() IOCTL")
+Signed-off-by: Dean Luick <dean.luick@cornelisnetworks.com>
+Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Link: https://lore.kernel.org/r/167328548150.1472310.1492305874804187634.stgit@awfm-02.cornelisnetworks.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hfi1/user_exp_rcv.c | 83 ++++++++++++++---------
+ 1 file changed, 50 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.c b/drivers/infiniband/hw/hfi1/user_exp_rcv.c
+index 236cfc560ab7..5b93a1aace9d 100644
+--- a/drivers/infiniband/hw/hfi1/user_exp_rcv.c
++++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.c
+@@ -268,15 +268,14 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
+ tidbuf->psets = kcalloc(uctxt->expected_count, sizeof(*tidbuf->psets),
+ GFP_KERNEL);
+ if (!tidbuf->psets) {
+- kfree(tidbuf);
+- return -ENOMEM;
++ ret = -ENOMEM;
++ goto fail_release_mem;
+ }
+
+ pinned = pin_rcv_pages(fd, tidbuf);
+ if (pinned <= 0) {
+- kfree(tidbuf->psets);
+- kfree(tidbuf);
+- return pinned;
++ ret = (pinned < 0) ? pinned : -ENOSPC;
++ goto fail_unpin;
+ }
+
+ /* Find sets of physically contiguous pages */
+@@ -291,14 +290,16 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
+ fd->tid_used += pageset_count;
+ spin_unlock(&fd->tid_lock);
+
+- if (!pageset_count)
+- goto bail;
++ if (!pageset_count) {
++ ret = -ENOSPC;
++ goto fail_unreserve;
++ }
+
+ ngroups = pageset_count / dd->rcv_entries.group_size;
+ tidlist = kcalloc(pageset_count, sizeof(*tidlist), GFP_KERNEL);
+ if (!tidlist) {
+ ret = -ENOMEM;
+- goto nomem;
++ goto fail_unreserve;
+ }
+
+ tididx = 0;
+@@ -394,44 +395,60 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
+ }
+ unlock:
+ mutex_unlock(&uctxt->exp_mutex);
+-nomem:
+ hfi1_cdbg(TID, "total mapped: tidpairs:%u pages:%u (%d)", tididx,
+ mapped_pages, ret);
++
++ /* fail if nothing was programmed, set error if none provided */
++ if (tididx == 0) {
++ if (ret >= 0)
++ ret = -ENOSPC;
++ goto fail_unreserve;
++ }
++
+ /* adjust reserved tid_used to actual count */
+ spin_lock(&fd->tid_lock);
+ fd->tid_used -= pageset_count - tididx;
+ spin_unlock(&fd->tid_lock);
+- if (tididx) {
+- tinfo->tidcnt = tididx;
+- tinfo->length = mapped_pages * PAGE_SIZE;
+
+- if (copy_to_user(u64_to_user_ptr(tinfo->tidlist),
+- tidlist, sizeof(tidlist[0]) * tididx)) {
+- /*
+- * On failure to copy to the user level, we need to undo
+- * everything done so far so we don't leak resources.
+- */
+- tinfo->tidlist = (unsigned long)&tidlist;
+- hfi1_user_exp_rcv_clear(fd, tinfo);
+- tinfo->tidlist = 0;
+- ret = -EFAULT;
+- goto bail;
+- }
++ /* unpin all pages not covered by a TID */
++ unpin_rcv_pages(fd, tidbuf, NULL, mapped_pages, pinned - mapped_pages,
++ false);
++
++ tinfo->tidcnt = tididx;
++ tinfo->length = mapped_pages * PAGE_SIZE;
++
++ if (copy_to_user(u64_to_user_ptr(tinfo->tidlist),
++ tidlist, sizeof(tidlist[0]) * tididx)) {
++ ret = -EFAULT;
++ goto fail_unprogram;
+ }
+
+- /*
+- * If not everything was mapped (due to insufficient RcvArray entries,
+- * for example), unpin all unmapped pages so we can pin them nex time.
+- */
+- if (mapped_pages != pinned)
+- unpin_rcv_pages(fd, tidbuf, NULL, mapped_pages,
+- (pinned - mapped_pages), false);
+-bail:
++ kfree(tidbuf->pages);
+ kfree(tidbuf->psets);
++ kfree(tidbuf);
+ kfree(tidlist);
++ return 0;
++
++fail_unprogram:
++ /* unprogram, unmap, and unpin all allocated TIDs */
++ tinfo->tidlist = (unsigned long)tidlist;
++ hfi1_user_exp_rcv_clear(fd, tinfo);
++ tinfo->tidlist = 0;
++ pinned = 0; /* nothing left to unpin */
++ pageset_count = 0; /* nothing left reserved */
++fail_unreserve:
++ spin_lock(&fd->tid_lock);
++ fd->tid_used -= pageset_count;
++ spin_unlock(&fd->tid_lock);
++fail_unpin:
++ if (pinned > 0)
++ unpin_rcv_pages(fd, tidbuf, NULL, 0, pinned, false);
++fail_release_mem:
+ kfree(tidbuf->pages);
++ kfree(tidbuf->psets);
+ kfree(tidbuf);
+- return ret > 0 ? 0 : ret;
++ kfree(tidlist);
++ return ret;
+ }
+
+ int hfi1_user_exp_rcv_clear(struct hfi1_filedata *fd,
+--
+2.39.0
+
--- /dev/null
+From ff6746221dd708dbe22ebe5bf97355f1b778e9ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 12:31:26 -0500
+Subject: IB/hfi1: Immediately remove invalid memory from hardware
+
+From: Dean Luick <dean.luick@cornelisnetworks.com>
+
+[ Upstream commit 1c7edde1b5720ddb0aff5ca8c7f605a0f92526eb ]
+
+When a user expected receive page is unmapped, it should be
+immediately removed from hardware rather than depend on a
+reaction from user space.
+
+Fixes: 2677a7680e77 ("IB/hfi1: Fix memory leak during unexpected shutdown")
+Signed-off-by: Dean Luick <dean.luick@cornelisnetworks.com>
+Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Link: https://lore.kernel.org/r/167328548663.1472310.7871808081861622659.stgit@awfm-02.cornelisnetworks.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hfi1/user_exp_rcv.c | 43 +++++++++++++++--------
+ drivers/infiniband/hw/hfi1/user_exp_rcv.h | 1 +
+ 2 files changed, 30 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.c b/drivers/infiniband/hw/hfi1/user_exp_rcv.c
+index 5b93a1aace9d..8337d995aa26 100644
+--- a/drivers/infiniband/hw/hfi1/user_exp_rcv.c
++++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.c
+@@ -28,8 +28,9 @@ static int program_rcvarray(struct hfi1_filedata *fd, struct tid_user_buf *,
+ unsigned int start, u16 count,
+ u32 *tidlist, unsigned int *tididx,
+ unsigned int *pmapped);
+-static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo,
+- struct tid_group **grp);
++static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo);
++static void __clear_tid_node(struct hfi1_filedata *fd,
++ struct tid_rb_node *node);
+ static void clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node);
+
+ static const struct mmu_interval_notifier_ops tid_mn_ops = {
+@@ -469,7 +470,7 @@ int hfi1_user_exp_rcv_clear(struct hfi1_filedata *fd,
+
+ mutex_lock(&uctxt->exp_mutex);
+ for (tididx = 0; tididx < tinfo->tidcnt; tididx++) {
+- ret = unprogram_rcvarray(fd, tidinfo[tididx], NULL);
++ ret = unprogram_rcvarray(fd, tidinfo[tididx]);
+ if (ret) {
+ hfi1_cdbg(TID, "Failed to unprogram rcv array %d",
+ ret);
+@@ -724,6 +725,7 @@ static int set_rcvarray_entry(struct hfi1_filedata *fd,
+ }
+
+ node->fdata = fd;
++ mutex_init(&node->invalidate_mutex);
+ node->phys = page_to_phys(pages[0]);
+ node->npages = npages;
+ node->rcventry = rcventry;
+@@ -763,8 +765,7 @@ static int set_rcvarray_entry(struct hfi1_filedata *fd,
+ return -EFAULT;
+ }
+
+-static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo,
+- struct tid_group **grp)
++static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo)
+ {
+ struct hfi1_ctxtdata *uctxt = fd->uctxt;
+ struct hfi1_devdata *dd = uctxt->dd;
+@@ -787,9 +788,6 @@ static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo,
+ if (!node || node->rcventry != (uctxt->expected_base + rcventry))
+ return -EBADF;
+
+- if (grp)
+- *grp = node->grp;
+-
+ if (fd->use_mn)
+ mmu_interval_notifier_remove(&node->notifier);
+ cacheless_tid_rb_remove(fd, node);
+@@ -797,23 +795,34 @@ static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo,
+ return 0;
+ }
+
+-static void clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node)
++static void __clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node)
+ {
+ struct hfi1_ctxtdata *uctxt = fd->uctxt;
+ struct hfi1_devdata *dd = uctxt->dd;
+
++ mutex_lock(&node->invalidate_mutex);
++ if (node->freed)
++ goto done;
++ node->freed = true;
++
+ trace_hfi1_exp_tid_unreg(uctxt->ctxt, fd->subctxt, node->rcventry,
+ node->npages,
+ node->notifier.interval_tree.start, node->phys,
+ node->dma_addr);
+
+- /*
+- * Make sure device has seen the write before we unpin the
+- * pages.
+- */
++ /* Make sure device has seen the write before pages are unpinned */
+ hfi1_put_tid(dd, node->rcventry, PT_INVALID_FLUSH, 0, 0);
+
+ unpin_rcv_pages(fd, NULL, node, 0, node->npages, true);
++done:
++ mutex_unlock(&node->invalidate_mutex);
++}
++
++static void clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node)
++{
++ struct hfi1_ctxtdata *uctxt = fd->uctxt;
++
++ __clear_tid_node(fd, node);
+
+ node->grp->used--;
+ node->grp->map &= ~(1 << (node->rcventry - node->grp->base));
+@@ -872,10 +881,16 @@ static bool tid_rb_invalidate(struct mmu_interval_notifier *mni,
+ if (node->freed)
+ return true;
+
++ /* take action only if unmapping */
++ if (range->event != MMU_NOTIFY_UNMAP)
++ return true;
++
+ trace_hfi1_exp_tid_inval(uctxt->ctxt, fdata->subctxt,
+ node->notifier.interval_tree.start,
+ node->rcventry, node->npages, node->dma_addr);
+- node->freed = true;
++
++ /* clear the hardware rcvarray entry */
++ __clear_tid_node(fdata, node);
+
+ spin_lock(&fdata->invalid_lock);
+ if (fdata->invalid_tid_idx < uctxt->expected_count) {
+diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.h b/drivers/infiniband/hw/hfi1/user_exp_rcv.h
+index 8c53e416bf84..2ddb3dac7d91 100644
+--- a/drivers/infiniband/hw/hfi1/user_exp_rcv.h
++++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.h
+@@ -27,6 +27,7 @@ struct tid_user_buf {
+ struct tid_rb_node {
+ struct mmu_interval_notifier notifier;
+ struct hfi1_filedata *fdata;
++ struct mutex invalidate_mutex; /* covers hw removal */
+ unsigned long phys;
+ struct tid_group *grp;
+ u32 rcventry;
+--
+2.39.0
+
--- /dev/null
+From fd62cf582b0d1b6c621ca83c4c1f4cb4cef3f321 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 12:31:11 -0500
+Subject: IB/hfi1: Reject a zero-length user expected buffer
+
+From: Dean Luick <dean.luick@cornelisnetworks.com>
+
+[ Upstream commit 0a0a6e80472c98947d73c3d13bcd7d101895f55d ]
+
+A zero length user buffer makes no sense and the code
+does not handle it correctly. Instead, reject a
+zero length as invalid.
+
+Fixes: 97736f36dbeb ("IB/hfi1: Validate page aligned for a given virtual addres")
+Signed-off-by: Dean Luick <dean.luick@cornelisnetworks.com>
+Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Link: https://lore.kernel.org/r/167328547120.1472310.6362802432127399257.stgit@awfm-02.cornelisnetworks.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hfi1/user_exp_rcv.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.c b/drivers/infiniband/hw/hfi1/user_exp_rcv.c
+index 0c86e9d354f8..212273fcf4dd 100644
+--- a/drivers/infiniband/hw/hfi1/user_exp_rcv.c
++++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.c
+@@ -256,6 +256,8 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
+
+ if (!PAGE_ALIGNED(tinfo->vaddr))
+ return -EINVAL;
++ if (tinfo->length == 0)
++ return -EINVAL;
+
+ tidbuf = kzalloc(sizeof(*tidbuf), GFP_KERNEL);
+ if (!tidbuf)
+--
+2.39.0
+
--- /dev/null
+From d7e459aa6045b91f4fc4dbb2d401355c22d89a15 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 12:31:31 -0500
+Subject: IB/hfi1: Remove user expected buffer invalidate race
+
+From: Dean Luick <dean.luick@cornelisnetworks.com>
+
+[ Upstream commit b3deec25847bda34e34d5d7be02f633caf000bd8 ]
+
+During setup, there is a possible race between a page invalidate
+and hardware programming. Add a covering invalidate over the user
+target range during setup. If anything within that range is
+invalidated during setup, fail the setup. Once set up, each
+TID will have its own invalidate callback and invalidate.
+
+Fixes: 3889551db212 ("RDMA/hfi1: Use mmu_interval_notifier_insert for user_exp_rcv")
+Signed-off-by: Dean Luick <dean.luick@cornelisnetworks.com>
+Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Link: https://lore.kernel.org/r/167328549178.1472310.9867497376936699488.stgit@awfm-02.cornelisnetworks.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hfi1/user_exp_rcv.c | 58 +++++++++++++++++++++--
+ drivers/infiniband/hw/hfi1/user_exp_rcv.h | 2 +
+ 2 files changed, 55 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.c b/drivers/infiniband/hw/hfi1/user_exp_rcv.c
+index 8337d995aa26..ba930112c162 100644
+--- a/drivers/infiniband/hw/hfi1/user_exp_rcv.c
++++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.c
+@@ -23,6 +23,9 @@ static void cacheless_tid_rb_remove(struct hfi1_filedata *fdata,
+ static bool tid_rb_invalidate(struct mmu_interval_notifier *mni,
+ const struct mmu_notifier_range *range,
+ unsigned long cur_seq);
++static bool tid_cover_invalidate(struct mmu_interval_notifier *mni,
++ const struct mmu_notifier_range *range,
++ unsigned long cur_seq);
+ static int program_rcvarray(struct hfi1_filedata *fd, struct tid_user_buf *,
+ struct tid_group *grp,
+ unsigned int start, u16 count,
+@@ -36,6 +39,9 @@ static void clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node);
+ static const struct mmu_interval_notifier_ops tid_mn_ops = {
+ .invalidate = tid_rb_invalidate,
+ };
++static const struct mmu_interval_notifier_ops tid_cover_ops = {
++ .invalidate = tid_cover_invalidate,
++};
+
+ /*
+ * Initialize context and file private data needed for Expected
+@@ -254,6 +260,7 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
+ tididx = 0, mapped, mapped_pages = 0;
+ u32 *tidlist = NULL;
+ struct tid_user_buf *tidbuf;
++ unsigned long mmu_seq = 0;
+
+ if (!PAGE_ALIGNED(tinfo->vaddr))
+ return -EINVAL;
+@@ -264,6 +271,7 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
+ if (!tidbuf)
+ return -ENOMEM;
+
++ mutex_init(&tidbuf->cover_mutex);
+ tidbuf->vaddr = tinfo->vaddr;
+ tidbuf->length = tinfo->length;
+ tidbuf->psets = kcalloc(uctxt->expected_count, sizeof(*tidbuf->psets),
+@@ -273,6 +281,16 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
+ goto fail_release_mem;
+ }
+
++ if (fd->use_mn) {
++ ret = mmu_interval_notifier_insert(
++ &tidbuf->notifier, current->mm,
++ tidbuf->vaddr, tidbuf->npages * PAGE_SIZE,
++ &tid_cover_ops);
++ if (ret)
++ goto fail_release_mem;
++ mmu_seq = mmu_interval_read_begin(&tidbuf->notifier);
++ }
++
+ pinned = pin_rcv_pages(fd, tidbuf);
+ if (pinned <= 0) {
+ ret = (pinned < 0) ? pinned : -ENOSPC;
+@@ -415,6 +433,20 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
+ unpin_rcv_pages(fd, tidbuf, NULL, mapped_pages, pinned - mapped_pages,
+ false);
+
++ if (fd->use_mn) {
++ /* check for an invalidate during setup */
++ bool fail = false;
++
++ mutex_lock(&tidbuf->cover_mutex);
++ fail = mmu_interval_read_retry(&tidbuf->notifier, mmu_seq);
++ mutex_unlock(&tidbuf->cover_mutex);
++
++ if (fail) {
++ ret = -EBUSY;
++ goto fail_unprogram;
++ }
++ }
++
+ tinfo->tidcnt = tididx;
+ tinfo->length = mapped_pages * PAGE_SIZE;
+
+@@ -424,6 +456,8 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
+ goto fail_unprogram;
+ }
+
++ if (fd->use_mn)
++ mmu_interval_notifier_remove(&tidbuf->notifier);
+ kfree(tidbuf->pages);
+ kfree(tidbuf->psets);
+ kfree(tidbuf);
+@@ -442,6 +476,8 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
+ fd->tid_used -= pageset_count;
+ spin_unlock(&fd->tid_lock);
+ fail_unpin:
++ if (fd->use_mn)
++ mmu_interval_notifier_remove(&tidbuf->notifier);
+ if (pinned > 0)
+ unpin_rcv_pages(fd, tidbuf, NULL, 0, pinned, false);
+ fail_release_mem:
+@@ -741,11 +777,6 @@ static int set_rcvarray_entry(struct hfi1_filedata *fd,
+ &tid_mn_ops);
+ if (ret)
+ goto out_unmap;
+- /*
+- * FIXME: This is in the wrong order, the notifier should be
+- * established before the pages are pinned by pin_rcv_pages.
+- */
+- mmu_interval_read_begin(&node->notifier);
+ }
+ fd->entry_to_rb[node->rcventry - uctxt->expected_base] = node;
+
+@@ -920,6 +951,23 @@ static bool tid_rb_invalidate(struct mmu_interval_notifier *mni,
+ return true;
+ }
+
++static bool tid_cover_invalidate(struct mmu_interval_notifier *mni,
++ const struct mmu_notifier_range *range,
++ unsigned long cur_seq)
++{
++ struct tid_user_buf *tidbuf =
++ container_of(mni, struct tid_user_buf, notifier);
++
++ /* take action only if unmapping */
++ if (range->event == MMU_NOTIFY_UNMAP) {
++ mutex_lock(&tidbuf->cover_mutex);
++ mmu_interval_set_seq(mni, cur_seq);
++ mutex_unlock(&tidbuf->cover_mutex);
++ }
++
++ return true;
++}
++
+ static void cacheless_tid_rb_remove(struct hfi1_filedata *fdata,
+ struct tid_rb_node *tnode)
+ {
+diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.h b/drivers/infiniband/hw/hfi1/user_exp_rcv.h
+index 2ddb3dac7d91..f8ee997d0050 100644
+--- a/drivers/infiniband/hw/hfi1/user_exp_rcv.h
++++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.h
+@@ -16,6 +16,8 @@ struct tid_pageset {
+ };
+
+ struct tid_user_buf {
++ struct mmu_interval_notifier notifier;
++ struct mutex cover_mutex;
+ unsigned long vaddr;
+ unsigned long length;
+ unsigned int npages;
+--
+2.39.0
+
--- /dev/null
+From 108b1a75a8f33a949e0af2b0470da7d2c63f3bbc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 12:31:16 -0500
+Subject: IB/hfi1: Reserve user expected TIDs
+
+From: Dean Luick <dean.luick@cornelisnetworks.com>
+
+[ Upstream commit ecf91551cdd2925ed6d9a9d99074fa5f67b90596 ]
+
+To avoid a race, reserve the number of user expected
+TIDs before setup.
+
+Fixes: 7e7a436ecb6e ("staging/hfi1: Add TID entry program function body")
+Signed-off-by: Dean Luick <dean.luick@cornelisnetworks.com>
+Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Link: https://lore.kernel.org/r/167328547636.1472310.7419712824785353905.stgit@awfm-02.cornelisnetworks.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hfi1/user_exp_rcv.c | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.c b/drivers/infiniband/hw/hfi1/user_exp_rcv.c
+index 212273fcf4dd..236cfc560ab7 100644
+--- a/drivers/infiniband/hw/hfi1/user_exp_rcv.c
++++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.c
+@@ -282,16 +282,13 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
+ /* Find sets of physically contiguous pages */
+ tidbuf->n_psets = find_phys_blocks(tidbuf, pinned);
+
+- /*
+- * We don't need to access this under a lock since tid_used is per
+- * process and the same process cannot be in hfi1_user_exp_rcv_clear()
+- * and hfi1_user_exp_rcv_setup() at the same time.
+- */
++ /* Reserve the number of expected tids to be used. */
+ spin_lock(&fd->tid_lock);
+ if (fd->tid_used + tidbuf->n_psets > fd->tid_limit)
+ pageset_count = fd->tid_limit - fd->tid_used;
+ else
+ pageset_count = tidbuf->n_psets;
++ fd->tid_used += pageset_count;
+ spin_unlock(&fd->tid_lock);
+
+ if (!pageset_count)
+@@ -400,10 +397,11 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
+ nomem:
+ hfi1_cdbg(TID, "total mapped: tidpairs:%u pages:%u (%d)", tididx,
+ mapped_pages, ret);
++ /* adjust reserved tid_used to actual count */
++ spin_lock(&fd->tid_lock);
++ fd->tid_used -= pageset_count - tididx;
++ spin_unlock(&fd->tid_lock);
+ if (tididx) {
+- spin_lock(&fd->tid_lock);
+- fd->tid_used += tididx;
+- spin_unlock(&fd->tid_lock);
+ tinfo->tidcnt = tididx;
+ tinfo->length = mapped_pages * PAGE_SIZE;
+
+--
+2.39.0
+
--- /dev/null
+From c8a520ba648cd7d95911f7a2134c945a6c1b271d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Dec 2022 23:28:21 -0800
+Subject: kcsan: test: don't put the expect array on the stack
+
+From: Max Filippov <jcmvbkbc@gmail.com>
+
+[ Upstream commit 5b24ac2dfd3eb3e36f794af3aa7f2828b19035bd ]
+
+Size of the 'expect' array in the __report_matches is 1536 bytes, which
+is exactly the default frame size warning limit of the xtensa
+architecture.
+As a result allmodconfig xtensa kernel builds with the gcc that does not
+support the compiler plugins (which otherwise would push the said
+warning limit to 2K) fail with the following message:
+
+ kernel/kcsan/kcsan_test.c:257:1: error: the frame size of 1680 bytes
+ is larger than 1536 bytes
+
+Fix it by dynamically allocating the 'expect' array.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+Reviewed-by: Marco Elver <elver@google.com>
+Tested-by: Marco Elver <elver@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/kcsan/kcsan_test.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/kcsan/kcsan_test.c b/kernel/kcsan/kcsan_test.c
+index dc55fd5a36fc..8b176aeab91b 100644
+--- a/kernel/kcsan/kcsan_test.c
++++ b/kernel/kcsan/kcsan_test.c
+@@ -151,7 +151,7 @@ static bool report_matches(const struct expect_report *r)
+ const bool is_assert = (r->access[0].type | r->access[1].type) & KCSAN_ACCESS_ASSERT;
+ bool ret = false;
+ unsigned long flags;
+- typeof(observed.lines) expect;
++ typeof(*observed.lines) *expect;
+ const char *end;
+ char *cur;
+ int i;
+@@ -160,6 +160,10 @@ static bool report_matches(const struct expect_report *r)
+ if (!report_available())
+ return false;
+
++ expect = kmalloc(sizeof(observed.lines), GFP_KERNEL);
++ if (WARN_ON(!expect))
++ return false;
++
+ /* Generate expected report contents. */
+
+ /* Title */
+@@ -243,6 +247,7 @@ static bool report_matches(const struct expect_report *r)
+ strstr(observed.lines[2], expect[1])));
+ out:
+ spin_unlock_irqrestore(&observed.lock, flags);
++ kfree(expect);
+ return ret;
+ }
+
+--
+2.39.0
+
--- /dev/null
+From 911d920002ef84e698a86d5845f2ab44bd6b4e89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 15:54:56 +0100
+Subject: KVM: s390: interrupt: use READ_ONCE() before cmpxchg()
+
+From: Heiko Carstens <hca@linux.ibm.com>
+
+[ Upstream commit 42400d99e9f0728c17240edb9645637ead40f6b9 ]
+
+Use READ_ONCE() before cmpxchg() to prevent that the compiler generates
+code that fetches the to be compared old value several times from memory.
+
+Reviewed-by: Christian Borntraeger <borntraeger@linux.ibm.com>
+Acked-by: Christian Borntraeger <borntraeger@linux.ibm.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Link: https://lore.kernel.org/r/20230109145456.2895385-1-hca@linux.ibm.com
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kvm/interrupt.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
+index 8ce03a5ca863..ca7d09f09809 100644
+--- a/arch/s390/kvm/interrupt.c
++++ b/arch/s390/kvm/interrupt.c
+@@ -81,8 +81,9 @@ static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id)
+ struct esca_block *sca = vcpu->kvm->arch.sca;
+ union esca_sigp_ctrl *sigp_ctrl =
+ &(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
+- union esca_sigp_ctrl new_val = {0}, old_val = *sigp_ctrl;
++ union esca_sigp_ctrl new_val = {0}, old_val;
+
++ old_val = READ_ONCE(*sigp_ctrl);
+ new_val.scn = src_id;
+ new_val.c = 1;
+ old_val.c = 0;
+@@ -93,8 +94,9 @@ static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id)
+ struct bsca_block *sca = vcpu->kvm->arch.sca;
+ union bsca_sigp_ctrl *sigp_ctrl =
+ &(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
+- union bsca_sigp_ctrl new_val = {0}, old_val = *sigp_ctrl;
++ union bsca_sigp_ctrl new_val = {0}, old_val;
+
++ old_val = READ_ONCE(*sigp_ctrl);
+ new_val.scn = src_id;
+ new_val.c = 1;
+ old_val.c = 0;
+@@ -124,16 +126,18 @@ static void sca_clear_ext_call(struct kvm_vcpu *vcpu)
+ struct esca_block *sca = vcpu->kvm->arch.sca;
+ union esca_sigp_ctrl *sigp_ctrl =
+ &(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
+- union esca_sigp_ctrl old = *sigp_ctrl;
++ union esca_sigp_ctrl old;
+
++ old = READ_ONCE(*sigp_ctrl);
+ expect = old.value;
+ rc = cmpxchg(&sigp_ctrl->value, old.value, 0);
+ } else {
+ struct bsca_block *sca = vcpu->kvm->arch.sca;
+ union bsca_sigp_ctrl *sigp_ctrl =
+ &(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
+- union bsca_sigp_ctrl old = *sigp_ctrl;
++ union bsca_sigp_ctrl old;
+
++ old = READ_ONCE(*sigp_ctrl);
+ expect = old.value;
+ rc = cmpxchg(&sigp_ctrl->value, old.value, 0);
+ }
+--
+2.39.0
+
--- /dev/null
+From c51a28d0eff6ba9ecd122c74f45ef4b2464bd2df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Jan 2023 19:01:37 -0800
+Subject: l2tp: close all race conditions in l2tp_tunnel_register()
+
+From: Cong Wang <cong.wang@bytedance.com>
+
+[ Upstream commit 0b2c59720e65885a394a017d0cf9cab118914682 ]
+
+The code in l2tp_tunnel_register() is racy in several ways:
+
+1. It modifies the tunnel socket _after_ publishing it.
+
+2. It calls setup_udp_tunnel_sock() on an existing socket without
+ locking.
+
+3. It changes sock lock class on fly, which triggers many syzbot
+ reports.
+
+This patch amends all of them by moving socket initialization code
+before publishing and under sock lock. As suggested by Jakub, the
+l2tp lockdep class is not necessary as we can just switch to
+bh_lock_sock_nested().
+
+Fixes: 37159ef2c1ae ("l2tp: fix a lockdep splat")
+Fixes: 6b9f34239b00 ("l2tp: fix races in tunnel creation")
+Reported-by: syzbot+52866e24647f9a23403f@syzkaller.appspotmail.com
+Reported-by: syzbot+94cc2a66fc228b23f360@syzkaller.appspotmail.com
+Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Cc: Guillaume Nault <gnault@redhat.com>
+Cc: Jakub Sitnicki <jakub@cloudflare.com>
+Cc: Eric Dumazet <edumazet@google.com>
+Cc: Tom Parkin <tparkin@katalix.com>
+Signed-off-by: Cong Wang <cong.wang@bytedance.com>
+Reviewed-by: Guillaume Nault <gnault@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/l2tp/l2tp_core.c | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
+index 68d8b2aa6f6d..4c5227048be4 100644
+--- a/net/l2tp/l2tp_core.c
++++ b/net/l2tp/l2tp_core.c
+@@ -1041,7 +1041,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, uns
+ IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | IPSKB_REROUTED);
+ nf_reset_ct(skb);
+
+- bh_lock_sock(sk);
++ bh_lock_sock_nested(sk);
+ if (sock_owned_by_user(sk)) {
+ kfree_skb(skb);
+ ret = NET_XMIT_DROP;
+@@ -1387,8 +1387,6 @@ static int l2tp_tunnel_sock_create(struct net *net,
+ return err;
+ }
+
+-static struct lock_class_key l2tp_socket_class;
+-
+ int l2tp_tunnel_create(int fd, int version, u32 tunnel_id, u32 peer_tunnel_id,
+ struct l2tp_tunnel_cfg *cfg, struct l2tp_tunnel **tunnelp)
+ {
+@@ -1484,21 +1482,16 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+ }
+
+ sk = sock->sk;
++ lock_sock(sk);
+ write_lock_bh(&sk->sk_callback_lock);
+ ret = l2tp_validate_socket(sk, net, tunnel->encap);
+- if (ret < 0)
++ if (ret < 0) {
++ release_sock(sk);
+ goto err_inval_sock;
++ }
+ rcu_assign_sk_user_data(sk, tunnel);
+ write_unlock_bh(&sk->sk_callback_lock);
+
+- sock_hold(sk);
+- tunnel->sock = sk;
+- tunnel->l2tp_net = net;
+-
+- spin_lock_bh(&pn->l2tp_tunnel_idr_lock);
+- idr_replace(&pn->l2tp_tunnel_idr, tunnel, tunnel->tunnel_id);
+- spin_unlock_bh(&pn->l2tp_tunnel_idr_lock);
+-
+ if (tunnel->encap == L2TP_ENCAPTYPE_UDP) {
+ struct udp_tunnel_sock_cfg udp_cfg = {
+ .sk_user_data = tunnel,
+@@ -1512,9 +1505,16 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+
+ tunnel->old_sk_destruct = sk->sk_destruct;
+ sk->sk_destruct = &l2tp_tunnel_destruct;
+- lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class,
+- "l2tp_sock");
+ sk->sk_allocation = GFP_ATOMIC;
++ release_sock(sk);
++
++ sock_hold(sk);
++ tunnel->sock = sk;
++ tunnel->l2tp_net = net;
++
++ spin_lock_bh(&pn->l2tp_tunnel_idr_lock);
++ idr_replace(&pn->l2tp_tunnel_idr, tunnel, tunnel->tunnel_id);
++ spin_unlock_bh(&pn->l2tp_tunnel_idr_lock);
+
+ trace_register_tunnel(tunnel);
+
+--
+2.39.0
+
--- /dev/null
+From feb87ccacef4cfb76ca089000453d580c3754c65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Jan 2023 19:01:36 -0800
+Subject: l2tp: convert l2tp_tunnel_list to idr
+
+From: Cong Wang <cong.wang@bytedance.com>
+
+[ Upstream commit c4d48a58f32c5972174a1d01c33b296fe378cce0 ]
+
+l2tp uses l2tp_tunnel_list to track all registered tunnels and
+to allocate tunnel ID's. IDR can do the same job.
+
+More importantly, with IDR we can hold the ID before a successful
+registration so that we don't need to worry about late error
+handling, it is not easy to rollback socket changes.
+
+This is a preparation for the following fix.
+
+Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Cc: Guillaume Nault <gnault@redhat.com>
+Cc: Jakub Sitnicki <jakub@cloudflare.com>
+Cc: Eric Dumazet <edumazet@google.com>
+Cc: Tom Parkin <tparkin@katalix.com>
+Signed-off-by: Cong Wang <cong.wang@bytedance.com>
+Reviewed-by: Guillaume Nault <gnault@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 0b2c59720e65 ("l2tp: close all race conditions in l2tp_tunnel_register()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/l2tp/l2tp_core.c | 85 ++++++++++++++++++++++----------------------
+ 1 file changed, 42 insertions(+), 43 deletions(-)
+
+diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
+index d22dbd92b709..68d8b2aa6f6d 100644
+--- a/net/l2tp/l2tp_core.c
++++ b/net/l2tp/l2tp_core.c
+@@ -104,9 +104,9 @@ static struct workqueue_struct *l2tp_wq;
+ /* per-net private data for this module */
+ static unsigned int l2tp_net_id;
+ struct l2tp_net {
+- struct list_head l2tp_tunnel_list;
+- /* Lock for write access to l2tp_tunnel_list */
+- spinlock_t l2tp_tunnel_list_lock;
++ /* Lock for write access to l2tp_tunnel_idr */
++ spinlock_t l2tp_tunnel_idr_lock;
++ struct idr l2tp_tunnel_idr;
+ struct hlist_head l2tp_session_hlist[L2TP_HASH_SIZE_2];
+ /* Lock for write access to l2tp_session_hlist */
+ spinlock_t l2tp_session_hlist_lock;
+@@ -208,13 +208,10 @@ struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id)
+ struct l2tp_tunnel *tunnel;
+
+ rcu_read_lock_bh();
+- list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
+- if (tunnel->tunnel_id == tunnel_id &&
+- refcount_inc_not_zero(&tunnel->ref_count)) {
+- rcu_read_unlock_bh();
+-
+- return tunnel;
+- }
++ tunnel = idr_find(&pn->l2tp_tunnel_idr, tunnel_id);
++ if (tunnel && refcount_inc_not_zero(&tunnel->ref_count)) {
++ rcu_read_unlock_bh();
++ return tunnel;
+ }
+ rcu_read_unlock_bh();
+
+@@ -224,13 +221,14 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_get);
+
+ struct l2tp_tunnel *l2tp_tunnel_get_nth(const struct net *net, int nth)
+ {
+- const struct l2tp_net *pn = l2tp_pernet(net);
++ struct l2tp_net *pn = l2tp_pernet(net);
++ unsigned long tunnel_id, tmp;
+ struct l2tp_tunnel *tunnel;
+ int count = 0;
+
+ rcu_read_lock_bh();
+- list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
+- if (++count > nth &&
++ idr_for_each_entry_ul(&pn->l2tp_tunnel_idr, tunnel, tmp, tunnel_id) {
++ if (tunnel && ++count > nth &&
+ refcount_inc_not_zero(&tunnel->ref_count)) {
+ rcu_read_unlock_bh();
+ return tunnel;
+@@ -1229,6 +1227,15 @@ static void l2tp_udp_encap_destroy(struct sock *sk)
+ l2tp_tunnel_delete(tunnel);
+ }
+
++static void l2tp_tunnel_remove(struct net *net, struct l2tp_tunnel *tunnel)
++{
++ struct l2tp_net *pn = l2tp_pernet(net);
++
++ spin_lock_bh(&pn->l2tp_tunnel_idr_lock);
++ idr_remove(&pn->l2tp_tunnel_idr, tunnel->tunnel_id);
++ spin_unlock_bh(&pn->l2tp_tunnel_idr_lock);
++}
++
+ /* Workqueue tunnel deletion function */
+ static void l2tp_tunnel_del_work(struct work_struct *work)
+ {
+@@ -1236,7 +1243,6 @@ static void l2tp_tunnel_del_work(struct work_struct *work)
+ del_work);
+ struct sock *sk = tunnel->sock;
+ struct socket *sock = sk->sk_socket;
+- struct l2tp_net *pn;
+
+ l2tp_tunnel_closeall(tunnel);
+
+@@ -1250,12 +1256,7 @@ static void l2tp_tunnel_del_work(struct work_struct *work)
+ }
+ }
+
+- /* Remove the tunnel struct from the tunnel list */
+- pn = l2tp_pernet(tunnel->l2tp_net);
+- spin_lock_bh(&pn->l2tp_tunnel_list_lock);
+- list_del_rcu(&tunnel->list);
+- spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
+-
++ l2tp_tunnel_remove(tunnel->l2tp_net, tunnel);
+ /* drop initial ref */
+ l2tp_tunnel_dec_refcount(tunnel);
+
+@@ -1457,12 +1458,19 @@ static int l2tp_validate_socket(const struct sock *sk, const struct net *net,
+ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+ struct l2tp_tunnel_cfg *cfg)
+ {
+- struct l2tp_tunnel *tunnel_walk;
+- struct l2tp_net *pn;
++ struct l2tp_net *pn = l2tp_pernet(net);
++ u32 tunnel_id = tunnel->tunnel_id;
+ struct socket *sock;
+ struct sock *sk;
+ int ret;
+
++ spin_lock_bh(&pn->l2tp_tunnel_idr_lock);
++ ret = idr_alloc_u32(&pn->l2tp_tunnel_idr, NULL, &tunnel_id, tunnel_id,
++ GFP_ATOMIC);
++ spin_unlock_bh(&pn->l2tp_tunnel_idr_lock);
++ if (ret)
++ return ret == -ENOSPC ? -EEXIST : ret;
++
+ if (tunnel->fd < 0) {
+ ret = l2tp_tunnel_sock_create(net, tunnel->tunnel_id,
+ tunnel->peer_tunnel_id, cfg,
+@@ -1483,23 +1491,13 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+ rcu_assign_sk_user_data(sk, tunnel);
+ write_unlock_bh(&sk->sk_callback_lock);
+
+- tunnel->l2tp_net = net;
+- pn = l2tp_pernet(net);
+-
+ sock_hold(sk);
+ tunnel->sock = sk;
++ tunnel->l2tp_net = net;
+
+- spin_lock_bh(&pn->l2tp_tunnel_list_lock);
+- list_for_each_entry(tunnel_walk, &pn->l2tp_tunnel_list, list) {
+- if (tunnel_walk->tunnel_id == tunnel->tunnel_id) {
+- spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
+- sock_put(sk);
+- ret = -EEXIST;
+- goto err_sock;
+- }
+- }
+- list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
+- spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
++ spin_lock_bh(&pn->l2tp_tunnel_idr_lock);
++ idr_replace(&pn->l2tp_tunnel_idr, tunnel, tunnel->tunnel_id);
++ spin_unlock_bh(&pn->l2tp_tunnel_idr_lock);
+
+ if (tunnel->encap == L2TP_ENCAPTYPE_UDP) {
+ struct udp_tunnel_sock_cfg udp_cfg = {
+@@ -1525,9 +1523,6 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+
+ return 0;
+
+-err_sock:
+- write_lock_bh(&sk->sk_callback_lock);
+- rcu_assign_sk_user_data(sk, NULL);
+ err_inval_sock:
+ write_unlock_bh(&sk->sk_callback_lock);
+
+@@ -1536,6 +1531,7 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+ else
+ sockfd_put(sock);
+ err:
++ l2tp_tunnel_remove(net, tunnel);
+ return ret;
+ }
+ EXPORT_SYMBOL_GPL(l2tp_tunnel_register);
+@@ -1649,8 +1645,8 @@ static __net_init int l2tp_init_net(struct net *net)
+ struct l2tp_net *pn = net_generic(net, l2tp_net_id);
+ int hash;
+
+- INIT_LIST_HEAD(&pn->l2tp_tunnel_list);
+- spin_lock_init(&pn->l2tp_tunnel_list_lock);
++ idr_init(&pn->l2tp_tunnel_idr);
++ spin_lock_init(&pn->l2tp_tunnel_idr_lock);
+
+ for (hash = 0; hash < L2TP_HASH_SIZE_2; hash++)
+ INIT_HLIST_HEAD(&pn->l2tp_session_hlist[hash]);
+@@ -1664,11 +1660,13 @@ static __net_exit void l2tp_exit_net(struct net *net)
+ {
+ struct l2tp_net *pn = l2tp_pernet(net);
+ struct l2tp_tunnel *tunnel = NULL;
++ unsigned long tunnel_id, tmp;
+ int hash;
+
+ rcu_read_lock_bh();
+- list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
+- l2tp_tunnel_delete(tunnel);
++ idr_for_each_entry_ul(&pn->l2tp_tunnel_idr, tunnel, tmp, tunnel_id) {
++ if (tunnel)
++ l2tp_tunnel_delete(tunnel);
+ }
+ rcu_read_unlock_bh();
+
+@@ -1678,6 +1676,7 @@ static __net_exit void l2tp_exit_net(struct net *net)
+
+ for (hash = 0; hash < L2TP_HASH_SIZE_2; hash++)
+ WARN_ON_ONCE(!hlist_empty(&pn->l2tp_session_hlist[hash]));
++ idr_destroy(&pn->l2tp_tunnel_idr);
+ }
+
+ static struct pernet_operations l2tp_net_ops = {
+--
+2.39.0
+
--- /dev/null
+From 111eb58d9e27e30e6d7ce9f4b594accc6f0016d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 09:54:26 +0100
+Subject: l2tp: Don't sleep and disable BH under writer-side sk_callback_lock
+
+From: Jakub Sitnicki <jakub@cloudflare.com>
+
+[ Upstream commit af295e854a4e3813ffbdef26dbb6a4d6226c3ea1 ]
+
+When holding a reader-writer spin lock we cannot sleep. Calling
+setup_udp_tunnel_sock() with write lock held violates this rule, because we
+end up calling percpu_down_read(), which might sleep, as syzbot reports
+[1]:
+
+ __might_resched.cold+0x222/0x26b kernel/sched/core.c:9890
+ percpu_down_read include/linux/percpu-rwsem.h:49 [inline]
+ cpus_read_lock+0x1b/0x140 kernel/cpu.c:310
+ static_key_slow_inc+0x12/0x20 kernel/jump_label.c:158
+ udp_tunnel_encap_enable include/net/udp_tunnel.h:187 [inline]
+ setup_udp_tunnel_sock+0x43d/0x550 net/ipv4/udp_tunnel_core.c:81
+ l2tp_tunnel_register+0xc51/0x1210 net/l2tp/l2tp_core.c:1509
+ pppol2tp_connect+0xcdc/0x1a10 net/l2tp/l2tp_ppp.c:723
+
+Trim the writer-side critical section for sk_callback_lock down to the
+minimum, so that it covers only operations on sk_user_data.
+
+Also, when grabbing the sk_callback_lock, we always need to disable BH, as
+Eric points out. Failing to do so leads to deadlocks because we acquire
+sk_callback_lock in softirq context, which can get stuck waiting on us if:
+
+1) it runs on the same CPU, or
+
+ CPU0
+ ----
+ lock(clock-AF_INET6);
+ <Interrupt>
+ lock(clock-AF_INET6);
+
+2) lock ordering leads to priority inversion
+
+ CPU0 CPU1
+ ---- ----
+ lock(clock-AF_INET6);
+ local_irq_disable();
+ lock(&tcp_hashinfo.bhash[i].lock);
+ lock(clock-AF_INET6);
+ <Interrupt>
+ lock(&tcp_hashinfo.bhash[i].lock);
+
+... as syzbot reports [2,3]. Use the _bh variants for write_(un)lock.
+
+[1] https://lore.kernel.org/netdev/0000000000004e78ec05eda79749@google.com/
+[2] https://lore.kernel.org/netdev/000000000000e38b6605eda76f98@google.com/
+[3] https://lore.kernel.org/netdev/000000000000dfa31e05eda76f75@google.com/
+
+v2:
+- Check and set sk_user_data while holding sk_callback_lock for both
+ L2TP encapsulation types (IP and UDP) (Tetsuo)
+
+Cc: Tom Parkin <tparkin@katalix.com>
+Cc: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
+Fixes: b68777d54fac ("l2tp: Serialize access to sk_user_data with sk_callback_lock")
+Reported-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot+703d9e154b3b58277261@syzkaller.appspotmail.com
+Reported-by: syzbot+50680ced9e98a61f7698@syzkaller.appspotmail.com
+Reported-by: syzbot+de987172bb74a381879b@syzkaller.appspotmail.com
+Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 0b2c59720e65 ("l2tp: close all race conditions in l2tp_tunnel_register()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/l2tp/l2tp_core.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
+index c77032638a06..d22dbd92b709 100644
+--- a/net/l2tp/l2tp_core.c
++++ b/net/l2tp/l2tp_core.c
+@@ -1476,11 +1476,12 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+ }
+
+ sk = sock->sk;
+- write_lock(&sk->sk_callback_lock);
+-
++ write_lock_bh(&sk->sk_callback_lock);
+ ret = l2tp_validate_socket(sk, net, tunnel->encap);
+ if (ret < 0)
+- goto err_sock;
++ goto err_inval_sock;
++ rcu_assign_sk_user_data(sk, tunnel);
++ write_unlock_bh(&sk->sk_callback_lock);
+
+ tunnel->l2tp_net = net;
+ pn = l2tp_pernet(net);
+@@ -1509,8 +1510,6 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+ };
+
+ setup_udp_tunnel_sock(net, sock, &udp_cfg);
+- } else {
+- rcu_assign_sk_user_data(sk, tunnel);
+ }
+
+ tunnel->old_sk_destruct = sk->sk_destruct;
+@@ -1524,16 +1523,18 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+ if (tunnel->fd >= 0)
+ sockfd_put(sock);
+
+- write_unlock(&sk->sk_callback_lock);
+ return 0;
+
+ err_sock:
++ write_lock_bh(&sk->sk_callback_lock);
++ rcu_assign_sk_user_data(sk, NULL);
++err_inval_sock:
++ write_unlock_bh(&sk->sk_callback_lock);
++
+ if (tunnel->fd < 0)
+ sock_release(sock);
+ else
+ sockfd_put(sock);
+-
+- write_unlock(&sk->sk_callback_lock);
+ err:
+ return ret;
+ }
+--
+2.39.0
+
--- /dev/null
+From b185efcbec0347d2cb4650c4a89569e64d71fa6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Jan 2023 11:01:31 +0000
+Subject: l2tp: prevent lockdep issue in l2tp_tunnel_register()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b9fb10d131b8c84af9bb14e2078d5c63600c7dea ]
+
+lockdep complains with the following lock/unlock sequence:
+
+ lock_sock(sk);
+ write_lock_bh(&sk->sk_callback_lock);
+[1] release_sock(sk);
+[2] write_unlock_bh(&sk->sk_callback_lock);
+
+We need to swap [1] and [2] to fix this issue.
+
+Fixes: 0b2c59720e65 ("l2tp: close all race conditions in l2tp_tunnel_register()")
+Reported-by: syzbot+bbd35b345c7cab0d9a08@syzkaller.appspotmail.com
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Link: https://lore.kernel.org/netdev/20230114030137.672706-1-xiyou.wangcong@gmail.com/T/#m1164ff20628671b0f326a24cb106ab3239c70ce3
+Cc: Cong Wang <cong.wang@bytedance.com>
+Cc: Guillaume Nault <gnault@redhat.com>
+Reviewed-by: Guillaume Nault <gnault@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/l2tp/l2tp_core.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
+index 4c5227048be4..a2b13e213e06 100644
+--- a/net/l2tp/l2tp_core.c
++++ b/net/l2tp/l2tp_core.c
+@@ -1485,10 +1485,8 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+ lock_sock(sk);
+ write_lock_bh(&sk->sk_callback_lock);
+ ret = l2tp_validate_socket(sk, net, tunnel->encap);
+- if (ret < 0) {
+- release_sock(sk);
++ if (ret < 0)
+ goto err_inval_sock;
+- }
+ rcu_assign_sk_user_data(sk, tunnel);
+ write_unlock_bh(&sk->sk_callback_lock);
+
+@@ -1525,6 +1523,7 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+
+ err_inval_sock:
+ write_unlock_bh(&sk->sk_callback_lock);
++ release_sock(sk);
+
+ if (tunnel->fd < 0)
+ sock_release(sock);
+--
+2.39.0
+
--- /dev/null
+From d547235ce4039b9a33fa27299503018cf6cde778 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 20:16:19 +0100
+Subject: l2tp: Serialize access to sk_user_data with sk_callback_lock
+
+From: Jakub Sitnicki <jakub@cloudflare.com>
+
+[ Upstream commit b68777d54fac21fc833ec26ea1a2a84f975ab035 ]
+
+sk->sk_user_data has multiple users, which are not compatible with each
+other. Writers must synchronize by grabbing the sk->sk_callback_lock.
+
+l2tp currently fails to grab the lock when modifying the underlying tunnel
+socket fields. Fix it by adding appropriate locking.
+
+We err on the side of safety and grab the sk_callback_lock also inside the
+sk_destruct callback overridden by l2tp, even though there should be no
+refs allowing access to the sock at the time when sk_destruct gets called.
+
+v4:
+- serialize write to sk_user_data in l2tp sk_destruct
+
+v3:
+- switch from sock lock to sk_callback_lock
+- document write-protection for sk_user_data
+
+v2:
+- update Fixes to point to origin of the bug
+- use real names in Reported/Tested-by tags
+
+Cc: Tom Parkin <tparkin@katalix.com>
+Fixes: 3557baabf280 ("[L2TP]: PPP over L2TP driver core")
+Reported-by: Haowei Yan <g1042620637@gmail.com>
+Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 0b2c59720e65 ("l2tp: close all race conditions in l2tp_tunnel_register()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sock.h | 2 +-
+ net/l2tp/l2tp_core.c | 19 +++++++++++++------
+ 2 files changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/include/net/sock.h b/include/net/sock.h
+index e1a303e4f0f7..3e9db5146765 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -323,7 +323,7 @@ struct bpf_local_storage;
+ * @sk_tskey: counter to disambiguate concurrent tstamp requests
+ * @sk_zckey: counter to order MSG_ZEROCOPY notifications
+ * @sk_socket: Identd and reporting IO signals
+- * @sk_user_data: RPC layer private data
++ * @sk_user_data: RPC layer private data. Write-protected by @sk_callback_lock.
+ * @sk_frag: cached page frag
+ * @sk_peek_off: current peek_offset value
+ * @sk_send_head: front of stuff to transmit
+diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
+index 93271a2632b8..c77032638a06 100644
+--- a/net/l2tp/l2tp_core.c
++++ b/net/l2tp/l2tp_core.c
+@@ -1150,8 +1150,10 @@ static void l2tp_tunnel_destruct(struct sock *sk)
+ }
+
+ /* Remove hooks into tunnel socket */
++ write_lock_bh(&sk->sk_callback_lock);
+ sk->sk_destruct = tunnel->old_sk_destruct;
+ sk->sk_user_data = NULL;
++ write_unlock_bh(&sk->sk_callback_lock);
+
+ /* Call the original destructor */
+ if (sk->sk_destruct)
+@@ -1471,16 +1473,18 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+ sock = sockfd_lookup(tunnel->fd, &ret);
+ if (!sock)
+ goto err;
+-
+- ret = l2tp_validate_socket(sock->sk, net, tunnel->encap);
+- if (ret < 0)
+- goto err_sock;
+ }
+
++ sk = sock->sk;
++ write_lock(&sk->sk_callback_lock);
++
++ ret = l2tp_validate_socket(sk, net, tunnel->encap);
++ if (ret < 0)
++ goto err_sock;
++
+ tunnel->l2tp_net = net;
+ pn = l2tp_pernet(net);
+
+- sk = sock->sk;
+ sock_hold(sk);
+ tunnel->sock = sk;
+
+@@ -1506,7 +1510,7 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+
+ setup_udp_tunnel_sock(net, sock, &udp_cfg);
+ } else {
+- sk->sk_user_data = tunnel;
++ rcu_assign_sk_user_data(sk, tunnel);
+ }
+
+ tunnel->old_sk_destruct = sk->sk_destruct;
+@@ -1520,6 +1524,7 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+ if (tunnel->fd >= 0)
+ sockfd_put(sock);
+
++ write_unlock(&sk->sk_callback_lock);
+ return 0;
+
+ err_sock:
+@@ -1527,6 +1532,8 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+ sock_release(sock);
+ else
+ sockfd_put(sock);
++
++ write_unlock(&sk->sk_callback_lock);
+ err:
+ return ret;
+ }
+--
+2.39.0
+
--- /dev/null
+From eb503a41bdd132f33628a2654a7337f06a3ccca3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Jan 2023 19:44:47 +0100
+Subject: lockref: stop doing cpu_relax in the cmpxchg loop
+
+From: Mateusz Guzik <mjguzik@gmail.com>
+
+[ Upstream commit f5fe24ef17b5fbe6db49534163e77499fb10ae8c ]
+
+On the x86-64 architecture even a failing cmpxchg grants exclusive
+access to the cacheline, making it preferable to retry the failed op
+immediately instead of stalling with the pause instruction.
+
+To illustrate the impact, below are benchmark results obtained by
+running various will-it-scale tests on top of the 6.2-rc3 kernel and
+Cascade Lake (2 sockets * 24 cores * 2 threads) CPU.
+
+All results in ops/s. Note there is some variance in re-runs, but the
+code is consistently faster when contention is present.
+
+ open3 ("Same file open/close"):
+ proc stock no-pause
+ 1 805603 814942 (+%1)
+ 2 1054980 1054781 (-0%)
+ 8 1544802 1822858 (+18%)
+ 24 1191064 2199665 (+84%)
+ 48 851582 1469860 (+72%)
+ 96 609481 1427170 (+134%)
+
+ fstat2 ("Same file fstat"):
+ proc stock no-pause
+ 1 3013872 3047636 (+1%)
+ 2 4284687 4400421 (+2%)
+ 8 3257721 5530156 (+69%)
+ 24 2239819 5466127 (+144%)
+ 48 1701072 5256609 (+209%)
+ 96 1269157 6649326 (+423%)
+
+Additionally, a kernel with a private patch to help access() scalability:
+access2 ("Same file access"):
+
+ proc stock patched patched
+ +nopause
+ 24 2378041 2005501 5370335 (-15% / +125%)
+
+That is, fixing the problems in access itself *reduces* scalability
+after the cacheline ping-pong only happens in lockref with the pause
+instruction.
+
+Note that fstat and access benchmarks are not currently integrated into
+will-it-scale, but interested parties can find them in pull requests to
+said project.
+
+Code at hand has a rather tortured history. First modification showed
+up in commit d472d9d98b46 ("lockref: Relax in cmpxchg loop"), written
+with Itanium in mind. Later it got patched up to use an arch-dependent
+macro to stop doing it on s390 where it caused a significant regression.
+Said macro had undergone revisions and was ultimately eliminated later,
+going back to cpu_relax.
+
+While I intended to only remove cpu_relax for x86-64, I got the
+following comment from Linus:
+
+ I would actually prefer just removing it entirely and see if
+ somebody else hollers. You have the numbers to prove it hurts on
+ real hardware, and I don't think we have any numbers to the
+ contrary.
+
+ So I think it's better to trust the numbers and remove it as a
+ failure, than say "let's just remove it on x86-64 and leave
+ everybody else with the potentially broken code"
+
+Additionally, Will Deacon (maintainer of the arm64 port, one of the
+architectures previously benchmarked):
+
+ So, from the arm64 side of the fence, I'm perfectly happy just
+ removing the cpu_relax() calls from lockref.
+
+As such, come back full circle in history and whack it altogether.
+
+Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
+Link: https://lore.kernel.org/all/CAGudoHHx0Nqg6DE70zAVA75eV-HXfWyhVMWZ-aSeOofkA_=WdA@mail.gmail.com/
+Acked-by: Tony Luck <tony.luck@intel.com> # ia64
+Acked-by: Nicholas Piggin <npiggin@gmail.com> # powerpc
+Acked-by: Will Deacon <will@kernel.org> # arm64
+Acked-by: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/lockref.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/lib/lockref.c b/lib/lockref.c
+index 5b34bbd3eba8..81ac5f355242 100644
+--- a/lib/lockref.c
++++ b/lib/lockref.c
+@@ -24,7 +24,6 @@
+ } \
+ if (!--retry) \
+ break; \
+- cpu_relax(); \
+ } \
+ } while (0)
+
+--
+2.39.0
+
--- /dev/null
+From 888bd3fd145a6abf2d3a5c8489184f2797af8064 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Nov 2022 15:37:57 +0800
+Subject: memory: atmel-sdramc: Fix missing clk_disable_unprepare in
+ atmel_ramc_probe()
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit 340cb392a038cf70540a4cdf2e98a247c66b6df4 ]
+
+The clk_disable_unprepare() should be called in the error handling
+of caps->has_mpddr_clk, fix it by replacing devm_clk_get and
+clk_prepare_enable by devm_clk_get_enabled.
+
+Fixes: e81b6abebc87 ("memory: add a driver for atmel ram controllers")
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Link: https://lore.kernel.org/r/20221125073757.3535219-1-cuigaosheng1@huawei.com
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/memory/atmel-sdramc.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/memory/atmel-sdramc.c b/drivers/memory/atmel-sdramc.c
+index 9c49d00c2a96..ea6e9e1eaf04 100644
+--- a/drivers/memory/atmel-sdramc.c
++++ b/drivers/memory/atmel-sdramc.c
+@@ -47,19 +47,17 @@ static int atmel_ramc_probe(struct platform_device *pdev)
+ caps = of_device_get_match_data(&pdev->dev);
+
+ if (caps->has_ddrck) {
+- clk = devm_clk_get(&pdev->dev, "ddrck");
++ clk = devm_clk_get_enabled(&pdev->dev, "ddrck");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+- clk_prepare_enable(clk);
+ }
+
+ if (caps->has_mpddr_clk) {
+- clk = devm_clk_get(&pdev->dev, "mpddr");
++ clk = devm_clk_get_enabled(&pdev->dev, "mpddr");
+ if (IS_ERR(clk)) {
+ pr_err("AT91 RAMC: couldn't get mpddr clock\n");
+ return PTR_ERR(clk);
+ }
+- clk_prepare_enable(clk);
+ }
+
+ return 0;
+--
+2.39.0
+
--- /dev/null
+From 626bc8264b39f17461ce202e9777f7e1c4cbc358 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Nov 2022 12:49:11 +0800
+Subject: memory: mvebu-devbus: Fix missing clk_disable_unprepare in
+ mvebu_devbus_probe()
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit cb8fd6f75775165390ededea8799b60d93d9fe3e ]
+
+The clk_disable_unprepare() should be called in the error handling
+of devbus_get_timing_params() and of_platform_populate(), fix it by
+replacing devm_clk_get and clk_prepare_enable by devm_clk_get_enabled.
+
+Fixes: e81b6abebc87 ("memory: add a driver for atmel ram controllers")
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Link: https://lore.kernel.org/r/20221126044911.7226-1-cuigaosheng1@huawei.com
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/memory/mvebu-devbus.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/memory/mvebu-devbus.c b/drivers/memory/mvebu-devbus.c
+index 8450638e8670..efc6c08db2b7 100644
+--- a/drivers/memory/mvebu-devbus.c
++++ b/drivers/memory/mvebu-devbus.c
+@@ -280,10 +280,9 @@ static int mvebu_devbus_probe(struct platform_device *pdev)
+ if (IS_ERR(devbus->base))
+ return PTR_ERR(devbus->base);
+
+- clk = devm_clk_get(&pdev->dev, NULL);
++ clk = devm_clk_get_enabled(&pdev->dev, NULL);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+- clk_prepare_enable(clk);
+
+ /*
+ * Obtain clock period in picoseconds,
+--
+2.39.0
+
--- /dev/null
+From af33a5aee3a208b4fbab1625fd1cdbbcaf6bd258 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Nov 2022 09:37:52 +0530
+Subject: memory: tegra: Remove clients SID override programming
+
+From: Ashish Mhetre <amhetre@nvidia.com>
+
+[ Upstream commit ef86b2c2807f41c045e5534d8513a8b83f63bc39 ]
+
+On newer Tegra releases, early boot SID override programming and SID
+override programming during resume is handled by bootloader.
+In the function tegra186_mc_program_sid() which is getting removed, SID
+override register of all clients is written without checking if secure
+firmware has allowed write on it or not. If write is disabled by secure
+firmware then it can lead to errors coming from secure firmware and hang
+in kernel boot.
+Also, SID override is programmed on-demand during probe_finalize() call
+of IOMMU which is done in tegra186_mc_client_sid_override() in this same
+file. This function does it correctly by checking if write is permitted
+on SID override register. It also checks if SID override register is
+already written with correct value and skips re-writing it in that case.
+
+Fixes: 393d66fd2cac ("memory: tegra: Implement SID override programming")
+Signed-off-by: Ashish Mhetre <amhetre@nvidia.com>
+Acked-by: Thierry Reding <treding@nvidia.com>
+Link: https://lore.kernel.org/r/20221125040752.12627-1-amhetre@nvidia.com
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/memory/tegra/tegra186.c | 36 ---------------------------------
+ 1 file changed, 36 deletions(-)
+
+diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c
+index 3d153881abc1..4bed0e54fd45 100644
+--- a/drivers/memory/tegra/tegra186.c
++++ b/drivers/memory/tegra/tegra186.c
+@@ -20,32 +20,6 @@
+ #define MC_SID_STREAMID_SECURITY_WRITE_ACCESS_DISABLED BIT(16)
+ #define MC_SID_STREAMID_SECURITY_OVERRIDE BIT(8)
+
+-static void tegra186_mc_program_sid(struct tegra_mc *mc)
+-{
+- unsigned int i;
+-
+- for (i = 0; i < mc->soc->num_clients; i++) {
+- const struct tegra_mc_client *client = &mc->soc->clients[i];
+- u32 override, security;
+-
+- override = readl(mc->regs + client->regs.sid.override);
+- security = readl(mc->regs + client->regs.sid.security);
+-
+- dev_dbg(mc->dev, "client %s: override: %x security: %x\n",
+- client->name, override, security);
+-
+- dev_dbg(mc->dev, "setting SID %u for %s\n", client->sid,
+- client->name);
+- writel(client->sid, mc->regs + client->regs.sid.override);
+-
+- override = readl(mc->regs + client->regs.sid.override);
+- security = readl(mc->regs + client->regs.sid.security);
+-
+- dev_dbg(mc->dev, "client %s: override: %x security: %x\n",
+- client->name, override, security);
+- }
+-}
+-
+ static int tegra186_mc_probe(struct tegra_mc *mc)
+ {
+ int err;
+@@ -54,8 +28,6 @@ static int tegra186_mc_probe(struct tegra_mc *mc)
+ if (err < 0)
+ return err;
+
+- tegra186_mc_program_sid(mc);
+-
+ return 0;
+ }
+
+@@ -64,13 +36,6 @@ static void tegra186_mc_remove(struct tegra_mc *mc)
+ of_platform_depopulate(mc->dev);
+ }
+
+-static int tegra186_mc_resume(struct tegra_mc *mc)
+-{
+- tegra186_mc_program_sid(mc);
+-
+- return 0;
+-}
+-
+ #if IS_ENABLED(CONFIG_IOMMU_API)
+ static void tegra186_mc_client_sid_override(struct tegra_mc *mc,
+ const struct tegra_mc_client *client,
+@@ -142,7 +107,6 @@ static int tegra186_mc_probe_device(struct tegra_mc *mc, struct device *dev)
+ const struct tegra_mc_ops tegra186_mc_ops = {
+ .probe = tegra186_mc_probe,
+ .remove = tegra186_mc_remove,
+- .resume = tegra186_mc_resume,
+ .probe_device = tegra186_mc_probe_device,
+ };
+
+--
+2.39.0
+
--- /dev/null
+From 371fe071edbdad4de34426abd911f27b1e7cfd25 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 23:17:35 +0530
+Subject: net: dsa: microchip: ksz9477: port map correction in ALU table entry
+ register
+
+From: Rakesh Sankaranarayanan <rakesh.sankaranarayanan@microchip.com>
+
+[ Upstream commit 6c977c5c2e4c5d8ad1b604724cc344e38f96fe9b ]
+
+ALU table entry 2 register in KSZ9477 have bit positions reserved for
+forwarding port map. This field is referred in ksz9477_fdb_del() for
+clearing forward port map and alu table.
+
+But current fdb_del refer ALU table entry 3 register for accessing forward
+port map. Update ksz9477_fdb_del() to get forward port map from correct
+alu table entry register.
+
+With this bug, issue can be observed while deleting static MAC entries.
+Delete any specific MAC entry using "bridge fdb del" command. This should
+clear all the specified MAC entries. But it is observed that entries with
+self static alone are retained.
+
+Tested on LAN9370 EVB since ksz9477_fdb_del() is used common across
+LAN937x and KSZ series.
+
+Fixes: b987e98e50ab ("dsa: add DSA switch driver for Microchip KSZ9477")
+Signed-off-by: Rakesh Sankaranarayanan <rakesh.sankaranarayanan@microchip.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Link: https://lore.kernel.org/r/20230118174735.702377-1-rakesh.sankaranarayanan@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/microchip/ksz9477.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c
+index 379b38c5844f..bf788e17f408 100644
+--- a/drivers/net/dsa/microchip/ksz9477.c
++++ b/drivers/net/dsa/microchip/ksz9477.c
+@@ -675,10 +675,10 @@ static int ksz9477_port_fdb_del(struct dsa_switch *ds, int port,
+ ksz_read32(dev, REG_SW_ALU_VAL_D, &alu_table[3]);
+
+ /* clear forwarding port */
+- alu_table[2] &= ~BIT(port);
++ alu_table[1] &= ~BIT(port);
+
+ /* if there is no port to forward, clear table */
+- if ((alu_table[2] & ALU_V_PORT_MAP) == 0) {
++ if ((alu_table[1] & ALU_V_PORT_MAP) == 0) {
+ alu_table[0] = 0;
+ alu_table[1] = 0;
+ alu_table[2] = 0;
+--
+2.39.0
+
--- /dev/null
+From f8808b9caddc826556ebe8d46f98b595b7a68c56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Jan 2023 12:54:40 +0200
+Subject: net: enetc: avoid deadlock in enetc_tx_onestep_tstamp()
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 3c463721a73bdb57a913e0d3124677a3758886fc ]
+
+This lockdep splat says it better than I could:
+
+================================
+WARNING: inconsistent lock state
+6.2.0-rc2-07010-ga9b9500ffaac-dirty #967 Not tainted
+--------------------------------
+inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage.
+kworker/1:3/179 [HC0[0]:SC0[0]:HE1:SE1] takes:
+ffff3ec4036ce098 (_xmit_ETHER#2){+.?.}-{3:3}, at: netif_freeze_queues+0x5c/0xc0
+{IN-SOFTIRQ-W} state was registered at:
+ _raw_spin_lock+0x5c/0xc0
+ sch_direct_xmit+0x148/0x37c
+ __dev_queue_xmit+0x528/0x111c
+ ip6_finish_output2+0x5ec/0xb7c
+ ip6_finish_output+0x240/0x3f0
+ ip6_output+0x78/0x360
+ ndisc_send_skb+0x33c/0x85c
+ ndisc_send_rs+0x54/0x12c
+ addrconf_rs_timer+0x154/0x260
+ call_timer_fn+0xb8/0x3a0
+ __run_timers.part.0+0x214/0x26c
+ run_timer_softirq+0x3c/0x74
+ __do_softirq+0x14c/0x5d8
+ ____do_softirq+0x10/0x20
+ call_on_irq_stack+0x2c/0x5c
+ do_softirq_own_stack+0x1c/0x30
+ __irq_exit_rcu+0x168/0x1a0
+ irq_exit_rcu+0x10/0x40
+ el1_interrupt+0x38/0x64
+irq event stamp: 7825
+hardirqs last enabled at (7825): [<ffffdf1f7200cae4>] exit_to_kernel_mode+0x34/0x130
+hardirqs last disabled at (7823): [<ffffdf1f708105f0>] __do_softirq+0x550/0x5d8
+softirqs last enabled at (7824): [<ffffdf1f7081050c>] __do_softirq+0x46c/0x5d8
+softirqs last disabled at (7811): [<ffffdf1f708166e0>] ____do_softirq+0x10/0x20
+
+other info that might help us debug this:
+ Possible unsafe locking scenario:
+
+ CPU0
+ ----
+ lock(_xmit_ETHER#2);
+ <Interrupt>
+ lock(_xmit_ETHER#2);
+
+ *** DEADLOCK ***
+
+3 locks held by kworker/1:3/179:
+ #0: ffff3ec400004748 ((wq_completion)events){+.+.}-{0:0}, at: process_one_work+0x1f4/0x6c0
+ #1: ffff80000a0bbdc8 ((work_completion)(&priv->tx_onestep_tstamp)){+.+.}-{0:0}, at: process_one_work+0x1f4/0x6c0
+ #2: ffff3ec4036cd438 (&dev->tx_global_lock){+.+.}-{3:3}, at: netif_tx_lock+0x1c/0x34
+
+Workqueue: events enetc_tx_onestep_tstamp
+Call trace:
+ print_usage_bug.part.0+0x208/0x22c
+ mark_lock+0x7f0/0x8b0
+ __lock_acquire+0x7c4/0x1ce0
+ lock_acquire.part.0+0xe0/0x220
+ lock_acquire+0x68/0x84
+ _raw_spin_lock+0x5c/0xc0
+ netif_freeze_queues+0x5c/0xc0
+ netif_tx_lock+0x24/0x34
+ enetc_tx_onestep_tstamp+0x20/0x100
+ process_one_work+0x28c/0x6c0
+ worker_thread+0x74/0x450
+ kthread+0x118/0x11c
+
+but I'll say it anyway: the enetc_tx_onestep_tstamp() work item runs in
+process context, therefore with softirqs enabled (i.o.w., it can be
+interrupted by a softirq). If we hold the netif_tx_lock() when there is
+an interrupt, and the NET_TX softirq then gets scheduled, this will take
+the netif_tx_lock() a second time and deadlock the kernel.
+
+To solve this, use netif_tx_lock_bh(), which blocks softirqs from
+running.
+
+Fixes: 7294380c5211 ("enetc: support PTP Sync packet one-step timestamping")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
+Link: https://lore.kernel.org/r/20230112105440.1786799-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/enetc/enetc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
+index adccb14c1644..8b7c93447770 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -2000,14 +2000,14 @@ static void enetc_tx_onestep_tstamp(struct work_struct *work)
+
+ priv = container_of(work, struct enetc_ndev_priv, tx_onestep_tstamp);
+
+- netif_tx_lock(priv->ndev);
++ netif_tx_lock_bh(priv->ndev);
+
+ clear_bit_unlock(ENETC_TX_ONESTEP_TSTAMP_IN_PROGRESS, &priv->flags);
+ skb = skb_dequeue(&priv->tx_skbs);
+ if (skb)
+ enetc_start_xmit(skb, priv->ndev);
+
+- netif_tx_unlock(priv->ndev);
++ netif_tx_unlock_bh(priv->ndev);
+ }
+
+ static void enetc_tx_onestep_tstamp_init(struct enetc_ndev_priv *priv)
+--
+2.39.0
+
--- /dev/null
+From e4c26a01eb3239b18663bdd66b05cc5cd85f1dc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 Jan 2023 17:59:24 +0000
+Subject: net: ipa: disable ipa interrupt during suspend
+
+From: Caleb Connolly <caleb.connolly@linaro.org>
+
+[ Upstream commit 9ec9b2a30853ba843b70ea16f196e5fe3327be5f ]
+
+The IPA interrupt can fire when pm_runtime is disabled due to it racing
+with the PM suspend/resume code. This causes a splat in the interrupt
+handler when it tries to call pm_runtime_get().
+
+Explicitly disable the interrupt in our ->suspend callback, and
+re-enable it in ->resume to avoid this. If there is an interrupt pending
+it will be handled after resuming. The interrupt is a wake_irq, as a
+result even when disabled if it fires it will cause the system to wake
+from suspend as well as cancel any suspend transition that may be in
+progress. If there is an interrupt pending, the ipa_isr_thread handler
+will be called after resuming.
+
+Fixes: 1aac309d3207 ("net: ipa: use autosuspend")
+Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
+Reviewed-by: Alex Elder <elder@linaro.org>
+Link: https://lore.kernel.org/r/20230115175925.465918-1-caleb.connolly@linaro.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ipa/ipa_interrupt.c | 10 ++++++++++
+ drivers/net/ipa/ipa_interrupt.h | 16 ++++++++++++++++
+ drivers/net/ipa/ipa_power.c | 17 +++++++++++++++++
+ 3 files changed, 43 insertions(+)
+
+diff --git a/drivers/net/ipa/ipa_interrupt.c b/drivers/net/ipa/ipa_interrupt.c
+index b35170a93b0f..0c9ff8c055a0 100644
+--- a/drivers/net/ipa/ipa_interrupt.c
++++ b/drivers/net/ipa/ipa_interrupt.c
+@@ -122,6 +122,16 @@ static irqreturn_t ipa_isr_thread(int irq, void *dev_id)
+ return IRQ_HANDLED;
+ }
+
++void ipa_interrupt_irq_disable(struct ipa *ipa)
++{
++ disable_irq(ipa->interrupt->irq);
++}
++
++void ipa_interrupt_irq_enable(struct ipa *ipa)
++{
++ enable_irq(ipa->interrupt->irq);
++}
++
+ /* Common function used to enable/disable TX_SUSPEND for an endpoint */
+ static void ipa_interrupt_suspend_control(struct ipa_interrupt *interrupt,
+ u32 endpoint_id, bool enable)
+diff --git a/drivers/net/ipa/ipa_interrupt.h b/drivers/net/ipa/ipa_interrupt.h
+index 231390cea52a..16aa84ee0094 100644
+--- a/drivers/net/ipa/ipa_interrupt.h
++++ b/drivers/net/ipa/ipa_interrupt.h
+@@ -85,6 +85,22 @@ void ipa_interrupt_suspend_clear_all(struct ipa_interrupt *interrupt);
+ */
+ void ipa_interrupt_simulate_suspend(struct ipa_interrupt *interrupt);
+
++/**
++ * ipa_interrupt_irq_enable() - Enable IPA interrupts
++ * @ipa: IPA pointer
++ *
++ * This enables the IPA interrupt line
++ */
++void ipa_interrupt_irq_enable(struct ipa *ipa);
++
++/**
++ * ipa_interrupt_irq_disable() - Disable IPA interrupts
++ * @ipa: IPA pointer
++ *
++ * This disables the IPA interrupt line
++ */
++void ipa_interrupt_irq_disable(struct ipa *ipa);
++
+ /**
+ * ipa_interrupt_config() - Configure the IPA interrupt framework
+ * @ipa: IPA pointer
+diff --git a/drivers/net/ipa/ipa_power.c b/drivers/net/ipa/ipa_power.c
+index f2989aac47a6..07fb367cfc99 100644
+--- a/drivers/net/ipa/ipa_power.c
++++ b/drivers/net/ipa/ipa_power.c
+@@ -277,6 +277,17 @@ static int ipa_suspend(struct device *dev)
+
+ __set_bit(IPA_POWER_FLAG_SYSTEM, ipa->power->flags);
+
++ /* Increment the disable depth to ensure that the IRQ won't
++ * be re-enabled until the matching _enable call in
++ * ipa_resume(). We do this to ensure that the interrupt
++ * handler won't run whilst PM runtime is disabled.
++ *
++ * Note that disabling the IRQ is NOT the same as disabling
++ * irq wake. If wakeup is enabled for the IPA then the IRQ
++ * will still cause the system to wake up, see irq_set_irq_wake().
++ */
++ ipa_interrupt_irq_disable(ipa);
++
+ return pm_runtime_force_suspend(dev);
+ }
+
+@@ -289,6 +300,12 @@ static int ipa_resume(struct device *dev)
+
+ __clear_bit(IPA_POWER_FLAG_SYSTEM, ipa->power->flags);
+
++ /* Now that PM runtime is enabled again it's safe
++ * to turn the IRQ back on and process any data
++ * that was received during suspend.
++ */
++ ipa_interrupt_irq_enable(ipa);
++
+ return ret;
+ }
+
+--
+2.39.0
+
--- /dev/null
+From edde9e025ed46f27974e63b9b706939f1696b378 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Jan 2023 15:41:33 -0600
+Subject: net: macb: fix PTP TX timestamp failure due to packet padding
+
+From: Robert Hancock <robert.hancock@calian.com>
+
+[ Upstream commit 7b90f5a665acd46efbbfa677a3a3a18d01ad6487 ]
+
+PTP TX timestamp handling was observed to be broken with this driver
+when using the raw Layer 2 PTP encapsulation. ptp4l was not receiving
+the expected TX timestamp after transmitting a packet, causing it to
+enter a failure state.
+
+The problem appears to be due to the way that the driver pads packets
+which are smaller than the Ethernet minimum of 60 bytes. If headroom
+space was available in the SKB, this caused the driver to move the data
+back to utilize it. However, this appears to cause other data references
+in the SKB to become inconsistent. In particular, this caused the
+ptp_one_step_sync function to later (in the TX completion path) falsely
+detect the packet as a one-step SYNC packet, even when it was not, which
+caused the TX timestamp to not be processed when it should be.
+
+Using the headroom for this purpose seems like an unnecessary complexity
+as this is not a hot path in the driver, and in most cases it appears
+that there is sufficient tailroom to not require using the headroom
+anyway. Remove this usage of headroom to prevent this inconsistency from
+occurring and causing other problems.
+
+Fixes: 653e92a9175e ("net: macb: add support for padding and fcs computation")
+Signed-off-by: Robert Hancock <robert.hancock@calian.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Tested-by: Claudiu Beznea <claudiu.beznea@microchip.com> # on SAMA7G5
+Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/cadence/macb_main.c | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
+index 61efb2350412..906c5bbefaac 100644
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -2154,7 +2154,6 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)
+ bool cloned = skb_cloned(*skb) || skb_header_cloned(*skb) ||
+ skb_is_nonlinear(*skb);
+ int padlen = ETH_ZLEN - (*skb)->len;
+- int headroom = skb_headroom(*skb);
+ int tailroom = skb_tailroom(*skb);
+ struct sk_buff *nskb;
+ u32 fcs;
+@@ -2168,9 +2167,6 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)
+ /* FCS could be appeded to tailroom. */
+ if (tailroom >= ETH_FCS_LEN)
+ goto add_fcs;
+- /* FCS could be appeded by moving data to headroom. */
+- else if (!cloned && headroom + tailroom >= ETH_FCS_LEN)
+- padlen = 0;
+ /* No room for FCS, need to reallocate skb. */
+ else
+ padlen = ETH_FCS_LEN;
+@@ -2179,10 +2175,7 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)
+ padlen += ETH_FCS_LEN;
+ }
+
+- if (!cloned && headroom + tailroom >= padlen) {
+- (*skb)->data = memmove((*skb)->head, (*skb)->data, (*skb)->len);
+- skb_set_tail_pointer(*skb, (*skb)->len);
+- } else {
++ if (cloned || tailroom < padlen) {
+ nskb = skb_copy_expand(*skb, 0, padlen, GFP_ATOMIC);
+ if (!nskb)
+ return -ENOMEM;
+--
+2.39.0
+
--- /dev/null
+From a140ea3d7c0739cd5db03fc7f3f9b98a88ab0a55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 Jan 2023 11:54:06 +0100
+Subject: net: mdio: validate parameter addr in mdiobus_get_phy()
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+[ Upstream commit 867dbe784c5010a466f00a7d1467c1c5ea569c75 ]
+
+The caller may pass any value as addr, what may result in an out-of-bounds
+access to array mdio_map. One existing case is stmmac_init_phy() that
+may pass -1 as addr. Therefore validate addr before using it.
+
+Fixes: 7f854420fbfe ("phy: Add API for {un}registering an mdio device to a bus.")
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/cdf664ea-3312-e915-73f8-021678d08887@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mdio_bus.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
+index dd7739b5f791..5f89828fd9f1 100644
+--- a/drivers/net/phy/mdio_bus.c
++++ b/drivers/net/phy/mdio_bus.c
+@@ -108,7 +108,12 @@ EXPORT_SYMBOL(mdiobus_unregister_device);
+
+ struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr)
+ {
+- struct mdio_device *mdiodev = bus->mdio_map[addr];
++ struct mdio_device *mdiodev;
++
++ if (addr < 0 || addr >= ARRAY_SIZE(bus->mdio_map))
++ return NULL;
++
++ mdiodev = bus->mdio_map[addr];
+
+ if (!mdiodev)
+ return NULL;
+--
+2.39.0
+
--- /dev/null
+From 4ccdd0e35e0da9fdf94b4def2452ecaef5417da2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Dec 2022 10:22:41 +0200
+Subject: net/mlx5: E-switch, Fix setting of reserved fields on
+ MODIFY_SCHEDULING_ELEMENT
+
+From: Maor Dickman <maord@nvidia.com>
+
+[ Upstream commit f51471d1935ce1f504fce6c115ce3bfbc32032b0 ]
+
+According to HW spec element_type, element_attributes and parent_element_id fields
+should be reserved (0x0) when calling MODIFY_SCHEDULING_ELEMENT command.
+
+This patch remove initialization of these fields when calling the command.
+
+Fixes: bd77bf1cb595 ("net/mlx5: Add SRIOV VF max rate configuration support")
+Signed-off-by: Maor Dickman <maord@nvidia.com>
+Reviewed-by: Eli Cohen <elic@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/esw/qos.c | 18 +++---------------
+ 1 file changed, 3 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
+index d377ddc70fc7..65c8f1f08472 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
+@@ -22,15 +22,13 @@ struct mlx5_esw_rate_group {
+ };
+
+ static int esw_qos_tsar_config(struct mlx5_core_dev *dev, u32 *sched_ctx,
+- u32 parent_ix, u32 tsar_ix,
+- u32 max_rate, u32 bw_share)
++ u32 tsar_ix, u32 max_rate, u32 bw_share)
+ {
+ u32 bitmask = 0;
+
+ if (!MLX5_CAP_GEN(dev, qos) || !MLX5_CAP_QOS(dev, esw_scheduling))
+ return -EOPNOTSUPP;
+
+- MLX5_SET(scheduling_context, sched_ctx, parent_element_id, parent_ix);
+ MLX5_SET(scheduling_context, sched_ctx, max_average_bw, max_rate);
+ MLX5_SET(scheduling_context, sched_ctx, bw_share, bw_share);
+ bitmask |= MODIFY_SCHEDULING_ELEMENT_IN_MODIFY_BITMASK_MAX_AVERAGE_BW;
+@@ -51,7 +49,7 @@ static int esw_qos_group_config(struct mlx5_eswitch *esw, struct mlx5_esw_rate_g
+ int err;
+
+ err = esw_qos_tsar_config(dev, sched_ctx,
+- esw->qos.root_tsar_ix, group->tsar_ix,
++ group->tsar_ix,
+ max_rate, bw_share);
+ if (err)
+ NL_SET_ERR_MSG_MOD(extack, "E-Switch modify group TSAR element failed");
+@@ -67,23 +65,13 @@ static int esw_qos_vport_config(struct mlx5_eswitch *esw,
+ struct netlink_ext_ack *extack)
+ {
+ u32 sched_ctx[MLX5_ST_SZ_DW(scheduling_context)] = {};
+- struct mlx5_esw_rate_group *group = vport->qos.group;
+ struct mlx5_core_dev *dev = esw->dev;
+- u32 parent_tsar_ix;
+- void *vport_elem;
+ int err;
+
+ if (!vport->qos.enabled)
+ return -EIO;
+
+- parent_tsar_ix = group ? group->tsar_ix : esw->qos.root_tsar_ix;
+- MLX5_SET(scheduling_context, sched_ctx, element_type,
+- SCHEDULING_CONTEXT_ELEMENT_TYPE_VPORT);
+- vport_elem = MLX5_ADDR_OF(scheduling_context, sched_ctx,
+- element_attributes);
+- MLX5_SET(vport_element, vport_elem, vport_number, vport->vport);
+-
+- err = esw_qos_tsar_config(dev, sched_ctx, parent_tsar_ix, vport->qos.esw_tsar_ix,
++ err = esw_qos_tsar_config(dev, sched_ctx, vport->qos.esw_tsar_ix,
+ max_rate, bw_share);
+ if (err) {
+ esw_warn(esw->dev,
+--
+2.39.0
+
--- /dev/null
+From 1badcc6645a66dc4bd4db7a2d29406cbc9b7942c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Aug 2022 20:12:29 -0700
+Subject: net: mlx5: eliminate anonymous module_init & module_exit
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 2c1e1b949024989e20907b84e11a731a50778416 ]
+
+Eliminate anonymous module_init() and module_exit(), which can lead to
+confusion or ambiguity when reading System.map, crashes/oops/bugs,
+or an initcall_debug log.
+
+Give each of these init and exit functions unique driver-specific
+names to eliminate the anonymous names.
+
+Example 1: (System.map)
+ ffffffff832fc78c t init
+ ffffffff832fc79e t init
+ ffffffff832fc8f8 t init
+
+Example 2: (initcall_debug log)
+ calling init+0x0/0x12 @ 1
+ initcall init+0x0/0x12 returned 0 after 15 usecs
+ calling init+0x0/0x60 @ 1
+ initcall init+0x0/0x60 returned 0 after 2 usecs
+ calling init+0x0/0x9a @ 1
+ initcall init+0x0/0x9a returned 0 after 74 usecs
+
+Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: Eli Cohen <eli@mellanox.com>
+Cc: Saeed Mahameed <saeedm@nvidia.com>
+Cc: Leon Romanovsky <leon@kernel.org>
+Cc: linux-rdma@vger.kernel.org
+Reviewed-by: Ira Weiny <ira.weiny@intel.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/main.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index 145e56f5eeee..9e15eea9743f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -1849,7 +1849,7 @@ static void mlx5_core_verify_params(void)
+ }
+ }
+
+-static int __init init(void)
++static int __init mlx5_init(void)
+ {
+ int err;
+
+@@ -1885,7 +1885,7 @@ static int __init init(void)
+ return err;
+ }
+
+-static void __exit cleanup(void)
++static void __exit mlx5_cleanup(void)
+ {
+ mlx5e_cleanup();
+ mlx5_sf_driver_unregister();
+@@ -1893,5 +1893,5 @@ static void __exit cleanup(void)
+ mlx5_unregister_debugfs();
+ }
+
+-module_init(init);
+-module_exit(cleanup);
++module_init(mlx5_init);
++module_exit(mlx5_cleanup);
+--
+2.39.0
+
--- /dev/null
+From 3b20bc81a3c904e68e3694884959a9d60e7f52cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 22:19:14 +0900
+Subject: net: nfc: Fix use-after-free in local_cleanup()
+
+From: Jisoo Jang <jisoo.jang@yonsei.ac.kr>
+
+[ Upstream commit 4bb4db7f3187c6e3de6b229ffc87cdb30a2d22b6 ]
+
+Fix a use-after-free that occurs in kfree_skb() called from
+local_cleanup(). This could happen when killing nfc daemon (e.g. neard)
+after detaching an nfc device.
+When detaching an nfc device, local_cleanup() called from
+nfc_llcp_unregister_device() frees local->rx_pending and decreases
+local->ref by kref_put() in nfc_llcp_local_put().
+In the terminating process, nfc daemon releases all sockets and it leads
+to decreasing local->ref. After the last release of local->ref,
+local_cleanup() called from local_release() frees local->rx_pending
+again, which leads to the bug.
+
+Setting local->rx_pending to NULL in local_cleanup() could prevent
+use-after-free when local_cleanup() is called twice.
+
+Found by a modified version of syzkaller.
+
+BUG: KASAN: use-after-free in kfree_skb()
+
+Call Trace:
+dump_stack_lvl (lib/dump_stack.c:106)
+print_address_description.constprop.0.cold (mm/kasan/report.c:306)
+kasan_check_range (mm/kasan/generic.c:189)
+kfree_skb (net/core/skbuff.c:955)
+local_cleanup (net/nfc/llcp_core.c:159)
+nfc_llcp_local_put.part.0 (net/nfc/llcp_core.c:172)
+nfc_llcp_local_put (net/nfc/llcp_core.c:181)
+llcp_sock_destruct (net/nfc/llcp_sock.c:959)
+__sk_destruct (net/core/sock.c:2133)
+sk_destruct (net/core/sock.c:2181)
+__sk_free (net/core/sock.c:2192)
+sk_free (net/core/sock.c:2203)
+llcp_sock_release (net/nfc/llcp_sock.c:646)
+__sock_release (net/socket.c:650)
+sock_close (net/socket.c:1365)
+__fput (fs/file_table.c:306)
+task_work_run (kernel/task_work.c:179)
+ptrace_notify (kernel/signal.c:2354)
+syscall_exit_to_user_mode_prepare (kernel/entry/common.c:278)
+syscall_exit_to_user_mode (kernel/entry/common.c:296)
+do_syscall_64 (arch/x86/entry/common.c:86)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:106)
+
+Allocated by task 4719:
+kasan_save_stack (mm/kasan/common.c:45)
+__kasan_slab_alloc (mm/kasan/common.c:325)
+slab_post_alloc_hook (mm/slab.h:766)
+kmem_cache_alloc_node (mm/slub.c:3497)
+__alloc_skb (net/core/skbuff.c:552)
+pn533_recv_response (drivers/nfc/pn533/usb.c:65)
+__usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1671)
+usb_giveback_urb_bh (drivers/usb/core/hcd.c:1704)
+tasklet_action_common.isra.0 (kernel/softirq.c:797)
+__do_softirq (kernel/softirq.c:571)
+
+Freed by task 1901:
+kasan_save_stack (mm/kasan/common.c:45)
+kasan_set_track (mm/kasan/common.c:52)
+kasan_save_free_info (mm/kasan/genericdd.c:518)
+__kasan_slab_free (mm/kasan/common.c:236)
+kmem_cache_free (mm/slub.c:3809)
+kfree_skbmem (net/core/skbuff.c:874)
+kfree_skb (net/core/skbuff.c:931)
+local_cleanup (net/nfc/llcp_core.c:159)
+nfc_llcp_unregister_device (net/nfc/llcp_core.c:1617)
+nfc_unregister_device (net/nfc/core.c:1179)
+pn53x_unregister_nfc (drivers/nfc/pn533/pn533.c:2846)
+pn533_usb_disconnect (drivers/nfc/pn533/usb.c:579)
+usb_unbind_interface (drivers/usb/core/driver.c:458)
+device_release_driver_internal (drivers/base/dd.c:1279)
+bus_remove_device (drivers/base/bus.c:529)
+device_del (drivers/base/core.c:3665)
+usb_disable_device (drivers/usb/core/message.c:1420)
+usb_disconnect (drivers/usb/core.c:2261)
+hub_event (drivers/usb/core/hub.c:5833)
+process_one_work (arch/x86/include/asm/jump_label.h:27 include/linux/jump_label.h:212 include/trace/events/workqueue.h:108 kernel/workqueue.c:2281)
+worker_thread (include/linux/list.h:282 kernel/workqueue.c:2423)
+kthread (kernel/kthread.c:319)
+ret_from_fork (arch/x86/entry/entry_64.S:301)
+
+Fixes: 3536da06db0b ("NFC: llcp: Clean local timers and works when removing a device")
+Signed-off-by: Jisoo Jang <jisoo.jang@yonsei.ac.kr>
+Link: https://lore.kernel.org/r/20230111131914.3338838-1-jisoo.jang@yonsei.ac.kr
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
+index eaeb2b1cfa6a..fd43e75abd94 100644
+--- a/net/nfc/llcp_core.c
++++ b/net/nfc/llcp_core.c
+@@ -159,6 +159,7 @@ static void local_cleanup(struct nfc_llcp_local *local)
+ cancel_work_sync(&local->rx_work);
+ cancel_work_sync(&local->timeout_work);
+ kfree_skb(local->rx_pending);
++ local->rx_pending = NULL;
+ del_timer_sync(&local->sdreq_timer);
+ cancel_work_sync(&local->sdreq_timeout_work);
+ nfc_llcp_free_sdp_tlv_list(&local->pending_sdreqs);
+--
+2.39.0
+
--- /dev/null
+From f7ec82ef4380bdca30e2c7a2626aac92884d34eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Jan 2023 16:48:49 +0000
+Subject: net/sched: sch_taprio: fix possible use-after-free
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 3a415d59c1dbec9d772dbfab2d2520d98360caae ]
+
+syzbot reported a nasty crash [1] in net_tx_action() which
+made little sense until we got a repro.
+
+This repro installs a taprio qdisc, but providing an
+invalid TCA_RATE attribute.
+
+qdisc_create() has to destroy the just initialized
+taprio qdisc, and taprio_destroy() is called.
+
+However, the hrtimer used by taprio had already fired,
+therefore advance_sched() called __netif_schedule().
+
+Then net_tx_action was trying to use a destroyed qdisc.
+
+We can not undo the __netif_schedule(), so we must wait
+until one cpu serviced the qdisc before we can proceed.
+
+Many thanks to Alexander Potapenko for his help.
+
+[1]
+BUG: KMSAN: uninit-value in queued_spin_trylock include/asm-generic/qspinlock.h:94 [inline]
+BUG: KMSAN: uninit-value in do_raw_spin_trylock include/linux/spinlock.h:191 [inline]
+BUG: KMSAN: uninit-value in __raw_spin_trylock include/linux/spinlock_api_smp.h:89 [inline]
+BUG: KMSAN: uninit-value in _raw_spin_trylock+0x92/0xa0 kernel/locking/spinlock.c:138
+ queued_spin_trylock include/asm-generic/qspinlock.h:94 [inline]
+ do_raw_spin_trylock include/linux/spinlock.h:191 [inline]
+ __raw_spin_trylock include/linux/spinlock_api_smp.h:89 [inline]
+ _raw_spin_trylock+0x92/0xa0 kernel/locking/spinlock.c:138
+ spin_trylock include/linux/spinlock.h:359 [inline]
+ qdisc_run_begin include/net/sch_generic.h:187 [inline]
+ qdisc_run+0xee/0x540 include/net/pkt_sched.h:125
+ net_tx_action+0x77c/0x9a0 net/core/dev.c:5086
+ __do_softirq+0x1cc/0x7fb kernel/softirq.c:571
+ run_ksoftirqd+0x2c/0x50 kernel/softirq.c:934
+ smpboot_thread_fn+0x554/0x9f0 kernel/smpboot.c:164
+ kthread+0x31b/0x430 kernel/kthread.c:376
+ ret_from_fork+0x1f/0x30
+
+Uninit was created at:
+ slab_post_alloc_hook mm/slab.h:732 [inline]
+ slab_alloc_node mm/slub.c:3258 [inline]
+ __kmalloc_node_track_caller+0x814/0x1250 mm/slub.c:4970
+ kmalloc_reserve net/core/skbuff.c:358 [inline]
+ __alloc_skb+0x346/0xcf0 net/core/skbuff.c:430
+ alloc_skb include/linux/skbuff.h:1257 [inline]
+ nlmsg_new include/net/netlink.h:953 [inline]
+ netlink_ack+0x5f3/0x12b0 net/netlink/af_netlink.c:2436
+ netlink_rcv_skb+0x55d/0x6c0 net/netlink/af_netlink.c:2507
+ rtnetlink_rcv+0x30/0x40 net/core/rtnetlink.c:6108
+ netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline]
+ netlink_unicast+0xf3b/0x1270 net/netlink/af_netlink.c:1345
+ netlink_sendmsg+0x1288/0x1440 net/netlink/af_netlink.c:1921
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ sock_sendmsg net/socket.c:734 [inline]
+ ____sys_sendmsg+0xabc/0xe90 net/socket.c:2482
+ ___sys_sendmsg+0x2a1/0x3f0 net/socket.c:2536
+ __sys_sendmsg net/socket.c:2565 [inline]
+ __do_sys_sendmsg net/socket.c:2574 [inline]
+ __se_sys_sendmsg net/socket.c:2572 [inline]
+ __x64_sys_sendmsg+0x367/0x540 net/socket.c:2572
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+CPU: 0 PID: 13 Comm: ksoftirqd/0 Not tainted 6.0.0-rc2-syzkaller-47461-gac3859c02d7f #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/22/2022
+
+Fixes: 5a781ccbd19e ("tc: Add support for configuring the taprio scheduler")
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Alexander Potapenko <glider@google.com>
+Cc: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sch_generic.h | 7 +++++++
+ net/sched/sch_taprio.c | 3 +++
+ 2 files changed, 10 insertions(+)
+
+diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
+index 891b44d80c98..6906da5c733e 100644
+--- a/include/net/sch_generic.h
++++ b/include/net/sch_generic.h
+@@ -1335,4 +1335,11 @@ void mini_qdisc_pair_block_init(struct mini_Qdisc_pair *miniqp,
+
+ int sch_frag_xmit_hook(struct sk_buff *skb, int (*xmit)(struct sk_buff *skb));
+
++/* Make sure qdisc is no longer in SCHED state. */
++static inline void qdisc_synchronize(const struct Qdisc *q)
++{
++ while (test_bit(__QDISC_STATE_SCHED, &q->state))
++ msleep(1);
++}
++
+ #endif
+diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
+index bd10a8eeb82d..a76a2afe9585 100644
+--- a/net/sched/sch_taprio.c
++++ b/net/sched/sch_taprio.c
+@@ -1632,6 +1632,8 @@ static void taprio_reset(struct Qdisc *sch)
+ int i;
+
+ hrtimer_cancel(&q->advance_timer);
++ qdisc_synchronize(sch);
++
+ if (q->qdiscs) {
+ for (i = 0; i < dev->num_tx_queues; i++)
+ if (q->qdiscs[i])
+@@ -1653,6 +1655,7 @@ static void taprio_destroy(struct Qdisc *sch)
+ * happens in qdisc_create(), after taprio_init() has been called.
+ */
+ hrtimer_cancel(&q->advance_timer);
++ qdisc_synchronize(sch);
+
+ taprio_disable_offload(dev, q, NULL);
+
+--
+2.39.0
+
--- /dev/null
+From c336e409a26ce7a237113913fb305ddd052ddb27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 10:56:38 -0600
+Subject: net: stmmac: enable all safety features by default
+
+From: Andrew Halaney <ahalaney@redhat.com>
+
+[ Upstream commit fdfc76a116b5e9d3e98e6c96fe83b42d011d21d4 ]
+
+In the original implementation of dwmac5
+commit 8bf993a5877e ("net: stmmac: Add support for DWMAC5 and implement Safety Features")
+all safety features were enabled by default.
+
+Later it seems some implementations didn't have support for all the
+features, so in
+commit 5ac712dcdfef ("net: stmmac: enable platform specific safety features")
+the safety_feat_cfg structure was added to the callback and defined for
+some platforms to selectively enable these safety features.
+
+The problem is that only certain platforms were given that software
+support. If the automotive safety package bit is set in the hardware
+features register the safety feature callback is called for the platform,
+and for platforms that didn't get a safety_feat_cfg defined this results
+in the following NULL pointer dereference:
+
+[ 7.933303] Call trace:
+[ 7.935812] dwmac5_safety_feat_config+0x20/0x170 [stmmac]
+[ 7.941455] __stmmac_open+0x16c/0x474 [stmmac]
+[ 7.946117] stmmac_open+0x38/0x70 [stmmac]
+[ 7.950414] __dev_open+0x100/0x1dc
+[ 7.954006] __dev_change_flags+0x18c/0x204
+[ 7.958297] dev_change_flags+0x24/0x6c
+[ 7.962237] do_setlink+0x2b8/0xfa4
+[ 7.965827] __rtnl_newlink+0x4ec/0x840
+[ 7.969766] rtnl_newlink+0x50/0x80
+[ 7.973353] rtnetlink_rcv_msg+0x12c/0x374
+[ 7.977557] netlink_rcv_skb+0x5c/0x130
+[ 7.981500] rtnetlink_rcv+0x18/0x2c
+[ 7.985172] netlink_unicast+0x2e8/0x340
+[ 7.989197] netlink_sendmsg+0x1a8/0x420
+[ 7.993222] ____sys_sendmsg+0x218/0x280
+[ 7.997249] ___sys_sendmsg+0xac/0x100
+[ 8.001103] __sys_sendmsg+0x84/0xe0
+[ 8.004776] __arm64_sys_sendmsg+0x24/0x30
+[ 8.008983] invoke_syscall+0x48/0x114
+[ 8.012840] el0_svc_common.constprop.0+0xcc/0xec
+[ 8.017665] do_el0_svc+0x38/0xb0
+[ 8.021071] el0_svc+0x2c/0x84
+[ 8.024212] el0t_64_sync_handler+0xf4/0x120
+[ 8.028598] el0t_64_sync+0x190/0x194
+
+Go back to the original behavior, if the automotive safety package
+is found to be supported in hardware enable all the features unless
+safety_feat_cfg is passed in saying this particular platform only
+supports a subset of the features.
+
+Fixes: 5ac712dcdfef ("net: stmmac: enable platform specific safety features")
+Reported-by: Ning Cai <ncai@quicinc.com>
+Signed-off-by: Andrew Halaney <ahalaney@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwmac5.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
+index 9c2d40f853ed..413f66017219 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
+@@ -186,11 +186,25 @@ static void dwmac5_handle_dma_err(struct net_device *ndev,
+ int dwmac5_safety_feat_config(void __iomem *ioaddr, unsigned int asp,
+ struct stmmac_safety_feature_cfg *safety_feat_cfg)
+ {
++ struct stmmac_safety_feature_cfg all_safety_feats = {
++ .tsoee = 1,
++ .mrxpee = 1,
++ .mestee = 1,
++ .mrxee = 1,
++ .mtxee = 1,
++ .epsi = 1,
++ .edpp = 1,
++ .prtyen = 1,
++ .tmouten = 1,
++ };
+ u32 value;
+
+ if (!asp)
+ return -EINVAL;
+
++ if (!safety_feat_cfg)
++ safety_feat_cfg = &all_safety_feats;
++
+ /* 1. Enable Safety Features */
+ value = readl(ioaddr + MTL_ECC_CONTROL);
+ value |= MEEAO; /* MTL ECC Error Addr Status Override */
+--
+2.39.0
+
--- /dev/null
+From 2f13262b4470cd3d58eef717ea32fa06a2fb1b0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 Jan 2023 18:24:08 +0100
+Subject: net: stmmac: fix invalid call to mdiobus_get_phy()
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+[ Upstream commit 1f3bd64ad921f051254591fbed04fd30b306cde6 ]
+
+In a number of cases the driver assigns a default value of -1 to
+priv->plat->phy_addr. This may result in calling mdiobus_get_phy()
+with addr parameter being -1. Therefore check for this scenario and
+bail out before calling mdiobus_get_phy().
+
+Fixes: 42e87024f727 ("net: stmmac: Fix case when PHY handle is not present")
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/669f9671-ecd1-a41b-2727-7b73e3003985@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 15b0daf416f3..4191502d6472 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -1242,6 +1242,11 @@ static int stmmac_init_phy(struct net_device *dev)
+ int addr = priv->plat->phy_addr;
+ struct phy_device *phydev;
+
++ if (addr < 0) {
++ netdev_err(priv->dev, "no phy found\n");
++ return -ENODEV;
++ }
++
+ phydev = mdiobus_get_phy(priv->mii, addr);
+ if (!phydev) {
+ netdev_err(priv->dev, "no phy at addr %d\n", addr);
+--
+2.39.0
+
--- /dev/null
+From 1c0f8dc629939a940d4b0d8c08a7873e36d05b7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 14 Jan 2023 13:04:37 +0100
+Subject: net: stmmac: Fix queue statistics reading
+
+From: Kurt Kanzenbach <kurt@linutronix.de>
+
+[ Upstream commit c296c77efb66994d94d9f706446a115581226550 ]
+
+Correct queue statistics reading. All queue statistics are stored as unsigned
+long values. The retrieval for ethtool fetches these values as u64. However, on
+some systems the size of the counters are 32 bit. That yields wrong queue
+statistic counters e.g., on arm32 systems such as the stm32mp157. Fix it by
+using the correct data type.
+
+Tested on Olimex STMP157-OLinuXino-LIME2 by simple running linuxptp for a short
+period of time:
+
+Non-patched kernel:
+|root@st1:~# ethtool -S eth0 | grep q0
+| q0_tx_pkt_n: 3775276254951 # ???
+| q0_tx_irq_n: 879
+| q0_rx_pkt_n: 1194000908909 # ???
+| q0_rx_irq_n: 278
+
+Patched kernel:
+|root@st1:~# ethtool -S eth0 | grep q0
+| q0_tx_pkt_n: 2434
+| q0_tx_irq_n: 1274
+| q0_rx_pkt_n: 1604
+| q0_rx_irq_n: 846
+
+Fixes: 68e9c5dee1cf ("net: stmmac: add ethtool per-queue statistic framework")
+Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
+Cc: Vijayakannan Ayyathurai <vijayakannan.ayyathurai@intel.com>
+Cc: Wong Vee Khee <vee.khee.wong@linux.intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+index dc31501fec8f..9e8ae4384e4f 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+@@ -548,16 +548,16 @@ static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data)
+ p = (char *)priv + offsetof(struct stmmac_priv,
+ xstats.txq_stats[q].tx_pkt_n);
+ for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) {
+- *data++ = (*(u64 *)p);
+- p += sizeof(u64 *);
++ *data++ = (*(unsigned long *)p);
++ p += sizeof(unsigned long);
+ }
+ }
+ for (q = 0; q < rx_cnt; q++) {
+ p = (char *)priv + offsetof(struct stmmac_priv,
+ xstats.rxq_stats[q].rx_pkt_n);
+ for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) {
+- *data++ = (*(u64 *)p);
+- p += sizeof(u64 *);
++ *data++ = (*(unsigned long *)p);
++ p += sizeof(unsigned long);
+ }
+ }
+ }
+--
+2.39.0
+
--- /dev/null
+From 8f1cdb23c22e24b46f73795870903d587fb9d7bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Jan 2023 11:42:49 +0800
+Subject: net: usb: cdc_ether: add support for Thales Cinterion PLS62-W modem
+
+From: Hui Wang <hui.wang@canonical.com>
+
+[ Upstream commit eea8ce81fbb544e3caad1a1c876ba1af467b3d3c ]
+
+This modem has 7 interfaces, 5 of them are serial interfaces and are
+driven by cdc_acm, while 2 of them are wwan interfaces and are driven
+by cdc_ether:
+If 0: Abstract (modem)
+If 1: Abstract (modem)
+If 2: Abstract (modem)
+If 3: Abstract (modem)
+If 4: Abstract (modem)
+If 5: Ethernet Networking
+If 6: Ethernet Networking
+
+Without this change, the 2 network interfaces will be named to usb0
+and usb1, our QA think the names are confusing and filed a bug on it.
+
+After applying this change, the name will be wwan0 and wwan1, and
+they could work well with modem manager.
+
+Signed-off-by: Hui Wang <hui.wang@canonical.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Link: https://lore.kernel.org/r/20230105034249.10433-1-hui.wang@canonical.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/cdc_ether.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
+index c6b0de1b752f..3497b5a286ea 100644
+--- a/drivers/net/usb/cdc_ether.c
++++ b/drivers/net/usb/cdc_ether.c
+@@ -1000,6 +1000,12 @@ static const struct usb_device_id products[] = {
+ USB_CDC_SUBCLASS_ETHERNET,
+ USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long)&wwan_info,
++}, {
++ /* Cinterion PLS62-W modem by GEMALTO/THALES */
++ USB_DEVICE_AND_INTERFACE_INFO(0x1e2d, 0x005b, USB_CLASS_COMM,
++ USB_CDC_SUBCLASS_ETHERNET,
++ USB_CDC_PROTO_NONE),
++ .driver_info = (unsigned long)&wwan_info,
+ }, {
+ /* Cinterion PLS83/PLS63 modem by GEMALTO/THALES */
+ USB_DEVICE_AND_INTERFACE_INFO(0x1e2d, 0x0069, USB_CLASS_COMM,
+--
+2.39.0
+
--- /dev/null
+From 022a0f42eedc49de6fcb13b864a33f305cb78624 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 14 Jan 2023 19:23:26 +0100
+Subject: net: usb: sr9700: Handle negative len
+
+From: Szymon Heidrich <szymon.heidrich@gmail.com>
+
+[ Upstream commit ecf7cf8efb59789e2b21d2f9ab926142579092b2 ]
+
+Packet len computed as difference of length word extracted from
+skb data and four may result in a negative value. In such case
+processing of the buffer should be interrupted rather than
+setting sr_skb->len to an unexpectedly large value (due to cast
+from signed to unsigned integer) and passing sr_skb to
+usbnet_skb_return.
+
+Fixes: e9da0b56fe27 ("sr9700: sanity check for packet length")
+Signed-off-by: Szymon Heidrich <szymon.heidrich@gmail.com>
+Link: https://lore.kernel.org/r/20230114182326.30479-1-szymon.heidrich@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/sr9700.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c
+index 0c50f24671da..1fac6ee273c4 100644
+--- a/drivers/net/usb/sr9700.c
++++ b/drivers/net/usb/sr9700.c
+@@ -410,7 +410,7 @@ static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+ /* ignore the CRC length */
+ len = (skb->data[1] | (skb->data[2] << 8)) - 4;
+
+- if (len > ETH_FRAME_LEN || len > skb->len)
++ if (len > ETH_FRAME_LEN || len > skb->len || len < 0)
+ return 0;
+
+ /* the last packet of current skb */
+--
+2.39.0
+
--- /dev/null
+From 82eeab28aa67863fe141d5196a8743058cf97690 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Jan 2023 10:47:03 +0300
+Subject: net: wan: Add checks for NULL for utdm in undo_uhdlc_init and
+ unmap_si_regs
+
+From: Esina Ekaterina <eesina@astralinux.ru>
+
+[ Upstream commit 488e0bf7f34af3d42d1d5e56f7a5a7beaff188a3 ]
+
+If uhdlc_priv_tsa != 1 then utdm is not initialized.
+And if ret != NULL then goto undo_uhdlc_init, where
+utdm is dereferenced. Same if dev == NULL.
+
+Found by Astra Linux on behalf of Linux Verification Center
+(linuxtesting.org) with SVACE.
+
+Fixes: 8d68100ab4ad ("soc/fsl/qe: fix err handling of ucc_of_parse_tdm")
+Signed-off-by: Esina Ekaterina <eesina@astralinux.ru>
+Link: https://lore.kernel.org/r/20230112074703.13558-1-eesina@astralinux.ru
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wan/fsl_ucc_hdlc.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
+index cda1b4ce6b21..8305df1a3008 100644
+--- a/drivers/net/wan/fsl_ucc_hdlc.c
++++ b/drivers/net/wan/fsl_ucc_hdlc.c
+@@ -1241,9 +1241,11 @@ static int ucc_hdlc_probe(struct platform_device *pdev)
+ free_dev:
+ free_netdev(dev);
+ undo_uhdlc_init:
+- iounmap(utdm->siram);
++ if (utdm)
++ iounmap(utdm->siram);
+ unmap_si_regs:
+- iounmap(utdm->si_regs);
++ if (utdm)
++ iounmap(utdm->si_regs);
+ free_utdm:
+ if (uhdlc_priv->tsa)
+ kfree(utdm);
+--
+2.39.0
+
--- /dev/null
+From 21ba959f2af6f067f751e7fdeb220d8ad761a9ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Jan 2023 00:24:53 +0800
+Subject: NFSD: fix use-after-free in nfsd4_ssc_setup_dul()
+
+From: Xingyuan Mo <hdthky0@gmail.com>
+
+[ Upstream commit e6cf91b7b47ff82b624bdfe2fdcde32bb52e71dd ]
+
+If signal_pending() returns true, schedule_timeout() will not be executed,
+causing the waiting task to remain in the wait queue.
+Fixed by adding a call to finish_wait(), which ensures that the waiting
+task will always be removed from the wait queue.
+
+Fixes: f4e44b393389 ("NFSD: delay unmount source's export after inter-server copy completed.")
+Signed-off-by: Xingyuan Mo <hdthky0@gmail.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4proc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
+index 09dd70f79158..0a900b9e39ea 100644
+--- a/fs/nfsd/nfs4proc.c
++++ b/fs/nfsd/nfs4proc.c
+@@ -1205,6 +1205,7 @@ static __be32 nfsd4_ssc_setup_dul(struct nfsd_net *nn, char *ipaddr,
+ /* allow 20secs for mount/unmount for now - revisit */
+ if (signal_pending(current) ||
+ (schedule_timeout(20*HZ) == 0)) {
++ finish_wait(&nn->nfsd_ssc_waitq, &wait);
+ kfree(work);
+ return nfserr_eagain;
+ }
+--
+2.39.0
+
--- /dev/null
+From efe5f3d989873a8c64f6a928928acdd8dbb7b876 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 08:44:16 -0800
+Subject: nvme-pci: fix timeout request state check
+
+From: Keith Busch <kbusch@kernel.org>
+
+[ Upstream commit 1c5842085851f786eba24a39ecd02650ad892064 ]
+
+Polling the completion can progress the request state to IDLE, either
+inline with the completion, or through softirq. Either way, the state
+may not be COMPLETED, so don't check for that. We only care if the state
+isn't IN_FLIGHT.
+
+This is fixing an issue where the driver aborts an IO that we just
+completed. Seeing the "aborting" message instead of "polled" is very
+misleading as to where the timeout problem resides.
+
+Fixes: bf392a5dc02a9b ("nvme-pci: Remove tag from process cq")
+Signed-off-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/pci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 0165e65cf548..00552cd02d73 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -1280,7 +1280,7 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved)
+ else
+ nvme_poll_irqdisable(nvmeq);
+
+- if (blk_mq_request_completed(req)) {
++ if (blk_mq_rq_state(req) != MQ_RQ_IN_FLIGHT) {
+ dev_warn(dev->ctrl.device,
+ "I/O %d QID %d timeout, completion polled\n",
+ req->tag, nvmeq->qid);
+--
+2.39.0
+
--- /dev/null
+From 8fbeb399a594afd750cae0af07585813b2e54c5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Jan 2023 11:49:02 +0530
+Subject: octeontx2-pf: Avoid use of GFP_KERNEL in atomic context
+
+From: Geetha sowjanya <gakula@marvell.com>
+
+[ Upstream commit 87b93b678e95c7d93fe6a55b0e0fbda26d8c7760 ]
+
+Using GFP_KERNEL in preemption disable context, causing below warning
+when CONFIG_DEBUG_ATOMIC_SLEEP is enabled.
+
+[ 32.542271] BUG: sleeping function called from invalid context at include/linux/sched/mm.h:274
+[ 32.550883] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 1, name: swapper/0
+[ 32.558707] preempt_count: 1, expected: 0
+[ 32.562710] RCU nest depth: 0, expected: 0
+[ 32.566800] CPU: 3 PID: 1 Comm: swapper/0 Tainted: G W 6.2.0-rc2-00269-gae9dcb91c606 #7
+[ 32.576188] Hardware name: Marvell CN106XX board (DT)
+[ 32.581232] Call trace:
+[ 32.583670] dump_backtrace.part.0+0xe0/0xf0
+[ 32.587937] show_stack+0x18/0x30
+[ 32.591245] dump_stack_lvl+0x68/0x84
+[ 32.594900] dump_stack+0x18/0x34
+[ 32.598206] __might_resched+0x12c/0x160
+[ 32.602122] __might_sleep+0x48/0xa0
+[ 32.605689] __kmem_cache_alloc_node+0x2b8/0x2e0
+[ 32.610301] __kmalloc+0x58/0x190
+[ 32.613610] otx2_sq_aura_pool_init+0x1a8/0x314
+[ 32.618134] otx2_open+0x1d4/0x9d0
+
+To avoid use of GFP_ATOMIC for memory allocation, disable preemption
+after all memory allocation is done.
+
+Fixes: 4af1b64f80fb ("octeontx2-pf: Fix lmtst ID used in aura free")
+Signed-off-by: Geetha sowjanya <gakula@marvell.com>
+Signed-off-by: Sunil Kovvuri Goutham <sgoutham@marvell.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+index f6306eedd59b..30d4c0ad712d 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -1316,7 +1316,6 @@ int otx2_sq_aura_pool_init(struct otx2_nic *pfvf)
+ if (err)
+ goto fail;
+
+- get_cpu();
+ /* Allocate pointers and free them to aura/pool */
+ for (qidx = 0; qidx < hw->tx_queues; qidx++) {
+ pool_id = otx2_get_pool_idx(pfvf, AURA_NIX_SQ, qidx);
+@@ -1334,13 +1333,14 @@ int otx2_sq_aura_pool_init(struct otx2_nic *pfvf)
+ err = otx2_alloc_rbuf(pfvf, pool, &bufptr);
+ if (err)
+ goto err_mem;
++ get_cpu();
+ pfvf->hw_ops->aura_freeptr(pfvf, pool_id, bufptr);
++ put_cpu();
+ sq->sqb_ptrs[sq->sqb_count++] = (u64)bufptr;
+ }
+ }
+
+ err_mem:
+- put_cpu();
+ return err ? -ENOMEM : 0;
+
+ fail:
+--
+2.39.0
+
--- /dev/null
+From 6dbacc51ce4a70939a80f04742d390f3c5570072 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 15:13:00 +0800
+Subject: octeontx2-pf: Fix the use of GFP_KERNEL in atomic context on rt
+
+From: Kevin Hao <haokexin@gmail.com>
+
+[ Upstream commit 55ba18dc62deff5910c0fa64486dea1ff20832ff ]
+
+The commit 4af1b64f80fb ("octeontx2-pf: Fix lmtst ID used in aura
+free") uses the get/put_cpu() to protect the usage of percpu pointer
+in ->aura_freeptr() callback, but it also unnecessarily disable the
+preemption for the blockable memory allocation. The commit 87b93b678e95
+("octeontx2-pf: Avoid use of GFP_KERNEL in atomic context") tried to
+fix these sleep inside atomic warnings. But it only fix the one for
+the non-rt kernel. For the rt kernel, we still get the similar warnings
+like below.
+ BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:46
+ in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 1, name: swapper/0
+ preempt_count: 1, expected: 0
+ RCU nest depth: 0, expected: 0
+ 3 locks held by swapper/0/1:
+ #0: ffff800009fc5fe8 (rtnl_mutex){+.+.}-{3:3}, at: rtnl_lock+0x24/0x30
+ #1: ffff000100c276c0 (&mbox->lock){+.+.}-{3:3}, at: otx2_init_hw_resources+0x8c/0x3a4
+ #2: ffffffbfef6537e0 (&cpu_rcache->lock){+.+.}-{2:2}, at: alloc_iova_fast+0x1ac/0x2ac
+ Preemption disabled at:
+ [<ffff800008b1908c>] otx2_rq_aura_pool_init+0x14c/0x284
+ CPU: 20 PID: 1 Comm: swapper/0 Tainted: G W 6.2.0-rc3-rt1-yocto-preempt-rt #1
+ Hardware name: Marvell OcteonTX CN96XX board (DT)
+ Call trace:
+ dump_backtrace.part.0+0xe8/0xf4
+ show_stack+0x20/0x30
+ dump_stack_lvl+0x9c/0xd8
+ dump_stack+0x18/0x34
+ __might_resched+0x188/0x224
+ rt_spin_lock+0x64/0x110
+ alloc_iova_fast+0x1ac/0x2ac
+ iommu_dma_alloc_iova+0xd4/0x110
+ __iommu_dma_map+0x80/0x144
+ iommu_dma_map_page+0xe8/0x260
+ dma_map_page_attrs+0xb4/0xc0
+ __otx2_alloc_rbuf+0x90/0x150
+ otx2_rq_aura_pool_init+0x1c8/0x284
+ otx2_init_hw_resources+0xe4/0x3a4
+ otx2_open+0xf0/0x610
+ __dev_open+0x104/0x224
+ __dev_change_flags+0x1e4/0x274
+ dev_change_flags+0x2c/0x7c
+ ic_open_devs+0x124/0x2f8
+ ip_auto_config+0x180/0x42c
+ do_one_initcall+0x90/0x4dc
+ do_basic_setup+0x10c/0x14c
+ kernel_init_freeable+0x10c/0x13c
+ kernel_init+0x2c/0x140
+ ret_from_fork+0x10/0x20
+
+Of course, we can shuffle the get/put_cpu() to only wrap the invocation
+of ->aura_freeptr() as what commit 87b93b678e95 does. But there are only
+two ->aura_freeptr() callbacks, otx2_aura_freeptr() and
+cn10k_aura_freeptr(). There is no usage of perpcu variable in the
+otx2_aura_freeptr() at all, so the get/put_cpu() seems redundant to it.
+We can move the get/put_cpu() into the corresponding callback which
+really has the percpu variable usage and avoid the sprinkling of
+get/put_cpu() in several places.
+
+Fixes: 4af1b64f80fb ("octeontx2-pf: Fix lmtst ID used in aura free")
+Signed-off-by: Kevin Hao <haokexin@gmail.com>
+Link: https://lore.kernel.org/r/20230118071300.3271125-1-haokexin@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/marvell/octeontx2/nic/otx2_common.c | 11 ++---------
+ .../net/ethernet/marvell/octeontx2/nic/otx2_common.h | 2 ++
+ 2 files changed, 4 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+index 30d4c0ad712d..2e225309de9c 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -962,7 +962,6 @@ static void otx2_pool_refill_task(struct work_struct *work)
+ rbpool = cq->rbpool;
+ free_ptrs = cq->pool_ptrs;
+
+- get_cpu();
+ while (cq->pool_ptrs) {
+ if (otx2_alloc_rbuf(pfvf, rbpool, &bufptr)) {
+ /* Schedule a WQ if we fails to free atleast half of the
+@@ -982,7 +981,6 @@ static void otx2_pool_refill_task(struct work_struct *work)
+ pfvf->hw_ops->aura_freeptr(pfvf, qidx, bufptr + OTX2_HEAD_ROOM);
+ cq->pool_ptrs--;
+ }
+- put_cpu();
+ cq->refill_task_sched = false;
+ }
+
+@@ -1333,9 +1331,7 @@ int otx2_sq_aura_pool_init(struct otx2_nic *pfvf)
+ err = otx2_alloc_rbuf(pfvf, pool, &bufptr);
+ if (err)
+ goto err_mem;
+- get_cpu();
+ pfvf->hw_ops->aura_freeptr(pfvf, pool_id, bufptr);
+- put_cpu();
+ sq->sqb_ptrs[sq->sqb_count++] = (u64)bufptr;
+ }
+ }
+@@ -1381,21 +1377,18 @@ int otx2_rq_aura_pool_init(struct otx2_nic *pfvf)
+ if (err)
+ goto fail;
+
+- get_cpu();
+ /* Allocate pointers and free them to aura/pool */
+ for (pool_id = 0; pool_id < hw->rqpool_cnt; pool_id++) {
+ pool = &pfvf->qset.pool[pool_id];
+ for (ptr = 0; ptr < num_ptrs; ptr++) {
+ err = otx2_alloc_rbuf(pfvf, pool, &bufptr);
+ if (err)
+- goto err_mem;
++ return -ENOMEM;
+ pfvf->hw_ops->aura_freeptr(pfvf, pool_id,
+ bufptr + OTX2_HEAD_ROOM);
+ }
+ }
+-err_mem:
+- put_cpu();
+- return err ? -ENOMEM : 0;
++ return 0;
+ fail:
+ otx2_mbox_reset(&pfvf->mbox.mbox, 0);
+ otx2_aura_pool_free(pfvf);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+index 095e5de78c0b..e685628b9294 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+@@ -605,8 +605,10 @@ static inline void cn10k_aura_freeptr(void *dev, int aura, u64 buf)
+ u64 ptrs[2];
+
+ ptrs[1] = buf;
++ get_cpu();
+ /* Free only one buffer at time during init and teardown */
+ __cn10k_aura_freeptr(pfvf, aura, ptrs, 2);
++ put_cpu();
+ }
+
+ /* Alloc pointer from pool/aura */
+--
+2.39.0
+
--- /dev/null
+From adfd6011a0cacc1ccfa2074d804c00faee020474 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Jan 2023 08:04:49 -0800
+Subject: perf/x86/intel/uncore: Add Emerald Rapids
+
+From: Kan Liang <kan.liang@linux.intel.com>
+
+[ Upstream commit 5268a2842066c227e6ccd94bac562f1e1000244f ]
+
+From the perspective of the uncore PMU, the new Emerald Rapids is the
+same as the Sapphire Rapids. The only difference is the event list,
+which will be supported in the perf tool later.
+
+Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/r/20230106160449.3566477-4-kan.liang@linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/events/intel/uncore.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
+index c72e368dd164..7e16c590f259 100644
+--- a/arch/x86/events/intel/uncore.c
++++ b/arch/x86/events/intel/uncore.c
+@@ -1829,6 +1829,7 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
+ X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &adl_uncore_init),
+ X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &adl_uncore_init),
+ X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &spr_uncore_init),
++ X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X, &spr_uncore_init),
+ X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &snr_uncore_init),
+ {},
+ };
+--
+2.39.0
+
--- /dev/null
+From 165d55a07b3ba5c0a73ab8ad6507db42a0c2a310 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Jan 2023 08:04:48 -0800
+Subject: perf/x86/msr: Add Emerald Rapids
+
+From: Kan Liang <kan.liang@linux.intel.com>
+
+[ Upstream commit 69ced4160969025821f2999ff92163ed26568f1c ]
+
+The same as Sapphire Rapids, the SMI_COUNT MSR is also supported on
+Emerald Rapids. Add Emerald Rapids model.
+
+Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/r/20230106160449.3566477-3-kan.liang@linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/events/msr.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c
+index 96c775abe31f..d23b5523cdd3 100644
+--- a/arch/x86/events/msr.c
++++ b/arch/x86/events/msr.c
+@@ -69,6 +69,7 @@ static bool test_intel(int idx, void *data)
+ case INTEL_FAM6_BROADWELL_G:
+ case INTEL_FAM6_BROADWELL_X:
+ case INTEL_FAM6_SAPPHIRERAPIDS_X:
++ case INTEL_FAM6_EMERALDRAPIDS_X:
+
+ case INTEL_FAM6_ATOM_SILVERMONT:
+ case INTEL_FAM6_ATOM_SILVERMONT_D:
+--
+2.39.0
+
--- /dev/null
+From 6249874e3c8eddfdac67ad202fa015d240e468d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 11:29:58 +0100
+Subject: phy: phy-can-transceiver: Skip warning if no "max-bitrate"
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit bc30c15f275484f9b9fe27c2fa0895f3022d9943 ]
+
+According to the DT bindings, the "max-bitrate" property is optional.
+However, when it is not present, a warning is printed.
+Fix this by adding a missing check for -EINVAL.
+
+Fixes: a4a86d273ff1b6f7 ("phy: phy-can-transceiver: Add support for generic CAN transceiver driver")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/88e158f97dd52ebaa7126cd9631f34764b9c0795.1674037334.git.geert+renesas@glider.be
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/phy-can-transceiver.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
+index c2cb93b4df71..4525d3fd903a 100644
+--- a/drivers/phy/phy-can-transceiver.c
++++ b/drivers/phy/phy-can-transceiver.c
+@@ -87,6 +87,7 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
+ struct gpio_desc *standby_gpio;
+ struct gpio_desc *enable_gpio;
+ u32 max_bitrate = 0;
++ int err;
+
+ can_transceiver_phy = devm_kzalloc(dev, sizeof(struct can_transceiver_phy), GFP_KERNEL);
+ if (!can_transceiver_phy)
+@@ -102,8 +103,8 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
+ return PTR_ERR(phy);
+ }
+
+- device_property_read_u32(dev, "max-bitrate", &max_bitrate);
+- if (!max_bitrate)
++ err = device_property_read_u32(dev, "max-bitrate", &max_bitrate);
++ if ((err != -EINVAL) && !max_bitrate)
+ dev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit\n");
+ phy->attrs.max_link_rate = max_bitrate;
+
+--
+2.39.0
+
--- /dev/null
+From a3ead60320e0868e2ba5e47f9c92c3784ef87afd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Dec 2022 19:58:23 +0800
+Subject: phy: rockchip-inno-usb2: Fix missing clk_disable_unprepare() in
+ rockchip_usb2phy_power_on()
+
+From: Shang XiaoJing <shangxiaojing@huawei.com>
+
+[ Upstream commit 5daba914da0e48950e9407ea4d75fa57029c9adc ]
+
+The clk_disable_unprepare() should be called in the error handling of
+rockchip_usb2phy_power_on().
+
+Fixes: 0e08d2a727e6 ("phy: rockchip-inno-usb2: add a new driver for Rockchip usb2phy")
+Signed-off-by: Shang XiaoJing <shangxiaojing@huawei.com>
+Link: https://lore.kernel.org/r/20221205115823.16957-1-shangxiaojing@huawei.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+index 4f569d9307b9..c167b8c5cc86 100644
+--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+@@ -467,8 +467,10 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
+ return ret;
+
+ ret = property_enable(base, &rport->port_cfg->phy_sus, false);
+- if (ret)
++ if (ret) {
++ clk_disable_unprepare(rphy->clk480m);
+ return ret;
++ }
+
+ /* waiting for the utmi_clk to become stable */
+ usleep_range(1500, 2000);
+--
+2.39.0
+
--- /dev/null
+From b1f860b8e8c759156259a0574f893daf61638c69 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 22:25:29 -0800
+Subject: phy: ti: fix Kconfig warning and operator precedence
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 7124c93887cc4e6c5b48920f83115e4a5892e870 ]
+
+Fix Kconfig depends operator precedence to prevent a Kconfig warning:
+
+WARNING: unmet direct dependencies detected for MUX_MMIO
+ Depends on [n]: MULTIPLEXER [=m] && OF [=n]
+ Selected by [m]:
+ - PHY_AM654_SERDES [=m] && (OF [=n] && ARCH_K3 || COMPILE_TEST [=y]) && COMMON_CLK [=y]
+
+Fixes: 71e2f5c5c224 ("phy: ti: Add a new SERDES driver for TI's AM654x SoC")
+Fixes: 091876cc355d ("phy: ti: j721e-wiz: Add support for WIZ module present in TI J721E SoC")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: Vinod Koul <vkoul@kernel.org>
+Cc: Kishon Vijay Abraham I <kishon@kernel.org>
+Cc: linux-phy@lists.infradead.org
+Cc: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20230110062529.22668-1-rdunlap@infradead.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/ti/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/phy/ti/Kconfig b/drivers/phy/ti/Kconfig
+index 15a3bcf32308..b905902d5750 100644
+--- a/drivers/phy/ti/Kconfig
++++ b/drivers/phy/ti/Kconfig
+@@ -23,7 +23,7 @@ config PHY_DM816X_USB
+
+ config PHY_AM654_SERDES
+ tristate "TI AM654 SERDES support"
+- depends on OF && ARCH_K3 || COMPILE_TEST
++ depends on OF && (ARCH_K3 || COMPILE_TEST)
+ depends on COMMON_CLK
+ select GENERIC_PHY
+ select MULTIPLEXER
+@@ -35,7 +35,7 @@ config PHY_AM654_SERDES
+
+ config PHY_J721E_WIZ
+ tristate "TI J721E WIZ (SERDES Wrapper) support"
+- depends on OF && ARCH_K3 || COMPILE_TEST
++ depends on OF && (ARCH_K3 || COMPILE_TEST)
+ depends on HAS_IOMEM && OF_ADDRESS
+ depends on COMMON_CLK
+ select GENERIC_PHY
+--
+2.39.0
+
--- /dev/null
+From b9554a2aee4442383fd7c860da4d0a46dfe3af85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Apr 2022 19:09:13 +0200
+Subject: pinctrl/rockchip: add error handling for pull/drive register getters
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+
+[ Upstream commit 42573ab3b9f94fbeba8b84e142703ea551624f6d ]
+
+Add error handling for the pull and driver register getters in preparation
+for RK3588 support.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Reviewed-by: Heiko Stübner <heiko@sntech.de>
+Link: https://lore.kernel.org/r/20220422170920.401914-13-sebastian.reichel@collabora.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Stable-dep-of: 31b62a98de42 ("pinctrl: rockchip: fix reading pull type on rk3568")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-rockchip.c | 168 ++++++++++++++++++-----------
+ drivers/pinctrl/pinctrl-rockchip.h | 4 +-
+ 2 files changed, 109 insertions(+), 63 deletions(-)
+
+diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
+index fcff8e7798b3..4888840dfc33 100644
+--- a/drivers/pinctrl/pinctrl-rockchip.c
++++ b/drivers/pinctrl/pinctrl-rockchip.c
+@@ -1039,9 +1039,9 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
+ #define PX30_PULL_PINS_PER_REG 8
+ #define PX30_PULL_BANK_STRIDE 16
+
+-static void px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+@@ -1061,6 +1061,8 @@ static void px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ *reg += ((pin_num / PX30_PULL_PINS_PER_REG) * 4);
+ *bit = (pin_num % PX30_PULL_PINS_PER_REG);
+ *bit *= PX30_PULL_BITS_PER_PIN;
++
++ return 0;
+ }
+
+ #define PX30_DRV_PMU_OFFSET 0x20
+@@ -1069,9 +1071,9 @@ static void px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ #define PX30_DRV_PINS_PER_REG 8
+ #define PX30_DRV_BANK_STRIDE 16
+
+-static void px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+@@ -1091,6 +1093,8 @@ static void px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+ *reg += ((pin_num / PX30_DRV_PINS_PER_REG) * 4);
+ *bit = (pin_num % PX30_DRV_PINS_PER_REG);
+ *bit *= PX30_DRV_BITS_PER_PIN;
++
++ return 0;
+ }
+
+ #define PX30_SCHMITT_PMU_OFFSET 0x38
+@@ -1130,9 +1134,9 @@ static int px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
+ #define RV1108_PULL_BITS_PER_PIN 2
+ #define RV1108_PULL_BANK_STRIDE 16
+
+-static void rv1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int rv1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+@@ -1151,6 +1155,8 @@ static void rv1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ *reg += ((pin_num / RV1108_PULL_PINS_PER_REG) * 4);
+ *bit = (pin_num % RV1108_PULL_PINS_PER_REG);
+ *bit *= RV1108_PULL_BITS_PER_PIN;
++
++ return 0;
+ }
+
+ #define RV1108_DRV_PMU_OFFSET 0x20
+@@ -1159,9 +1165,9 @@ static void rv1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ #define RV1108_DRV_PINS_PER_REG 8
+ #define RV1108_DRV_BANK_STRIDE 16
+
+-static void rv1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int rv1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+@@ -1181,6 +1187,8 @@ static void rv1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+ *reg += ((pin_num / RV1108_DRV_PINS_PER_REG) * 4);
+ *bit = pin_num % RV1108_DRV_PINS_PER_REG;
+ *bit *= RV1108_DRV_BITS_PER_PIN;
++
++ return 0;
+ }
+
+ #define RV1108_SCHMITT_PMU_OFFSET 0x30
+@@ -1237,9 +1245,9 @@ static int rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
+ #define RK2928_PULL_PINS_PER_REG 16
+ #define RK2928_PULL_BANK_STRIDE 8
+
+-static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+@@ -1249,13 +1257,15 @@ static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ *reg += (pin_num / RK2928_PULL_PINS_PER_REG) * 4;
+
+ *bit = pin_num % RK2928_PULL_PINS_PER_REG;
++
++ return 0;
+ };
+
+ #define RK3128_PULL_OFFSET 0x118
+
+-static void rk3128_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int rk3128_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+@@ -1265,6 +1275,8 @@ static void rk3128_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ *reg += ((pin_num / RK2928_PULL_PINS_PER_REG) * 4);
+
+ *bit = pin_num % RK2928_PULL_PINS_PER_REG;
++
++ return 0;
+ }
+
+ #define RK3188_PULL_OFFSET 0x164
+@@ -1273,9 +1285,9 @@ static void rk3128_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ #define RK3188_PULL_BANK_STRIDE 16
+ #define RK3188_PULL_PMU_OFFSET 0x64
+
+-static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+@@ -1305,12 +1317,14 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ *bit = 7 - (pin_num % RK3188_PULL_PINS_PER_REG);
+ *bit *= RK3188_PULL_BITS_PER_PIN;
+ }
++
++ return 0;
+ }
+
+ #define RK3288_PULL_OFFSET 0x140
+-static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+@@ -1334,6 +1348,8 @@ static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ *bit = (pin_num % RK3188_PULL_PINS_PER_REG);
+ *bit *= RK3188_PULL_BITS_PER_PIN;
+ }
++
++ return 0;
+ }
+
+ #define RK3288_DRV_PMU_OFFSET 0x70
+@@ -1342,9 +1358,9 @@ static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ #define RK3288_DRV_PINS_PER_REG 8
+ #define RK3288_DRV_BANK_STRIDE 16
+
+-static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+@@ -1368,13 +1384,15 @@ static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+ *bit = (pin_num % RK3288_DRV_PINS_PER_REG);
+ *bit *= RK3288_DRV_BITS_PER_PIN;
+ }
++
++ return 0;
+ }
+
+ #define RK3228_PULL_OFFSET 0x100
+
+-static void rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+@@ -1385,13 +1403,15 @@ static void rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+
+ *bit = (pin_num % RK3188_PULL_PINS_PER_REG);
+ *bit *= RK3188_PULL_BITS_PER_PIN;
++
++ return 0;
+ }
+
+ #define RK3228_DRV_GRF_OFFSET 0x200
+
+-static void rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+@@ -1402,13 +1422,15 @@ static void rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+
+ *bit = (pin_num % RK3288_DRV_PINS_PER_REG);
+ *bit *= RK3288_DRV_BITS_PER_PIN;
++
++ return 0;
+ }
+
+ #define RK3308_PULL_OFFSET 0xa0
+
+-static void rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+@@ -1419,13 +1441,15 @@ static void rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+
+ *bit = (pin_num % RK3188_PULL_PINS_PER_REG);
+ *bit *= RK3188_PULL_BITS_PER_PIN;
++
++ return 0;
+ }
+
+ #define RK3308_DRV_GRF_OFFSET 0x100
+
+-static void rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+@@ -1436,14 +1460,16 @@ static void rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+
+ *bit = (pin_num % RK3288_DRV_PINS_PER_REG);
+ *bit *= RK3288_DRV_BITS_PER_PIN;
++
++ return 0;
+ }
+
+ #define RK3368_PULL_GRF_OFFSET 0x100
+ #define RK3368_PULL_PMU_OFFSET 0x10
+
+-static void rk3368_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int rk3368_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+@@ -1467,14 +1493,16 @@ static void rk3368_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ *bit = (pin_num % RK3188_PULL_PINS_PER_REG);
+ *bit *= RK3188_PULL_BITS_PER_PIN;
+ }
++
++ return 0;
+ }
+
+ #define RK3368_DRV_PMU_OFFSET 0x20
+ #define RK3368_DRV_GRF_OFFSET 0x200
+
+-static void rk3368_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int rk3368_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+@@ -1498,15 +1526,17 @@ static void rk3368_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+ *bit = (pin_num % RK3288_DRV_PINS_PER_REG);
+ *bit *= RK3288_DRV_BITS_PER_PIN;
+ }
++
++ return 0;
+ }
+
+ #define RK3399_PULL_GRF_OFFSET 0xe040
+ #define RK3399_PULL_PMU_OFFSET 0x40
+ #define RK3399_DRV_3BITS_PER_PIN 3
+
+-static void rk3399_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int rk3399_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+@@ -1532,11 +1562,13 @@ static void rk3399_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ *bit = (pin_num % RK3188_PULL_PINS_PER_REG);
+ *bit *= RK3188_PULL_BITS_PER_PIN;
+ }
++
++ return 0;
+ }
+
+-static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+ int drv_num = (pin_num / 8);
+@@ -1553,6 +1585,8 @@ static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+ *bit = (pin_num % 8) * 3;
+ else
+ *bit = (pin_num % 8) * 2;
++
++ return 0;
+ }
+
+ #define RK3568_PULL_PMU_OFFSET 0x20
+@@ -1561,9 +1595,9 @@ static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+ #define RK3568_PULL_PINS_PER_REG 8
+ #define RK3568_PULL_BANK_STRIDE 0x10
+
+-static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+@@ -1584,6 +1618,8 @@ static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ *bit = (pin_num % RK3568_PULL_PINS_PER_REG);
+ *bit *= RK3568_PULL_BITS_PER_PIN;
+ }
++
++ return 0;
+ }
+
+ #define RK3568_DRV_PMU_OFFSET 0x70
+@@ -1592,9 +1628,9 @@ static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ #define RK3568_DRV_PINS_PER_REG 2
+ #define RK3568_DRV_BANK_STRIDE 0x40
+
+-static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+- int pin_num, struct regmap **regmap,
+- int *reg, u8 *bit)
++static int rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+@@ -1615,6 +1651,8 @@ static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+ *bit = (pin_num % RK3568_DRV_PINS_PER_REG);
+ *bit *= RK3568_DRV_BITS_PER_PIN;
+ }
++
++ return 0;
+ }
+
+ static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = {
+@@ -1637,7 +1675,9 @@ static int rockchip_get_drive_perpin(struct rockchip_pin_bank *bank,
+ u8 bit;
+ int drv_type = bank->drv[pin_num / 8].drv_type;
+
+- ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit);
++ ret = ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit);
++ if (ret)
++ return ret;
+
+ switch (drv_type) {
+ case DRV_TYPE_IO_1V8_3V0_AUTO:
+@@ -1717,7 +1757,9 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
+ dev_dbg(dev, "setting drive of GPIO%d-%d to %d\n",
+ bank->bank_num, pin_num, strength);
+
+- ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit);
++ ret = ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit);
++ if (ret)
++ return ret;
+ if (ctrl->type == RK3568) {
+ rmask_bits = RK3568_DRV_BITS_PER_PIN;
+ ret = (1 << (strength + 1)) - 1;
+@@ -1830,7 +1872,9 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
+ if (ctrl->type == RK3066B)
+ return PIN_CONFIG_BIAS_DISABLE;
+
+- ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit);
++ ret = ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit);
++ if (ret)
++ return ret;
+
+ ret = regmap_read(regmap, reg, &data);
+ if (ret)
+@@ -1877,7 +1921,9 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
+ if (ctrl->type == RK3066B)
+ return pull ? -EINVAL : 0;
+
+- ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit);
++ ret = ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit);
++ if (ret)
++ return ret;
+
+ switch (ctrl->type) {
+ case RK2928:
+diff --git a/drivers/pinctrl/pinctrl-rockchip.h b/drivers/pinctrl/pinctrl-rockchip.h
+index 98a01a616da6..59116e13758d 100644
+--- a/drivers/pinctrl/pinctrl-rockchip.h
++++ b/drivers/pinctrl/pinctrl-rockchip.h
+@@ -230,10 +230,10 @@ struct rockchip_pin_ctrl {
+ struct rockchip_mux_route_data *iomux_routes;
+ u32 niomux_routes;
+
+- void (*pull_calc_reg)(struct rockchip_pin_bank *bank,
++ int (*pull_calc_reg)(struct rockchip_pin_bank *bank,
+ int pin_num, struct regmap **regmap,
+ int *reg, u8 *bit);
+- void (*drv_calc_reg)(struct rockchip_pin_bank *bank,
++ int (*drv_calc_reg)(struct rockchip_pin_bank *bank,
+ int pin_num, struct regmap **regmap,
+ int *reg, u8 *bit);
+ int (*schmitt_calc_reg)(struct rockchip_pin_bank *bank,
+--
+2.39.0
+
--- /dev/null
+From 5209535a5ffb14bd47e777f0dba15c9c8096a904 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Jan 2023 08:46:53 +0000
+Subject: pinctrl: rockchip: fix mux route data for rk3568
+
+From: Jonas Karlman <jonas@kwiboo.se>
+
+[ Upstream commit 431d1531466033909d2e8c754a7dc3704b70843f ]
+
+IO mux selection is configured in PMU_GRF_SOC_CON4 and GRF_IOFUNC_SEL0-5
+regs on RK3568. pwm0-2 is configured in PMU_GRF reg and the rest is
+configured in GRF_IOFUNC regs according to TRM [1].
+
+Update mux route data to reflect this and use proper detection pin for
+UART1 IO mux M1.
+
+This fixes HDMITX IO mux M1 selection and makes it possible to enable
+HDMI CEC on my Radxa ROCK 3 Model A v1.31 board.
+
+[1] http://opensource.rock-chips.com/images/2/26/Rockchip_RK3568_TRM_Part1_V1.3-20220930P.PDF
+
+Fixes: c0dadc0e47a8 ("pinctrl: rockchip: add support for rk3568")
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Link: https://lore.kernel.org/r/20230110084636.1141740-1-jonas@kwiboo.se
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-rockchip.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
+index 0ca830fcf371..c33cbf7568db 100644
+--- a/drivers/pinctrl/pinctrl-rockchip.c
++++ b/drivers/pinctrl/pinctrl-rockchip.c
+@@ -758,19 +758,19 @@ static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
+ RK_MUXROUTE_PMU(0, RK_PB5, 4, 0x0110, WRITE_MASK_VAL(3, 2, 1)), /* PWM1 IO mux M1 */
+ RK_MUXROUTE_PMU(0, RK_PC1, 1, 0x0110, WRITE_MASK_VAL(5, 4, 0)), /* PWM2 IO mux M0 */
+ RK_MUXROUTE_PMU(0, RK_PB6, 4, 0x0110, WRITE_MASK_VAL(5, 4, 1)), /* PWM2 IO mux M1 */
+- RK_MUXROUTE_PMU(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */
++ RK_MUXROUTE_GRF(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */
+ RK_MUXROUTE_GRF(2, RK_PA1, 4, 0x0300, WRITE_MASK_VAL(0, 0, 1)), /* CAN0 IO mux M1 */
+ RK_MUXROUTE_GRF(1, RK_PA1, 3, 0x0300, WRITE_MASK_VAL(2, 2, 0)), /* CAN1 IO mux M0 */
+ RK_MUXROUTE_GRF(4, RK_PC3, 3, 0x0300, WRITE_MASK_VAL(2, 2, 1)), /* CAN1 IO mux M1 */
+ RK_MUXROUTE_GRF(4, RK_PB5, 3, 0x0300, WRITE_MASK_VAL(4, 4, 0)), /* CAN2 IO mux M0 */
+ RK_MUXROUTE_GRF(2, RK_PB2, 4, 0x0300, WRITE_MASK_VAL(4, 4, 1)), /* CAN2 IO mux M1 */
+ RK_MUXROUTE_GRF(4, RK_PC4, 1, 0x0300, WRITE_MASK_VAL(6, 6, 0)), /* HPDIN IO mux M0 */
+- RK_MUXROUTE_PMU(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */
++ RK_MUXROUTE_GRF(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */
+ RK_MUXROUTE_GRF(3, RK_PB1, 3, 0x0300, WRITE_MASK_VAL(8, 8, 0)), /* GMAC1 IO mux M0 */
+ RK_MUXROUTE_GRF(4, RK_PA7, 3, 0x0300, WRITE_MASK_VAL(8, 8, 1)), /* GMAC1 IO mux M1 */
+ RK_MUXROUTE_GRF(4, RK_PD1, 1, 0x0300, WRITE_MASK_VAL(10, 10, 0)), /* HDMITX IO mux M0 */
+- RK_MUXROUTE_PMU(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */
+- RK_MUXROUTE_PMU(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */
++ RK_MUXROUTE_GRF(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */
++ RK_MUXROUTE_GRF(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */
+ RK_MUXROUTE_GRF(4, RK_PB4, 1, 0x0300, WRITE_MASK_VAL(14, 14, 1)), /* I2C2 IO mux M1 */
+ RK_MUXROUTE_GRF(1, RK_PA0, 1, 0x0304, WRITE_MASK_VAL(0, 0, 0)), /* I2C3 IO mux M0 */
+ RK_MUXROUTE_GRF(3, RK_PB6, 4, 0x0304, WRITE_MASK_VAL(0, 0, 1)), /* I2C3 IO mux M1 */
+@@ -796,7 +796,7 @@ static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
+ RK_MUXROUTE_GRF(4, RK_PC3, 1, 0x0308, WRITE_MASK_VAL(12, 12, 1)), /* PWM15 IO mux M1 */
+ RK_MUXROUTE_GRF(3, RK_PD2, 3, 0x0308, WRITE_MASK_VAL(14, 14, 0)), /* SDMMC2 IO mux M0 */
+ RK_MUXROUTE_GRF(3, RK_PA5, 5, 0x0308, WRITE_MASK_VAL(14, 14, 1)), /* SDMMC2 IO mux M1 */
+- RK_MUXROUTE_PMU(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */
++ RK_MUXROUTE_GRF(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */
+ RK_MUXROUTE_GRF(2, RK_PD3, 3, 0x030c, WRITE_MASK_VAL(0, 0, 1)), /* SPI0 IO mux M1 */
+ RK_MUXROUTE_GRF(2, RK_PB5, 3, 0x030c, WRITE_MASK_VAL(2, 2, 0)), /* SPI1 IO mux M0 */
+ RK_MUXROUTE_GRF(3, RK_PC3, 3, 0x030c, WRITE_MASK_VAL(2, 2, 1)), /* SPI1 IO mux M1 */
+@@ -805,8 +805,8 @@ static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
+ RK_MUXROUTE_GRF(4, RK_PB3, 4, 0x030c, WRITE_MASK_VAL(6, 6, 0)), /* SPI3 IO mux M0 */
+ RK_MUXROUTE_GRF(4, RK_PC2, 2, 0x030c, WRITE_MASK_VAL(6, 6, 1)), /* SPI3 IO mux M1 */
+ RK_MUXROUTE_GRF(2, RK_PB4, 2, 0x030c, WRITE_MASK_VAL(8, 8, 0)), /* UART1 IO mux M0 */
+- RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */
+- RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */
++ RK_MUXROUTE_GRF(3, RK_PD6, 4, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */
++ RK_MUXROUTE_GRF(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */
+ RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x030c, WRITE_MASK_VAL(10, 10, 1)), /* UART2 IO mux M1 */
+ RK_MUXROUTE_GRF(1, RK_PA1, 2, 0x030c, WRITE_MASK_VAL(12, 12, 0)), /* UART3 IO mux M0 */
+ RK_MUXROUTE_GRF(3, RK_PB7, 4, 0x030c, WRITE_MASK_VAL(12, 12, 1)), /* UART3 IO mux M1 */
+@@ -836,13 +836,13 @@ static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
+ RK_MUXROUTE_GRF(3, RK_PD6, 5, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */
+ RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */
+ RK_MUXROUTE_GRF(3, RK_PC4, 5, 0x0314, WRITE_MASK_VAL(1, 0, 2)), /* PDM IO mux M2 */
+- RK_MUXROUTE_PMU(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */
++ RK_MUXROUTE_GRF(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */
+ RK_MUXROUTE_GRF(2, RK_PD0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 1)), /* PCIE20 IO mux M1 */
+ RK_MUXROUTE_GRF(1, RK_PB0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 2)), /* PCIE20 IO mux M2 */
+- RK_MUXROUTE_PMU(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */
++ RK_MUXROUTE_GRF(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */
+ RK_MUXROUTE_GRF(2, RK_PD2, 4, 0x0314, WRITE_MASK_VAL(5, 4, 1)), /* PCIE30X1 IO mux M1 */
+ RK_MUXROUTE_GRF(1, RK_PA5, 4, 0x0314, WRITE_MASK_VAL(5, 4, 2)), /* PCIE30X1 IO mux M2 */
+- RK_MUXROUTE_PMU(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */
++ RK_MUXROUTE_GRF(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */
+ RK_MUXROUTE_GRF(2, RK_PD4, 4, 0x0314, WRITE_MASK_VAL(7, 6, 1)), /* PCIE30X2 IO mux M1 */
+ RK_MUXROUTE_GRF(4, RK_PC2, 4, 0x0314, WRITE_MASK_VAL(7, 6, 2)), /* PCIE30X2 IO mux M2 */
+ };
+--
+2.39.0
+
--- /dev/null
+From 335b20accf1708d347667efcf44377c941f28f29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Jan 2023 17:29:58 +0000
+Subject: pinctrl: rockchip: fix reading pull type on rk3568
+
+From: Jonas Karlman <jonas@kwiboo.se>
+
+[ Upstream commit 31b62a98de42cf65d76e4dcfb571af067d27d83a ]
+
+When reading pinconf-pins from debugfs it fails to get the configured pull
+type on RK3568, "unsupported pinctrl type" error messages is also reported.
+
+Fix this by adding support for RK3568 in rockchip_get_pull, including a
+reverse of the pull-up value swap applied in rockchip_set_pull so that
+pull-up is correctly reported in pinconf-pins.
+Also update the workaround comment to reflect affected pins, GPIO0_D3-D6.
+
+Fixes: c0dadc0e47a8 ("pinctrl: rockchip: add support for rk3568")
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Reviewed-by: Heiko Stuebner <heiko@sntech.de>
+Reviewed-by: Jianqun Xu <jay.xu@rock-chips.com>
+Link: https://lore.kernel.org/r/20230110172955.1258840-1-jonas@kwiboo.se
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-rockchip.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
+index 4888840dfc33..0ca830fcf371 100644
+--- a/drivers/pinctrl/pinctrl-rockchip.c
++++ b/drivers/pinctrl/pinctrl-rockchip.c
+@@ -1893,9 +1893,18 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
+ case RK3308:
+ case RK3368:
+ case RK3399:
++ case RK3568:
+ pull_type = bank->pull_type[pin_num / 8];
+ data >>= bit;
+ data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1;
++ /*
++ * In the TRM, pull-up being 1 for everything except the GPIO0_D3-D6,
++ * where that pull up value becomes 3.
++ */
++ if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) {
++ if (data == 3)
++ data = 1;
++ }
+
+ return rockchip_pull_list[pull_type][data];
+ default:
+@@ -1951,7 +1960,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
+ }
+ }
+ /*
+- * In the TRM, pull-up being 1 for everything except the GPIO0_D0-D6,
++ * In the TRM, pull-up being 1 for everything except the GPIO0_D3-D6,
+ * where that pull up value becomes 3.
+ */
+ if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) {
+--
+2.39.0
+
--- /dev/null
+From ba57a35e0a2029bbdbe9998bdb1a0a38e9ecc241 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Nov 2021 14:42:27 +0200
+Subject: pinctrl/rockchip: Use temporary variable for struct device
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit e4dd7fd5ff0acb3f3ed290f52afe20fd840d22b0 ]
+
+Use temporary variable for struct device to make code neater.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Heiko Stuebner <heiko@sntech.de>
+Stable-dep-of: 31b62a98de42 ("pinctrl: rockchip: fix reading pull type on rk3568")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-rockchip.c | 116 +++++++++++++----------------
+ 1 file changed, 53 insertions(+), 63 deletions(-)
+
+diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
+index 25ec0d22f184..fcff8e7798b3 100644
+--- a/drivers/pinctrl/pinctrl-rockchip.c
++++ b/drivers/pinctrl/pinctrl-rockchip.c
+@@ -285,6 +285,7 @@ static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev,
+ {
+ struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+ const struct rockchip_pin_group *grp;
++ struct device *dev = info->dev;
+ struct pinctrl_map *new_map;
+ struct device_node *parent;
+ int map_num = 1;
+@@ -296,8 +297,7 @@ static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev,
+ */
+ grp = pinctrl_name_to_group(info, np->name);
+ if (!grp) {
+- dev_err(info->dev, "unable to find group for node %pOFn\n",
+- np);
++ dev_err(dev, "unable to find group for node %pOFn\n", np);
+ return -EINVAL;
+ }
+
+@@ -331,7 +331,7 @@ static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev,
+ new_map[i].data.configs.num_configs = grp->data[i].nconfigs;
+ }
+
+- dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n",
++ dev_dbg(dev, "maps: function %s group %s num %d\n",
+ (*map)->data.mux.function, (*map)->data.mux.group, map_num);
+
+ return 0;
+@@ -927,20 +927,20 @@ static int rockchip_verify_mux(struct rockchip_pin_bank *bank,
+ int pin, int mux)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
++ struct device *dev = info->dev;
+ int iomux_num = (pin / 8);
+
+ if (iomux_num > 3)
+ return -EINVAL;
+
+ if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
+- dev_err(info->dev, "pin %d is unrouted\n", pin);
++ dev_err(dev, "pin %d is unrouted\n", pin);
+ return -EINVAL;
+ }
+
+ if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) {
+ if (mux != RK_FUNC_GPIO) {
+- dev_err(info->dev,
+- "pin %d only supports a gpio mux\n", pin);
++ dev_err(dev, "pin %d only supports a gpio mux\n", pin);
+ return -ENOTSUPP;
+ }
+ }
+@@ -964,6 +964,7 @@ static int rockchip_verify_mux(struct rockchip_pin_bank *bank,
+ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
++ struct device *dev = info->dev;
+ int iomux_num = (pin / 8);
+ struct regmap *regmap;
+ int reg, ret, mask, mux_type;
+@@ -977,8 +978,7 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
+ if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
+ return 0;
+
+- dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n",
+- bank->bank_num, pin, mux);
++ dev_dbg(dev, "setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
+
+ regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
+ ? info->regmap_pmu : info->regmap_base;
+@@ -1630,6 +1630,7 @@ static int rockchip_get_drive_perpin(struct rockchip_pin_bank *bank,
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+ struct rockchip_pin_ctrl *ctrl = info->ctrl;
++ struct device *dev = info->dev;
+ struct regmap *regmap;
+ int reg, ret;
+ u32 data, temp, rmask_bits;
+@@ -1675,7 +1676,7 @@ static int rockchip_get_drive_perpin(struct rockchip_pin_bank *bank,
+ bit -= 16;
+ break;
+ default:
+- dev_err(info->dev, "unsupported bit: %d for pinctrl drive type: %d\n",
++ dev_err(dev, "unsupported bit: %d for pinctrl drive type: %d\n",
+ bit, drv_type);
+ return -EINVAL;
+ }
+@@ -1687,8 +1688,7 @@ static int rockchip_get_drive_perpin(struct rockchip_pin_bank *bank,
+ rmask_bits = RK3288_DRV_BITS_PER_PIN;
+ break;
+ default:
+- dev_err(info->dev, "unsupported pinctrl drive type: %d\n",
+- drv_type);
++ dev_err(dev, "unsupported pinctrl drive type: %d\n", drv_type);
+ return -EINVAL;
+ }
+
+@@ -1707,13 +1707,14 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+ struct rockchip_pin_ctrl *ctrl = info->ctrl;
++ struct device *dev = info->dev;
+ struct regmap *regmap;
+ int reg, ret, i;
+ u32 data, rmask, rmask_bits, temp;
+ u8 bit;
+ int drv_type = bank->drv[pin_num / 8].drv_type;
+
+- dev_dbg(info->dev, "setting drive of GPIO%d-%d to %d\n",
++ dev_dbg(dev, "setting drive of GPIO%d-%d to %d\n",
+ bank->bank_num, pin_num, strength);
+
+ ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit);
+@@ -1735,8 +1736,7 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
+ }
+
+ if (ret < 0) {
+- dev_err(info->dev, "unsupported driver strength %d\n",
+- strength);
++ dev_err(dev, "unsupported driver strength %d\n", strength);
+ return ret;
+ }
+
+@@ -1775,7 +1775,7 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
+ bit -= 16;
+ break;
+ default:
+- dev_err(info->dev, "unsupported bit: %d for pinctrl drive type: %d\n",
++ dev_err(dev, "unsupported bit: %d for pinctrl drive type: %d\n",
+ bit, drv_type);
+ return -EINVAL;
+ }
+@@ -1786,8 +1786,7 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
+ rmask_bits = RK3288_DRV_BITS_PER_PIN;
+ break;
+ default:
+- dev_err(info->dev, "unsupported pinctrl drive type: %d\n",
+- drv_type);
++ dev_err(dev, "unsupported pinctrl drive type: %d\n", drv_type);
+ return -EINVAL;
+ }
+
+@@ -1821,6 +1820,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+ struct rockchip_pin_ctrl *ctrl = info->ctrl;
++ struct device *dev = info->dev;
+ struct regmap *regmap;
+ int reg, ret, pull_type;
+ u8 bit;
+@@ -1855,7 +1855,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
+
+ return rockchip_pull_list[pull_type][data];
+ default:
+- dev_err(info->dev, "unsupported pinctrl type\n");
++ dev_err(dev, "unsupported pinctrl type\n");
+ return -EINVAL;
+ };
+ }
+@@ -1865,13 +1865,13 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+ struct rockchip_pin_ctrl *ctrl = info->ctrl;
++ struct device *dev = info->dev;
+ struct regmap *regmap;
+ int reg, ret, i, pull_type;
+ u8 bit;
+ u32 data, rmask;
+
+- dev_dbg(info->dev, "setting pull of GPIO%d-%d to %d\n",
+- bank->bank_num, pin_num, pull);
++ dev_dbg(dev, "setting pull of GPIO%d-%d to %d\n", bank->bank_num, pin_num, pull);
+
+ /* rk3066b does support any pulls */
+ if (ctrl->type == RK3066B)
+@@ -1914,8 +1914,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
+ }
+
+ if (ret < 0) {
+- dev_err(info->dev, "unsupported pull setting %d\n",
+- pull);
++ dev_err(dev, "unsupported pull setting %d\n", pull);
+ return ret;
+ }
+
+@@ -1927,7 +1926,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
+ ret = regmap_update_bits(regmap, reg, rmask, data);
+ break;
+ default:
+- dev_err(info->dev, "unsupported pinctrl type\n");
++ dev_err(dev, "unsupported pinctrl type\n");
+ return -EINVAL;
+ }
+
+@@ -2018,12 +2017,13 @@ static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+ struct rockchip_pin_ctrl *ctrl = info->ctrl;
++ struct device *dev = info->dev;
+ struct regmap *regmap;
+ int reg, ret;
+ u8 bit;
+ u32 data, rmask;
+
+- dev_dbg(info->dev, "setting input schmitt of GPIO%d-%d to %d\n",
++ dev_dbg(dev, "setting input schmitt of GPIO%d-%d to %d\n",
+ bank->bank_num, pin_num, enable);
+
+ ret = ctrl->schmitt_calc_reg(bank, pin_num, ®map, ®, &bit);
+@@ -2083,10 +2083,11 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
+ struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+ const unsigned int *pins = info->groups[group].pins;
+ const struct rockchip_pin_config *data = info->groups[group].data;
++ struct device *dev = info->dev;
+ struct rockchip_pin_bank *bank;
+ int cnt, ret = 0;
+
+- dev_dbg(info->dev, "enable function %s group %s\n",
++ dev_dbg(dev, "enable function %s group %s\n",
+ info->functions[selector].name, info->groups[group].name);
+
+ /*
+@@ -2392,6 +2393,7 @@ static int rockchip_pinctrl_parse_groups(struct device_node *np,
+ struct rockchip_pinctrl *info,
+ u32 index)
+ {
++ struct device *dev = info->dev;
+ struct rockchip_pin_bank *bank;
+ int size;
+ const __be32 *list;
+@@ -2399,7 +2401,7 @@ static int rockchip_pinctrl_parse_groups(struct device_node *np,
+ int i, j;
+ int ret;
+
+- dev_dbg(info->dev, "group(%d): %pOFn\n", index, np);
++ dev_dbg(dev, "group(%d): %pOFn\n", index, np);
+
+ /* Initialise group */
+ grp->name = np->name;
+@@ -2412,18 +2414,14 @@ static int rockchip_pinctrl_parse_groups(struct device_node *np,
+ /* we do not check return since it's safe node passed down */
+ size /= sizeof(*list);
+ if (!size || size % 4) {
+- dev_err(info->dev, "wrong pins number or pins and configs should be by 4\n");
++ dev_err(dev, "wrong pins number or pins and configs should be by 4\n");
+ return -EINVAL;
+ }
+
+ grp->npins = size / 4;
+
+- grp->pins = devm_kcalloc(info->dev, grp->npins, sizeof(unsigned int),
+- GFP_KERNEL);
+- grp->data = devm_kcalloc(info->dev,
+- grp->npins,
+- sizeof(struct rockchip_pin_config),
+- GFP_KERNEL);
++ grp->pins = devm_kcalloc(dev, grp->npins, sizeof(*grp->pins), GFP_KERNEL);
++ grp->data = devm_kcalloc(dev, grp->npins, sizeof(*grp->data), GFP_KERNEL);
+ if (!grp->pins || !grp->data)
+ return -ENOMEM;
+
+@@ -2457,6 +2455,7 @@ static int rockchip_pinctrl_parse_functions(struct device_node *np,
+ struct rockchip_pinctrl *info,
+ u32 index)
+ {
++ struct device *dev = info->dev;
+ struct device_node *child;
+ struct rockchip_pmx_func *func;
+ struct rockchip_pin_group *grp;
+@@ -2464,7 +2463,7 @@ static int rockchip_pinctrl_parse_functions(struct device_node *np,
+ static u32 grp_index;
+ u32 i = 0;
+
+- dev_dbg(info->dev, "parse function(%d): %pOFn\n", index, np);
++ dev_dbg(dev, "parse function(%d): %pOFn\n", index, np);
+
+ func = &info->functions[index];
+
+@@ -2474,8 +2473,7 @@ static int rockchip_pinctrl_parse_functions(struct device_node *np,
+ if (func->ngroups <= 0)
+ return 0;
+
+- func->groups = devm_kcalloc(info->dev,
+- func->ngroups, sizeof(char *), GFP_KERNEL);
++ func->groups = devm_kcalloc(dev, func->ngroups, sizeof(*func->groups), GFP_KERNEL);
+ if (!func->groups)
+ return -ENOMEM;
+
+@@ -2503,20 +2501,14 @@ static int rockchip_pinctrl_parse_dt(struct platform_device *pdev,
+
+ rockchip_pinctrl_child_count(info, np);
+
+- dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions);
+- dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups);
++ dev_dbg(dev, "nfunctions = %d\n", info->nfunctions);
++ dev_dbg(dev, "ngroups = %d\n", info->ngroups);
+
+- info->functions = devm_kcalloc(dev,
+- info->nfunctions,
+- sizeof(struct rockchip_pmx_func),
+- GFP_KERNEL);
++ info->functions = devm_kcalloc(dev, info->nfunctions, sizeof(*info->functions), GFP_KERNEL);
+ if (!info->functions)
+ return -ENOMEM;
+
+- info->groups = devm_kcalloc(dev,
+- info->ngroups,
+- sizeof(struct rockchip_pin_group),
+- GFP_KERNEL);
++ info->groups = devm_kcalloc(dev, info->ngroups, sizeof(*info->groups), GFP_KERNEL);
+ if (!info->groups)
+ return -ENOMEM;
+
+@@ -2528,7 +2520,7 @@ static int rockchip_pinctrl_parse_dt(struct platform_device *pdev,
+
+ ret = rockchip_pinctrl_parse_functions(child, info, i++);
+ if (ret) {
+- dev_err(&pdev->dev, "failed to parse function\n");
++ dev_err(dev, "failed to parse function\n");
+ of_node_put(child);
+ return ret;
+ }
+@@ -2543,6 +2535,7 @@ static int rockchip_pinctrl_register(struct platform_device *pdev,
+ struct pinctrl_desc *ctrldesc = &info->pctl;
+ struct pinctrl_pin_desc *pindesc, *pdesc;
+ struct rockchip_pin_bank *pin_bank;
++ struct device *dev = &pdev->dev;
+ int pin, bank, ret;
+ int k;
+
+@@ -2552,9 +2545,7 @@ static int rockchip_pinctrl_register(struct platform_device *pdev,
+ ctrldesc->pmxops = &rockchip_pmx_ops;
+ ctrldesc->confops = &rockchip_pinconf_ops;
+
+- pindesc = devm_kcalloc(&pdev->dev,
+- info->ctrl->nr_pins, sizeof(*pindesc),
+- GFP_KERNEL);
++ pindesc = devm_kcalloc(dev, info->ctrl->nr_pins, sizeof(*pindesc), GFP_KERNEL);
+ if (!pindesc)
+ return -ENOMEM;
+
+@@ -2579,9 +2570,9 @@ static int rockchip_pinctrl_register(struct platform_device *pdev,
+ if (ret)
+ return ret;
+
+- info->pctl_dev = devm_pinctrl_register(&pdev->dev, ctrldesc, info);
++ info->pctl_dev = devm_pinctrl_register(dev, ctrldesc, info);
+ if (IS_ERR(info->pctl_dev)) {
+- dev_err(&pdev->dev, "could not register pinctrl driver\n");
++ dev_err(dev, "could not register pinctrl driver\n");
+ return PTR_ERR(info->pctl_dev);
+ }
+
+@@ -2595,8 +2586,9 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
+ struct rockchip_pinctrl *d,
+ struct platform_device *pdev)
+ {
++ struct device *dev = &pdev->dev;
++ struct device_node *node = dev->of_node;
+ const struct of_device_id *match;
+- struct device_node *node = pdev->dev.of_node;
+ struct rockchip_pin_ctrl *ctrl;
+ struct rockchip_pin_bank *bank;
+ int grf_offs, pmu_offs, drv_grf_offs, drv_pmu_offs, i, j;
+@@ -2648,7 +2640,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
+ drv_pmu_offs : drv_grf_offs;
+ }
+
+- dev_dbg(d->dev, "bank %d, iomux %d has iom_offset 0x%x drv_offset 0x%x\n",
++ dev_dbg(dev, "bank %d, iomux %d has iom_offset 0x%x drv_offset 0x%x\n",
+ i, j, iom->offset, drv->offset);
+
+ /*
+@@ -2757,8 +2749,8 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
+ {
+ struct rockchip_pinctrl *info;
+ struct device *dev = &pdev->dev;
++ struct device_node *np = dev->of_node, *node;
+ struct rockchip_pin_ctrl *ctrl;
+- struct device_node *np = pdev->dev.of_node, *node;
+ struct resource *res;
+ void __iomem *base;
+ int ret;
+@@ -2795,8 +2787,8 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
+
+ rockchip_regmap_config.max_register = resource_size(res) - 4;
+ rockchip_regmap_config.name = "rockchip,pinctrl";
+- info->regmap_base = devm_regmap_init_mmio(&pdev->dev, base,
+- &rockchip_regmap_config);
++ info->regmap_base =
++ devm_regmap_init_mmio(dev, base, &rockchip_regmap_config);
+
+ /* to check for the old dt-bindings */
+ info->reg_size = resource_size(res);
+@@ -2808,12 +2800,10 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+- rockchip_regmap_config.max_register =
+- resource_size(res) - 4;
++ rockchip_regmap_config.max_register = resource_size(res) - 4;
+ rockchip_regmap_config.name = "rockchip,pinctrl-pull";
+- info->regmap_pull = devm_regmap_init_mmio(&pdev->dev,
+- base,
+- &rockchip_regmap_config);
++ info->regmap_pull =
++ devm_regmap_init_mmio(dev, base, &rockchip_regmap_config);
+ }
+ }
+
+@@ -2834,7 +2824,7 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
+
+ ret = of_platform_populate(np, NULL, NULL, &pdev->dev);
+ if (ret) {
+- dev_err(&pdev->dev, "failed to register gpio device\n");
++ dev_err(dev, "failed to register gpio device\n");
+ return ret;
+ }
+
+--
+2.39.0
+
--- /dev/null
+From 8d2cb396e0e6534b6dbf7e45895586178a3bb569 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Jan 2023 19:18:41 +0100
+Subject: platform/x86: asus-nb-wmi: Add alternate mapping for KEY_SCREENLOCK
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit db9494895b405bf318dc7e563dee6daa51b3b6ed ]
+
+The 0x33 keycode is emitted by Fn + F6 on a ASUS FX705GE laptop.
+
+Reported-by: Nemcev Aleksey <Nemcev_Aleksey@inbox.ru>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20230112181841.84652-1-hdegoede@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/asus-nb-wmi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
+index a81dc4b191b7..4d7327b67a7d 100644
+--- a/drivers/platform/x86/asus-nb-wmi.c
++++ b/drivers/platform/x86/asus-nb-wmi.c
+@@ -521,6 +521,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = {
+ { KE_KEY, 0x30, { KEY_VOLUMEUP } },
+ { KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
+ { KE_KEY, 0x32, { KEY_MUTE } },
++ { KE_KEY, 0x33, { KEY_SCREENLOCK } },
+ { KE_KEY, 0x35, { KEY_SCREENLOCK } },
+ { KE_KEY, 0x40, { KEY_PREVIOUSSONG } },
+ { KE_KEY, 0x41, { KEY_NEXTSONG } },
+--
+2.39.0
+
--- /dev/null
+From 4e5798e9e1914112e0277f7dfcbfdf6ef4394345 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Dec 2022 13:11:03 +0100
+Subject: platform/x86: touchscreen_dmi: Add info for the CSL Panther Tab HD
+
+From: Michael Klein <m.klein@mvz-labor-lb.de>
+
+[ Upstream commit 36c2b9d6710427f802494ba070621cb415198293 ]
+
+Add touchscreen info for the CSL Panther Tab HD.
+
+Signed-off-by: Michael Klein <m.klein@mvz-labor-lb.de>
+Link: https://lore.kernel.org/r/20221220121103.uiwn5l7fii2iggct@LLGMVZLB-0037
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/touchscreen_dmi.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c
+index 3d0790263fa7..93671037fd59 100644
+--- a/drivers/platform/x86/touchscreen_dmi.c
++++ b/drivers/platform/x86/touchscreen_dmi.c
+@@ -255,6 +255,23 @@ static const struct ts_dmi_data connect_tablet9_data = {
+ .properties = connect_tablet9_props,
+ };
+
++static const struct property_entry csl_panther_tab_hd_props[] = {
++ PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
++ PROPERTY_ENTRY_U32("touchscreen-min-y", 20),
++ PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
++ PROPERTY_ENTRY_U32("touchscreen-size-y", 1526),
++ PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
++ PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
++ PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-csl-panther-tab-hd.fw"),
++ PROPERTY_ENTRY_U32("silead,max-fingers", 10),
++ { }
++};
++
++static const struct ts_dmi_data csl_panther_tab_hd_data = {
++ .acpi_name = "MSSL1680:00",
++ .properties = csl_panther_tab_hd_props,
++};
++
+ static const struct property_entry cube_iwork8_air_props[] = {
+ PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
+ PROPERTY_ENTRY_U32("touchscreen-min-y", 3),
+@@ -1100,6 +1117,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Tablet 9"),
+ },
+ },
++ {
++ /* CSL Panther Tab HD */
++ .driver_data = (void *)&csl_panther_tab_hd_data,
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "CSL Computer GmbH & Co. KG"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "CSL Panther Tab HD"),
++ },
++ },
+ {
+ /* CUBE iwork8 Air */
+ .driver_data = (void *)&cube_iwork8_air_data,
+--
+2.39.0
+
--- /dev/null
+From ec883629fbd3d7c3877e9baefd2049c6c8dfcca5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Dec 2022 17:05:41 +0100
+Subject: PM: AVS: qcom-cpr: Fix an error handling path in cpr_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 6049aae52392539e505bfb8ccbcff3c26f1d2f0b ]
+
+If an error occurs after a successful pm_genpd_init() call, it should be
+undone by a corresponding pm_genpd_remove().
+
+Add the missing call in the error handling path, as already done in the
+remove function.
+
+Fixes: bf6910abf548 ("power: avs: Add support for CPR (Core Power Reduction)")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/0f520597dbad89ab99c217c8986912fa53eaf5f9.1671293108.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/cpr.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/qcom/cpr.c b/drivers/soc/qcom/cpr.c
+index 84dd93472a25..e61cff3d9c8a 100644
+--- a/drivers/soc/qcom/cpr.c
++++ b/drivers/soc/qcom/cpr.c
+@@ -1710,12 +1710,16 @@ static int cpr_probe(struct platform_device *pdev)
+
+ ret = of_genpd_add_provider_simple(dev->of_node, &drv->pd);
+ if (ret)
+- return ret;
++ goto err_remove_genpd;
+
+ platform_set_drvdata(pdev, drv);
+ cpr_debugfs_init(drv);
+
+ return 0;
++
++err_remove_genpd:
++ pm_genpd_remove(&drv->pd);
++ return ret;
+ }
+
+ static int cpr_remove(struct platform_device *pdev)
+--
+2.39.0
+
--- /dev/null
+From 2324dff0579e30622cd6a671ba98614737a2ea48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 19:39:08 -0800
+Subject: ptdma: pt_core_execute_cmd() should use spinlock
+
+From: Eric Pilmore <epilmore@gigaio.com>
+
+[ Upstream commit 95e5fda3b5f9ed8239b145da3fa01e641cf5d53c ]
+
+The interrupt handler (pt_core_irq_handler()) of the ptdma
+driver can be called from interrupt context. The code flow
+in this function can lead down to pt_core_execute_cmd() which
+will attempt to grab a mutex, which is not appropriate in
+interrupt context and ultimately leads to a kernel panic.
+The fix here changes this mutex to a spinlock, which has
+been verified to resolve the issue.
+
+Fixes: fa5d823b16a9 ("dmaengine: ptdma: Initial driver for the AMD PTDMA")
+Signed-off-by: Eric Pilmore <epilmore@gigaio.com>
+Link: https://lore.kernel.org/r/20230119033907.35071-1-epilmore@gigaio.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/ptdma/ptdma-dev.c | 7 ++++---
+ drivers/dma/ptdma/ptdma.h | 2 +-
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/dma/ptdma/ptdma-dev.c b/drivers/dma/ptdma/ptdma-dev.c
+index daafea5bc35d..bca4063b0dce 100644
+--- a/drivers/dma/ptdma/ptdma-dev.c
++++ b/drivers/dma/ptdma/ptdma-dev.c
+@@ -71,12 +71,13 @@ static int pt_core_execute_cmd(struct ptdma_desc *desc, struct pt_cmd_queue *cmd
+ bool soc = FIELD_GET(DWORD0_SOC, desc->dw0);
+ u8 *q_desc = (u8 *)&cmd_q->qbase[cmd_q->qidx];
+ u32 tail;
++ unsigned long flags;
+
+ if (soc) {
+ desc->dw0 |= FIELD_PREP(DWORD0_IOC, desc->dw0);
+ desc->dw0 &= ~DWORD0_SOC;
+ }
+- mutex_lock(&cmd_q->q_mutex);
++ spin_lock_irqsave(&cmd_q->q_lock, flags);
+
+ /* Copy 32-byte command descriptor to hw queue. */
+ memcpy(q_desc, desc, 32);
+@@ -91,7 +92,7 @@ static int pt_core_execute_cmd(struct ptdma_desc *desc, struct pt_cmd_queue *cmd
+
+ /* Turn the queue back on using our cached control register */
+ pt_start_queue(cmd_q);
+- mutex_unlock(&cmd_q->q_mutex);
++ spin_unlock_irqrestore(&cmd_q->q_lock, flags);
+
+ return 0;
+ }
+@@ -197,7 +198,7 @@ int pt_core_init(struct pt_device *pt)
+
+ cmd_q->pt = pt;
+ cmd_q->dma_pool = dma_pool;
+- mutex_init(&cmd_q->q_mutex);
++ spin_lock_init(&cmd_q->q_lock);
+
+ /* Page alignment satisfies our needs for N <= 128 */
+ cmd_q->qsize = Q_SIZE(Q_DESC_SIZE);
+diff --git a/drivers/dma/ptdma/ptdma.h b/drivers/dma/ptdma/ptdma.h
+index afbf192c9230..0f0b400a864e 100644
+--- a/drivers/dma/ptdma/ptdma.h
++++ b/drivers/dma/ptdma/ptdma.h
+@@ -196,7 +196,7 @@ struct pt_cmd_queue {
+ struct ptdma_desc *qbase;
+
+ /* Aligned queue start address (per requirement) */
+- struct mutex q_mutex ____cacheline_aligned;
++ spinlock_t q_lock ____cacheline_aligned;
+ unsigned int qidx;
+
+ unsigned int qsize;
+--
+2.39.0
+
--- /dev/null
+From 77c1dce0f39456e37cea4fa4dc379f81bead0e4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 13:32:28 +0000
+Subject: r8152: add vendor/device ID pair for Microsoft Devkit
+
+From: Andre Przywara <andre.przywara@arm.com>
+
+[ Upstream commit be53771c87f4e322a9835d3faa9cd73a4ecdec5b ]
+
+The Microsoft Devkit 2023 is a an ARM64 based machine featuring a
+Realtek 8153 USB3.0-to-GBit Ethernet adapter. As in their other
+machines, Microsoft uses a custom USB device ID.
+
+Add the respective ID values to the driver. This makes Ethernet work on
+the MS Devkit device. The chip has been visually confirmed to be a
+RTL8153.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Link: https://lore.kernel.org/r/20230111133228.190801-1-andre.przywara@arm.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/r8152.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
+index 109c288d8b47..cf6941b1d280 100644
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -9809,6 +9809,7 @@ static const struct usb_device_id rtl8152_table[] = {
+ REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07ab),
+ REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07c6),
+ REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x0927),
++ REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x0c5e),
+ REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, 0xa101),
+ REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x304f),
+ REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3054),
+--
+2.39.0
+
--- /dev/null
+From 342aca9643f61f6a076b8013fdbbc2d969f41108 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 13:37:11 +0000
+Subject: RDMA/core: Fix ib block iterator counter overflow
+
+From: Yonatan Nachum <ynachum@amazon.com>
+
+[ Upstream commit 0afec5e9cea732cb47014655685a2a47fb180c31 ]
+
+When registering a new DMA MR after selecting the best aligned page size
+for it, we iterate over the given sglist to split each entry to smaller,
+aligned to the selected page size, DMA blocks.
+
+In given circumstances where the sg entry and page size fit certain
+sizes and the sg entry is not aligned to the selected page size, the
+total size of the aligned pages we need to cover the sg entry is >= 4GB.
+Under this circumstances, while iterating page aligned blocks, the
+counter responsible for counting how much we advanced from the start of
+the sg entry is overflowed because its type is u32 and we pass 4GB in
+size. This can lead to an infinite loop inside the iterator function
+because the overflow prevents the counter to be larger
+than the size of the sg entry.
+
+Fix the presented problem by changing the advancement condition to
+eliminate overflow.
+
+Backtrace:
+[ 192.374329] efa_reg_user_mr_dmabuf
+[ 192.376783] efa_register_mr
+[ 192.382579] pgsz_bitmap 0xfffff000 rounddown 0x80000000
+[ 192.386423] pg_sz [0x80000000] umem_length[0xc0000000]
+[ 192.392657] start 0x0 length 0xc0000000 params.page_shift 31 params.page_num 3
+[ 192.399559] hp_cnt[3], pages_in_hp[524288]
+[ 192.403690] umem->sgt_append.sgt.nents[1]
+[ 192.407905] number entries: [1], pg_bit: [31]
+[ 192.411397] biter->__sg_nents [1] biter->__sg [0000000008b0c5d8]
+[ 192.415601] biter->__sg_advance [665837568] sg_dma_len[3221225472]
+[ 192.419823] biter->__sg_nents [1] biter->__sg [0000000008b0c5d8]
+[ 192.423976] biter->__sg_advance [2813321216] sg_dma_len[3221225472]
+[ 192.428243] biter->__sg_nents [1] biter->__sg [0000000008b0c5d8]
+[ 192.432397] biter->__sg_advance [665837568] sg_dma_len[3221225472]
+
+Fixes: a808273a495c ("RDMA/verbs: Add a DMA iterator to return aligned contiguous memory blocks")
+Signed-off-by: Yonatan Nachum <ynachum@amazon.com>
+Link: https://lore.kernel.org/r/20230109133711.13678-1-ynachum@amazon.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/verbs.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
+index b721085bb597..f0c07e4ba438 100644
+--- a/drivers/infiniband/core/verbs.c
++++ b/drivers/infiniband/core/verbs.c
+@@ -2965,15 +2965,18 @@ EXPORT_SYMBOL(__rdma_block_iter_start);
+ bool __rdma_block_iter_next(struct ib_block_iter *biter)
+ {
+ unsigned int block_offset;
++ unsigned int sg_delta;
+
+ if (!biter->__sg_nents || !biter->__sg)
+ return false;
+
+ biter->__dma_addr = sg_dma_address(biter->__sg) + biter->__sg_advance;
+ block_offset = biter->__dma_addr & (BIT_ULL(biter->__pg_bit) - 1);
+- biter->__sg_advance += BIT_ULL(biter->__pg_bit) - block_offset;
++ sg_delta = BIT_ULL(biter->__pg_bit) - block_offset;
+
+- if (biter->__sg_advance >= sg_dma_len(biter->__sg)) {
++ if (sg_dma_len(biter->__sg) - biter->__sg_advance > sg_delta) {
++ biter->__sg_advance += sg_delta;
++ } else {
+ biter->__sg_advance = 0;
+ biter->__sg = sg_next(biter->__sg);
+ biter->__sg_nents--;
+--
+2.39.0
+
--- /dev/null
+From 906535973df4867e316c222825cb2b76af7b8674 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 08:49:58 +0800
+Subject: reset: uniphier-glue: Fix possible null-ptr-deref
+
+From: Hui Tang <tanghui20@huawei.com>
+
+[ Upstream commit 3a2390c6777e3f6662980c6cfc25cafe9e4fef98 ]
+
+It will cause null-ptr-deref when resource_size(res) invoked,
+if platform_get_resource() returns NULL.
+
+Fixes: 499fef09a323 ("reset: uniphier: add USB3 core reset control")
+Signed-off-by: Hui Tang <tanghui20@huawei.com>
+Reviewed-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+Link: https://lore.kernel.org/r/20221114004958.258513-1-tanghui20@huawei.com
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/reset/reset-uniphier-glue.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/reset/reset-uniphier-glue.c b/drivers/reset/reset-uniphier-glue.c
+index 6d422c69532c..7493e9618837 100644
+--- a/drivers/reset/reset-uniphier-glue.c
++++ b/drivers/reset/reset-uniphier-glue.c
+@@ -33,7 +33,6 @@ static int uniphier_glue_reset_probe(struct platform_device *pdev)
+ struct device *dev = &pdev->dev;
+ struct uniphier_glue_reset_priv *priv;
+ struct resource *res;
+- resource_size_t size;
+ int i, ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+@@ -46,7 +45,6 @@ static int uniphier_glue_reset_probe(struct platform_device *pdev)
+ return -EINVAL;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- size = resource_size(res);
+ priv->rdata.membase = devm_ioremap_resource(dev, res);
+ if (IS_ERR(priv->rdata.membase))
+ return PTR_ERR(priv->rdata.membase);
+@@ -74,7 +72,7 @@ static int uniphier_glue_reset_probe(struct platform_device *pdev)
+
+ spin_lock_init(&priv->rdata.lock);
+ priv->rdata.rcdev.owner = THIS_MODULE;
+- priv->rdata.rcdev.nr_resets = size * BITS_PER_BYTE;
++ priv->rdata.rcdev.nr_resets = resource_size(res) * BITS_PER_BYTE;
+ priv->rdata.rcdev.ops = &reset_simple_ops;
+ priv->rdata.rcdev.of_node = dev->of_node;
+ priv->rdata.active_low = true;
+--
+2.39.0
+
--- /dev/null
+From 9563bba300c6eded9bbd8f7cb706dd11aa9c6d36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Dec 2021 10:38:28 +0100
+Subject: reset: uniphier-glue: Use reset_control_bulk API
+
+From: Philipp Zabel <p.zabel@pengutronix.de>
+
+[ Upstream commit 176cae38719196a43cd8ae08377413a3884a9f15 ]
+
+This driver already uses the clk_bulk API. Simplify the driver by using
+the reset_control_bulk API as well.
+
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+Reviewed-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+Link: https://lore.kernel.org/r/20211215093829.3209416-1-p.zabel@pengutronix.de
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+Stable-dep-of: 3a2390c6777e ("reset: uniphier-glue: Fix possible null-ptr-deref")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/reset/reset-uniphier-glue.c | 33 ++++++++++++-----------------
+ 1 file changed, 14 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/reset/reset-uniphier-glue.c b/drivers/reset/reset-uniphier-glue.c
+index 027990b79f61..6d422c69532c 100644
+--- a/drivers/reset/reset-uniphier-glue.c
++++ b/drivers/reset/reset-uniphier-glue.c
+@@ -23,7 +23,7 @@ struct uniphier_glue_reset_soc_data {
+
+ struct uniphier_glue_reset_priv {
+ struct clk_bulk_data clk[MAX_CLKS];
+- struct reset_control *rst[MAX_RSTS];
++ struct reset_control_bulk_data rst[MAX_RSTS];
+ struct reset_simple_data rdata;
+ const struct uniphier_glue_reset_soc_data *data;
+ };
+@@ -34,8 +34,7 @@ static int uniphier_glue_reset_probe(struct platform_device *pdev)
+ struct uniphier_glue_reset_priv *priv;
+ struct resource *res;
+ resource_size_t size;
+- const char *name;
+- int i, ret, nr;
++ int i, ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+@@ -58,22 +57,20 @@ static int uniphier_glue_reset_probe(struct platform_device *pdev)
+ if (ret)
+ return ret;
+
+- for (i = 0; i < priv->data->nrsts; i++) {
+- name = priv->data->reset_names[i];
+- priv->rst[i] = devm_reset_control_get_shared(dev, name);
+- if (IS_ERR(priv->rst[i]))
+- return PTR_ERR(priv->rst[i]);
+- }
++ for (i = 0; i < priv->data->nrsts; i++)
++ priv->rst[i].id = priv->data->reset_names[i];
++ ret = devm_reset_control_bulk_get_shared(dev, priv->data->nrsts,
++ priv->rst);
++ if (ret)
++ return ret;
+
+ ret = clk_bulk_prepare_enable(priv->data->nclks, priv->clk);
+ if (ret)
+ return ret;
+
+- for (nr = 0; nr < priv->data->nrsts; nr++) {
+- ret = reset_control_deassert(priv->rst[nr]);
+- if (ret)
+- goto out_rst_assert;
+- }
++ ret = reset_control_bulk_deassert(priv->data->nrsts, priv->rst);
++ if (ret)
++ goto out_clk_disable;
+
+ spin_lock_init(&priv->rdata.lock);
+ priv->rdata.rcdev.owner = THIS_MODULE;
+@@ -91,9 +88,9 @@ static int uniphier_glue_reset_probe(struct platform_device *pdev)
+ return 0;
+
+ out_rst_assert:
+- while (nr--)
+- reset_control_assert(priv->rst[nr]);
++ reset_control_bulk_assert(priv->data->nrsts, priv->rst);
+
++out_clk_disable:
+ clk_bulk_disable_unprepare(priv->data->nclks, priv->clk);
+
+ return ret;
+@@ -102,10 +99,8 @@ static int uniphier_glue_reset_probe(struct platform_device *pdev)
+ static int uniphier_glue_reset_remove(struct platform_device *pdev)
+ {
+ struct uniphier_glue_reset_priv *priv = platform_get_drvdata(pdev);
+- int i;
+
+- for (i = 0; i < priv->data->nrsts; i++)
+- reset_control_assert(priv->rst[i]);
++ reset_control_bulk_assert(priv->data->nrsts, priv->rst);
+
+ clk_bulk_disable_unprepare(priv->data->nclks, priv->clk);
+
+--
+2.39.0
+
--- /dev/null
+From aba3846aef0dd10d62f0ed5f643ddb416bdbc641 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jan 2023 15:11:07 +0100
+Subject: s390/debug: add _ASM_S390_ prefix to header guard
+
+From: Niklas Schnelle <schnelle@linux.ibm.com>
+
+[ Upstream commit 0d4d52361b6c29bf771acd4fa461f06d78fb2fac ]
+
+Using DEBUG_H without a prefix is very generic and inconsistent with
+other header guards in arch/s390/include/asm. In fact it collides with
+the same name in the ath9k wireless driver though that depends on !S390
+via disabled wireless support. Let's just use a consistent header guard
+name and prevent possible future trouble.
+
+Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/include/asm/debug.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/s390/include/asm/debug.h b/arch/s390/include/asm/debug.h
+index 19a55e1e3a0c..5fc91a90657e 100644
+--- a/arch/s390/include/asm/debug.h
++++ b/arch/s390/include/asm/debug.h
+@@ -4,8 +4,8 @@
+ *
+ * Copyright IBM Corp. 1999, 2020
+ */
+-#ifndef DEBUG_H
+-#define DEBUG_H
++#ifndef _ASM_S390_DEBUG_H
++#define _ASM_S390_DEBUG_H
+
+ #include <linux/string.h>
+ #include <linux/spinlock.h>
+@@ -487,4 +487,4 @@ void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas);
+
+ #endif /* MODULE */
+
+-#endif /* DEBUG_H */
++#endif /* _ASM_S390_DEBUG_H */
+--
+2.39.0
+
--- /dev/null
+From 19294ae040c17ec0ccd194f8250d1b2efac70250 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 17:15:19 +0100
+Subject: s390: expicitly align _edata and _end symbols on page boundary
+
+From: Alexander Gordeev <agordeev@linux.ibm.com>
+
+[ Upstream commit 45d619bdaf799196d702a9ae464b07066d6db2f9 ]
+
+Symbols _edata and _end in the linker script are the
+only unaligned expicitly on page boundary. Although
+_end is aligned implicitly by BSS_SECTION macro that
+is still inconsistent and could lead to a bug if a tool
+or function would assume that _edata is as aligned as
+others.
+
+For example, vmem_map_init() function does not align
+symbols _etext, _einittext etc. Should these symbols
+be unaligned as well, the size of ranges to update
+were short on one page.
+
+Instead of fixing every occurrence of this kind in the
+code and external tools just force the alignment on
+these two symbols.
+
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/vmlinux.lds.S | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
+index b508ccad4856..8ce1615c1046 100644
+--- a/arch/s390/kernel/vmlinux.lds.S
++++ b/arch/s390/kernel/vmlinux.lds.S
+@@ -80,6 +80,7 @@ SECTIONS
+ _end_amode31_refs = .;
+ }
+
++ . = ALIGN(PAGE_SIZE);
+ _edata = .; /* End of data section */
+
+ /* will be freed after init */
+@@ -194,6 +195,7 @@ SECTIONS
+
+ BSS_SECTION(PAGE_SIZE, 4 * PAGE_SIZE, PAGE_SIZE)
+
++ . = ALIGN(PAGE_SIZE);
+ _end = . ;
+
+ /*
+--
+2.39.0
+
--- /dev/null
+From 861aa27180d85825e8de4d0ec7b01177710300d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Jan 2023 16:55:29 -0800
+Subject: sch_htb: Avoid grafting on htb_destroy_class_offload when destroying
+ htb
+
+From: Rahul Rameshbabu <rrameshbabu@nvidia.com>
+
+[ Upstream commit a22b7388d658ecfcd226600c8c34ce4481e88655 ]
+
+Peek at old qdisc and graft only when deleting a leaf class in the htb,
+rather than when deleting the htb itself. Do not peek at the qdisc of the
+netdev queue when destroying the htb. The caller may already have grafted a
+new qdisc that is not part of the htb structure being destroyed.
+
+This fix resolves two use cases.
+
+ 1. Using tc to destroy the htb.
+ - Netdev was being prematurely activated before the htb was fully
+ destroyed.
+ 2. Using tc to replace the htb with another qdisc (which also leads to
+ the htb being destroyed).
+ - Premature netdev activation like previous case. Newly grafted qdisc
+ was also getting accidentally overwritten when destroying the htb.
+
+Fixes: d03b195b5aa0 ("sch_htb: Hierarchical QoS hardware offload")
+Signed-off-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
+Reviewed-by: Saeed Mahameed <saeedm@nvidia.com>
+Reviewed-by: Maxim Mikityanskiy <maxtram95@gmail.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Link: https://lore.kernel.org/r/20230113005528.302625-1-rrameshbabu@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_htb.c | 27 ++++++++++++++++-----------
+ 1 file changed, 16 insertions(+), 11 deletions(-)
+
+diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
+index caabdaa2f30f..45b92e40082e 100644
+--- a/net/sched/sch_htb.c
++++ b/net/sched/sch_htb.c
+@@ -1558,7 +1558,7 @@ static int htb_destroy_class_offload(struct Qdisc *sch, struct htb_class *cl,
+ struct tc_htb_qopt_offload offload_opt;
+ struct netdev_queue *dev_queue;
+ struct Qdisc *q = cl->leaf.q;
+- struct Qdisc *old = NULL;
++ struct Qdisc *old;
+ int err;
+
+ if (cl->level)
+@@ -1566,14 +1566,17 @@ static int htb_destroy_class_offload(struct Qdisc *sch, struct htb_class *cl,
+
+ WARN_ON(!q);
+ dev_queue = htb_offload_get_queue(cl);
+- old = htb_graft_helper(dev_queue, NULL);
+- if (destroying)
+- /* Before HTB is destroyed, the kernel grafts noop_qdisc to
+- * all queues.
++ /* When destroying, caller qdisc_graft grafts the new qdisc and invokes
++ * qdisc_put for the qdisc being destroyed. htb_destroy_class_offload
++ * does not need to graft or qdisc_put the qdisc being destroyed.
++ */
++ if (!destroying) {
++ old = htb_graft_helper(dev_queue, NULL);
++ /* Last qdisc grafted should be the same as cl->leaf.q when
++ * calling htb_delete.
+ */
+- WARN_ON(!(old->flags & TCQ_F_BUILTIN));
+- else
+ WARN_ON(old != q);
++ }
+
+ if (cl->parent) {
+ cl->parent->bstats_bias.bytes += q->bstats.bytes;
+@@ -1589,10 +1592,12 @@ static int htb_destroy_class_offload(struct Qdisc *sch, struct htb_class *cl,
+ };
+ err = htb_offload(qdisc_dev(sch), &offload_opt);
+
+- if (!err || destroying)
+- qdisc_put(old);
+- else
+- htb_graft_helper(dev_queue, old);
++ if (!destroying) {
++ if (!err)
++ qdisc_put(old);
++ else
++ htb_graft_helper(dev_queue, old);
++ }
+
+ if (last_child)
+ return err;
+--
+2.39.0
+
--- /dev/null
+From 5a5f8cb5f48b6da9cd765c8cd2500f2b60a91e9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Jan 2023 12:03:20 +0800
+Subject: scsi: hisi_sas: Set a port invalid only if there are no devices
+ attached when refreshing port id
+
+From: Yihang Li <liyihang9@huawei.com>
+
+[ Upstream commit f58c89700630da6554b24fd3df293a24874c10c1 ]
+
+Currently the driver sets the port invalid if one phy in the port is not
+enabled, which may cause issues in expander situation. In directly attached
+situation, if phy up doesn't occur in time when refreshing port id, the
+port is incorrectly set to invalid which will also cause disk lost.
+
+Therefore set a port invalid only if there are no devices attached to the
+port.
+
+Signed-off-by: Yihang Li <liyihang9@huawei.com>
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Link: https://lore.kernel.org/r/1672805000-141102-3-git-send-email-chenxiang66@hisilicon.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 9515c45affa5..7d93783c09a5 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1414,7 +1414,7 @@ static void hisi_sas_refresh_port_id(struct hisi_hba *hisi_hba)
+ device->linkrate = phy->sas_phy.linkrate;
+
+ hisi_hba->hw->setup_itct(hisi_hba, sas_dev);
+- } else
++ } else if (!port->port_attached)
+ port->id = 0xff;
+ }
+ }
+--
+2.39.0
+
--- /dev/null
+From bce6ea0e95edfe32b5752faf71561235ec603180 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Nov 2022 09:07:52 +0800
+Subject: scsi: iscsi: Fix multiple iSCSI session unbind events sent to
+ userspace
+
+From: Wenchao Hao <haowenchao@huawei.com>
+
+[ Upstream commit a3be19b91ea7121d388084e8c07f5b1b982eb40c ]
+
+It was observed that the kernel would potentially send
+ISCSI_KEVENT_UNBIND_SESSION multiple times. Introduce 'target_state' in
+iscsi_cls_session() to make sure session will send only one unbind session
+event.
+
+This introduces a regression wrt. the issue fixed in commit 13e60d3ba287
+("scsi: iscsi: Report unbind session event when the target has been
+removed"). If iscsid dies for any reason after sending an unbind session to
+kernel, once iscsid is restarted, the kernel's ISCSI_KEVENT_UNBIND_SESSION
+event is lost and userspace is then unable to logout. However, the session
+is actually in invalid state (its target_id is INVALID) so iscsid should
+not sync this session during restart.
+
+Consequently we need to check the session's target state during iscsid
+restart. If session is in unbound state, do not sync this session and
+perform session teardown. This is OK because once a session is unbound, we
+can not recover it any more (mainly because its target id is INVALID).
+
+Signed-off-by: Wenchao Hao <haowenchao@huawei.com>
+Link: https://lore.kernel.org/r/20221126010752.231917-1-haowenchao@huawei.com
+Reviewed-by: Mike Christie <michael.christie@oracle.com>
+Reviewed-by: Wu Bo <wubo40@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_transport_iscsi.c | 50 ++++++++++++++++++++++++++---
+ include/scsi/scsi_transport_iscsi.h | 9 ++++++
+ 2 files changed, 54 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index cc39cbef9d7f..4d23e5af20d3 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -1679,6 +1679,13 @@ static const char *iscsi_session_state_name(int state)
+ return name;
+ }
+
++static char *iscsi_session_target_state_name[] = {
++ [ISCSI_SESSION_TARGET_UNBOUND] = "UNBOUND",
++ [ISCSI_SESSION_TARGET_ALLOCATED] = "ALLOCATED",
++ [ISCSI_SESSION_TARGET_SCANNED] = "SCANNED",
++ [ISCSI_SESSION_TARGET_UNBINDING] = "UNBINDING",
++};
++
+ int iscsi_session_chkready(struct iscsi_cls_session *session)
+ {
+ int err;
+@@ -1807,9 +1814,13 @@ static int iscsi_user_scan_session(struct device *dev, void *data)
+ if ((scan_data->channel == SCAN_WILD_CARD ||
+ scan_data->channel == 0) &&
+ (scan_data->id == SCAN_WILD_CARD ||
+- scan_data->id == id))
++ scan_data->id == id)) {
+ scsi_scan_target(&session->dev, 0, id,
+ scan_data->lun, scan_data->rescan);
++ spin_lock_irqsave(&session->lock, flags);
++ session->target_state = ISCSI_SESSION_TARGET_SCANNED;
++ spin_unlock_irqrestore(&session->lock, flags);
++ }
+ }
+
+ user_scan_exit:
+@@ -1998,31 +2009,41 @@ static void __iscsi_unbind_session(struct work_struct *work)
+ struct iscsi_cls_host *ihost = shost->shost_data;
+ unsigned long flags;
+ unsigned int target_id;
++ bool remove_target = true;
+
+ ISCSI_DBG_TRANS_SESSION(session, "Unbinding session\n");
+
+ /* Prevent new scans and make sure scanning is not in progress */
+ mutex_lock(&ihost->mutex);
+ spin_lock_irqsave(&session->lock, flags);
+- if (session->target_id == ISCSI_MAX_TARGET) {
++ if (session->target_state == ISCSI_SESSION_TARGET_ALLOCATED) {
++ remove_target = false;
++ } else if (session->target_state != ISCSI_SESSION_TARGET_SCANNED) {
+ spin_unlock_irqrestore(&session->lock, flags);
+ mutex_unlock(&ihost->mutex);
+- goto unbind_session_exit;
++ ISCSI_DBG_TRANS_SESSION(session,
++ "Skipping target unbinding: Session is unbound/unbinding.\n");
++ return;
+ }
+
++ session->target_state = ISCSI_SESSION_TARGET_UNBINDING;
+ target_id = session->target_id;
+ session->target_id = ISCSI_MAX_TARGET;
+ spin_unlock_irqrestore(&session->lock, flags);
+ mutex_unlock(&ihost->mutex);
+
+- scsi_remove_target(&session->dev);
++ if (remove_target)
++ scsi_remove_target(&session->dev);
+
+ if (session->ida_used)
+ ida_simple_remove(&iscsi_sess_ida, target_id);
+
+-unbind_session_exit:
+ iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
+ ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n");
++
++ spin_lock_irqsave(&session->lock, flags);
++ session->target_state = ISCSI_SESSION_TARGET_UNBOUND;
++ spin_unlock_irqrestore(&session->lock, flags);
+ }
+
+ static void __iscsi_destroy_session(struct work_struct *work)
+@@ -2091,6 +2112,9 @@ int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id)
+ session->ida_used = true;
+ } else
+ session->target_id = target_id;
++ spin_lock_irqsave(&session->lock, flags);
++ session->target_state = ISCSI_SESSION_TARGET_ALLOCATED;
++ spin_unlock_irqrestore(&session->lock, flags);
+
+ dev_set_name(&session->dev, "session%u", session->sid);
+ err = device_add(&session->dev);
+@@ -4391,6 +4415,19 @@ iscsi_session_attr(def_taskmgmt_tmo, ISCSI_PARAM_DEF_TASKMGMT_TMO, 0);
+ iscsi_session_attr(discovery_parent_idx, ISCSI_PARAM_DISCOVERY_PARENT_IDX, 0);
+ iscsi_session_attr(discovery_parent_type, ISCSI_PARAM_DISCOVERY_PARENT_TYPE, 0);
+
++static ssize_t
++show_priv_session_target_state(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ struct iscsi_cls_session *session = iscsi_dev_to_session(dev->parent);
++
++ return sysfs_emit(buf, "%s\n",
++ iscsi_session_target_state_name[session->target_state]);
++}
++
++static ISCSI_CLASS_ATTR(priv_sess, target_state, S_IRUGO,
++ show_priv_session_target_state, NULL);
++
+ static ssize_t
+ show_priv_session_state(struct device *dev, struct device_attribute *attr,
+ char *buf)
+@@ -4493,6 +4530,7 @@ static struct attribute *iscsi_session_attrs[] = {
+ &dev_attr_sess_boot_target.attr,
+ &dev_attr_priv_sess_recovery_tmo.attr,
+ &dev_attr_priv_sess_state.attr,
++ &dev_attr_priv_sess_target_state.attr,
+ &dev_attr_priv_sess_creator.attr,
+ &dev_attr_sess_chap_out_idx.attr,
+ &dev_attr_sess_chap_in_idx.attr,
+@@ -4606,6 +4644,8 @@ static umode_t iscsi_session_attr_is_visible(struct kobject *kobj,
+ return S_IRUGO | S_IWUSR;
+ else if (attr == &dev_attr_priv_sess_state.attr)
+ return S_IRUGO;
++ else if (attr == &dev_attr_priv_sess_target_state.attr)
++ return S_IRUGO;
+ else if (attr == &dev_attr_priv_sess_creator.attr)
+ return S_IRUGO;
+ else if (attr == &dev_attr_priv_sess_target_id.attr)
+diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
+index 0f2f149ad916..304ccf153928 100644
+--- a/include/scsi/scsi_transport_iscsi.h
++++ b/include/scsi/scsi_transport_iscsi.h
+@@ -236,6 +236,14 @@ enum {
+ ISCSI_SESSION_FREE,
+ };
+
++enum {
++ ISCSI_SESSION_TARGET_UNBOUND,
++ ISCSI_SESSION_TARGET_ALLOCATED,
++ ISCSI_SESSION_TARGET_SCANNED,
++ ISCSI_SESSION_TARGET_UNBINDING,
++ ISCSI_SESSION_TARGET_MAX,
++};
++
+ #define ISCSI_MAX_TARGET -1
+
+ struct iscsi_cls_session {
+@@ -262,6 +270,7 @@ struct iscsi_cls_session {
+ */
+ pid_t creator;
+ int state;
++ int target_state; /* session target bind state */
+ int sid; /* session id */
+ void *dd_data; /* LLD private data */
+ struct device dev; /* sysfs transport/container device */
+--
+2.39.0
+
--- /dev/null
+From 1eaedf6f0c8ba137074f6fabc64ffcd689159920 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 10:18:47 -0500
+Subject: selftests/net: toeplitz: fix race on tpacket_v3 block close
+
+From: Willem de Bruijn <willemb@google.com>
+
+[ Upstream commit 903848249a781d76d59561d51676c95b3a4d7162 ]
+
+Avoid race between process wakeup and tpacket_v3 block timeout.
+
+The test waits for cfg_timeout_msec for packets to arrive. Packets
+arrive in tpacket_v3 rings, which pass packets ("frames") to the
+process in batches ("blocks"). The sk waits for req3.tp_retire_blk_tov
+msec to release a block.
+
+Set the block timeout lower than the process waiting time, else
+the process may find that no block has been released by the time it
+scans the socket list. Convert to a ring of more than one, smaller,
+blocks with shorter timeouts. Blocks must be page aligned, so >= 64KB.
+
+Fixes: 5ebfb4cc3048 ("selftests/net: toeplitz test")
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Link: https://lore.kernel.org/r/20230118151847.4124260-1-willemdebruijn.kernel@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/toeplitz.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/tools/testing/selftests/net/toeplitz.c b/tools/testing/selftests/net/toeplitz.c
+index c5489341cfb8..8ce96028341d 100644
+--- a/tools/testing/selftests/net/toeplitz.c
++++ b/tools/testing/selftests/net/toeplitz.c
+@@ -213,7 +213,7 @@ static char *recv_frame(const struct ring_state *ring, char *frame)
+ }
+
+ /* A single TPACKET_V3 block can hold multiple frames */
+-static void recv_block(struct ring_state *ring)
++static bool recv_block(struct ring_state *ring)
+ {
+ struct tpacket_block_desc *block;
+ char *frame;
+@@ -221,7 +221,7 @@ static void recv_block(struct ring_state *ring)
+
+ block = (void *)(ring->mmap + ring->idx * ring_block_sz);
+ if (!(block->hdr.bh1.block_status & TP_STATUS_USER))
+- return;
++ return false;
+
+ frame = (char *)block;
+ frame += block->hdr.bh1.offset_to_first_pkt;
+@@ -233,6 +233,8 @@ static void recv_block(struct ring_state *ring)
+
+ block->hdr.bh1.block_status = TP_STATUS_KERNEL;
+ ring->idx = (ring->idx + 1) % ring_block_nr;
++
++ return true;
+ }
+
+ /* simple test: sleep once unconditionally and then process all rings */
+@@ -243,7 +245,7 @@ static void process_rings(void)
+ usleep(1000 * cfg_timeout_msec);
+
+ for (i = 0; i < num_cpus; i++)
+- recv_block(&rings[i]);
++ do {} while (recv_block(&rings[i]));
+
+ fprintf(stderr, "count: pass=%u nohash=%u fail=%u\n",
+ frames_received - frames_nohash - frames_error,
+@@ -255,12 +257,12 @@ static char *setup_ring(int fd)
+ struct tpacket_req3 req3 = {0};
+ void *ring;
+
+- req3.tp_retire_blk_tov = cfg_timeout_msec;
++ req3.tp_retire_blk_tov = cfg_timeout_msec / 8;
+ req3.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH;
+
+ req3.tp_frame_size = 2048;
+ req3.tp_frame_nr = 1 << 10;
+- req3.tp_block_nr = 2;
++ req3.tp_block_nr = 16;
+
+ req3.tp_block_size = req3.tp_frame_size * req3.tp_frame_nr;
+ req3.tp_block_size /= req3.tp_block_nr;
+--
+2.39.0
+
--- /dev/null
+memory-tegra-remove-clients-sid-override-programming.patch
+memory-atmel-sdramc-fix-missing-clk_disable_unprepar.patch
+memory-mvebu-devbus-fix-missing-clk_disable_unprepar.patch
+dmaengine-ti-k3-udma-do-conditional-decrement-of-udm.patch
+arm64-dts-imx8mp-phycore-som-remove-invalid-pmic-pro.patch
+arm-dts-imx6ul-pico-dwarf-use-clock-frequency.patch
+arm-dts-imx7d-pico-use-clock-frequency.patch
+arm-dts-imx6qdl-gw560x-remove-incorrect-uart-has-rts.patch
+arm64-dts-imx8mm-beacon-fix-ecspi2-pinmux.patch
+arm-imx-add-missing-of_node_put.patch
+hid-intel_ish-hid-add-check-for-ishtp_dma_tx_map.patch
+arm64-dts-imx8mm-venice-gw7901-fix-usb2-controller-o.patch
+soc-imx8m-fix-incorrect-check-for-of_clk_get_by_name.patch
+reset-uniphier-glue-use-reset_control_bulk-api.patch
+reset-uniphier-glue-fix-possible-null-ptr-deref.patch
+edac-highbank-fix-memory-leak-in-highbank_mc_probe.patch
+firmware-arm_scmi-harden-shared-memory-access-in-fet.patch
+firmware-arm_scmi-harden-shared-memory-access-in-fet.patch-9946
+tomoyo-fix-broken-dependency-on-.conf.default.patch
+rdma-core-fix-ib-block-iterator-counter-overflow.patch
+ib-hfi1-reject-a-zero-length-user-expected-buffer.patch
+ib-hfi1-reserve-user-expected-tids.patch
+ib-hfi1-fix-expected-receive-setup-error-exit-issues.patch
+ib-hfi1-immediately-remove-invalid-memory-from-hardw.patch
+ib-hfi1-remove-user-expected-buffer-invalidate-race.patch
+affs-initialize-fsdata-in-affs_truncate.patch
+pm-avs-qcom-cpr-fix-an-error-handling-path-in-cpr_pr.patch
+arm64-dts-qcom-msm8992-don-t-use-sfpb-mutex.patch
+arm64-dts-qcom-msm8992-libra-add-cpu-regulators.patch
+arm64-dts-qcom-msm8992-libra-fix-the-memory-map.patch
+phy-ti-fix-kconfig-warning-and-operator-precedence.patch
+nfsd-fix-use-after-free-in-nfsd4_ssc_setup_dul.patch
+arm-dts-at91-sam9x60-fix-the-ddr-clock-for-sam9x60.patch
+bpf-always-use-raw-spinlock-for-hash-bucket-lock.patch
+bpf-hash-map-avoid-deadlock-with-suitable-hash-mask.patch
+amd-xgbe-tx-flow-ctrl-registers-are-h-w-ver-dependen.patch
+amd-xgbe-delay-an-timeout-during-kr-training.patch
+bpf-fix-pointer-leak-due-to-insufficient-speculative.patch
+phy-rockchip-inno-usb2-fix-missing-clk_disable_unpre.patch
+net-nfc-fix-use-after-free-in-local_cleanup.patch
+net-wan-add-checks-for-null-for-utdm-in-undo_uhdlc_i.patch
+net-enetc-avoid-deadlock-in-enetc_tx_onestep_tstamp.patch
+sch_htb-avoid-grafting-on-htb_destroy_class_offload-.patch
+gpio-use-raw-spinlock-for-gpio-chip-shadowed-data.patch
+gpio-mxc-protect-gpio-irqchip-rmw-with-bgpio-spinloc.patch
+gpio-mxc-always-set-gpios-used-as-interrupt-source-t.patch
+wifi-rndis_wlan-prevent-buffer-overflow-in-rndis_que.patch
+pinctrl-rockchip-use-temporary-variable-for-struct-d.patch
+pinctrl-rockchip-add-error-handling-for-pull-drive-r.patch
+pinctrl-rockchip-fix-reading-pull-type-on-rk3568.patch
+net-stmmac-fix-queue-statistics-reading.patch
+net-sched-sch_taprio-fix-possible-use-after-free.patch
+l2tp-serialize-access-to-sk_user_data-with-sk_callba.patch
+l2tp-don-t-sleep-and-disable-bh-under-writer-side-sk.patch
+l2tp-convert-l2tp_tunnel_list-to-idr.patch
+l2tp-close-all-race-conditions-in-l2tp_tunnel_regist.patch
+octeontx2-pf-avoid-use-of-gfp_kernel-in-atomic-conte.patch
+net-usb-sr9700-handle-negative-len.patch
+net-mdio-validate-parameter-addr-in-mdiobus_get_phy.patch
+hid-check-empty-report_list-in-hid_validate_values.patch
+hid-check-empty-report_list-in-bigben_probe.patch
+net-stmmac-fix-invalid-call-to-mdiobus_get_phy.patch
+pinctrl-rockchip-fix-mux-route-data-for-rk3568.patch
+hid-revert-cherry_mouse_000c-quirk.patch
+usb-gadget-f_fs-prevent-race-during-ffs_ep0_queue_wa.patch
+usb-gadget-f_fs-ensure-ep0req-is-dequeued-before-fre.patch
+bluetooth-fix-possible-deadlock-in-rfcomm_sk_state_c.patch
+net-ipa-disable-ipa-interrupt-during-suspend.patch
+net-mlx5-e-switch-fix-setting-of-reserved-fields-on-.patch
+net-mlx5-eliminate-anonymous-module_init-module_exit.patch
+drm-panfrost-fix-generic_atomic64-dependency.patch
+dmaengine-fix-double-increment-of-client_count-in-dm.patch
+net-macb-fix-ptp-tx-timestamp-failure-due-to-packet-.patch
+virtio-net-correctly-enable-callback-during-start_xm.patch
+l2tp-prevent-lockdep-issue-in-l2tp_tunnel_register.patch
+hid-betop-check-shape-of-output-reports.patch
+cifs-fix-potential-deadlock-in-cache_refresh_path.patch
+dmaengine-xilinx_dma-call-of_node_put-when-breaking-.patch
+phy-phy-can-transceiver-skip-warning-if-no-max-bitra.patch
+drm-amd-display-fix-issues-with-driver-unload.patch
+nvme-pci-fix-timeout-request-state-check.patch
+tcp-avoid-the-lookup-process-failing-to-get-sk-in-eh.patch
+octeontx2-pf-fix-the-use-of-gfp_kernel-in-atomic-con.patch
+ptdma-pt_core_execute_cmd-should-use-spinlock.patch
+device-property-fix-of-node-refcount-leak-in-fwnode_.patch
+w1-fix-deadloop-in-__w1_remove_master_device.patch
+w1-fix-warning-after-calling-w1_process.patch
+driver-core-fix-test_async_probe_init-saves-device-i.patch
+selftests-net-toeplitz-fix-race-on-tpacket_v3-block-.patch
+net-dsa-microchip-ksz9477-port-map-correction-in-alu.patch
+thermal-core-remove-duplicate-information-when-an-er.patch
+thermal-core-rename-trips-to-num_trips.patch
+thermal-validate-new-state-in-cur_state_store.patch
+thermal-core-fix-error-code-in-__thermal_cooling_dev.patch
+thermal-core-call-put_device-only-after-device_regis.patch
+net-stmmac-enable-all-safety-features-by-default.patch
+tcp-fix-rate_app_limited-to-default-to-1.patch
+scsi-iscsi-fix-multiple-iscsi-session-unbind-events-.patch
+cpufreq-add-tegra234-to-cpufreq-dt-platdev-blocklist.patch
+kcsan-test-don-t-put-the-expect-array-on-the-stack.patch
+cpufreq-add-sm6375-to-cpufreq-dt-platdev-blocklist.patch
+asoc-fsl_micfil-correct-the-number-of-steps-on-sx-co.patch
+net-usb-cdc_ether-add-support-for-thales-cinterion-p.patch
+drm-add-orientation-quirk-for-lenovo-ideapad-d330-10.patch
+s390-debug-add-_asm_s390_-prefix-to-header-guard.patch
+s390-expicitly-align-_edata-and-_end-symbols-on-page.patch
+perf-x86-msr-add-emerald-rapids.patch
+perf-x86-intel-uncore-add-emerald-rapids.patch
+cpufreq-armada-37xx-stop-using-0-as-null-pointer.patch
+asoc-fsl_ssi-rename-ac-97-streams-to-avoid-collision.patch
+asoc-fsl-asoc-card-fix-naming-of-ac-97-codec-widgets.patch
+spi-spidev-remove-debug-messages-that-access-spidev-.patch
+kvm-s390-interrupt-use-read_once-before-cmpxchg.patch
+scsi-hisi_sas-set-a-port-invalid-only-if-there-are-n.patch
+r8152-add-vendor-device-id-pair-for-microsoft-devkit.patch
+platform-x86-touchscreen_dmi-add-info-for-the-csl-pa.patch
+platform-x86-asus-nb-wmi-add-alternate-mapping-for-k.patch
+lockref-stop-doing-cpu_relax-in-the-cmpxchg-loop.patch
+firmware-coreboot-check-size-of-table-entry-and-use-.patch
+arm64-dts-imx8mp-correct-usb-clocks.patch
+drm-i915-allow-switching-away-via-vga-switcheroo-if-.patch
--- /dev/null
+From 5b7076a41e6e9a6e9c47f14df8db95864f9910eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 31 Dec 2022 13:58:48 +0400
+Subject: soc: imx8m: Fix incorrect check for of_clk_get_by_name()
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 490748874ebf1875420fc29b335bba2075dd1b5e ]
+
+of_clk_get_by_name() returns error pointers instead of NULL.
+Use IS_ERR() checks the return value to catch errors.
+
+Fixes: 836fb30949d9 ("soc: imx8m: Enable OCOTP clock before reading the register")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/imx/soc-imx8m.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-imx8m.c
+index 28144c699b0c..32ed9dc88e45 100644
+--- a/drivers/soc/imx/soc-imx8m.c
++++ b/drivers/soc/imx/soc-imx8m.c
+@@ -66,8 +66,8 @@ static u32 __init imx8mq_soc_revision(void)
+ ocotp_base = of_iomap(np, 0);
+ WARN_ON(!ocotp_base);
+ clk = of_clk_get_by_name(np, NULL);
+- if (!clk) {
+- WARN_ON(!clk);
++ if (IS_ERR(clk)) {
++ WARN_ON(IS_ERR(clk));
+ return 0;
+ }
+
+--
+2.39.0
+
--- /dev/null
+From 18b7bd9741757f25118f23182ceafd9141759a8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Jan 2023 11:07:19 +0100
+Subject: spi: spidev: remove debug messages that access spidev->spi without
+ locking
+
+From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+
+[ Upstream commit 6b35b173dbc1711f8d272e3f322d2ad697015919 ]
+
+The two debug messages in spidev_open() dereference spidev->spi without
+taking the lock and without checking if it's not null. This can lead to
+a crash. Drop the messages as they're not needed - the user-space will
+get informed about ENOMEM with the syscall return value.
+
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://lore.kernel.org/r/20230106100719.196243-2-brgl@bgdev.pl
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spidev.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
+index d233e2424ad1..922d778df064 100644
+--- a/drivers/spi/spidev.c
++++ b/drivers/spi/spidev.c
+@@ -592,7 +592,6 @@ static int spidev_open(struct inode *inode, struct file *filp)
+ if (!spidev->tx_buffer) {
+ spidev->tx_buffer = kmalloc(bufsiz, GFP_KERNEL);
+ if (!spidev->tx_buffer) {
+- dev_dbg(&spidev->spi->dev, "open/ENOMEM\n");
+ status = -ENOMEM;
+ goto err_find_dev;
+ }
+@@ -601,7 +600,6 @@ static int spidev_open(struct inode *inode, struct file *filp)
+ if (!spidev->rx_buffer) {
+ spidev->rx_buffer = kmalloc(bufsiz, GFP_KERNEL);
+ if (!spidev->rx_buffer) {
+- dev_dbg(&spidev->spi->dev, "open/ENOMEM\n");
+ status = -ENOMEM;
+ goto err_alloc_rx_buf;
+ }
+--
+2.39.0
+
--- /dev/null
+From 69ca0d63362ece010dac429164b856e01b5e3f31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 09:59:41 +0800
+Subject: tcp: avoid the lookup process failing to get sk in ehash table
+
+From: Jason Xing <kernelxing@tencent.com>
+
+[ Upstream commit 3f4ca5fafc08881d7a57daa20449d171f2887043 ]
+
+While one cpu is working on looking up the right socket from ehash
+table, another cpu is done deleting the request socket and is about
+to add (or is adding) the big socket from the table. It means that
+we could miss both of them, even though it has little chance.
+
+Let me draw a call trace map of the server side.
+ CPU 0 CPU 1
+ ----- -----
+tcp_v4_rcv() syn_recv_sock()
+ inet_ehash_insert()
+ -> sk_nulls_del_node_init_rcu(osk)
+__inet_lookup_established()
+ -> __sk_nulls_add_node_rcu(sk, list)
+
+Notice that the CPU 0 is receiving the data after the final ack
+during 3-way shakehands and CPU 1 is still handling the final ack.
+
+Why could this be a real problem?
+This case is happening only when the final ack and the first data
+receiving by different CPUs. Then the server receiving data with
+ACK flag tries to search one proper established socket from ehash
+table, but apparently it fails as my map shows above. After that,
+the server fetches a listener socket and then sends a RST because
+it finds a ACK flag in the skb (data), which obeys RST definition
+in RFC 793.
+
+Besides, Eric pointed out there's one more race condition where it
+handles tw socket hashdance. Only by adding to the tail of the list
+before deleting the old one can we avoid the race if the reader has
+already begun the bucket traversal and it would possibly miss the head.
+
+Many thanks to Eric for great help from beginning to end.
+
+Fixes: 5e0724d027f0 ("tcp/dccp: fix hashdance race for passive sessions")
+Suggested-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Jason Xing <kernelxing@tencent.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://lore.kernel.org/lkml/20230112065336.41034-1-kerneljasonxing@gmail.com/
+Link: https://lore.kernel.org/r/20230118015941.1313-1-kerneljasonxing@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/inet_hashtables.c | 17 +++++++++++++++--
+ net/ipv4/inet_timewait_sock.c | 8 ++++----
+ 2 files changed, 19 insertions(+), 6 deletions(-)
+
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index 0d378da4b1b1..410b6b7998ca 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -571,8 +571,20 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk)
+ spin_lock(lock);
+ if (osk) {
+ WARN_ON_ONCE(sk->sk_hash != osk->sk_hash);
+- ret = sk_nulls_del_node_init_rcu(osk);
+- } else if (found_dup_sk) {
++ ret = sk_hashed(osk);
++ if (ret) {
++ /* Before deleting the node, we insert a new one to make
++ * sure that the look-up-sk process would not miss either
++ * of them and that at least one node would exist in ehash
++ * table all the time. Otherwise there's a tiny chance
++ * that lookup process could find nothing in ehash table.
++ */
++ __sk_nulls_add_node_tail_rcu(sk, list);
++ sk_nulls_del_node_init_rcu(osk);
++ }
++ goto unlock;
++ }
++ if (found_dup_sk) {
+ *found_dup_sk = inet_ehash_lookup_by_sk(sk, list);
+ if (*found_dup_sk)
+ ret = false;
+@@ -581,6 +593,7 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk)
+ if (ret)
+ __sk_nulls_add_node_rcu(sk, list);
+
++unlock:
+ spin_unlock(lock);
+
+ return ret;
+diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
+index 437afe392e66..fe6340c363b4 100644
+--- a/net/ipv4/inet_timewait_sock.c
++++ b/net/ipv4/inet_timewait_sock.c
+@@ -81,10 +81,10 @@ void inet_twsk_put(struct inet_timewait_sock *tw)
+ }
+ EXPORT_SYMBOL_GPL(inet_twsk_put);
+
+-static void inet_twsk_add_node_rcu(struct inet_timewait_sock *tw,
+- struct hlist_nulls_head *list)
++static void inet_twsk_add_node_tail_rcu(struct inet_timewait_sock *tw,
++ struct hlist_nulls_head *list)
+ {
+- hlist_nulls_add_head_rcu(&tw->tw_node, list);
++ hlist_nulls_add_tail_rcu(&tw->tw_node, list);
+ }
+
+ static void inet_twsk_add_bind_node(struct inet_timewait_sock *tw,
+@@ -120,7 +120,7 @@ void inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
+
+ spin_lock(lock);
+
+- inet_twsk_add_node_rcu(tw, &ehead->chain);
++ inet_twsk_add_node_tail_rcu(tw, &ehead->chain);
+
+ /* Step 3: Remove SK from hash chain */
+ if (__sk_nulls_del_node_init_rcu(sk))
+--
+2.39.0
+
--- /dev/null
+From 3a259eac136cee82d5ceca562ff3e983d5bf5c45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Jan 2023 19:00:28 +0000
+Subject: tcp: fix rate_app_limited to default to 1
+
+From: David Morley <morleyd@google.com>
+
+[ Upstream commit 300b655db1b5152d6101bcb6801d50899b20c2d6 ]
+
+The initial default value of 0 for tp->rate_app_limited was incorrect,
+since a flow is indeed application-limited until it first sends
+data. Fixing the default to be 1 is generally correct but also
+specifically will help user-space applications avoid using the initial
+tcpi_delivery_rate value of 0 that persists until the connection has
+some non-zero bandwidth sample.
+
+Fixes: eb8329e0a04d ("tcp: export data delivery rate")
+Suggested-by: Yuchung Cheng <ycheng@google.com>
+Signed-off-by: David Morley <morleyd@google.com>
+Signed-off-by: Neal Cardwell <ncardwell@google.com>
+Tested-by: David Morley <morleyd@google.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index fe1972aad279..51f34560a9d6 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -439,6 +439,7 @@ void tcp_init_sock(struct sock *sk)
+
+ /* There's a bubble in the pipe until at least the first ACK. */
+ tp->app_limited = ~0U;
++ tp->rate_app_limited = 1;
+
+ /* See draft-stevens-tcpca-spec-01 for discussion of the
+ * initialization of these values.
+@@ -3066,6 +3067,7 @@ int tcp_disconnect(struct sock *sk, int flags)
+ tp->last_oow_ack_time = 0;
+ /* There's a bubble in the pipe until at least the first ACK. */
+ tp->app_limited = ~0U;
++ tp->rate_app_limited = 1;
+ tp->rack.mstamp = 0;
+ tp->rack.advanced = 0;
+ tp->rack.reo_wnd_steps = 1;
+--
+2.39.0
+
--- /dev/null
+From 0279e8efe36892ffeb9a203af69d7e540da3b1f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 14:08:24 +0530
+Subject: thermal: core: call put_device() only after device_register() fails
+
+From: Viresh Kumar <viresh.kumar@linaro.org>
+
+[ Upstream commit 6c54b7bc8a31ce0f7cc7f8deef05067df414f1d8 ]
+
+put_device() shouldn't be called before a prior call to
+device_register(). __thermal_cooling_device_register() doesn't follow
+that properly and needs fixing. Also
+thermal_cooling_device_destroy_sysfs() is getting called unnecessarily
+on few error paths.
+
+Fix all this by placing the calls at the right place.
+
+Based on initial work done by Caleb Connolly.
+
+Fixes: 4748f9687caa ("thermal: core: fix some possible name leaks in error paths")
+Fixes: c408b3d1d9bb ("thermal: Validate new state in cur_state_store()")
+Reported-by: Caleb Connolly <caleb.connolly@linaro.org>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Tested-by: Frank Rowand <frowand.list@gmail.com>
+Reviewed-by: Yang Yingliang <yangyingliang@huawei.com>
+Tested-by: Caleb Connolly <caleb.connolly@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/thermal_core.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index b21d886aef22..052e8e8fbb21 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -915,15 +915,20 @@ __thermal_cooling_device_register(struct device_node *np,
+ cdev->devdata = devdata;
+
+ ret = cdev->ops->get_max_state(cdev, &cdev->max_state);
+- if (ret)
+- goto out_kfree_type;
++ if (ret) {
++ kfree(cdev->type);
++ goto out_ida_remove;
++ }
+
+ thermal_cooling_device_setup_sysfs(cdev);
++
+ ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
+ if (ret) {
++ kfree(cdev->type);
+ thermal_cooling_device_destroy_sysfs(cdev);
+- goto out_kfree_type;
++ goto out_ida_remove;
+ }
++
+ ret = device_register(&cdev->device);
+ if (ret)
+ goto out_kfree_type;
+@@ -949,6 +954,8 @@ __thermal_cooling_device_register(struct device_node *np,
+ thermal_cooling_device_destroy_sysfs(cdev);
+ kfree(cdev->type);
+ put_device(&cdev->device);
++
++ /* thermal_release() takes care of the rest */
+ cdev = NULL;
+ out_ida_remove:
+ ida_simple_remove(&thermal_cdev_ida, id);
+--
+2.39.0
+
--- /dev/null
+From 093c29c4a595f7f6109614864eec1eeb71b1e76c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Oct 2022 18:02:34 +0300
+Subject: thermal/core: fix error code in __thermal_cooling_device_register()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit e49a1e1ee078aee21006192076a8d93335e0daa9 ]
+
+Return an error pointer if ->get_max_state() fails. The current code
+returns NULL which will cause an oops in the callers.
+
+Fixes: c408b3d1d9bb ("thermal: Validate new state in cur_state_store()")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: 6c54b7bc8a31 ("thermal: core: call put_device() only after device_register() fails")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/thermal_core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index 96d6082864ee..b21d886aef22 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -914,7 +914,8 @@ __thermal_cooling_device_register(struct device_node *np,
+ cdev->device.class = &thermal_class;
+ cdev->devdata = devdata;
+
+- if (cdev->ops->get_max_state(cdev, &cdev->max_state))
++ ret = cdev->ops->get_max_state(cdev, &cdev->max_state);
++ if (ret)
+ goto out_kfree_type;
+
+ thermal_cooling_device_setup_sysfs(cdev);
+--
+2.39.0
+
--- /dev/null
+From 38cff71fb788c3961acef202a58e914c1cf65207 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jul 2022 21:59:58 +0200
+Subject: thermal/core: Remove duplicate information when an error occurs
+
+From: Daniel Lezcano <daniel.lezcano@linexp.org>
+
+[ Upstream commit 3f95ac324535eafafd436d35bf58f0319dd4a70b ]
+
+The pr_err already tells it is an error, it is pointless to add the
+'Error:' string in the messages. Remove them.
+
+Cc: Alexandre Bailon <abailon@baylibre.com>
+Cc: Kevin Hilman <khilman@baylibre.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linexp.org>
+Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
+Link: https://lore.kernel.org/r/20220722200007.1839356-2-daniel.lezcano@linexp.org
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Stable-dep-of: 6c54b7bc8a31 ("thermal: core: call put_device() only after device_register() fails")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/thermal_core.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index 38082fdc4fde..9ec7a8e04fa6 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -1197,23 +1197,23 @@ thermal_zone_device_register(const char *type, int trips, int mask,
+ struct thermal_governor *governor;
+
+ if (!type || strlen(type) == 0) {
+- pr_err("Error: No thermal zone type defined\n");
++ pr_err("No thermal zone type defined\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (type && strlen(type) >= THERMAL_NAME_LENGTH) {
+- pr_err("Error: Thermal zone name (%s) too long, should be under %d chars\n",
++ pr_err("Thermal zone name (%s) too long, should be under %d chars\n",
+ type, THERMAL_NAME_LENGTH);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (trips > THERMAL_MAX_TRIPS || trips < 0 || mask >> trips) {
+- pr_err("Error: Incorrect number of thermal trips\n");
++ pr_err("Incorrect number of thermal trips\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (!ops) {
+- pr_err("Error: Thermal zone device ops not defined\n");
++ pr_err("Thermal zone device ops not defined\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+--
+2.39.0
+
--- /dev/null
+From 48ed3c343d4bfa85e08f80b565dbde82aa357d52 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jul 2022 22:00:04 +0200
+Subject: thermal/core: Rename 'trips' to 'num_trips'
+
+From: Daniel Lezcano <daniel.lezcano@linexp.org>
+
+[ Upstream commit e5bfcd30f88fdb0ce830229e7ccdeddcb7a59b04 ]
+
+In order to use thermal trips defined in the thermal structure, rename
+the 'trips' field to 'num_trips' to have the 'trips' field containing the
+thermal trip points.
+
+Cc: Alexandre Bailon <abailon@baylibre.com>
+Cc: Kevin Hilman <khilman@baylibre.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linexp.org>
+Link: https://lore.kernel.org/r/20220722200007.1839356-8-daniel.lezcano@linexp.org
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Stable-dep-of: 6c54b7bc8a31 ("thermal: core: call put_device() only after device_register() fails")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/gov_fair_share.c | 6 +++---
+ drivers/thermal/gov_power_allocator.c | 4 ++--
+ drivers/thermal/tegra/tegra30-tsensor.c | 2 +-
+ drivers/thermal/thermal_core.c | 20 ++++++++++----------
+ drivers/thermal/thermal_helpers.c | 4 ++--
+ drivers/thermal/thermal_netlink.c | 2 +-
+ drivers/thermal/thermal_sysfs.c | 22 +++++++++++-----------
+ include/linux/thermal.h | 4 ++--
+ 8 files changed, 32 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/thermal/gov_fair_share.c b/drivers/thermal/gov_fair_share.c
+index 1e5abf4822be..6a2abcfc648f 100644
+--- a/drivers/thermal/gov_fair_share.c
++++ b/drivers/thermal/gov_fair_share.c
+@@ -25,10 +25,10 @@ static int get_trip_level(struct thermal_zone_device *tz)
+ int trip_temp;
+ enum thermal_trip_type trip_type;
+
+- if (tz->trips == 0 || !tz->ops->get_trip_temp)
++ if (tz->num_trips == 0 || !tz->ops->get_trip_temp)
+ return 0;
+
+- for (count = 0; count < tz->trips; count++) {
++ for (count = 0; count < tz->num_trips; count++) {
+ tz->ops->get_trip_temp(tz, count, &trip_temp);
+ if (tz->temperature < trip_temp)
+ break;
+@@ -53,7 +53,7 @@ static long get_target_state(struct thermal_zone_device *tz,
+
+ cdev->ops->get_max_state(cdev, &max_state);
+
+- return (long)(percentage * level * max_state) / (100 * tz->trips);
++ return (long)(percentage * level * max_state) / (100 * tz->num_trips);
+ }
+
+ /**
+diff --git a/drivers/thermal/gov_power_allocator.c b/drivers/thermal/gov_power_allocator.c
+index 13e375751d22..1d5052470967 100644
+--- a/drivers/thermal/gov_power_allocator.c
++++ b/drivers/thermal/gov_power_allocator.c
+@@ -527,7 +527,7 @@ static void get_governor_trips(struct thermal_zone_device *tz,
+ last_active = INVALID_TRIP;
+ last_passive = INVALID_TRIP;
+
+- for (i = 0; i < tz->trips; i++) {
++ for (i = 0; i < tz->num_trips; i++) {
+ enum thermal_trip_type type;
+ int ret;
+
+@@ -668,7 +668,7 @@ static int power_allocator_bind(struct thermal_zone_device *tz)
+
+ get_governor_trips(tz, params);
+
+- if (tz->trips > 0) {
++ if (tz->num_trips > 0) {
+ ret = tz->ops->get_trip_temp(tz,
+ params->trip_max_desired_temperature,
+ &control_temp);
+diff --git a/drivers/thermal/tegra/tegra30-tsensor.c b/drivers/thermal/tegra/tegra30-tsensor.c
+index 9b6b693cbcf8..05886684f429 100644
+--- a/drivers/thermal/tegra/tegra30-tsensor.c
++++ b/drivers/thermal/tegra/tegra30-tsensor.c
+@@ -316,7 +316,7 @@ static void tegra_tsensor_get_hw_channel_trips(struct thermal_zone_device *tzd,
+ *hot_trip = 85000;
+ *crit_trip = 90000;
+
+- for (i = 0; i < tzd->trips; i++) {
++ for (i = 0; i < tzd->num_trips; i++) {
+ enum thermal_trip_type type;
+ int trip_temp;
+
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index 9ec7a8e04fa6..c6b7eaffceda 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -503,7 +503,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz,
+
+ tz->notify_event = event;
+
+- for (count = 0; count < tz->trips; count++)
++ for (count = 0; count < tz->num_trips; count++)
+ handle_thermal_trip(tz, count);
+ }
+ EXPORT_SYMBOL_GPL(thermal_zone_device_update);
+@@ -628,7 +628,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
+ unsigned long max_state;
+ int result, ret;
+
+- if (trip >= tz->trips || trip < 0)
++ if (trip >= tz->num_trips || trip < 0)
+ return -EINVAL;
+
+ list_for_each_entry(pos1, &thermal_tz_list, node) {
+@@ -809,7 +809,7 @@ static void __bind(struct thermal_zone_device *tz, int mask,
+ {
+ int i, ret;
+
+- for (i = 0; i < tz->trips; i++) {
++ for (i = 0; i < tz->num_trips; i++) {
+ if (mask & (1 << i)) {
+ unsigned long upper, lower;
+
+@@ -1056,7 +1056,7 @@ static void __unbind(struct thermal_zone_device *tz, int mask,
+ {
+ int i;
+
+- for (i = 0; i < tz->trips; i++)
++ for (i = 0; i < tz->num_trips; i++)
+ if (mask & (1 << i))
+ thermal_zone_unbind_cooling_device(tz, i, cdev);
+ }
+@@ -1161,7 +1161,7 @@ static void bind_tz(struct thermal_zone_device *tz)
+ /**
+ * thermal_zone_device_register() - register a new thermal zone device
+ * @type: the thermal zone device type
+- * @trips: the number of trip points the thermal zone support
++ * @num_trips: the number of trip points the thermal zone support
+ * @mask: a bit string indicating the writeablility of trip points
+ * @devdata: private device data
+ * @ops: standard thermal zone device callbacks
+@@ -1183,7 +1183,7 @@ static void bind_tz(struct thermal_zone_device *tz)
+ * IS_ERR*() helpers.
+ */
+ struct thermal_zone_device *
+-thermal_zone_device_register(const char *type, int trips, int mask,
++thermal_zone_device_register(const char *type, int num_trips, int mask,
+ void *devdata, struct thermal_zone_device_ops *ops,
+ struct thermal_zone_params *tzp, int passive_delay,
+ int polling_delay)
+@@ -1207,7 +1207,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
+ return ERR_PTR(-EINVAL);
+ }
+
+- if (trips > THERMAL_MAX_TRIPS || trips < 0 || mask >> trips) {
++ if (num_trips > THERMAL_MAX_TRIPS || num_trips < 0 || mask >> num_trips) {
+ pr_err("Incorrect number of thermal trips\n");
+ return ERR_PTR(-EINVAL);
+ }
+@@ -1217,7 +1217,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
+ return ERR_PTR(-EINVAL);
+ }
+
+- if (trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp))
++ if (num_trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp))
+ return ERR_PTR(-EINVAL);
+
+ tz = kzalloc(sizeof(*tz), GFP_KERNEL);
+@@ -1243,7 +1243,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
+ tz->tzp = tzp;
+ tz->device.class = &thermal_class;
+ tz->devdata = devdata;
+- tz->trips = trips;
++ tz->num_trips = num_trips;
+
+ thermal_set_delay_jiffies(&tz->passive_delay_jiffies, passive_delay);
+ thermal_set_delay_jiffies(&tz->polling_delay_jiffies, polling_delay);
+@@ -1266,7 +1266,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
+ if (result)
+ goto release_device;
+
+- for (count = 0; count < trips; count++) {
++ for (count = 0; count < num_trips; count++) {
+ if (tz->ops->get_trip_type(tz, count, &trip_type) ||
+ tz->ops->get_trip_temp(tz, count, &trip_temp) ||
+ !trip_temp)
+diff --git a/drivers/thermal/thermal_helpers.c b/drivers/thermal/thermal_helpers.c
+index 3edd047e144f..ee7027bdcafa 100644
+--- a/drivers/thermal/thermal_helpers.c
++++ b/drivers/thermal/thermal_helpers.c
+@@ -90,7 +90,7 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
+ ret = tz->ops->get_temp(tz, temp);
+
+ if (IS_ENABLED(CONFIG_THERMAL_EMULATION) && tz->emul_temperature) {
+- for (count = 0; count < tz->trips; count++) {
++ for (count = 0; count < tz->num_trips; count++) {
+ ret = tz->ops->get_trip_type(tz, count, &type);
+ if (!ret && type == THERMAL_TRIP_CRITICAL) {
+ ret = tz->ops->get_trip_temp(tz, count,
+@@ -138,7 +138,7 @@ void thermal_zone_set_trips(struct thermal_zone_device *tz)
+ if (!tz->ops->set_trips || !tz->ops->get_trip_hyst)
+ goto exit;
+
+- for (i = 0; i < tz->trips; i++) {
++ for (i = 0; i < tz->num_trips; i++) {
+ int trip_low;
+
+ tz->ops->get_trip_temp(tz, i, &trip_temp);
+diff --git a/drivers/thermal/thermal_netlink.c b/drivers/thermal/thermal_netlink.c
+index 41c8d47805c4..c70d407c2c71 100644
+--- a/drivers/thermal/thermal_netlink.c
++++ b/drivers/thermal/thermal_netlink.c
+@@ -415,7 +415,7 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p)
+
+ mutex_lock(&tz->lock);
+
+- for (i = 0; i < tz->trips; i++) {
++ for (i = 0; i < tz->num_trips; i++) {
+
+ enum thermal_trip_type type;
+ int temp, hyst = 0;
+diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c
+index 1e5a78131aba..3a8d6e747c25 100644
+--- a/drivers/thermal/thermal_sysfs.c
++++ b/drivers/thermal/thermal_sysfs.c
+@@ -416,15 +416,15 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
+ int indx;
+
+ /* This function works only for zones with at least one trip */
+- if (tz->trips <= 0)
++ if (tz->num_trips <= 0)
+ return -EINVAL;
+
+- tz->trip_type_attrs = kcalloc(tz->trips, sizeof(*tz->trip_type_attrs),
++ tz->trip_type_attrs = kcalloc(tz->num_trips, sizeof(*tz->trip_type_attrs),
+ GFP_KERNEL);
+ if (!tz->trip_type_attrs)
+ return -ENOMEM;
+
+- tz->trip_temp_attrs = kcalloc(tz->trips, sizeof(*tz->trip_temp_attrs),
++ tz->trip_temp_attrs = kcalloc(tz->num_trips, sizeof(*tz->trip_temp_attrs),
+ GFP_KERNEL);
+ if (!tz->trip_temp_attrs) {
+ kfree(tz->trip_type_attrs);
+@@ -432,7 +432,7 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
+ }
+
+ if (tz->ops->get_trip_hyst) {
+- tz->trip_hyst_attrs = kcalloc(tz->trips,
++ tz->trip_hyst_attrs = kcalloc(tz->num_trips,
+ sizeof(*tz->trip_hyst_attrs),
+ GFP_KERNEL);
+ if (!tz->trip_hyst_attrs) {
+@@ -442,7 +442,7 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
+ }
+ }
+
+- attrs = kcalloc(tz->trips * 3 + 1, sizeof(*attrs), GFP_KERNEL);
++ attrs = kcalloc(tz->num_trips * 3 + 1, sizeof(*attrs), GFP_KERNEL);
+ if (!attrs) {
+ kfree(tz->trip_type_attrs);
+ kfree(tz->trip_temp_attrs);
+@@ -451,7 +451,7 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
+ return -ENOMEM;
+ }
+
+- for (indx = 0; indx < tz->trips; indx++) {
++ for (indx = 0; indx < tz->num_trips; indx++) {
+ /* create trip type attribute */
+ snprintf(tz->trip_type_attrs[indx].name, THERMAL_NAME_LENGTH,
+ "trip_point_%d_type", indx);
+@@ -478,7 +478,7 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
+ tz->trip_temp_attrs[indx].attr.store =
+ trip_point_temp_store;
+ }
+- attrs[indx + tz->trips] = &tz->trip_temp_attrs[indx].attr.attr;
++ attrs[indx + tz->num_trips] = &tz->trip_temp_attrs[indx].attr.attr;
+
+ /* create Optional trip hyst attribute */
+ if (!tz->ops->get_trip_hyst)
+@@ -496,10 +496,10 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
+ tz->trip_hyst_attrs[indx].attr.store =
+ trip_point_hyst_store;
+ }
+- attrs[indx + tz->trips * 2] =
++ attrs[indx + tz->num_trips * 2] =
+ &tz->trip_hyst_attrs[indx].attr.attr;
+ }
+- attrs[tz->trips * 3] = NULL;
++ attrs[tz->num_trips * 3] = NULL;
+
+ tz->trips_attribute_group.attrs = attrs;
+
+@@ -540,7 +540,7 @@ int thermal_zone_create_device_groups(struct thermal_zone_device *tz,
+ for (i = 0; i < size - 2; i++)
+ groups[i] = thermal_zone_attribute_groups[i];
+
+- if (tz->trips) {
++ if (tz->num_trips) {
+ result = create_trip_attrs(tz, mask);
+ if (result) {
+ kfree(groups);
+@@ -561,7 +561,7 @@ void thermal_zone_destroy_device_groups(struct thermal_zone_device *tz)
+ if (!tz)
+ return;
+
+- if (tz->trips)
++ if (tz->num_trips)
+ destroy_trip_attrs(tz);
+
+ kfree(tz->device.groups);
+diff --git a/include/linux/thermal.h b/include/linux/thermal.h
+index c314893970b3..67f121914020 100644
+--- a/include/linux/thermal.h
++++ b/include/linux/thermal.h
+@@ -113,7 +113,7 @@ struct thermal_cooling_device {
+ * @trip_hyst_attrs: attributes for trip points for sysfs: trip hysteresis
+ * @mode: current mode of this thermal zone
+ * @devdata: private pointer for device private data
+- * @trips: number of trip points the thermal zone supports
++ * @num_trips: number of trip points the thermal zone supports
+ * @trips_disabled; bitmap for disabled trips
+ * @passive_delay_jiffies: number of jiffies to wait between polls when
+ * performing passive cooling.
+@@ -153,7 +153,7 @@ struct thermal_zone_device {
+ struct thermal_attr *trip_hyst_attrs;
+ enum thermal_device_mode mode;
+ void *devdata;
+- int trips;
++ int num_trips;
+ unsigned long trips_disabled; /* bitmap for disabled trips */
+ unsigned long passive_delay_jiffies;
+ unsigned long polling_delay_jiffies;
+--
+2.39.0
+
--- /dev/null
+From 96ea7378862a752aa495d4969dbf5c5e01f0915c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Oct 2022 15:33:01 +0530
+Subject: thermal: Validate new state in cur_state_store()
+
+From: Viresh Kumar <viresh.kumar@linaro.org>
+
+[ Upstream commit c408b3d1d9bbc7de5fb0304fea424ef2539da616 ]
+
+In cur_state_store(), the new state of the cooling device is received
+from user-space and is not validated by the thermal core but the same is
+left for the individual drivers to take care of. Apart from duplicating
+the code it leaves possibility for introducing bugs where a driver may
+not do it right.
+
+Lets make the thermal core check the new state itself and store the max
+value in the cooling device structure.
+
+Link: https://lore.kernel.org/all/Y0ltRJRjO7AkawvE@kili/
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: 6c54b7bc8a31 ("thermal: core: call put_device() only after device_register() fails")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/gov_fair_share.c | 6 +-----
+ drivers/thermal/thermal_core.c | 15 +++++++--------
+ drivers/thermal/thermal_sysfs.c | 11 +++++------
+ include/linux/thermal.h | 1 +
+ 4 files changed, 14 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/thermal/gov_fair_share.c b/drivers/thermal/gov_fair_share.c
+index 6a2abcfc648f..a4c30797b534 100644
+--- a/drivers/thermal/gov_fair_share.c
++++ b/drivers/thermal/gov_fair_share.c
+@@ -49,11 +49,7 @@ static int get_trip_level(struct thermal_zone_device *tz)
+ static long get_target_state(struct thermal_zone_device *tz,
+ struct thermal_cooling_device *cdev, int percentage, int level)
+ {
+- unsigned long max_state;
+-
+- cdev->ops->get_max_state(cdev, &max_state);
+-
+- return (long)(percentage * level * max_state) / (100 * tz->num_trips);
++ return (long)(percentage * level * cdev->max_state) / (100 * tz->num_trips);
+ }
+
+ /**
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index c6b7eaffceda..96d6082864ee 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -625,8 +625,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
+ struct thermal_instance *pos;
+ struct thermal_zone_device *pos1;
+ struct thermal_cooling_device *pos2;
+- unsigned long max_state;
+- int result, ret;
++ int result;
+
+ if (trip >= tz->num_trips || trip < 0)
+ return -EINVAL;
+@@ -643,15 +642,11 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
+ if (tz != pos1 || cdev != pos2)
+ return -EINVAL;
+
+- ret = cdev->ops->get_max_state(cdev, &max_state);
+- if (ret)
+- return ret;
+-
+ /* lower default 0, upper default max_state */
+ lower = lower == THERMAL_NO_LIMIT ? 0 : lower;
+- upper = upper == THERMAL_NO_LIMIT ? max_state : upper;
++ upper = upper == THERMAL_NO_LIMIT ? cdev->max_state : upper;
+
+- if (lower > upper || upper > max_state)
++ if (lower > upper || upper > cdev->max_state)
+ return -EINVAL;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+@@ -918,6 +913,10 @@ __thermal_cooling_device_register(struct device_node *np,
+ cdev->updated = false;
+ cdev->device.class = &thermal_class;
+ cdev->devdata = devdata;
++
++ if (cdev->ops->get_max_state(cdev, &cdev->max_state))
++ goto out_kfree_type;
++
+ thermal_cooling_device_setup_sysfs(cdev);
+ ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
+ if (ret) {
+diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c
+index 3a8d6e747c25..de7cdec3db90 100644
+--- a/drivers/thermal/thermal_sysfs.c
++++ b/drivers/thermal/thermal_sysfs.c
+@@ -580,13 +580,8 @@ static ssize_t max_state_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+ {
+ struct thermal_cooling_device *cdev = to_cooling_device(dev);
+- unsigned long state;
+- int ret;
+
+- ret = cdev->ops->get_max_state(cdev, &state);
+- if (ret)
+- return ret;
+- return sprintf(buf, "%ld\n", state);
++ return sprintf(buf, "%ld\n", cdev->max_state);
+ }
+
+ static ssize_t cur_state_show(struct device *dev, struct device_attribute *attr,
+@@ -616,6 +611,10 @@ cur_state_store(struct device *dev, struct device_attribute *attr,
+ if ((long)state < 0)
+ return -EINVAL;
+
++ /* Requested state should be less than max_state + 1 */
++ if (state > cdev->max_state)
++ return -EINVAL;
++
+ mutex_lock(&cdev->lock);
+
+ result = cdev->ops->set_cur_state(cdev, state);
+diff --git a/include/linux/thermal.h b/include/linux/thermal.h
+index 67f121914020..b94314ed0c96 100644
+--- a/include/linux/thermal.h
++++ b/include/linux/thermal.h
+@@ -92,6 +92,7 @@ struct thermal_cooling_device_ops {
+ struct thermal_cooling_device {
+ int id;
+ char *type;
++ unsigned long max_state;
+ struct device device;
+ struct device_node *np;
+ void *devdata;
+--
+2.39.0
+
--- /dev/null
+From b48217ed95b26c2e5d394d2e30605533b059056f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 7 Jan 2023 16:47:41 +0900
+Subject: tomoyo: fix broken dependency on *.conf.default
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit eaf2213ba563b2d74a1f2c13a6b258273f689802 ]
+
+If *.conf.default is updated, builtin-policy.h should be rebuilt,
+but this does not work when compiled with O= option.
+
+[Without this commit]
+
+ $ touch security/tomoyo/policy/exception_policy.conf.default
+ $ make O=/tmp security/tomoyo/
+ make[1]: Entering directory '/tmp'
+ GEN Makefile
+ CALL /home/masahiro/ref/linux/scripts/checksyscalls.sh
+ DESCEND objtool
+ make[1]: Leaving directory '/tmp'
+
+[With this commit]
+
+ $ touch security/tomoyo/policy/exception_policy.conf.default
+ $ make O=/tmp security/tomoyo/
+ make[1]: Entering directory '/tmp'
+ GEN Makefile
+ CALL /home/masahiro/ref/linux/scripts/checksyscalls.sh
+ DESCEND objtool
+ POLICY security/tomoyo/builtin-policy.h
+ CC security/tomoyo/common.o
+ AR security/tomoyo/built-in.a
+ make[1]: Leaving directory '/tmp'
+
+$(srctree)/ is essential because $(wildcard ) does not follow VPATH.
+
+Fixes: f02dee2d148b ("tomoyo: Do not generate empty policy files")
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/tomoyo/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/tomoyo/Makefile b/security/tomoyo/Makefile
+index cca5a3012fee..221eaadffb09 100644
+--- a/security/tomoyo/Makefile
++++ b/security/tomoyo/Makefile
+@@ -10,7 +10,7 @@ endef
+ quiet_cmd_policy = POLICY $@
+ cmd_policy = ($(call do_policy,profile); $(call do_policy,exception_policy); $(call do_policy,domain_policy); $(call do_policy,manager); $(call do_policy,stat)) >$@
+
+-$(obj)/builtin-policy.h: $(wildcard $(obj)/policy/*.conf $(src)/policy/*.conf.default) FORCE
++$(obj)/builtin-policy.h: $(wildcard $(obj)/policy/*.conf $(srctree)/$(src)/policy/*.conf.default) FORCE
+ $(call if_changed,policy)
+
+ $(obj)/common.o: $(obj)/builtin-policy.h
+--
+2.39.0
+
--- /dev/null
+From 7f8ca28c5b189dbdb42fdfa03cbab134f120a29b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Dec 2022 10:59:06 +0530
+Subject: usb: gadget: f_fs: Ensure ep0req is dequeued before free_request
+
+From: Udipto Goswami <quic_ugoswami@quicinc.com>
+
+[ Upstream commit ce405d561b020e5a46340eb5146805a625dcacee ]
+
+As per the documentation, function usb_ep_free_request guarantees
+the request will not be queued or no longer be re-queued (or
+otherwise used). However, with the current implementation it
+doesn't make sure that the request in ep0 isn't reused.
+
+Fix this by dequeuing the ep0req on functionfs_unbind before
+freeing the request to align with the definition.
+
+Fixes: ddf8abd25994 ("USB: f_fs: the FunctionFS driver")
+Signed-off-by: Udipto Goswami <quic_ugoswami@quicinc.com>
+Tested-by: Krishna Kurapati <quic_kriskura@quicinc.com>
+Link: https://lore.kernel.org/r/20221215052906.8993-3-quic_ugoswami@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/f_fs.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
+index 54f36d5c42a7..c9145ee95956 100644
+--- a/drivers/usb/gadget/function/f_fs.c
++++ b/drivers/usb/gadget/function/f_fs.c
+@@ -1895,6 +1895,8 @@ static void functionfs_unbind(struct ffs_data *ffs)
+ ENTER();
+
+ if (!WARN_ON(!ffs->gadget)) {
++ /* dequeue before freeing ep0req */
++ usb_ep_dequeue(ffs->gadget->ep0, ffs->ep0req);
+ mutex_lock(&ffs->mutex);
+ usb_ep_free_request(ffs->gadget->ep0, ffs->ep0req);
+ ffs->ep0req = NULL;
+--
+2.39.0
+
--- /dev/null
+From 9469127d5658023b712f914c3393a1a91763e0bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Dec 2022 10:59:05 +0530
+Subject: usb: gadget: f_fs: Prevent race during ffs_ep0_queue_wait
+
+From: Udipto Goswami <quic_ugoswami@quicinc.com>
+
+[ Upstream commit 6a19da111057f69214b97c62fb0ac59023970850 ]
+
+While performing fast composition switch, there is a possibility that the
+process of ffs_ep0_write/ffs_ep0_read get into a race condition
+due to ep0req being freed up from functionfs_unbind.
+
+Consider the scenario that the ffs_ep0_write calls the ffs_ep0_queue_wait
+by taking a lock &ffs->ev.waitq.lock. However, the functionfs_unbind isn't
+bounded so it can go ahead and mark the ep0req to NULL, and since there
+is no NULL check in ffs_ep0_queue_wait we will end up in use-after-free.
+
+Fix this by making a serialized execution between the two functions using
+a mutex_lock(ffs->mutex).
+
+Fixes: ddf8abd25994 ("USB: f_fs: the FunctionFS driver")
+Signed-off-by: Udipto Goswami <quic_ugoswami@quicinc.com>
+Tested-by: Krishna Kurapati <quic_kriskura@quicinc.com>
+Link: https://lore.kernel.org/r/20221215052906.8993-2-quic_ugoswami@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/f_fs.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
+index adc44a2685b5..54f36d5c42a7 100644
+--- a/drivers/usb/gadget/function/f_fs.c
++++ b/drivers/usb/gadget/function/f_fs.c
+@@ -279,6 +279,9 @@ static int __ffs_ep0_queue_wait(struct ffs_data *ffs, char *data, size_t len)
+ struct usb_request *req = ffs->ep0req;
+ int ret;
+
++ if (!req)
++ return -EINVAL;
++
+ req->zero = len < le16_to_cpu(ffs->ev.setup.wLength);
+
+ spin_unlock_irq(&ffs->ev.waitq.lock);
+@@ -1892,10 +1895,12 @@ static void functionfs_unbind(struct ffs_data *ffs)
+ ENTER();
+
+ if (!WARN_ON(!ffs->gadget)) {
++ mutex_lock(&ffs->mutex);
+ usb_ep_free_request(ffs->gadget->ep0, ffs->ep0req);
+ ffs->ep0req = NULL;
+ ffs->gadget = NULL;
+ clear_bit(FFS_FL_BOUND, &ffs->flags);
++ mutex_unlock(&ffs->mutex);
+ ffs_data_put(ffs);
+ }
+ }
+--
+2.39.0
+
--- /dev/null
+From da35da73e8b8d415d7dc7df559eb5792db0256f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Jan 2023 11:47:07 +0800
+Subject: virtio-net: correctly enable callback during start_xmit
+
+From: Jason Wang <jasowang@redhat.com>
+
+[ Upstream commit d71ebe8114b4bf622804b810f5e274069060a174 ]
+
+Commit a7766ef18b33("virtio_net: disable cb aggressively") enables
+virtqueue callback via the following statement:
+
+ do {
+ if (use_napi)
+ virtqueue_disable_cb(sq->vq);
+
+ free_old_xmit_skbs(sq, false);
+
+ } while (use_napi && kick &&
+ unlikely(!virtqueue_enable_cb_delayed(sq->vq)));
+
+When NAPI is used and kick is false, the callback won't be enabled
+here. And when the virtqueue is about to be full, the tx will be
+disabled, but we still don't enable tx interrupt which will cause a TX
+hang. This could be observed when using pktgen with burst enabled.
+
+TO be consistent with the logic that tries to disable cb only for
+NAPI, fixing this by trying to enable delayed callback only when NAPI
+is enabled when the queue is about to be full.
+
+Fixes: a7766ef18b33 ("virtio_net: disable cb aggressively")
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Tested-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/virtio_net.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
+index 48fb7bdc0f0b..9222be208aba 100644
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -1780,8 +1780,10 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
+ */
+ if (sq->vq->num_free < 2+MAX_SKB_FRAGS) {
+ netif_stop_subqueue(dev, qnum);
+- if (!use_napi &&
+- unlikely(!virtqueue_enable_cb_delayed(sq->vq))) {
++ if (use_napi) {
++ if (unlikely(!virtqueue_enable_cb_delayed(sq->vq)))
++ virtqueue_napi_schedule(&sq->napi, sq->vq);
++ } else if (unlikely(!virtqueue_enable_cb_delayed(sq->vq))) {
+ /* More just got used, free them then recheck. */
+ free_old_xmit_skbs(sq, false);
+ if (sq->vq->num_free >= 2+MAX_SKB_FRAGS) {
+--
+2.39.0
+
--- /dev/null
+From d00ed71b6427884eac15b08d9d475de8b4e7d1b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Dec 2022 16:04:34 +0800
+Subject: w1: fix deadloop in __w1_remove_master_device()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 25d5648802f12ae486076ceca5d7ddf1fef792b2 ]
+
+I got a deadloop report while doing device(ds2482) add/remove test:
+
+ [ 162.241881] w1_master_driver w1_bus_master1: Waiting for w1_bus_master1 to become free: refcnt=1.
+ [ 163.272251] w1_master_driver w1_bus_master1: Waiting for w1_bus_master1 to become free: refcnt=1.
+ [ 164.296157] w1_master_driver w1_bus_master1: Waiting for w1_bus_master1 to become free: refcnt=1.
+ ...
+
+__w1_remove_master_device() can't return, because the dev->refcnt is not zero.
+
+w1_add_master_device() |
+ w1_alloc_dev() |
+ atomic_set(&dev->refcnt, 2) |
+ kthread_run() |
+ |__w1_remove_master_device()
+ | kthread_stop()
+ // KTHREAD_SHOULD_STOP is set, |
+ // threadfn(w1_process) won't be |
+ // called. |
+ kthread() |
+ | // refcnt will never be 0, it's deadloop.
+ | while (atomic_read(&dev->refcnt)) {...}
+
+After calling w1_add_master_device(), w1_process() is not really
+invoked, before w1_process() starting, if kthread_stop() is called
+in __w1_remove_master_device(), w1_process() will never be called,
+the refcnt can not be decreased, then it causes deadloop in remove
+function because of non-zero refcnt.
+
+We need to make sure w1_process() is really started, so move the
+set refcnt into w1_process() to fix this problem.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221205080434.3149205-1-yangyingliang@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/w1/w1.c | 2 ++
+ drivers/w1/w1_int.c | 5 ++---
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
+index f2ae2e563dc5..8b35fae4cd61 100644
+--- a/drivers/w1/w1.c
++++ b/drivers/w1/w1.c
+@@ -1166,6 +1166,8 @@ int w1_process(void *data)
+ /* remainder if it woke up early */
+ unsigned long jremain = 0;
+
++ atomic_inc(&dev->refcnt);
++
+ for (;;) {
+
+ if (!jremain && dev->search_count) {
+diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
+index b3e1792d9c49..3a71c5eb2f83 100644
+--- a/drivers/w1/w1_int.c
++++ b/drivers/w1/w1_int.c
+@@ -51,10 +51,9 @@ static struct w1_master *w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
+ dev->search_count = w1_search_count;
+ dev->enable_pullup = w1_enable_pullup;
+
+- /* 1 for w1_process to decrement
+- * 1 for __w1_remove_master_device to decrement
++ /* For __w1_remove_master_device to decrement
+ */
+- atomic_set(&dev->refcnt, 2);
++ atomic_set(&dev->refcnt, 1);
+
+ INIT_LIST_HEAD(&dev->slist);
+ INIT_LIST_HEAD(&dev->async_list);
+--
+2.39.0
+
--- /dev/null
+From a1da556dd1b2aa28f72dc86f41791496badaf4c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Dec 2022 18:15:58 +0800
+Subject: w1: fix WARNING after calling w1_process()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 36225a7c72e9e3e1ce4001b6ce72849f5c9a2d3b ]
+
+I got the following WARNING message while removing driver(ds2482):
+
+------------[ cut here ]------------
+do not call blocking ops when !TASK_RUNNING; state=1 set at [<000000002d50bfb6>] w1_process+0x9e/0x1d0 [wire]
+WARNING: CPU: 0 PID: 262 at kernel/sched/core.c:9817 __might_sleep+0x98/0xa0
+CPU: 0 PID: 262 Comm: w1_bus_master1 Tainted: G N 6.1.0-rc3+ #307
+RIP: 0010:__might_sleep+0x98/0xa0
+Call Trace:
+ exit_signals+0x6c/0x550
+ do_exit+0x2b4/0x17e0
+ kthread_exit+0x52/0x60
+ kthread+0x16d/0x1e0
+ ret_from_fork+0x1f/0x30
+
+The state of task is set to TASK_INTERRUPTIBLE in loop in w1_process(),
+set it to TASK_RUNNING when it breaks out of the loop to avoid the
+warning.
+
+Fixes: 3c52e4e62789 ("W1: w1_process, block or sleep")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221205101558.3599162-1-yangyingliang@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/w1/w1.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
+index 8b35fae4cd61..4a2ddf730a3a 100644
+--- a/drivers/w1/w1.c
++++ b/drivers/w1/w1.c
+@@ -1195,8 +1195,10 @@ int w1_process(void *data)
+ */
+ mutex_unlock(&dev->list_mutex);
+
+- if (kthread_should_stop())
++ if (kthread_should_stop()) {
++ __set_current_state(TASK_RUNNING);
+ break;
++ }
+
+ /* Only sleep when the search is active. */
+ if (dev->search_count) {
+--
+2.39.0
+
--- /dev/null
+From 087877a75f658f802064ab1471b4503e7b01bf77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 18:50:31 +0100
+Subject: wifi: rndis_wlan: Prevent buffer overflow in rndis_query_oid
+
+From: Szymon Heidrich <szymon.heidrich@gmail.com>
+
+[ Upstream commit b870e73a56c4cccbec33224233eaf295839f228c ]
+
+Since resplen and respoffs are signed integers sufficiently
+large values of unsigned int len and offset members of RNDIS
+response will result in negative values of prior variables.
+This may be utilized to bypass implemented security checks
+to either extract memory contents by manipulating offset or
+overflow the data buffer via memcpy by manipulating both
+offset and len.
+
+Additionally assure that sum of resplen and respoffs does not
+overflow so buffer boundaries are kept.
+
+Fixes: 80f8c5b434f9 ("rndis_wlan: copy only useful data from rndis_command respond")
+Signed-off-by: Szymon Heidrich <szymon.heidrich@gmail.com>
+Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230111175031.7049-1-szymon.heidrich@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/rndis_wlan.c | 19 ++++++-------------
+ 1 file changed, 6 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
+index 63ce2443f136..70841d131d72 100644
+--- a/drivers/net/wireless/rndis_wlan.c
++++ b/drivers/net/wireless/rndis_wlan.c
+@@ -694,8 +694,8 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
+ struct rndis_query *get;
+ struct rndis_query_c *get_c;
+ } u;
+- int ret, buflen;
+- int resplen, respoffs, copylen;
++ int ret;
++ size_t buflen, resplen, respoffs, copylen;
+
+ buflen = *len + sizeof(*u.get);
+ if (buflen < CONTROL_BUFFER_SIZE)
+@@ -730,22 +730,15 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
+
+ if (respoffs > buflen) {
+ /* Device returned data offset outside buffer, error. */
+- netdev_dbg(dev->net, "%s(%s): received invalid "
+- "data offset: %d > %d\n", __func__,
+- oid_to_string(oid), respoffs, buflen);
++ netdev_dbg(dev->net,
++ "%s(%s): received invalid data offset: %zu > %zu\n",
++ __func__, oid_to_string(oid), respoffs, buflen);
+
+ ret = -EINVAL;
+ goto exit_unlock;
+ }
+
+- if ((resplen + respoffs) > buflen) {
+- /* Device would have returned more data if buffer would
+- * have been big enough. Copy just the bits that we got.
+- */
+- copylen = buflen - respoffs;
+- } else {
+- copylen = resplen;
+- }
++ copylen = min(resplen, buflen - respoffs);
+
+ if (copylen > *len)
+ copylen = *len;
+--
+2.39.0
+