From: Sasha Levin Date: Mon, 12 Apr 2021 03:51:16 +0000 (-0400) Subject: Fixes for 5.4 X-Git-Tag: v4.19.187~42 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=571a475790b15bbb9ba3eab59baac9b6b293beaa;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.4 Signed-off-by: Sasha Levin --- diff --git a/queue-5.4/amd-xgbe-update-dma-coherency-values.patch b/queue-5.4/amd-xgbe-update-dma-coherency-values.patch new file mode 100644 index 00000000000..2ae736cd320 --- /dev/null +++ b/queue-5.4/amd-xgbe-update-dma-coherency-values.patch @@ -0,0 +1,42 @@ +From 36701e3318f56780acdf84c403c130b0f5778277 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Mar 2021 08:39:12 +0530 +Subject: amd-xgbe: Update DMA coherency values + +From: Shyam Sundar S K + +[ Upstream commit d75135082698140a26a56defe1bbc1b06f26a41f ] + +Based on the IOMMU configuration, the current cache control settings can +result in possible coherency issues. The hardware team has recommended +new settings for the PCI device path to eliminate the issue. + +Fixes: 6f595959c095 ("amd-xgbe: Adjust register settings to improve performance") +Signed-off-by: Shyam Sundar S K +Acked-by: Tom Lendacky +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/amd/xgbe/xgbe.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h +index 47bcbcf58048..0c93a552b921 100644 +--- a/drivers/net/ethernet/amd/xgbe/xgbe.h ++++ b/drivers/net/ethernet/amd/xgbe/xgbe.h +@@ -181,9 +181,9 @@ + #define XGBE_DMA_SYS_AWCR 0x30303030 + + /* DMA cache settings - PCI device */ +-#define XGBE_DMA_PCI_ARCR 0x00000003 +-#define XGBE_DMA_PCI_AWCR 0x13131313 +-#define XGBE_DMA_PCI_AWARCR 0x00000313 ++#define XGBE_DMA_PCI_ARCR 0x000f0f0f ++#define XGBE_DMA_PCI_AWCR 0x0f0f0f0f ++#define XGBE_DMA_PCI_AWARCR 0x00000f0f + + /* DMA channel interrupt modes */ + #define XGBE_IRQ_MODE_EDGE 0 +-- +2.30.2 + diff --git a/queue-5.4/arm-dts-imx6-pbab01-set-vmmc-supply-for-both-sd-inte.patch b/queue-5.4/arm-dts-imx6-pbab01-set-vmmc-supply-for-both-sd-inte.patch new file mode 100644 index 00000000000..08000857a76 --- /dev/null +++ b/queue-5.4/arm-dts-imx6-pbab01-set-vmmc-supply-for-both-sd-inte.patch @@ -0,0 +1,45 @@ +From 88c43c52245221c582c3df5a1fe3fe93faa91d38 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Mar 2021 15:01:03 +0200 +Subject: ARM: dts: imx6: pbab01: Set vmmc supply for both SD interfaces + +From: Stefan Riedmueller + +[ Upstream commit f57011e72f5fe0421ec7a812beb1b57bdf4bb47f ] + +Setting the vmmc supplies is crucial since otherwise the supplying +regulators get disabled and the SD interfaces are no longer powered +which leads to system failures if the system is booted from that SD +interface. + +Fixes: 1e44d3f880d5 ("ARM i.MX6Q: dts: Enable I2C1 with EEPROM and PMIC on Phytec phyFLEX-i.MX6 Ouad module") +Signed-off-by: Stefan Riedmueller +Reviewed-by: Fabio Estevam +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi +index bc43c75f1745..6678b97b1007 100644 +--- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi +@@ -432,6 +432,7 @@ + pinctrl-0 = <&pinctrl_usdhc2>; + cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; ++ vmmc-supply = <&vdd_sd1_reg>; + status = "disabled"; + }; + +@@ -441,5 +442,6 @@ + &pinctrl_usdhc3_cdwp>; + cd-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio1 29 GPIO_ACTIVE_HIGH>; ++ vmmc-supply = <&vdd_sd0_reg>; + status = "disabled"; + }; +-- +2.30.2 + diff --git a/queue-5.4/arm64-dts-imx8mm-q-fix-pad-control-of-sd1_data0.patch b/queue-5.4/arm64-dts-imx8mm-q-fix-pad-control-of-sd1_data0.patch new file mode 100644 index 00000000000..0f3e26b5f6f --- /dev/null +++ b/queue-5.4/arm64-dts-imx8mm-q-fix-pad-control-of-sd1_data0.patch @@ -0,0 +1,58 @@ +From 7b4ad12f3f2bde95a2c966120c5e36454a2c0826 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Mar 2021 14:28:41 +0100 +Subject: arm64: dts: imx8mm/q: Fix pad control of SD1_DATA0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Oliver Stäbler + +[ Upstream commit 5cfad4f45806f6f898b63b8c77cea7452c704cb3 ] + +Fix address of the pad control register +(IOMUXC_SW_PAD_CTL_PAD_SD1_DATA0) for SD1_DATA0_GPIO2_IO2. This seems +to be a typo but it leads to an exception when pinctrl is applied due to +wrong memory address access. + +Signed-off-by: Oliver Stäbler +Reviewed-by: Fabio Estevam +Acked-by: Rob Herring +Fixes: c1c9d41319c3 ("dt-bindings: imx: Add pinctrl binding doc for imx8mm") +Fixes: 748f908cc882 ("arm64: add basic DTS for i.MX8MQ") +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h | 2 +- + arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h +index cffa8991880d..93b44efdbc52 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h ++++ b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h +@@ -124,7 +124,7 @@ + #define MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x0A4 0x30C 0x000 0x0 0x0 + #define MX8MM_IOMUXC_SD1_CMD_GPIO2_IO1 0x0A4 0x30C 0x000 0x5 0x0 + #define MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x0A8 0x310 0x000 0x0 0x0 +-#define MX8MM_IOMUXC_SD1_DATA0_GPIO2_IO2 0x0A8 0x31 0x000 0x5 0x0 ++#define MX8MM_IOMUXC_SD1_DATA0_GPIO2_IO2 0x0A8 0x310 0x000 0x5 0x0 + #define MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x0AC 0x314 0x000 0x0 0x0 + #define MX8MM_IOMUXC_SD1_DATA1_GPIO2_IO3 0x0AC 0x314 0x000 0x5 0x0 + #define MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x0B0 0x318 0x000 0x0 0x0 +diff --git a/arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h b/arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h +index b94b02080a34..68e8fa172974 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h ++++ b/arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h +@@ -130,7 +130,7 @@ + #define MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0x0A4 0x30C 0x000 0x0 0x0 + #define MX8MQ_IOMUXC_SD1_CMD_GPIO2_IO1 0x0A4 0x30C 0x000 0x5 0x0 + #define MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x0A8 0x310 0x000 0x0 0x0 +-#define MX8MQ_IOMUXC_SD1_DATA0_GPIO2_IO2 0x0A8 0x31 0x000 0x5 0x0 ++#define MX8MQ_IOMUXC_SD1_DATA0_GPIO2_IO2 0x0A8 0x310 0x000 0x5 0x0 + #define MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x0AC 0x314 0x000 0x0 0x0 + #define MX8MQ_IOMUXC_SD1_DATA1_GPIO2_IO3 0x0AC 0x314 0x000 0x5 0x0 + #define MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x0B0 0x318 0x000 0x0 0x0 +-- +2.30.2 + diff --git a/queue-5.4/asoc-sof-intel-hda-fix-core-status-verification.patch b/queue-5.4/asoc-sof-intel-hda-fix-core-status-verification.patch new file mode 100644 index 00000000000..fe461b47b35 --- /dev/null +++ b/queue-5.4/asoc-sof-intel-hda-fix-core-status-verification.patch @@ -0,0 +1,54 @@ +From 67422a436ff3f457dfd617e484dc7af8696446ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Mar 2021 11:37:21 -0500 +Subject: ASoC: SOF: Intel: HDA: fix core status verification + +From: Guennadi Liakhovetski + +[ Upstream commit 927280909fa7d8e61596800d82f18047c6cfbbe4 ] + +When checking for enabled cores it isn't enough to check that +some of the requested cores are running, we have to check that +all of them are. + +Fixes: 747503b1813a ("ASoC: SOF: Intel: Add Intel specific HDA DSP HW operations") +Reviewed-by: Kai Vehmanen +Reviewed-by: Ranjani Sridharan +Signed-off-by: Guennadi Liakhovetski +Signed-off-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20210322163728.16616-2-pierre-louis.bossart@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/sof/intel/hda-dsp.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c +index d4c7160717c7..06715b3d8c31 100644 +--- a/sound/soc/sof/intel/hda-dsp.c ++++ b/sound/soc/sof/intel/hda-dsp.c +@@ -192,10 +192,17 @@ bool hda_dsp_core_is_enabled(struct snd_sof_dev *sdev, + + val = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPCS); + +- is_enable = (val & HDA_DSP_ADSPCS_CPA_MASK(core_mask)) && +- (val & HDA_DSP_ADSPCS_SPA_MASK(core_mask)) && +- !(val & HDA_DSP_ADSPCS_CRST_MASK(core_mask)) && +- !(val & HDA_DSP_ADSPCS_CSTALL_MASK(core_mask)); ++#define MASK_IS_EQUAL(v, m, field) ({ \ ++ u32 _m = field(m); \ ++ ((v) & _m) == _m; \ ++}) ++ ++ is_enable = MASK_IS_EQUAL(val, core_mask, HDA_DSP_ADSPCS_CPA_MASK) && ++ MASK_IS_EQUAL(val, core_mask, HDA_DSP_ADSPCS_SPA_MASK) && ++ !(val & HDA_DSP_ADSPCS_CRST_MASK(core_mask)) && ++ !(val & HDA_DSP_ADSPCS_CSTALL_MASK(core_mask)); ++ ++#undef MASK_IS_EQUAL + + dev_dbg(sdev->dev, "DSP core(s) enabled? %d : core_mask %x\n", + is_enable, core_mask); +-- +2.30.2 + diff --git a/queue-5.4/asoc-sof-intel-hda-remove-unnecessary-parentheses.patch b/queue-5.4/asoc-sof-intel-hda-remove-unnecessary-parentheses.patch new file mode 100644 index 00000000000..19a94fab97c --- /dev/null +++ b/queue-5.4/asoc-sof-intel-hda-remove-unnecessary-parentheses.patch @@ -0,0 +1,46 @@ +From 677bb21fd924d6f71fa1ce61783774cf89b03861 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Apr 2020 13:48:53 -0500 +Subject: ASoC: SOF: Intel: hda: remove unnecessary parentheses + +From: Payal Kshirsagar + +[ Upstream commit 805a23de2657c10c2ca96588a309a42df947bb36 ] + +Remove unnecessary parentheses around the right hand side of an assignment +and align the code. + +Signed-off-by: Payal Kshirsagar +Signed-off-by: Pierre-Louis Bossart +Reviewed-by: Ranjani Sridharan +Reviewed-by: Guennadi Liakhovetski +Reviewed-by: Kai Vehmanen +Link: https://lore.kernel.org/r/20200409184853.15896-3-pierre-louis.bossart@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/sof/intel/hda-dsp.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c +index 94b093b370e2..d4c7160717c7 100644 +--- a/sound/soc/sof/intel/hda-dsp.c ++++ b/sound/soc/sof/intel/hda-dsp.c +@@ -192,10 +192,10 @@ bool hda_dsp_core_is_enabled(struct snd_sof_dev *sdev, + + val = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPCS); + +- is_enable = ((val & HDA_DSP_ADSPCS_CPA_MASK(core_mask)) && +- (val & HDA_DSP_ADSPCS_SPA_MASK(core_mask)) && +- !(val & HDA_DSP_ADSPCS_CRST_MASK(core_mask)) && +- !(val & HDA_DSP_ADSPCS_CSTALL_MASK(core_mask))); ++ is_enable = (val & HDA_DSP_ADSPCS_CPA_MASK(core_mask)) && ++ (val & HDA_DSP_ADSPCS_SPA_MASK(core_mask)) && ++ !(val & HDA_DSP_ADSPCS_CRST_MASK(core_mask)) && ++ !(val & HDA_DSP_ADSPCS_CSTALL_MASK(core_mask)); + + dev_dbg(sdev->dev, "DSP core(s) enabled? %d : core_mask %x\n", + is_enable, core_mask); +-- +2.30.2 + diff --git a/queue-5.4/asoc-sunxi-sun4i-codec-fill-asoc-card-owner.patch b/queue-5.4/asoc-sunxi-sun4i-codec-fill-asoc-card-owner.patch new file mode 100644 index 00000000000..9aae7def914 --- /dev/null +++ b/queue-5.4/asoc-sunxi-sun4i-codec-fill-asoc-card-owner.patch @@ -0,0 +1,83 @@ +From 9336af0fff707a7161a8f160c162590297e1a97b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Mar 2021 17:18:43 +0200 +Subject: ASoC: sunxi: sun4i-codec: fill ASoC card owner + +From: Bastian Germann + +[ Upstream commit 7c0d6e482062eb5c06ecccfab340abc523bdca00 ] + +card->owner is a required property and since commit 81033c6b584b ("ALSA: +core: Warn on empty module") a warning is issued if it is empty. Add it. +This fixes following warning observed on Lamobo R1: + +WARNING: CPU: 1 PID: 190 at sound/core/init.c:207 snd_card_new+0x430/0x480 [snd] +Modules linked in: sun4i_codec(E+) sun4i_backend(E+) snd_soc_core(E) ... +CPU: 1 PID: 190 Comm: systemd-udevd Tainted: G C E 5.10.0-1-armmp #1 Debian 5.10.4-1 +Hardware name: Allwinner sun7i (A20) Family +Call trace: + (snd_card_new [snd]) + (snd_soc_bind_card [snd_soc_core]) + (snd_soc_register_card [snd_soc_core]) + (sun4i_codec_probe [sun4i_codec]) + +Fixes: 45fb6b6f2aa3 ("ASoC: sunxi: add support for the on-chip codec on early Allwinner SoCs") +Related: commit 3c27ea23ffb4 ("ASoC: qcom: Set card->owner to avoid warnings") +Related: commit ec653df2a0cb ("drm/vc4/vc4_hdmi: fill ASoC card owner") +Cc: linux-arm-kernel@lists.infradead.org +Cc: alsa-devel@alsa-project.org +Signed-off-by: Bastian Germann +Link: https://lore.kernel.org/r/20210331151843.30583-1-bage@linutronix.de +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/sunxi/sun4i-codec.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c +index ee448d5e07a6..c4021d6ac9df 100644 +--- a/sound/soc/sunxi/sun4i-codec.c ++++ b/sound/soc/sunxi/sun4i-codec.c +@@ -1364,6 +1364,7 @@ static struct snd_soc_card *sun4i_codec_create_card(struct device *dev) + return ERR_PTR(-ENOMEM); + + card->dev = dev; ++ card->owner = THIS_MODULE; + card->name = "sun4i-codec"; + card->dapm_widgets = sun4i_codec_card_dapm_widgets; + card->num_dapm_widgets = ARRAY_SIZE(sun4i_codec_card_dapm_widgets); +@@ -1396,6 +1397,7 @@ static struct snd_soc_card *sun6i_codec_create_card(struct device *dev) + return ERR_PTR(-ENOMEM); + + card->dev = dev; ++ card->owner = THIS_MODULE; + card->name = "A31 Audio Codec"; + card->dapm_widgets = sun6i_codec_card_dapm_widgets; + card->num_dapm_widgets = ARRAY_SIZE(sun6i_codec_card_dapm_widgets); +@@ -1449,6 +1451,7 @@ static struct snd_soc_card *sun8i_a23_codec_create_card(struct device *dev) + return ERR_PTR(-ENOMEM); + + card->dev = dev; ++ card->owner = THIS_MODULE; + card->name = "A23 Audio Codec"; + card->dapm_widgets = sun6i_codec_card_dapm_widgets; + card->num_dapm_widgets = ARRAY_SIZE(sun6i_codec_card_dapm_widgets); +@@ -1487,6 +1490,7 @@ static struct snd_soc_card *sun8i_h3_codec_create_card(struct device *dev) + return ERR_PTR(-ENOMEM); + + card->dev = dev; ++ card->owner = THIS_MODULE; + card->name = "H3 Audio Codec"; + card->dapm_widgets = sun6i_codec_card_dapm_widgets; + card->num_dapm_widgets = ARRAY_SIZE(sun6i_codec_card_dapm_widgets); +@@ -1525,6 +1529,7 @@ static struct snd_soc_card *sun8i_v3s_codec_create_card(struct device *dev) + return ERR_PTR(-ENOMEM); + + card->dev = dev; ++ card->owner = THIS_MODULE; + card->name = "V3s Audio Codec"; + card->dapm_widgets = sun6i_codec_card_dapm_widgets; + card->num_dapm_widgets = ARRAY_SIZE(sun6i_codec_card_dapm_widgets); +-- +2.30.2 + diff --git a/queue-5.4/asoc-wm8960-fix-wrong-bclk-and-lrclk-with-pll-enable.patch b/queue-5.4/asoc-wm8960-fix-wrong-bclk-and-lrclk-with-pll-enable.patch new file mode 100644 index 00000000000..2a21e22441c --- /dev/null +++ b/queue-5.4/asoc-wm8960-fix-wrong-bclk-and-lrclk-with-pll-enable.patch @@ -0,0 +1,54 @@ +From 0277bfa6c2c151bed9a2e95c4466f613599307e6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Mar 2021 18:48:46 +0800 +Subject: ASoC: wm8960: Fix wrong bclk and lrclk with pll enabled for some + chips + +From: Shengjiu Wang + +[ Upstream commit 16b82e75c15a7dbd564ea3654f3feb61df9e1e6f ] + +The input MCLK is 12.288MHz, the desired output sysclk is 11.2896MHz +and sample rate is 44100Hz, with the configuration pllprescale=2, +postscale=sysclkdiv=1, some chip may have wrong bclk +and lrclk output with pll enabled in master mode, but with the +configuration pllprescale=1, postscale=2, the output clock is correct. + +>From Datasheet, the PLL performs best when f2 is between +90MHz and 100MHz when the desired sysclk output is 11.2896MHz +or 12.288MHz, so sysclkdiv = 2 (f2/8) is the best choice. + +So search available sysclk_divs from 2 to 1 other than from 1 to 2. + +Fixes: 84fdc00d519f ("ASoC: codec: wm9860: Refactor PLL out freq search") +Signed-off-by: Shengjiu Wang +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/1616150926-22892-1-git-send-email-shengjiu.wang@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/wm8960.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c +index 6cf0f6612bda..708fc4ed54ed 100644 +--- a/sound/soc/codecs/wm8960.c ++++ b/sound/soc/codecs/wm8960.c +@@ -707,7 +707,13 @@ int wm8960_configure_pll(struct snd_soc_component *component, int freq_in, + best_freq_out = -EINVAL; + *sysclk_idx = *dac_idx = *bclk_idx = -1; + +- for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) { ++ /* ++ * From Datasheet, the PLL performs best when f2 is between ++ * 90MHz and 100MHz, the desired sysclk output is 11.2896MHz ++ * or 12.288MHz, then sysclkdiv = 2 is the best choice. ++ * So search sysclk_divs from 2 to 1 other than from 1 to 2. ++ */ ++ for (i = ARRAY_SIZE(sysclk_divs) - 1; i >= 0; --i) { + if (sysclk_divs[i] == -1) + continue; + for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) { +-- +2.30.2 + diff --git a/queue-5.4/can-bcm-raw-fix-msg_namelen-values-depending-on-can_.patch b/queue-5.4/can-bcm-raw-fix-msg_namelen-values-depending-on-can_.patch new file mode 100644 index 00000000000..e2ba1b023d7 --- /dev/null +++ b/queue-5.4/can-bcm-raw-fix-msg_namelen-values-depending-on-can_.patch @@ -0,0 +1,134 @@ +From aa4e05ca4af224d9ae757d8d47526899db0dcf85 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Mar 2021 13:58:48 +0100 +Subject: can: bcm/raw: fix msg_namelen values depending on CAN_REQUIRED_SIZE + +From: Oliver Hartkopp + +[ Upstream commit 9e9714742fb70467464359693a73b911a630226f ] + +Since commit f5223e9eee65 ("can: extend sockaddr_can to include j1939 +members") the sockaddr_can has been extended in size and a new +CAN_REQUIRED_SIZE macro has been introduced to calculate the protocol +specific needed size. + +The ABI for the msg_name and msg_namelen has not been adapted to the +new CAN_REQUIRED_SIZE macro for the other CAN protocols which leads to +a problem when an existing binary reads the (increased) struct +sockaddr_can in msg_name. + +Fixes: f5223e9eee65 ("can: extend sockaddr_can to include j1939 members") +Reported-by: Richard Weinberger +Tested-by: Richard Weinberger +Acked-by: Kurt Van Dijck +Link: https://lore.kernel.org/linux-can/1135648123.112255.1616613706554.JavaMail.zimbra@nod.at/T/#t +Link: https://lore.kernel.org/r/20210325125850.1620-1-socketcan@hartkopp.net +Signed-off-by: Oliver Hartkopp +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + net/can/bcm.c | 10 ++++++---- + net/can/raw.c | 14 ++++++++------ + 2 files changed, 14 insertions(+), 10 deletions(-) + +diff --git a/net/can/bcm.c b/net/can/bcm.c +index c96fa0f33db3..d3aac6a2479b 100644 +--- a/net/can/bcm.c ++++ b/net/can/bcm.c +@@ -88,6 +88,8 @@ MODULE_LICENSE("Dual BSD/GPL"); + MODULE_AUTHOR("Oliver Hartkopp "); + MODULE_ALIAS("can-proto-2"); + ++#define BCM_MIN_NAMELEN CAN_REQUIRED_SIZE(struct sockaddr_can, can_ifindex) ++ + /* + * easy access to the first 64 bit of can(fd)_frame payload. cp->data is + * 64 bit aligned so the offset has to be multiples of 8 which is ensured +@@ -1294,7 +1296,7 @@ static int bcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) + /* no bound device as default => check msg_name */ + DECLARE_SOCKADDR(struct sockaddr_can *, addr, msg->msg_name); + +- if (msg->msg_namelen < CAN_REQUIRED_SIZE(*addr, can_ifindex)) ++ if (msg->msg_namelen < BCM_MIN_NAMELEN) + return -EINVAL; + + if (addr->can_family != AF_CAN) +@@ -1536,7 +1538,7 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len, + struct net *net = sock_net(sk); + int ret = 0; + +- if (len < CAN_REQUIRED_SIZE(*addr, can_ifindex)) ++ if (len < BCM_MIN_NAMELEN) + return -EINVAL; + + lock_sock(sk); +@@ -1618,8 +1620,8 @@ static int bcm_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, + sock_recv_ts_and_drops(msg, sk, skb); + + if (msg->msg_name) { +- __sockaddr_check_size(sizeof(struct sockaddr_can)); +- msg->msg_namelen = sizeof(struct sockaddr_can); ++ __sockaddr_check_size(BCM_MIN_NAMELEN); ++ msg->msg_namelen = BCM_MIN_NAMELEN; + memcpy(msg->msg_name, skb->cb, msg->msg_namelen); + } + +diff --git a/net/can/raw.c b/net/can/raw.c +index 59c039d73c6d..af513d0957c7 100644 +--- a/net/can/raw.c ++++ b/net/can/raw.c +@@ -62,6 +62,8 @@ MODULE_LICENSE("Dual BSD/GPL"); + MODULE_AUTHOR("Urs Thuermann "); + MODULE_ALIAS("can-proto-1"); + ++#define RAW_MIN_NAMELEN CAN_REQUIRED_SIZE(struct sockaddr_can, can_ifindex) ++ + #define MASK_ALL 0 + + /* A raw socket has a list of can_filters attached to it, each receiving +@@ -396,7 +398,7 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len) + int err = 0; + int notify_enetdown = 0; + +- if (len < CAN_REQUIRED_SIZE(*addr, can_ifindex)) ++ if (len < RAW_MIN_NAMELEN) + return -EINVAL; + if (addr->can_family != AF_CAN) + return -EINVAL; +@@ -477,11 +479,11 @@ static int raw_getname(struct socket *sock, struct sockaddr *uaddr, + if (peer) + return -EOPNOTSUPP; + +- memset(addr, 0, sizeof(*addr)); ++ memset(addr, 0, RAW_MIN_NAMELEN); + addr->can_family = AF_CAN; + addr->can_ifindex = ro->ifindex; + +- return sizeof(*addr); ++ return RAW_MIN_NAMELEN; + } + + static int raw_setsockopt(struct socket *sock, int level, int optname, +@@ -733,7 +735,7 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) + if (msg->msg_name) { + DECLARE_SOCKADDR(struct sockaddr_can *, addr, msg->msg_name); + +- if (msg->msg_namelen < CAN_REQUIRED_SIZE(*addr, can_ifindex)) ++ if (msg->msg_namelen < RAW_MIN_NAMELEN) + return -EINVAL; + + if (addr->can_family != AF_CAN) +@@ -822,8 +824,8 @@ static int raw_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, + sock_recv_ts_and_drops(msg, sk, skb); + + if (msg->msg_name) { +- __sockaddr_check_size(sizeof(struct sockaddr_can)); +- msg->msg_namelen = sizeof(struct sockaddr_can); ++ __sockaddr_check_size(RAW_MIN_NAMELEN); ++ msg->msg_namelen = RAW_MIN_NAMELEN; + memcpy(msg->msg_name, skb->cb, msg->msg_namelen); + } + +-- +2.30.2 + diff --git a/queue-5.4/clk-fix-invalid-usage-of-list-cursor-in-register.patch b/queue-5.4/clk-fix-invalid-usage-of-list-cursor-in-register.patch new file mode 100644 index 00000000000..9196f99f624 --- /dev/null +++ b/queue-5.4/clk-fix-invalid-usage-of-list-cursor-in-register.patch @@ -0,0 +1,88 @@ +From a15a0a75206ec0f725465ea5e1638c225cf2ed97 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Apr 2021 00:51:48 +0200 +Subject: clk: fix invalid usage of list cursor in register + +From: Lukasz Bartosik + +[ Upstream commit 8d3c0c01cb2e36b2bf3c06a82b18b228d0c8f5d0 ] + +Fix invalid usage of a list_for_each_entry cursor in +clk_notifier_register(). When list is empty or if the list +is completely traversed (without breaking from the loop on one +of the entries) then the list cursor does not point to a valid +entry and therefore should not be used. + +The issue was dicovered when running 5.12-rc1 kernel on x86_64 +with KASAN enabled: +BUG: KASAN: global-out-of-bounds in clk_notifier_register+0xab/0x230 +Read of size 8 at addr ffffffffa0d10588 by task swapper/0/1 + +CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.12.0-rc1 #1 +Hardware name: Google Caroline/Caroline, +BIOS Google_Caroline.7820.430.0 07/20/2018 +Call Trace: + dump_stack+0xee/0x15c + print_address_description+0x1e/0x2dc + kasan_report+0x188/0x1ce + ? clk_notifier_register+0xab/0x230 + ? clk_prepare_lock+0x15/0x7b + ? clk_notifier_register+0xab/0x230 + clk_notifier_register+0xab/0x230 + dw8250_probe+0xc01/0x10d4 +... +Memory state around the buggy address: + ffffffffa0d10480: 00 00 00 00 00 03 f9 f9 f9 f9 f9 f9 00 00 00 00 + ffffffffa0d10500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f9 f9 +>ffffffffa0d10580: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00 + ^ + ffffffffa0d10600: 00 00 00 00 00 00 f9 f9 f9 f9 f9 f9 00 00 00 00 + ffffffffa0d10680: 00 00 00 00 00 00 00 00 f9 f9 f9 f9 00 00 00 00 + ================================================================== + +Fixes: b2476490ef11 ("clk: introduce the common clock framework") +Reported-by: Lukasz Majczak +Signed-off-by: Lukasz Bartosik +Link: https://lore.kernel.org/r/20210401225149.18826-1-lb@semihalf.com +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/clk.c | 17 ++++++++--------- + 1 file changed, 8 insertions(+), 9 deletions(-) + +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index 36e9f38a3882..5db91903d02b 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -4151,20 +4151,19 @@ int clk_notifier_register(struct clk *clk, struct notifier_block *nb) + /* search the list of notifiers for this clk */ + list_for_each_entry(cn, &clk_notifier_list, node) + if (cn->clk == clk) +- break; ++ goto found; + + /* if clk wasn't in the notifier list, allocate new clk_notifier */ +- if (cn->clk != clk) { +- cn = kzalloc(sizeof(*cn), GFP_KERNEL); +- if (!cn) +- goto out; ++ cn = kzalloc(sizeof(*cn), GFP_KERNEL); ++ if (!cn) ++ goto out; + +- cn->clk = clk; +- srcu_init_notifier_head(&cn->notifier_head); ++ cn->clk = clk; ++ srcu_init_notifier_head(&cn->notifier_head); + +- list_add(&cn->node, &clk_notifier_list); +- } ++ list_add(&cn->node, &clk_notifier_list); + ++found: + ret = srcu_notifier_chain_register(&cn->notifier_head, nb); + + clk->core->notifier_count++; +-- +2.30.2 + diff --git a/queue-5.4/clk-fix-invalid-usage-of-list-cursor-in-unregister.patch b/queue-5.4/clk-fix-invalid-usage-of-list-cursor-in-unregister.patch new file mode 100644 index 00000000000..7527fbc5ebe --- /dev/null +++ b/queue-5.4/clk-fix-invalid-usage-of-list-cursor-in-unregister.patch @@ -0,0 +1,107 @@ +From bffee8788e80b50335c0f4af34829892cbd35f7f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Apr 2021 00:51:49 +0200 +Subject: clk: fix invalid usage of list cursor in unregister + +From: Lukasz Bartosik + +[ Upstream commit 7045465500e465b09f09d6e5bdc260a9f1aab97b ] + +Fix invalid usage of a list_for_each_entry cursor in +clk_notifier_unregister(). When list is empty or if the list +is completely traversed (without breaking from the loop on one +of the entries) then the list cursor does not point to a valid +entry and therefore should not be used. The patch fixes a logical +bug that hasn't been seen in pratice however it is analogus +to the bug fixed in clk_notifier_register(). + +The issue was dicovered when running 5.12-rc1 kernel on x86_64 +with KASAN enabled: +BUG: KASAN: global-out-of-bounds in clk_notifier_register+0xab/0x230 +Read of size 8 at addr ffffffffa0d10588 by task swapper/0/1 + +CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.12.0-rc1 #1 +Hardware name: Google Caroline/Caroline, +BIOS Google_Caroline.7820.430.0 07/20/2018 +Call Trace: + dump_stack+0xee/0x15c + print_address_description+0x1e/0x2dc + kasan_report+0x188/0x1ce + ? clk_notifier_register+0xab/0x230 + ? clk_prepare_lock+0x15/0x7b + ? clk_notifier_register+0xab/0x230 + clk_notifier_register+0xab/0x230 + dw8250_probe+0xc01/0x10d4 + ... + Memory state around the buggy address: + ffffffffa0d10480: 00 00 00 00 00 03 f9 f9 f9 f9 f9 f9 00 00 00 00 + ffffffffa0d10500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f9 f9 + >ffffffffa0d10580: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00 + ^ + ffffffffa0d10600: 00 00 00 00 00 00 f9 f9 f9 f9 f9 f9 00 00 00 00 + ffffffffa0d10680: 00 00 00 00 00 00 00 00 f9 f9 f9 f9 00 00 00 00 + ================================================================== + +Fixes: b2476490ef11 ("clk: introduce the common clock framework") +Reported-by: Lukasz Majczak +Signed-off-by: Lukasz Bartosik +Link: https://lore.kernel.org/r/20210401225149.18826-2-lb@semihalf.com +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/clk.c | 30 +++++++++++++----------------- + 1 file changed, 13 insertions(+), 17 deletions(-) + +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index 5db91903d02b..6ff87cd86712 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -4188,32 +4188,28 @@ EXPORT_SYMBOL_GPL(clk_notifier_register); + */ + int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb) + { +- struct clk_notifier *cn = NULL; +- int ret = -EINVAL; ++ struct clk_notifier *cn; ++ int ret = -ENOENT; + + if (!clk || !nb) + return -EINVAL; + + clk_prepare_lock(); + +- list_for_each_entry(cn, &clk_notifier_list, node) +- if (cn->clk == clk) +- break; +- +- if (cn->clk == clk) { +- ret = srcu_notifier_chain_unregister(&cn->notifier_head, nb); ++ list_for_each_entry(cn, &clk_notifier_list, node) { ++ if (cn->clk == clk) { ++ ret = srcu_notifier_chain_unregister(&cn->notifier_head, nb); + +- clk->core->notifier_count--; ++ clk->core->notifier_count--; + +- /* XXX the notifier code should handle this better */ +- if (!cn->notifier_head.head) { +- srcu_cleanup_notifier_head(&cn->notifier_head); +- list_del(&cn->node); +- kfree(cn); ++ /* XXX the notifier code should handle this better */ ++ if (!cn->notifier_head.head) { ++ srcu_cleanup_notifier_head(&cn->notifier_head); ++ list_del(&cn->node); ++ kfree(cn); ++ } ++ break; + } +- +- } else { +- ret = -ENOENT; + } + + clk_prepare_unlock(); +-- +2.30.2 + diff --git a/queue-5.4/cxgb4-avoid-collecting-sge_qbase-regs-during-traffic.patch b/queue-5.4/cxgb4-avoid-collecting-sge_qbase-regs-during-traffic.patch new file mode 100644 index 00000000000..8c4b810fe5e --- /dev/null +++ b/queue-5.4/cxgb4-avoid-collecting-sge_qbase-regs-during-traffic.patch @@ -0,0 +1,83 @@ +From 04e06a5bff3b793f901fb811c463676fd68d0a80 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 27 Mar 2021 23:49:08 +0530 +Subject: cxgb4: avoid collecting SGE_QBASE regs during traffic + +From: Rahul Lakkireddy + +[ Upstream commit 1bfb3dea965ff9f6226fd1709338f227363b6061 ] + +Accessing SGE_QBASE_MAP[0-3] and SGE_QBASE_INDEX registers can lead +to SGE missing doorbells under heavy traffic. So, only collect them +when adapter is idle. Also update the regdump range to skip collecting +these registers. + +Fixes: 80a95a80d358 ("cxgb4: collect SGE PF/VF queue map") +Signed-off-by: Rahul Lakkireddy +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../net/ethernet/chelsio/cxgb4/cudbg_lib.c | 23 +++++++++++++++---- + drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 3 ++- + 2 files changed, 21 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c +index e26ae298a080..7801425e2726 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c +@@ -1393,11 +1393,25 @@ int cudbg_collect_sge_indirect(struct cudbg_init *pdbg_init, + struct cudbg_buffer temp_buff = { 0 }; + struct sge_qbase_reg_field *sge_qbase; + struct ireg_buf *ch_sge_dbg; ++ u8 padap_running = 0; + int i, rc; ++ u32 size; + +- rc = cudbg_get_buff(pdbg_init, dbg_buff, +- sizeof(*ch_sge_dbg) * 2 + sizeof(*sge_qbase), +- &temp_buff); ++ /* Accessing SGE_QBASE_MAP[0-3] and SGE_QBASE_INDEX regs can ++ * lead to SGE missing doorbells under heavy traffic. So, only ++ * collect them when adapter is idle. ++ */ ++ for_each_port(padap, i) { ++ padap_running = netif_running(padap->port[i]); ++ if (padap_running) ++ break; ++ } ++ ++ size = sizeof(*ch_sge_dbg) * 2; ++ if (!padap_running) ++ size += sizeof(*sge_qbase); ++ ++ rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff); + if (rc) + return rc; + +@@ -1419,7 +1433,8 @@ int cudbg_collect_sge_indirect(struct cudbg_init *pdbg_init, + ch_sge_dbg++; + } + +- if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5) { ++ if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5 && ++ !padap_running) { + sge_qbase = (struct sge_qbase_reg_field *)ch_sge_dbg; + /* 1 addr reg SGE_QBASE_INDEX and 4 data reg + * SGE_QBASE_MAP[0-3] +diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +index 588b63473c47..42374859b9d3 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +@@ -2093,7 +2093,8 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size) + 0x1190, 0x1194, + 0x11a0, 0x11a4, + 0x11b0, 0x11b4, +- 0x11fc, 0x1274, ++ 0x11fc, 0x123c, ++ 0x1254, 0x1274, + 0x1280, 0x133c, + 0x1800, 0x18fc, + 0x3000, 0x302c, +-- +2.30.2 + diff --git a/queue-5.4/drm-msm-set-drvdata-to-null-when-msm_drm_init-fails.patch b/queue-5.4/drm-msm-set-drvdata-to-null-when-msm_drm_init-fails.patch new file mode 100644 index 00000000000..0053a47b3b7 --- /dev/null +++ b/queue-5.4/drm-msm-set-drvdata-to-null-when-msm_drm_init-fails.patch @@ -0,0 +1,54 @@ +From 583905845ade726283b32938c4d33d5c308174d1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Mar 2021 14:28:22 -0700 +Subject: drm/msm: Set drvdata to NULL when msm_drm_init() fails + +From: Stephen Boyd + +[ Upstream commit 5620b135aea49a8f41c86aaecfcb1598a7774121 ] + +We should set the platform device's driver data to NULL here so that +code doesn't assume the struct drm_device pointer is valid when it could +have been destroyed. The lifetime of this pointer is managed by a kref +but when msm_drm_init() fails we call drm_dev_put() on the pointer which +will free the pointer's memory. This driver uses the component model, so +there's sort of two "probes" in this file, one for the platform device +i.e. msm_pdev_probe() and one for the component i.e. msm_drm_bind(). The +msm_drm_bind() code is using the platform device's driver data to store +struct drm_device so the two functions are intertwined. + +This relationship becomes a problem for msm_pdev_shutdown() when it +tests the NULL-ness of the pointer to see if it should call +drm_atomic_helper_shutdown(). The NULL test is a proxy check for if the +pointer has been freed by kref_put(). If the drm_device has been +destroyed, then we shouldn't call the shutdown helper, and we know that +is the case if msm_drm_init() failed, therefore set the driver data to +NULL so that this pointer liveness is tracked properly. + +Fixes: 9d5cbf5fe46e ("drm/msm: add shutdown support for display platform_driver") +Cc: Dmitry Baryshkov +Cc: Fabio Estevam +Cc: Krishna Manikandan +Signed-off-by: Stephen Boyd +Message-Id: <20210325212822.3663144-1-swboyd@chromium.org> +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/msm_drv.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c +index 896d6f95a960..7443df77cadb 100644 +--- a/drivers/gpu/drm/msm/msm_drv.c ++++ b/drivers/gpu/drm/msm/msm_drv.c +@@ -567,6 +567,7 @@ err_free_priv: + kfree(priv); + err_put_drm_dev: + drm_dev_put(ddev); ++ platform_set_drvdata(pdev, NULL); + return ret; + } + +-- +2.30.2 + diff --git a/queue-5.4/esp-delete-netif_f_sctp_crc-bit-from-features-for-es.patch b/queue-5.4/esp-delete-netif_f_sctp_crc-bit-from-features-for-es.patch new file mode 100644 index 00000000000..6ae01630aef --- /dev/null +++ b/queue-5.4/esp-delete-netif_f_sctp_crc-bit-from-features-for-es.patch @@ -0,0 +1,70 @@ +From 0bc9f27c9aa73e6e23307399890a53b8a00f35ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Mar 2021 15:35:07 +0800 +Subject: esp: delete NETIF_F_SCTP_CRC bit from features for esp offload + +From: Xin Long + +[ Upstream commit 154deab6a3ba47792936edf77f2f13a1cbc4351d ] + +Now in esp4/6_gso_segment(), before calling inner proto .gso_segment, +NETIF_F_CSUM_MASK bits are deleted, as HW won't be able to do the +csum for inner proto due to the packet encrypted already. + +So the UDP/TCP packet has to do the checksum on its own .gso_segment. +But SCTP is using CRC checksum, and for that NETIF_F_SCTP_CRC should +be deleted to make SCTP do the csum in own .gso_segment as well. + +In Xiumei's testing with SCTP over IPsec/veth, the packets are kept +dropping due to the wrong CRC checksum. + +Reported-by: Xiumei Mu +Fixes: 7862b4058b9f ("esp: Add gso handlers for esp4 and esp6") +Signed-off-by: Xin Long +Signed-off-by: Steffen Klassert +Signed-off-by: Sasha Levin +--- + net/ipv4/esp4_offload.c | 6 ++++-- + net/ipv6/esp6_offload.c | 6 ++++-- + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c +index 25c8ba6732df..8c0af30fb067 100644 +--- a/net/ipv4/esp4_offload.c ++++ b/net/ipv4/esp4_offload.c +@@ -177,10 +177,12 @@ static struct sk_buff *esp4_gso_segment(struct sk_buff *skb, + + if ((!(skb->dev->gso_partial_features & NETIF_F_HW_ESP) && + !(features & NETIF_F_HW_ESP)) || x->xso.dev != skb->dev) +- esp_features = features & ~(NETIF_F_SG | NETIF_F_CSUM_MASK); ++ esp_features = features & ~(NETIF_F_SG | NETIF_F_CSUM_MASK | ++ NETIF_F_SCTP_CRC); + else if (!(features & NETIF_F_HW_ESP_TX_CSUM) && + !(skb->dev->gso_partial_features & NETIF_F_HW_ESP_TX_CSUM)) +- esp_features = features & ~NETIF_F_CSUM_MASK; ++ esp_features = features & ~(NETIF_F_CSUM_MASK | ++ NETIF_F_SCTP_CRC); + + xo->flags |= XFRM_GSO_SEGMENT; + +diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c +index 93e086cf058a..1c532638b2ad 100644 +--- a/net/ipv6/esp6_offload.c ++++ b/net/ipv6/esp6_offload.c +@@ -210,9 +210,11 @@ static struct sk_buff *esp6_gso_segment(struct sk_buff *skb, + skb->encap_hdr_csum = 1; + + if (!(features & NETIF_F_HW_ESP) || x->xso.dev != skb->dev) +- esp_features = features & ~(NETIF_F_SG | NETIF_F_CSUM_MASK); ++ esp_features = features & ~(NETIF_F_SG | NETIF_F_CSUM_MASK | ++ NETIF_F_SCTP_CRC); + else if (!(features & NETIF_F_HW_ESP_TX_CSUM)) +- esp_features = features & ~NETIF_F_CSUM_MASK; ++ esp_features = features & ~(NETIF_F_CSUM_MASK | ++ NETIF_F_SCTP_CRC); + + xo->flags |= XFRM_GSO_SEGMENT; + +-- +2.30.2 + diff --git a/queue-5.4/gianfar-handle-error-code-at-mac-address-change.patch b/queue-5.4/gianfar-handle-error-code-at-mac-address-change.patch new file mode 100644 index 00000000000..6f8dac71a6d --- /dev/null +++ b/queue-5.4/gianfar-handle-error-code-at-mac-address-change.patch @@ -0,0 +1,39 @@ +From 7892638649efb814fa3dbd0b1f9a6d02240e272e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Mar 2021 17:08:47 +0300 +Subject: gianfar: Handle error code at MAC address change + +From: Claudiu Manoil + +[ Upstream commit bff5b62585123823842833ab20b1c0a7fa437f8c ] + +Handle return error code of eth_mac_addr(); + +Fixes: 3d23a05c75c7 ("gianfar: Enable changing mac addr when if up") +Signed-off-by: Claudiu Manoil +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/freescale/gianfar.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c +index a8959a092344..382a45d84cc3 100644 +--- a/drivers/net/ethernet/freescale/gianfar.c ++++ b/drivers/net/ethernet/freescale/gianfar.c +@@ -366,7 +366,11 @@ static void gfar_set_mac_for_addr(struct net_device *dev, int num, + + static int gfar_set_mac_addr(struct net_device *dev, void *p) + { +- eth_mac_addr(dev, p); ++ int ret; ++ ++ ret = eth_mac_addr(dev, p); ++ if (ret) ++ return ret; + + gfar_set_mac_for_addr(dev, 0, dev->dev_addr); + +-- +2.30.2 + diff --git a/queue-5.4/hostfs-fix-memory-handling-in-follow_link.patch b/queue-5.4/hostfs-fix-memory-handling-in-follow_link.patch new file mode 100644 index 00000000000..0df8765aada --- /dev/null +++ b/queue-5.4/hostfs-fix-memory-handling-in-follow_link.patch @@ -0,0 +1,55 @@ +From 54979138fe7141e097f89dd20525382a4ac0647b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Mar 2021 14:12:34 -0400 +Subject: hostfs: fix memory handling in follow_link() + +From: Al Viro + +[ Upstream commit 7f6c411c9b50cfab41cc798e003eff27608c7016 ] + +1) argument should not be freed in any case - the caller already has +it as ->s_fs_info (and uses it a lot afterwards) +2) allocate readlink buffer with kmalloc() - the caller has no way +to tell if it's got that (on absolute symlink) or a result of +kasprintf(). Sure, for SLAB and SLUB kfree() works on results of +kmem_cache_alloc(), but that's not documented anywhere, might change +in the future *and* is already not true for SLOB. + +Fixes: 52b209f7b848 ("get rid of hostfs_read_inode()") +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +--- + fs/hostfs/hostfs_kern.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c +index 4f5d857f6ecb..58a972667bf8 100644 +--- a/fs/hostfs/hostfs_kern.c ++++ b/fs/hostfs/hostfs_kern.c +@@ -142,7 +142,7 @@ static char *follow_link(char *link) + char *name, *resolved, *end; + int n; + +- name = __getname(); ++ name = kmalloc(PATH_MAX, GFP_KERNEL); + if (!name) { + n = -ENOMEM; + goto out_free; +@@ -171,12 +171,11 @@ static char *follow_link(char *link) + goto out_free; + } + +- __putname(name); +- kfree(link); ++ kfree(name); + return resolved; + + out_free: +- __putname(name); ++ kfree(name); + return ERR_PTR(n); + } + +-- +2.30.2 + diff --git a/queue-5.4/hostfs-use-kasprintf-instead-of-fixed-buffer-formatt.patch b/queue-5.4/hostfs-use-kasprintf-instead-of-fixed-buffer-formatt.patch new file mode 100644 index 00000000000..43a173d8401 --- /dev/null +++ b/queue-5.4/hostfs-use-kasprintf-instead-of-fixed-buffer-formatt.patch @@ -0,0 +1,74 @@ +From 0dcc55e8282fb5a59955bb4569053b161e76241d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Mar 2020 15:07:35 +0200 +Subject: hostfs: Use kasprintf() instead of fixed buffer formatting + +From: Andy Shevchenko + +[ Upstream commit b58c4e96192ee7c47d5c67853b1557306cfa0e7f ] + +Improve readability and maintainability by replacing a hardcoded string +allocation and formatting by the use of the kasprintf() helper. + +Signed-off-by: Andy Shevchenko +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + fs/hostfs/hostfs_kern.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c +index 5a7eb0c79839..4f5d857f6ecb 100644 +--- a/fs/hostfs/hostfs_kern.c ++++ b/fs/hostfs/hostfs_kern.c +@@ -139,8 +139,8 @@ static char *inode_name(struct inode *ino) + + static char *follow_link(char *link) + { +- int len, n; + char *name, *resolved, *end; ++ int n; + + name = __getname(); + if (!name) { +@@ -164,15 +164,13 @@ static char *follow_link(char *link) + return name; + + *(end + 1) = '\0'; +- len = strlen(link) + strlen(name) + 1; + +- resolved = kmalloc(len, GFP_KERNEL); ++ resolved = kasprintf(GFP_KERNEL, "%s%s", link, name); + if (resolved == NULL) { + n = -ENOMEM; + goto out_free; + } + +- sprintf(resolved, "%s%s", link, name); + __putname(name); + kfree(link); + return resolved; +@@ -918,18 +916,16 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) + sb->s_d_op = &simple_dentry_operations; + sb->s_maxbytes = MAX_LFS_FILESIZE; + +- /* NULL is printed as by sprintf: avoid that. */ ++ /* NULL is printed as '(null)' by printf(): avoid that. */ + if (req_root == NULL) + req_root = ""; + + err = -ENOMEM; + sb->s_fs_info = host_root_path = +- kmalloc(strlen(root_ino) + strlen(req_root) + 2, GFP_KERNEL); ++ kasprintf(GFP_KERNEL, "%s/%s", root_ino, req_root); + if (host_root_path == NULL) + goto out; + +- sprintf(host_root_path, "%s/%s", root_ino, req_root); +- + root_inode = new_inode(sb); + if (!root_inode) + goto out; +-- +2.30.2 + diff --git a/queue-5.4/i40e-added-asym_pause-to-supported-link-modes.patch b/queue-5.4/i40e-added-asym_pause-to-supported-link-modes.patch new file mode 100644 index 00000000000..f5c8ff8ddfd --- /dev/null +++ b/queue-5.4/i40e-added-asym_pause-to-supported-link-modes.patch @@ -0,0 +1,41 @@ +From f1f4c91e5a08621d17df5df6493ba315416aa20b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Jan 2021 15:00:02 +0000 +Subject: i40e: Added Asym_Pause to supported link modes + +From: Mateusz Palczewski + +[ Upstream commit 90449e98c265296329446c7abcd2aae3b20c0bc9 ] + +Add Asym_Pause to supported link modes (it is supported by HW). +Lack of Asym_Pause in supported modes can cause several problems, +i.e. it won't be possible to turn the autonegotiation on +with asymmetric pause settings (i.e. Tx on, Rx off). + +Fixes: 4e91bcd5d47a ("i40e: Finish implementation of ethtool get settings") +Signed-off-by: Dawid Lukwinski +Signed-off-by: Mateusz Palczewski +Reviewed-by: Aleksandr Loktionov +Reviewed-by: Przemyslaw Patynowski +Tested-by: Tony Brelinski +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +index 82c62e467870..20562ffd1ab3 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +@@ -1098,6 +1098,7 @@ static int i40e_get_link_ksettings(struct net_device *netdev, + + /* Set flow control settings */ + ethtool_link_ksettings_add_link_mode(ks, supported, Pause); ++ ethtool_link_ksettings_add_link_mode(ks, supported, Asym_Pause); + + switch (hw->fc.requested_mode) { + case I40E_FC_FULL: +-- +2.30.2 + diff --git a/queue-5.4/i40e-fix-display-statistics-for-veb_tc.patch b/queue-5.4/i40e-fix-display-statistics-for-veb_tc.patch new file mode 100644 index 00000000000..b44524a1da2 --- /dev/null +++ b/queue-5.4/i40e-fix-display-statistics-for-veb_tc.patch @@ -0,0 +1,115 @@ +From b4a5d9b5851674dc5d37b54169410519e30b2d36 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Mar 2021 08:46:27 +0100 +Subject: i40e: Fix display statistics for veb_tc + +From: Eryk Rybak + +[ Upstream commit c3214de929dbf1b7374add8bbed30ce82b197bbb ] + +If veb-stats was enabled, the ethtool stats triggered a warning +due to invalid size: 'unexpected stat size for veb.tc_%u_tx_packets'. +This was due to an incorrect structure definition for the statistics. +Structures and functions have been improved in line with requirements +for the presentation of statistics, in particular for the functions: +'i40e_add_ethtool_stats' and 'i40e_add_stat_strings'. + +Fixes: 1510ae0be2a4 ("i40e: convert VEB TC stats to use an i40e_stats array") +Signed-off-by: Eryk Rybak +Signed-off-by: Grzegorz Szczurek +Reviewed-by: Aleksandr Loktionov +Tested-by: Dave Switzer +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + .../net/ethernet/intel/i40e/i40e_ethtool.c | 52 ++++++++++++++++--- + 1 file changed, 46 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +index 20562ffd1ab3..b519e5af5ed9 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +@@ -232,6 +232,8 @@ static void __i40e_add_stat_strings(u8 **p, const struct i40e_stats stats[], + I40E_STAT(struct i40e_vsi, _name, _stat) + #define I40E_VEB_STAT(_name, _stat) \ + I40E_STAT(struct i40e_veb, _name, _stat) ++#define I40E_VEB_TC_STAT(_name, _stat) \ ++ I40E_STAT(struct i40e_cp_veb_tc_stats, _name, _stat) + #define I40E_PFC_STAT(_name, _stat) \ + I40E_STAT(struct i40e_pfc_stats, _name, _stat) + #define I40E_QUEUE_STAT(_name, _stat) \ +@@ -266,11 +268,18 @@ static const struct i40e_stats i40e_gstrings_veb_stats[] = { + I40E_VEB_STAT("veb.rx_unknown_protocol", stats.rx_unknown_protocol), + }; + ++struct i40e_cp_veb_tc_stats { ++ u64 tc_rx_packets; ++ u64 tc_rx_bytes; ++ u64 tc_tx_packets; ++ u64 tc_tx_bytes; ++}; ++ + static const struct i40e_stats i40e_gstrings_veb_tc_stats[] = { +- I40E_VEB_STAT("veb.tc_%u_tx_packets", tc_stats.tc_tx_packets), +- I40E_VEB_STAT("veb.tc_%u_tx_bytes", tc_stats.tc_tx_bytes), +- I40E_VEB_STAT("veb.tc_%u_rx_packets", tc_stats.tc_rx_packets), +- I40E_VEB_STAT("veb.tc_%u_rx_bytes", tc_stats.tc_rx_bytes), ++ I40E_VEB_TC_STAT("veb.tc_%u_tx_packets", tc_tx_packets), ++ I40E_VEB_TC_STAT("veb.tc_%u_tx_bytes", tc_tx_bytes), ++ I40E_VEB_TC_STAT("veb.tc_%u_rx_packets", tc_rx_packets), ++ I40E_VEB_TC_STAT("veb.tc_%u_rx_bytes", tc_rx_bytes), + }; + + static const struct i40e_stats i40e_gstrings_misc_stats[] = { +@@ -2213,6 +2222,29 @@ static int i40e_get_sset_count(struct net_device *netdev, int sset) + } + } + ++/** ++ * i40e_get_veb_tc_stats - copy VEB TC statistics to formatted structure ++ * @tc: the TC statistics in VEB structure (veb->tc_stats) ++ * @i: the index of traffic class in (veb->tc_stats) structure to copy ++ * ++ * Copy VEB TC statistics from structure of arrays (veb->tc_stats) to ++ * one dimensional structure i40e_cp_veb_tc_stats. ++ * Produce formatted i40e_cp_veb_tc_stats structure of the VEB TC ++ * statistics for the given TC. ++ **/ ++static struct i40e_cp_veb_tc_stats ++i40e_get_veb_tc_stats(struct i40e_veb_tc_stats *tc, unsigned int i) ++{ ++ struct i40e_cp_veb_tc_stats veb_tc = { ++ .tc_rx_packets = tc->tc_rx_packets[i], ++ .tc_rx_bytes = tc->tc_rx_bytes[i], ++ .tc_tx_packets = tc->tc_tx_packets[i], ++ .tc_tx_bytes = tc->tc_tx_bytes[i], ++ }; ++ ++ return veb_tc; ++} ++ + /** + * i40e_get_pfc_stats - copy HW PFC statistics to formatted structure + * @pf: the PF device structure +@@ -2297,8 +2329,16 @@ static void i40e_get_ethtool_stats(struct net_device *netdev, + i40e_gstrings_veb_stats); + + for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) +- i40e_add_ethtool_stats(&data, veb_stats ? veb : NULL, +- i40e_gstrings_veb_tc_stats); ++ if (veb_stats) { ++ struct i40e_cp_veb_tc_stats veb_tc = ++ i40e_get_veb_tc_stats(&veb->tc_stats, i); ++ ++ i40e_add_ethtool_stats(&data, &veb_tc, ++ i40e_gstrings_veb_tc_stats); ++ } else { ++ i40e_add_ethtool_stats(&data, NULL, ++ i40e_gstrings_veb_tc_stats); ++ } + + i40e_add_ethtool_stats(&data, pf, i40e_gstrings_stats); + +-- +2.30.2 + diff --git a/queue-5.4/i40e-fix-kernel-oops-when-i40e-driver-removes-vf-s.patch b/queue-5.4/i40e-fix-kernel-oops-when-i40e-driver-removes-vf-s.patch new file mode 100644 index 00000000000..9f76abf9ddd --- /dev/null +++ b/queue-5.4/i40e-fix-kernel-oops-when-i40e-driver-removes-vf-s.patch @@ -0,0 +1,84 @@ +From fd56fef27c43731fd1d5ba10c89e2c15e1e18206 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Feb 2021 11:15:26 +0000 +Subject: i40e: Fix kernel oops when i40e driver removes VF's + +From: Eryk Rybak + +[ Upstream commit 347b5650cd158d1d953487cc2bec567af5c5bf96 ] + +Fix the reason of kernel oops when i40e driver removed VFs. +Added new __I40E_VFS_RELEASING state to signalize releasing +process by PF, that it makes possible to exit of reset VF procedure. +Without this patch, it is possible to suspend the VFs reset by +releasing VFs resources procedure. Retrying the reset after the +timeout works on the freed VF memory causing a kernel oops. + +Fixes: d43d60e5eb95 ("i40e: ensure reset occurs when disabling VF") +Signed-off-by: Eryk Rybak +Signed-off-by: Grzegorz Szczurek +Reviewed-by: Aleksandr Loktionov +Tested-by: Konrad Jankowski +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/i40e/i40e.h | 1 + + drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 9 +++++++++ + 2 files changed, 10 insertions(+) + +diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h +index 678e4190b8a8..e571c6116c4b 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e.h ++++ b/drivers/net/ethernet/intel/i40e/i40e.h +@@ -152,6 +152,7 @@ enum i40e_state_t { + __I40E_VIRTCHNL_OP_PENDING, + __I40E_RECOVERY_MODE, + __I40E_VF_RESETS_DISABLED, /* disable resets during i40e_remove */ ++ __I40E_VFS_RELEASING, + /* This must be last as it determines the size of the BITMAP */ + __I40E_STATE_SIZE__, + }; +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index 5acd599d6b9a..e56107305486 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -137,6 +137,7 @@ void i40e_vc_notify_vf_reset(struct i40e_vf *vf) + **/ + static inline void i40e_vc_disable_vf(struct i40e_vf *vf) + { ++ struct i40e_pf *pf = vf->pf; + int i; + + i40e_vc_notify_vf_reset(vf); +@@ -147,6 +148,11 @@ static inline void i40e_vc_disable_vf(struct i40e_vf *vf) + * ensure a reset. + */ + for (i = 0; i < 20; i++) { ++ /* If PF is in VFs releasing state reset VF is impossible, ++ * so leave it. ++ */ ++ if (test_bit(__I40E_VFS_RELEASING, pf->state)) ++ return; + if (i40e_reset_vf(vf, false)) + return; + usleep_range(10000, 20000); +@@ -1506,6 +1512,8 @@ void i40e_free_vfs(struct i40e_pf *pf) + + if (!pf->vf) + return; ++ ++ set_bit(__I40E_VFS_RELEASING, pf->state); + while (test_and_set_bit(__I40E_VF_DISABLE, pf->state)) + usleep_range(1000, 2000); + +@@ -1563,6 +1571,7 @@ void i40e_free_vfs(struct i40e_pf *pf) + } + } + clear_bit(__I40E_VF_DISABLE, pf->state); ++ clear_bit(__I40E_VFS_RELEASING, pf->state); + } + + #ifdef CONFIG_PCI_IOV +-- +2.30.2 + diff --git a/queue-5.4/net-hns3-clear-vf-down-state-bit-before-request-link.patch b/queue-5.4/net-hns3-clear-vf-down-state-bit-before-request-link.patch new file mode 100644 index 00000000000..05407b1ddbb --- /dev/null +++ b/queue-5.4/net-hns3-clear-vf-down-state-bit-before-request-link.patch @@ -0,0 +1,51 @@ +From f9c1cc5599f2df344dbeb2f2b776f139a6d53fe2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Apr 2021 21:10:43 +0800 +Subject: net: hns3: clear VF down state bit before request link status + +From: Guangbin Huang + +[ Upstream commit ed7bedd2c3ca040f1e8ea02c6590a93116b1ec78 ] + +Currently, the VF down state bit is cleared after VF sending +link status request command. There is problem that when VF gets +link status replied from PF, the down state bit may still set +as 1. In this case, the link status replied from PF will be +ignored and always set VF link status to down. + +To fix this problem, clear VF down state bit before VF requests +link status. + +Fixes: e2cb1dec9779 ("net: hns3: Add HNS3 VF HCL(Hardware Compatibility Layer) Support") +Signed-off-by: Guangbin Huang +Signed-off-by: Huazhong Tan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +index 9b09dd95e878..fc275d4f484c 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +@@ -2140,14 +2140,14 @@ static int hclgevf_ae_start(struct hnae3_handle *handle) + { + struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); + ++ clear_bit(HCLGEVF_STATE_DOWN, &hdev->state); ++ + hclgevf_reset_tqp_stats(handle); + + hclgevf_request_link_info(hdev); + + hclgevf_update_link_mode(hdev); + +- clear_bit(HCLGEVF_STATE_DOWN, &hdev->state); +- + return 0; + } + +-- +2.30.2 + diff --git a/queue-5.4/net-macb-restore-cmp-registers-on-resume-path.patch b/queue-5.4/net-macb-restore-cmp-registers-on-resume-path.patch new file mode 100644 index 00000000000..00bd5a3a2ea --- /dev/null +++ b/queue-5.4/net-macb-restore-cmp-registers-on-resume-path.patch @@ -0,0 +1,55 @@ +From b71094836f8e5c3bb1cb61fb2a7ec6308b7a1561 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Apr 2021 15:42:53 +0300 +Subject: net: macb: restore cmp registers on resume path + +From: Claudiu Beznea + +[ Upstream commit a14d273ba15968495896a38b7b3399dba66d0270 ] + +Restore CMP screener registers on resume path. + +Fixes: c1e85c6ce57ef ("net: macb: save/restore the remaining registers and features") +Signed-off-by: Claudiu Beznea +Acked-by: Nicolas Ferre +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/cadence/macb_main.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index 3f74416bb874..bdef5b3dd848 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -2915,6 +2915,9 @@ static void gem_prog_cmp_regs(struct macb *bp, struct ethtool_rx_flow_spec *fs) + bool cmp_b = false; + bool cmp_c = false; + ++ if (!macb_is_gem(bp)) ++ return; ++ + tp4sp_v = &(fs->h_u.tcp_ip4_spec); + tp4sp_m = &(fs->m_u.tcp_ip4_spec); + +@@ -3286,6 +3289,7 @@ static void macb_restore_features(struct macb *bp) + { + struct net_device *netdev = bp->dev; + netdev_features_t features = netdev->features; ++ struct ethtool_rx_fs_item *item; + + /* TX checksum offload */ + macb_set_txcsum_feature(bp, features); +@@ -3294,6 +3298,9 @@ static void macb_restore_features(struct macb *bp) + macb_set_rxcsum_feature(bp, features); + + /* RX Flow Filters */ ++ list_for_each_entry(item, &bp->rx_fs_list.list, list) ++ gem_prog_cmp_regs(bp, &item->fs); ++ + macb_set_rxflow_feature(bp, features); + } + +-- +2.30.2 + diff --git a/queue-5.4/net-mlx5-don-t-request-more-than-supported-eqs.patch b/queue-5.4/net-mlx5-don-t-request-more-than-supported-eqs.patch new file mode 100644 index 00000000000..d66a1e7b34e --- /dev/null +++ b/queue-5.4/net-mlx5-don-t-request-more-than-supported-eqs.patch @@ -0,0 +1,57 @@ +From c115f7b785f335edb255007228d82ca889e6cc2c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Dec 2019 16:58:10 -0600 +Subject: net/mlx5: Don't request more than supported EQs + +From: Daniel Jurgens + +[ Upstream commit a7b76002ae78cd230ee652ccdfedf21aa94fcecc ] + +Calculating the number of compeltion EQs based on the number of +available IRQ vectors doesn't work now that all async EQs share one IRQ. +Thus the max number of EQs can be exceeded on systems with more than +approximately 256 CPUs. Take this into account when calculating the +number of available completion EQs. + +Fixes: 81bfa206032a ("net/mlx5: Use a single IRQ for all async EQs") +Signed-off-by: Daniel Jurgens +Reviewed-by: Parav Pandit +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/eq.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c +index 0a20938b4aad..30a2ee3c40a0 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c +@@ -926,13 +926,24 @@ void mlx5_core_eq_free_irqs(struct mlx5_core_dev *dev) + mutex_unlock(&table->lock); + } + ++#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING ++#define MLX5_MAX_ASYNC_EQS 4 ++#else ++#define MLX5_MAX_ASYNC_EQS 3 ++#endif ++ + int mlx5_eq_table_create(struct mlx5_core_dev *dev) + { + struct mlx5_eq_table *eq_table = dev->priv.eq_table; ++ int num_eqs = MLX5_CAP_GEN(dev, max_num_eqs) ? ++ MLX5_CAP_GEN(dev, max_num_eqs) : ++ 1 << MLX5_CAP_GEN(dev, log_max_eq); + int err; + + eq_table->num_comp_eqs = +- mlx5_irq_get_num_comp(eq_table->irq_table); ++ min_t(int, ++ mlx5_irq_get_num_comp(eq_table->irq_table), ++ num_eqs - MLX5_MAX_ASYNC_EQS); + + err = create_async_eqs(dev); + if (err) { +-- +2.30.2 + diff --git a/queue-5.4/net-mlx5-fix-pbmc-register-mapping.patch b/queue-5.4/net-mlx5-fix-pbmc-register-mapping.patch new file mode 100644 index 00000000000..a91953853f3 --- /dev/null +++ b/queue-5.4/net-mlx5-fix-pbmc-register-mapping.patch @@ -0,0 +1,37 @@ +From b13dfe7ae961f9e9d3aebe3ab75c1f8af41ab5cc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 4 Apr 2021 12:55:00 +0300 +Subject: net/mlx5: Fix PBMC register mapping + +From: Aya Levin + +[ Upstream commit 534b1204ca4694db1093b15cf3e79a99fcb6a6da ] + +Add reserved mapping to cover all the register in order to avoid setting +arbitrary values to newer FW which implements the reserved fields. + +Fixes: 50b4a3c23646 ("net/mlx5: PPTB and PBMC register firmware command support") +Signed-off-by: Aya Levin +Reviewed-by: Moshe Shemesh +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + include/linux/mlx5/mlx5_ifc.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h +index 8099517e2e61..36516fe86fe7 100644 +--- a/include/linux/mlx5/mlx5_ifc.h ++++ b/include/linux/mlx5/mlx5_ifc.h +@@ -9669,7 +9669,7 @@ struct mlx5_ifc_pbmc_reg_bits { + + struct mlx5_ifc_bufferx_reg_bits buffer[10]; + +- u8 reserved_at_2e0[0x40]; ++ u8 reserved_at_2e0[0x80]; + }; + + struct mlx5_ifc_qtct_reg_bits { +-- +2.30.2 + diff --git a/queue-5.4/net-mlx5-fix-placement-of-log_max_flow_counter.patch b/queue-5.4/net-mlx5-fix-placement-of-log_max_flow_counter.patch new file mode 100644 index 00000000000..588a26733ea --- /dev/null +++ b/queue-5.4/net-mlx5-fix-placement-of-log_max_flow_counter.patch @@ -0,0 +1,44 @@ +From ff0e3d82ab754c42b985e8a0974f8f008b54ca5d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Jan 2021 16:01:37 +0200 +Subject: net/mlx5: Fix placement of log_max_flow_counter + +From: Raed Salem + +[ Upstream commit a14587dfc5ad2312dabdd42a610d80ecd0dc8bea ] + +The cited commit wrongly placed log_max_flow_counter field of +mlx5_ifc_flow_table_prop_layout_bits, align it to the HW spec intended +placement. + +Fixes: 16f1c5bb3ed7 ("net/mlx5: Check device capability for maximum flow counters") +Signed-off-by: Raed Salem +Reviewed-by: Roi Dayan +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + include/linux/mlx5/mlx5_ifc.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h +index 75e5a7fe341f..8099517e2e61 100644 +--- a/include/linux/mlx5/mlx5_ifc.h ++++ b/include/linux/mlx5/mlx5_ifc.h +@@ -415,11 +415,11 @@ struct mlx5_ifc_flow_table_prop_layout_bits { + u8 reserved_at_60[0x18]; + u8 log_max_ft_num[0x8]; + +- u8 reserved_at_80[0x18]; ++ u8 reserved_at_80[0x10]; ++ u8 log_max_flow_counter[0x8]; + u8 log_max_destination[0x8]; + +- u8 log_max_flow_counter[0x8]; +- u8 reserved_at_a8[0x10]; ++ u8 reserved_at_a0[0x18]; + u8 log_max_flow[0x8]; + + u8 reserved_at_c0[0x40]; +-- +2.30.2 + diff --git a/queue-5.4/net-mlx5e-fix-ethtool-indication-of-connector-type.patch b/queue-5.4/net-mlx5e-fix-ethtool-indication-of-connector-type.patch new file mode 100644 index 00000000000..65fbe0e2943 --- /dev/null +++ b/queue-5.4/net-mlx5e-fix-ethtool-indication-of-connector-type.patch @@ -0,0 +1,73 @@ +From d751cfababa393c4a0035299cd760c08a7a65097 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Mar 2021 12:25:06 +0200 +Subject: net/mlx5e: Fix ethtool indication of connector type + +From: Aya Levin + +[ Upstream commit 3211434dfe7a66fcf55e43961ea524b78336c04c ] + +Use connector_type read from PTYS register when it's valid, based on +corresponding capability bit. + +Fixes: 5b4793f81745 ("net/mlx5e: Add support for reading connector type from PTYS") +Signed-off-by: Aya Levin +Reviewed-by: Eran Ben Elisha +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + .../ethernet/mellanox/mlx5/core/en_ethtool.c | 22 +++++++++---------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +index e09b4a96a1d5..e3dc2cbdc9f6 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +@@ -700,11 +700,11 @@ static int get_fec_supported_advertised(struct mlx5_core_dev *dev, + return 0; + } + +-static void ptys2ethtool_supported_advertised_port(struct ethtool_link_ksettings *link_ksettings, +- u32 eth_proto_cap, +- u8 connector_type, bool ext) ++static void ptys2ethtool_supported_advertised_port(struct mlx5_core_dev *mdev, ++ struct ethtool_link_ksettings *link_ksettings, ++ u32 eth_proto_cap, u8 connector_type) + { +- if ((!connector_type && !ext) || connector_type >= MLX5E_CONNECTOR_TYPE_NUMBER) { ++ if (!MLX5_CAP_PCAM_FEATURE(mdev, ptys_connector_type)) { + if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_10GBASE_CR) + | MLX5E_PROT_MASK(MLX5E_10GBASE_SR) + | MLX5E_PROT_MASK(MLX5E_40GBASE_CR4) +@@ -836,9 +836,9 @@ static int ptys2connector_type[MLX5E_CONNECTOR_TYPE_NUMBER] = { + [MLX5E_PORT_OTHER] = PORT_OTHER, + }; + +-static u8 get_connector_port(u32 eth_proto, u8 connector_type, bool ext) ++static u8 get_connector_port(struct mlx5_core_dev *mdev, u32 eth_proto, u8 connector_type) + { +- if ((connector_type || ext) && connector_type < MLX5E_CONNECTOR_TYPE_NUMBER) ++ if (MLX5_CAP_PCAM_FEATURE(mdev, ptys_connector_type)) + return ptys2connector_type[connector_type]; + + if (eth_proto & +@@ -937,11 +937,11 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv, + link_ksettings); + + eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap; +- +- link_ksettings->base.port = get_connector_port(eth_proto_oper, +- connector_type, ext); +- ptys2ethtool_supported_advertised_port(link_ksettings, eth_proto_admin, +- connector_type, ext); ++ connector_type = connector_type < MLX5E_CONNECTOR_TYPE_NUMBER ? ++ connector_type : MLX5E_PORT_UNKNOWN; ++ link_ksettings->base.port = get_connector_port(mdev, eth_proto_oper, connector_type); ++ ptys2ethtool_supported_advertised_port(mdev, link_ksettings, eth_proto_admin, ++ connector_type); + get_lp_advertising(mdev, eth_proto_lp, link_ksettings); + + if (an_status == MLX5_AN_COMPLETE) +-- +2.30.2 + diff --git a/queue-5.4/net-ncsi-avoid-channel_monitor-hrtimer-deadlock.patch b/queue-5.4/net-ncsi-avoid-channel_monitor-hrtimer-deadlock.patch new file mode 100644 index 00000000000..c086e8a99e7 --- /dev/null +++ b/queue-5.4/net-ncsi-avoid-channel_monitor-hrtimer-deadlock.patch @@ -0,0 +1,76 @@ +From 4309b255300fa44a1a0091c1cd6a82c23891c984 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Mar 2021 10:20:39 -0500 +Subject: net/ncsi: Avoid channel_monitor hrtimer deadlock + +From: Milton Miller + +[ Upstream commit 03cb4d05b4ea9a3491674ca40952adb708d549fa ] + +Calling ncsi_stop_channel_monitor from channel_monitor is a guaranteed +deadlock on SMP because stop calls del_timer_sync on the timer that +invoked channel_monitor as its timer function. + +Recognise the inherent race of marking the monitor disabled before +deleting the timer by just returning if enable was cleared. After +a timeout (the default case -- reset to START when response received) +just mark the monitor.enabled false. + +If the channel has an entry on the channel_queue list, or if the +state is not ACTIVE or INACTIVE, then warn and mark the timer stopped +and don't restart, as the locking is broken somehow. + +Fixes: 0795fb2021f0 ("net/ncsi: Stop monitor if channel times out or is inactive") +Signed-off-by: Milton Miller +Signed-off-by: Eddie James +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ncsi/ncsi-manage.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c +index 4910e6162232..9bd12f7517ed 100644 +--- a/net/ncsi/ncsi-manage.c ++++ b/net/ncsi/ncsi-manage.c +@@ -103,13 +103,20 @@ static void ncsi_channel_monitor(struct timer_list *t) + monitor_state = nc->monitor.state; + spin_unlock_irqrestore(&nc->lock, flags); + +- if (!enabled || chained) { +- ncsi_stop_channel_monitor(nc); +- return; +- } ++ if (!enabled) ++ return; /* expected race disabling timer */ ++ if (WARN_ON_ONCE(chained)) ++ goto bad_state; ++ + if (state != NCSI_CHANNEL_INACTIVE && + state != NCSI_CHANNEL_ACTIVE) { +- ncsi_stop_channel_monitor(nc); ++bad_state: ++ netdev_warn(ndp->ndev.dev, ++ "Bad NCSI monitor state channel %d 0x%x %s queue\n", ++ nc->id, state, chained ? "on" : "off"); ++ spin_lock_irqsave(&nc->lock, flags); ++ nc->monitor.enabled = false; ++ spin_unlock_irqrestore(&nc->lock, flags); + return; + } + +@@ -134,10 +141,9 @@ static void ncsi_channel_monitor(struct timer_list *t) + ncsi_report_link(ndp, true); + ndp->flags |= NCSI_DEV_RESHUFFLE; + +- ncsi_stop_channel_monitor(nc); +- + ncm = &nc->modes[NCSI_MODE_LINK]; + spin_lock_irqsave(&nc->lock, flags); ++ nc->monitor.enabled = false; + nc->state = NCSI_CHANNEL_INVISIBLE; + ncm->data[2] &= ~0x1; + spin_unlock_irqrestore(&nc->lock, flags); +-- +2.30.2 + diff --git a/queue-5.4/net-openvswitch-conntrack-simplify-the-return-expres.patch b/queue-5.4/net-openvswitch-conntrack-simplify-the-return-expres.patch new file mode 100644 index 00000000000..1fef6e315d0 --- /dev/null +++ b/queue-5.4/net-openvswitch-conntrack-simplify-the-return-expres.patch @@ -0,0 +1,44 @@ +From 461095fda2c7db5be2fc4df8d8c2846a9edd25f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Dec 2020 20:13:53 +0800 +Subject: net: openvswitch: conntrack: simplify the return expression of + ovs_ct_limit_get_default_limit() + +From: Zheng Yongjun + +[ Upstream commit 5e359044c107ecbdc2e9b3fd5ce296006e6de4bc ] + +Simplify the return expression. + +Signed-off-by: Zheng Yongjun +Reviewed-by: Eelco Chaudron +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/openvswitch/conntrack.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c +index d06d7d58eaf2..e905248b11c2 100644 +--- a/net/openvswitch/conntrack.c ++++ b/net/openvswitch/conntrack.c +@@ -2020,15 +2020,11 @@ static int ovs_ct_limit_get_default_limit(struct ovs_ct_limit_info *info, + struct sk_buff *reply) + { + struct ovs_zone_limit zone_limit; +- int err; + + zone_limit.zone_id = OVS_ZONE_LIMIT_DEFAULT_ZONE; + zone_limit.limit = info->default_limit; +- err = nla_put_nohdr(reply, sizeof(zone_limit), &zone_limit); +- if (err) +- return err; + +- return 0; ++ return nla_put_nohdr(reply, sizeof(zone_limit), &zone_limit); + } + + static int __ovs_ct_limit_get_zone_limit(struct net *net, +-- +2.30.2 + diff --git a/queue-5.4/net-phy-broadcom-only-advertise-eee-for-supported-mo.patch b/queue-5.4/net-phy-broadcom-only-advertise-eee-for-supported-mo.patch new file mode 100644 index 00000000000..c8b4c8ead65 --- /dev/null +++ b/queue-5.4/net-phy-broadcom-only-advertise-eee-for-supported-mo.patch @@ -0,0 +1,56 @@ +From c29e4aa4f95b9987893b1e52b74292fe9a499ef9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Mar 2021 15:00:24 -0700 +Subject: net: phy: broadcom: Only advertise EEE for supported modes + +From: Florian Fainelli + +[ Upstream commit c056d480b40a68f2520ccc156c7fae672d69d57d ] + +We should not be advertising EEE for modes that we do not support, +correct that oversight by looking at the PHY device supported linkmodes. + +Fixes: 99cec8a4dda2 ("net: phy: broadcom: Allow enabling or disabling of EEE") +Signed-off-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/phy/bcm-phy-lib.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/phy/bcm-phy-lib.c b/drivers/net/phy/bcm-phy-lib.c +index e0d3310957ff..c99883120556 100644 +--- a/drivers/net/phy/bcm-phy-lib.c ++++ b/drivers/net/phy/bcm-phy-lib.c +@@ -190,7 +190,7 @@ EXPORT_SYMBOL_GPL(bcm_phy_enable_apd); + + int bcm_phy_set_eee(struct phy_device *phydev, bool enable) + { +- int val; ++ int val, mask = 0; + + /* Enable EEE at PHY level */ + val = phy_read_mmd(phydev, MDIO_MMD_AN, BRCM_CL45VEN_EEE_CONTROL); +@@ -209,10 +209,17 @@ int bcm_phy_set_eee(struct phy_device *phydev, bool enable) + if (val < 0) + return val; + ++ if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, ++ phydev->supported)) ++ mask |= MDIO_EEE_1000T; ++ if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, ++ phydev->supported)) ++ mask |= MDIO_EEE_100TX; ++ + if (enable) +- val |= (MDIO_EEE_100TX | MDIO_EEE_1000T); ++ val |= mask; + else +- val &= ~(MDIO_EEE_100TX | MDIO_EEE_1000T); ++ val &= ~mask; + + phy_write_mmd(phydev, MDIO_MMD_AN, BCM_CL45VEN_EEE_ADV, (u32)val); + +-- +2.30.2 + diff --git a/queue-5.4/net-rds-fix-a-use-after-free-in-rds_message_map_page.patch b/queue-5.4/net-rds-fix-a-use-after-free-in-rds_message_map_page.patch new file mode 100644 index 00000000000..7d0aad8f2d1 --- /dev/null +++ b/queue-5.4/net-rds-fix-a-use-after-free-in-rds_message_map_page.patch @@ -0,0 +1,45 @@ +From 9d973b3ec0fc5dff8c5a34a4349a2f73f498ed71 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Mar 2021 18:59:59 -0700 +Subject: net/rds: Fix a use after free in rds_message_map_pages +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lv Yunlong + +[ Upstream commit bdc2ab5c61a5c07388f4820ff21e787b4dfd1ced ] + +In rds_message_map_pages, the rm is freed by rds_message_put(rm). +But rm is still used by rm->data.op_sg in return value. + +My patch assigns ERR_CAST(rm->data.op_sg) to err before the rm is +freed to avoid the uaf. + +Fixes: 7dba92037baf3 ("net/rds: Use ERR_PTR for rds_message_alloc_sgs()") +Signed-off-by: Lv Yunlong +Reviewed-by: Håkon Bugge +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/rds/message.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/rds/message.c b/net/rds/message.c +index 2d43e13d6dd5..92b6b22884d4 100644 +--- a/net/rds/message.c ++++ b/net/rds/message.c +@@ -347,8 +347,9 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in + rm->data.op_nents = DIV_ROUND_UP(total_len, PAGE_SIZE); + rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs); + if (IS_ERR(rm->data.op_sg)) { ++ void *err = ERR_CAST(rm->data.op_sg); + rds_message_put(rm); +- return ERR_CAST(rm->data.op_sg); ++ return err; + } + + for (i = 0; i < rm->data.op_nents; ++i) { +-- +2.30.2 + diff --git a/queue-5.4/net-tipc-fix-a-double-free-in-tipc_sk_mcast_rcv.patch b/queue-5.4/net-tipc-fix-a-double-free-in-tipc_sk_mcast_rcv.patch new file mode 100644 index 00000000000..583ec9a61a6 --- /dev/null +++ b/queue-5.4/net-tipc-fix-a-double-free-in-tipc_sk_mcast_rcv.patch @@ -0,0 +1,44 @@ +From e1cd26742609deee1bbcd21fe70ec583105c4f38 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Mar 2021 00:30:29 -0700 +Subject: net:tipc: Fix a double free in tipc_sk_mcast_rcv + +From: Lv Yunlong + +[ Upstream commit 6bf24dc0cc0cc43b29ba344b66d78590e687e046 ] + +In the if(skb_peek(arrvq) == skb) branch, it calls __skb_dequeue(arrvq) to get +the skb by skb = skb_peek(arrvq). Then __skb_dequeue() unlinks the skb from arrvq +and returns the skb which equals to skb_peek(arrvq). After __skb_dequeue(arrvq) +finished, the skb is freed by kfree_skb(__skb_dequeue(arrvq)) in the first time. + +Unfortunately, the same skb is freed in the second time by kfree_skb(skb) after +the branch completed. + +My patch removes kfree_skb() in the if(skb_peek(arrvq) == skb) branch, because +this skb will be freed by kfree_skb(skb) finally. + +Fixes: cb1b728096f54 ("tipc: eliminate race condition at multicast reception") +Signed-off-by: Lv Yunlong +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/tipc/socket.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/tipc/socket.c b/net/tipc/socket.c +index 66e8f89bce53..b2c36dcfc8e2 100644 +--- a/net/tipc/socket.c ++++ b/net/tipc/socket.c +@@ -1210,7 +1210,7 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, + spin_lock_bh(&inputq->lock); + if (skb_peek(arrvq) == skb) { + skb_queue_splice_tail_init(&tmpq, inputq); +- kfree_skb(__skb_dequeue(arrvq)); ++ __skb_dequeue(arrvq); + } + spin_unlock_bh(&inputq->lock); + __skb_queue_purge(&tmpq); +-- +2.30.2 + diff --git a/queue-5.4/net-udp-add-support-for-getsockopt-.-.-udp_gro.patch b/queue-5.4/net-udp-add-support-for-getsockopt-.-.-udp_gro.patch new file mode 100644 index 00000000000..4d3d63d258b --- /dev/null +++ b/queue-5.4/net-udp-add-support-for-getsockopt-.-.-udp_gro.patch @@ -0,0 +1,41 @@ +From 23960dbc172a65e328b0d87118eff899caad9b49 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Apr 2021 08:59:17 +0200 +Subject: net: udp: Add support for getsockopt(..., ..., UDP_GRO, ..., ...); + +From: Norman Maurer + +[ Upstream commit 98184612aca0a9ee42b8eb0262a49900ee9eef0d ] + +Support for UDP_GRO was added in the past but the implementation for +getsockopt was missed which did lead to an error when we tried to +retrieve the setting for UDP_GRO. This patch adds the missing switch +case for UDP_GRO + +Fixes: e20cf8d3f1f7 ("udp: implement GRO for plain UDP sockets.") +Signed-off-by: Norman Maurer +Reviewed-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv4/udp.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 994a150ae3e9..24841a9e9966 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -2692,6 +2692,10 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname, + val = up->gso_size; + break; + ++ case UDP_GRO: ++ val = up->gro_enabled; ++ break; ++ + /* The following two cannot be changed on UDP sockets, the return is + * always 0 (which corresponds to the full checksum coverage of UDP). */ + case UDPLITE_SEND_CSCOV: +-- +2.30.2 + diff --git a/queue-5.4/net-xfrm-localize-sequence-counter-per-network-names.patch b/queue-5.4/net-xfrm-localize-sequence-counter-per-network-names.patch new file mode 100644 index 00000000000..223b0206fc7 --- /dev/null +++ b/queue-5.4/net-xfrm-localize-sequence-counter-per-network-names.patch @@ -0,0 +1,104 @@ +From e05b0df5e5940281b03b2539d83e3b2e72f63edc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Mar 2021 11:56:29 +0100 +Subject: net: xfrm: Localize sequence counter per network namespace + +From: Ahmed S. Darwish + +[ Upstream commit e88add19f68191448427a6e4eb059664650a837f ] + +A sequence counter write section must be serialized or its internal +state can get corrupted. The "xfrm_state_hash_generation" seqcount is +global, but its write serialization lock (net->xfrm.xfrm_state_lock) is +instantiated per network namespace. The write protection is thus +insufficient. + +To provide full protection, localize the sequence counter per network +namespace instead. This should be safe as both the seqcount read and +write sections access data exclusively within the network namespace. It +also lays the foundation for transforming "xfrm_state_hash_generation" +data type from seqcount_t to seqcount_LOCKNAME_t in further commits. + +Fixes: b65e3d7be06f ("xfrm: state: add sequence count to detect hash resizes") +Signed-off-by: Ahmed S. Darwish +Signed-off-by: Steffen Klassert +Signed-off-by: Sasha Levin +--- + include/net/netns/xfrm.h | 4 +++- + net/xfrm/xfrm_state.c | 10 +++++----- + 2 files changed, 8 insertions(+), 6 deletions(-) + +diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h +index 59f45b1e9dac..b59d73d529ba 100644 +--- a/include/net/netns/xfrm.h ++++ b/include/net/netns/xfrm.h +@@ -72,7 +72,9 @@ struct netns_xfrm { + #if IS_ENABLED(CONFIG_IPV6) + struct dst_ops xfrm6_dst_ops; + #endif +- spinlock_t xfrm_state_lock; ++ spinlock_t xfrm_state_lock; ++ seqcount_t xfrm_state_hash_generation; ++ + spinlock_t xfrm_policy_lock; + struct mutex xfrm_cfg_mutex; + }; +diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c +index 61fd0569d393..1423e2b7cb42 100644 +--- a/net/xfrm/xfrm_state.c ++++ b/net/xfrm/xfrm_state.c +@@ -44,7 +44,6 @@ static void xfrm_state_gc_task(struct work_struct *work); + */ + + static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024; +-static __read_mostly seqcount_t xfrm_state_hash_generation = SEQCNT_ZERO(xfrm_state_hash_generation); + static struct kmem_cache *xfrm_state_cache __ro_after_init; + + static DECLARE_WORK(xfrm_state_gc_work, xfrm_state_gc_task); +@@ -140,7 +139,7 @@ static void xfrm_hash_resize(struct work_struct *work) + } + + spin_lock_bh(&net->xfrm.xfrm_state_lock); +- write_seqcount_begin(&xfrm_state_hash_generation); ++ write_seqcount_begin(&net->xfrm.xfrm_state_hash_generation); + + nhashmask = (nsize / sizeof(struct hlist_head)) - 1U; + odst = xfrm_state_deref_prot(net->xfrm.state_bydst, net); +@@ -156,7 +155,7 @@ static void xfrm_hash_resize(struct work_struct *work) + rcu_assign_pointer(net->xfrm.state_byspi, nspi); + net->xfrm.state_hmask = nhashmask; + +- write_seqcount_end(&xfrm_state_hash_generation); ++ write_seqcount_end(&net->xfrm.xfrm_state_hash_generation); + spin_unlock_bh(&net->xfrm.xfrm_state_lock); + + osize = (ohashmask + 1) * sizeof(struct hlist_head); +@@ -1058,7 +1057,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr, + + to_put = NULL; + +- sequence = read_seqcount_begin(&xfrm_state_hash_generation); ++ sequence = read_seqcount_begin(&net->xfrm.xfrm_state_hash_generation); + + rcu_read_lock(); + h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family); +@@ -1171,7 +1170,7 @@ out: + if (to_put) + xfrm_state_put(to_put); + +- if (read_seqcount_retry(&xfrm_state_hash_generation, sequence)) { ++ if (read_seqcount_retry(&net->xfrm.xfrm_state_hash_generation, sequence)) { + *err = -EAGAIN; + if (x) { + xfrm_state_put(x); +@@ -2588,6 +2587,7 @@ int __net_init xfrm_state_init(struct net *net) + net->xfrm.state_num = 0; + INIT_WORK(&net->xfrm.state_hash_work, xfrm_hash_resize); + spin_lock_init(&net->xfrm.xfrm_state_lock); ++ seqcount_init(&net->xfrm.xfrm_state_hash_generation); + return 0; + + out_byspi: +-- +2.30.2 + diff --git a/queue-5.4/nfp-flower-ignore-duplicate-merge-hints-from-fw.patch b/queue-5.4/nfp-flower-ignore-duplicate-merge-hints-from-fw.patch new file mode 100644 index 00000000000..53209f72735 --- /dev/null +++ b/queue-5.4/nfp-flower-ignore-duplicate-merge-hints-from-fw.patch @@ -0,0 +1,219 @@ +From 148d754f9629e728fb6c515b5857ce275997d6cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Mar 2021 10:30:23 +0200 +Subject: nfp: flower: ignore duplicate merge hints from FW + +From: Yinjun Zhang + +[ Upstream commit 2ea538dbee1c79f6f6c24a6f2f82986e4b7ccb78 ] + +A merge hint message needs some time to process before the merged +flow actually reaches the firmware, during which we may get duplicate +merge hints if there're more than one packet that hit the pre-merged +flow. And processing duplicate merge hints will cost extra host_ctx's +which are a limited resource. + +Avoid the duplicate merge by using hash table to store the sub_flows +to be merged. + +Fixes: 8af56f40e53b ("nfp: flower: offload merge flows") +Signed-off-by: Yinjun Zhang +Signed-off-by: Louis Peens +Signed-off-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../net/ethernet/netronome/nfp/flower/main.h | 8 ++++ + .../ethernet/netronome/nfp/flower/metadata.c | 16 ++++++- + .../ethernet/netronome/nfp/flower/offload.c | 48 ++++++++++++++++++- + 3 files changed, 69 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h +index 31d94592a7c0..2d99533ad3e0 100644 +--- a/drivers/net/ethernet/netronome/nfp/flower/main.h ++++ b/drivers/net/ethernet/netronome/nfp/flower/main.h +@@ -164,6 +164,7 @@ struct nfp_fl_internal_ports { + * @qos_rate_limiters: Current active qos rate limiters + * @qos_stats_lock: Lock on qos stats updates + * @pre_tun_rule_cnt: Number of pre-tunnel rules offloaded ++ * @merge_table: Hash table to store merged flows + */ + struct nfp_flower_priv { + struct nfp_app *app; +@@ -196,6 +197,7 @@ struct nfp_flower_priv { + unsigned int qos_rate_limiters; + spinlock_t qos_stats_lock; /* Protect the qos stats */ + int pre_tun_rule_cnt; ++ struct rhashtable merge_table; + }; + + /** +@@ -310,6 +312,12 @@ struct nfp_fl_payload_link { + }; + + extern const struct rhashtable_params nfp_flower_table_params; ++extern const struct rhashtable_params merge_table_params; ++ ++struct nfp_merge_info { ++ u64 parent_ctx; ++ struct rhash_head ht_node; ++}; + + struct nfp_fl_stats_frame { + __be32 stats_con_id; +diff --git a/drivers/net/ethernet/netronome/nfp/flower/metadata.c b/drivers/net/ethernet/netronome/nfp/flower/metadata.c +index aa06fcb38f8b..327bb56b3ef5 100644 +--- a/drivers/net/ethernet/netronome/nfp/flower/metadata.c ++++ b/drivers/net/ethernet/netronome/nfp/flower/metadata.c +@@ -490,6 +490,12 @@ const struct rhashtable_params nfp_flower_table_params = { + .automatic_shrinking = true, + }; + ++const struct rhashtable_params merge_table_params = { ++ .key_offset = offsetof(struct nfp_merge_info, parent_ctx), ++ .head_offset = offsetof(struct nfp_merge_info, ht_node), ++ .key_len = sizeof(u64), ++}; ++ + int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count, + unsigned int host_num_mems) + { +@@ -506,6 +512,10 @@ int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count, + if (err) + goto err_free_flow_table; + ++ err = rhashtable_init(&priv->merge_table, &merge_table_params); ++ if (err) ++ goto err_free_stats_ctx_table; ++ + get_random_bytes(&priv->mask_id_seed, sizeof(priv->mask_id_seed)); + + /* Init ring buffer and unallocated mask_ids. */ +@@ -513,7 +523,7 @@ int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count, + kmalloc_array(NFP_FLOWER_MASK_ENTRY_RS, + NFP_FLOWER_MASK_ELEMENT_RS, GFP_KERNEL); + if (!priv->mask_ids.mask_id_free_list.buf) +- goto err_free_stats_ctx_table; ++ goto err_free_merge_table; + + priv->mask_ids.init_unallocated = NFP_FLOWER_MASK_ENTRY_RS - 1; + +@@ -550,6 +560,8 @@ err_free_last_used: + kfree(priv->mask_ids.last_used); + err_free_mask_id: + kfree(priv->mask_ids.mask_id_free_list.buf); ++err_free_merge_table: ++ rhashtable_destroy(&priv->merge_table); + err_free_stats_ctx_table: + rhashtable_destroy(&priv->stats_ctx_table); + err_free_flow_table: +@@ -568,6 +580,8 @@ void nfp_flower_metadata_cleanup(struct nfp_app *app) + nfp_check_rhashtable_empty, NULL); + rhashtable_free_and_destroy(&priv->stats_ctx_table, + nfp_check_rhashtable_empty, NULL); ++ rhashtable_free_and_destroy(&priv->merge_table, ++ nfp_check_rhashtable_empty, NULL); + kvfree(priv->stats); + kfree(priv->mask_ids.mask_id_free_list.buf); + kfree(priv->mask_ids.last_used); +diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c +index 4dd3f8a5a9b8..f57e7f337012 100644 +--- a/drivers/net/ethernet/netronome/nfp/flower/offload.c ++++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c +@@ -923,6 +923,8 @@ int nfp_flower_merge_offloaded_flows(struct nfp_app *app, + struct netlink_ext_ack *extack = NULL; + struct nfp_fl_payload *merge_flow; + struct nfp_fl_key_ls merge_key_ls; ++ struct nfp_merge_info *merge_info; ++ u64 parent_ctx = 0; + int err; + + ASSERT_RTNL(); +@@ -933,6 +935,15 @@ int nfp_flower_merge_offloaded_flows(struct nfp_app *app, + nfp_flower_is_merge_flow(sub_flow2)) + return -EINVAL; + ++ /* check if the two flows are already merged */ ++ parent_ctx = (u64)(be32_to_cpu(sub_flow1->meta.host_ctx_id)) << 32; ++ parent_ctx |= (u64)(be32_to_cpu(sub_flow2->meta.host_ctx_id)); ++ if (rhashtable_lookup_fast(&priv->merge_table, ++ &parent_ctx, merge_table_params)) { ++ nfp_flower_cmsg_warn(app, "The two flows are already merged.\n"); ++ return 0; ++ } ++ + err = nfp_flower_can_merge(sub_flow1, sub_flow2); + if (err) + return err; +@@ -974,16 +985,33 @@ int nfp_flower_merge_offloaded_flows(struct nfp_app *app, + if (err) + goto err_release_metadata; + ++ merge_info = kmalloc(sizeof(*merge_info), GFP_KERNEL); ++ if (!merge_info) { ++ err = -ENOMEM; ++ goto err_remove_rhash; ++ } ++ merge_info->parent_ctx = parent_ctx; ++ err = rhashtable_insert_fast(&priv->merge_table, &merge_info->ht_node, ++ merge_table_params); ++ if (err) ++ goto err_destroy_merge_info; ++ + err = nfp_flower_xmit_flow(app, merge_flow, + NFP_FLOWER_CMSG_TYPE_FLOW_MOD); + if (err) +- goto err_remove_rhash; ++ goto err_remove_merge_info; + + merge_flow->in_hw = true; + sub_flow1->in_hw = false; + + return 0; + ++err_remove_merge_info: ++ WARN_ON_ONCE(rhashtable_remove_fast(&priv->merge_table, ++ &merge_info->ht_node, ++ merge_table_params)); ++err_destroy_merge_info: ++ kfree(merge_info); + err_remove_rhash: + WARN_ON_ONCE(rhashtable_remove_fast(&priv->flow_table, + &merge_flow->fl_node, +@@ -1211,7 +1239,9 @@ nfp_flower_remove_merge_flow(struct nfp_app *app, + { + struct nfp_flower_priv *priv = app->priv; + struct nfp_fl_payload_link *link, *temp; ++ struct nfp_merge_info *merge_info; + struct nfp_fl_payload *origin; ++ u64 parent_ctx = 0; + bool mod = false; + int err; + +@@ -1248,8 +1278,22 @@ nfp_flower_remove_merge_flow(struct nfp_app *app, + err_free_links: + /* Clean any links connected with the merged flow. */ + list_for_each_entry_safe(link, temp, &merge_flow->linked_flows, +- merge_flow.list) ++ merge_flow.list) { ++ u32 ctx_id = be32_to_cpu(link->sub_flow.flow->meta.host_ctx_id); ++ ++ parent_ctx = (parent_ctx << 32) | (u64)(ctx_id); + nfp_flower_unlink_flow(link); ++ } ++ ++ merge_info = rhashtable_lookup_fast(&priv->merge_table, ++ &parent_ctx, ++ merge_table_params); ++ if (merge_info) { ++ WARN_ON_ONCE(rhashtable_remove_fast(&priv->merge_table, ++ &merge_info->ht_node, ++ merge_table_params)); ++ kfree(merge_info); ++ } + + kfree(merge_flow->action_data); + kfree(merge_flow->mask_data); +-- +2.30.2 + diff --git a/queue-5.4/openvswitch-fix-send-of-uninitialized-stack-memory-i.patch b/queue-5.4/openvswitch-fix-send-of-uninitialized-stack-memory-i.patch new file mode 100644 index 00000000000..af6db5e8336 --- /dev/null +++ b/queue-5.4/openvswitch-fix-send-of-uninitialized-stack-memory-i.patch @@ -0,0 +1,47 @@ +From db533bc87a15a707a219f2519cebd1a2613dc0eb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 4 Apr 2021 19:50:31 +0200 +Subject: openvswitch: fix send of uninitialized stack memory in ct limit reply + +From: Ilya Maximets + +[ Upstream commit 4d51419d49930be2701c2633ae271b350397c3ca ] + +'struct ovs_zone_limit' has more members than initialized in +ovs_ct_limit_get_default_limit(). The rest of the memory is a random +kernel stack content that ends up being sent to userspace. + +Fix that by using designated initializer that will clear all +non-specified fields. + +Fixes: 11efd5cb04a1 ("openvswitch: Support conntrack zone limit") +Signed-off-by: Ilya Maximets +Acked-by: Tonghao Zhang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/openvswitch/conntrack.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c +index e905248b11c2..b6f98eba71f1 100644 +--- a/net/openvswitch/conntrack.c ++++ b/net/openvswitch/conntrack.c +@@ -2019,10 +2019,10 @@ static int ovs_ct_limit_del_zone_limit(struct nlattr *nla_zone_limit, + static int ovs_ct_limit_get_default_limit(struct ovs_ct_limit_info *info, + struct sk_buff *reply) + { +- struct ovs_zone_limit zone_limit; +- +- zone_limit.zone_id = OVS_ZONE_LIMIT_DEFAULT_ZONE; +- zone_limit.limit = info->default_limit; ++ struct ovs_zone_limit zone_limit = { ++ .zone_id = OVS_ZONE_LIMIT_DEFAULT_ZONE, ++ .limit = info->default_limit, ++ }; + + return nla_put_nohdr(reply, sizeof(zone_limit), &zone_limit); + } +-- +2.30.2 + diff --git a/queue-5.4/perf-inject-fix-repipe-usage.patch b/queue-5.4/perf-inject-fix-repipe-usage.patch new file mode 100644 index 00000000000..3672fde1923 --- /dev/null +++ b/queue-5.4/perf-inject-fix-repipe-usage.patch @@ -0,0 +1,54 @@ +From 41e9cd56c9f5566447ee98477a2cc37323e56ec2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Apr 2021 13:36:05 +0300 +Subject: perf inject: Fix repipe usage + +From: Adrian Hunter + +[ Upstream commit 026334a3bb6a3919b42aba9fc11843db2b77fd41 ] + +Since commit 14d3d54052539a1e ("perf session: Try to read pipe data from +file") 'perf inject' has started printing "PERFILE2h" when not processing +pipes. + +The commit exposed perf to the possiblity that the input is not a pipe +but the 'repipe' parameter gets used. That causes the printing because +perf inject sets 'repipe' to true always. + +The 'repipe' parameter of perf_session__new() is used by 2 functions: + + - perf_file_header__read_pipe() + - trace_report() + +In both cases, the functions copy data to STDOUT_FILENO when 'repipe' is +true. + +Fix by setting 'repipe' to true only if the output is a pipe. + +Fixes: e558a5bd8b74aff4 ("perf inject: Work with files") +Signed-off-by: Adrian Hunter +Acked-by: Jiri Olsa +Cc: Andrew Vagin +Link: http://lore.kernel.org/lkml/20210401103605.9000-1-adrian.hunter@intel.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-inject.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c +index 372ecb3e2c06..0d524ef3606d 100644 +--- a/tools/perf/builtin-inject.c ++++ b/tools/perf/builtin-inject.c +@@ -835,7 +835,7 @@ int cmd_inject(int argc, const char **argv) + inject.tool.ordered_events = inject.sched_stat; + + data.path = inject.input_name; +- inject.session = perf_session__new(&data, true, &inject.tool); ++ inject.session = perf_session__new(&data, inject.output.is_pipe, &inject.tool); + if (IS_ERR(inject.session)) + return PTR_ERR(inject.session); + +-- +2.30.2 + diff --git a/queue-5.4/rdma-addr-be-strict-with-gid-size.patch b/queue-5.4/rdma-addr-be-strict-with-gid-size.patch new file mode 100644 index 00000000000..17ae0c92436 --- /dev/null +++ b/queue-5.4/rdma-addr-be-strict-with-gid-size.patch @@ -0,0 +1,41 @@ +From 6155eeb642afca53d30fa7db012d03a380833201 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Apr 2021 10:44:34 +0300 +Subject: RDMA/addr: Be strict with gid size + +From: Leon Romanovsky + +[ Upstream commit d1c803a9ccd7bd3aff5e989ccfb39ed3b799b975 ] + +The nla_len() is less than or equal to 16. If it's less than 16 then end +of the "gid" buffer is uninitialized. + +Fixes: ae43f8286730 ("IB/core: Add IP to GID netlink offload") +Link: https://lore.kernel.org/r/20210405074434.264221-1-leon@kernel.org +Reported-by: Dan Carpenter +Signed-off-by: Mark Bloch +Signed-off-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/core/addr.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c +index 8beed4197e73..c9e63c692b6e 100644 +--- a/drivers/infiniband/core/addr.c ++++ b/drivers/infiniband/core/addr.c +@@ -76,7 +76,9 @@ static struct workqueue_struct *addr_wq; + + static const struct nla_policy ib_nl_addr_policy[LS_NLA_TYPE_MAX] = { + [LS_NLA_TYPE_DGID] = {.type = NLA_BINARY, +- .len = sizeof(struct rdma_nla_ls_gid)}, ++ .len = sizeof(struct rdma_nla_ls_gid), ++ .validation_type = NLA_VALIDATE_MIN, ++ .min = sizeof(struct rdma_nla_ls_gid)}, + }; + + static inline bool ib_nl_is_good_ip_resp(const struct nlmsghdr *nlh) +-- +2.30.2 + diff --git a/queue-5.4/rdma-cxgb4-check-for-ipv6-address-properly-while-des.patch b/queue-5.4/rdma-cxgb4-check-for-ipv6-address-properly-while-des.patch new file mode 100644 index 00000000000..eba3fdc54f8 --- /dev/null +++ b/queue-5.4/rdma-cxgb4-check-for-ipv6-address-properly-while-des.patch @@ -0,0 +1,39 @@ +From 85cfba459edcce875da97e2c069f9989ed81d531 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Mar 2021 19:27:15 +0530 +Subject: RDMA/cxgb4: check for ipv6 address properly while destroying listener + +From: Potnuri Bharat Teja + +[ Upstream commit 603c4690b01aaffe3a6c3605a429f6dac39852ae ] + +ipv6 bit is wrongly set by the below which causes fatal adapter lookup +engine errors for ipv4 connections while destroying a listener. Fix it to +properly check the local address for ipv6. + +Fixes: 3408be145a5d ("RDMA/cxgb4: Fix adapter LE hash errors while destroying ipv6 listening server") +Link: https://lore.kernel.org/r/20210331135715.30072-1-bharat@chelsio.com +Signed-off-by: Potnuri Bharat Teja +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/cxgb4/cm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c +index 3c78f8c32d12..535ee41ee421 100644 +--- a/drivers/infiniband/hw/cxgb4/cm.c ++++ b/drivers/infiniband/hw/cxgb4/cm.c +@@ -3616,7 +3616,8 @@ int c4iw_destroy_listen(struct iw_cm_id *cm_id) + c4iw_init_wr_wait(ep->com.wr_waitp); + err = cxgb4_remove_server( + ep->com.dev->rdev.lldi.ports[0], ep->stid, +- ep->com.dev->rdev.lldi.rxq_ids[0], true); ++ ep->com.dev->rdev.lldi.rxq_ids[0], ++ ep->com.local_addr.ss_family == AF_INET6); + if (err) + goto done; + err = c4iw_wait_for_reply(&ep->com.dev->rdev, ep->com.wr_waitp, +-- +2.30.2 + diff --git a/queue-5.4/regulator-bd9571mwv-fix-avs-and-dvfs-voltage-range.patch b/queue-5.4/regulator-bd9571mwv-fix-avs-and-dvfs-voltage-range.patch new file mode 100644 index 00000000000..c1d514e8fa1 --- /dev/null +++ b/queue-5.4/regulator-bd9571mwv-fix-avs-and-dvfs-voltage-range.patch @@ -0,0 +1,50 @@ +From 7f07a83f6d7d9d6231308bf5510dbb47d4cf5117 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Mar 2021 14:02:40 +0100 +Subject: regulator: bd9571mwv: Fix AVS and DVFS voltage range + +From: Geert Uytterhoeven + +[ Upstream commit 3b6e7088afc919f5b52e4d2de8501ad34d35b09b ] + +According to Table 30 ("DVFS_MoniVDAC [6:0] Setting Table") in the +BD9571MWV-M Datasheet Rev. 002, the valid voltage range is 600..1100 mV +(settings 0x3c..0x6e). While the lower limit is taken into account (by +setting regulator_desc.linear_min_sel to 0x3c), the upper limit is not. + +Fix this by reducing regulator_desc.n_voltages from 0x80 to 0x6f. + +Fixes: e85c5a153fe237f2 ("regulator: Add ROHM BD9571MWV-M PMIC regulator driver") +Signed-off-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20210312130242.3390038-2-geert+renesas@glider.be +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/bd9571mwv-regulator.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/regulator/bd9571mwv-regulator.c b/drivers/regulator/bd9571mwv-regulator.c +index e690c2ce5b3c..25e33028871c 100644 +--- a/drivers/regulator/bd9571mwv-regulator.c ++++ b/drivers/regulator/bd9571mwv-regulator.c +@@ -124,7 +124,7 @@ static const struct regulator_ops vid_ops = { + + static const struct regulator_desc regulators[] = { + BD9571MWV_REG("VD09", "vd09", VD09, avs_ops, 0, 0x7f, +- 0x80, 600000, 10000, 0x3c), ++ 0x6f, 600000, 10000, 0x3c), + BD9571MWV_REG("VD18", "vd18", VD18, vid_ops, BD9571MWV_VD18_VID, 0xf, + 16, 1625000, 25000, 0), + BD9571MWV_REG("VD25", "vd25", VD25, vid_ops, BD9571MWV_VD25_VID, 0xf, +@@ -133,7 +133,7 @@ static const struct regulator_desc regulators[] = { + 11, 2800000, 100000, 0), + BD9571MWV_REG("DVFS", "dvfs", DVFS, reg_ops, + BD9571MWV_DVFS_MONIVDAC, 0x7f, +- 0x80, 600000, 10000, 0x3c), ++ 0x6f, 600000, 10000, 0x3c), + }; + + #ifdef CONFIG_PM_SLEEP +-- +2.30.2 + diff --git a/queue-5.4/s390-cpcmd-fix-inline-assembly-register-clobbering.patch b/queue-5.4/s390-cpcmd-fix-inline-assembly-register-clobbering.patch new file mode 100644 index 00000000000..e049e494435 --- /dev/null +++ b/queue-5.4/s390-cpcmd-fix-inline-assembly-register-clobbering.patch @@ -0,0 +1,46 @@ +From 8721a35dc50849f3cda499e94d96dca499624447 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Mar 2021 18:35:07 +0200 +Subject: s390/cpcmd: fix inline assembly register clobbering + +From: Alexander Gordeev + +[ Upstream commit 7a2f91441b2c1d81b77c1cd816a4659f4abc9cbe ] + +Register variables initialized using arithmetic. That leads to +kasan instrumentaton code corrupting the registers contents. +Follow GCC guidlines and use temporary variables for assigning +init values to register variables. + +Fixes: 94c12cc7d196 ("[S390] Inline assembly cleanup.") +Signed-off-by: Alexander Gordeev +Acked-by: Ilya Leoshkevich +Link: https://gcc.gnu.org/onlinedocs/gcc-10.2.0/gcc/Local-Register-Variables.html +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + arch/s390/kernel/cpcmd.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c +index af013b4244d3..2da027359798 100644 +--- a/arch/s390/kernel/cpcmd.c ++++ b/arch/s390/kernel/cpcmd.c +@@ -37,10 +37,12 @@ static int diag8_noresponse(int cmdlen) + + static int diag8_response(int cmdlen, char *response, int *rlen) + { ++ unsigned long _cmdlen = cmdlen | 0x40000000L; ++ unsigned long _rlen = *rlen; + register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf; + register unsigned long reg3 asm ("3") = (addr_t) response; +- register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L; +- register unsigned long reg5 asm ("5") = *rlen; ++ register unsigned long reg4 asm ("4") = _cmdlen; ++ register unsigned long reg5 asm ("5") = _rlen; + + asm volatile( + " diag %2,%0,0x8\n" +-- +2.30.2 + diff --git a/queue-5.4/sch_red-fix-off-by-one-checks-in-red_check_params.patch b/queue-5.4/sch_red-fix-off-by-one-checks-in-red_check_params.patch new file mode 100644 index 00000000000..439eb82304f --- /dev/null +++ b/queue-5.4/sch_red-fix-off-by-one-checks-in-red_check_params.patch @@ -0,0 +1,73 @@ +From 3b1af94595a940a61de7d0022934ce51978af735 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Mar 2021 11:14:53 -0700 +Subject: sch_red: fix off-by-one checks in red_check_params() + +From: Eric Dumazet + +[ Upstream commit 3a87571f0ffc51ba3bf3ecdb6032861d0154b164 ] + +This fixes following syzbot report: + +UBSAN: shift-out-of-bounds in ./include/net/red.h:237:23 +shift exponent 32 is too large for 32-bit type 'unsigned int' +CPU: 1 PID: 8418 Comm: syz-executor170 Not tainted 5.12.0-rc4-next-20210324-syzkaller #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:79 [inline] + dump_stack+0x141/0x1d7 lib/dump_stack.c:120 + ubsan_epilogue+0xb/0x5a lib/ubsan.c:148 + __ubsan_handle_shift_out_of_bounds.cold+0xb1/0x181 lib/ubsan.c:327 + red_set_parms include/net/red.h:237 [inline] + choke_change.cold+0x3c/0xc8 net/sched/sch_choke.c:414 + qdisc_create+0x475/0x12f0 net/sched/sch_api.c:1247 + tc_modify_qdisc+0x4c8/0x1a50 net/sched/sch_api.c:1663 + rtnetlink_rcv_msg+0x44e/0xad0 net/core/rtnetlink.c:5553 + netlink_rcv_skb+0x153/0x420 net/netlink/af_netlink.c:2502 + netlink_unicast_kernel net/netlink/af_netlink.c:1312 [inline] + netlink_unicast+0x533/0x7d0 net/netlink/af_netlink.c:1338 + netlink_sendmsg+0x856/0xd90 net/netlink/af_netlink.c:1927 + sock_sendmsg_nosec net/socket.c:654 [inline] + sock_sendmsg+0xcf/0x120 net/socket.c:674 + ____sys_sendmsg+0x6e8/0x810 net/socket.c:2350 + ___sys_sendmsg+0xf3/0x170 net/socket.c:2404 + __sys_sendmsg+0xe5/0x1b0 net/socket.c:2433 + do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46 + entry_SYSCALL_64_after_hwframe+0x44/0xae +RIP: 0033:0x43f039 +Code: 28 c3 e8 2a 14 00 00 66 2e 0f 1f 84 00 00 00 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 c0 ff ff ff f7 d8 64 89 01 48 +RSP: 002b:00007ffdfa725168 EFLAGS: 00000246 ORIG_RAX: 000000000000002e +RAX: ffffffffffffffda RBX: 0000000000400488 RCX: 000000000043f039 +RDX: 0000000000000000 RSI: 0000000020000040 RDI: 0000000000000004 +RBP: 0000000000403020 R08: 0000000000400488 R09: 0000000000400488 +R10: 0000000000400488 R11: 0000000000000246 R12: 00000000004030b0 +R13: 0000000000000000 R14: 00000000004ac018 R15: 0000000000400488 + +Fixes: 8afa10cbe281 ("net_sched: red: Avoid illegal values") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/net/red.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/net/red.h b/include/net/red.h +index 8fe55b8b2fb8..ff07a7cedf68 100644 +--- a/include/net/red.h ++++ b/include/net/red.h +@@ -171,9 +171,9 @@ static inline void red_set_vars(struct red_vars *v) + static inline bool red_check_params(u32 qth_min, u32 qth_max, u8 Wlog, + u8 Scell_log, u8 *stab) + { +- if (fls(qth_min) + Wlog > 32) ++ if (fls(qth_min) + Wlog >= 32) + return false; +- if (fls(qth_max) + Wlog > 32) ++ if (fls(qth_max) + Wlog >= 32) + return false; + if (Scell_log >= 32) + return false; +-- +2.30.2 + diff --git a/queue-5.4/scsi-ufs-avoid-busy-waiting-by-eliminating-tag-confl.patch b/queue-5.4/scsi-ufs-avoid-busy-waiting-by-eliminating-tag-confl.patch new file mode 100644 index 00000000000..b09c75f6f1c --- /dev/null +++ b/queue-5.4/scsi-ufs-avoid-busy-waiting-by-eliminating-tag-confl.patch @@ -0,0 +1,354 @@ +From 884551564e02e3b94e32b24c252388c0caa4ac5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Dec 2019 10:13:08 -0800 +Subject: scsi: ufs: Avoid busy-waiting by eliminating tag conflicts + +From: Bart Van Assche + +[ Upstream commit 7252a3603015f1fd04363956f4b72a537c9f9c42 ] + +Instead of tracking which tags are in use in the ufs_hba.lrb_in_use +bitmask, rely on the block layer tag allocation mechanism. This patch +removes the following busy-waiting loop if ufshcd_issue_devman_upiu_cmd() +and the block layer accidentally allocate the same tag for a SCSI request: + + * ufshcd_queuecommand() returns SCSI_MLQUEUE_HOST_BUSY. + + * The SCSI core requeues the SCSI command. + +Cc: Can Guo +Cc: Stanley Chu +Cc: Avri Altman +Cc: Tomas Winkler +Link: https://lore.kernel.org/r/20191209181309.196233-2-bvanassche@acm.org +Tested-by: Bean Huo +Reviewed-by: Avri Altman +Signed-off-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/ufs/ufshcd.c | 121 +++++++++++++++----------------------- + drivers/scsi/ufs/ufshcd.h | 6 +- + 2 files changed, 50 insertions(+), 77 deletions(-) + +diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c +index 289edf70ccb9..e84617172968 100644 +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -496,8 +496,8 @@ static void ufshcd_print_tmrs(struct ufs_hba *hba, unsigned long bitmap) + static void ufshcd_print_host_state(struct ufs_hba *hba) + { + dev_err(hba->dev, "UFS Host state=%d\n", hba->ufshcd_state); +- dev_err(hba->dev, "lrb in use=0x%lx, outstanding reqs=0x%lx tasks=0x%lx\n", +- hba->lrb_in_use, hba->outstanding_reqs, hba->outstanding_tasks); ++ dev_err(hba->dev, "outstanding reqs=0x%lx tasks=0x%lx\n", ++ hba->outstanding_reqs, hba->outstanding_tasks); + dev_err(hba->dev, "saved_err=0x%x, saved_uic_err=0x%x\n", + hba->saved_err, hba->saved_uic_err); + dev_err(hba->dev, "Device power mode=%d, UIC link state=%d\n", +@@ -1279,6 +1279,24 @@ out: + return ret; + } + ++static bool ufshcd_is_busy(struct request *req, void *priv, bool reserved) ++{ ++ int *busy = priv; ++ ++ WARN_ON_ONCE(reserved); ++ (*busy)++; ++ return false; ++} ++ ++/* Whether or not any tag is in use by a request that is in progress. */ ++static bool ufshcd_any_tag_in_use(struct ufs_hba *hba) ++{ ++ struct request_queue *q = hba->cmd_queue; ++ int busy = 0; ++ ++ blk_mq_tagset_busy_iter(q->tag_set, ufshcd_is_busy, &busy); ++ return busy; ++} + + static int ufshcd_devfreq_get_dev_status(struct device *dev, + struct devfreq_dev_status *stat) +@@ -1633,7 +1651,7 @@ static void ufshcd_gate_work(struct work_struct *work) + + if (hba->clk_gating.active_reqs + || hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL +- || hba->lrb_in_use || hba->outstanding_tasks ++ || ufshcd_any_tag_in_use(hba) || hba->outstanding_tasks + || hba->active_uic_cmd || hba->uic_async_done) + goto rel_lock; + +@@ -1687,7 +1705,7 @@ static void __ufshcd_release(struct ufs_hba *hba) + + if (hba->clk_gating.active_reqs || hba->clk_gating.is_suspended + || hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL +- || hba->lrb_in_use || hba->outstanding_tasks ++ || ufshcd_any_tag_in_use(hba) || hba->outstanding_tasks + || hba->active_uic_cmd || hba->uic_async_done + || ufshcd_eh_in_progress(hba)) + return; +@@ -2457,22 +2475,9 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) + + hba->req_abort_count = 0; + +- /* acquire the tag to make sure device cmds don't use it */ +- if (test_and_set_bit_lock(tag, &hba->lrb_in_use)) { +- /* +- * Dev manage command in progress, requeue the command. +- * Requeuing the command helps in cases where the request *may* +- * find different tag instead of waiting for dev manage command +- * completion. +- */ +- err = SCSI_MLQUEUE_HOST_BUSY; +- goto out; +- } +- + err = ufshcd_hold(hba, true); + if (err) { + err = SCSI_MLQUEUE_HOST_BUSY; +- clear_bit_unlock(tag, &hba->lrb_in_use); + goto out; + } + WARN_ON(hba->clk_gating.state != CLKS_ON); +@@ -2494,7 +2499,6 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) + if (err) { + ufshcd_release(hba); + lrbp->cmd = NULL; +- clear_bit_unlock(tag, &hba->lrb_in_use); + goto out; + } + /* Make sure descriptors are ready before ringing the doorbell */ +@@ -2641,44 +2645,6 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba, + return err; + } + +-/** +- * ufshcd_get_dev_cmd_tag - Get device management command tag +- * @hba: per-adapter instance +- * @tag_out: pointer to variable with available slot value +- * +- * Get a free slot and lock it until device management command +- * completes. +- * +- * Returns false if free slot is unavailable for locking, else +- * return true with tag value in @tag. +- */ +-static bool ufshcd_get_dev_cmd_tag(struct ufs_hba *hba, int *tag_out) +-{ +- int tag; +- bool ret = false; +- unsigned long tmp; +- +- if (!tag_out) +- goto out; +- +- do { +- tmp = ~hba->lrb_in_use; +- tag = find_last_bit(&tmp, hba->nutrs); +- if (tag >= hba->nutrs) +- goto out; +- } while (test_and_set_bit_lock(tag, &hba->lrb_in_use)); +- +- *tag_out = tag; +- ret = true; +-out: +- return ret; +-} +- +-static inline void ufshcd_put_dev_cmd_tag(struct ufs_hba *hba, int tag) +-{ +- clear_bit_unlock(tag, &hba->lrb_in_use); +-} +- + /** + * ufshcd_exec_dev_cmd - API for sending device management requests + * @hba: UFS hba +@@ -2691,6 +2657,8 @@ static inline void ufshcd_put_dev_cmd_tag(struct ufs_hba *hba, int tag) + static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, + enum dev_cmd_type cmd_type, int timeout) + { ++ struct request_queue *q = hba->cmd_queue; ++ struct request *req; + struct ufshcd_lrb *lrbp; + int err; + int tag; +@@ -2704,7 +2672,11 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, + * Even though we use wait_event() which sleeps indefinitely, + * the maximum wait time is bounded by SCSI request timeout. + */ +- wait_event(hba->dev_cmd.tag_wq, ufshcd_get_dev_cmd_tag(hba, &tag)); ++ req = blk_get_request(q, REQ_OP_DRV_OUT, 0); ++ if (IS_ERR(req)) ++ return PTR_ERR(req); ++ tag = req->tag; ++ WARN_ON_ONCE(!ufshcd_valid_tag(hba, tag)); + + init_completion(&wait); + lrbp = &hba->lrb[tag]; +@@ -2729,8 +2701,7 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, + err ? "query_complete_err" : "query_complete"); + + out_put_tag: +- ufshcd_put_dev_cmd_tag(hba, tag); +- wake_up(&hba->dev_cmd.tag_wq); ++ blk_put_request(req); + up_read(&hba->clk_scaling_lock); + return err; + } +@@ -4863,7 +4834,6 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, + cmd->result = result; + /* Mark completed command as NULL in LRB */ + lrbp->cmd = NULL; +- clear_bit_unlock(index, &hba->lrb_in_use); + /* Do not touch lrbp after scsi done */ + cmd->scsi_done(cmd); + __ufshcd_release(hba); +@@ -4885,9 +4855,6 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, + hba->outstanding_reqs ^= completed_reqs; + + ufshcd_clk_scaling_update_busy(hba); +- +- /* we might have free'd some tags above */ +- wake_up(&hba->dev_cmd.tag_wq); + } + + /** +@@ -5873,6 +5840,8 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, + int cmd_type, + enum query_opcode desc_op) + { ++ struct request_queue *q = hba->cmd_queue; ++ struct request *req; + struct ufshcd_lrb *lrbp; + int err = 0; + int tag; +@@ -5882,7 +5851,11 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, + + down_read(&hba->clk_scaling_lock); + +- wait_event(hba->dev_cmd.tag_wq, ufshcd_get_dev_cmd_tag(hba, &tag)); ++ req = blk_get_request(q, REQ_OP_DRV_OUT, 0); ++ if (IS_ERR(req)) ++ return PTR_ERR(req); ++ tag = req->tag; ++ WARN_ON_ONCE(!ufshcd_valid_tag(hba, tag)); + + init_completion(&wait); + lrbp = &hba->lrb[tag]; +@@ -5956,8 +5929,7 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, + } + } + +- ufshcd_put_dev_cmd_tag(hba, tag); +- wake_up(&hba->dev_cmd.tag_wq); ++ blk_put_request(req); + up_read(&hba->clk_scaling_lock); + return err; + } +@@ -6250,9 +6222,6 @@ cleanup: + hba->lrb[tag].cmd = NULL; + spin_unlock_irqrestore(host->host_lock, flags); + +- clear_bit_unlock(tag, &hba->lrb_in_use); +- wake_up(&hba->dev_cmd.tag_wq); +- + out: + if (!err) { + err = SUCCESS; +@@ -8248,6 +8217,7 @@ void ufshcd_remove(struct ufs_hba *hba) + { + ufs_bsg_remove(hba); + ufs_sysfs_remove_nodes(hba->dev); ++ blk_cleanup_queue(hba->cmd_queue); + scsi_remove_host(hba->host); + /* disable interrupts */ + ufshcd_disable_intr(hba, hba->intr_mask); +@@ -8411,9 +8381,6 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) + + init_rwsem(&hba->clk_scaling_lock); + +- /* Initialize device management tag acquire wait queue */ +- init_waitqueue_head(&hba->dev_cmd.tag_wq); +- + ufshcd_init_clk_gating(hba); + + ufshcd_init_clk_scaling(hba); +@@ -8447,6 +8414,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) + goto exit_gating; + } + ++ hba->cmd_queue = blk_mq_init_queue(&hba->host->tag_set); ++ if (IS_ERR(hba->cmd_queue)) { ++ err = PTR_ERR(hba->cmd_queue); ++ goto out_remove_scsi_host; ++ } ++ + /* Reset the attached device */ + ufshcd_vops_device_reset(hba); + +@@ -8456,7 +8429,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) + dev_err(hba->dev, "Host controller enable failed\n"); + ufshcd_print_host_regs(hba); + ufshcd_print_host_state(hba); +- goto out_remove_scsi_host; ++ goto free_cmd_queue; + } + + /* +@@ -8493,6 +8466,8 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) + + return 0; + ++free_cmd_queue: ++ blk_cleanup_queue(hba->cmd_queue); + out_remove_scsi_host: + scsi_remove_host(hba->host); + exit_gating: +diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h +index 4f1dec68a853..8fd6fd75cb5c 100644 +--- a/drivers/scsi/ufs/ufshcd.h ++++ b/drivers/scsi/ufs/ufshcd.h +@@ -213,13 +213,11 @@ struct ufs_query { + * @type: device management command type - Query, NOP OUT + * @lock: lock to allow one command at a time + * @complete: internal commands completion +- * @tag_wq: wait queue until free command slot is available + */ + struct ufs_dev_cmd { + enum dev_cmd_type type; + struct mutex lock; + struct completion *complete; +- wait_queue_head_t tag_wq; + struct ufs_query query; + }; + +@@ -484,7 +482,7 @@ struct ufs_stats { + * @host: Scsi_Host instance of the driver + * @dev: device handle + * @lrb: local reference block +- * @lrb_in_use: lrb in use ++ * @cmd_queue: Used to allocate command tags from hba->host->tag_set. + * @outstanding_tasks: Bits representing outstanding task requests + * @outstanding_reqs: Bits representing outstanding transfer requests + * @capabilities: UFS Controller Capabilities +@@ -543,6 +541,7 @@ struct ufs_hba { + + struct Scsi_Host *host; + struct device *dev; ++ struct request_queue *cmd_queue; + /* + * This field is to keep a reference to "scsi_device" corresponding to + * "UFS device" W-LU. +@@ -563,7 +562,6 @@ struct ufs_hba { + u32 ahit; + + struct ufshcd_lrb *lrb; +- unsigned long lrb_in_use; + + unsigned long outstanding_tasks; + unsigned long outstanding_reqs; +-- +2.30.2 + diff --git a/queue-5.4/scsi-ufs-core-fix-task-management-request-completion.patch b/queue-5.4/scsi-ufs-core-fix-task-management-request-completion.patch new file mode 100644 index 00000000000..49242040164 --- /dev/null +++ b/queue-5.4/scsi-ufs-core-fix-task-management-request-completion.patch @@ -0,0 +1,40 @@ +From ffce6f17239e5ffe05034bfb7c4c7e6c8dd6ae52 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Apr 2021 00:39:08 -0700 +Subject: scsi: ufs: core: Fix task management request completion timeout + +From: Can Guo + +[ Upstream commit 1235fc569e0bf541ddda0a1224d4c6fa6d914890 ] + +ufshcd_tmc_handler() calls blk_mq_tagset_busy_iter(fn = ufshcd_compl_tm()), +but since blk_mq_tagset_busy_iter() only iterates over all reserved tags +and requests which are not in IDLE state, ufshcd_compl_tm() never gets a +chance to run. Thus, TMR always ends up with completion timeout. Fix it by +calling blk_mq_start_request() in __ufshcd_issue_tm_cmd(). + +Link: https://lore.kernel.org/r/1617262750-4864-2-git-send-email-cang@codeaurora.org +Fixes: 69a6c269c097 ("scsi: ufs: Use blk_{get,put}_request() to allocate and free TMFs") +Reviewed-by: Bart Van Assche +Signed-off-by: Can Guo +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/ufs/ufshcd.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c +index e7e6405401dd..3f20270f0ca0 100644 +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -5710,6 +5710,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, + + spin_lock_irqsave(host->host_lock, flags); + task_tag = hba->nutrs + free_slot; ++ blk_mq_start_request(req); + + treq->req_header.dword_0 |= cpu_to_be32(task_tag); + +-- +2.30.2 + diff --git a/queue-5.4/scsi-ufs-core-fix-wrong-task-tag-used-in-task-manage.patch b/queue-5.4/scsi-ufs-core-fix-wrong-task-tag-used-in-task-manage.patch new file mode 100644 index 00000000000..97b3ad06588 --- /dev/null +++ b/queue-5.4/scsi-ufs-core-fix-wrong-task-tag-used-in-task-manage.patch @@ -0,0 +1,104 @@ +From c7674b017ba12b2dd6f3c783c0eef6c1b2a5210f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Apr 2021 00:39:09 -0700 +Subject: scsi: ufs: core: Fix wrong Task Tag used in task management request + UPIUs + +From: Can Guo + +[ Upstream commit 4b42d557a8add52b9a9924fb31e40a218aab7801 ] + +In __ufshcd_issue_tm_cmd(), it is not correct to use hba->nutrs + req->tag +as the Task Tag in a TMR UPIU. Directly use req->tag as the Task Tag. + +Fixes: e293313262d3 ("scsi: ufs: Fix broken task management command implementation") +Link: https://lore.kernel.org/r/1617262750-4864-3-git-send-email-cang@codeaurora.org +Reviewed-by: Bart Van Assche +Signed-off-by: Can Guo +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/ufs/ufshcd.c | 30 +++++++++++++----------------- + 1 file changed, 13 insertions(+), 17 deletions(-) + +diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c +index 3f20270f0ca0..b81eebc7e2df 100644 +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -5695,35 +5695,31 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, + DECLARE_COMPLETION_ONSTACK(wait); + struct request *req; + unsigned long flags; +- int free_slot, task_tag, err; ++ int task_tag, err; + + /* +- * Get free slot, sleep if slots are unavailable. +- * Even though we use wait_event() which sleeps indefinitely, +- * the maximum wait time is bounded by %TM_CMD_TIMEOUT. ++ * blk_get_request() is used here only to get a free tag. + */ + req = blk_get_request(q, REQ_OP_DRV_OUT, BLK_MQ_REQ_RESERVED); + req->end_io_data = &wait; +- free_slot = req->tag; +- WARN_ON_ONCE(free_slot < 0 || free_slot >= hba->nutmrs); + ufshcd_hold(hba, false); + + spin_lock_irqsave(host->host_lock, flags); +- task_tag = hba->nutrs + free_slot; + blk_mq_start_request(req); + ++ task_tag = req->tag; + treq->req_header.dword_0 |= cpu_to_be32(task_tag); + +- memcpy(hba->utmrdl_base_addr + free_slot, treq, sizeof(*treq)); +- ufshcd_vops_setup_task_mgmt(hba, free_slot, tm_function); ++ memcpy(hba->utmrdl_base_addr + task_tag, treq, sizeof(*treq)); ++ ufshcd_vops_setup_task_mgmt(hba, task_tag, tm_function); + + /* send command to the controller */ +- __set_bit(free_slot, &hba->outstanding_tasks); ++ __set_bit(task_tag, &hba->outstanding_tasks); + + /* Make sure descriptors are ready before ringing the task doorbell */ + wmb(); + +- ufshcd_writel(hba, 1 << free_slot, REG_UTP_TASK_REQ_DOOR_BELL); ++ ufshcd_writel(hba, 1 << task_tag, REG_UTP_TASK_REQ_DOOR_BELL); + /* Make sure that doorbell is committed immediately */ + wmb(); + +@@ -5743,24 +5739,24 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, + ufshcd_add_tm_upiu_trace(hba, task_tag, "tm_complete_err"); + dev_err(hba->dev, "%s: task management cmd 0x%.2x timed-out\n", + __func__, tm_function); +- if (ufshcd_clear_tm_cmd(hba, free_slot)) +- dev_WARN(hba->dev, "%s: unable clear tm cmd (slot %d) after timeout\n", +- __func__, free_slot); ++ if (ufshcd_clear_tm_cmd(hba, task_tag)) ++ dev_WARN(hba->dev, "%s: unable to clear tm cmd (slot %d) after timeout\n", ++ __func__, task_tag); + err = -ETIMEDOUT; + } else { + err = 0; +- memcpy(treq, hba->utmrdl_base_addr + free_slot, sizeof(*treq)); ++ memcpy(treq, hba->utmrdl_base_addr + task_tag, sizeof(*treq)); + + ufshcd_add_tm_upiu_trace(hba, task_tag, "tm_complete"); + } + + spin_lock_irqsave(hba->host->host_lock, flags); +- __clear_bit(free_slot, &hba->outstanding_tasks); ++ __clear_bit(task_tag, &hba->outstanding_tasks); + spin_unlock_irqrestore(hba->host->host_lock, flags); + ++ ufshcd_release(hba); + blk_put_request(req); + +- ufshcd_release(hba); + return err; + } + +-- +2.30.2 + diff --git a/queue-5.4/scsi-ufs-fix-irq-return-code.patch b/queue-5.4/scsi-ufs-fix-irq-return-code.patch new file mode 100644 index 00000000000..dec259c82a1 --- /dev/null +++ b/queue-5.4/scsi-ufs-fix-irq-return-code.patch @@ -0,0 +1,344 @@ +From 4938caae0751595698a28272efd59b12ef5910da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Nov 2019 22:09:28 -0800 +Subject: scsi: ufs: Fix irq return code + +From: Venkat Gopalakrishnan + +[ Upstream commit 9333d77573485c827b4c0fc960c840df3e5ce719 ] + +Return IRQ_HANDLED only if the irq is really handled, this will help in +catching spurious interrupts that go unhandled. + +Link: https://lore.kernel.org/r/1573798172-20534-6-git-send-email-cang@codeaurora.org +Reviewed-by: Avri Altman +Signed-off-by: Venkat Gopalakrishnan +Signed-off-by: Can Guo +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/ufs/ufshcd.c | 134 ++++++++++++++++++++++++++++---------- + drivers/scsi/ufs/ufshci.h | 2 +- + 2 files changed, 100 insertions(+), 36 deletions(-) + +diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c +index 476ef8044ae5..289edf70ccb9 100644 +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -239,7 +239,7 @@ static struct ufs_dev_fix ufs_fixups[] = { + END_FIX + }; + +-static void ufshcd_tmc_handler(struct ufs_hba *hba); ++static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba); + static void ufshcd_async_scan(void *data, async_cookie_t cookie); + static int ufshcd_reset_and_restore(struct ufs_hba *hba); + static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd); +@@ -4815,19 +4815,29 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) + * ufshcd_uic_cmd_compl - handle completion of uic command + * @hba: per adapter instance + * @intr_status: interrupt status generated by the controller ++ * ++ * Returns ++ * IRQ_HANDLED - If interrupt is valid ++ * IRQ_NONE - If invalid interrupt + */ +-static void ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status) ++static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status) + { ++ irqreturn_t retval = IRQ_NONE; ++ + if ((intr_status & UIC_COMMAND_COMPL) && hba->active_uic_cmd) { + hba->active_uic_cmd->argument2 |= + ufshcd_get_uic_cmd_result(hba); + hba->active_uic_cmd->argument3 = + ufshcd_get_dme_attr_val(hba); + complete(&hba->active_uic_cmd->done); ++ retval = IRQ_HANDLED; + } + +- if ((intr_status & UFSHCD_UIC_PWR_MASK) && hba->uic_async_done) ++ if ((intr_status & UFSHCD_UIC_PWR_MASK) && hba->uic_async_done) { + complete(hba->uic_async_done); ++ retval = IRQ_HANDLED; ++ } ++ return retval; + } + + /** +@@ -4883,8 +4893,12 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, + /** + * ufshcd_transfer_req_compl - handle SCSI and query command completion + * @hba: per adapter instance ++ * ++ * Returns ++ * IRQ_HANDLED - If interrupt is valid ++ * IRQ_NONE - If invalid interrupt + */ +-static void ufshcd_transfer_req_compl(struct ufs_hba *hba) ++static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba) + { + unsigned long completed_reqs; + u32 tr_doorbell; +@@ -4903,7 +4917,12 @@ static void ufshcd_transfer_req_compl(struct ufs_hba *hba) + tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); + completed_reqs = tr_doorbell ^ hba->outstanding_reqs; + +- __ufshcd_transfer_req_compl(hba, completed_reqs); ++ if (completed_reqs) { ++ __ufshcd_transfer_req_compl(hba, completed_reqs); ++ return IRQ_HANDLED; ++ } else { ++ return IRQ_NONE; ++ } + } + + /** +@@ -5424,61 +5443,77 @@ out: + /** + * ufshcd_update_uic_error - check and set fatal UIC error flags. + * @hba: per-adapter instance ++ * ++ * Returns ++ * IRQ_HANDLED - If interrupt is valid ++ * IRQ_NONE - If invalid interrupt + */ +-static void ufshcd_update_uic_error(struct ufs_hba *hba) ++static irqreturn_t ufshcd_update_uic_error(struct ufs_hba *hba) + { + u32 reg; ++ irqreturn_t retval = IRQ_NONE; + + /* PHY layer lane error */ + reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER); + /* Ignore LINERESET indication, as this is not an error */ + if ((reg & UIC_PHY_ADAPTER_LAYER_ERROR) && +- (reg & UIC_PHY_ADAPTER_LAYER_LANE_ERR_MASK)) { ++ (reg & UIC_PHY_ADAPTER_LAYER_LANE_ERR_MASK)) { + /* + * To know whether this error is fatal or not, DB timeout + * must be checked but this error is handled separately. + */ + dev_dbg(hba->dev, "%s: UIC Lane error reported\n", __func__); + ufshcd_update_reg_hist(&hba->ufs_stats.pa_err, reg); ++ retval |= IRQ_HANDLED; + } + + /* PA_INIT_ERROR is fatal and needs UIC reset */ + reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_DATA_LINK_LAYER); +- if (reg) ++ if ((reg & UIC_DATA_LINK_LAYER_ERROR) && ++ (reg & UIC_DATA_LINK_LAYER_ERROR_CODE_MASK)) { + ufshcd_update_reg_hist(&hba->ufs_stats.dl_err, reg); + +- if (reg & UIC_DATA_LINK_LAYER_ERROR_PA_INIT) +- hba->uic_error |= UFSHCD_UIC_DL_PA_INIT_ERROR; +- else if (hba->dev_quirks & +- UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS) { +- if (reg & UIC_DATA_LINK_LAYER_ERROR_NAC_RECEIVED) +- hba->uic_error |= +- UFSHCD_UIC_DL_NAC_RECEIVED_ERROR; +- else if (reg & UIC_DATA_LINK_LAYER_ERROR_TCx_REPLAY_TIMEOUT) +- hba->uic_error |= UFSHCD_UIC_DL_TCx_REPLAY_ERROR; ++ if (reg & UIC_DATA_LINK_LAYER_ERROR_PA_INIT) ++ hba->uic_error |= UFSHCD_UIC_DL_PA_INIT_ERROR; ++ else if (hba->dev_quirks & ++ UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS) { ++ if (reg & UIC_DATA_LINK_LAYER_ERROR_NAC_RECEIVED) ++ hba->uic_error |= ++ UFSHCD_UIC_DL_NAC_RECEIVED_ERROR; ++ else if (reg & UIC_DATA_LINK_LAYER_ERROR_TCx_REPLAY_TIMEOUT) ++ hba->uic_error |= UFSHCD_UIC_DL_TCx_REPLAY_ERROR; ++ } ++ retval |= IRQ_HANDLED; + } + + /* UIC NL/TL/DME errors needs software retry */ + reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_NETWORK_LAYER); +- if (reg) { ++ if ((reg & UIC_NETWORK_LAYER_ERROR) && ++ (reg & UIC_NETWORK_LAYER_ERROR_CODE_MASK)) { + ufshcd_update_reg_hist(&hba->ufs_stats.nl_err, reg); + hba->uic_error |= UFSHCD_UIC_NL_ERROR; ++ retval |= IRQ_HANDLED; + } + + reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_TRANSPORT_LAYER); +- if (reg) { ++ if ((reg & UIC_TRANSPORT_LAYER_ERROR) && ++ (reg & UIC_TRANSPORT_LAYER_ERROR_CODE_MASK)) { + ufshcd_update_reg_hist(&hba->ufs_stats.tl_err, reg); + hba->uic_error |= UFSHCD_UIC_TL_ERROR; ++ retval |= IRQ_HANDLED; + } + + reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_DME); +- if (reg) { ++ if ((reg & UIC_DME_ERROR) && ++ (reg & UIC_DME_ERROR_CODE_MASK)) { + ufshcd_update_reg_hist(&hba->ufs_stats.dme_err, reg); + hba->uic_error |= UFSHCD_UIC_DME_ERROR; ++ retval |= IRQ_HANDLED; + } + + dev_dbg(hba->dev, "%s: UIC error flags = 0x%08x\n", + __func__, hba->uic_error); ++ return retval; + } + + static bool ufshcd_is_auto_hibern8_error(struct ufs_hba *hba, +@@ -5502,10 +5537,15 @@ static bool ufshcd_is_auto_hibern8_error(struct ufs_hba *hba, + /** + * ufshcd_check_errors - Check for errors that need s/w attention + * @hba: per-adapter instance ++ * ++ * Returns ++ * IRQ_HANDLED - If interrupt is valid ++ * IRQ_NONE - If invalid interrupt + */ +-static void ufshcd_check_errors(struct ufs_hba *hba) ++static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba) + { + bool queue_eh_work = false; ++ irqreturn_t retval = IRQ_NONE; + + if (hba->errors & INT_FATAL_ERRORS) { + ufshcd_update_reg_hist(&hba->ufs_stats.fatal_err, hba->errors); +@@ -5514,7 +5554,7 @@ static void ufshcd_check_errors(struct ufs_hba *hba) + + if (hba->errors & UIC_ERROR) { + hba->uic_error = 0; +- ufshcd_update_uic_error(hba); ++ retval = ufshcd_update_uic_error(hba); + if (hba->uic_error) + queue_eh_work = true; + } +@@ -5562,6 +5602,7 @@ static void ufshcd_check_errors(struct ufs_hba *hba) + } + schedule_work(&hba->eh_work); + } ++ retval |= IRQ_HANDLED; + } + /* + * if (!queue_eh_work) - +@@ -5569,44 +5610,62 @@ static void ufshcd_check_errors(struct ufs_hba *hba) + * itself without s/w intervention or errors that will be + * handled by the SCSI core layer. + */ ++ return retval; + } + + /** + * ufshcd_tmc_handler - handle task management function completion + * @hba: per adapter instance ++ * ++ * Returns ++ * IRQ_HANDLED - If interrupt is valid ++ * IRQ_NONE - If invalid interrupt + */ +-static void ufshcd_tmc_handler(struct ufs_hba *hba) ++static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba) + { + u32 tm_doorbell; + + tm_doorbell = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL); + hba->tm_condition = tm_doorbell ^ hba->outstanding_tasks; +- wake_up(&hba->tm_wq); ++ if (hba->tm_condition) { ++ wake_up(&hba->tm_wq); ++ return IRQ_HANDLED; ++ } else { ++ return IRQ_NONE; ++ } + } + + /** + * ufshcd_sl_intr - Interrupt service routine + * @hba: per adapter instance + * @intr_status: contains interrupts generated by the controller ++ * ++ * Returns ++ * IRQ_HANDLED - If interrupt is valid ++ * IRQ_NONE - If invalid interrupt + */ +-static void ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status) ++static irqreturn_t ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status) + { ++ irqreturn_t retval = IRQ_NONE; ++ + hba->errors = UFSHCD_ERROR_MASK & intr_status; + + if (ufshcd_is_auto_hibern8_error(hba, intr_status)) + hba->errors |= (UFSHCD_UIC_HIBERN8_MASK & intr_status); + + if (hba->errors) +- ufshcd_check_errors(hba); ++ retval |= ufshcd_check_errors(hba); + + if (intr_status & UFSHCD_UIC_MASK) +- ufshcd_uic_cmd_compl(hba, intr_status); ++ retval |= ufshcd_uic_cmd_compl(hba, intr_status); + + if (intr_status & UTP_TASK_REQ_COMPL) +- ufshcd_tmc_handler(hba); ++ retval |= ufshcd_tmc_handler(hba); + + if (intr_status & UTP_TRANSFER_REQ_COMPL) +- ufshcd_transfer_req_compl(hba); ++ retval |= ufshcd_transfer_req_compl(hba); ++ ++ return retval; + } + + /** +@@ -5614,8 +5673,9 @@ static void ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status) + * @irq: irq number + * @__hba: pointer to adapter instance + * +- * Returns IRQ_HANDLED - If interrupt is valid +- * IRQ_NONE - If invalid interrupt ++ * Returns ++ * IRQ_HANDLED - If interrupt is valid ++ * IRQ_NONE - If invalid interrupt + */ + static irqreturn_t ufshcd_intr(int irq, void *__hba) + { +@@ -5638,14 +5698,18 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba) + intr_status & ufshcd_readl(hba, REG_INTERRUPT_ENABLE); + if (intr_status) + ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS); +- if (enabled_intr_status) { +- ufshcd_sl_intr(hba, enabled_intr_status); +- retval = IRQ_HANDLED; +- } ++ if (enabled_intr_status) ++ retval |= ufshcd_sl_intr(hba, enabled_intr_status); + + intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS); + } + ++ if (retval == IRQ_NONE) { ++ dev_err(hba->dev, "%s: Unhandled interrupt 0x%08x\n", ++ __func__, intr_status); ++ ufshcd_dump_regs(hba, 0, UFSHCI_REG_SPACE_SIZE, "host_regs: "); ++ } ++ + spin_unlock(hba->host->host_lock); + return retval; + } +diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h +index dbb75cd28dc8..c2961d37cc1c 100644 +--- a/drivers/scsi/ufs/ufshci.h ++++ b/drivers/scsi/ufs/ufshci.h +@@ -195,7 +195,7 @@ enum { + + /* UECDL - Host UIC Error Code Data Link Layer 3Ch */ + #define UIC_DATA_LINK_LAYER_ERROR 0x80000000 +-#define UIC_DATA_LINK_LAYER_ERROR_CODE_MASK 0x7FFF ++#define UIC_DATA_LINK_LAYER_ERROR_CODE_MASK 0xFFFF + #define UIC_DATA_LINK_LAYER_ERROR_TCX_REP_TIMER_EXP 0x2 + #define UIC_DATA_LINK_LAYER_ERROR_AFCX_REQ_TIMER_EXP 0x4 + #define UIC_DATA_LINK_LAYER_ERROR_FCX_PRO_TIMER_EXP 0x8 +-- +2.30.2 + diff --git a/queue-5.4/scsi-ufs-use-blk_-get-put-_request-to-allocate-and-f.patch b/queue-5.4/scsi-ufs-use-blk_-get-put-_request-to-allocate-and-f.patch new file mode 100644 index 00000000000..afdf9c55fbd --- /dev/null +++ b/queue-5.4/scsi-ufs-use-blk_-get-put-_request-to-allocate-and-f.patch @@ -0,0 +1,292 @@ +From 6fbc42f7ae1346a44d0c881ef0b537de3800ed4c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Dec 2019 10:13:09 -0800 +Subject: scsi: ufs: Use blk_{get,put}_request() to allocate and free TMFs + +From: Bart Van Assche + +[ Upstream commit 69a6c269c097d780a2db320ecd47f7a62fafd92e ] + +Manage TMF tags with blk_{get,put}_request() instead of +ufshcd_get_tm_free_slot() / ufshcd_put_tm_slot(). Store a per-request +completion pointer in request.end_io_data instead of using a waitqueue to +report TMF completion. + +Cc: Can Guo +Cc: Stanley Chu +Cc: Avri Altman +Cc: Tomas Winkler +Link: https://lore.kernel.org/r/20191209181309.196233-3-bvanassche@acm.org +Tested-by: Bean Huo +Reviewed-by: Avri Altman +Signed-off-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/ufs/ufshcd.c | 130 ++++++++++++++++++++++---------------- + drivers/scsi/ufs/ufshcd.h | 12 ++-- + 2 files changed, 80 insertions(+), 62 deletions(-) + +diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c +index e84617172968..e7e6405401dd 100644 +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -644,40 +644,6 @@ static inline int ufshcd_get_tr_ocs(struct ufshcd_lrb *lrbp) + return le32_to_cpu(lrbp->utr_descriptor_ptr->header.dword_2) & MASK_OCS; + } + +-/** +- * ufshcd_get_tm_free_slot - get a free slot for task management request +- * @hba: per adapter instance +- * @free_slot: pointer to variable with available slot value +- * +- * Get a free tag and lock it until ufshcd_put_tm_slot() is called. +- * Returns 0 if free slot is not available, else return 1 with tag value +- * in @free_slot. +- */ +-static bool ufshcd_get_tm_free_slot(struct ufs_hba *hba, int *free_slot) +-{ +- int tag; +- bool ret = false; +- +- if (!free_slot) +- goto out; +- +- do { +- tag = find_first_zero_bit(&hba->tm_slots_in_use, hba->nutmrs); +- if (tag >= hba->nutmrs) +- goto out; +- } while (test_and_set_bit_lock(tag, &hba->tm_slots_in_use)); +- +- *free_slot = tag; +- ret = true; +-out: +- return ret; +-} +- +-static inline void ufshcd_put_tm_slot(struct ufs_hba *hba, int slot) +-{ +- clear_bit_unlock(slot, &hba->tm_slots_in_use); +-} +- + /** + * ufshcd_utrl_clear - Clear a bit in UTRLCLR register + * @hba: per adapter instance +@@ -5580,6 +5546,27 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba) + return retval; + } + ++struct ctm_info { ++ struct ufs_hba *hba; ++ unsigned long pending; ++ unsigned int ncpl; ++}; ++ ++static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved) ++{ ++ struct ctm_info *const ci = priv; ++ struct completion *c; ++ ++ WARN_ON_ONCE(reserved); ++ if (test_bit(req->tag, &ci->pending)) ++ return true; ++ ci->ncpl++; ++ c = req->end_io_data; ++ if (c) ++ complete(c); ++ return true; ++} ++ + /** + * ufshcd_tmc_handler - handle task management function completion + * @hba: per adapter instance +@@ -5590,16 +5577,14 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba) + */ + static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba) + { +- u32 tm_doorbell; ++ struct request_queue *q = hba->tmf_queue; ++ struct ctm_info ci = { ++ .hba = hba, ++ .pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL), ++ }; + +- tm_doorbell = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL); +- hba->tm_condition = tm_doorbell ^ hba->outstanding_tasks; +- if (hba->tm_condition) { +- wake_up(&hba->tm_wq); +- return IRQ_HANDLED; +- } else { +- return IRQ_NONE; +- } ++ blk_mq_tagset_busy_iter(q->tag_set, ufshcd_compl_tm, &ci); ++ return ci.ncpl ? IRQ_HANDLED : IRQ_NONE; + } + + /** +@@ -5705,7 +5690,10 @@ out: + static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, + struct utp_task_req_desc *treq, u8 tm_function) + { ++ struct request_queue *q = hba->tmf_queue; + struct Scsi_Host *host = hba->host; ++ DECLARE_COMPLETION_ONSTACK(wait); ++ struct request *req; + unsigned long flags; + int free_slot, task_tag, err; + +@@ -5714,7 +5702,10 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, + * Even though we use wait_event() which sleeps indefinitely, + * the maximum wait time is bounded by %TM_CMD_TIMEOUT. + */ +- wait_event(hba->tm_tag_wq, ufshcd_get_tm_free_slot(hba, &free_slot)); ++ req = blk_get_request(q, REQ_OP_DRV_OUT, BLK_MQ_REQ_RESERVED); ++ req->end_io_data = &wait; ++ free_slot = req->tag; ++ WARN_ON_ONCE(free_slot < 0 || free_slot >= hba->nutmrs); + ufshcd_hold(hba, false); + + spin_lock_irqsave(host->host_lock, flags); +@@ -5740,10 +5731,14 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, + ufshcd_add_tm_upiu_trace(hba, task_tag, "tm_send"); + + /* wait until the task management command is completed */ +- err = wait_event_timeout(hba->tm_wq, +- test_bit(free_slot, &hba->tm_condition), ++ err = wait_for_completion_io_timeout(&wait, + msecs_to_jiffies(TM_CMD_TIMEOUT)); + if (!err) { ++ /* ++ * Make sure that ufshcd_compl_tm() does not trigger a ++ * use-after-free. ++ */ ++ req->end_io_data = NULL; + ufshcd_add_tm_upiu_trace(hba, task_tag, "tm_complete_err"); + dev_err(hba->dev, "%s: task management cmd 0x%.2x timed-out\n", + __func__, tm_function); +@@ -5762,9 +5757,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, + __clear_bit(free_slot, &hba->outstanding_tasks); + spin_unlock_irqrestore(hba->host->host_lock, flags); + +- clear_bit(free_slot, &hba->tm_condition); +- ufshcd_put_tm_slot(hba, free_slot); +- wake_up(&hba->tm_tag_wq); ++ blk_put_request(req); + + ufshcd_release(hba); + return err; +@@ -8217,6 +8210,8 @@ void ufshcd_remove(struct ufs_hba *hba) + { + ufs_bsg_remove(hba); + ufs_sysfs_remove_nodes(hba->dev); ++ blk_cleanup_queue(hba->tmf_queue); ++ blk_mq_free_tag_set(&hba->tmf_tag_set); + blk_cleanup_queue(hba->cmd_queue); + scsi_remove_host(hba->host); + /* disable interrupts */ +@@ -8296,6 +8291,18 @@ out_error: + } + EXPORT_SYMBOL(ufshcd_alloc_host); + ++/* This function exists because blk_mq_alloc_tag_set() requires this. */ ++static blk_status_t ufshcd_queue_tmf(struct blk_mq_hw_ctx *hctx, ++ const struct blk_mq_queue_data *qd) ++{ ++ WARN_ON_ONCE(true); ++ return BLK_STS_NOTSUPP; ++} ++ ++static const struct blk_mq_ops ufshcd_tmf_ops = { ++ .queue_rq = ufshcd_queue_tmf, ++}; ++ + /** + * ufshcd_init - Driver initialization routine + * @hba: per-adapter instance +@@ -8365,10 +8372,6 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) + + hba->max_pwr_info.is_valid = false; + +- /* Initailize wait queue for task management */ +- init_waitqueue_head(&hba->tm_wq); +- init_waitqueue_head(&hba->tm_tag_wq); +- + /* Initialize work queues */ + INIT_WORK(&hba->eh_work, ufshcd_err_handler); + INIT_WORK(&hba->eeh_work, ufshcd_exception_event_handler); +@@ -8420,6 +8423,21 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) + goto out_remove_scsi_host; + } + ++ hba->tmf_tag_set = (struct blk_mq_tag_set) { ++ .nr_hw_queues = 1, ++ .queue_depth = hba->nutmrs, ++ .ops = &ufshcd_tmf_ops, ++ .flags = BLK_MQ_F_NO_SCHED, ++ }; ++ err = blk_mq_alloc_tag_set(&hba->tmf_tag_set); ++ if (err < 0) ++ goto free_cmd_queue; ++ hba->tmf_queue = blk_mq_init_queue(&hba->tmf_tag_set); ++ if (IS_ERR(hba->tmf_queue)) { ++ err = PTR_ERR(hba->tmf_queue); ++ goto free_tmf_tag_set; ++ } ++ + /* Reset the attached device */ + ufshcd_vops_device_reset(hba); + +@@ -8429,7 +8447,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) + dev_err(hba->dev, "Host controller enable failed\n"); + ufshcd_print_host_regs(hba); + ufshcd_print_host_state(hba); +- goto free_cmd_queue; ++ goto free_tmf_queue; + } + + /* +@@ -8466,6 +8484,10 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) + + return 0; + ++free_tmf_queue: ++ blk_cleanup_queue(hba->tmf_queue); ++free_tmf_tag_set: ++ blk_mq_free_tag_set(&hba->tmf_tag_set); + free_cmd_queue: + blk_cleanup_queue(hba->cmd_queue); + out_remove_scsi_host: +diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h +index 8fd6fd75cb5c..92ef6e6a3e51 100644 +--- a/drivers/scsi/ufs/ufshcd.h ++++ b/drivers/scsi/ufs/ufshcd.h +@@ -494,11 +494,9 @@ struct ufs_stats { + * @irq: Irq number of the controller + * @active_uic_cmd: handle of active UIC command + * @uic_cmd_mutex: mutex for uic command +- * @tm_wq: wait queue for task management +- * @tm_tag_wq: wait queue for free task management slots +- * @tm_slots_in_use: bit map of task management request slots in use ++ * @tmf_tag_set: TMF tag set. ++ * @tmf_queue: Used to allocate TMF tags. + * @pwr_done: completion for power mode change +- * @tm_condition: condition variable for task management + * @ufshcd_state: UFSHCD states + * @eh_flags: Error handling flags + * @intr_mask: Interrupt Mask Bits +@@ -643,10 +641,8 @@ struct ufs_hba { + /* Device deviations from standard UFS device spec. */ + unsigned int dev_quirks; + +- wait_queue_head_t tm_wq; +- wait_queue_head_t tm_tag_wq; +- unsigned long tm_condition; +- unsigned long tm_slots_in_use; ++ struct blk_mq_tag_set tmf_tag_set; ++ struct request_queue *tmf_queue; + + struct uic_command *active_uic_cmd; + struct mutex uic_cmd_mutex; +-- +2.30.2 + diff --git a/queue-5.4/series b/queue-5.4/series index 48effe1bebf..84c53ae6e05 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -42,3 +42,52 @@ virtio_net-add-xdp-meta-data-support.patch virtio_net-do-not-pull-payload-in-skb-head.patch net-dsa-lantiq_gswip-don-t-use-phy-auto-polling.patch net-dsa-lantiq_gswip-configure-all-remaining-gswip_m.patch +xfrm-interface-fix-ipv4-pmtu-check-to-honor-ip-heade.patch +regulator-bd9571mwv-fix-avs-and-dvfs-voltage-range.patch +net-xfrm-localize-sequence-counter-per-network-names.patch +esp-delete-netif_f_sctp_crc-bit-from-features-for-es.patch +asoc-sof-intel-hda-remove-unnecessary-parentheses.patch +asoc-sof-intel-hda-fix-core-status-verification.patch +asoc-wm8960-fix-wrong-bclk-and-lrclk-with-pll-enable.patch +xfrm-fix-null-pointer-dereference-on-policy-lookup.patch +i40e-added-asym_pause-to-supported-link-modes.patch +i40e-fix-kernel-oops-when-i40e-driver-removes-vf-s.patch +hostfs-use-kasprintf-instead-of-fixed-buffer-formatt.patch +hostfs-fix-memory-handling-in-follow_link.patch +amd-xgbe-update-dma-coherency-values.patch +sch_red-fix-off-by-one-checks-in-red_check_params.patch +arm64-dts-imx8mm-q-fix-pad-control-of-sd1_data0.patch +can-bcm-raw-fix-msg_namelen-values-depending-on-can_.patch +gianfar-handle-error-code-at-mac-address-change.patch +cxgb4-avoid-collecting-sge_qbase-regs-during-traffic.patch +net-tipc-fix-a-double-free-in-tipc_sk_mcast_rcv.patch +arm-dts-imx6-pbab01-set-vmmc-supply-for-both-sd-inte.patch +net-ncsi-avoid-channel_monitor-hrtimer-deadlock.patch +nfp-flower-ignore-duplicate-merge-hints-from-fw.patch +net-phy-broadcom-only-advertise-eee-for-supported-mo.patch +asoc-sunxi-sun4i-codec-fill-asoc-card-owner.patch +net-mlx5e-fix-ethtool-indication-of-connector-type.patch +net-mlx5-don-t-request-more-than-supported-eqs.patch +net-rds-fix-a-use-after-free-in-rds_message_map_page.patch +soc-fsl-qbman-fix-conflicting-alignment-attributes.patch +i40e-fix-display-statistics-for-veb_tc.patch +drm-msm-set-drvdata-to-null-when-msm_drm_init-fails.patch +net-udp-add-support-for-getsockopt-.-.-udp_gro.patch +scsi-ufs-fix-irq-return-code.patch +scsi-ufs-avoid-busy-waiting-by-eliminating-tag-confl.patch +scsi-ufs-use-blk_-get-put-_request-to-allocate-and-f.patch +scsi-ufs-core-fix-task-management-request-completion.patch +scsi-ufs-core-fix-wrong-task-tag-used-in-task-manage.patch +net-macb-restore-cmp-registers-on-resume-path.patch +clk-fix-invalid-usage-of-list-cursor-in-register.patch +clk-fix-invalid-usage-of-list-cursor-in-unregister.patch +workqueue-move-the-position-of-debug_work_activate-i.patch +s390-cpcmd-fix-inline-assembly-register-clobbering.patch +perf-inject-fix-repipe-usage.patch +net-openvswitch-conntrack-simplify-the-return-expres.patch +openvswitch-fix-send-of-uninitialized-stack-memory-i.patch +net-hns3-clear-vf-down-state-bit-before-request-link.patch +net-mlx5-fix-placement-of-log_max_flow_counter.patch +net-mlx5-fix-pbmc-register-mapping.patch +rdma-cxgb4-check-for-ipv6-address-properly-while-des.patch +rdma-addr-be-strict-with-gid-size.patch diff --git a/queue-5.4/soc-fsl-qbman-fix-conflicting-alignment-attributes.patch b/queue-5.4/soc-fsl-qbman-fix-conflicting-alignment-attributes.patch new file mode 100644 index 00000000000..42cd93cf600 --- /dev/null +++ b/queue-5.4/soc-fsl-qbman-fix-conflicting-alignment-attributes.patch @@ -0,0 +1,44 @@ +From 4b0f61274f62efefa38e8e8082c30aa3aff736f7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Mar 2021 14:15:23 +0100 +Subject: soc/fsl: qbman: fix conflicting alignment attributes + +From: Arnd Bergmann + +[ Upstream commit 040f31196e8b2609613f399793b9225271b79471 ] + +When building with W=1, gcc points out that the __packed attribute +on struct qm_eqcr_entry conflicts with the 8-byte alignment +attribute on struct qm_fd inside it: + +drivers/soc/fsl/qbman/qman.c:189:1: error: alignment 1 of 'struct qm_eqcr_entry' is less than 8 [-Werror=packed-not-aligned] + +I assume that the alignment attribute is the correct one, and +that qm_eqcr_entry cannot actually be unaligned in memory, +so add the same alignment on the outer struct. + +Fixes: c535e923bb97 ("soc/fsl: Introduce DPAA 1.x QMan device driver") +Signed-off-by: Arnd Bergmann +Link: https://lore.kernel.org/r/20210323131530.2619900-1-arnd@kernel.org' +Signed-off-by: Arnd Bergmann +Signed-off-by: Sasha Levin +--- + drivers/soc/fsl/qbman/qman.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c +index bf68d86d80ee..95f9e4805245 100644 +--- a/drivers/soc/fsl/qbman/qman.c ++++ b/drivers/soc/fsl/qbman/qman.c +@@ -186,7 +186,7 @@ struct qm_eqcr_entry { + __be32 tag; + struct qm_fd fd; + u8 __reserved3[32]; +-} __packed; ++} __packed __aligned(8); + #define QM_EQCR_VERB_VBIT 0x80 + #define QM_EQCR_VERB_CMD_MASK 0x61 /* but only one value; */ + #define QM_EQCR_VERB_CMD_ENQUEUE 0x01 +-- +2.30.2 + diff --git a/queue-5.4/workqueue-move-the-position-of-debug_work_activate-i.patch b/queue-5.4/workqueue-move-the-position-of-debug_work_activate-i.patch new file mode 100644 index 00000000000..bd4a308a3df --- /dev/null +++ b/queue-5.4/workqueue-move-the-position-of-debug_work_activate-i.patch @@ -0,0 +1,46 @@ +From 9ff728219e74edf7bdd458b7396558eaf576b13b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Feb 2021 11:16:49 +0800 +Subject: workqueue: Move the position of debug_work_activate() in + __queue_work() + +From: Zqiang + +[ Upstream commit 0687c66b5f666b5ad433f4e94251590d9bc9d10e ] + +The debug_work_activate() is called on the premise that +the work can be inserted, because if wq be in WQ_DRAINING +status, insert work may be failed. + +Fixes: e41e704bc4f4 ("workqueue: improve destroy_workqueue() debuggability") +Signed-off-by: Zqiang +Reviewed-by: Lai Jiangshan +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/workqueue.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index 29c36c029062..5d7092e32912 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -1411,7 +1411,6 @@ static void __queue_work(int cpu, struct workqueue_struct *wq, + */ + lockdep_assert_irqs_disabled(); + +- debug_work_activate(work); + + /* if draining, only works from the same workqueue are allowed */ + if (unlikely(wq->flags & __WQ_DRAINING) && +@@ -1493,6 +1492,7 @@ retry: + worklist = &pwq->delayed_works; + } + ++ debug_work_activate(work); + insert_work(pwq, work, worklist, work_flags); + + out: +-- +2.30.2 + diff --git a/queue-5.4/xfrm-fix-null-pointer-dereference-on-policy-lookup.patch b/queue-5.4/xfrm-fix-null-pointer-dereference-on-policy-lookup.patch new file mode 100644 index 00000000000..ae716454219 --- /dev/null +++ b/queue-5.4/xfrm-fix-null-pointer-dereference-on-policy-lookup.patch @@ -0,0 +1,40 @@ +From aa53cbc8c731b7eb3e8debc04b0578bd9abed5c0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Mar 2021 09:26:44 +0100 +Subject: xfrm: Fix NULL pointer dereference on policy lookup + +From: Steffen Klassert + +[ Upstream commit b1e3a5607034aa0a481c6f69a6893049406665fb ] + +When xfrm interfaces are used in combination with namespaces +and ESP offload, we get a dst_entry NULL pointer dereference. +This is because we don't have a dst_entry attached in the ESP +offloading case and we need to do a policy lookup before the +namespace transition. + +Fix this by expicit checking of skb_dst(skb) before accessing it. + +Fixes: f203b76d78092 ("xfrm: Add virtual xfrm interfaces") +Signed-off-by: Steffen Klassert +Signed-off-by: Sasha Levin +--- + include/net/xfrm.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/net/xfrm.h b/include/net/xfrm.h +index c00b9ae71ae4..614f19bbad74 100644 +--- a/include/net/xfrm.h ++++ b/include/net/xfrm.h +@@ -1098,7 +1098,7 @@ static inline int __xfrm_policy_check2(struct sock *sk, int dir, + return __xfrm_policy_check(sk, ndir, skb, family); + + return (!net->xfrm.policy_count[dir] && !secpath_exists(skb)) || +- (skb_dst(skb)->flags & DST_NOPOLICY) || ++ (skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY)) || + __xfrm_policy_check(sk, ndir, skb, family); + } + +-- +2.30.2 + diff --git a/queue-5.4/xfrm-interface-fix-ipv4-pmtu-check-to-honor-ip-heade.patch b/queue-5.4/xfrm-interface-fix-ipv4-pmtu-check-to-honor-ip-heade.patch new file mode 100644 index 00000000000..bee292a6cae --- /dev/null +++ b/queue-5.4/xfrm-interface-fix-ipv4-pmtu-check-to-honor-ip-heade.patch @@ -0,0 +1,48 @@ +From a637f27886379dc079a73e553b3898bf38bdafa0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 20 Feb 2021 15:01:15 +0200 +Subject: xfrm: interface: fix ipv4 pmtu check to honor ip header df + +From: Eyal Birger + +[ Upstream commit 8fc0e3b6a8666d656923d214e4dc791e9a17164a ] + +Frag needed should only be sent if the header enables DF. + +This fix allows packets larger than MTU to pass the xfrm interface +and be fragmented after encapsulation, aligning behavior with +non-interface xfrm. + +Fixes: f203b76d7809 ("xfrm: Add virtual xfrm interfaces") +Signed-off-by: Eyal Birger +Reviewed-by: Sabrina Dubroca +Signed-off-by: Steffen Klassert +Signed-off-by: Sasha Levin +--- + net/xfrm/xfrm_interface.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c +index 01c65f96d283..74e90d78c3b4 100644 +--- a/net/xfrm/xfrm_interface.c ++++ b/net/xfrm/xfrm_interface.c +@@ -302,6 +302,8 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) + + icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + } else { ++ if (!(ip_hdr(skb)->frag_off & htons(IP_DF))) ++ goto xmit; + icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, + htonl(mtu)); + } +@@ -310,6 +312,7 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) + return -EMSGSIZE; + } + ++xmit: + xfrmi_scrub_packet(skb, !net_eq(xi->net, dev_net(dev))); + skb_dst_set(skb, dst); + skb->dev = tdev; +-- +2.30.2 +