--- /dev/null
+From a031bc3b497d2da47277eaf425fa9d9369a9dab2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 13:40:01 +0200
+Subject: ARM: dts: BCM53573: Drop nonexistent "default-off" LED trigger
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafał Miłecki <rafal@milecki.pl>
+
+[ Upstream commit be7e1e5b0f67c58ec4be0a54db23b6a4fa6e2116 ]
+
+There is no such trigger documented or implemented in Linux. It was a
+copy & paste mistake.
+
+This fixes:
+arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-1440.dtb: leds: led-wlan:linux,default-trigger: 'oneOf' conditional failed, one must be fixed:
+ 'default-off' is not one of ['backlight', 'default-on', 'heartbeat', 'disk-activity', 'disk-read', 'disk-write', 'timer', 'pattern', 'audio-micmute', 'audio-mute', 'bluetooth-power', 'flash', 'kbd-capslock', 'mtd', 'nand-disk', 'none', 'torch', 'usb-gadget', 'usb-host', 'usbport']
+ 'default-off' does not match '^cpu[0-9]*$'
+ 'default-off' does not match '^hci[0-9]+-power$'
+ 'default-off' does not match '^mmc[0-9]+$'
+ 'default-off' does not match '^phy[0-9]+tx$'
+ From schema: Documentation/devicetree/bindings/leds/leds-gpio.yaml
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Link: https://lore.kernel.org/r/20230707114004.2740-1-zajec5@gmail.com
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts | 1 -
+ arch/arm/boot/dts/bcm47189-luxul-xap-810.dts | 2 --
+ 2 files changed, 3 deletions(-)
+
+diff --git a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
+index 00e688b45d981..5901160919dcd 100644
+--- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
++++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
+@@ -26,7 +26,6 @@ leds {
+ wlan {
+ label = "bcm53xx:blue:wlan";
+ gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
+- linux,default-trigger = "default-off";
+ };
+
+ system {
+diff --git a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
+index 78c80a5d3f4fa..8e7483272d47d 100644
+--- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
++++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
+@@ -26,7 +26,6 @@ leds {
+ 5ghz {
+ label = "bcm53xx:blue:5ghz";
+ gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
+- linux,default-trigger = "default-off";
+ };
+
+ system {
+@@ -42,7 +41,6 @@ pcie0_leds {
+ 2ghz {
+ label = "bcm53xx:blue:2ghz";
+ gpios = <&pcie0_chipcommon 3 GPIO_ACTIVE_HIGH>;
+- linux,default-trigger = "default-off";
+ };
+ };
+
+--
+2.43.0
+
--- /dev/null
+From 0f8f019e9f3988f4270ae0d397f173c564961037 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jul 2023 15:57:47 +0800
+Subject: ARM: dts: imx: Set default tuning step for imx6sx usdhc
+
+From: Xiaolei Wang <xiaolei.wang@windriver.com>
+
+[ Upstream commit 0a2b96e42a0284c4fc03022236f656a085ca714a ]
+
+If the tuning step is not set, the tuning step is set to 1.
+For some sd cards, the following Tuning timeout will occur.
+
+Tuning failed, falling back to fixed sampling clock
+
+So set the default tuning step. This refers to the NXP vendor's
+commit below:
+
+https://github.com/nxp-imx/linux-imx/blob/lf-6.1.y/
+arch/arm/boot/dts/imx6sx.dtsi#L1108-L1109
+
+Fixes: 1e336aa0c025 ("mmc: sdhci-esdhc-imx: correct the tuning start tap and step setting")
+Signed-off-by: Xiaolei Wang <xiaolei.wang@windriver.com>
+Reviewed-by: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6sx.dtsi | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
+index 08332f70a8dc2..51491b7418e40 100644
+--- a/arch/arm/boot/dts/imx6sx.dtsi
++++ b/arch/arm/boot/dts/imx6sx.dtsi
+@@ -981,6 +981,8 @@ usdhc1: mmc@2190000 {
+ <&clks IMX6SX_CLK_USDHC1>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
++ fsl,tuning-start-tap = <20>;
++ fsl,tuning-step= <2>;
+ status = "disabled";
+ };
+
+@@ -993,6 +995,8 @@ usdhc2: mmc@2194000 {
+ <&clks IMX6SX_CLK_USDHC2>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
++ fsl,tuning-start-tap = <20>;
++ fsl,tuning-step= <2>;
+ status = "disabled";
+ };
+
+@@ -1005,6 +1009,8 @@ usdhc3: mmc@2198000 {
+ <&clks IMX6SX_CLK_USDHC3>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
++ fsl,tuning-start-tap = <20>;
++ fsl,tuning-step= <2>;
+ status = "disabled";
+ };
+
+--
+2.43.0
+
--- /dev/null
+From 27d2db837f047f8e2a38ed810c8e83a4e755e12f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Sep 2021 18:30:04 +0800
+Subject: ASoC: fsl_micfil: register platform component before registering cpu
+ dai
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit 0adf292069dcca8bab76a603251fcaabf77468ca ]
+
+There is no defer probe when adding platform component to
+snd_soc_pcm_runtime(rtd), the code is in snd_soc_add_pcm_runtime()
+
+snd_soc_register_card()
+ -> snd_soc_bind_card()
+ -> snd_soc_add_pcm_runtime()
+ -> adding cpu dai
+ -> adding codec dai
+ -> adding platform component.
+
+So if the platform component is not ready at that time, then the
+sound card still registered successfully, but platform component
+is empty, the sound card can't be used.
+
+As there is defer probe checking for cpu dai component, then register
+platform component before cpu dai to avoid such issue.
+
+Fixes: 47a70e6fc9a8 ("ASoC: Add MICFIL SoC Digital Audio Interface driver.")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Link: https://lore.kernel.org/r/1630665006-31437-4-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_micfil.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
+index 97f83c63e7652..826829e3ff7a2 100644
+--- a/sound/soc/fsl/fsl_micfil.c
++++ b/sound/soc/fsl/fsl_micfil.c
+@@ -756,18 +756,23 @@ static int fsl_micfil_probe(struct platform_device *pdev)
+
+ pm_runtime_enable(&pdev->dev);
+
++ /*
++ * Register platform component before registering cpu dai for there
++ * is not defer probe for platform component in snd_soc_add_pcm_runtime().
++ */
++ ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to pcm register\n");
++ return ret;
++ }
++
+ ret = devm_snd_soc_register_component(&pdev->dev, &fsl_micfil_component,
+ &fsl_micfil_dai, 1);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register component %s\n",
+ fsl_micfil_component.name);
+- return ret;
+ }
+
+- ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+- if (ret)
+- dev_err(&pdev->dev, "failed to pcm register\n");
+-
+ return ret;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 19d53b9cb499a7b6a94ebe015566b683d05d7962 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Aug 2021 10:11:11 -0500
+Subject: ASoC: Intel: boards: get codec device with ACPI instead of bus search
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit d3409eb20d3ed7d9e021cd13243e9e63255a315f ]
+
+We have an existing 'adev' handle from which we can find the codec
+device, no need for an I2C bus search.
+
+Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20210813151116.23931-4-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 721858823d7c ("ASoC: Intel: bytcr_rt5651: Drop reference count of ACPI device after use")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/bytcht_es8316.c | 4 ++--
+ sound/soc/intel/boards/bytcr_rt5640.c | 5 ++---
+ sound/soc/intel/boards/bytcr_rt5651.c | 6 ++----
+ 3 files changed, 6 insertions(+), 9 deletions(-)
+
+diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
+index 91351b8536aa1..03b9cdbd3170f 100644
+--- a/sound/soc/intel/boards/bytcht_es8316.c
++++ b/sound/soc/intel/boards/bytcht_es8316.c
+@@ -550,9 +550,10 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
+ }
+
+ /* get speaker enable GPIO */
+- codec_dev = bus_find_device_by_name(&i2c_bus_type, NULL, codec_name);
++ codec_dev = acpi_get_first_physical_node(adev);
+ if (!codec_dev)
+ return -EPROBE_DEFER;
++ priv->codec_dev = get_device(codec_dev);
+
+ if (quirk & BYT_CHT_ES8316_JD_INVERTED)
+ props[cnt++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted");
+@@ -570,7 +571,6 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
+ gpiod_get_index(codec_dev, "speaker-enable", 0,
+ /* see comment in byt_cht_es8316_resume */
+ GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
+- priv->codec_dev = codec_dev;
+
+ if (IS_ERR(priv->speaker_en_gpio)) {
+ ret = PTR_ERR(priv->speaker_en_gpio);
+diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
+index b531c348fb697..f5b1b3b876980 100644
+--- a/sound/soc/intel/boards/bytcr_rt5640.c
++++ b/sound/soc/intel/boards/bytcr_rt5640.c
+@@ -1425,11 +1425,10 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
+ byt_rt5640_quirk = quirk_override;
+ }
+
+- codec_dev = bus_find_device_by_name(&i2c_bus_type, NULL, byt_rt5640_codec_name);
++ codec_dev = acpi_get_first_physical_node(adev);
+ if (!codec_dev)
+ return -EPROBE_DEFER;
+-
+- priv->codec_dev = codec_dev;
++ priv->codec_dev = get_device(codec_dev);
+
+ /* Must be called before register_card, also see declaration comment. */
+ ret_val = byt_rt5640_add_codec_device_props(codec_dev, priv);
+diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c
+index acea83e814acb..472f6e3327960 100644
+--- a/sound/soc/intel/boards/bytcr_rt5651.c
++++ b/sound/soc/intel/boards/bytcr_rt5651.c
+@@ -926,10 +926,10 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
+ return -ENODEV;
+ }
+
+- codec_dev = bus_find_device_by_name(&i2c_bus_type, NULL,
+- byt_rt5651_codec_name);
++ codec_dev = acpi_get_first_physical_node(adev);
+ if (!codec_dev)
+ return -EPROBE_DEFER;
++ priv->codec_dev = get_device(codec_dev);
+
+ /*
+ * swap SSP0 if bytcr is detected
+@@ -996,8 +996,6 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
+ byt_rt5651_quirk = quirk_override;
+ }
+
+- priv->codec_dev = codec_dev;
+-
+ /* Must be called before register_card, also see declaration comment. */
+ ret_val = byt_rt5651_add_codec_device_props(codec_dev);
+ if (ret_val)
+--
+2.43.0
+
--- /dev/null
+From ce2b0901f13d910f8b684e9b32044977ac085323 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Aug 2021 10:11:09 -0500
+Subject: ASoC: Intel: boards: harden codec property handling
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit c50f126b3c9ebb77585838726a3a490ad33b92cd ]
+
+In current ACPI-based devices, the DSDT does not include any of the
+properties required by the codec driver. This is not an ACPI
+limitation proper since the _DSD method could be used, as done for
+Camera and SoundWire in newer platforms. For legacy devices, there is
+unfortunately no other option than using a work-around: we add
+properties to the codec device from the machine driver.
+
+To avoid any issues with the codec driver being unbound, we need to
+keep a reference to the codec device until the card is removed.
+
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Co-developed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20210813151116.23931-2-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 721858823d7c ("ASoC: Intel: bytcr_rt5651: Drop reference count of ACPI device after use")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/bytcht_es8316.c | 12 +++++--
+ sound/soc/intel/boards/bytcr_rt5640.c | 47 +++++++++++++++++---------
+ sound/soc/intel/boards/bytcr_rt5651.c | 37 +++++++++++++-------
+ 3 files changed, 64 insertions(+), 32 deletions(-)
+
+diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
+index 81269ed5a2aaa..91351b8536aa1 100644
+--- a/sound/soc/intel/boards/bytcht_es8316.c
++++ b/sound/soc/intel/boards/bytcht_es8316.c
+@@ -37,6 +37,7 @@ struct byt_cht_es8316_private {
+ struct clk *mclk;
+ struct snd_soc_jack jack;
+ struct gpio_desc *speaker_en_gpio;
++ struct device *codec_dev;
+ bool speaker_en;
+ };
+
+@@ -569,7 +570,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
+ gpiod_get_index(codec_dev, "speaker-enable", 0,
+ /* see comment in byt_cht_es8316_resume */
+ GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
+- put_device(codec_dev);
++ priv->codec_dev = codec_dev;
+
+ if (IS_ERR(priv->speaker_en_gpio)) {
+ ret = PTR_ERR(priv->speaker_en_gpio);
+@@ -581,7 +582,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
+ dev_err(dev, "get speaker GPIO failed: %d\n", ret);
+ fallthrough;
+ case -EPROBE_DEFER:
+- return ret;
++ goto err_put_codec;
+ }
+ }
+
+@@ -604,10 +605,14 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
+ if (ret) {
+ gpiod_put(priv->speaker_en_gpio);
+ dev_err(dev, "snd_soc_register_card failed: %d\n", ret);
+- return ret;
++ goto err_put_codec;
+ }
+ platform_set_drvdata(pdev, &byt_cht_es8316_card);
+ return 0;
++
++err_put_codec:
++ put_device(priv->codec_dev);
++ return ret;
+ }
+
+ static int snd_byt_cht_es8316_mc_remove(struct platform_device *pdev)
+@@ -616,6 +621,7 @@ static int snd_byt_cht_es8316_mc_remove(struct platform_device *pdev)
+ struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
+
+ gpiod_put(priv->speaker_en_gpio);
++ put_device(priv->codec_dev);
+ return 0;
+ }
+
+diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
+index 9a5ab96f917d3..b531c348fb697 100644
+--- a/sound/soc/intel/boards/bytcr_rt5640.c
++++ b/sound/soc/intel/boards/bytcr_rt5640.c
+@@ -86,6 +86,7 @@ enum {
+ struct byt_rt5640_private {
+ struct snd_soc_jack jack;
+ struct clk *mclk;
++ struct device *codec_dev;
+ };
+ static bool is_bytcr;
+
+@@ -941,15 +942,11 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
+ * Note this MUST be called before snd_soc_register_card(), so that the props
+ * are in place before the codec component driver's probe function parses them.
+ */
+-static int byt_rt5640_add_codec_device_props(const char *i2c_dev_name)
++static int byt_rt5640_add_codec_device_props(struct device *i2c_dev,
++ struct byt_rt5640_private *priv)
+ {
+ struct property_entry props[MAX_NO_PROPS] = {};
+- struct device *i2c_dev;
+- int ret, cnt = 0;
+-
+- i2c_dev = bus_find_device_by_name(&i2c_bus_type, NULL, i2c_dev_name);
+- if (!i2c_dev)
+- return -EPROBE_DEFER;
++ int cnt = 0;
+
+ switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
+ case BYT_RT5640_DMIC1_MAP:
+@@ -989,10 +986,7 @@ static int byt_rt5640_add_codec_device_props(const char *i2c_dev_name)
+ if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
+ props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted");
+
+- ret = device_add_properties(i2c_dev, props);
+- put_device(i2c_dev);
+-
+- return ret;
++ return device_add_properties(i2c_dev, props);
+ }
+
+ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
+@@ -1324,6 +1318,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
+ struct snd_soc_acpi_mach *mach;
+ const char *platform_name;
+ struct acpi_device *adev;
++ struct device *codec_dev;
+ int ret_val = 0;
+ int dai_index = 0;
+ int i, cfg_spk;
+@@ -1430,10 +1425,16 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
+ byt_rt5640_quirk = quirk_override;
+ }
+
++ codec_dev = bus_find_device_by_name(&i2c_bus_type, NULL, byt_rt5640_codec_name);
++ if (!codec_dev)
++ return -EPROBE_DEFER;
++
++ priv->codec_dev = codec_dev;
++
+ /* Must be called before register_card, also see declaration comment. */
+- ret_val = byt_rt5640_add_codec_device_props(byt_rt5640_codec_name);
++ ret_val = byt_rt5640_add_codec_device_props(codec_dev, priv);
+ if (ret_val)
+- return ret_val;
++ goto err;
+
+ log_quirks(&pdev->dev);
+
+@@ -1460,7 +1461,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
+ * for all other errors, including -EPROBE_DEFER
+ */
+ if (ret_val != -ENOENT)
+- return ret_val;
++ goto err;
+ byt_rt5640_quirk &= ~BYT_RT5640_MCLK_EN;
+ }
+ }
+@@ -1493,17 +1494,30 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
+ ret_val = snd_soc_fixup_dai_links_platform_name(&byt_rt5640_card,
+ platform_name);
+ if (ret_val)
+- return ret_val;
++ goto err;
+
+ ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
+
+ if (ret_val) {
+ dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n",
+ ret_val);
+- return ret_val;
++ goto err;
+ }
+ platform_set_drvdata(pdev, &byt_rt5640_card);
+ return ret_val;
++
++err:
++ put_device(priv->codec_dev);
++ return ret_val;
++}
++
++static int snd_byt_rt5640_mc_remove(struct platform_device *pdev)
++{
++ struct snd_soc_card *card = platform_get_drvdata(pdev);
++ struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
++
++ put_device(priv->codec_dev);
++ return 0;
+ }
+
+ static struct platform_driver snd_byt_rt5640_mc_driver = {
+@@ -1514,6 +1528,7 @@ static struct platform_driver snd_byt_rt5640_mc_driver = {
+ #endif
+ },
+ .probe = snd_byt_rt5640_mc_probe,
++ .remove = snd_byt_rt5640_mc_remove,
+ };
+
+ module_platform_driver(snd_byt_rt5640_mc_driver);
+diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c
+index bf8b87d45cb0a..acea83e814acb 100644
+--- a/sound/soc/intel/boards/bytcr_rt5651.c
++++ b/sound/soc/intel/boards/bytcr_rt5651.c
+@@ -85,6 +85,7 @@ struct byt_rt5651_private {
+ struct gpio_desc *ext_amp_gpio;
+ struct gpio_desc *hp_detect;
+ struct snd_soc_jack jack;
++ struct device *codec_dev;
+ };
+
+ static const struct acpi_gpio_mapping *byt_rt5651_gpios;
+@@ -995,12 +996,12 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
+ byt_rt5651_quirk = quirk_override;
+ }
+
++ priv->codec_dev = codec_dev;
++
+ /* Must be called before register_card, also see declaration comment. */
+ ret_val = byt_rt5651_add_codec_device_props(codec_dev);
+- if (ret_val) {
+- put_device(codec_dev);
+- return ret_val;
+- }
++ if (ret_val)
++ goto err;
+
+ /* Cherry Trail devices use an external amplifier enable gpio */
+ if (soc_intel_is_cht() && !byt_rt5651_gpios)
+@@ -1024,8 +1025,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
+ ret_val);
+ fallthrough;
+ case -EPROBE_DEFER:
+- put_device(codec_dev);
+- return ret_val;
++ goto err;
+ }
+ }
+ priv->hp_detect = devm_fwnode_gpiod_get(&pdev->dev,
+@@ -1044,14 +1044,11 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
+ ret_val);
+ fallthrough;
+ case -EPROBE_DEFER:
+- put_device(codec_dev);
+- return ret_val;
++ goto err;
+ }
+ }
+ }
+
+- put_device(codec_dev);
+-
+ log_quirks(&pdev->dev);
+
+ if ((byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2) ||
+@@ -1075,7 +1072,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
+ * for all other errors, including -EPROBE_DEFER
+ */
+ if (ret_val != -ENOENT)
+- return ret_val;
++ goto err;
+ byt_rt5651_quirk &= ~BYT_RT5651_MCLK_EN;
+ }
+ }
+@@ -1104,17 +1101,30 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
+ ret_val = snd_soc_fixup_dai_links_platform_name(&byt_rt5651_card,
+ platform_name);
+ if (ret_val)
+- return ret_val;
++ goto err;
+
+ ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5651_card);
+
+ if (ret_val) {
+ dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n",
+ ret_val);
+- return ret_val;
++ goto err;
+ }
+ platform_set_drvdata(pdev, &byt_rt5651_card);
+ return ret_val;
++
++err:
++ put_device(priv->codec_dev);
++ return ret_val;
++}
++
++static int snd_byt_rt5651_mc_remove(struct platform_device *pdev)
++{
++ struct snd_soc_card *card = platform_get_drvdata(pdev);
++ struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
++
++ put_device(priv->codec_dev);
++ return 0;
+ }
+
+ static struct platform_driver snd_byt_rt5651_mc_driver = {
+@@ -1125,6 +1135,7 @@ static struct platform_driver snd_byt_rt5651_mc_driver = {
+ #endif
+ },
+ .probe = snd_byt_rt5651_mc_probe,
++ .remove = snd_byt_rt5651_mc_remove,
+ };
+
+ module_platform_driver(snd_byt_rt5651_mc_driver);
+--
+2.43.0
+
--- /dev/null
+From 1496556315320f59ff3c3fa718cc28e4dbcde478 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Jan 2023 13:28:49 +0200
+Subject: ASoC: Intel: bytcr_rt5651: Drop reference count of ACPI device after
+ use
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 721858823d7cdc8f2a897579b040e935989f6f02 ]
+
+Theoretically the device might gone if its reference count drops to 0.
+This might be the case when we try to find the first physical node of
+the ACPI device. We need to keep reference to it until we get a result
+of the above mentioned call. Refactor the code to drop the reference
+count at the correct place.
+
+While at it, move to acpi_dev_put() as symmetrical call to the
+acpi_dev_get_first_match_dev().
+
+Fixes: 02c0a3b3047f ("ASoC: Intel: bytcr_rt5651: add MCLK, quirks and cleanups")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20230112112852.67714-3-andriy.shevchenko@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/bytcr_rt5651.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c
+index 472f6e3327960..a8289f74463e9 100644
+--- a/sound/soc/intel/boards/bytcr_rt5651.c
++++ b/sound/soc/intel/boards/bytcr_rt5651.c
+@@ -919,7 +919,6 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
+ if (adev) {
+ snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name),
+ "i2c-%s", acpi_dev_name(adev));
+- put_device(&adev->dev);
+ byt_rt5651_dais[dai_index].codecs->name = byt_rt5651_codec_name;
+ } else {
+ dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id);
+@@ -927,6 +926,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
+ }
+
+ codec_dev = acpi_get_first_physical_node(adev);
++ acpi_dev_put(adev);
+ if (!codec_dev)
+ return -EPROBE_DEFER;
+ priv->codec_dev = get_device(codec_dev);
+--
+2.43.0
+
--- /dev/null
+From 4d9ab599060576628afbc9a33a6bfb026599b15e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Oct 2021 19:13:21 +1300
+Subject: block: ataflop: fix breakage introduced at blk-mq refactoring
+
+From: Michael Schmitz <schmitzmic@gmail.com>
+
+[ Upstream commit 86d46fdaa12ae5befc16b8d73fc85a3ca0399ea6 ]
+
+Refactoring of the Atari floppy driver when converting to blk-mq
+has broken the state machine in not-so-subtle ways:
+
+finish_fdc() must be called when operations on the floppy device
+have completed. This is crucial in order to relase the ST-DMA
+lock, which protects against concurrent access to the ST-DMA
+controller by other drivers (some DMA related, most just related
+to device register access - broken beyond compare, I know).
+
+When rewriting the driver's old do_request() function, the fact
+that finish_fdc() was called only when all queued requests had
+completed appears to have been overlooked. Instead, the new
+request function calls finish_fdc() immediately after the last
+request has been queued. finish_fdc() executes a dummy seek after
+most requests, and this overwrites the state machine's interrupt
+hander that was set up to wait for completion of the read/write
+request just prior. To make matters worse, finish_fdc() is called
+before device interrupts are re-enabled, making certain that the
+read/write interupt is missed.
+
+Shifting the finish_fdc() call into the read/write request
+completion handler ensures the driver waits for the request to
+actually complete. With a queue depth of 2, we won't see long
+request sequences, so calling finish_fdc() unconditionally just
+adds a little overhead for the dummy seeks, and keeps the code
+simple.
+
+While we're at it, kill ataflop_commit_rqs() which does nothing
+but run finish_fdc() unconditionally, again likely wiping out an
+in-flight request.
+
+Signed-off-by: Michael Schmitz <schmitzmic@gmail.com>
+Fixes: 6ec3938cff95 ("ataflop: convert to blk-mq")
+CC: linux-block@vger.kernel.org
+CC: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
+Link: https://lore.kernel.org/r/20211019061321.26425-1-schmitzmic@gmail.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/ataflop.c | 18 +++---------------
+ 1 file changed, 3 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
+index 3e881fdb06e0a..cd612cd04767a 100644
+--- a/drivers/block/ataflop.c
++++ b/drivers/block/ataflop.c
+@@ -653,9 +653,6 @@ static inline void copy_buffer(void *from, void *to)
+ *p2++ = *p1++;
+ }
+
+-
+-
+-
+ /* General Interrupt Handling */
+
+ static void (*FloppyIRQHandler)( int status ) = NULL;
+@@ -1225,6 +1222,7 @@ static void fd_rwsec_done1(int status)
+ }
+ else {
+ /* all sectors finished */
++ finish_fdc();
+ fd_end_request_cur(BLK_STS_OK);
+ }
+ return;
+@@ -1472,15 +1470,6 @@ static void setup_req_params( int drive )
+ ReqTrack, ReqSector, (unsigned long)ReqData ));
+ }
+
+-static void ataflop_commit_rqs(struct blk_mq_hw_ctx *hctx)
+-{
+- spin_lock_irq(&ataflop_lock);
+- atari_disable_irq(IRQ_MFP_FDC);
+- finish_fdc();
+- atari_enable_irq(IRQ_MFP_FDC);
+- spin_unlock_irq(&ataflop_lock);
+-}
+-
+ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
+ const struct blk_mq_queue_data *bd)
+ {
+@@ -1488,6 +1477,8 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
+ int drive = floppy - unit;
+ int type = floppy->type;
+
++ DPRINT(("Queue request: drive %d type %d last %d\n", drive, type, bd->last));
++
+ spin_lock_irq(&ataflop_lock);
+ if (fd_request) {
+ spin_unlock_irq(&ataflop_lock);
+@@ -1547,8 +1538,6 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
+ setup_req_params( drive );
+ do_fd_action( drive );
+
+- if (bd->last)
+- finish_fdc();
+ atari_enable_irq( IRQ_MFP_FDC );
+
+ out:
+@@ -1959,7 +1948,6 @@ static const struct block_device_operations floppy_fops = {
+
+ static const struct blk_mq_ops ataflop_mq_ops = {
+ .queue_rq = ataflop_queue_rq,
+- .commit_rqs = ataflop_commit_rqs,
+ };
+
+ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
+--
+2.43.0
+
--- /dev/null
+From 79c2b66c9d8b013d9dc1c1a1f405603b143dc7fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Jul 2021 11:24:45 +0100
+Subject: btrfs: do not pin logs too early during renames
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit bd54f381a12ac695593271a663d36d14220215b2 ]
+
+During renames we pin the logs of the roots a bit too early, before the
+calls to btrfs_insert_inode_ref(). We can pin the logs after those calls,
+since those will not change anything in a log tree.
+
+In a scenario where we have multiple and diverse filesystem operations
+running in parallel, those calls can take a significant amount of time,
+due to lock contention on extent buffers, and delay log commits from other
+tasks for longer than necessary.
+
+So just pin logs after calls to btrfs_insert_inode_ref() and right before
+the first operation that can update a log tree.
+
+The following script that uses dbench was used for testing:
+
+ $ cat dbench-test.sh
+ #!/bin/bash
+
+ DEV=/dev/nvme0n1
+ MNT=/mnt/nvme0n1
+ MOUNT_OPTIONS="-o ssd"
+ MKFS_OPTIONS="-m single -d single"
+
+ echo "performance" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
+
+ umount $DEV &> /dev/null
+ mkfs.btrfs -f $MKFS_OPTIONS $DEV
+ mount $MOUNT_OPTIONS $DEV $MNT
+
+ dbench -D $MNT -t 120 16
+
+ umount $MNT
+
+The tests were run on a machine with 12 cores, 64G of RAN, a NVMe device
+and using a non-debug kernel config (Debian's default config).
+
+The results compare a branch without this patch and without the previous
+patch in the series, that has the subject:
+
+ "btrfs: eliminate some false positives when checking if inode was logged"
+
+Versus the same branch with these two patches applied.
+
+dbench with 8 clients, results before:
+
+ Operation Count AvgLat MaxLat
+ ----------------------------------------
+ NTCreateX 4391359 0.009 249.745
+ Close 3225882 0.001 3.243
+ Rename 185953 0.065 240.643
+ Unlink 886669 0.049 249.906
+ Deltree 112 2.455 217.433
+ Mkdir 56 0.002 0.004
+ Qpathinfo 3980281 0.004 3.109
+ Qfileinfo 697579 0.001 0.187
+ Qfsinfo 729780 0.002 2.424
+ Sfileinfo 357764 0.004 1.415
+ Find 1538861 0.016 4.863
+ WriteX 2189666 0.010 3.327
+ ReadX 6883443 0.002 0.729
+ LockX 14298 0.002 0.073
+ UnlockX 14298 0.001 0.042
+ Flush 307777 2.447 303.663
+
+Throughput 1149.6 MB/sec 8 clients 8 procs max_latency=303.666 ms
+
+dbench with 8 clients, results after:
+
+ Operation Count AvgLat MaxLat
+ ----------------------------------------
+ NTCreateX 4269920 0.009 213.532
+ Close 3136653 0.001 0.690
+ Rename 180805 0.082 213.858
+ Unlink 862189 0.050 172.893
+ Deltree 112 2.998 218.328
+ Mkdir 56 0.002 0.003
+ Qpathinfo 3870158 0.004 5.072
+ Qfileinfo 678375 0.001 0.194
+ Qfsinfo 709604 0.002 0.485
+ Sfileinfo 347850 0.004 1.304
+ Find 1496310 0.017 5.504
+ WriteX 2129613 0.010 2.882
+ ReadX 6693066 0.002 1.517
+ LockX 13902 0.002 0.075
+ UnlockX 13902 0.001 0.055
+ Flush 299276 2.511 220.189
+
+Throughput 1187.33 MB/sec 8 clients 8 procs max_latency=220.194 ms
+
++3.2% throughput, -31.8% max latency
+
+dbench with 16 clients, results before:
+
+ Operation Count AvgLat MaxLat
+ ----------------------------------------
+ NTCreateX 5978334 0.028 156.507
+ Close 4391598 0.001 1.345
+ Rename 253136 0.241 155.057
+ Unlink 1207220 0.182 257.344
+ Deltree 160 6.123 36.277
+ Mkdir 80 0.003 0.005
+ Qpathinfo 5418817 0.012 6.867
+ Qfileinfo 949929 0.001 0.941
+ Qfsinfo 993560 0.002 1.386
+ Sfileinfo 486904 0.004 2.829
+ Find 2095088 0.059 8.164
+ WriteX 2982319 0.017 9.029
+ ReadX 9371484 0.002 4.052
+ LockX 19470 0.002 0.461
+ UnlockX 19470 0.001 0.990
+ Flush 418936 2.740 347.902
+
+Throughput 1495.31 MB/sec 16 clients 16 procs max_latency=347.909 ms
+
+dbench with 16 clients, results after:
+
+ Operation Count AvgLat MaxLat
+ ----------------------------------------
+ NTCreateX 5711833 0.029 131.240
+ Close 4195897 0.001 1.732
+ Rename 241849 0.204 147.831
+ Unlink 1153341 0.184 231.322
+ Deltree 160 6.086 30.198
+ Mkdir 80 0.003 0.021
+ Qpathinfo 5177011 0.012 7.150
+ Qfileinfo 907768 0.001 0.793
+ Qfsinfo 949205 0.002 1.431
+ Sfileinfo 465317 0.004 2.454
+ Find 2001541 0.058 7.819
+ WriteX 2850661 0.017 9.110
+ ReadX 8952289 0.002 3.991
+ LockX 18596 0.002 0.655
+ UnlockX 18596 0.001 0.179
+ Flush 400342 2.879 293.607
+
+Throughput 1565.73 MB/sec 16 clients 16 procs max_latency=293.611 ms
+
++4.6% throughput, -16.9% max latency
+
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/inode.c | 48 ++++++++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 42 insertions(+), 6 deletions(-)
+
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index 250b6064876de..591caac2bf814 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -8968,8 +8968,6 @@ static int btrfs_rename_exchange(struct inode *old_dir,
+ /* force full log commit if subvolume involved. */
+ btrfs_set_log_full_commit(trans);
+ } else {
+- btrfs_pin_log_trans(root);
+- root_log_pinned = true;
+ ret = btrfs_insert_inode_ref(trans, dest,
+ new_dentry->d_name.name,
+ new_dentry->d_name.len,
+@@ -8986,8 +8984,6 @@ static int btrfs_rename_exchange(struct inode *old_dir,
+ /* force full log commit if subvolume involved. */
+ btrfs_set_log_full_commit(trans);
+ } else {
+- btrfs_pin_log_trans(dest);
+- dest_log_pinned = true;
+ ret = btrfs_insert_inode_ref(trans, root,
+ old_dentry->d_name.name,
+ old_dentry->d_name.len,
+@@ -9018,6 +9014,29 @@ static int btrfs_rename_exchange(struct inode *old_dir,
+ BTRFS_I(new_inode), 1);
+ }
+
++ /*
++ * Now pin the logs of the roots. We do it to ensure that no other task
++ * can sync the logs while we are in progress with the rename, because
++ * that could result in an inconsistency in case any of the inodes that
++ * are part of this rename operation were logged before.
++ *
++ * We pin the logs even if at this precise moment none of the inodes was
++ * logged before. This is because right after we checked for that, some
++ * other task fsyncing some other inode not involved with this rename
++ * operation could log that one of our inodes exists.
++ *
++ * We don't need to pin the logs before the above calls to
++ * btrfs_insert_inode_ref(), since those don't ever need to change a log.
++ */
++ if (old_ino != BTRFS_FIRST_FREE_OBJECTID) {
++ btrfs_pin_log_trans(root);
++ root_log_pinned = true;
++ }
++ if (new_ino != BTRFS_FIRST_FREE_OBJECTID) {
++ btrfs_pin_log_trans(dest);
++ dest_log_pinned = true;
++ }
++
+ /* src is a subvolume */
+ if (old_ino == BTRFS_FIRST_FREE_OBJECTID) {
+ ret = btrfs_unlink_subvol(trans, old_dir, old_dentry);
+@@ -9267,8 +9286,6 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+ /* force full log commit if subvolume involved. */
+ btrfs_set_log_full_commit(trans);
+ } else {
+- btrfs_pin_log_trans(root);
+- log_pinned = true;
+ ret = btrfs_insert_inode_ref(trans, dest,
+ new_dentry->d_name.name,
+ new_dentry->d_name.len,
+@@ -9292,6 +9309,25 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+ if (unlikely(old_ino == BTRFS_FIRST_FREE_OBJECTID)) {
+ ret = btrfs_unlink_subvol(trans, old_dir, old_dentry);
+ } else {
++ /*
++ * Now pin the log. We do it to ensure that no other task can
++ * sync the log while we are in progress with the rename, as
++ * that could result in an inconsistency in case any of the
++ * inodes that are part of this rename operation were logged
++ * before.
++ *
++ * We pin the log even if at this precise moment none of the
++ * inodes was logged before. This is because right after we
++ * checked for that, some other task fsyncing some other inode
++ * not involved with this rename operation could log that one of
++ * our inodes exists.
++ *
++ * We don't need to pin the logs before the above call to
++ * btrfs_insert_inode_ref(), since that does not need to change
++ * a log.
++ */
++ btrfs_pin_log_trans(root);
++ log_pinned = true;
+ ret = __btrfs_unlink_inode(trans, root, BTRFS_I(old_dir),
+ BTRFS_I(d_inode(old_dentry)),
+ old_dentry->d_name.name,
+--
+2.43.0
+
--- /dev/null
+From cd669746950cf7389ef38fbf8e7916ccde0ba699 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jul 2021 16:19:09 -0300
+Subject: btrfs: introduce btrfs_lookup_match_dir
+
+From: Marcos Paulo de Souza <mpdesouza@suse.com>
+
+[ Upstream commit a7d1c5dc8632e9b370ad26478c468d4e4e29f263 ]
+
+btrfs_search_slot is called in multiple places in dir-item.c to search
+for a dir entry, and then calling btrfs_match_dir_name to return a
+btrfs_dir_item.
+
+In order to reduce the number of callers of btrfs_search_slot, create a
+common function that looks for the dir key, and if found call
+btrfs_match_dir_item_name.
+
+Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: 8dcbc26194eb ("btrfs: unify lookup return value when dir entry is missing")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/dir-item.c | 76 +++++++++++++++++++++++----------------------
+ 1 file changed, 39 insertions(+), 37 deletions(-)
+
+diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c
+index 863367c2c6205..1c0a7cd6b9b0a 100644
+--- a/fs/btrfs/dir-item.c
++++ b/fs/btrfs/dir-item.c
+@@ -171,6 +171,25 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, const char *name,
+ return 0;
+ }
+
++static struct btrfs_dir_item *btrfs_lookup_match_dir(
++ struct btrfs_trans_handle *trans,
++ struct btrfs_root *root, struct btrfs_path *path,
++ struct btrfs_key *key, const char *name,
++ int name_len, int mod)
++{
++ const int ins_len = (mod < 0 ? -1 : 0);
++ const int cow = (mod != 0);
++ int ret;
++
++ ret = btrfs_search_slot(trans, root, key, path, ins_len, cow);
++ if (ret < 0)
++ return ERR_PTR(ret);
++ if (ret > 0)
++ return ERR_PTR(-ENOENT);
++
++ return btrfs_match_dir_item_name(root->fs_info, path, name, name_len);
++}
++
+ /*
+ * lookup a directory item based on name. 'dir' is the objectid
+ * we're searching in, and 'mod' tells us if you plan on deleting the
+@@ -182,23 +201,18 @@ struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans,
+ const char *name, int name_len,
+ int mod)
+ {
+- int ret;
+ struct btrfs_key key;
+- int ins_len = mod < 0 ? -1 : 0;
+- int cow = mod != 0;
++ struct btrfs_dir_item *di;
+
+ key.objectid = dir;
+ key.type = BTRFS_DIR_ITEM_KEY;
+-
+ key.offset = btrfs_name_hash(name, name_len);
+
+- ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
+- if (ret < 0)
+- return ERR_PTR(ret);
+- if (ret > 0)
++ di = btrfs_lookup_match_dir(trans, root, path, &key, name, name_len, mod);
++ if (IS_ERR(di) && PTR_ERR(di) == -ENOENT)
+ return NULL;
+
+- return btrfs_match_dir_item_name(root->fs_info, path, name, name_len);
++ return di;
+ }
+
+ int btrfs_check_dir_item_collision(struct btrfs_root *root, u64 dir,
+@@ -212,7 +226,6 @@ int btrfs_check_dir_item_collision(struct btrfs_root *root, u64 dir,
+ int slot;
+ struct btrfs_path *path;
+
+-
+ path = btrfs_alloc_path();
+ if (!path)
+ return -ENOMEM;
+@@ -221,20 +234,20 @@ int btrfs_check_dir_item_collision(struct btrfs_root *root, u64 dir,
+ key.type = BTRFS_DIR_ITEM_KEY;
+ key.offset = btrfs_name_hash(name, name_len);
+
+- ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+-
+- /* return back any errors */
+- if (ret < 0)
+- goto out;
++ di = btrfs_lookup_match_dir(NULL, root, path, &key, name, name_len, 0);
++ if (IS_ERR(di)) {
++ ret = PTR_ERR(di);
++ /* Nothing found, we're safe */
++ if (ret == -ENOENT) {
++ ret = 0;
++ goto out;
++ }
+
+- /* nothing found, we're safe */
+- if (ret > 0) {
+- ret = 0;
+- goto out;
++ if (ret < 0)
++ goto out;
+ }
+
+ /* we found an item, look for our name in the item */
+- di = btrfs_match_dir_item_name(root->fs_info, path, name, name_len);
+ if (di) {
+ /* our exact name was found */
+ ret = -EEXIST;
+@@ -275,21 +288,13 @@ btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans,
+ u64 objectid, const char *name, int name_len,
+ int mod)
+ {
+- int ret;
+ struct btrfs_key key;
+- int ins_len = mod < 0 ? -1 : 0;
+- int cow = mod != 0;
+
+ key.objectid = dir;
+ key.type = BTRFS_DIR_INDEX_KEY;
+ key.offset = objectid;
+
+- ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
+- if (ret < 0)
+- return ERR_PTR(ret);
+- if (ret > 0)
+- return ERR_PTR(-ENOENT);
+- return btrfs_match_dir_item_name(root->fs_info, path, name, name_len);
++ return btrfs_lookup_match_dir(trans, root, path, &key, name, name_len, mod);
+ }
+
+ struct btrfs_dir_item *
+@@ -346,21 +351,18 @@ struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans,
+ const char *name, u16 name_len,
+ int mod)
+ {
+- int ret;
+ struct btrfs_key key;
+- int ins_len = mod < 0 ? -1 : 0;
+- int cow = mod != 0;
++ struct btrfs_dir_item *di;
+
+ key.objectid = dir;
+ key.type = BTRFS_XATTR_ITEM_KEY;
+ key.offset = btrfs_name_hash(name, name_len);
+- ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
+- if (ret < 0)
+- return ERR_PTR(ret);
+- if (ret > 0)
++
++ di = btrfs_lookup_match_dir(trans, root, path, &key, name, name_len, mod);
++ if (IS_ERR(di) && PTR_ERR(di) == -ENOENT)
+ return NULL;
+
+- return btrfs_match_dir_item_name(root->fs_info, path, name, name_len);
++ return di;
+ }
+
+ /*
+--
+2.43.0
+
--- /dev/null
+From 0599d520506883b8e0763e2949d668c60aa7c8bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Aug 2022 14:28:47 -0400
+Subject: btrfs: tree-checker: check for overlapping extent items
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit 899b7f69f244e539ea5df1b4d756046337de44a5 ]
+
+We're seeing a weird problem in production where we have overlapping
+extent items in the extent tree. It's unclear where these are coming
+from, and in debugging we realized there's no check in the tree checker
+for this sort of problem. Add a check to the tree-checker to make sure
+that the extents do not overlap each other.
+
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.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/btrfs/tree-checker.c | 25 +++++++++++++++++++++++--
+ 1 file changed, 23 insertions(+), 2 deletions(-)
+
+diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c
+index c0eda3816f685..5b952f69bc1f6 100644
+--- a/fs/btrfs/tree-checker.c
++++ b/fs/btrfs/tree-checker.c
+@@ -1189,7 +1189,8 @@ static void extent_err(const struct extent_buffer *eb, int slot,
+ }
+
+ static int check_extent_item(struct extent_buffer *leaf,
+- struct btrfs_key *key, int slot)
++ struct btrfs_key *key, int slot,
++ struct btrfs_key *prev_key)
+ {
+ struct btrfs_fs_info *fs_info = leaf->fs_info;
+ struct btrfs_extent_item *ei;
+@@ -1400,6 +1401,26 @@ static int check_extent_item(struct extent_buffer *leaf,
+ total_refs, inline_refs);
+ return -EUCLEAN;
+ }
++
++ if ((prev_key->type == BTRFS_EXTENT_ITEM_KEY) ||
++ (prev_key->type == BTRFS_METADATA_ITEM_KEY)) {
++ u64 prev_end = prev_key->objectid;
++
++ if (prev_key->type == BTRFS_METADATA_ITEM_KEY)
++ prev_end += fs_info->nodesize;
++ else
++ prev_end += prev_key->offset;
++
++ if (unlikely(prev_end > key->objectid)) {
++ extent_err(leaf, slot,
++ "previous extent [%llu %u %llu] overlaps current extent [%llu %u %llu]",
++ prev_key->objectid, prev_key->type,
++ prev_key->offset, key->objectid, key->type,
++ key->offset);
++ return -EUCLEAN;
++ }
++ }
++
+ return 0;
+ }
+
+@@ -1568,7 +1589,7 @@ static int check_leaf_item(struct extent_buffer *leaf,
+ break;
+ case BTRFS_EXTENT_ITEM_KEY:
+ case BTRFS_METADATA_ITEM_KEY:
+- ret = check_extent_item(leaf, key, slot);
++ ret = check_extent_item(leaf, key, slot, prev_key);
+ break;
+ case BTRFS_TREE_BLOCK_REF_KEY:
+ case BTRFS_SHARED_DATA_REF_KEY:
+--
+2.43.0
+
--- /dev/null
+From a5dd6c29a25b5f8b2be106733df3d0b5e1c92e41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Oct 2021 13:52:33 +0100
+Subject: btrfs: unify lookup return value when dir entry is missing
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 8dcbc26194eb872cc3430550fb70bb461424d267 ]
+
+btrfs_lookup_dir_index_item() and btrfs_lookup_dir_item() lookup for dir
+entries and both are used during log replay or when updating a log tree
+during an unlink.
+
+However when the dir item does not exists, btrfs_lookup_dir_item() returns
+NULL while btrfs_lookup_dir_index_item() returns PTR_ERR(-ENOENT), and if
+the dir item exists but there is no matching entry for a given name or
+index, both return NULL. This makes the call sites during log replay to
+be more verbose than necessary and it makes it easy to miss this slight
+difference. Since we don't need to distinguish between those two cases,
+make btrfs_lookup_dir_index_item() always return NULL when there is no
+matching directory entry - either because there isn't any dir entry or
+because there is one but it does not match the given name and index.
+
+Also rename the argument 'objectid' of btrfs_lookup_dir_index_item() to
+'index' since it is supposed to match an index number, and the name
+'objectid' is not very good because it can easily be confused with an
+inode number (like the inode number a dir entry points to).
+
+CC: stable@vger.kernel.org # 4.14+
+Signed-off-by: Filipe Manana <fdmanana@suse.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/btrfs/ctree.h | 2 +-
+ fs/btrfs/dir-item.c | 48 ++++++++++++++++++++++++++++++++++-----------
+ fs/btrfs/tree-log.c | 14 ++++---------
+ 3 files changed, 42 insertions(+), 22 deletions(-)
+
+diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
+index 67831868ef0de..3ddb09f2b1685 100644
+--- a/fs/btrfs/ctree.h
++++ b/fs/btrfs/ctree.h
+@@ -2879,7 +2879,7 @@ struct btrfs_dir_item *
+ btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ struct btrfs_path *path, u64 dir,
+- u64 objectid, const char *name, int name_len,
++ u64 index, const char *name, int name_len,
+ int mod);
+ struct btrfs_dir_item *
+ btrfs_search_dir_index_item(struct btrfs_root *root,
+diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c
+index 1c0a7cd6b9b0a..98c6faa8ce15b 100644
+--- a/fs/btrfs/dir-item.c
++++ b/fs/btrfs/dir-item.c
+@@ -191,9 +191,20 @@ static struct btrfs_dir_item *btrfs_lookup_match_dir(
+ }
+
+ /*
+- * lookup a directory item based on name. 'dir' is the objectid
+- * we're searching in, and 'mod' tells us if you plan on deleting the
+- * item (use mod < 0) or changing the options (use mod > 0)
++ * Lookup for a directory item by name.
++ *
++ * @trans: The transaction handle to use. Can be NULL if @mod is 0.
++ * @root: The root of the target tree.
++ * @path: Path to use for the search.
++ * @dir: The inode number (objectid) of the directory.
++ * @name: The name associated to the directory entry we are looking for.
++ * @name_len: The length of the name.
++ * @mod: Used to indicate if the tree search is meant for a read only
++ * lookup, for a modification lookup or for a deletion lookup, so
++ * its value should be 0, 1 or -1, respectively.
++ *
++ * Returns: NULL if the dir item does not exists, an error pointer if an error
++ * happened, or a pointer to a dir item if a dir item exists for the given name.
+ */
+ struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+@@ -274,27 +285,42 @@ int btrfs_check_dir_item_collision(struct btrfs_root *root, u64 dir,
+ }
+
+ /*
+- * lookup a directory item based on index. 'dir' is the objectid
+- * we're searching in, and 'mod' tells us if you plan on deleting the
+- * item (use mod < 0) or changing the options (use mod > 0)
++ * Lookup for a directory index item by name and index number.
+ *
+- * The name is used to make sure the index really points to the name you were
+- * looking for.
++ * @trans: The transaction handle to use. Can be NULL if @mod is 0.
++ * @root: The root of the target tree.
++ * @path: Path to use for the search.
++ * @dir: The inode number (objectid) of the directory.
++ * @index: The index number.
++ * @name: The name associated to the directory entry we are looking for.
++ * @name_len: The length of the name.
++ * @mod: Used to indicate if the tree search is meant for a read only
++ * lookup, for a modification lookup or for a deletion lookup, so
++ * its value should be 0, 1 or -1, respectively.
++ *
++ * Returns: NULL if the dir index item does not exists, an error pointer if an
++ * error happened, or a pointer to a dir item if the dir index item exists and
++ * matches the criteria (name and index number).
+ */
+ struct btrfs_dir_item *
+ btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ struct btrfs_path *path, u64 dir,
+- u64 objectid, const char *name, int name_len,
++ u64 index, const char *name, int name_len,
+ int mod)
+ {
++ struct btrfs_dir_item *di;
+ struct btrfs_key key;
+
+ key.objectid = dir;
+ key.type = BTRFS_DIR_INDEX_KEY;
+- key.offset = objectid;
++ key.offset = index;
+
+- return btrfs_lookup_match_dir(trans, root, path, &key, name, name_len, mod);
++ di = btrfs_lookup_match_dir(trans, root, path, &key, name, name_len, mod);
++ if (di == ERR_PTR(-ENOENT))
++ return NULL;
++
++ return di;
+ }
+
+ struct btrfs_dir_item *
+diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
+index 10a0913ffb492..34e9eb5010cda 100644
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -912,8 +912,7 @@ static noinline int inode_in_dir(struct btrfs_root *root,
+ di = btrfs_lookup_dir_index_item(NULL, root, path, dirid,
+ index, name, name_len, 0);
+ if (IS_ERR(di)) {
+- if (PTR_ERR(di) != -ENOENT)
+- ret = PTR_ERR(di);
++ ret = PTR_ERR(di);
+ goto out;
+ } else if (di) {
+ btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location);
+@@ -1149,8 +1148,7 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
+ di = btrfs_lookup_dir_index_item(trans, root, path, btrfs_ino(dir),
+ ref_index, name, namelen, 0);
+ if (IS_ERR(di)) {
+- if (PTR_ERR(di) != -ENOENT)
+- return PTR_ERR(di);
++ return PTR_ERR(di);
+ } else if (di) {
+ ret = drop_one_dir_item(trans, root, path, dir, di);
+ if (ret)
+@@ -1976,9 +1974,6 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
+ goto out;
+ }
+
+- if (dst_di == ERR_PTR(-ENOENT))
+- dst_di = NULL;
+-
+ if (IS_ERR(dst_di)) {
+ ret = PTR_ERR(dst_di);
+ goto out;
+@@ -2286,7 +2281,7 @@ static noinline int check_item_in_log(struct btrfs_trans_handle *trans,
+ dir_key->offset,
+ name, name_len, 0);
+ }
+- if (!log_di || log_di == ERR_PTR(-ENOENT)) {
++ if (!log_di) {
+ btrfs_dir_item_key_to_cpu(eb, di, &location);
+ btrfs_release_path(path);
+ btrfs_release_path(log_path);
+@@ -3495,8 +3490,7 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
+ if (err == -ENOSPC) {
+ btrfs_set_log_full_commit(trans);
+ err = 0;
+- } else if (err < 0 && err != -ENOENT) {
+- /* ENOENT can be returned if the entry hasn't been fsynced yet */
++ } else if (err < 0) {
+ btrfs_abort_transaction(trans, err);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 2f3e26abcc335b77e4bf8176b6351f462bd7ab12 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jun 2023 17:46:56 +0000
+Subject: cifs: add a warning when the in-flight count goes negative
+
+From: Shyam Prasad N <sprasad@microsoft.com>
+
+[ Upstream commit e4645cc2f1e2d6f268bb8dcfac40997c52432aed ]
+
+We've seen the in-flight count go into negative with some
+internal stress testing in Microsoft.
+
+Adding a WARN when this happens, in hope of understanding
+why this happens when it happens.
+
+Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
+Reviewed-by: Bharath SM <bharathsm@microsoft.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/smb2ops.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index f83901c1c17a5..b2a7238a34221 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -82,6 +82,7 @@ smb2_add_credits(struct TCP_Server_Info *server,
+ *val = 65000; /* Don't get near 64K credits, avoid srv bugs */
+ pr_warn_once("server overflowed SMB3 credits\n");
+ }
++ WARN_ON_ONCE(server->in_flight == 0);
+ server->in_flight--;
+ if (server->in_flight == 0 && (optype & CIFS_OP_MASK) != CIFS_NEG_OP)
+ rc = change_conf(server);
+--
+2.43.0
+
--- /dev/null
+From 04e6ec71cc692c92adc9cc18d1adb0c0abd1407b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Nov 2022 17:48:10 +0100
+Subject: hsr: Avoid double remove of a node.
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+[ Upstream commit 0c74d9f79ec4299365bbe803baa736ae0068179e ]
+
+Due to the hashed-MAC optimisation one problem become visible:
+hsr_handle_sup_frame() walks over the list of available nodes and merges
+two node entries into one if based on the information in the supervision
+both MAC addresses belong to one node. The list-walk happens on a RCU
+protected list and delete operation happens under a lock.
+
+If the supervision arrives on both slave interfaces at the same time
+then this delete operation can occur simultaneously on two CPUs. The
+result is the first-CPU deletes the from the list and the second CPUs
+BUGs while attempting to dereference a poisoned list-entry. This happens
+more likely with the optimisation because a new node for the mac_B entry
+is created once a packet has been received and removed (merged) once the
+supervision frame has been received.
+
+Avoid removing/ cleaning up a hsr_node twice by adding a `removed' field
+which is set to true after the removal and checked before the removal.
+
+Fixes: f266a683a4804 ("net/hsr: Better frame dispatch")
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_framereg.c | 16 +++++++++++-----
+ net/hsr/hsr_framereg.h | 1 +
+ 2 files changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c
+index afc97d65cf2d8..87fc86aade5c9 100644
+--- a/net/hsr/hsr_framereg.c
++++ b/net/hsr/hsr_framereg.c
+@@ -327,9 +327,12 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)
+ node_real->addr_B_port = port_rcv->type;
+
+ spin_lock_bh(&hsr->list_lock);
+- list_del_rcu(&node_curr->mac_list);
++ if (!node_curr->removed) {
++ list_del_rcu(&node_curr->mac_list);
++ node_curr->removed = true;
++ kfree_rcu(node_curr, rcu_head);
++ }
+ spin_unlock_bh(&hsr->list_lock);
+- kfree_rcu(node_curr, rcu_head);
+
+ done:
+ /* PRP uses v0 header */
+@@ -506,9 +509,12 @@ void hsr_prune_nodes(struct timer_list *t)
+ if (time_is_before_jiffies(timestamp +
+ msecs_to_jiffies(HSR_NODE_FORGET_TIME))) {
+ hsr_nl_nodedown(hsr, node->macaddress_A);
+- list_del_rcu(&node->mac_list);
+- /* Note that we need to free this entry later: */
+- kfree_rcu(node, rcu_head);
++ if (!node->removed) {
++ list_del_rcu(&node->mac_list);
++ node->removed = true;
++ /* Note that we need to free this entry later: */
++ kfree_rcu(node, rcu_head);
++ }
+ }
+ }
+ spin_unlock_bh(&hsr->list_lock);
+diff --git a/net/hsr/hsr_framereg.h b/net/hsr/hsr_framereg.h
+index 5a771cb3f0325..48990166e4c4e 100644
+--- a/net/hsr/hsr_framereg.h
++++ b/net/hsr/hsr_framereg.h
+@@ -82,6 +82,7 @@ struct hsr_node {
+ bool san_a;
+ bool san_b;
+ u16 seq_out[HSR_PT_PORTS];
++ bool removed;
+ struct rcu_head rcu_head;
+ };
+
+--
+2.43.0
+
--- /dev/null
+From 3c62db5430ed3b672d215d4106bc0732f6c479bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Nov 2022 16:09:11 +0100
+Subject: hvc/xen: prevent concurrent accesses to the shared ring
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Roger Pau Monne <roger.pau@citrix.com>
+
+[ Upstream commit 6214894f49a967c749ee6c07cb00f9cede748df4 ]
+
+The hvc machinery registers both a console and a tty device based on
+the hv ops provided by the specific implementation. Those two
+interfaces however have different locks, and there's no single locks
+that's shared between the tty and the console implementations, hence
+the driver needs to protect itself against concurrent accesses.
+Otherwise concurrent calls using the split interfaces are likely to
+corrupt the ring indexes, leaving the console unusable.
+
+Introduce a lock to xencons_info to serialize accesses to the shared
+ring. This is only required when using the shared memory console,
+concurrent accesses to the hypercall based console implementation are
+not an issue.
+
+Note the conditional logic in domU_read_console() is slightly modified
+so the notify_daemon() call can be done outside of the locked region:
+it's an hypercall and there's no need for it to be done with the lock
+held.
+
+Fixes: b536b4b96230 ('xen: use the hvc console infrastructure for Xen console')
+Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Link: https://lore.kernel.org/r/20221130150919.13935-1-roger.pau@citrix.com
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/hvc/hvc_xen.c | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
+index cf0fb650a9247..4886cad0fde61 100644
+--- a/drivers/tty/hvc/hvc_xen.c
++++ b/drivers/tty/hvc/hvc_xen.c
+@@ -43,6 +43,7 @@ struct xencons_info {
+ int irq;
+ int vtermno;
+ grant_ref_t gntref;
++ spinlock_t ring_lock;
+ };
+
+ static LIST_HEAD(xenconsoles);
+@@ -89,12 +90,15 @@ static int __write_console(struct xencons_info *xencons,
+ XENCONS_RING_IDX cons, prod;
+ struct xencons_interface *intf = xencons->intf;
+ int sent = 0;
++ unsigned long flags;
+
++ spin_lock_irqsave(&xencons->ring_lock, flags);
+ cons = intf->out_cons;
+ prod = intf->out_prod;
+ mb(); /* update queue values before going on */
+
+ if ((prod - cons) > sizeof(intf->out)) {
++ spin_unlock_irqrestore(&xencons->ring_lock, flags);
+ pr_err_once("xencons: Illegal ring page indices");
+ return -EINVAL;
+ }
+@@ -104,6 +108,7 @@ static int __write_console(struct xencons_info *xencons,
+
+ wmb(); /* write ring before updating pointer */
+ intf->out_prod = prod;
++ spin_unlock_irqrestore(&xencons->ring_lock, flags);
+
+ if (sent)
+ notify_daemon(xencons);
+@@ -146,16 +151,19 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len)
+ int recv = 0;
+ struct xencons_info *xencons = vtermno_to_xencons(vtermno);
+ unsigned int eoiflag = 0;
++ unsigned long flags;
+
+ if (xencons == NULL)
+ return -EINVAL;
+ intf = xencons->intf;
+
++ spin_lock_irqsave(&xencons->ring_lock, flags);
+ cons = intf->in_cons;
+ prod = intf->in_prod;
+ mb(); /* get pointers before reading ring */
+
+ if ((prod - cons) > sizeof(intf->in)) {
++ spin_unlock_irqrestore(&xencons->ring_lock, flags);
+ pr_err_once("xencons: Illegal ring page indices");
+ return -EINVAL;
+ }
+@@ -179,10 +187,13 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len)
+ xencons->out_cons = intf->out_cons;
+ xencons->out_cons_same = 0;
+ }
++ if (!recv && xencons->out_cons_same++ > 1) {
++ eoiflag = XEN_EOI_FLAG_SPURIOUS;
++ }
++ spin_unlock_irqrestore(&xencons->ring_lock, flags);
++
+ if (recv) {
+ notify_daemon(xencons);
+- } else if (xencons->out_cons_same++ > 1) {
+- eoiflag = XEN_EOI_FLAG_SPURIOUS;
+ }
+
+ xen_irq_lateeoi(xencons->irq, eoiflag);
+@@ -239,6 +250,7 @@ static int xen_hvm_console_init(void)
+ info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
++ spin_lock_init(&info->ring_lock);
+ } else if (info->intf != NULL) {
+ /* already configured */
+ return 0;
+@@ -275,6 +287,7 @@ static int xen_hvm_console_init(void)
+
+ static int xencons_info_pv_init(struct xencons_info *info, int vtermno)
+ {
++ spin_lock_init(&info->ring_lock);
+ info->evtchn = xen_start_info->console.domU.evtchn;
+ /* GFN == MFN for PV guest */
+ info->intf = gfn_to_virt(xen_start_info->console.domU.mfn);
+@@ -325,6 +338,7 @@ static int xen_initial_domain_console_init(void)
+ info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
++ spin_lock_init(&info->ring_lock);
+ }
+
+ info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0, false);
+@@ -485,6 +499,7 @@ static int xencons_probe(struct xenbus_device *dev,
+ info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
++ spin_lock_init(&info->ring_lock);
+ dev_set_drvdata(&dev->dev, info);
+ info->xbdev = dev;
+ info->vtermno = xenbus_devid_to_vtermno(devid);
+--
+2.43.0
+
--- /dev/null
+From ac8d057dd9d9bd6574fdcde88522ae9c81be174b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Apr 2023 11:31:55 +0100
+Subject: irqchip/mips-gic: Don't touch vl_map if a local interrupt is not
+ routable
+
+From: Jiaxun Yang <jiaxun.yang@flygoat.com>
+
+[ Upstream commit 2c6c9c049510163090b979ea5f92a68ae8d93c45 ]
+
+When a GIC local interrupt is not routable, it's vl_map will be used
+to control some internal states for core (providing IPTI, IPPCI, IPFDC
+input signal for core). Overriding it will interfere core's intetrupt
+controller.
+
+Do not touch vl_map if a local interrupt is not routable, we are not
+going to remap it.
+
+Before dd098a0e0319 (" irqchip/mips-gic: Get rid of the reliance on
+irq_cpu_online()"), if a local interrupt is not routable, then it won't
+be requested from GIC Local domain, and thus gic_all_vpes_irq_cpu_online
+won't be called for that particular interrupt.
+
+Fixes: dd098a0e0319 (" irqchip/mips-gic: Get rid of the reliance on irq_cpu_online()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
+Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
+Tested-by: Serge Semin <fancer.lancer@gmail.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20230424103156.66753-2-jiaxun.yang@flygoat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-mips-gic.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
+index fc25b900cef71..7888e3c08df40 100644
+--- a/drivers/irqchip/irq-mips-gic.c
++++ b/drivers/irqchip/irq-mips-gic.c
+@@ -398,6 +398,8 @@ static void gic_all_vpes_irq_cpu_online(void)
+ unsigned int intr = local_intrs[i];
+ struct gic_all_vpes_chip_data *cd;
+
++ if (!gic_local_irq_is_routable(intr))
++ continue;
+ cd = &gic_all_vpes_chip_data[intr];
+ write_gic_vl_map(mips_gic_vx_map_reg(intr), cd->map);
+ if (cd->mask)
+--
+2.43.0
+
--- /dev/null
+From 097431a2b270f8ecce1b799de76e1050293283e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Dec 2020 23:16:31 +0200
+Subject: iwlwifi: mvm: do more useful queue sync accounting
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 2f7a04c7b03b7fd63b7618e29295fc25732faac1 ]
+
+We're currently doing accounting on the queue sync with an
+atomic variable that counts down the number of remaining
+notifications that we still need.
+
+As we've been hitting issues in this area, modify this to
+track a bitmap of queues, not just the number of queues,
+and print out the remaining bitmap in the warning.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Link: https://lore.kernel.org/r/iwlwifi.20201209231352.0a3fa177cd6b.I7c69ff999419368266279ec27dd618eb450908b3@changeid
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Stable-dep-of: 5f8a3561ea8b ("iwlwifi: mvm: write queue_sync_state only for sync")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 11 ++++++-----
+ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 +-
+ drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 2 +-
+ drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 10 +++++++---
+ 4 files changed, 15 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+index d2c6fdb702732..f2096729ac5ac 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+@@ -5155,8 +5155,7 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
+
+ if (notif->sync) {
+ notif->cookie = mvm->queue_sync_cookie;
+- atomic_set(&mvm->queue_sync_counter,
+- mvm->trans->num_rx_queues);
++ mvm->queue_sync_state = (1 << mvm->trans->num_rx_queues) - 1;
+ }
+
+ ret = iwl_mvm_notify_rx_queue(mvm, qmask, (u8 *)notif,
+@@ -5169,14 +5168,16 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
+ if (notif->sync) {
+ lockdep_assert_held(&mvm->mutex);
+ ret = wait_event_timeout(mvm->rx_sync_waitq,
+- atomic_read(&mvm->queue_sync_counter) == 0 ||
++ READ_ONCE(mvm->queue_sync_state) == 0 ||
+ iwl_mvm_is_radio_killed(mvm),
+ HZ);
+- WARN_ON_ONCE(!ret && !iwl_mvm_is_radio_killed(mvm));
++ WARN_ONCE(!ret && !iwl_mvm_is_radio_killed(mvm),
++ "queue sync: failed to sync, state is 0x%lx\n",
++ mvm->queue_sync_state);
+ }
+
+ out:
+- atomic_set(&mvm->queue_sync_counter, 0);
++ mvm->queue_sync_state = 0;
+ if (notif->sync)
+ mvm->queue_sync_cookie++;
+ }
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+index 64f5a4cb3d3ac..8b779c3a92d43 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+@@ -842,7 +842,7 @@ struct iwl_mvm {
+ unsigned long status;
+
+ u32 queue_sync_cookie;
+- atomic_t queue_sync_counter;
++ unsigned long queue_sync_state;
+ /*
+ * for beacon filtering -
+ * currently only one interface can be supported
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+index 5b173f21e87bf..3548eb57f1f30 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+@@ -725,7 +725,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
+
+ init_waitqueue_head(&mvm->rx_sync_waitq);
+
+- atomic_set(&mvm->queue_sync_counter, 0);
++ mvm->queue_sync_state = 0;
+
+ SET_IEEE80211_DEV(mvm->hw, mvm->trans->dev);
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+index 86b3fb321dfdd..e2a39e8b98d07 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+@@ -853,9 +853,13 @@ void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct napi_struct *napi,
+ WARN_ONCE(1, "Invalid identifier %d", internal_notif->type);
+ }
+
+- if (internal_notif->sync &&
+- !atomic_dec_return(&mvm->queue_sync_counter))
+- wake_up(&mvm->rx_sync_waitq);
++ if (internal_notif->sync) {
++ WARN_ONCE(!test_and_clear_bit(queue, &mvm->queue_sync_state),
++ "queue sync: queue %d responded a second time!\n",
++ queue);
++ if (READ_ONCE(mvm->queue_sync_state) == 0)
++ wake_up(&mvm->rx_sync_waitq);
++ }
+ }
+
+ static void iwl_mvm_oldsn_workaround(struct iwl_mvm *mvm,
+--
+2.43.0
+
--- /dev/null
+From 5af83703fcbf21ff5d7e3c271e56b2eeaa04b972 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Mar 2021 12:14:41 +0300
+Subject: iwlwifi: mvm: write queue_sync_state only for sync
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 5f8a3561ea8bf75ad52cb16dafe69dd550fa542e ]
+
+We use mvm->queue_sync_state to wait for synchronous queue sync
+messages, but if an async one happens inbetween we shouldn't
+clear mvm->queue_sync_state after sending the async one, that
+can run concurrently (at least from the CPU POV) with another
+synchronous queue sync.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Link: https://lore.kernel.org/r/iwlwifi.20210331121101.d11c9bcdb4aa.I0772171dbaec87433a11513e9586d98b5d920b5f@changeid
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+index f2096729ac5ac..08008b0c0637c 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+@@ -5177,9 +5177,10 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
+ }
+
+ out:
+- mvm->queue_sync_state = 0;
+- if (notif->sync)
++ if (notif->sync) {
++ mvm->queue_sync_state = 0;
+ mvm->queue_sync_cookie++;
++ }
+ }
+
+ static void iwl_mvm_sync_rx_queues(struct ieee80211_hw *hw)
+--
+2.43.0
+
--- /dev/null
+From 22f2ba8418a0cc762b4ec67f8c0782abd491d4c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 21:59:26 +0800
+Subject: jbd2: Fix wrongly judgement for buffer head removing while doing
+ checkpoint
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit e34c8dd238d0c9368b746480f313055f5bab5040 ]
+
+Following process,
+
+jbd2_journal_commit_transaction
+// there are several dirty buffer heads in transaction->t_checkpoint_list
+ P1 wb_workfn
+jbd2_log_do_checkpoint
+ if (buffer_locked(bh)) // false
+ __block_write_full_page
+ trylock_buffer(bh)
+ test_clear_buffer_dirty(bh)
+ if (!buffer_dirty(bh))
+ __jbd2_journal_remove_checkpoint(jh)
+ if (buffer_write_io_error(bh)) // false
+ >> bh IO error occurs <<
+ jbd2_cleanup_journal_tail
+ __jbd2_update_log_tail
+ jbd2_write_superblock
+ // The bh won't be replayed in next mount.
+, which could corrupt the ext4 image, fetch a reproducer in [Link].
+
+Since writeback process clears buffer dirty after locking buffer head,
+we can fix it by try locking buffer and check dirtiness while buffer is
+locked, the buffer head can be removed if it is neither dirty nor locked.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=217490
+Fixes: 470decc613ab ("[PATCH] jbd2: initial copy of files from jbd")
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20230606135928.434610-5-yi.zhang@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jbd2/checkpoint.c | 32 +++++++++++++++++---------------
+ 1 file changed, 17 insertions(+), 15 deletions(-)
+
+diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
+index aac17c59b7ece..7898983c9fba0 100644
+--- a/fs/jbd2/checkpoint.c
++++ b/fs/jbd2/checkpoint.c
+@@ -228,20 +228,6 @@ int jbd2_log_do_checkpoint(journal_t *journal)
+ jh = transaction->t_checkpoint_list;
+ bh = jh2bh(jh);
+
+- /*
+- * The buffer may be writing back, or flushing out in the
+- * last couple of cycles, or re-adding into a new transaction,
+- * need to check it again until it's unlocked.
+- */
+- if (buffer_locked(bh)) {
+- get_bh(bh);
+- spin_unlock(&journal->j_list_lock);
+- wait_on_buffer(bh);
+- /* the journal_head may have gone by now */
+- BUFFER_TRACE(bh, "brelse");
+- __brelse(bh);
+- goto retry;
+- }
+ if (jh->b_transaction != NULL) {
+ transaction_t *t = jh->b_transaction;
+ tid_t tid = t->t_tid;
+@@ -276,7 +262,22 @@ int jbd2_log_do_checkpoint(journal_t *journal)
+ spin_lock(&journal->j_list_lock);
+ goto restart;
+ }
+- if (!buffer_dirty(bh)) {
++ if (!trylock_buffer(bh)) {
++ /*
++ * The buffer is locked, it may be writing back, or
++ * flushing out in the last couple of cycles, or
++ * re-adding into a new transaction, need to check
++ * it again until it's unlocked.
++ */
++ get_bh(bh);
++ spin_unlock(&journal->j_list_lock);
++ wait_on_buffer(bh);
++ /* the journal_head may have gone by now */
++ BUFFER_TRACE(bh, "brelse");
++ __brelse(bh);
++ goto retry;
++ } else if (!buffer_dirty(bh)) {
++ unlock_buffer(bh);
+ BUFFER_TRACE(bh, "remove from checkpoint");
+ /*
+ * If the transaction was released or the checkpoint
+@@ -286,6 +287,7 @@ int jbd2_log_do_checkpoint(journal_t *journal)
+ !transaction->t_checkpoint_list)
+ goto out;
+ } else {
++ unlock_buffer(bh);
+ /*
+ * We are about to write the buffer, it could be
+ * raced by some other transaction shrink or buffer
+--
+2.43.0
+
--- /dev/null
+From d2f8623acd10bbb54613815123ec600ef49667ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 21:59:23 +0800
+Subject: jbd2: recheck chechpointing non-dirty buffer
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+[ Upstream commit c2d6fd9d6f35079f1669f0100f05b46708c74b7f ]
+
+There is a long-standing metadata corruption issue that happens from
+time to time, but it's very difficult to reproduce and analyse, benefit
+from the JBD2_CYCLE_RECORD option, we found out that the problem is the
+checkpointing process miss to write out some buffers which are raced by
+another do_get_write_access(). Looks below for detail.
+
+jbd2_log_do_checkpoint() //transaction X
+ //buffer A is dirty and not belones to any transaction
+ __buffer_relink_io() //move it to the IO list
+ __flush_batch()
+ write_dirty_buffer()
+ do_get_write_access()
+ clear_buffer_dirty
+ __jbd2_journal_file_buffer()
+ //add buffer A to a new transaction Y
+ lock_buffer(bh)
+ //doesn't write out
+ __jbd2_journal_remove_checkpoint()
+ //finish checkpoint except buffer A
+ //filesystem corrupt if the new transaction Y isn't fully write out.
+
+Due to the t_checkpoint_list walking loop in jbd2_log_do_checkpoint()
+have already handles waiting for buffers under IO and re-added new
+transaction to complete commit, and it also removing cleaned buffers,
+this makes sure the list will eventually get empty. So it's fine to
+leave buffers on the t_checkpoint_list while flushing out and completely
+stop using the t_checkpoint_io_list.
+
+Cc: stable@vger.kernel.org
+Suggested-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Tested-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20230606135928.434610-2-yi.zhang@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: e34c8dd238d0 ("jbd2: Fix wrongly judgement for buffer head removing while doing checkpoint")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jbd2/checkpoint.c | 102 ++++++++++++-------------------------------
+ 1 file changed, 29 insertions(+), 73 deletions(-)
+
+diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
+index ea08adcea84c3..aac17c59b7ece 100644
+--- a/fs/jbd2/checkpoint.c
++++ b/fs/jbd2/checkpoint.c
+@@ -57,28 +57,6 @@ static inline void __buffer_unlink(struct journal_head *jh)
+ }
+ }
+
+-/*
+- * Move a buffer from the checkpoint list to the checkpoint io list
+- *
+- * Called with j_list_lock held
+- */
+-static inline void __buffer_relink_io(struct journal_head *jh)
+-{
+- transaction_t *transaction = jh->b_cp_transaction;
+-
+- __buffer_unlink_first(jh);
+-
+- if (!transaction->t_checkpoint_io_list) {
+- jh->b_cpnext = jh->b_cpprev = jh;
+- } else {
+- jh->b_cpnext = transaction->t_checkpoint_io_list;
+- jh->b_cpprev = transaction->t_checkpoint_io_list->b_cpprev;
+- jh->b_cpprev->b_cpnext = jh;
+- jh->b_cpnext->b_cpprev = jh;
+- }
+- transaction->t_checkpoint_io_list = jh;
+-}
+-
+ /*
+ * Try to release a checkpointed buffer from its transaction.
+ * Returns 1 if we released it and 2 if we also released the
+@@ -190,6 +168,7 @@ __flush_batch(journal_t *journal, int *batch_count)
+ struct buffer_head *bh = journal->j_chkpt_bhs[i];
+ BUFFER_TRACE(bh, "brelse");
+ __brelse(bh);
++ journal->j_chkpt_bhs[i] = NULL;
+ }
+ *batch_count = 0;
+ }
+@@ -249,6 +228,11 @@ int jbd2_log_do_checkpoint(journal_t *journal)
+ jh = transaction->t_checkpoint_list;
+ bh = jh2bh(jh);
+
++ /*
++ * The buffer may be writing back, or flushing out in the
++ * last couple of cycles, or re-adding into a new transaction,
++ * need to check it again until it's unlocked.
++ */
+ if (buffer_locked(bh)) {
+ get_bh(bh);
+ spin_unlock(&journal->j_list_lock);
+@@ -294,28 +278,32 @@ int jbd2_log_do_checkpoint(journal_t *journal)
+ }
+ if (!buffer_dirty(bh)) {
+ BUFFER_TRACE(bh, "remove from checkpoint");
+- if (__jbd2_journal_remove_checkpoint(jh))
+- /* The transaction was released; we're done */
++ /*
++ * If the transaction was released or the checkpoint
++ * list was empty, we're done.
++ */
++ if (__jbd2_journal_remove_checkpoint(jh) ||
++ !transaction->t_checkpoint_list)
+ goto out;
+- continue;
++ } else {
++ /*
++ * We are about to write the buffer, it could be
++ * raced by some other transaction shrink or buffer
++ * re-log logic once we release the j_list_lock,
++ * leave it on the checkpoint list and check status
++ * again to make sure it's clean.
++ */
++ BUFFER_TRACE(bh, "queue");
++ get_bh(bh);
++ J_ASSERT_BH(bh, !buffer_jwrite(bh));
++ journal->j_chkpt_bhs[batch_count++] = bh;
++ transaction->t_chp_stats.cs_written++;
++ transaction->t_checkpoint_list = jh->b_cpnext;
+ }
+- /*
+- * Important: we are about to write the buffer, and
+- * possibly block, while still holding the journal
+- * lock. We cannot afford to let the transaction
+- * logic start messing around with this buffer before
+- * we write it to disk, as that would break
+- * recoverability.
+- */
+- BUFFER_TRACE(bh, "queue");
+- get_bh(bh);
+- J_ASSERT_BH(bh, !buffer_jwrite(bh));
+- journal->j_chkpt_bhs[batch_count++] = bh;
+- __buffer_relink_io(jh);
+- transaction->t_chp_stats.cs_written++;
++
+ if ((batch_count == JBD2_NR_BATCH) ||
+- need_resched() ||
+- spin_needbreak(&journal->j_list_lock))
++ need_resched() || spin_needbreak(&journal->j_list_lock) ||
++ jh2bh(transaction->t_checkpoint_list) == journal->j_chkpt_bhs[0])
+ goto unlock_and_flush;
+ }
+
+@@ -329,38 +317,6 @@ int jbd2_log_do_checkpoint(journal_t *journal)
+ goto restart;
+ }
+
+- /*
+- * Now we issued all of the transaction's buffers, let's deal
+- * with the buffers that are out for I/O.
+- */
+-restart2:
+- /* Did somebody clean up the transaction in the meanwhile? */
+- if (journal->j_checkpoint_transactions != transaction ||
+- transaction->t_tid != this_tid)
+- goto out;
+-
+- while (transaction->t_checkpoint_io_list) {
+- jh = transaction->t_checkpoint_io_list;
+- bh = jh2bh(jh);
+- if (buffer_locked(bh)) {
+- get_bh(bh);
+- spin_unlock(&journal->j_list_lock);
+- wait_on_buffer(bh);
+- /* the journal_head may have gone by now */
+- BUFFER_TRACE(bh, "brelse");
+- __brelse(bh);
+- spin_lock(&journal->j_list_lock);
+- goto restart2;
+- }
+-
+- /*
+- * Now in whatever state the buffer currently is, we
+- * know that it has been written out and so we can
+- * drop it from the list
+- */
+- if (__jbd2_journal_remove_checkpoint(jh))
+- break;
+- }
+ out:
+ spin_unlock(&journal->j_list_lock);
+ result = jbd2_cleanup_journal_tail(journal);
+--
+2.43.0
+
--- /dev/null
+From 5b9158f65a056fb8b4398665d84b2d785cc0aa67 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jun 2021 19:24:36 +0800
+Subject: jbd2: remove redundant buffer io error checks
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+[ Upstream commit 214eb5a4d8a2032fb9f0711d1b202eb88ee02920 ]
+
+Now that __jbd2_journal_remove_checkpoint() can detect buffer io error
+and mark journal checkpoint error, then we abort the journal later
+before updating log tail to ensure the filesystem works consistently.
+So we could remove other redundant buffer io error checkes.
+
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20210610112440.3438139-5-yi.zhang@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: e34c8dd238d0 ("jbd2: Fix wrongly judgement for buffer head removing while doing checkpoint")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jbd2/checkpoint.c | 13 ++-----------
+ 1 file changed, 2 insertions(+), 11 deletions(-)
+
+diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
+index 472932b9e6bca..ea08adcea84c3 100644
+--- a/fs/jbd2/checkpoint.c
++++ b/fs/jbd2/checkpoint.c
+@@ -91,8 +91,7 @@ static int __try_to_free_cp_buf(struct journal_head *jh)
+ int ret = 0;
+ struct buffer_head *bh = jh2bh(jh);
+
+- if (jh->b_transaction == NULL && !buffer_locked(bh) &&
+- !buffer_dirty(bh) && !buffer_write_io_error(bh)) {
++ if (!jh->b_transaction && !buffer_locked(bh) && !buffer_dirty(bh)) {
+ JBUFFER_TRACE(jh, "remove from checkpoint list");
+ ret = __jbd2_journal_remove_checkpoint(jh) + 1;
+ }
+@@ -228,7 +227,6 @@ int jbd2_log_do_checkpoint(journal_t *journal)
+ * OK, we need to start writing disk blocks. Take one transaction
+ * and write it.
+ */
+- result = 0;
+ spin_lock(&journal->j_list_lock);
+ if (!journal->j_checkpoint_transactions)
+ goto out;
+@@ -295,8 +293,6 @@ int jbd2_log_do_checkpoint(journal_t *journal)
+ goto restart;
+ }
+ if (!buffer_dirty(bh)) {
+- if (unlikely(buffer_write_io_error(bh)) && !result)
+- result = -EIO;
+ BUFFER_TRACE(bh, "remove from checkpoint");
+ if (__jbd2_journal_remove_checkpoint(jh))
+ /* The transaction was released; we're done */
+@@ -356,8 +352,6 @@ int jbd2_log_do_checkpoint(journal_t *journal)
+ spin_lock(&journal->j_list_lock);
+ goto restart2;
+ }
+- if (unlikely(buffer_write_io_error(bh)) && !result)
+- result = -EIO;
+
+ /*
+ * Now in whatever state the buffer currently is, we
+@@ -369,10 +363,7 @@ int jbd2_log_do_checkpoint(journal_t *journal)
+ }
+ out:
+ spin_unlock(&journal->j_list_lock);
+- if (result < 0)
+- jbd2_journal_abort(journal, result);
+- else
+- result = jbd2_cleanup_journal_tail(journal);
++ result = jbd2_cleanup_journal_tail(journal);
+
+ return (result < 0) ? result : 0;
+ }
+--
+2.43.0
+
--- /dev/null
+From 424ca6f0f8d94d59316320866b8e41b1ab614b1a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Nov 2020 01:35:55 +0300
+Subject: lan743x: fix for potential NULL pointer dereference with bare card
+
+From: Sergej Bauer <sbauer@blackbox.su>
+
+[ Upstream commit e9e13b6adc338be1eb88db87bcb392696144bd02 ]
+
+This is the 3rd revision of the patch fix for potential null pointer dereference
+with lan743x card.
+
+The simpliest way to reproduce: boot with bare lan743x and issue "ethtool ethN"
+commant where ethN is the interface with lan743x card. Example:
+
+$ sudo ethtool eth7
+dmesg:
+[ 103.510336] BUG: kernel NULL pointer dereference, address: 0000000000000340
+...
+[ 103.510836] RIP: 0010:phy_ethtool_get_wol+0x5/0x30 [libphy]
+...
+[ 103.511629] Call Trace:
+[ 103.511666] lan743x_ethtool_get_wol+0x21/0x40 [lan743x]
+[ 103.511724] dev_ethtool+0x1507/0x29d0
+[ 103.511769] ? avc_has_extended_perms+0x17f/0x440
+[ 103.511820] ? tomoyo_init_request_info+0x84/0x90
+[ 103.511870] ? tomoyo_path_number_perm+0x68/0x1e0
+[ 103.511919] ? tty_insert_flip_string_fixed_flag+0x82/0xe0
+[ 103.511973] ? inet_ioctl+0x187/0x1d0
+[ 103.512016] dev_ioctl+0xb5/0x560
+[ 103.512055] sock_do_ioctl+0xa0/0x140
+[ 103.512098] sock_ioctl+0x2cb/0x3c0
+[ 103.512139] __x64_sys_ioctl+0x84/0xc0
+[ 103.512183] do_syscall_64+0x33/0x80
+[ 103.512224] entry_SYSCALL_64_after_hwframe+0x44/0xa9
+[ 103.512274] RIP: 0033:0x7f54a9cba427
+...
+
+Previous versions can be found at:
+v1:
+initial version
+ https://lkml.org/lkml/2020/10/28/921
+
+v2:
+do not return from lan743x_ethtool_set_wol if netdev->phydev == NULL, just skip
+the call of phy_ethtool_set_wol() instead.
+ https://lkml.org/lkml/2020/10/31/380
+
+v3:
+in function lan743x_ethtool_set_wol:
+use ternary operator instead of if-else sentence (review by Markus Elfring)
+return -ENETDOWN insted of -EIO (review by Andrew Lunn)
+
+Signed-off-by: Sergej Bauer <sbauer@blackbox.su>
+
+Link: https://lore.kernel.org/r/20201101223556.16116-1-sbauer@blackbox.su
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/lan743x_ethtool.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/microchip/lan743x_ethtool.c b/drivers/net/ethernet/microchip/lan743x_ethtool.c
+index dcde496da7fb4..c5de8f46cdd35 100644
+--- a/drivers/net/ethernet/microchip/lan743x_ethtool.c
++++ b/drivers/net/ethernet/microchip/lan743x_ethtool.c
+@@ -780,7 +780,9 @@ static void lan743x_ethtool_get_wol(struct net_device *netdev,
+
+ wol->supported = 0;
+ wol->wolopts = 0;
+- phy_ethtool_get_wol(netdev->phydev, wol);
++
++ if (netdev->phydev)
++ phy_ethtool_get_wol(netdev->phydev, wol);
+
+ wol->supported |= WAKE_BCAST | WAKE_UCAST | WAKE_MCAST |
+ WAKE_MAGIC | WAKE_PHY | WAKE_ARP;
+@@ -809,9 +811,8 @@ static int lan743x_ethtool_set_wol(struct net_device *netdev,
+
+ device_set_wakeup_enable(&adapter->pdev->dev, (bool)wol->wolopts);
+
+- phy_ethtool_set_wol(netdev->phydev, wol);
+-
+- return 0;
++ return netdev->phydev ? phy_ethtool_set_wol(netdev->phydev, wol)
++ : -ENETDOWN;
+ }
+ #endif /* CONFIG_PM */
+
+--
+2.43.0
+
--- /dev/null
+From be5fe86adde5088bf8b48eb9d14ac347c69c5714 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Mar 2023 11:00:23 +0100
+Subject: media: av7110: prevent underflow in write_ts_to_decoder()
+
+From: Dan Carpenter <error27@gmail.com>
+
+[ Upstream commit eed9496a0501357aa326ddd6b71408189ed872eb ]
+
+The buf[4] value comes from the user via ts_play(). It is a value in
+the u8 range. The final length we pass to av7110_ipack_instant_repack()
+is "len - (buf[4] + 1) - 4" so add a check to ensure that the length is
+not negative. It's not clear that passing a negative len value does
+anything bad necessarily, but it's not best practice.
+
+With the new bounds checking the "if (!len)" condition is no longer
+possible or required so remove that.
+
+Fixes: fd46d16d602a ("V4L/DVB (11759): dvb-ttpci: Add TS replay capability")
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/ttpci/av7110_av.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/pci/ttpci/av7110_av.c b/drivers/media/pci/ttpci/av7110_av.c
+index ea9f7d0058a21..e201d5a56bc65 100644
+--- a/drivers/media/pci/ttpci/av7110_av.c
++++ b/drivers/media/pci/ttpci/av7110_av.c
+@@ -822,10 +822,10 @@ static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, s
+ av7110_ipack_flush(ipack);
+
+ if (buf[3] & ADAPT_FIELD) {
++ if (buf[4] > len - 1 - 4)
++ return 0;
+ len -= buf[4] + 1;
+ buf += buf[4] + 1;
+- if (!len)
+- return 0;
+ }
+
+ av7110_ipack_instant_repack(buf + 4, len - 4, ipack);
+--
+2.43.0
+
--- /dev/null
+From 14e828b93fb1104ce9f4c90f7e5ff2d1bcbde356 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Nov 2020 15:23:40 +0800
+Subject: mtd: spinand: macronix: Add support for MX35LFxGE4AD
+
+From: YouChing Lin <ycllin@mxic.com.tw>
+
+[ Upstream commit 5ece78de88739b4c68263e9f2582380c1fd8314f ]
+
+The Macronix MX35LF2GE4AD / MX35LF4GE4AD are 3V, 2G / 4Gbit serial
+SLC NAND flash device (with on-die ECC).
+
+Validated by read, erase, read back, write, read back and nandtest
+on Xilinx Zynq PicoZed FPGA board which included Macronix SPI Host
+(drivers/spi/spi-mxic.c).
+
+Signed-off-by: YouChing Lin <ycllin@mxic.com.tw>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/1604561020-13499-1-git-send-email-ycllin@mxic.com.tw
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/spi/macronix.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
+index cd7a9cacc3fbf..8bd3f6bf9b103 100644
+--- a/drivers/mtd/nand/spi/macronix.c
++++ b/drivers/mtd/nand/spi/macronix.c
+@@ -119,6 +119,26 @@ static const struct spinand_info macronix_spinand_table[] = {
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
++ SPINAND_INFO("MX35LF2GE4AD",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x26),
++ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
++ NAND_ECCREQ(8, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++ &write_cache_variants,
++ &update_cache_variants),
++ 0,
++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
++ mx35lf1ge4ab_ecc_get_status)),
++ SPINAND_INFO("MX35LF4GE4AD",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x37),
++ NAND_MEMORG(1, 4096, 128, 64, 2048, 40, 1, 1, 1),
++ NAND_ECCREQ(8, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++ &write_cache_variants,
++ &update_cache_variants),
++ 0,
++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
++ mx35lf1ge4ab_ecc_get_status)),
+ SPINAND_INFO("MX31LF1GE4BC",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e),
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
+--
+2.43.0
+
--- /dev/null
+From 522cb6e3e939db76edc8a79b247cb6fdca623c83 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Nov 2020 15:16:52 +0200
+Subject: platform/x86: intel-vbtn: Support for tablet mode on HP Pavilion 13
+ x360 PC
+
+From: Max Verevkin <me@maxverevkin.tk>
+
+[ Upstream commit 07b211992d6c0d80b321403244d43bbd2d6cf48c ]
+
+The Pavilion 13 x360 PC has a chassis-type which does not indicate it is
+a convertible, while it is actually a convertible. Add it to the
+dmi_switches_allow_list.
+
+Signed-off-by: Max Verevkin <me@maxverevkin.tk>
+Link: https://lore.kernel.org/r/20201124131652.11165-1-me@maxverevkin.tk
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/intel-vbtn.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c
+index a90c32d072da3..9c8a6722f115e 100644
+--- a/drivers/platform/x86/intel-vbtn.c
++++ b/drivers/platform/x86/intel-vbtn.c
+@@ -230,6 +230,12 @@ static const struct dmi_system_id dmi_switches_allow_list[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7352"),
+ },
+ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion 13 x360 PC"),
++ },
++ },
+ {} /* Array terminator */
+ };
+
+--
+2.43.0
+
--- /dev/null
+From af4b485cb28c3df3f0daeae34a22e879dda41be0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Nov 2020 10:26:50 +0530
+Subject: powerpc/watchpoint: Workaround P10 DD1 issue with VSX-32 byte
+ instructions
+
+From: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
+
+[ Upstream commit 3d2ffcdd2a982e8bbe65fa0f94fb21bf304c281e ]
+
+POWER10 DD1 has an issue where it generates watchpoint exceptions when
+it shouldn't. The conditions where this occur are:
+
+ - octword op
+ - ending address of DAWR range is less than starting address of op
+ - those addresses need to be in the same or in two consecutive 512B
+ blocks
+ - 'op address + 64B' generates an address that has a carry into bit
+ 52 (crosses 2K boundary)
+
+Handle such spurious exception by considering them as extraneous and
+emulating/single-steeping instruction without generating an event.
+
+[ravi: Fixed build warning reported by lkp@intel.com]
+Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20201106045650.278987-1-ravi.bangoria@linux.ibm.com
+Stable-dep-of: 27646b2e02b0 ("powerpc/watchpoints: Annotate atomic context in more places")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/hw_breakpoint.c | 67 ++++++++++++++++++++++++++++-
+ 1 file changed, 65 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
+index 6e5bed50c3578..49273f67c7498 100644
+--- a/arch/powerpc/kernel/hw_breakpoint.c
++++ b/arch/powerpc/kernel/hw_breakpoint.c
+@@ -504,6 +504,11 @@ static bool is_larx_stcx_instr(int type)
+ return type == LARX || type == STCX;
+ }
+
++static bool is_octword_vsx_instr(int type, int size)
++{
++ return ((type == LOAD_VSX || type == STORE_VSX) && size == 32);
++}
++
+ /*
+ * We've failed in reliably handling the hw-breakpoint. Unregister
+ * it and throw a warning message to let the user know about it.
+@@ -554,6 +559,58 @@ static bool stepping_handler(struct pt_regs *regs, struct perf_event **bp,
+ return true;
+ }
+
++static void handle_p10dd1_spurious_exception(struct arch_hw_breakpoint **info,
++ int *hit, unsigned long ea)
++{
++ int i;
++ unsigned long hw_end_addr;
++
++ /*
++ * Handle spurious exception only when any bp_per_reg is set.
++ * Otherwise this might be created by xmon and not actually a
++ * spurious exception.
++ */
++ for (i = 0; i < nr_wp_slots(); i++) {
++ if (!info[i])
++ continue;
++
++ hw_end_addr = ALIGN(info[i]->address + info[i]->len, HW_BREAKPOINT_SIZE);
++
++ /*
++ * Ending address of DAWR range is less than starting
++ * address of op.
++ */
++ if ((hw_end_addr - 1) >= ea)
++ continue;
++
++ /*
++ * Those addresses need to be in the same or in two
++ * consecutive 512B blocks;
++ */
++ if (((hw_end_addr - 1) >> 10) != (ea >> 10))
++ continue;
++
++ /*
++ * 'op address + 64B' generates an address that has a
++ * carry into bit 52 (crosses 2K boundary).
++ */
++ if ((ea & 0x800) == ((ea + 64) & 0x800))
++ continue;
++
++ break;
++ }
++
++ if (i == nr_wp_slots())
++ return;
++
++ for (i = 0; i < nr_wp_slots(); i++) {
++ if (info[i]) {
++ hit[i] = 1;
++ info[i]->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ;
++ }
++ }
++}
++
+ int hw_breakpoint_handler(struct die_args *args)
+ {
+ bool err = false;
+@@ -612,8 +669,14 @@ int hw_breakpoint_handler(struct die_args *args)
+ goto reset;
+
+ if (!nr_hit) {
+- rc = NOTIFY_DONE;
+- goto out;
++ /* Workaround for Power10 DD1 */
++ if (!IS_ENABLED(CONFIG_PPC_8xx) && mfspr(SPRN_PVR) == 0x800100 &&
++ is_octword_vsx_instr(type, size)) {
++ handle_p10dd1_spurious_exception(info, hit, ea);
++ } else {
++ rc = NOTIFY_DONE;
++ goto out;
++ }
+ }
+
+ /*
+--
+2.43.0
+
--- /dev/null
+From 89d36f31280e1e585885ed9df519c4ffc110e9f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Aug 2023 16:34:57 +1000
+Subject: powerpc/watchpoints: Annotate atomic context in more places
+
+From: Benjamin Gray <bgray@linux.ibm.com>
+
+[ Upstream commit 27646b2e02b096a6936b3e3b6ba334ae20763eab ]
+
+It can be easy to miss that the notifier mechanism invokes the callbacks
+in an atomic context, so add some comments to that effect on the two
+handlers we register here.
+
+Signed-off-by: Benjamin Gray <bgray@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20230829063457.54157-4-bgray@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/hw_breakpoint.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
+index 49273f67c7498..ca3374c6f3749 100644
+--- a/arch/powerpc/kernel/hw_breakpoint.c
++++ b/arch/powerpc/kernel/hw_breakpoint.c
+@@ -611,6 +611,11 @@ static void handle_p10dd1_spurious_exception(struct arch_hw_breakpoint **info,
+ }
+ }
+
++/*
++ * Handle a DABR or DAWR exception.
++ *
++ * Called in atomic context.
++ */
+ int hw_breakpoint_handler(struct die_args *args)
+ {
+ bool err = false;
+@@ -737,6 +742,8 @@ NOKPROBE_SYMBOL(hw_breakpoint_handler);
+
+ /*
+ * Handle single-step exceptions following a DABR hit.
++ *
++ * Called in atomic context.
+ */
+ static int single_step_dabr_instruction(struct die_args *args)
+ {
+@@ -794,6 +801,8 @@ NOKPROBE_SYMBOL(single_step_dabr_instruction);
+
+ /*
+ * Handle debug exception notifications.
++ *
++ * Called in atomic context.
+ */
+ int hw_breakpoint_exceptions_notify(
+ struct notifier_block *unused, unsigned long val, void *data)
+--
+2.43.0
+
--- /dev/null
+From ecf30932cf59a59ff4a6e5a91cc7a3daf513bea7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Feb 2022 20:21:13 -0800
+Subject: seccomp: Invalidate seccomp mode to catch death failures
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 495ac3069a6235bfdf516812a2a9b256671bbdf9 ]
+
+If seccomp tries to kill a process, it should never see that process
+again. To enforce this proactively, switch the mode to something
+impossible. If encountered: WARN, reject all syscalls, and attempt to
+kill the process again even harder.
+
+Cc: Andy Lutomirski <luto@amacapital.net>
+Cc: Will Drewry <wad@chromium.org>
+Fixes: 8112c4f140fa ("seccomp: remove 2-phase API")
+Cc: stable@vger.kernel.org
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/seccomp.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/kernel/seccomp.c b/kernel/seccomp.c
+index 305f0eca163ed..0b0331346e4be 100644
+--- a/kernel/seccomp.c
++++ b/kernel/seccomp.c
+@@ -29,6 +29,9 @@
+ #include <linux/syscalls.h>
+ #include <linux/sysctl.h>
+
++/* Not exposed in headers: strictly internal use only. */
++#define SECCOMP_MODE_DEAD (SECCOMP_MODE_FILTER + 1)
++
+ #ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
+ #include <asm/syscall.h>
+ #endif
+@@ -795,6 +798,7 @@ static void __secure_computing_strict(int this_syscall)
+ #ifdef SECCOMP_DEBUG
+ dump_stack();
+ #endif
++ current->seccomp.mode = SECCOMP_MODE_DEAD;
+ seccomp_log(this_syscall, SIGKILL, SECCOMP_RET_KILL_THREAD, true);
+ do_exit(SIGKILL);
+ }
+@@ -1023,6 +1027,7 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
+ case SECCOMP_RET_KILL_THREAD:
+ case SECCOMP_RET_KILL_PROCESS:
+ default:
++ current->seccomp.mode = SECCOMP_MODE_DEAD;
+ seccomp_log(this_syscall, SIGSYS, action, true);
+ /* Dump core only if this is the last remaining thread. */
+ if (action != SECCOMP_RET_KILL_THREAD ||
+@@ -1075,6 +1080,11 @@ int __secure_computing(const struct seccomp_data *sd)
+ return 0;
+ case SECCOMP_MODE_FILTER:
+ return __seccomp_filter(this_syscall, sd, false);
++ /* Surviving SECCOMP_RET_KILL_* must be proactively impossible. */
++ case SECCOMP_MODE_DEAD:
++ WARN_ON_ONCE(1);
++ do_exit(SIGKILL);
++ return -1;
+ default:
+ BUG();
+ }
+--
+2.43.0
+
firewire-core-send-bus-reset-promptly-on-gap-count-e.patch
virtio-blk-ensure-no-requests-in-virtqueues-before-d.patch
pmdomain-renesas-r8a77980-sysc-cr7-must-be-always-on.patch
+arm-dts-bcm53573-drop-nonexistent-default-off-led-tr.patch
+irqchip-mips-gic-don-t-touch-vl_map-if-a-local-inter.patch
+arm-dts-imx-set-default-tuning-step-for-imx6sx-usdhc.patch
+asoc-fsl_micfil-register-platform-component-before-r.patch
+media-av7110-prevent-underflow-in-write_ts_to_decode.patch
+hvc-xen-prevent-concurrent-accesses-to-the-shared-ri.patch
+hsr-avoid-double-remove-of-a-node.patch
+x86-uaccess-implement-macros-for-cmpxchg-on-user-add.patch
+seccomp-invalidate-seccomp-mode-to-catch-death-failu.patch
+block-ataflop-fix-breakage-introduced-at-blk-mq-refa.patch
+powerpc-watchpoint-workaround-p10-dd1-issue-with-vsx.patch
+powerpc-watchpoints-annotate-atomic-context-in-more-.patch
+cifs-add-a-warning-when-the-in-flight-count-goes-neg.patch
+mtd-spinand-macronix-add-support-for-mx35lfxge4ad.patch
+asoc-intel-boards-harden-codec-property-handling.patch
+asoc-intel-boards-get-codec-device-with-acpi-instead.patch
+asoc-intel-bytcr_rt5651-drop-reference-count-of-acpi.patch
+task_stack-x86-cea-force-inline-stack-helpers.patch
+btrfs-tree-checker-check-for-overlapping-extent-item.patch
+btrfs-introduce-btrfs_lookup_match_dir.patch
+btrfs-unify-lookup-return-value-when-dir-entry-is-mi.patch
+btrfs-do-not-pin-logs-too-early-during-renames.patch
+lan743x-fix-for-potential-null-pointer-dereference-w.patch
+platform-x86-intel-vbtn-support-for-tablet-mode-on-h.patch
+iwlwifi-mvm-do-more-useful-queue-sync-accounting.patch
+iwlwifi-mvm-write-queue_sync_state-only-for-sync.patch
+jbd2-remove-redundant-buffer-io-error-checks.patch
+jbd2-recheck-chechpointing-non-dirty-buffer.patch
+jbd2-fix-wrongly-judgement-for-buffer-head-removing-.patch
--- /dev/null
+From 7486ddef1504b2dfc412194ab7fe03de0a6e78a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Mar 2022 20:02:41 +0100
+Subject: task_stack, x86/cea: Force-inline stack helpers
+
+From: Borislav Petkov <bp@suse.de>
+
+[ Upstream commit e87f4152e542610d0b4c6c8548964a68a59d2040 ]
+
+Force-inline two stack helpers to fix the following objtool warnings:
+
+ vmlinux.o: warning: objtool: in_task_stack()+0xc: call to task_stack_page() leaves .noinstr.text section
+ vmlinux.o: warning: objtool: in_entry_stack()+0x10: call to cpu_entry_stack() leaves .noinstr.text section
+
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20220324183607.31717-2-bp@alien8.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/cpu_entry_area.h | 2 +-
+ include/linux/sched/task_stack.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/include/asm/cpu_entry_area.h b/arch/x86/include/asm/cpu_entry_area.h
+index dd5ea1bdf04c5..75efc4c6f0766 100644
+--- a/arch/x86/include/asm/cpu_entry_area.h
++++ b/arch/x86/include/asm/cpu_entry_area.h
+@@ -143,7 +143,7 @@ extern void cea_set_pte(void *cea_vaddr, phys_addr_t pa, pgprot_t flags);
+
+ extern struct cpu_entry_area *get_cpu_entry_area(int cpu);
+
+-static inline struct entry_stack *cpu_entry_stack(int cpu)
++static __always_inline struct entry_stack *cpu_entry_stack(int cpu)
+ {
+ return &get_cpu_entry_area(cpu)->entry_stack_page.stack;
+ }
+diff --git a/include/linux/sched/task_stack.h b/include/linux/sched/task_stack.h
+index f24575942dabe..879a5c8f930b6 100644
+--- a/include/linux/sched/task_stack.h
++++ b/include/linux/sched/task_stack.h
+@@ -16,7 +16,7 @@
+ * try_get_task_stack() instead. task_stack_page will return a pointer
+ * that could get freed out from under you.
+ */
+-static inline void *task_stack_page(const struct task_struct *task)
++static __always_inline void *task_stack_page(const struct task_struct *task)
+ {
+ return task->stack;
+ }
+--
+2.43.0
+
--- /dev/null
+From 3ebd53663a48d6f20320150fba80da41e4614589 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Feb 2022 00:49:42 +0000
+Subject: x86/uaccess: Implement macros for CMPXCHG on user addresses
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit 989b5db215a2f22f89d730b607b071d964780f10 ]
+
+Add support for CMPXCHG loops on userspace addresses. Provide both an
+"unsafe" version for tight loops that do their own uaccess begin/end, as
+well as a "safe" version for use cases where the CMPXCHG is not buried in
+a loop, e.g. KVM will resume the guest instead of looping when emulation
+of a guest atomic accesses fails the CMPXCHG.
+
+Provide 8-byte versions for 32-bit kernels so that KVM can do CMPXCHG on
+guest PAE PTEs, which are accessed via userspace addresses.
+
+Guard the asm_volatile_goto() variation with CC_HAS_ASM_GOTO_TIED_OUTPUT,
+the "+m" constraint fails on some compilers that otherwise support
+CC_HAS_ASM_GOTO_OUTPUT.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Co-developed-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20220202004945.2540433-3-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/uaccess.h | 142 +++++++++++++++++++++++++++++++++
+ 1 file changed, 142 insertions(+)
+
+diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
+index bf2561a5eb581..68b910f30b222 100644
+--- a/arch/x86/include/asm/uaccess.h
++++ b/arch/x86/include/asm/uaccess.h
+@@ -414,6 +414,103 @@ do { \
+
+ #endif // CONFIG_CC_ASM_GOTO_OUTPUT
+
++#ifdef CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT
++#define __try_cmpxchg_user_asm(itype, ltype, _ptr, _pold, _new, label) ({ \
++ bool success; \
++ __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \
++ __typeof__(*(_ptr)) __old = *_old; \
++ __typeof__(*(_ptr)) __new = (_new); \
++ asm_volatile_goto("\n" \
++ "1: " LOCK_PREFIX "cmpxchg"itype" %[new], %[ptr]\n"\
++ _ASM_EXTABLE_UA(1b, %l[label]) \
++ : CC_OUT(z) (success), \
++ [ptr] "+m" (*_ptr), \
++ [old] "+a" (__old) \
++ : [new] ltype (__new) \
++ : "memory" \
++ : label); \
++ if (unlikely(!success)) \
++ *_old = __old; \
++ likely(success); })
++
++#ifdef CONFIG_X86_32
++#define __try_cmpxchg64_user_asm(_ptr, _pold, _new, label) ({ \
++ bool success; \
++ __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \
++ __typeof__(*(_ptr)) __old = *_old; \
++ __typeof__(*(_ptr)) __new = (_new); \
++ asm_volatile_goto("\n" \
++ "1: " LOCK_PREFIX "cmpxchg8b %[ptr]\n" \
++ _ASM_EXTABLE_UA(1b, %l[label]) \
++ : CC_OUT(z) (success), \
++ "+A" (__old), \
++ [ptr] "+m" (*_ptr) \
++ : "b" ((u32)__new), \
++ "c" ((u32)((u64)__new >> 32)) \
++ : "memory" \
++ : label); \
++ if (unlikely(!success)) \
++ *_old = __old; \
++ likely(success); })
++#endif // CONFIG_X86_32
++#else // !CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT
++#define __try_cmpxchg_user_asm(itype, ltype, _ptr, _pold, _new, label) ({ \
++ int __err = 0; \
++ bool success; \
++ __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \
++ __typeof__(*(_ptr)) __old = *_old; \
++ __typeof__(*(_ptr)) __new = (_new); \
++ asm volatile("\n" \
++ "1: " LOCK_PREFIX "cmpxchg"itype" %[new], %[ptr]\n"\
++ CC_SET(z) \
++ "2:\n" \
++ _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG, \
++ %[errout]) \
++ : CC_OUT(z) (success), \
++ [errout] "+r" (__err), \
++ [ptr] "+m" (*_ptr), \
++ [old] "+a" (__old) \
++ : [new] ltype (__new) \
++ : "memory", "cc"); \
++ if (unlikely(__err)) \
++ goto label; \
++ if (unlikely(!success)) \
++ *_old = __old; \
++ likely(success); })
++
++#ifdef CONFIG_X86_32
++/*
++ * Unlike the normal CMPXCHG, hardcode ECX for both success/fail and error.
++ * There are only six GPRs available and four (EAX, EBX, ECX, and EDX) are
++ * hardcoded by CMPXCHG8B, leaving only ESI and EDI. If the compiler uses
++ * both ESI and EDI for the memory operand, compilation will fail if the error
++ * is an input+output as there will be no register available for input.
++ */
++#define __try_cmpxchg64_user_asm(_ptr, _pold, _new, label) ({ \
++ int __result; \
++ __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \
++ __typeof__(*(_ptr)) __old = *_old; \
++ __typeof__(*(_ptr)) __new = (_new); \
++ asm volatile("\n" \
++ "1: " LOCK_PREFIX "cmpxchg8b %[ptr]\n" \
++ "mov $0, %%ecx\n\t" \
++ "setz %%cl\n" \
++ "2:\n" \
++ _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG, %%ecx) \
++ : [result]"=c" (__result), \
++ "+A" (__old), \
++ [ptr] "+m" (*_ptr) \
++ : "b" ((u32)__new), \
++ "c" ((u32)((u64)__new >> 32)) \
++ : "memory", "cc"); \
++ if (unlikely(__result < 0)) \
++ goto label; \
++ if (unlikely(!__result)) \
++ *_old = __old; \
++ likely(__result); })
++#endif // CONFIG_X86_32
++#endif // CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT
++
+ /* FIXME: this hack is definitely wrong -AK */
+ struct __large_struct { unsigned long buf[100]; };
+ #define __m(x) (*(struct __large_struct __user *)(x))
+@@ -506,6 +603,51 @@ do { \
+ } while (0)
+ #endif // CONFIG_CC_HAS_ASM_GOTO_OUTPUT
+
++extern void __try_cmpxchg_user_wrong_size(void);
++
++#ifndef CONFIG_X86_32
++#define __try_cmpxchg64_user_asm(_ptr, _oldp, _nval, _label) \
++ __try_cmpxchg_user_asm("q", "r", (_ptr), (_oldp), (_nval), _label)
++#endif
++
++/*
++ * Force the pointer to u<size> to match the size expected by the asm helper.
++ * clang/LLVM compiles all cases and only discards the unused paths after
++ * processing errors, which breaks i386 if the pointer is an 8-byte value.
++ */
++#define unsafe_try_cmpxchg_user(_ptr, _oldp, _nval, _label) ({ \
++ bool __ret; \
++ __chk_user_ptr(_ptr); \
++ switch (sizeof(*(_ptr))) { \
++ case 1: __ret = __try_cmpxchg_user_asm("b", "q", \
++ (__force u8 *)(_ptr), (_oldp), \
++ (_nval), _label); \
++ break; \
++ case 2: __ret = __try_cmpxchg_user_asm("w", "r", \
++ (__force u16 *)(_ptr), (_oldp), \
++ (_nval), _label); \
++ break; \
++ case 4: __ret = __try_cmpxchg_user_asm("l", "r", \
++ (__force u32 *)(_ptr), (_oldp), \
++ (_nval), _label); \
++ break; \
++ case 8: __ret = __try_cmpxchg64_user_asm((__force u64 *)(_ptr), (_oldp),\
++ (_nval), _label); \
++ break; \
++ default: __try_cmpxchg_user_wrong_size(); \
++ } \
++ __ret; })
++
++/* "Returns" 0 on success, 1 on failure, -EFAULT if the access faults. */
++#define __try_cmpxchg_user(_ptr, _oldp, _nval, _label) ({ \
++ int __ret = -EFAULT; \
++ __uaccess_begin_nospec(); \
++ __ret = !unsafe_try_cmpxchg_user(_ptr, _oldp, _nval, _label); \
++_label: \
++ __uaccess_end(); \
++ __ret; \
++ })
++
+ /*
+ * We want the unsafe accessors to always be inlined and use
+ * the error labels - thus the macro games.
+--
+2.43.0
+